@office-kit/pptx 0.16.1 → 0.18.0

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.
@@ -27,6 +27,9 @@ const STORE_BY_EXTENSION = new Set([
27
27
  "wmv",
28
28
  "mov",
29
29
  "avi",
30
+ "webm",
31
+ "ogg",
32
+ "wma",
30
33
  "pdf",
31
34
  "zip",
32
35
  "gz",
@@ -825,7 +828,7 @@ const emptyContentTypes = () => ({
825
828
  const REL_NS = NS.relationships;
826
829
  const NAME_RELATIONSHIPS = qname("", "Relationships", REL_NS);
827
830
  const NAME_RELATIONSHIP = qname("", "Relationship", REL_NS);
828
- const ATTR_ID$14 = qname("", "Id", "");
831
+ const ATTR_ID$16 = qname("", "Id", "");
829
832
  const ATTR_TYPE$7 = qname("", "Type", "");
830
833
  const ATTR_TARGET = qname("", "Target", "");
831
834
  const ATTR_TARGET_MODE = qname("", "TargetMode", "");
@@ -863,7 +866,7 @@ const serializeRels = (rels) => {
863
866
  const children = rels.items.map((r) => {
864
867
  const attrs = [
865
868
  {
866
- name: ATTR_ID$14,
869
+ name: ATTR_ID$16,
867
870
  value: r.id
868
871
  },
869
872
  {
@@ -1060,6 +1063,79 @@ const contentTypeForFormat = (format) => {
1060
1063
  }
1061
1064
  };
1062
1065
  //#endregion
1066
+ //#region src/internal/opc/media-format.ts
1067
+ const VIDEO_CONTENT_TYPES = {
1068
+ mp4: "video/mp4",
1069
+ m4v: "video/mp4",
1070
+ mov: "video/quicktime",
1071
+ webm: "video/webm",
1072
+ avi: "video/x-msvideo",
1073
+ wmv: "video/x-ms-wmv"
1074
+ };
1075
+ const AUDIO_CONTENT_TYPES = {
1076
+ mp3: "audio/mpeg",
1077
+ wav: "audio/x-wav",
1078
+ m4a: "audio/mp4",
1079
+ ogg: "audio/ogg",
1080
+ wma: "audio/x-ms-wma"
1081
+ };
1082
+ const contentTypeForVideoFormat = (format) => VIDEO_CONTENT_TYPES[format];
1083
+ const contentTypeForAudioFormat = (format) => AUDIO_CONTENT_TYPES[format];
1084
+ const hasBytesAt = (bytes, at, signature) => {
1085
+ if (bytes.length < at + signature.length) return false;
1086
+ for (let i = 0; i < signature.length; i++) if (bytes[at + i] !== signature[i]) return false;
1087
+ return true;
1088
+ };
1089
+ const hasAsciiAt = (bytes, at, text) => hasBytesAt(bytes, at, Array.from(text, (ch) => ch.charCodeAt(0)));
1090
+ const isoBrand = (bytes) => hasAsciiAt(bytes, 4, "ftyp") && bytes.length >= 12 ? String.fromCharCode(bytes[8], bytes[9], bytes[10], bytes[11]) : null;
1091
+ const isRiff = (bytes, form) => hasAsciiAt(bytes, 0, "RIFF") && hasAsciiAt(bytes, 8, form);
1092
+ const ASF_HEADER = [
1093
+ 48,
1094
+ 38,
1095
+ 178,
1096
+ 117,
1097
+ 142,
1098
+ 102,
1099
+ 207,
1100
+ 17
1101
+ ];
1102
+ const EBML_HEADER = [
1103
+ 26,
1104
+ 69,
1105
+ 223,
1106
+ 163
1107
+ ];
1108
+ const EBML_DOCTYPE_WINDOW = 64;
1109
+ const isWebm = (bytes) => {
1110
+ if (!hasBytesAt(bytes, 0, EBML_HEADER)) return false;
1111
+ const limit = Math.min(bytes.length, EBML_DOCTYPE_WINDOW) - 4;
1112
+ for (let i = 4; i <= limit; i++) if (hasAsciiAt(bytes, i, "webm")) return true;
1113
+ return false;
1114
+ };
1115
+ /** Detects a video container, or `null` when no known signature matches. */
1116
+ const detectVideoFormat = (bytes) => {
1117
+ const brand = isoBrand(bytes);
1118
+ if (brand !== null) {
1119
+ if (brand === "qt ") return "mov";
1120
+ if (brand === "M4V ") return "m4v";
1121
+ return "mp4";
1122
+ }
1123
+ if (isWebm(bytes)) return "webm";
1124
+ if (isRiff(bytes, "AVI ")) return "avi";
1125
+ if (hasBytesAt(bytes, 0, ASF_HEADER)) return "wmv";
1126
+ return null;
1127
+ };
1128
+ /** Detects an audio container, or `null` when no known signature matches. */
1129
+ const detectAudioFormat = (bytes) => {
1130
+ if (isoBrand(bytes) !== null) return "m4a";
1131
+ if (isRiff(bytes, "WAVE")) return "wav";
1132
+ if (hasAsciiAt(bytes, 0, "OggS")) return "ogg";
1133
+ if (hasBytesAt(bytes, 0, ASF_HEADER)) return "wma";
1134
+ if (hasAsciiAt(bytes, 0, "ID3")) return "mp3";
1135
+ if (bytes.length >= 2 && bytes[0] === 255 && (bytes[1] & 224) === 224) return "mp3";
1136
+ return null;
1137
+ };
1138
+ //#endregion
1063
1139
  //#region src/internal/parts/package.ts
1064
1140
  const TEXT_DECODER$1 = new TextDecoder();
1065
1141
  const TEXT_ENCODER$3 = new TextEncoder();
@@ -1382,7 +1458,7 @@ const savePresentation = (pres) => {
1382
1458
  //#region src/internal/presentationml/relationship-types.ts
1383
1459
  const OFFICE_DOC = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
1384
1460
  const PACKAGE = "http://schemas.openxmlformats.org/package/2006/relationships";
1385
- const MS_2010 = "http://schemas.microsoft.com/office/2010/relationships";
1461
+ const MS_2007 = "http://schemas.microsoft.com/office/2007/relationships";
1386
1462
  const MS_2015 = "http://schemas.microsoft.com/office/2015/relationships";
1387
1463
  const REL_TYPES = {
1388
1464
  officeDocument: `${OFFICE_DOC}/officeDocument`,
@@ -1411,10 +1487,10 @@ const REL_TYPES = {
1411
1487
  diagramLayout: `${OFFICE_DOC}/diagramLayout`,
1412
1488
  diagramQuickStyle: `${OFFICE_DOC}/diagramQuickStyle`,
1413
1489
  diagramColors: `${OFFICE_DOC}/diagramColors`,
1414
- media: `${MS_2010}/media`,
1415
- video: `${MS_2010}/video`,
1416
- audio: `${MS_2010}/audio`,
1417
- font: `${MS_2010}/font`,
1490
+ media: `${MS_2007}/media`,
1491
+ video: `${OFFICE_DOC}/video`,
1492
+ audio: `${OFFICE_DOC}/audio`,
1493
+ font: `${OFFICE_DOC}/font`,
1418
1494
  authors: `${MS_2015}/authors`,
1419
1495
  modernComment: `${MS_2015}/comments`,
1420
1496
  comments: `${OFFICE_DOC}/comments`,
@@ -1431,13 +1507,13 @@ const NAME_NOTES_MASTER_ID_LST = qname("p", "notesMasterIdLst", NS.pml);
1431
1507
  const NAME_NOTES_MASTER_ID = qname("p", "notesMasterId", NS.pml);
1432
1508
  const NAME_SLD_SZ = qname("p", "sldSz", NS.pml);
1433
1509
  const NAME_NOTES_SZ = qname("p", "notesSz", NS.pml);
1434
- const ATTR_ID$13 = qname("", "id", "");
1435
- const ATTR_R_ID$3 = qname("r", "id", NS.officeDocRels);
1510
+ const ATTR_ID$15 = qname("", "id", "");
1511
+ const ATTR_R_ID$4 = qname("r", "id", NS.officeDocRels);
1436
1512
  const ATTR_CX$9 = qname("", "cx", "");
1437
1513
  const ATTR_CY$9 = qname("", "cy", "");
1438
1514
  const ATTR_TYPE$6 = qname("", "type", "");
1439
1515
  const requireRId = (element, context) => {
1440
- const value = getAttrValue(element, ATTR_R_ID$3);
1516
+ const value = getAttrValue(element, ATTR_R_ID$4);
1441
1517
  if (value === null) throw new Error(`${context}: missing r:id attribute`);
1442
1518
  return value;
1443
1519
  };
@@ -1463,7 +1539,7 @@ const readPresentationPart = (root) => {
1463
1539
  const sldMasters = [];
1464
1540
  const sldMasterLst = firstChildElement(root, NAME_SLD_MASTER_ID_LST$1);
1465
1541
  if (sldMasterLst !== null) for (const item of allChildElements(sldMasterLst, NAME_SLD_MASTER_ID)) {
1466
- const idRaw = getAttrValue(item, ATTR_ID$13);
1542
+ const idRaw = getAttrValue(item, ATTR_ID$15);
1467
1543
  if (idRaw === null) throw new Error("<p:sldMasterId>: missing id attribute");
1468
1544
  sldMasters.push({
1469
1545
  id: Number.parseInt(idRaw, 10),
@@ -1473,7 +1549,7 @@ const readPresentationPart = (root) => {
1473
1549
  const slides = [];
1474
1550
  const sldLst = firstChildElement(root, NAME_SLD_ID_LST$2);
1475
1551
  if (sldLst !== null) for (const item of allChildElements(sldLst, NAME_SLD_ID$2)) {
1476
- const idRaw = getAttrValue(item, ATTR_ID$13);
1552
+ const idRaw = getAttrValue(item, ATTR_ID$15);
1477
1553
  if (idRaw === null) throw new Error("<p:sldId>: missing id attribute");
1478
1554
  slides.push({
1479
1555
  id: Number.parseInt(idRaw, 10),
@@ -1551,7 +1627,15 @@ const RANGES = {
1551
1627
  overlap: [-100, 100],
1552
1628
  gapAmount: [0, 500],
1553
1629
  holeSize: [1, 90],
1554
- firstSliceAng: [0, 360]
1630
+ firstSliceAng: [0, 360],
1631
+ rotX: [-90, 90],
1632
+ rotY: [0, 360],
1633
+ perspective: [0, 240],
1634
+ depthPercent: [20, 2e3],
1635
+ heightPercent: [5, 500],
1636
+ secondPieSize: [5, 200],
1637
+ bubbleScale: [0, 300],
1638
+ percent100000: [0, 1e5]
1555
1639
  };
1556
1640
  const boundedInt = (value, key, field) => {
1557
1641
  if (!Number.isFinite(value)) throw new RangeError(`${field}: expected a finite number, got ${value}`);
@@ -1598,6 +1682,310 @@ const oneOf = (value, allowed, field) => {
1598
1682
  return value;
1599
1683
  };
1600
1684
  //#endregion
1685
+ //#region src/internal/enum-values.ts
1686
+ const SHAPE_PRESETS = [
1687
+ "line",
1688
+ "lineInv",
1689
+ "triangle",
1690
+ "rtTriangle",
1691
+ "rect",
1692
+ "diamond",
1693
+ "parallelogram",
1694
+ "trapezoid",
1695
+ "nonIsoscelesTrapezoid",
1696
+ "pentagon",
1697
+ "hexagon",
1698
+ "heptagon",
1699
+ "octagon",
1700
+ "decagon",
1701
+ "dodecagon",
1702
+ "star4",
1703
+ "star5",
1704
+ "star6",
1705
+ "star7",
1706
+ "star8",
1707
+ "star10",
1708
+ "star12",
1709
+ "star16",
1710
+ "star24",
1711
+ "star32",
1712
+ "roundRect",
1713
+ "round1Rect",
1714
+ "round2SameRect",
1715
+ "round2DiagRect",
1716
+ "snipRoundRect",
1717
+ "snip1Rect",
1718
+ "snip2SameRect",
1719
+ "snip2DiagRect",
1720
+ "plaque",
1721
+ "ellipse",
1722
+ "teardrop",
1723
+ "homePlate",
1724
+ "chevron",
1725
+ "pieWedge",
1726
+ "pie",
1727
+ "blockArc",
1728
+ "donut",
1729
+ "noSmoking",
1730
+ "rightArrow",
1731
+ "leftArrow",
1732
+ "upArrow",
1733
+ "downArrow",
1734
+ "stripedRightArrow",
1735
+ "notchedRightArrow",
1736
+ "bentUpArrow",
1737
+ "leftRightArrow",
1738
+ "upDownArrow",
1739
+ "leftUpArrow",
1740
+ "leftRightUpArrow",
1741
+ "quadArrow",
1742
+ "leftArrowCallout",
1743
+ "rightArrowCallout",
1744
+ "upArrowCallout",
1745
+ "downArrowCallout",
1746
+ "leftRightArrowCallout",
1747
+ "upDownArrowCallout",
1748
+ "quadArrowCallout",
1749
+ "bentArrow",
1750
+ "uturnArrow",
1751
+ "circularArrow",
1752
+ "leftCircularArrow",
1753
+ "leftRightCircularArrow",
1754
+ "curvedRightArrow",
1755
+ "curvedLeftArrow",
1756
+ "curvedUpArrow",
1757
+ "curvedDownArrow",
1758
+ "swooshArrow",
1759
+ "cube",
1760
+ "can",
1761
+ "lightningBolt",
1762
+ "heart",
1763
+ "sun",
1764
+ "moon",
1765
+ "smileyFace",
1766
+ "irregularSeal1",
1767
+ "irregularSeal2",
1768
+ "foldedCorner",
1769
+ "bevel",
1770
+ "frame",
1771
+ "halfFrame",
1772
+ "corner",
1773
+ "diagStripe",
1774
+ "chord",
1775
+ "arc",
1776
+ "leftBracket",
1777
+ "rightBracket",
1778
+ "leftBrace",
1779
+ "rightBrace",
1780
+ "bracketPair",
1781
+ "bracePair",
1782
+ "straightConnector1",
1783
+ "bentConnector2",
1784
+ "bentConnector3",
1785
+ "bentConnector4",
1786
+ "bentConnector5",
1787
+ "curvedConnector2",
1788
+ "curvedConnector3",
1789
+ "curvedConnector4",
1790
+ "curvedConnector5",
1791
+ "callout1",
1792
+ "callout2",
1793
+ "callout3",
1794
+ "accentCallout1",
1795
+ "accentCallout2",
1796
+ "accentCallout3",
1797
+ "borderCallout1",
1798
+ "borderCallout2",
1799
+ "borderCallout3",
1800
+ "accentBorderCallout1",
1801
+ "accentBorderCallout2",
1802
+ "accentBorderCallout3",
1803
+ "wedgeRectCallout",
1804
+ "wedgeRoundRectCallout",
1805
+ "wedgeEllipseCallout",
1806
+ "cloudCallout",
1807
+ "cloud",
1808
+ "ribbon",
1809
+ "ribbon2",
1810
+ "ellipseRibbon",
1811
+ "ellipseRibbon2",
1812
+ "leftRightRibbon",
1813
+ "verticalScroll",
1814
+ "horizontalScroll",
1815
+ "wave",
1816
+ "doubleWave",
1817
+ "plus",
1818
+ "flowChartProcess",
1819
+ "flowChartDecision",
1820
+ "flowChartInputOutput",
1821
+ "flowChartPredefinedProcess",
1822
+ "flowChartInternalStorage",
1823
+ "flowChartDocument",
1824
+ "flowChartMultidocument",
1825
+ "flowChartTerminator",
1826
+ "flowChartPreparation",
1827
+ "flowChartManualInput",
1828
+ "flowChartManualOperation",
1829
+ "flowChartConnector",
1830
+ "flowChartPunchedCard",
1831
+ "flowChartPunchedTape",
1832
+ "flowChartSummingJunction",
1833
+ "flowChartOr",
1834
+ "flowChartCollate",
1835
+ "flowChartSort",
1836
+ "flowChartExtract",
1837
+ "flowChartMerge",
1838
+ "flowChartOfflineStorage",
1839
+ "flowChartOnlineStorage",
1840
+ "flowChartMagneticTape",
1841
+ "flowChartMagneticDisk",
1842
+ "flowChartMagneticDrum",
1843
+ "flowChartDisplay",
1844
+ "flowChartDelay",
1845
+ "flowChartAlternateProcess",
1846
+ "flowChartOffpageConnector",
1847
+ "actionButtonBlank",
1848
+ "actionButtonHome",
1849
+ "actionButtonHelp",
1850
+ "actionButtonInformation",
1851
+ "actionButtonForwardNext",
1852
+ "actionButtonBackPrevious",
1853
+ "actionButtonEnd",
1854
+ "actionButtonBeginning",
1855
+ "actionButtonReturn",
1856
+ "actionButtonDocument",
1857
+ "actionButtonSound",
1858
+ "actionButtonMovie",
1859
+ "gear6",
1860
+ "gear9",
1861
+ "funnel",
1862
+ "mathPlus",
1863
+ "mathMinus",
1864
+ "mathMultiply",
1865
+ "mathDivide",
1866
+ "mathEqual",
1867
+ "mathNotEqual",
1868
+ "cornerTabs",
1869
+ "squareTabs",
1870
+ "plaqueTabs",
1871
+ "chartX",
1872
+ "chartStar",
1873
+ "chartPlus"
1874
+ ];
1875
+ const LINE_DASHES = [
1876
+ "solid",
1877
+ "dot",
1878
+ "dash",
1879
+ "lgDash",
1880
+ "dashDot",
1881
+ "lgDashDot",
1882
+ "lgDashDotDot",
1883
+ "sysDash",
1884
+ "sysDot",
1885
+ "sysDashDot",
1886
+ "sysDashDotDot"
1887
+ ];
1888
+ const TEXT_DIRECTIONS = [
1889
+ "horz",
1890
+ "vert",
1891
+ "vert270",
1892
+ "wordArtVert",
1893
+ "eaVert",
1894
+ "mongolianVert",
1895
+ "wordArtVertRtl"
1896
+ ];
1897
+ const AUTO_NUMBER_SCHEMES = [
1898
+ "alphaLcParenBoth",
1899
+ "alphaUcParenBoth",
1900
+ "alphaLcParenR",
1901
+ "alphaUcParenR",
1902
+ "alphaLcPeriod",
1903
+ "alphaUcPeriod",
1904
+ "arabicParenBoth",
1905
+ "arabicParenR",
1906
+ "arabicPeriod",
1907
+ "arabicPlain",
1908
+ "romanLcParenBoth",
1909
+ "romanUcParenBoth",
1910
+ "romanLcParenR",
1911
+ "romanUcParenR",
1912
+ "romanLcPeriod",
1913
+ "romanUcPeriod",
1914
+ "circleNumDbPlain",
1915
+ "circleNumWdBlackPlain",
1916
+ "circleNumWdWhitePlain",
1917
+ "arabicDbPeriod",
1918
+ "arabicDbPlain",
1919
+ "ea1ChsPeriod",
1920
+ "ea1ChsPlain",
1921
+ "ea1ChtPeriod",
1922
+ "ea1ChtPlain",
1923
+ "ea1JpnChsDbPeriod",
1924
+ "ea1JpnKorPlain",
1925
+ "ea1JpnKorPeriod",
1926
+ "arabic1Minus",
1927
+ "arabic2Minus",
1928
+ "hebrew2Minus",
1929
+ "thaiAlphaPeriod",
1930
+ "thaiAlphaParenR",
1931
+ "thaiAlphaParenBoth",
1932
+ "thaiNumPeriod",
1933
+ "thaiNumParenR",
1934
+ "thaiNumParenBoth",
1935
+ "hindiAlphaPeriod",
1936
+ "hindiNumPeriod",
1937
+ "hindiNumParenR",
1938
+ "hindiAlpha1Period"
1939
+ ];
1940
+ const UNDERLINES = [
1941
+ "none",
1942
+ "words",
1943
+ "sng",
1944
+ "dbl",
1945
+ "heavy",
1946
+ "dotted",
1947
+ "dottedHeavy",
1948
+ "dash",
1949
+ "dashHeavy",
1950
+ "dashLong",
1951
+ "dashLongHeavy",
1952
+ "dotDash",
1953
+ "dotDashHeavy",
1954
+ "dotDotDash",
1955
+ "dotDotDashHeavy",
1956
+ "wavy",
1957
+ "wavyHeavy",
1958
+ "wavyDbl"
1959
+ ];
1960
+ const STRIKES = [
1961
+ "noStrike",
1962
+ "sngStrike",
1963
+ "dblStrike"
1964
+ ];
1965
+ const SLIDE_SIZE_TYPES = [
1966
+ "screen4x3",
1967
+ "letter",
1968
+ "A4",
1969
+ "35mm",
1970
+ "overhead",
1971
+ "banner",
1972
+ "custom",
1973
+ "ledger",
1974
+ "A3",
1975
+ "B4ISO",
1976
+ "B5ISO",
1977
+ "B4JIS",
1978
+ "B5JIS",
1979
+ "hagakiCard",
1980
+ "screen16x9",
1981
+ "screen16x10"
1982
+ ];
1983
+ const TEXT_ANCHORS = {
1984
+ top: "t",
1985
+ center: "ctr",
1986
+ bottom: "b"
1987
+ };
1988
+ //#endregion
1601
1989
  //#region src/internal/drawingml/color.ts
1602
1990
  const NAME_SRGB_CLR$4 = qname("a", "srgbClr", NS.dml);
1603
1991
  const NAME_SCHEME_CLR$2 = qname("a", "schemeClr", NS.dml);
@@ -1754,8 +2142,21 @@ const setHighlight = (rPr, value) => {
1754
2142
  if (parsed === null) throw new Error(`unrecognized highlight color: ${value}`);
1755
2143
  insertChildByRank(rPr, elem(NAME_HIGHLIGHT, { children: [parsed.kind === "srgb" ? elem(NAME_SRGB_CLR$3, { attrs: [attr(ATTR_VAL$8, parsed.hex)] }) : elem(NAME_SCHEME_CLR$1, { attrs: [attr(ATTR_VAL$8, parsed.token)] })] }), rprChildRank);
1756
2144
  };
2145
+ const validateFormatEnums = (format, caller) => {
2146
+ if (format.underline != null && typeof format.underline !== "boolean") oneOf(format.underline, UNDERLINES, `${caller}: underline`);
2147
+ if (format.strike != null && typeof format.strike !== "boolean") oneOf(format.strike, STRIKES, `${caller}: strike`);
2148
+ if (format.cap != null) oneOf(format.cap, [
2149
+ "none",
2150
+ "small",
2151
+ "all"
2152
+ ], `${caller}: cap`);
2153
+ };
1757
2154
  /** Mutates `rPr` in place per `format`. */
1758
- const applyRunFormat = (rPr, format) => {
2155
+ const applyRunFormat = (rPr, format, caller = "setShapeRunFormat") => {
2156
+ validateFormatEnums(format, caller);
2157
+ applyValidatedRunFormat(rPr, format);
2158
+ };
2159
+ const applyValidatedRunFormat = (rPr, format) => {
1759
2160
  let attrs = rPr.attrs;
1760
2161
  if (format.size !== void 0) {
1761
2162
  const sz = fontSizeHundredthPt(format.size * 100, "setShapeRunFormat: size");
@@ -1793,7 +2194,11 @@ const applyRunFormat = (rPr, format) => {
1793
2194
  * supplied format. Existing run-property attributes not addressed by
1794
2195
  * `format` are preserved.
1795
2196
  */
1796
- const applyFormatToAllRuns = (txBody, format) => {
2197
+ const applyFormatToAllRuns = (txBody, format, caller = "setShapeTextFormat") => {
2198
+ validateFormatEnums(format, caller);
2199
+ applyValidatedFormatToAllRuns(txBody, format);
2200
+ };
2201
+ const applyValidatedFormatToAllRuns = (txBody, format) => {
1797
2202
  for (const p of txBody.children) {
1798
2203
  if (p.kind !== "element" || p.name.namespaceURI !== NS.dml || p.name.localName !== "p") continue;
1799
2204
  for (const r of p.children) {
@@ -1803,7 +2208,7 @@ const applyFormatToAllRuns = (txBody, format) => {
1803
2208
  rPr = elem(NAME_RPR$6);
1804
2209
  r.children.unshift(rPr);
1805
2210
  }
1806
- applyRunFormat(rPr, format);
2211
+ applyValidatedRunFormat(rPr, format);
1807
2212
  }
1808
2213
  }
1809
2214
  };
@@ -1942,7 +2347,12 @@ const replaceTextInTree = (root, from, to) => {
1942
2347
  });
1943
2348
  return count;
1944
2349
  };
1945
- const normalizeBulletStyle = (s) => {
2350
+ const normalizeBulletStyle = (s, caller) => {
2351
+ if (typeof s === "string") oneOf(s, [
2352
+ "bullet",
2353
+ "number",
2354
+ "none"
2355
+ ], `${caller}: bullets`);
1946
2356
  if (s === "bullet") return {
1947
2357
  kind: "char",
1948
2358
  char: "•"
@@ -1958,11 +2368,10 @@ const normalizeBulletStyle = (s) => {
1958
2368
  };
1959
2369
  return {
1960
2370
  kind: "autoNum",
1961
- type: s.autoNum
2371
+ type: oneOf(s.autoNum, AUTO_NUMBER_SCHEMES, `${caller}: bullets.autoNum`)
1962
2372
  };
1963
2373
  };
1964
- const buildBulletElement = (style) => {
1965
- const n = normalizeBulletStyle(style);
2374
+ const buildBulletElement = (n) => {
1966
2375
  switch (n.kind) {
1967
2376
  case "char": return elem(NAME_BU_CHAR, { attrs: [attr(ATTR_CHAR, n.char)] });
1968
2377
  case "autoNum": return elem(NAME_BU_AUTO_NUM, { attrs: [attr(ATTR_START_AT, "1"), attr(ATTR_BU_TYPE, n.type)] });
@@ -1971,7 +2380,21 @@ const buildBulletElement = (style) => {
1971
2380
  };
1972
2381
  const NAME_PPR_FOR_BULLET = qname("a", "pPr", NS.dml);
1973
2382
  const NAME_P_FOR_BULLET = qname("a", "p", NS.dml);
1974
- const alignToken = (a) => {
2383
+ const alignToken = (a, caller) => {
2384
+ oneOf(a, [
2385
+ "left",
2386
+ "center",
2387
+ "right",
2388
+ "justify",
2389
+ "distribute",
2390
+ "l",
2391
+ "ctr",
2392
+ "r",
2393
+ "just",
2394
+ "dist",
2395
+ "justLow",
2396
+ "thaiDist"
2397
+ ], `${caller}: align`);
1975
2398
  switch (a) {
1976
2399
  case "left":
1977
2400
  case "l": return "l";
@@ -1991,8 +2414,10 @@ const ATTR_ALGN$1 = qname("", "algn", "");
1991
2414
  * Sets `<a:pPr algn="...">` on every paragraph in `txBody`. Existing
1992
2415
  * pPr attributes other than `algn` are preserved.
1993
2416
  */
1994
- const applyAlignmentToAllParagraphs = (txBody, align) => {
1995
- const token = alignToken(align);
2417
+ const applyAlignmentToAllParagraphs = (txBody, align, caller = "setShapeAlignment") => {
2418
+ applyAlignmentTokenToAllParagraphs(txBody, alignToken(align, caller));
2419
+ };
2420
+ const applyAlignmentTokenToAllParagraphs = (txBody, token) => {
1996
2421
  for (const p of txBody.children) {
1997
2422
  if (p.kind !== "element" || p.name.namespaceURI !== NAME_P_FOR_BULLET.namespaceURI || p.name.localName !== "p") continue;
1998
2423
  let pPr = firstChildElement(p, NAME_PPR_FOR_BULLET);
@@ -2034,32 +2459,39 @@ const BULLET_INDENT_BY_LEVEL = [
2034
2459
  const bulletIndentForLevel = (lvl) => BULLET_INDENT_BY_LEVEL[Math.min(lvl, BULLET_INDENT_BY_LEVEL.length - 1)];
2035
2460
  const ATTR_MAR_L$1 = qname("", "marL", "");
2036
2461
  const ATTR_INDENT$1 = qname("", "indent", "");
2462
+ const updateBulletIndentForLevel = (pPr, previousLevel, level) => {
2463
+ const previous = bulletIndentForLevel(previousLevel);
2464
+ const marL = pPr.attrs.find((a) => a.name.namespaceURI === "" && a.name.localName === "marL");
2465
+ const indent = pPr.attrs.find((a) => a.name.namespaceURI === "" && a.name.localName === "indent");
2466
+ if (marL?.value !== String(previous.marL) || indent?.value !== String(previous.indent)) return;
2467
+ const next = bulletIndentForLevel(level);
2468
+ pPr.attrs = pPr.attrs.map((a) => a === marL ? attr(a.name, String(next.marL)) : a === indent ? attr(a.name, String(next.indent)) : a);
2469
+ };
2037
2470
  const hasAttr = (el, local) => el.attrs.some((a) => a.name.namespaceURI === "" && a.name.localName === local);
2038
- const applyBulletToParagraph = (paragraph, style) => {
2471
+ const applyNormalizedBullet = (paragraph, style) => {
2039
2472
  let pPr = firstChildElement(paragraph, NAME_PPR_FOR_BULLET);
2040
2473
  if (pPr === null) {
2041
2474
  pPr = elem(NAME_PPR_FOR_BULLET);
2042
2475
  paragraph.children.unshift(pPr);
2043
2476
  }
2044
2477
  pPr.children = pPr.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.dml && (c.name.localName === "buChar" || c.name.localName === "buAutoNum" || c.name.localName === "buNone" || c.name.localName === "buFont")));
2045
- if (style !== "none") {
2478
+ if (style.kind !== "none") {
2046
2479
  const lvl = Number.parseInt(pPr.attrs.find((a) => a.name.localName === "lvl")?.value ?? "0", 10);
2047
2480
  const { marL, indent } = bulletIndentForLevel(Number.isFinite(lvl) ? lvl : 0);
2048
2481
  if (!hasAttr(pPr, "marL")) pPr.attrs.push(attr(ATTR_MAR_L$1, String(marL)));
2049
2482
  if (!hasAttr(pPr, "indent")) pPr.attrs.push(attr(ATTR_INDENT$1, String(indent)));
2050
2483
  }
2051
- if (normalizeBulletStyle(style).kind === "autoNum") pPr.children.push(elem(NAME_BU_FONT, { attrs: [attr(ATTR_TYPEFACE$2, "+mj-lt")] }));
2484
+ if (style.kind === "autoNum") pPr.children.push(elem(NAME_BU_FONT, { attrs: [attr(ATTR_TYPEFACE$2, "+mj-lt")] }));
2052
2485
  pPr.children.push(buildBulletElement(style));
2053
2486
  };
2054
- /**
2055
- * Sets the bullet style on every paragraph in `txBody`. Drops any
2056
- * existing bullet child element (`a:buChar`, `a:buAutoNum`, `a:buNone`)
2057
- * before inserting the new one. Creates `<a:pPr>` if absent.
2058
- */
2487
+ const applyBulletToParagraph = (paragraph, style) => {
2488
+ applyNormalizedBullet(paragraph, normalizeBulletStyle(style, "setParagraphBullet"));
2489
+ };
2059
2490
  const applyBulletToAllParagraphs = (txBody, style) => {
2491
+ const normalized = normalizeBulletStyle(style, "setShapeBullets");
2060
2492
  for (const p of txBody.children) {
2061
2493
  if (p.kind !== "element" || p.name.namespaceURI !== NAME_P_FOR_BULLET.namespaceURI || p.name.localName !== "p") continue;
2062
- applyBulletToParagraph(p, style);
2494
+ applyNormalizedBullet(p, normalized);
2063
2495
  }
2064
2496
  };
2065
2497
  /**
@@ -2075,7 +2507,8 @@ const applyBulletToAllParagraphs = (txBody, style) => {
2075
2507
  *
2076
2508
  * The `bodyPr` and `lstStyle` children (if any) are preserved untouched.
2077
2509
  */
2078
- const setTextBody = (txBody, value) => {
2510
+ const setTextBody = (txBody, value, bullets) => {
2511
+ const normalized = bullets === void 0 ? void 0 : normalizeBulletStyle(bullets, "setShapeText");
2079
2512
  const rPrTemplate = findFirstRunProperties(txBody);
2080
2513
  const pPrTemplate = findFirstParagraphProperties(txBody);
2081
2514
  removeAllParagraphs(txBody);
@@ -2084,6 +2517,7 @@ const setTextBody = (txBody, value) => {
2084
2517
  const t = elem(NAME_T$5, { children: line.length > 0 ? [text(line)] : [] });
2085
2518
  const r = elem(NAME_R$4, { children: rPrTemplate !== null ? [cloneElement(rPrTemplate), t] : [t] });
2086
2519
  const p = elem(NAME_P$5, { children: pPrTemplate !== null ? [cloneElement(pPrTemplate), r] : [r] });
2520
+ if (normalized !== void 0) applyNormalizedBullet(p, normalized);
2087
2521
  txBody.children.push(p);
2088
2522
  }
2089
2523
  };
@@ -2092,21 +2526,21 @@ const setTextBody = (txBody, value) => {
2092
2526
  * here, so a caller that builds before it touches the tree leaves the
2093
2527
  * existing text intact when a value is rejected.
2094
2528
  */
2095
- const buildTextBodyParagraphs = (paragraphs) => {
2529
+ const buildTextBodyParagraphs = (paragraphs, caller = "setShapeParagraphs") => {
2096
2530
  if (paragraphs.length === 0) throw new Error("setTextBodyParagraphs: at least one paragraph is required");
2097
2531
  const built = [];
2098
2532
  for (const para of paragraphs) {
2099
2533
  const children = [];
2100
- if (para.align !== void 0) children.push(elem(NAME_PPR$1, { attrs: [attr(ATTR_ALGN$1, alignToken(para.align))] }));
2534
+ if (para.align !== void 0) children.push(elem(NAME_PPR$1, { attrs: [attr(ATTR_ALGN$1, alignToken(para.align, caller))] }));
2101
2535
  for (const run of para.runs) {
2102
2536
  const rPr = elem(NAME_RPR$5);
2103
- if (run.format !== void 0) applyRunFormat(rPr, run.format);
2537
+ if (run.format !== void 0) applyRunFormat(rPr, run.format, caller);
2104
2538
  const t = elem(NAME_T$5, { children: run.text.length > 0 ? [text(run.text)] : [] });
2105
2539
  children.push(elem(NAME_R$4, { children: [rPr, t] }));
2106
2540
  }
2107
2541
  if (para.endFormat !== void 0) {
2108
2542
  const endParaRPr = elem(NAME_END_PARA_RPR);
2109
- applyRunFormat(endParaRPr, para.endFormat);
2543
+ applyRunFormat(endParaRPr, para.endFormat, caller);
2110
2544
  children.push(endParaRPr);
2111
2545
  }
2112
2546
  built.push(elem(NAME_P$5, { children }));
@@ -2266,6 +2700,12 @@ const setPatternFill = (host, options) => {
2266
2700
  };
2267
2701
  /** Sets `<a:gradFill>` on `host`, replacing any previous fill choice. */
2268
2702
  const setGradientFill = (host, options) => {
2703
+ if (options.path !== void 0) oneOf(options.path, [
2704
+ "linear",
2705
+ "circle",
2706
+ "rect",
2707
+ "shape"
2708
+ ], "setShapeGradientFill: path");
2269
2709
  if (options.stops.length < 2) throw new Error("gradient fill requires at least two stops");
2270
2710
  removeAnyFill(host);
2271
2711
  const stops = options.stops.map((s) => {
@@ -2450,6 +2890,7 @@ const ATTR_VAL$6 = qname("", "val", "");
2450
2890
  * `<a:ln>` if absent. Replacing the dash choice on subsequent calls.
2451
2891
  */
2452
2892
  const setStrokeDash = (spPr, dash) => {
2893
+ oneOf(dash, LINE_DASHES, "setShapeStrokeDash: dash");
2453
2894
  const ln = ensureLn(spPr);
2454
2895
  ln.children = ln.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.dml && c.name.localName === "prstDash"));
2455
2896
  insertLnChild(ln, elem(NAME_PRST_DASH, { attrs: [attr(ATTR_VAL$6, dash)] }));
@@ -2467,8 +2908,30 @@ const ATTR_LEN = qname("", "len", "");
2467
2908
  * behavior).
2468
2909
  */
2469
2910
  const setStrokeArrow = (spPr, end, options) => {
2911
+ oneOf(end, ["head", "tail"], "setShapeStrokeArrow: end");
2912
+ oneOf(options.type, [
2913
+ "none",
2914
+ "triangle",
2915
+ "stealth",
2916
+ "diamond",
2917
+ "oval",
2918
+ "arrow"
2919
+ ], "setShapeStrokeArrow: type");
2920
+ if (options.width !== void 0) oneOf(options.width, [
2921
+ "sm",
2922
+ "med",
2923
+ "lg"
2924
+ ], "setShapeStrokeArrow: width");
2925
+ if (options.length !== void 0) oneOf(options.length, [
2926
+ "sm",
2927
+ "med",
2928
+ "lg"
2929
+ ], "setShapeStrokeArrow: length");
2470
2930
  const ln = ensureLn(spPr);
2471
- const localName = end === "head" ? "headEnd" : "tailEnd";
2931
+ const localName = {
2932
+ head: "headEnd",
2933
+ tail: "tailEnd"
2934
+ }[end];
2472
2935
  ln.children = ln.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.dml && c.name.localName === localName));
2473
2936
  const attrs = [attr(ATTR_TYPE$5, options.type)];
2474
2937
  if (options.width !== void 0) attrs.push(attr(ATTR_W$3, options.width));
@@ -2477,6 +2940,11 @@ const setStrokeArrow = (spPr, end, options) => {
2477
2940
  };
2478
2941
  /** Sets `<a:ln cap="…"/>`. Pass `null` to clear the attribute. */
2479
2942
  const setStrokeCap = (spPr, cap) => {
2943
+ if (cap !== null) oneOf(cap, [
2944
+ "rnd",
2945
+ "sq",
2946
+ "flat"
2947
+ ], "setShapeStrokeCap: cap");
2480
2948
  const ln = ensureLn(spPr);
2481
2949
  ln.attrs = ln.attrs.filter((a) => !(a.name.namespaceURI === "" && a.name.localName === "cap"));
2482
2950
  if (cap !== null) ln.attrs.push(attr(qname("", "cap", ""), cap));
@@ -2488,12 +2956,24 @@ const JOIN_LOCALS = new Set([
2488
2956
  ]);
2489
2957
  /** Replaces the join child of `<a:ln>`. Pass `null` to remove it. */
2490
2958
  const setStrokeJoin = (spPr, join) => {
2959
+ if (join !== null) oneOf(join, [
2960
+ "round",
2961
+ "bevel",
2962
+ "miter"
2963
+ ], "setShapeStrokeJoin: join");
2491
2964
  const ln = ensureLn(spPr);
2492
2965
  removeChildrenIn(ln, JOIN_LOCALS);
2493
2966
  if (join !== null) insertLnChild(ln, elem(qname("a", join, NS.dml)));
2494
2967
  };
2495
2968
  /** Sets `<a:ln cmpd="…"/>`. Pass `null` to clear the attribute. */
2496
2969
  const setStrokeCompound = (spPr, cmpd) => {
2970
+ if (cmpd !== null) oneOf(cmpd, [
2971
+ "sng",
2972
+ "dbl",
2973
+ "thickThin",
2974
+ "thinThick",
2975
+ "tri"
2976
+ ], "setShapeStrokeCompound: cmpd");
2497
2977
  const ln = ensureLn(spPr);
2498
2978
  ln.attrs = ln.attrs.filter((a) => !(a.name.namespaceURI === "" && a.name.localName === "cmpd"));
2499
2979
  if (cmpd !== null) ln.attrs.push(attr(qname("", "cmpd", ""), cmpd));
@@ -2518,7 +2998,7 @@ const ATTR_WR = qname("", "wR", "");
2518
2998
  const ATTR_HR = qname("", "hR", "");
2519
2999
  const ATTR_ST_ANG = qname("", "stAng", "");
2520
3000
  const ATTR_SW_ANG = qname("", "swAng", "");
2521
- const ATTR_FILL$1 = qname("", "fill", "");
3001
+ const ATTR_FILL$2 = qname("", "fill", "");
2522
3002
  const ATTR_STROKE = qname("", "stroke", "");
2523
3003
  const NAME_AV_LST$5 = qname("a", "avLst", NS.dml);
2524
3004
  const NAME_GD_LST = qname("a", "gdLst", NS.dml);
@@ -2667,7 +3147,7 @@ const isPathFillMode = (s) => FILL_MODES.has(s);
2667
3147
  const parsePath = (pathEl, guides) => {
2668
3148
  const w = parseIntOrNull(getAttrValue(pathEl, ATTR_W$2));
2669
3149
  const h = parseIntOrNull(getAttrValue(pathEl, ATTR_H$1));
2670
- const fillRaw = getAttrValue(pathEl, ATTR_FILL$1);
3150
+ const fillRaw = getAttrValue(pathEl, ATTR_FILL$2);
2671
3151
  const fill = fillRaw !== null && isPathFillMode(fillRaw) ? fillRaw : "norm";
2672
3152
  const strokeRaw = getAttrValue(pathEl, ATTR_STROKE);
2673
3153
  const stroke = !(strokeRaw === "0" || strokeRaw === "false");
@@ -2760,8 +3240,8 @@ const parseCustomGeometry = (custGeom, shapeW, shapeH) => {
2760
3240
  //#region src/internal/drawingml/hyperlink.ts
2761
3241
  NS.dml;
2762
3242
  const NAME_RPR$4 = qname("a", "rPr", NS.dml);
2763
- const NAME_HLINK_CLICK = qname("a", "hlinkClick", NS.dml);
2764
- const ATTR_R_ID$2 = qname("r", "id", NS.officeDocRels);
3243
+ const NAME_HLINK_CLICK$1 = qname("a", "hlinkClick", NS.dml);
3244
+ const ATTR_R_ID$3 = qname("r", "id", NS.officeDocRels);
2765
3245
  /**
2766
3246
  * Sets `<a:hlinkClick r:id="rIdN" [tooltip="…"]/>` inside the `<a:rPr>`
2767
3247
  * of every run in `txBody`. Pass `null` for `rId` to remove an existing
@@ -2781,9 +3261,9 @@ const applyHyperlinkToAllRuns = (txBody, rId, tooltip) => {
2781
3261
  }
2782
3262
  rPr.children = rPr.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.dml && c.name.localName === "hlinkClick"));
2783
3263
  if (rId !== null) {
2784
- const attrs = [attr(ATTR_R_ID$2, rId)];
3264
+ const attrs = [attr(ATTR_R_ID$3, rId)];
2785
3265
  if (tooltip !== void 0) attrs.push(attr(qname("", "tooltip", ""), tooltip));
2786
- rPr.children.push(elem(NAME_HLINK_CLICK, { attrs }));
3266
+ rPr.children.push(elem(NAME_HLINK_CLICK$1, { attrs }));
2787
3267
  }
2788
3268
  }
2789
3269
  }
@@ -2792,7 +3272,7 @@ const applyHyperlinkToAllRuns = (txBody, rId, tooltip) => {
2792
3272
  //#region src/internal/drawingml/picture-mutation.ts
2793
3273
  const NAME_BLIP_FILL$1 = qname("p", "blipFill", NS.pml);
2794
3274
  const NAME_BLIP$1 = qname("a", "blip", NS.dml);
2795
- const ATTR_R_EMBED$1 = qname("r", "embed", NS.officeDocRels);
3275
+ const ATTR_R_EMBED$2 = qname("r", "embed", NS.officeDocRels);
2796
3276
  /**
2797
3277
  * Returns the `r:embed` rId on this picture shape's `a:blip`. Returns null
2798
3278
  * if the shape has no blip fill, no blip, or no embed attribute (which
@@ -2803,7 +3283,7 @@ const getPictureEmbedRId = (picElement) => {
2803
3283
  if (blipFill === null) return null;
2804
3284
  const blip = firstChildElement(blipFill, NAME_BLIP$1);
2805
3285
  if (blip === null) return null;
2806
- return getAttrValue(blip, ATTR_R_EMBED$1);
3286
+ return getAttrValue(blip, ATTR_R_EMBED$2);
2807
3287
  };
2808
3288
  //#endregion
2809
3289
  //#region src/internal/drawingml/geometry.ts
@@ -2812,7 +3292,7 @@ const NAME_GRP_SP_PR$4 = qname("p", "grpSpPr", NS.pml);
2812
3292
  const NAME_A_XFRM$6 = qname("a", "xfrm", NS.dml);
2813
3293
  const NAME_P_XFRM$2 = qname("p", "xfrm", NS.pml);
2814
3294
  const NAME_OFF$8 = qname("a", "off", NS.dml);
2815
- const NAME_EXT$8 = qname("a", "ext", NS.dml);
3295
+ const NAME_EXT$9 = qname("a", "ext", NS.dml);
2816
3296
  const ATTR_X$8 = qname("", "x", "");
2817
3297
  const ATTR_Y$8 = qname("", "y", "");
2818
3298
  const ATTR_CX$8 = qname("", "cx", "");
@@ -2853,7 +3333,7 @@ const readPosition = (shape, kind) => {
2853
3333
  const readSize = (shape, kind) => {
2854
3334
  const xfrm = findTransform(shape, kind);
2855
3335
  if (xfrm === null) return null;
2856
- const ext = firstChildElement(xfrm, NAME_EXT$8);
3336
+ const ext = firstChildElement(xfrm, NAME_EXT$9);
2857
3337
  if (ext === null) return null;
2858
3338
  const w = parseIntOr(getAttrValue(ext, ATTR_CX$8));
2859
3339
  const h = parseIntOr(getAttrValue(ext, ATTR_CY$8));
@@ -2893,7 +3373,7 @@ const NAME_GRP_SP_PR$3 = qname("p", "grpSpPr", NS.pml);
2893
3373
  const NAME_A_XFRM$5 = qname("a", "xfrm", NS.dml);
2894
3374
  const NAME_P_XFRM$1 = qname("p", "xfrm", NS.pml);
2895
3375
  const NAME_OFF$7 = qname("a", "off", NS.dml);
2896
- const NAME_EXT$7 = qname("a", "ext", NS.dml);
3376
+ const NAME_EXT$8 = qname("a", "ext", NS.dml);
2897
3377
  const ATTR_X$7 = qname("", "x", "");
2898
3378
  const ATTR_Y$7 = qname("", "y", "");
2899
3379
  const ATTR_CX$7 = qname("", "cx", "");
@@ -2939,9 +3419,9 @@ const setPosition = (shape, kind, x, y) => {
2939
3419
  /** Sets the shape's `<a:ext>` to `(w, h)` in EMU. */
2940
3420
  const setSize = (shape, kind, w, h) => {
2941
3421
  const xfrm = ensureTransform(shape, kind);
2942
- let ext = firstChildElement(xfrm, NAME_EXT$7);
3422
+ let ext = firstChildElement(xfrm, NAME_EXT$8);
2943
3423
  if (ext === null) {
2944
- ext = elem(NAME_EXT$7);
3424
+ ext = elem(NAME_EXT$8);
2945
3425
  const offIdx = xfrm.children.findIndex((c) => c.kind === "element" && c.name.localName === "off" && c.name.namespaceURI === NS.dml);
2946
3426
  if (offIdx >= 0) xfrm.children.splice(offIdx + 1, 0, ext);
2947
3427
  else xfrm.children.push(ext);
@@ -3013,21 +3493,21 @@ const setAdjustValues = (shape, values) => {
3013
3493
  const NAME_CSLD$4 = qname("p", "cSld", NS.pml);
3014
3494
  const NAME_SP_TREE$3 = qname("p", "spTree", NS.pml);
3015
3495
  const NAME_NV_SP_PR$4 = qname("p", "nvSpPr", NS.pml);
3016
- const NAME_NV_PIC_PR$1 = qname("p", "nvPicPr", NS.pml);
3496
+ const NAME_NV_PIC_PR$2 = qname("p", "nvPicPr", NS.pml);
3017
3497
  const NAME_NV_GRP_SP_PR$3 = qname("p", "nvGrpSpPr", NS.pml);
3018
3498
  const NAME_NV_GRAPHIC_FRAME_PR$2 = qname("p", "nvGraphicFramePr", NS.pml);
3019
3499
  const NAME_NV_CXN_SP_PR$1 = qname("p", "nvCxnSpPr", NS.pml);
3020
- const NAME_C_NV_PR$8 = qname("p", "cNvPr", NS.pml);
3021
- const NAME_NV_PR$9 = qname("p", "nvPr", NS.pml);
3500
+ const NAME_C_NV_PR$9 = qname("p", "cNvPr", NS.pml);
3501
+ const NAME_NV_PR$10 = qname("p", "nvPr", NS.pml);
3022
3502
  const NAME_PH$2 = qname("p", "ph", NS.pml);
3023
3503
  const NAME_TX_BODY$9 = qname("p", "txBody", NS.pml);
3024
- const ATTR_ID$12 = qname("", "id", "");
3504
+ const ATTR_ID$14 = qname("", "id", "");
3025
3505
  const ATTR_NAME$11 = qname("", "name", "");
3026
3506
  const ATTR_TYPE$4 = qname("", "type", "");
3027
3507
  const ATTR_IDX$6 = qname("", "idx", "");
3028
3508
  const NV_BY_KIND = {
3029
3509
  shape: NAME_NV_SP_PR$4,
3030
- picture: NAME_NV_PIC_PR$1,
3510
+ picture: NAME_NV_PIC_PR$2,
3031
3511
  group: NAME_NV_GRP_SP_PR$3,
3032
3512
  graphicFrame: NAME_NV_GRAPHIC_FRAME_PR$2,
3033
3513
  connector: NAME_NV_CXN_SP_PR$1
@@ -3050,14 +3530,14 @@ const extractShape = (element, kind) => {
3050
3530
  let placeholderType = null;
3051
3531
  let placeholderIdx = null;
3052
3532
  if (nvContainer !== null) {
3053
- const cNvPr = firstChildElement(nvContainer, NAME_C_NV_PR$8);
3533
+ const cNvPr = firstChildElement(nvContainer, NAME_C_NV_PR$9);
3054
3534
  if (cNvPr !== null) {
3055
- const idRaw = getAttrValue(cNvPr, ATTR_ID$12);
3535
+ const idRaw = getAttrValue(cNvPr, ATTR_ID$14);
3056
3536
  if (idRaw !== null) id = Number.parseInt(idRaw, 10);
3057
3537
  const nameRaw = getAttrValue(cNvPr, ATTR_NAME$11);
3058
3538
  if (nameRaw !== null) name = nameRaw;
3059
3539
  }
3060
- const nvPr = firstChildElement(nvContainer, NAME_NV_PR$9);
3540
+ const nvPr = firstChildElement(nvContainer, NAME_NV_PR$10);
3061
3541
  if (nvPr !== null) {
3062
3542
  const ph = firstChildElement(nvPr, NAME_PH$2);
3063
3543
  if (ph !== null) {
@@ -3165,9 +3645,9 @@ const NAME_SLD = qname("p", "sld", NS.pml);
3165
3645
  const NAME_CSLD$2 = qname("p", "cSld", NS.pml);
3166
3646
  const NAME_SP_TREE$2 = qname("p", "spTree", NS.pml);
3167
3647
  const NAME_NV_GRP_SP_PR$2 = qname("p", "nvGrpSpPr", NS.pml);
3168
- const NAME_C_NV_PR$7 = qname("p", "cNvPr", NS.pml);
3648
+ const NAME_C_NV_PR$8 = qname("p", "cNvPr", NS.pml);
3169
3649
  const NAME_C_NV_GRP_SP_PR$2 = qname("p", "cNvGrpSpPr", NS.pml);
3170
- const NAME_NV_PR$8 = qname("p", "nvPr", NS.pml);
3650
+ const NAME_NV_PR$9 = qname("p", "nvPr", NS.pml);
3171
3651
  const NAME_GRP_SP_PR$2 = qname("p", "grpSpPr", NS.pml);
3172
3652
  const NAME_SP$3 = qname("p", "sp", NS.pml);
3173
3653
  const NAME_NV_SP_PR$3 = qname("p", "nvSpPr", NS.pml);
@@ -3179,7 +3659,7 @@ const NAME_BODY_PR$4 = qname("a", "bodyPr", NS.dml);
3179
3659
  const NAME_LST_STYLE$4 = qname("a", "lstStyle", NS.dml);
3180
3660
  const NAME_P$4 = qname("a", "p", NS.dml);
3181
3661
  const NAME_SP_LOCKS$1 = qname("a", "spLocks", NS.dml);
3182
- const ATTR_ID$11 = qname("", "id", "");
3662
+ const ATTR_ID$13 = qname("", "id", "");
3183
3663
  const ATTR_NAME$9 = qname("", "name", "");
3184
3664
  const ATTR_TYPE$2 = qname("", "type", "");
3185
3665
  const ATTR_IDX$5 = qname("", "idx", "");
@@ -3200,7 +3680,7 @@ const buildSlideFromLayout = (layoutSpTree) => {
3200
3680
  if (child.name.namespaceURI !== NS.pml || child.name.localName !== "sp") continue;
3201
3681
  const nvSpPr = firstChildElement(child, NAME_NV_SP_PR$3);
3202
3682
  if (nvSpPr === null) continue;
3203
- const nvPr = firstChildElement(nvSpPr, NAME_NV_PR$8);
3683
+ const nvPr = firstChildElement(nvSpPr, NAME_NV_PR$9);
3204
3684
  if (nvPr === null) continue;
3205
3685
  const ph = firstChildElement(nvPr, NAME_PH$1);
3206
3686
  if (ph === null) continue;
@@ -3240,21 +3720,21 @@ const buildSlideFromLayout = (layoutSpTree) => {
3240
3720
  };
3241
3721
  };
3242
3722
  const buildNvGrpSpPr = (id) => elem(NAME_NV_GRP_SP_PR$2, { children: [
3243
- elem(NAME_C_NV_PR$7, { attrs: [attr(ATTR_ID$11, String(id)), attr(ATTR_NAME$9, "")] }),
3723
+ elem(NAME_C_NV_PR$8, { attrs: [attr(ATTR_ID$13, String(id)), attr(ATTR_NAME$9, "")] }),
3244
3724
  elem(NAME_C_NV_GRP_SP_PR$2),
3245
- elem(NAME_NV_PR$8)
3725
+ elem(NAME_NV_PR$9)
3246
3726
  ] });
3247
3727
  const buildGrpSpPr = () => elem(NAME_GRP_SP_PR$2);
3248
3728
  const buildPlaceholderStub = (id, phType, phIdx) => {
3249
3729
  const phAttrs = [];
3250
3730
  if (phType !== null) phAttrs.push(attr(ATTR_TYPE$2, phType));
3251
3731
  if (phIdx !== null) phAttrs.push(attr(ATTR_IDX$5, phIdx));
3252
- const nvPr = elem(NAME_NV_PR$8, { children: [elem(NAME_PH$1, { attrs: phAttrs })] });
3732
+ const nvPr = elem(NAME_NV_PR$9, { children: [elem(NAME_PH$1, { attrs: phAttrs })] });
3253
3733
  const cNvSpPr = elem(NAME_C_NV_SP_PR$3, { children: [elem(NAME_SP_LOCKS$1, { attrs: [attr(ATTR_NO_GRP$2, "1")] })] });
3254
3734
  const name = inferPlaceholderName(id, phType);
3255
3735
  return elem(NAME_SP$3, { children: [
3256
3736
  elem(NAME_NV_SP_PR$3, { children: [
3257
- elem(NAME_C_NV_PR$7, { attrs: [attr(ATTR_ID$11, String(id)), attr(ATTR_NAME$9, name)] }),
3737
+ elem(NAME_C_NV_PR$8, { attrs: [attr(ATTR_ID$13, String(id)), attr(ATTR_NAME$9, name)] }),
3258
3738
  cNvSpPr,
3259
3739
  nvPr
3260
3740
  ] }),
@@ -3290,14 +3770,14 @@ const inferPlaceholderName = (id, phType) => {
3290
3770
  //#region src/internal/presentationml/text-box-builder.ts
3291
3771
  const NAME_SP$2 = qname("p", "sp", NS.pml);
3292
3772
  const NAME_NV_SP_PR$2 = qname("p", "nvSpPr", NS.pml);
3293
- const NAME_C_NV_PR$6 = qname("p", "cNvPr", NS.pml);
3773
+ const NAME_C_NV_PR$7 = qname("p", "cNvPr", NS.pml);
3294
3774
  const NAME_C_NV_SP_PR$2 = qname("p", "cNvSpPr", NS.pml);
3295
- const NAME_NV_PR$7 = qname("p", "nvPr", NS.pml);
3775
+ const NAME_NV_PR$8 = qname("p", "nvPr", NS.pml);
3296
3776
  const NAME_SP_PR$4 = qname("p", "spPr", NS.pml);
3297
3777
  const NAME_TX_BODY$7 = qname("p", "txBody", NS.pml);
3298
3778
  const NAME_A_XFRM$4 = qname("a", "xfrm", NS.dml);
3299
3779
  const NAME_OFF$6 = qname("a", "off", NS.dml);
3300
- const NAME_EXT$6 = qname("a", "ext", NS.dml);
3780
+ const NAME_EXT$7 = qname("a", "ext", NS.dml);
3301
3781
  const NAME_PRST_GEOM$3 = qname("a", "prstGeom", NS.dml);
3302
3782
  const NAME_AV_LST$3 = qname("a", "avLst", NS.dml);
3303
3783
  const NAME_NO_FILL = qname("a", "noFill", NS.dml);
@@ -3307,7 +3787,7 @@ const NAME_P$3 = qname("a", "p", NS.dml);
3307
3787
  const NAME_R$3 = qname("a", "r", NS.dml);
3308
3788
  const NAME_RPR$3 = qname("a", "rPr", NS.dml);
3309
3789
  const NAME_T$4 = qname("a", "t", NS.dml);
3310
- const ATTR_ID$10 = qname("", "id", "");
3790
+ const ATTR_ID$12 = qname("", "id", "");
3311
3791
  const ATTR_NAME$8 = qname("", "name", "");
3312
3792
  const ATTR_TX_BOX$1 = qname("", "txBox", "");
3313
3793
  const ATTR_X$6 = qname("", "x", "");
@@ -3328,12 +3808,12 @@ NS.xml;
3328
3808
  const buildTextBox = (opts) => {
3329
3809
  const name = opts.name ?? `TextBox ${opts.id}`;
3330
3810
  const nvSpPr = elem(NAME_NV_SP_PR$2, { children: [
3331
- elem(NAME_C_NV_PR$6, { attrs: [attr(ATTR_ID$10, String(opts.id)), attr(ATTR_NAME$8, name)] }),
3811
+ elem(NAME_C_NV_PR$7, { attrs: [attr(ATTR_ID$12, String(opts.id)), attr(ATTR_NAME$8, name)] }),
3332
3812
  elem(NAME_C_NV_SP_PR$2, { attrs: [attr(ATTR_TX_BOX$1, "1")] }),
3333
- elem(NAME_NV_PR$7)
3813
+ elem(NAME_NV_PR$8)
3334
3814
  ] });
3335
3815
  const spPr = elem(NAME_SP_PR$4, { children: [
3336
- elem(NAME_A_XFRM$4, { children: [elem(NAME_OFF$6, { attrs: [attr(ATTR_X$6, String(emuCoordinate(opts.x, "addSlideTextBox: x"))), attr(ATTR_Y$6, String(emuCoordinate(opts.y, "addSlideTextBox: y")))] }), elem(NAME_EXT$6, { attrs: [attr(ATTR_CX$6, String(emuExtent(opts.w, "addSlideTextBox: w"))), attr(ATTR_CY$6, String(emuExtent(opts.h, "addSlideTextBox: h")))] })] }),
3816
+ elem(NAME_A_XFRM$4, { children: [elem(NAME_OFF$6, { attrs: [attr(ATTR_X$6, String(emuCoordinate(opts.x, "addSlideTextBox: x"))), attr(ATTR_Y$6, String(emuCoordinate(opts.y, "addSlideTextBox: y")))] }), elem(NAME_EXT$7, { attrs: [attr(ATTR_CX$6, String(emuExtent(opts.w, "addSlideTextBox: w"))), attr(ATTR_CY$6, String(emuExtent(opts.h, "addSlideTextBox: h")))] })] }),
3337
3817
  elem(NAME_PRST_GEOM$3, {
3338
3818
  attrs: [attr(ATTR_PRST$3, "rect")],
3339
3819
  children: [elem(NAME_AV_LST$3)]
@@ -3358,14 +3838,14 @@ const buildTextBox = (opts) => {
3358
3838
  //#region src/internal/presentationml/shape-builder.ts
3359
3839
  const NAME_SP$1 = qname("p", "sp", NS.pml);
3360
3840
  const NAME_NV_SP_PR$1 = qname("p", "nvSpPr", NS.pml);
3361
- const NAME_C_NV_PR$5 = qname("p", "cNvPr", NS.pml);
3841
+ const NAME_C_NV_PR$6 = qname("p", "cNvPr", NS.pml);
3362
3842
  const NAME_C_NV_SP_PR$1 = qname("p", "cNvSpPr", NS.pml);
3363
- const NAME_NV_PR$6 = qname("p", "nvPr", NS.pml);
3843
+ const NAME_NV_PR$7 = qname("p", "nvPr", NS.pml);
3364
3844
  const NAME_SP_PR$3 = qname("p", "spPr", NS.pml);
3365
3845
  const NAME_TX_BODY$6 = qname("p", "txBody", NS.pml);
3366
3846
  const NAME_A_XFRM$3 = qname("a", "xfrm", NS.dml);
3367
3847
  const NAME_OFF$5 = qname("a", "off", NS.dml);
3368
- const NAME_EXT$5 = qname("a", "ext", NS.dml);
3848
+ const NAME_EXT$6 = qname("a", "ext", NS.dml);
3369
3849
  const NAME_PRST_GEOM$2 = qname("a", "prstGeom", NS.dml);
3370
3850
  const NAME_AV_LST$2 = qname("a", "avLst", NS.dml);
3371
3851
  const NAME_BODY_PR$2 = qname("a", "bodyPr", NS.dml);
@@ -3374,7 +3854,7 @@ const NAME_P$2 = qname("a", "p", NS.dml);
3374
3854
  const NAME_R$2 = qname("a", "r", NS.dml);
3375
3855
  const NAME_RPR$2 = qname("a", "rPr", NS.dml);
3376
3856
  const NAME_T$3 = qname("a", "t", NS.dml);
3377
- const ATTR_ID$9 = qname("", "id", "");
3857
+ const ATTR_ID$11 = qname("", "id", "");
3378
3858
  const ATTR_NAME$7 = qname("", "name", "");
3379
3859
  const ATTR_X$5 = qname("", "x", "");
3380
3860
  const ATTR_Y$5 = qname("", "y", "");
@@ -3403,13 +3883,19 @@ const buildTextBody = (text$1, anchor) => {
3403
3883
  ] });
3404
3884
  };
3405
3885
  const buildShape = (opts) => {
3886
+ oneOf(opts.preset, SHAPE_PRESETS, "addSlideShape: preset");
3887
+ if (opts.textAnchor !== void 0) oneOf(opts.textAnchor, [
3888
+ "t",
3889
+ "ctr",
3890
+ "b"
3891
+ ], "addSlideShape: textAnchor");
3406
3892
  const name = opts.name ?? `${opts.preset} ${opts.id}`;
3407
3893
  const anchor = opts.textAnchor ?? "ctr";
3408
3894
  const children = [elem(NAME_NV_SP_PR$1, { children: [
3409
- elem(NAME_C_NV_PR$5, { attrs: [attr(ATTR_ID$9, String(opts.id)), attr(ATTR_NAME$7, name)] }),
3895
+ elem(NAME_C_NV_PR$6, { attrs: [attr(ATTR_ID$11, String(opts.id)), attr(ATTR_NAME$7, name)] }),
3410
3896
  elem(NAME_C_NV_SP_PR$1),
3411
- elem(NAME_NV_PR$6)
3412
- ] }), elem(NAME_SP_PR$3, { children: [elem(NAME_A_XFRM$3, { children: [elem(NAME_OFF$5, { attrs: [attr(ATTR_X$5, String(emuCoordinate(opts.x, "addSlideShape: x"))), attr(ATTR_Y$5, String(emuCoordinate(opts.y, "addSlideShape: y")))] }), elem(NAME_EXT$5, { attrs: [attr(ATTR_CX$5, String(emuExtent(opts.w, "addSlideShape: w"))), attr(ATTR_CY$5, String(emuExtent(opts.h, "addSlideShape: h")))] })] }), elem(NAME_PRST_GEOM$2, {
3897
+ elem(NAME_NV_PR$7)
3898
+ ] }), elem(NAME_SP_PR$3, { children: [elem(NAME_A_XFRM$3, { children: [elem(NAME_OFF$5, { attrs: [attr(ATTR_X$5, String(emuCoordinate(opts.x, "addSlideShape: x"))), attr(ATTR_Y$5, String(emuCoordinate(opts.y, "addSlideShape: y")))] }), elem(NAME_EXT$6, { attrs: [attr(ATTR_CX$5, String(emuExtent(opts.w, "addSlideShape: w"))), attr(ATTR_CY$5, String(emuExtent(opts.h, "addSlideShape: h")))] })] }), elem(NAME_PRST_GEOM$2, {
3413
3899
  attrs: [attr(ATTR_PRST$2, opts.preset)],
3414
3900
  children: [elem(NAME_AV_LST$2)]
3415
3901
  })] })];
@@ -3421,13 +3907,13 @@ const buildShape = (opts) => {
3421
3907
  //#region src/internal/presentationml/connector-builder.ts
3422
3908
  const NAME_CXN_SP = qname("p", "cxnSp", NS.pml);
3423
3909
  const NAME_NV_CXN_SP_PR = qname("p", "nvCxnSpPr", NS.pml);
3424
- const NAME_C_NV_PR$4 = qname("p", "cNvPr", NS.pml);
3910
+ const NAME_C_NV_PR$5 = qname("p", "cNvPr", NS.pml);
3425
3911
  const NAME_C_NV_CXN_SP_PR = qname("p", "cNvCxnSpPr", NS.pml);
3426
- const NAME_NV_PR$5 = qname("p", "nvPr", NS.pml);
3912
+ const NAME_NV_PR$6 = qname("p", "nvPr", NS.pml);
3427
3913
  const NAME_SP_PR$2 = qname("p", "spPr", NS.pml);
3428
3914
  const NAME_A_XFRM$2 = qname("a", "xfrm", NS.dml);
3429
3915
  const NAME_OFF$4 = qname("a", "off", NS.dml);
3430
- const NAME_EXT$4 = qname("a", "ext", NS.dml);
3916
+ const NAME_EXT$5 = qname("a", "ext", NS.dml);
3431
3917
  const NAME_PRST_GEOM$1 = qname("a", "prstGeom", NS.dml);
3432
3918
  const NAME_AV_LST$1 = qname("a", "avLst", NS.dml);
3433
3919
  const NAME_LN = qname("a", "ln", NS.dml);
@@ -3440,7 +3926,7 @@ const NAME_FONT_REF = qname("a", "fontRef", NS.dml);
3440
3926
  const NAME_SCHEME_CLR = qname("a", "schemeClr", NS.dml);
3441
3927
  const ATTR_IDX$4 = qname("", "idx", "");
3442
3928
  const ATTR_VAL$5 = qname("", "val", "");
3443
- const ATTR_ID$8 = qname("", "id", "");
3929
+ const ATTR_ID$10 = qname("", "id", "");
3444
3930
  const ATTR_NAME$6 = qname("", "name", "");
3445
3931
  const ATTR_X$4 = qname("", "x", "");
3446
3932
  const ATTR_Y$4 = qname("", "y", "");
@@ -3454,9 +3940,9 @@ const ATTR_FLIP_V = qname("", "flipV", "");
3454
3940
  const buildConnector = (opts) => {
3455
3941
  const name = opts.name ?? `Straight Connector ${opts.id}`;
3456
3942
  const nvCxnSpPr = elem(NAME_NV_CXN_SP_PR, { children: [
3457
- elem(NAME_C_NV_PR$4, { attrs: [attr(ATTR_ID$8, String(opts.id)), attr(ATTR_NAME$6, name)] }),
3943
+ elem(NAME_C_NV_PR$5, { attrs: [attr(ATTR_ID$10, String(opts.id)), attr(ATTR_NAME$6, name)] }),
3458
3944
  elem(NAME_C_NV_CXN_SP_PR),
3459
- elem(NAME_NV_PR$5)
3945
+ elem(NAME_NV_PR$6)
3460
3946
  ] });
3461
3947
  const x = Math.min(opts.from.x, opts.to.x);
3462
3948
  const y = Math.min(opts.from.y, opts.to.y);
@@ -3469,7 +3955,7 @@ const buildConnector = (opts) => {
3469
3955
  if (flipV) xfrmAttrs.push(attr(ATTR_FLIP_V, "1"));
3470
3956
  const xfrm = elem(NAME_A_XFRM$2, {
3471
3957
  attrs: xfrmAttrs,
3472
- children: [elem(NAME_OFF$4, { attrs: [attr(ATTR_X$4, String(emuCoordinate(x, "addSlideLine: x"))), attr(ATTR_Y$4, String(emuCoordinate(y, "addSlideLine: y")))] }), elem(NAME_EXT$4, { attrs: [attr(ATTR_CX$4, String(emuExtent(cx, "addSlideLine: width"))), attr(ATTR_CY$4, String(emuExtent(cy, "addSlideLine: height")))] })]
3958
+ children: [elem(NAME_OFF$4, { attrs: [attr(ATTR_X$4, String(emuCoordinate(x, "addSlideLine: x"))), attr(ATTR_Y$4, String(emuCoordinate(y, "addSlideLine: y")))] }), elem(NAME_EXT$5, { attrs: [attr(ATTR_CX$4, String(emuExtent(cx, "addSlideLine: width"))), attr(ATTR_CY$4, String(emuExtent(cy, "addSlideLine: height")))] })]
3473
3959
  });
3474
3960
  const prstGeom = elem(NAME_PRST_GEOM$1, {
3475
3961
  attrs: [attr(ATTR_PRST$1, "line")],
@@ -3503,16 +3989,16 @@ const buildConnector = (opts) => {
3503
3989
  //#region src/internal/presentationml/group-builder.ts
3504
3990
  const NAME_GRP_SP = qname("p", "grpSp", NS.pml);
3505
3991
  const NAME_NV_GRP_SP_PR$1 = qname("p", "nvGrpSpPr", NS.pml);
3506
- const NAME_C_NV_PR$3 = qname("p", "cNvPr", NS.pml);
3992
+ const NAME_C_NV_PR$4 = qname("p", "cNvPr", NS.pml);
3507
3993
  const NAME_C_NV_GRP_SP_PR$1 = qname("p", "cNvGrpSpPr", NS.pml);
3508
- const NAME_NV_PR$4 = qname("p", "nvPr", NS.pml);
3994
+ const NAME_NV_PR$5 = qname("p", "nvPr", NS.pml);
3509
3995
  const NAME_GRP_SP_PR$1 = qname("p", "grpSpPr", NS.pml);
3510
3996
  const NAME_A_XFRM$1 = qname("a", "xfrm", NS.dml);
3511
3997
  const NAME_OFF$3 = qname("a", "off", NS.dml);
3512
- const NAME_EXT$3 = qname("a", "ext", NS.dml);
3998
+ const NAME_EXT$4 = qname("a", "ext", NS.dml);
3513
3999
  const NAME_CH_OFF = qname("a", "chOff", NS.dml);
3514
4000
  const NAME_CH_EXT = qname("a", "chExt", NS.dml);
3515
- const ATTR_ID$7 = qname("", "id", "");
4001
+ const ATTR_ID$9 = qname("", "id", "");
3516
4002
  const ATTR_NAME$5 = qname("", "name", "");
3517
4003
  const ATTR_X$3 = qname("", "x", "");
3518
4004
  const ATTR_Y$3 = qname("", "y", "");
@@ -3522,9 +4008,9 @@ const ATTR_CY$3 = qname("", "cy", "");
3522
4008
  const buildGroup = (opts) => {
3523
4009
  const name = opts.name ?? `Group ${opts.id}`;
3524
4010
  const nvGrpSpPr = elem(NAME_NV_GRP_SP_PR$1, { children: [
3525
- elem(NAME_C_NV_PR$3, { attrs: [attr(ATTR_ID$7, String(opts.id)), attr(ATTR_NAME$5, name)] }),
4011
+ elem(NAME_C_NV_PR$4, { attrs: [attr(ATTR_ID$9, String(opts.id)), attr(ATTR_NAME$5, name)] }),
3526
4012
  elem(NAME_C_NV_GRP_SP_PR$1),
3527
- elem(NAME_NV_PR$4)
4013
+ elem(NAME_NV_PR$5)
3528
4014
  ] });
3529
4015
  const x = emuCoordinate(opts.x, "groupShapes: x");
3530
4016
  const y = emuCoordinate(opts.y, "groupShapes: y");
@@ -3534,7 +4020,7 @@ const buildGroup = (opts) => {
3534
4020
  nvGrpSpPr,
3535
4021
  elem(NAME_GRP_SP_PR$1, { children: [elem(NAME_A_XFRM$1, { children: [
3536
4022
  elem(NAME_OFF$3, { attrs: [attr(ATTR_X$3, String(x)), attr(ATTR_Y$3, String(y))] }),
3537
- elem(NAME_EXT$3, { attrs: [attr(ATTR_CX$3, String(cx)), attr(ATTR_CY$3, String(cy))] }),
4023
+ elem(NAME_EXT$4, { attrs: [attr(ATTR_CX$3, String(cx)), attr(ATTR_CY$3, String(cy))] }),
3538
4024
  elem(NAME_CH_OFF, { attrs: [attr(ATTR_X$3, String(x)), attr(ATTR_Y$3, String(y))] }),
3539
4025
  elem(NAME_CH_EXT, { attrs: [attr(ATTR_CX$3, String(cx)), attr(ATTR_CY$3, String(cy))] })
3540
4026
  ] })] }),
@@ -3544,10 +4030,10 @@ const buildGroup = (opts) => {
3544
4030
  //#endregion
3545
4031
  //#region src/internal/presentationml/picture-builder.ts
3546
4032
  const NAME_PIC = qname("p", "pic", NS.pml);
3547
- const NAME_NV_PIC_PR = qname("p", "nvPicPr", NS.pml);
3548
- const NAME_C_NV_PR$2 = qname("p", "cNvPr", NS.pml);
4033
+ const NAME_NV_PIC_PR$1 = qname("p", "nvPicPr", NS.pml);
4034
+ const NAME_C_NV_PR$3 = qname("p", "cNvPr", NS.pml);
3549
4035
  const NAME_C_NV_PIC_PR = qname("p", "cNvPicPr", NS.pml);
3550
- const NAME_NV_PR$3 = qname("p", "nvPr", NS.pml);
4036
+ const NAME_NV_PR$4 = qname("p", "nvPr", NS.pml);
3551
4037
  const NAME_BLIP_FILL = qname("p", "blipFill", NS.pml);
3552
4038
  const NAME_BLIP = qname("a", "blip", NS.dml);
3553
4039
  const NAME_STRETCH = qname("a", "stretch", NS.dml);
@@ -3555,37 +4041,175 @@ const NAME_FILL_RECT = qname("a", "fillRect", NS.dml);
3555
4041
  const NAME_SP_PR$1 = qname("p", "spPr", NS.pml);
3556
4042
  const NAME_A_XFRM = qname("a", "xfrm", NS.dml);
3557
4043
  const NAME_OFF$2 = qname("a", "off", NS.dml);
3558
- const NAME_EXT$2 = qname("a", "ext", NS.dml);
4044
+ const NAME_EXT$3 = qname("a", "ext", NS.dml);
3559
4045
  const NAME_PRST_GEOM = qname("a", "prstGeom", NS.dml);
3560
4046
  const NAME_AV_LST = qname("a", "avLst", NS.dml);
3561
4047
  const NAME_PIC_LOCKS = qname("a", "picLocks", NS.dml);
3562
- const ATTR_ID$6 = qname("", "id", "");
4048
+ const ATTR_ID$8 = qname("", "id", "");
3563
4049
  const ATTR_NAME$4 = qname("", "name", "");
3564
4050
  const ATTR_X$2 = qname("", "x", "");
3565
4051
  const ATTR_Y$2 = qname("", "y", "");
3566
4052
  const ATTR_CX$2 = qname("", "cx", "");
3567
4053
  const ATTR_CY$2 = qname("", "cy", "");
3568
4054
  const ATTR_PRST = qname("", "prst", "");
3569
- const ATTR_R_EMBED = qname("r", "embed", NS.officeDocRels);
4055
+ const ATTR_R_EMBED$1 = qname("r", "embed", NS.officeDocRels);
3570
4056
  const ATTR_NO_CHANGE_ASPECT$1 = qname("", "noChangeAspect", "");
3571
4057
  /** Returns a `<p:pic>` element ready to be appended to a slide's `<p:spTree>`. */
3572
4058
  const buildPicture = (opts) => {
3573
4059
  const name = opts.name ?? `Picture ${opts.id}`;
3574
4060
  const cNvPicPr = elem(NAME_C_NV_PIC_PR, { children: [elem(NAME_PIC_LOCKS, { attrs: opts.lockAspect ?? true ? [attr(ATTR_NO_CHANGE_ASPECT$1, "1")] : [] })] });
3575
4061
  return elem(NAME_PIC, { children: [
3576
- elem(NAME_NV_PIC_PR, { children: [
3577
- elem(NAME_C_NV_PR$2, { attrs: [attr(ATTR_ID$6, String(opts.id)), attr(ATTR_NAME$4, name)] }),
4062
+ elem(NAME_NV_PIC_PR$1, { children: [
4063
+ elem(NAME_C_NV_PR$3, { attrs: [attr(ATTR_ID$8, String(opts.id)), attr(ATTR_NAME$4, name)] }),
3578
4064
  cNvPicPr,
3579
- elem(NAME_NV_PR$3)
4065
+ elem(NAME_NV_PR$4)
3580
4066
  ] }),
3581
- elem(NAME_BLIP_FILL, { children: [elem(NAME_BLIP, { attrs: [attr(ATTR_R_EMBED, opts.rEmbed)] }), elem(NAME_STRETCH, { children: [elem(NAME_FILL_RECT)] })] }),
3582
- elem(NAME_SP_PR$1, { children: [elem(NAME_A_XFRM, { children: [elem(NAME_OFF$2, { attrs: [attr(ATTR_X$2, String(emuCoordinate(opts.x, "addSlideImage: x"))), attr(ATTR_Y$2, String(emuCoordinate(opts.y, "addSlideImage: y")))] }), elem(NAME_EXT$2, { attrs: [attr(ATTR_CX$2, String(emuExtent(opts.w, "addSlideImage: w"))), attr(ATTR_CY$2, String(emuExtent(opts.h, "addSlideImage: h")))] })] }), elem(NAME_PRST_GEOM, {
4067
+ elem(NAME_BLIP_FILL, { children: [elem(NAME_BLIP, { attrs: [attr(ATTR_R_EMBED$1, opts.rEmbed)] }), elem(NAME_STRETCH, { children: [elem(NAME_FILL_RECT)] })] }),
4068
+ elem(NAME_SP_PR$1, { children: [elem(NAME_A_XFRM, { children: [elem(NAME_OFF$2, { attrs: [attr(ATTR_X$2, String(emuCoordinate(opts.x, "addSlideImage: x"))), attr(ATTR_Y$2, String(emuCoordinate(opts.y, "addSlideImage: y")))] }), elem(NAME_EXT$3, { attrs: [attr(ATTR_CX$2, String(emuExtent(opts.w, "addSlideImage: w"))), attr(ATTR_CY$2, String(emuExtent(opts.h, "addSlideImage: h")))] })] }), elem(NAME_PRST_GEOM, {
3583
4069
  attrs: [attr(ATTR_PRST, "rect")],
3584
4070
  children: [elem(NAME_AV_LST)]
3585
4071
  })] })
3586
4072
  ] });
3587
4073
  };
3588
4074
  //#endregion
4075
+ //#region src/internal/presentationml/media-builder.ts
4076
+ const NAME_NV_PIC_PR = qname("p", "nvPicPr", NS.pml);
4077
+ const NAME_C_NV_PR$2 = qname("p", "cNvPr", NS.pml);
4078
+ const NAME_NV_PR$3 = qname("p", "nvPr", NS.pml);
4079
+ const NAME_HLINK_CLICK = qname("a", "hlinkClick", NS.dml);
4080
+ const NAME_VIDEO_FILE = qname("a", "videoFile", NS.dml);
4081
+ const NAME_AUDIO_FILE = qname("a", "audioFile", NS.dml);
4082
+ const NAME_EXT_LST$2 = qname("p", "extLst", NS.pml);
4083
+ const NAME_EXT$2 = qname("p", "ext", NS.pml);
4084
+ const NAME_P14_MEDIA = qname("p14", "media", NS.p14);
4085
+ const NAME_TIMING$2 = qname("p", "timing", NS.pml);
4086
+ const NAME_TN_LST$2 = qname("p", "tnLst", NS.pml);
4087
+ const NAME_PAR$2 = qname("p", "par", NS.pml);
4088
+ const NAME_C_TN$2 = qname("p", "cTn", NS.pml);
4089
+ const NAME_CHILD_TN_LST$2 = qname("p", "childTnLst", NS.pml);
4090
+ const NAME_VIDEO = qname("p", "video", NS.pml);
4091
+ const NAME_AUDIO = qname("p", "audio", NS.pml);
4092
+ const NAME_C_MEDIA_NODE = qname("p", "cMediaNode", NS.pml);
4093
+ const NAME_ST_COND_LST$1 = qname("p", "stCondLst", NS.pml);
4094
+ const NAME_COND$1 = qname("p", "cond", NS.pml);
4095
+ const NAME_TGT_EL$1 = qname("p", "tgtEl", NS.pml);
4096
+ const NAME_SP_TGT$1 = qname("p", "spTgt", NS.pml);
4097
+ const ATTR_R_ID$2 = qname("r", "id", NS.officeDocRels);
4098
+ const ATTR_R_LINK = qname("r", "link", NS.officeDocRels);
4099
+ const ATTR_R_EMBED = qname("r", "embed", NS.officeDocRels);
4100
+ const ATTR_ACTION = qname("", "action", "");
4101
+ const ATTR_URI$2 = qname("", "uri", "");
4102
+ const ATTR_ID$7 = qname("", "id", "");
4103
+ const ATTR_DUR$1 = qname("", "dur", "");
4104
+ const ATTR_RESTART$1 = qname("", "restart", "");
4105
+ const ATTR_NODE_TYPE$1 = qname("", "nodeType", "");
4106
+ const ATTR_VOL = qname("", "vol", "");
4107
+ const ATTR_FILL$1 = qname("", "fill", "");
4108
+ const ATTR_DISPLAY = qname("", "display", "");
4109
+ const ATTR_DELAY$1 = qname("", "delay", "");
4110
+ const ATTR_SPID$1 = qname("", "spid", "");
4111
+ const MEDIA_ACTION = "ppaction://media";
4112
+ const P14_MEDIA_EXT_URI = "{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}";
4113
+ const DEFAULT_MEDIA_VOLUME = "80000";
4114
+ /** Returns a media `<p:pic>`; `opts.rEmbed` is the poster image relationship. */
4115
+ const buildMediaPicture = (opts) => {
4116
+ const pic = buildPicture(opts);
4117
+ const nvPicPr = firstChildElement(pic, NAME_NV_PIC_PR);
4118
+ const cNvPr = firstChildElement(nvPicPr, NAME_C_NV_PR$2);
4119
+ const nvPr = firstChildElement(nvPicPr, NAME_NV_PR$3);
4120
+ cNvPr.children.push(elem(NAME_HLINK_CLICK, { attrs: [attr(ATTR_R_ID$2, ""), attr(ATTR_ACTION, MEDIA_ACTION)] }));
4121
+ nvPr.children.push(elem(opts.kind === "video" ? NAME_VIDEO_FILE : NAME_AUDIO_FILE, { attrs: [attr(ATTR_R_LINK, opts.rLink)] }));
4122
+ if (opts.rMedia !== void 0) {
4123
+ const media = elem(NAME_P14_MEDIA, {
4124
+ attrs: [attr(ATTR_R_EMBED, opts.rMedia)],
4125
+ prefixDecls: new Map([["p14", NS.p14]])
4126
+ });
4127
+ const ext = elem(NAME_EXT$2, {
4128
+ attrs: [attr(ATTR_URI$2, P14_MEDIA_EXT_URI)],
4129
+ children: [media]
4130
+ });
4131
+ nvPr.children.push(elem(NAME_EXT_LST$2, { children: [ext] }));
4132
+ }
4133
+ return pic;
4134
+ };
4135
+ /** Returns the `<p:video>` / `<p:audio>` time node that targets shape `spid`. */
4136
+ const buildMediaTimingNode = (kind, spid, cTnId) => {
4137
+ const cTn = elem(NAME_C_TN$2, {
4138
+ attrs: [
4139
+ attr(ATTR_ID$7, String(cTnId)),
4140
+ attr(ATTR_FILL$1, "hold"),
4141
+ attr(ATTR_DISPLAY, "0")
4142
+ ],
4143
+ children: [elem(NAME_ST_COND_LST$1, { children: [elem(NAME_COND$1, { attrs: [attr(ATTR_DELAY$1, "indefinite")] })] })]
4144
+ });
4145
+ const tgtEl = elem(NAME_TGT_EL$1, { children: [elem(NAME_SP_TGT$1, { attrs: [attr(ATTR_SPID$1, String(spid))] })] });
4146
+ const cMediaNode = elem(NAME_C_MEDIA_NODE, {
4147
+ attrs: [attr(ATTR_VOL, DEFAULT_MEDIA_VOLUME)],
4148
+ children: [cTn, tgtEl]
4149
+ });
4150
+ return elem(kind === "video" ? NAME_VIDEO : NAME_AUDIO, { children: [cMediaNode] });
4151
+ };
4152
+ /**
4153
+ * Returns a `<p:timing>` holding only the root time node, with `nodes` as its
4154
+ * children. `nodes` must be non-empty (`<p:childTnLst>` requires a child).
4155
+ */
4156
+ const buildTimingRoot = (nodes) => {
4157
+ return elem(NAME_TIMING$2, { children: [elem(NAME_TN_LST$2, { children: [elem(NAME_PAR$2, { children: [elem(NAME_C_TN$2, {
4158
+ attrs: [
4159
+ attr(ATTR_ID$7, "1"),
4160
+ attr(ATTR_DUR$1, "indefinite"),
4161
+ attr(ATTR_RESTART$1, "never"),
4162
+ attr(ATTR_NODE_TYPE$1, "tmRoot")
4163
+ ],
4164
+ children: [elem(NAME_CHILD_TN_LST$2, { children: [...nodes] })]
4165
+ })] })] })] });
4166
+ };
4167
+ /** `true` for a `<p:video>` / `<p:audio>` time node. */
4168
+ const isMediaTimingNode = (el) => el.name.namespaceURI === NS.pml && (el.name.localName === "video" || el.name.localName === "audio");
4169
+ /** Shape id a media time node targets, or `null` when it has no `<p:spTgt>`. */
4170
+ const mediaTimingNodeTarget = (node) => {
4171
+ const cMediaNode = firstChildElement(node, NAME_C_MEDIA_NODE);
4172
+ const tgtEl = cMediaNode ? firstChildElement(cMediaNode, NAME_TGT_EL$1) : null;
4173
+ const spTgt = tgtEl ? firstChildElement(tgtEl, NAME_SP_TGT$1) : null;
4174
+ const raw = spTgt ? getAttrValue(spTgt, ATTR_SPID$1) : null;
4175
+ if (raw === null) return null;
4176
+ const spid = Number.parseInt(raw, 10);
4177
+ return Number.isFinite(spid) ? spid : null;
4178
+ };
4179
+ const MEDIA_FILE_ELEMENTS = {
4180
+ videoFile: "video",
4181
+ quickTimeFile: "video",
4182
+ audioFile: "audio",
4183
+ wavAudioFile: "audio"
4184
+ };
4185
+ /** Reads the media reference off a `<p:pic>`, or `null` for a plain picture. */
4186
+ const readPictureMediaRef = (pic) => {
4187
+ const nvPicPr = firstChildElement(pic, NAME_NV_PIC_PR);
4188
+ const nvPr = nvPicPr ? firstChildElement(nvPicPr, NAME_NV_PR$3) : null;
4189
+ if (!nvPr) return null;
4190
+ for (const child of nvPr.children) {
4191
+ if (child.kind !== "element" || child.name.namespaceURI !== NS.dml) continue;
4192
+ const kind = MEDIA_FILE_ELEMENTS[child.name.localName];
4193
+ if (kind === void 0) continue;
4194
+ return {
4195
+ kind,
4196
+ fileRId: child.name.localName === "wavAudioFile" ? getAttrValue(child, ATTR_R_EMBED) : getAttrValue(child, ATTR_R_LINK),
4197
+ mediaRId: readP14MediaRId(nvPr)
4198
+ };
4199
+ }
4200
+ return null;
4201
+ };
4202
+ const readP14MediaRId = (nvPr) => {
4203
+ const extLst = firstChildElement(nvPr, NAME_EXT_LST$2);
4204
+ if (!extLst) return null;
4205
+ for (const ext of extLst.children) {
4206
+ if (ext.kind !== "element") continue;
4207
+ const media = firstChildElement(ext, NAME_P14_MEDIA);
4208
+ if (media) return getAttrValue(media, ATTR_R_EMBED);
4209
+ }
4210
+ return null;
4211
+ };
4212
+ //#endregion
3589
4213
  //#region src/internal/presentationml/table-builder.ts
3590
4214
  const TABLE_URI = "http://schemas.openxmlformats.org/drawingml/2006/table";
3591
4215
  const DEFAULT_TABLE_STYLE_ID = "{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}";
@@ -3625,7 +4249,7 @@ const ATTR_MAR_R = qname("", "marR", "");
3625
4249
  const ATTR_MAR_T = qname("", "marT", "");
3626
4250
  const ATTR_MAR_B = qname("", "marB", "");
3627
4251
  const ATTR_INDENT = qname("", "indent", "");
3628
- const ATTR_ID$5 = qname("", "id", "");
4252
+ const ATTR_ID$6 = qname("", "id", "");
3629
4253
  const ATTR_NAME$3 = qname("", "name", "");
3630
4254
  const ATTR_NO_GRP$1 = qname("", "noGrp", "");
3631
4255
  const ATTR_X$1 = qname("", "x", "");
@@ -3701,7 +4325,7 @@ const buildTable = (opts) => {
3701
4325
  if (rowHeights.length !== rows.length) throw new Error(`addSlideTable: rowHeights has ${rowHeights.length} entries; expected ${rows.length}`);
3702
4326
  const name = opts.name ?? `Table ${opts.id}`;
3703
4327
  const nvGraphicFramePr = elem(NAME_NV_GRAPHIC_FRAME_PR$1, { children: [
3704
- elem(NAME_C_NV_PR$1, { attrs: [attr(ATTR_ID$5, String(opts.id)), attr(ATTR_NAME$3, name)] }),
4328
+ elem(NAME_C_NV_PR$1, { attrs: [attr(ATTR_ID$6, String(opts.id)), attr(ATTR_NAME$3, name)] }),
3705
4329
  elem(NAME_C_NV_GRAPHIC_FRAME_PR$1, { children: [elem(NAME_GRAPHIC_FRAME_LOCKS, { attrs: [attr(ATTR_NO_GRP$1, "1")] })] }),
3706
4330
  elem(NAME_NV_PR$2)
3707
4331
  ] });
@@ -3749,7 +4373,7 @@ const NAME_R = qname("a", "r", NS.dml);
3749
4373
  const NAME_RPR = qname("a", "rPr", NS.dml);
3750
4374
  const NAME_T$1 = qname("a", "t", NS.dml);
3751
4375
  const NAME_SP_LOCKS = qname("a", "spLocks", NS.dml);
3752
- const ATTR_ID$4 = qname("", "id", "");
4376
+ const ATTR_ID$5 = qname("", "id", "");
3753
4377
  const ATTR_NAME$2 = qname("", "name", "");
3754
4378
  const ATTR_NO_GRP = qname("", "noGrp", "");
3755
4379
  const ATTR_NO_ROT = qname("", "noRot", "");
@@ -3759,14 +4383,14 @@ const ATTR_IDX$3 = qname("", "idx", "");
3759
4383
  const ATTR_LANG = qname("", "lang", "");
3760
4384
  const buildRootGroup = () => {
3761
4385
  return elem(NAME_NV_GRP_SP_PR, { children: [
3762
- elem(NAME_C_NV_PR, { attrs: [attr(ATTR_ID$4, "1"), attr(ATTR_NAME$2, "")] }),
4386
+ elem(NAME_C_NV_PR, { attrs: [attr(ATTR_ID$5, "1"), attr(ATTR_NAME$2, "")] }),
3763
4387
  elem(NAME_C_NV_GRP_SP_PR),
3764
4388
  elem(NAME_NV_PR$1)
3765
4389
  ] });
3766
4390
  };
3767
4391
  const buildSldImgPlaceholder = (id) => {
3768
4392
  return elem(NAME_SP, { children: [elem(NAME_NV_SP_PR, { children: [
3769
- elem(NAME_C_NV_PR, { attrs: [attr(ATTR_ID$4, String(id)), attr(ATTR_NAME$2, `Slide Image Placeholder ${id - 1}`)] }),
4393
+ elem(NAME_C_NV_PR, { attrs: [attr(ATTR_ID$5, String(id)), attr(ATTR_NAME$2, `Slide Image Placeholder ${id - 1}`)] }),
3770
4394
  elem(NAME_C_NV_SP_PR, { children: [elem(NAME_SP_LOCKS, { attrs: [
3771
4395
  attr(ATTR_NO_GRP, "1"),
3772
4396
  attr(ATTR_NO_ROT, "1"),
@@ -3783,7 +4407,7 @@ const buildNotesParagraphs = (notes) => {
3783
4407
  };
3784
4408
  const buildNotesBodyPlaceholder = (id, notes) => {
3785
4409
  const nvSpPr = elem(NAME_NV_SP_PR, { children: [
3786
- elem(NAME_C_NV_PR, { attrs: [attr(ATTR_ID$4, String(id)), attr(ATTR_NAME$2, `Notes Placeholder ${id - 1}`)] }),
4410
+ elem(NAME_C_NV_PR, { attrs: [attr(ATTR_ID$5, String(id)), attr(ATTR_NAME$2, `Notes Placeholder ${id - 1}`)] }),
3787
4411
  elem(NAME_C_NV_SP_PR, { children: [elem(NAME_SP_LOCKS, { attrs: [attr(ATTR_NO_GRP, "1")] })] }),
3788
4412
  elem(NAME_NV_PR$1, { children: [elem(NAME_PH, { attrs: [attr(ATTR_TYPE$1, "body"), attr(ATTR_IDX$3, "1")] })] })
3789
4413
  ] });
@@ -3903,12 +4527,20 @@ const buildEffectElement = (opts) => {
3903
4527
  attrs.push(attr(ATTR_DIR, opts.direction));
3904
4528
  }
3905
4529
  }
3906
- if (opts.orientation !== void 0 && opts.effect === "split") attrs.push(attr(ATTR_ORIENT, opts.orientation));
4530
+ if (opts.orientation !== void 0 && opts.effect === "split") {
4531
+ oneOf(opts.orientation, ["horz", "vert"], "setSlideTransition: orientation");
4532
+ attrs.push(attr(ATTR_ORIENT, opts.orientation));
4533
+ }
3907
4534
  if (opts.thruBlack && THRU_BLK_EFFECTS.has(opts.effect)) attrs.push(attr(ATTR_THRU_BLK, "1"));
3908
4535
  return elem(name, { attrs });
3909
4536
  };
3910
4537
  /** Returns a complete `<p:transition>` element. */
3911
4538
  const buildTransition = (opts) => {
4539
+ if (opts.speed !== void 0) oneOf(opts.speed, [
4540
+ "slow",
4541
+ "med",
4542
+ "fast"
4543
+ ], "setSlideTransition: speed");
3912
4544
  const attrs = [];
3913
4545
  if (opts.speed !== void 0) attrs.push(attr(ATTR_SPD, opts.speed));
3914
4546
  if (opts.advanceOnClick === false) attrs.push(attr(ATTR_ADV_CLICK, "0"));
@@ -3924,11 +4556,11 @@ const buildTransition = (opts) => {
3924
4556
  };
3925
4557
  //#endregion
3926
4558
  //#region src/internal/presentationml/animation-builder.ts
3927
- const NAME_TIMING = qname("p", "timing", NS.pml);
3928
- const NAME_TN_LST = qname("p", "tnLst", NS.pml);
3929
- const NAME_PAR = qname("p", "par", NS.pml);
3930
- const NAME_C_TN = qname("p", "cTn", NS.pml);
3931
- const NAME_CHILD_TN_LST = qname("p", "childTnLst", NS.pml);
4559
+ const NAME_TIMING$1 = qname("p", "timing", NS.pml);
4560
+ const NAME_TN_LST$1 = qname("p", "tnLst", NS.pml);
4561
+ const NAME_PAR$1 = qname("p", "par", NS.pml);
4562
+ const NAME_C_TN$1 = qname("p", "cTn", NS.pml);
4563
+ const NAME_CHILD_TN_LST$1 = qname("p", "childTnLst", NS.pml);
3932
4564
  const NAME_SEQ = qname("p", "seq", NS.pml);
3933
4565
  const NAME_ST_COND_LST = qname("p", "stCondLst", NS.pml);
3934
4566
  const NAME_PREV_COND_LST = qname("p", "prevCondLst", NS.pml);
@@ -3950,7 +4582,7 @@ const NAME_TAV_LST = qname("p", "tavLst", NS.pml);
3950
4582
  const NAME_TAV = qname("p", "tav", NS.pml);
3951
4583
  const NAME_BLD_LST = qname("p", "bldLst", NS.pml);
3952
4584
  const NAME_BLD_P = qname("p", "bldP", NS.pml);
3953
- const ATTR_ID$3 = qname("", "id", "");
4585
+ const ATTR_ID$4 = qname("", "id", "");
3954
4586
  const ATTR_DUR = qname("", "dur", "");
3955
4587
  const ATTR_RESTART = qname("", "restart", "");
3956
4588
  const ATTR_NODE_TYPE = qname("", "nodeType", "");
@@ -3998,9 +4630,9 @@ const buildSetVisibility = (spid, visible) => {
3998
4630
  data: "style.visibility"
3999
4631
  }] })] });
4000
4632
  return elem(NAME_SET, { children: [elem(NAME_C_BHVR, { children: [
4001
- elem(NAME_C_TN, {
4633
+ elem(NAME_C_TN$1, {
4002
4634
  attrs: [
4003
- attr(ATTR_ID$3, "6"),
4635
+ attr(ATTR_ID$4, "6"),
4004
4636
  attr(ATTR_DUR, "1"),
4005
4637
  attr(ATTR_FILL, "hold")
4006
4638
  ],
@@ -4016,8 +4648,8 @@ const buildOpacityAnim = (spid, durationMs, fadeIn) => {
4016
4648
  kind: "text",
4017
4649
  data: "style.opacity"
4018
4650
  }] })] });
4019
- const cTn = elem(NAME_C_TN, { attrs: [
4020
- attr(ATTR_ID$3, "7"),
4651
+ const cTn = elem(NAME_C_TN$1, { attrs: [
4652
+ attr(ATTR_ID$4, "7"),
4021
4653
  attr(ATTR_DUR, String(durationMs)),
4022
4654
  attr(ATTR_FILL, "hold")
4023
4655
  ] });
@@ -4045,19 +4677,24 @@ const buildOpacityAnim = (spid, durationMs, fadeIn) => {
4045
4677
  };
4046
4678
  /**
4047
4679
  * Builds the complete `<p:timing>` element for a single click-effect on
4048
- * the given shape id. Returns null for unsupported effect kinds.
4680
+ * the given shape id.
4049
4681
  */
4050
4682
  const buildSingleEffectTiming = (spid, opts) => {
4051
- const preset = PRESETS[opts.effect];
4683
+ const preset = PRESETS[oneOf(opts.effect, [
4684
+ "fadeIn",
4685
+ "fadeOut",
4686
+ "appear",
4687
+ "disappear"
4688
+ ], "setShapeAnimation: effect")];
4052
4689
  const duration = opts.durationMs === void 0 ? 500 : unsignedIntMs(opts.durationMs, "setShapeAnimation: durationMs");
4053
4690
  const isFade = opts.effect === "fadeIn" || opts.effect === "fadeOut";
4054
4691
  const isEntrance = preset.presetClass === "entr";
4055
4692
  const effectChildren = [];
4056
4693
  effectChildren.push(buildSetVisibility(spid, isEntrance));
4057
4694
  if (isFade) effectChildren.push(buildOpacityAnim(spid, duration, isEntrance));
4058
- const effectPar = elem(NAME_PAR, { children: [elem(NAME_C_TN, {
4695
+ const effectPar = elem(NAME_PAR$1, { children: [elem(NAME_C_TN$1, {
4059
4696
  attrs: [
4060
- attr(ATTR_ID$3, "5"),
4697
+ attr(ATTR_ID$4, "5"),
4061
4698
  attr(ATTR_PRESET_ID, String(preset.presetId)),
4062
4699
  attr(ATTR_PRESET_CLASS, preset.presetClass),
4063
4700
  attr(ATTR_PRESET_SUBTYPE, String(preset.presetSubtype)),
@@ -4065,23 +4702,23 @@ const buildSingleEffectTiming = (spid, opts) => {
4065
4702
  attr(ATTR_GRP_ID, "0"),
4066
4703
  attr(ATTR_NODE_TYPE, "clickEffect")
4067
4704
  ],
4068
- children: [elem(NAME_ST_COND_LST, { children: [elem(NAME_COND, { attrs: [attr(ATTR_DELAY, "0")] })] }), elem(NAME_CHILD_TN_LST, { children: effectChildren })]
4705
+ children: [elem(NAME_ST_COND_LST, { children: [elem(NAME_COND, { attrs: [attr(ATTR_DELAY, "0")] })] }), elem(NAME_CHILD_TN_LST$1, { children: effectChildren })]
4069
4706
  })] });
4070
- const clickWrapperPar = elem(NAME_PAR, { children: [elem(NAME_C_TN, {
4071
- attrs: [attr(ATTR_ID$3, "4"), attr(ATTR_FILL, "hold")],
4072
- children: [elem(NAME_ST_COND_LST, { children: [elem(NAME_COND, { attrs: [attr(ATTR_DELAY, "0")] })] }), elem(NAME_CHILD_TN_LST, { children: [effectPar] })]
4707
+ const clickWrapperPar = elem(NAME_PAR$1, { children: [elem(NAME_C_TN$1, {
4708
+ attrs: [attr(ATTR_ID$4, "4"), attr(ATTR_FILL, "hold")],
4709
+ children: [elem(NAME_ST_COND_LST, { children: [elem(NAME_COND, { attrs: [attr(ATTR_DELAY, "0")] })] }), elem(NAME_CHILD_TN_LST$1, { children: [effectPar] })]
4073
4710
  })] });
4074
- const indefinitePar = elem(NAME_PAR, { children: [elem(NAME_C_TN, {
4075
- attrs: [attr(ATTR_ID$3, "3"), attr(ATTR_FILL, "hold")],
4076
- children: [elem(NAME_ST_COND_LST, { children: [elem(NAME_COND, { attrs: [attr(ATTR_DELAY, "indefinite")] })] }), elem(NAME_CHILD_TN_LST, { children: [clickWrapperPar] })]
4711
+ const indefinitePar = elem(NAME_PAR$1, { children: [elem(NAME_C_TN$1, {
4712
+ attrs: [attr(ATTR_ID$4, "3"), attr(ATTR_FILL, "hold")],
4713
+ children: [elem(NAME_ST_COND_LST, { children: [elem(NAME_COND, { attrs: [attr(ATTR_DELAY, "indefinite")] })] }), elem(NAME_CHILD_TN_LST$1, { children: [clickWrapperPar] })]
4077
4714
  })] });
4078
- const mainSeqCTn = elem(NAME_C_TN, {
4715
+ const mainSeqCTn = elem(NAME_C_TN$1, {
4079
4716
  attrs: [
4080
- attr(ATTR_ID$3, "2"),
4717
+ attr(ATTR_ID$4, "2"),
4081
4718
  attr(ATTR_DUR, "indefinite"),
4082
4719
  attr(ATTR_NODE_TYPE, "mainSeq")
4083
4720
  ],
4084
- children: [elem(NAME_CHILD_TN_LST, { children: [indefinitePar] })]
4721
+ children: [elem(NAME_CHILD_TN_LST$1, { children: [indefinitePar] })]
4085
4722
  });
4086
4723
  const prevCond = elem(NAME_PREV_COND_LST, { children: [elem(NAME_COND, {
4087
4724
  attrs: [attr(ATTR_EVT, "onPrev"), attr(ATTR_DELAY, "0")],
@@ -4099,14 +4736,14 @@ const buildSingleEffectTiming = (spid, opts) => {
4099
4736
  nextCond
4100
4737
  ]
4101
4738
  });
4102
- return elem(NAME_TIMING, { children: [elem(NAME_TN_LST, { children: [elem(NAME_PAR, { children: [elem(NAME_C_TN, {
4739
+ return elem(NAME_TIMING$1, { children: [elem(NAME_TN_LST$1, { children: [elem(NAME_PAR$1, { children: [elem(NAME_C_TN$1, {
4103
4740
  attrs: [
4104
- attr(ATTR_ID$3, "1"),
4741
+ attr(ATTR_ID$4, "1"),
4105
4742
  attr(ATTR_DUR, "indefinite"),
4106
4743
  attr(ATTR_RESTART, "never"),
4107
4744
  attr(ATTR_NODE_TYPE, "tmRoot")
4108
4745
  ],
4109
- children: [elem(NAME_CHILD_TN_LST, { children: [seq] })]
4746
+ children: [elem(NAME_CHILD_TN_LST$1, { children: [seq] })]
4110
4747
  })] })] }), elem(NAME_BLD_LST, { children: [elem(NAME_BLD_P, { attrs: [attr(ATTR_SPID, String(spid)), attr(ATTR_GRP_ID, "0")] })] })] });
4111
4748
  };
4112
4749
  //#endregion
@@ -4117,7 +4754,7 @@ const NAME_CM_LST = qname("p", "cmLst", NS.pml);
4117
4754
  const NAME_CM = qname("p", "cm", NS.pml);
4118
4755
  const NAME_POS = qname("p", "pos", NS.pml);
4119
4756
  const NAME_TEXT = qname("p", "text", NS.pml);
4120
- const ATTR_ID$2 = qname("", "id", "");
4757
+ const ATTR_ID$3 = qname("", "id", "");
4121
4758
  const ATTR_NAME$1 = qname("", "name", "");
4122
4759
  const ATTR_INITIALS = qname("", "initials", "");
4123
4760
  const ATTR_LAST_IDX = qname("", "lastIdx", "");
@@ -4131,7 +4768,7 @@ const readCommentAuthorList = (root) => {
4131
4768
  if (root.name.namespaceURI !== NS.pml || root.name.localName !== "cmAuthorLst") throw new Error(`expected <p:cmAuthorLst> root, got <${root.name.prefix}:${root.name.localName}>`);
4132
4769
  const authors = [];
4133
4770
  for (const el of allChildElements(root, NAME_CM_AUTHOR)) {
4134
- const idRaw = getAttrValue(el, ATTR_ID$2);
4771
+ const idRaw = getAttrValue(el, ATTR_ID$3);
4135
4772
  const nameVal = getAttrValue(el, ATTR_NAME$1);
4136
4773
  const initialsVal = getAttrValue(el, ATTR_INITIALS);
4137
4774
  const lastIdxRaw = getAttrValue(el, ATTR_LAST_IDX);
@@ -4191,7 +4828,7 @@ const readCommentList = (root) => {
4191
4828
  };
4192
4829
  const commentAuthorElement = (a) => {
4193
4830
  return elem(NAME_CM_AUTHOR, { attrs: [
4194
- attr(ATTR_ID$2, String(a.id)),
4831
+ attr(ATTR_ID$3, String(a.id)),
4195
4832
  attr(ATTR_NAME$1, a.name),
4196
4833
  attr(ATTR_INITIALS, a.initials),
4197
4834
  attr(ATTR_LAST_IDX, String(a.lastIdx)),
@@ -4255,7 +4892,7 @@ const NAME_SLD_ID_LST$1 = qname("p", "sldIdLst", NS.pml);
4255
4892
  const NAME_SLD_ID$1 = qname("p", "sldId", NS.pml);
4256
4893
  const NAME_CSLD = qname("p", "cSld", NS.pml);
4257
4894
  const NAME_SP_TREE = qname("p", "spTree", NS.pml);
4258
- const ATTR_ID$1 = qname("", "id", "");
4895
+ const ATTR_ID$2 = qname("", "id", "");
4259
4896
  const ATTR_R_ID$1 = qname("r", "id", NS.officeDocRels);
4260
4897
  const SLD_ID_MAX = 2147482623;
4261
4898
  const commitSlideData = (slide) => {
@@ -5159,6 +5796,348 @@ const setShapeClickAction = (shape, action) => {
5159
5796
  commitAndRefresh(shape);
5160
5797
  };
5161
5798
  //#endregion
5799
+ //#region src/internal/chartml/enum-validation.ts
5800
+ const LABEL_POSITIONS = [
5801
+ "ctr",
5802
+ "inEnd",
5803
+ "outEnd",
5804
+ "inBase",
5805
+ "t",
5806
+ "b",
5807
+ "l",
5808
+ "r",
5809
+ "bestFit"
5810
+ ];
5811
+ const DISPLAY_UNITS = [
5812
+ "hundreds",
5813
+ "thousands",
5814
+ "tenThousands",
5815
+ "hundredThousands",
5816
+ "millions",
5817
+ "tenMillions",
5818
+ "hundredMillions",
5819
+ "billions",
5820
+ "trillions"
5821
+ ];
5822
+ const LABEL_ALIGNMENTS = [
5823
+ "ctr",
5824
+ "l",
5825
+ "r"
5826
+ ];
5827
+ const DISPLAY_BLANKS = [
5828
+ "gap",
5829
+ "zero",
5830
+ "span"
5831
+ ];
5832
+ const SCATTER_STYLES = [
5833
+ "none",
5834
+ "line",
5835
+ "lineMarker",
5836
+ "marker",
5837
+ "smooth",
5838
+ "smoothMarker"
5839
+ ];
5840
+ const RADAR_STYLES = [
5841
+ "standard",
5842
+ "marker",
5843
+ "filled"
5844
+ ];
5845
+ const BAR_3D_SHAPES = [
5846
+ "box",
5847
+ "cone",
5848
+ "coneToMax",
5849
+ "cylinder",
5850
+ "pyramid",
5851
+ "pyramidToMax"
5852
+ ];
5853
+ const OF_PIE_TYPES = ["pie", "bar"];
5854
+ const SPLIT_TYPES = [
5855
+ "auto",
5856
+ "cust",
5857
+ "percent",
5858
+ "pos",
5859
+ "val"
5860
+ ];
5861
+ const LAYOUT_TARGETS = ["inner", "outer"];
5862
+ const AXIS_CROSSES = [
5863
+ "autoZero",
5864
+ "min",
5865
+ "max"
5866
+ ];
5867
+ const LEGEND_POSITIONS = [
5868
+ "r",
5869
+ "t",
5870
+ "b",
5871
+ "l",
5872
+ "tr"
5873
+ ];
5874
+ const MARKER_SYMBOLS = [
5875
+ "none",
5876
+ "auto",
5877
+ "circle",
5878
+ "square",
5879
+ "diamond",
5880
+ "triangle",
5881
+ "star",
5882
+ "x",
5883
+ "plus",
5884
+ "dash",
5885
+ "dot",
5886
+ "picture"
5887
+ ];
5888
+ const TRENDLINE_TYPES = [
5889
+ "linear",
5890
+ "exp",
5891
+ "log",
5892
+ "poly",
5893
+ "power",
5894
+ "movingAvg"
5895
+ ];
5896
+ const ERROR_BAR_TYPES = [
5897
+ "both",
5898
+ "plus",
5899
+ "minus"
5900
+ ];
5901
+ const ERROR_VALUE_TYPES = [
5902
+ "fixedVal",
5903
+ "percentage",
5904
+ "stdDev",
5905
+ "stdErr",
5906
+ "cust"
5907
+ ];
5908
+ const GROUPINGS = [
5909
+ "clustered",
5910
+ "stacked",
5911
+ "percentStacked",
5912
+ "standard"
5913
+ ];
5914
+ const TICK_MARKS = [
5915
+ "in",
5916
+ "out",
5917
+ "cross",
5918
+ "none"
5919
+ ];
5920
+ const TICK_LABEL_POSITIONS = [
5921
+ "none",
5922
+ "low",
5923
+ "high",
5924
+ "nextTo"
5925
+ ];
5926
+ const ORIENTATIONS = ["minMax", "maxMin"];
5927
+ const CROSS_BETWEEN = ["between", "midCat"];
5928
+ const TIME_UNITS$1 = [
5929
+ "days",
5930
+ "months",
5931
+ "years"
5932
+ ];
5933
+ const validateLabels = (labels, field) => {
5934
+ if (labels?.position !== void 0) oneOf(labels.position, LABEL_POSITIONS, `${field}.position`);
5935
+ };
5936
+ const validateScaling = (scaling, field) => {
5937
+ if (scaling?.displayUnits !== void 0) oneOf(scaling.displayUnits, DISPLAY_UNITS, `${field}.displayUnits`);
5938
+ };
5939
+ /** Validate before chart XML or its embedded workbook is changed. */
5940
+ const validateChartSpecEnums = (spec, caller) => {
5941
+ oneOf(spec.kind, [
5942
+ "bar",
5943
+ "column",
5944
+ "line",
5945
+ "pie",
5946
+ "doughnut",
5947
+ "area",
5948
+ "scatter",
5949
+ "radar",
5950
+ "bubble",
5951
+ "stock",
5952
+ "surface"
5953
+ ], `${caller}: kind`);
5954
+ if (spec.grouping !== void 0) oneOf(spec.grouping, GROUPINGS, `${caller}: grouping`);
5955
+ if (spec.valueAxisMajorTickMark !== void 0) oneOf(spec.valueAxisMajorTickMark, TICK_MARKS, `${caller}: valueAxisMajorTickMark`);
5956
+ if (spec.valueAxisMinorTickMark !== void 0) oneOf(spec.valueAxisMinorTickMark, TICK_MARKS, `${caller}: valueAxisMinorTickMark`);
5957
+ if (spec.categoryAxisMajorTickMark !== void 0) oneOf(spec.categoryAxisMajorTickMark, TICK_MARKS, `${caller}: categoryAxisMajorTickMark`);
5958
+ if (spec.categoryAxisMinorTickMark !== void 0) oneOf(spec.categoryAxisMinorTickMark, TICK_MARKS, `${caller}: categoryAxisMinorTickMark`);
5959
+ if (spec.valueAxisTickLabelPos !== void 0) oneOf(spec.valueAxisTickLabelPos, TICK_LABEL_POSITIONS, `${caller}: valueAxisTickLabelPos`);
5960
+ if (spec.categoryAxisTickLabelPos !== void 0) oneOf(spec.categoryAxisTickLabelPos, TICK_LABEL_POSITIONS, `${caller}: categoryAxisTickLabelPos`);
5961
+ if (spec.categoryAxisLabelAlign !== void 0) oneOf(spec.categoryAxisLabelAlign, LABEL_ALIGNMENTS, `${caller}: categoryAxisLabelAlign`);
5962
+ if (spec.categoryAxisOrientation !== void 0) oneOf(spec.categoryAxisOrientation, ORIENTATIONS, `${caller}: categoryAxisOrientation`);
5963
+ if (spec.valueAxisOrientation !== void 0) oneOf(spec.valueAxisOrientation, ORIENTATIONS, `${caller}: valueAxisOrientation`);
5964
+ if (spec.valueAxisCrossBetween !== void 0) oneOf(spec.valueAxisCrossBetween, CROSS_BETWEEN, `${caller}: valueAxisCrossBetween`);
5965
+ if (spec.dispBlanksAs !== void 0) oneOf(spec.dispBlanksAs, DISPLAY_BLANKS, `${caller}: dispBlanksAs`);
5966
+ if (spec.scatterStyle !== void 0) oneOf(spec.scatterStyle, SCATTER_STYLES, `${caller}: scatterStyle`);
5967
+ if (spec.radarStyle !== void 0) oneOf(spec.radarStyle, RADAR_STYLES, `${caller}: radarStyle`);
5968
+ if (spec.bubbleSizeRepresents !== void 0) oneOf(spec.bubbleSizeRepresents, ["area", "width"], `${caller}: bubbleSizeRepresents`);
5969
+ if (spec.bar3DShape !== void 0) oneOf(spec.bar3DShape, BAR_3D_SHAPES, `${caller}: bar3DShape`);
5970
+ if (spec.secondaryValueAxis?.majorTickMark !== void 0) oneOf(spec.secondaryValueAxis.majorTickMark, TICK_MARKS, `${caller}: secondaryValueAxis.majorTickMark`);
5971
+ if (spec.secondaryValueAxis?.minorTickMark !== void 0) oneOf(spec.secondaryValueAxis.minorTickMark, TICK_MARKS, `${caller}: secondaryValueAxis.minorTickMark`);
5972
+ if (spec.secondaryValueAxis?.tickLabelPos !== void 0) oneOf(spec.secondaryValueAxis.tickLabelPos, TICK_LABEL_POSITIONS, `${caller}: secondaryValueAxis.tickLabelPos`);
5973
+ if (spec.secondaryValueAxis?.crossBetween !== void 0) oneOf(spec.secondaryValueAxis.crossBetween, CROSS_BETWEEN, `${caller}: secondaryValueAxis.crossBetween`);
5974
+ if (spec.seriesAxis?.orientation !== void 0) oneOf(spec.seriesAxis.orientation, ORIENTATIONS, `${caller}: seriesAxis.orientation`);
5975
+ if (spec.seriesAxis?.tickLabelPos !== void 0) oneOf(spec.seriesAxis.tickLabelPos, TICK_LABEL_POSITIONS, `${caller}: seriesAxis.tickLabelPos`);
5976
+ if (spec.categoryAxisDate?.baseTimeUnit !== void 0) oneOf(spec.categoryAxisDate.baseTimeUnit, TIME_UNITS$1, `${caller}: categoryAxisDate.baseTimeUnit`);
5977
+ if (spec.categoryAxisDate?.majorTimeUnit !== void 0) oneOf(spec.categoryAxisDate.majorTimeUnit, TIME_UNITS$1, `${caller}: categoryAxisDate.majorTimeUnit`);
5978
+ if (spec.categoryAxisDate?.minorTimeUnit !== void 0) oneOf(spec.categoryAxisDate.minorTimeUnit, TIME_UNITS$1, `${caller}: categoryAxisDate.minorTimeUnit`);
5979
+ if (spec.ofPie?.type !== void 0) oneOf(spec.ofPie.type, OF_PIE_TYPES, `${caller}: ofPie.type`);
5980
+ if (spec.ofPie?.splitType !== void 0) oneOf(spec.ofPie.splitType, SPLIT_TYPES, `${caller}: ofPie.splitType`);
5981
+ if (spec.plotAreaLayout?.target !== void 0) oneOf(spec.plotAreaLayout.target, LAYOUT_TARGETS, `${caller}: plotAreaLayout.target`);
5982
+ if (spec.legend?.layout?.target !== void 0) oneOf(spec.legend.layout.target, LAYOUT_TARGETS, `${caller}: legend.layout.target`);
5983
+ if (spec.valueAxisCrosses !== void 0 && typeof spec.valueAxisCrosses !== "object") oneOf(spec.valueAxisCrosses, AXIS_CROSSES, `${caller}: valueAxisCrosses`);
5984
+ if (spec.legend?.position != null) oneOf(spec.legend.position, LEGEND_POSITIONS, `${caller}: legend.position`);
5985
+ validateLabels(spec.dataLabels, `${caller}: dataLabels`);
5986
+ validateScaling(spec.valueAxis, `${caller}: valueAxis`);
5987
+ validateScaling(spec.categoryAxisScaling, `${caller}: categoryAxisScaling`);
5988
+ validateScaling(spec.secondaryValueAxis?.scaling, `${caller}: secondaryValueAxis.scaling`);
5989
+ for (const [index, series] of spec.series.entries()) {
5990
+ const field = `${caller}: series[${index}]`;
5991
+ if (series.chartKind !== void 0) oneOf(series.chartKind, [
5992
+ "bar",
5993
+ "column",
5994
+ "line",
5995
+ "area"
5996
+ ], `${field}.chartKind`);
5997
+ if (series.lineDash !== void 0) oneOf(series.lineDash, LINE_DASHES, `${field}.lineDash`);
5998
+ if (series.markerSymbol !== void 0) oneOf(series.markerSymbol, MARKER_SYMBOLS, `${field}.markerSymbol`);
5999
+ if (series.trendline !== void 0) oneOf(series.trendline.type, TRENDLINE_TYPES, `${field}.trendline.type`);
6000
+ validateLabels(series.dataLabels, `${field}.dataLabels`);
6001
+ for (const [point, labels] of (series.pointDataLabels ?? []).entries()) validateLabels(labels, `${field}.pointDataLabels[${point}]`);
6002
+ for (const direction of ["errorBars", "xErrorBars"]) {
6003
+ const bars = series[direction];
6004
+ if (bars === void 0) continue;
6005
+ oneOf(bars.barType, ERROR_BAR_TYPES, `${field}.${direction}.barType`);
6006
+ oneOf(bars.amount.type, ERROR_VALUE_TYPES, `${field}.${direction}.amount.type`);
6007
+ }
6008
+ }
6009
+ };
6010
+ //#endregion
6011
+ //#region src/internal/chartml/embedded-xlsx.ts
6012
+ const TEXT_ENCODER = new TextEncoder();
6013
+ const encode = (s) => TEXT_ENCODER.encode(s);
6014
+ const xmlEscape = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
6015
+ const colLetter = (col) => {
6016
+ let n = col;
6017
+ let out = "";
6018
+ while (true) {
6019
+ out = String.fromCharCode(65 + n % 26) + out;
6020
+ if (n < 26) return out;
6021
+ n = Math.floor(n / 26) - 1;
6022
+ }
6023
+ };
6024
+ const cellRef = (row, col) => `${colLetter(col)}${row + 1}`;
6025
+ /**
6026
+ * Builds the bytes of a fresh xlsx whose only sheet holds `grid`, row by
6027
+ * row from A1. Which cell means what is the caller's business — see
6028
+ * `layoutChartSheet`, which also produces the `<c:f>` formulas that point
6029
+ * back into this grid.
6030
+ */
6031
+ const buildEmbeddedXlsx = (grid) => {
6032
+ const sheetXmlParts = [];
6033
+ sheetXmlParts.push("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n", "<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">", "<sheetData>");
6034
+ grid.forEach((row, r) => {
6035
+ sheetXmlParts.push(`<row r="${r + 1}">`);
6036
+ row.forEach((cell, col) => {
6037
+ if (cell === null) return;
6038
+ sheetXmlParts.push(typeof cell === "number" ? `<c r="${cellRef(r, col)}"><v>${cell}</v></c>` : `<c r="${cellRef(r, col)}" t="inlineStr"><is><t>${xmlEscape(cell)}</t></is></c>`);
6039
+ });
6040
+ sheetXmlParts.push("</row>");
6041
+ });
6042
+ sheetXmlParts.push("</sheetData></worksheet>");
6043
+ const sheetXml = sheetXmlParts.join("");
6044
+ return writeZip([
6045
+ {
6046
+ name: "[Content_Types].xml",
6047
+ data: encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/><Default Extension=\"xml\" ContentType=\"application/xml\"/><Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/><Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/></Types>")
6048
+ },
6049
+ {
6050
+ name: "_rels/.rels",
6051
+ data: encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/></Relationships>")
6052
+ },
6053
+ {
6054
+ name: "xl/workbook.xml",
6055
+ data: encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"><sheets><sheet name=\"Sheet1\" sheetId=\"1\" r:id=\"rId1\"/></sheets></workbook>")
6056
+ },
6057
+ {
6058
+ name: "xl/_rels/workbook.xml.rels",
6059
+ data: encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/></Relationships>")
6060
+ },
6061
+ {
6062
+ name: "xl/worksheets/sheet1.xml",
6063
+ data: encode(sheetXml)
6064
+ }
6065
+ ]);
6066
+ };
6067
+ /**
6068
+ * Returns the spreadsheet-cell reference span used by chart `<c:f>`
6069
+ * formulas. Example: `cellRange('Sheet1', 1, 0, 4)` →
6070
+ * `"Sheet1!$A$2:$A$5"` (column A, rows 2–5 inclusive, 0-indexed input).
6071
+ */
6072
+ const cellRange = (sheet, startRow, col, count, endCol = col) => `${sheet}!$${colLetter(col)}$${startRow + 1}:$${colLetter(endCol)}$${startRow + count}`;
6073
+ /** Single-cell reference, e.g. `cellAddr('Sheet1', 0, 1)` → `"Sheet1!$B$1"`. */
6074
+ const cellAddr = (sheet, row, col) => `${sheet}!$${colLetter(col)}$${row + 1}`;
6075
+ //#endregion
6076
+ //#region src/internal/chartml/sheet-layout.ts
6077
+ const SHEET = "Sheet1";
6078
+ const isXyKind = (spec) => spec.kind === "scatter" || spec.kind === "bubble";
6079
+ /** Parses a date-axis category; the caller has validated it is numeric. */
6080
+ const dateSerial = (category) => Number(category);
6081
+ const layoutCategorySheet = (spec) => {
6082
+ const outerLevels = [...spec.categoryGroupLevels ?? []].reverse();
6083
+ const levelCount = outerLevels.length + 1;
6084
+ const rowCount = spec.categories.length;
6085
+ const isDateAxis = spec.categoryAxisDate !== void 0;
6086
+ const grid = [[...Array.from({ length: levelCount }, () => ""), ...spec.series.map((s) => s.name)]];
6087
+ for (let r = 0; r < rowCount; r++) {
6088
+ const category = spec.categories[r] ?? "";
6089
+ const row = outerLevels.map((level) => {
6090
+ const label = level[r] ?? "";
6091
+ return label === "" ? null : label;
6092
+ });
6093
+ row.push(isDateAxis ? dateSerial(category) : category);
6094
+ for (const s of spec.series) row.push(s.values[r] ?? null);
6095
+ grid.push(row);
6096
+ }
6097
+ return {
6098
+ grid,
6099
+ categories: cellRange(SHEET, 1, 0, rowCount, levelCount - 1),
6100
+ series: spec.series.map((_, i) => ({
6101
+ name: cellAddr(SHEET, 0, levelCount + i),
6102
+ values: cellRange(SHEET, 1, levelCount + i, rowCount)
6103
+ }))
6104
+ };
6105
+ };
6106
+ const layoutXySheet = (spec) => {
6107
+ const isBubble = spec.kind === "bubble";
6108
+ const stride = isBubble ? 3 : 2;
6109
+ const rowCount = Math.max(0, ...spec.series.map((s) => Math.max(s.values.length, s.xValues?.length ?? 0, s.bubbleSizes?.length ?? 0)));
6110
+ const header = [];
6111
+ for (const s of spec.series) {
6112
+ header.push("X", s.name);
6113
+ if (isBubble) header.push("Size");
6114
+ }
6115
+ const grid = [header];
6116
+ for (let r = 0; r < rowCount; r++) {
6117
+ const row = [];
6118
+ for (const s of spec.series) {
6119
+ row.push(s.xValues?.[r] ?? null, s.values[r] ?? null);
6120
+ if (isBubble) row.push(s.bubbleSizes?.[r] ?? null);
6121
+ }
6122
+ grid.push(row);
6123
+ }
6124
+ return {
6125
+ grid,
6126
+ series: spec.series.map((s, i) => {
6127
+ const base = i * stride;
6128
+ const pointCount = s.values.length;
6129
+ return {
6130
+ name: cellAddr(SHEET, 0, base + 1),
6131
+ xValues: cellRange(SHEET, 1, base, pointCount),
6132
+ values: cellRange(SHEET, 1, base + 1, pointCount),
6133
+ ...isBubble ? { bubbleSizes: cellRange(SHEET, 1, base + 2, pointCount) } : {}
6134
+ };
6135
+ })
6136
+ };
6137
+ };
6138
+ /** Lays `spec` out as a sheet grid plus the formulas that address it. */
6139
+ const layoutChartSheet = (spec) => isXyKind(spec) ? layoutXySheet(spec) : layoutCategorySheet(spec);
6140
+ //#endregion
5162
6141
  //#region src/internal/chartml/chart-builder.ts
5163
6142
  const NS_C$1 = NS.chart;
5164
6143
  const NS_A$1 = NS.dml;
@@ -5177,20 +6156,21 @@ const strRef = (formula, points) => {
5177
6156
  const strCache = elem(c("strCache"), { children: [valNode(c("ptCount"), points.length), ...points.map((p, i) => ptNode(i, p))] });
5178
6157
  return elem(c("strRef"), { children: [elem(c("f"), { children: [text(formula)] }), strCache] });
5179
6158
  };
5180
- const numRef = (formula, points) => {
5181
- const numCache = elem(c("numCache"), { children: [
5182
- elem(c("formatCode"), { children: [text("General")] }),
5183
- valNode(c("ptCount"), points.length),
5184
- ...points.map((v, i) => v === null ? null : ptNode(i, String(v))).filter((n) => n !== null)
5185
- ] });
5186
- return elem(c("numRef"), { children: [elem(c("f"), { children: [text(formula)] }), numCache] });
5187
- };
5188
- const solidFillSpPr = (color) => {
5189
- const srgbClr = elem(a("srgbClr"), { attrs: [attr(qname("", "val", ""), color.replace(/^#/, "").toUpperCase())] });
5190
- const solidFill = elem(a("solidFill"), { children: [srgbClr] });
5191
- return elem(c("spPr"), { children: [solidFill] });
5192
- };
5193
- const lineSpPr = (color, widthEmu, field) => {
6159
+ const numDataChildren = (points, formatCode) => [
6160
+ elem(c("formatCode"), { children: [text(formatCode)] }),
6161
+ valNode(c("ptCount"), points.length),
6162
+ ...points.map((v, i) => v === null ? null : ptNode(i, String(v))).filter((n) => n !== null)
6163
+ ];
6164
+ const numRef = (formula, points, formatCode = "General") => elem(c("numRef"), { children: [elem(c("f"), { children: [text(formula)] }), elem(c("numCache"), { children: numDataChildren(points, formatCode) })] });
6165
+ const multiLvlStrRef = (formula, levels, pointCount) => elem(c("multiLvlStrRef"), { children: [elem(c("f"), { children: [text(formula)] }), elem(c("multiLvlStrCache"), { children: [valNode(c("ptCount"), pointCount), ...levels.map((level, depth) => elem(c("lvl"), { children: level.map((label, i) => depth > 0 && label === "" ? null : ptNode(i, label)).filter((n) => n !== null) }))] })] });
6166
+ const hexOf = (color) => color.replace(/^#/, "").toUpperCase();
6167
+ const solidFill = (color, opacity) => elem(a("solidFill"), { children: [elem(a("srgbClr"), {
6168
+ attrs: [attr(ATTR_VAL$1, hexOf(color))],
6169
+ children: opacity !== void 0 ? [valNode(a("alpha"), boundedInt(opacity * 1e5, "percent100000", "chart series: fillOpacity"))] : []
6170
+ })] });
6171
+ const solidFillSpPr = (color, opacity) => elem(c("spPr"), { children: [solidFill(color, opacity)] });
6172
+ const lineSpPr = (color, widthEmu, field, hidden = false) => {
6173
+ if (hidden) return elem(c("spPr"), { children: [elem(a("ln"), { children: [elem(a("noFill"))] })] });
5194
6174
  if (color === void 0 && widthEmu === void 0) return null;
5195
6175
  const ln = elem(a("ln"), {
5196
6176
  attrs: widthEmu !== void 0 ? [attr(qname("", "w", ""), String(lineWidthEmu(widthEmu, field)))] : [],
@@ -5216,14 +6196,14 @@ const DEFAULT_ACCENT_COLORS = [
5216
6196
  "5B9BD5",
5217
6197
  "70AD47"
5218
6198
  ];
5219
- const seriesSpPr = (color, lineColor, lineWidthEmu$1, lineDash) => {
5220
- const lnChildren = [elem(a("solidFill"), { children: [elem(a("srgbClr"), { attrs: [attr(qname("", "val", ""), lineColor)] })] })];
5221
- if (lineDash !== void 0) lnChildren.push(elem(a("prstDash"), { attrs: [attr(qname("", "val", ""), lineDash)] }));
6199
+ const seriesSpPr = (color, lineColor, lineWidthEmu$1, lineDash, fillOpacity) => {
6200
+ const lnChildren = [lineColor === null ? elem(a("noFill")) : solidFill(lineColor)];
6201
+ if (lineColor !== null && lineDash !== void 0) lnChildren.push(elem(a("prstDash"), { attrs: [attr(qname("", "val", ""), lineDash)] }));
5222
6202
  const ln = lineWidthEmu$1 !== void 0 ? elem(a("ln"), {
5223
6203
  attrs: [attr(qname("", "w", ""), String(lineWidthEmu(lineWidthEmu$1, "chart series: lineWidthEmu")))],
5224
6204
  children: lnChildren
5225
6205
  }) : elem(a("ln"), { children: lnChildren });
5226
- return elem(c("spPr"), { children: [elem(a("solidFill"), { children: [elem(a("srgbClr"), { attrs: [attr(qname("", "val", ""), color)] })] }), ln] });
6206
+ return elem(c("spPr"), { children: [solidFill(color, fillOpacity), ln] });
5227
6207
  };
5228
6208
  const markerElement = (symbol, sizePt, color, lineColor) => {
5229
6209
  const children = [];
@@ -5235,7 +6215,7 @@ const markerElement = (symbol, sizePt, color, lineColor) => {
5235
6215
  }
5236
6216
  return elem(c("marker"), { children });
5237
6217
  };
5238
- const dPtElements = (colors, explosions) => {
6218
+ const dPtElements = (colors, explosions, fillOpacity, bubble3D) => {
5239
6219
  const out = [];
5240
6220
  const colorLen = colors?.length ?? 0;
5241
6221
  const explLen = explosions?.length ?? 0;
@@ -5244,12 +6224,9 @@ const dPtElements = (colors, explosions) => {
5244
6224
  const color = colors?.[i] ?? null;
5245
6225
  const expl = explosions?.[i] ?? null;
5246
6226
  if (color === null && (expl === null || !Number.isFinite(expl))) continue;
5247
- const children = [valNode(c("idx"), i), valNode(c("bubble3D"), "0")];
6227
+ const children = [valNode(c("idx"), i), valNode(c("bubble3D"), bubble3D ? "1" : "0")];
5248
6228
  if (expl !== null) children.push(valNode(c("explosion"), Math.round(expl)));
5249
- if (color !== null) {
5250
- const hex = color.replace(/^#/, "").toUpperCase();
5251
- children.push(solidFillSpPr(hex));
5252
- }
6229
+ if (color !== null) children.push(solidFillSpPr(color, fillOpacity));
5253
6230
  out.push(elem(c("dPt"), { children }));
5254
6231
  }
5255
6232
  return out;
@@ -5271,39 +6248,121 @@ const trendlineElement = (tl) => {
5271
6248
  if (tl.displayEquation) children.push(valNode(c("dispEq"), "1"));
5272
6249
  return elem(c("trendline"), { children });
5273
6250
  };
5274
- const seriesElement = (spec, seriesIdx, sheet) => {
6251
+ const errBarsElement = (bars, direction) => {
6252
+ const children = [];
6253
+ if (direction !== null) children.push(valNode(c("errDir"), direction));
6254
+ children.push(valNode(c("errBarType"), bars.barType), valNode(c("errValType"), bars.amount.type));
6255
+ if (bars.noEndCap !== void 0) children.push(valNode(c("noEndCap"), bars.noEndCap ? "1" : "0"));
6256
+ if (bars.amount.type === "cust") {
6257
+ const literal = (name, points) => elem(c(name), { children: [elem(c("numLit"), { children: numDataChildren(points, "General") })] });
6258
+ if (bars.amount.plus !== void 0) children.push(literal("plus", bars.amount.plus));
6259
+ if (bars.amount.minus !== void 0) children.push(literal("minus", bars.amount.minus));
6260
+ } else if (bars.amount.type !== "stdErr") children.push(valNode(c("val"), bars.amount.value));
6261
+ const spPr = lineSpPr(bars.color, bars.lineWidthEmu, "chart series: errorBars.lineWidthEmu");
6262
+ if (spPr !== null) children.push(spPr);
6263
+ return elem(c("errBars"), { children });
6264
+ };
6265
+ const SERIES_SHAPE = {
6266
+ bar: "bar",
6267
+ column: "bar",
6268
+ line: "line",
6269
+ stock: "line",
6270
+ area: "area",
6271
+ pie: "pie",
6272
+ doughnut: "pie",
6273
+ scatter: "scatter",
6274
+ bubble: "bubble",
6275
+ radar: "radar",
6276
+ surface: "surface"
6277
+ };
6278
+ const SHAPES_WITH_MARKER = new Set([
6279
+ "line",
6280
+ "scatter",
6281
+ "radar"
6282
+ ]);
6283
+ const SHAPES_WITH_TRENDLINE = new Set([
6284
+ "bar",
6285
+ "line",
6286
+ "area",
6287
+ "scatter",
6288
+ "bubble"
6289
+ ]);
6290
+ const SHAPES_WITH_ERR_BARS = SHAPES_WITH_TRENDLINE;
6291
+ const SHAPES_WITH_INVERT = new Set(["bar", "bubble"]);
6292
+ const SCATTER_STYLES_WITH_LINE = new Set([
6293
+ "line",
6294
+ "lineMarker",
6295
+ "smooth",
6296
+ "smoothMarker"
6297
+ ]);
6298
+ const SCATTER_STYLES_WITH_MARKER = new Set([
6299
+ "marker",
6300
+ "lineMarker",
6301
+ "smoothMarker"
6302
+ ]);
6303
+ const categoryChannel = (spec, formula) => {
6304
+ if (spec.categoryAxisDate !== void 0) return elem(c("cat"), { children: [numRef(formula, spec.categories.map(dateSerial), spec.categoryAxisNumberFormat ?? "General")] });
6305
+ if (spec.categoryGroupLevels !== void 0 && spec.categoryGroupLevels.length > 0) return elem(c("cat"), { children: [multiLvlStrRef(formula, [spec.categories, ...spec.categoryGroupLevels], spec.categories.length)] });
6306
+ return elem(c("cat"), { children: [strRef(formula, spec.categories)] });
6307
+ };
6308
+ const padTo = (values, length) => Array.from({ length }, (_, i) => values?.[i] ?? null);
6309
+ const seriesElement = (spec, seriesIdx, layout) => {
5275
6310
  const series = spec.series[seriesIdx];
5276
- if (!series) throw new Error("seriesElement: out of range");
5277
- const headerCellFormula = `${sheet}!$${String.fromCharCode(66 + seriesIdx)}$1`;
5278
- const catRange = `${sheet}!$A$2:$A$${spec.categories.length + 1}`;
5279
- const valRange = `${sheet}!$${String.fromCharCode(66 + seriesIdx)}$2:$${String.fromCharCode(66 + seriesIdx)}$${spec.categories.length + 1}`;
5280
- const color = series.color !== void 0 ? series.color.replace(/^#/, "").toUpperCase() : DEFAULT_ACCENT_COLORS[seriesIdx % DEFAULT_ACCENT_COLORS.length] ?? "4472C4";
5281
- const paddedValues = [];
5282
- for (let i = 0; i < spec.categories.length; i++) paddedValues.push(i < series.values.length ? series.values[i] ?? null : null);
6311
+ const refs = layout.series[seriesIdx];
6312
+ if (!series || !refs) throw new Error("seriesElement: out of range");
6313
+ const color = series.color !== void 0 ? hexOf(series.color) : DEFAULT_ACCENT_COLORS[seriesIdx % DEFAULT_ACCENT_COLORS.length] ?? "4472C4";
5283
6314
  const kind = series.chartKind ?? spec.kind;
6315
+ const shape = SERIES_SHAPE[kind];
5284
6316
  const children = [
5285
6317
  valNode(c("idx"), seriesIdx),
5286
6318
  valNode(c("order"), seriesIdx),
5287
- elem(c("tx"), { children: [strRef(headerCellFormula, [series.name])] })
6319
+ elem(c("tx"), { children: [strRef(refs.name, [series.name])] })
5288
6320
  ];
5289
- if (kind === "line" || series.lineWidthEmu !== void 0 || series.lineColor !== void 0 || series.lineDash !== void 0) {
5290
- const lineColor = series.lineColor !== void 0 ? series.lineColor.replace(/^#/, "").toUpperCase() : color;
5291
- children.push(seriesSpPr(color, lineColor, series.lineWidthEmu, series.lineDash));
5292
- } else children.push(solidFillSpPr(color));
5293
- if (series.invertIfNegative === true && (kind === "bar" || kind === "column")) children.push(valNode(c("invertIfNegative"), "1"));
5294
- if (kind === "line" || kind === "scatter" || kind === "radar") {
5295
- const markerColor = series.markerColor !== void 0 ? series.markerColor.replace(/^#/, "").toUpperCase() : color;
5296
- const markerLineColor = series.markerLineColor !== void 0 ? series.markerLineColor.replace(/^#/, "").toUpperCase() : markerColor;
5297
- children.push(markerElement(series.markerSymbol, series.markerSizePt, markerColor, markerLineColor));
5298
- }
5299
- for (const dPt of dPtElements(series.pointColors, series.pointExplosions)) children.push(dPt);
6321
+ const isXy = shape === "scatter" || shape === "bubble";
6322
+ const pointCount = isXy ? series.values.length : spec.categories.length;
6323
+ const channels = [];
6324
+ if (isXy) {
6325
+ if (refs.xValues === void 0) throw new Error("seriesElement: xy series without an x range");
6326
+ channels.push(elem(c("xVal"), { children: [numRef(refs.xValues, padTo(series.xValues, pointCount))] }), elem(c("yVal"), { children: [numRef(refs.values, padTo(series.values, pointCount))] }));
6327
+ if (shape === "bubble") {
6328
+ if (refs.bubbleSizes === void 0) throw new Error("seriesElement: bubble series without a size range");
6329
+ channels.push(elem(c("bubbleSize"), { children: [numRef(refs.bubbleSizes, padTo(series.bubbleSizes, pointCount))] }), valNode(c("bubble3D"), spec.bubble3D === true ? "1" : "0"));
6330
+ }
6331
+ } else {
6332
+ if (layout.categories === void 0) throw new Error("seriesElement: category series without a category range");
6333
+ channels.push(categoryChannel(spec, layout.categories), elem(c("val"), { children: [numRef(refs.values, padTo(series.values, pointCount))] }));
6334
+ }
6335
+ if (shape === "surface") return elem(c("ser"), { children: [...children, ...channels] });
6336
+ const scatterStyle = spec.scatterStyle ?? "marker";
6337
+ const lineHidden = spec.kind === "stock" || shape === "scatter" && !SCATTER_STYLES_WITH_LINE.has(scatterStyle);
6338
+ if (lineHidden || shape === "line" || shape === "scatter" || shape === "radar" || series.lineWidthEmu !== void 0 || series.lineColor !== void 0 || series.lineDash !== void 0) {
6339
+ const lineColor = lineHidden ? null : series.lineColor !== void 0 ? hexOf(series.lineColor) : color;
6340
+ children.push(seriesSpPr(color, lineColor, series.lineWidthEmu, series.lineDash, series.fillOpacity));
6341
+ } else children.push(solidFillSpPr(color, series.fillOpacity));
6342
+ if (series.invertIfNegative === true && SHAPES_WITH_INVERT.has(shape)) children.push(valNode(c("invertIfNegative"), "1"));
6343
+ if (SHAPES_WITH_MARKER.has(shape)) {
6344
+ const markerColor = series.markerColor !== void 0 ? hexOf(series.markerColor) : color;
6345
+ const markerLineColor = series.markerLineColor !== void 0 ? hexOf(series.markerLineColor) : markerColor;
6346
+ const markersOff = spec.kind === "stock" || shape === "scatter" && !SCATTER_STYLES_WITH_MARKER.has(scatterStyle) || shape === "radar" && spec.radarStyle !== "marker";
6347
+ children.push(markerElement(series.markerSymbol ?? (markersOff ? "none" : void 0), series.markerSizePt, markerColor, markerLineColor));
6348
+ }
6349
+ for (const dPt of dPtElements(series.pointColors, series.pointExplosions, series.fillOpacity, spec.bubble3D === true)) children.push(dPt);
5300
6350
  if (series.pointDataLabels !== void 0 && series.dataLabels === void 0) throw new Error(`chart: series '${series.name}' sets pointDataLabels without dataLabels; add the series-level dataLabels the overrides fall back to`);
5301
6351
  const serDLbls = buildDLblsFromLabels(series.dataLabels, series.pointDataLabels);
5302
6352
  if (serDLbls !== null) children.push(serDLbls);
5303
- if (series.trendline && kind !== "pie" && kind !== "doughnut" && kind !== "radar") children.push(trendlineElement(series.trendline));
5304
- children.push(elem(c("cat"), { children: [strRef(catRange, spec.categories)] }));
5305
- children.push(elem(c("val"), { children: [numRef(valRange, paddedValues)] }));
5306
- if (kind === "line") children.push(valNode(c("smooth"), series.smooth === true ? "1" : "0"));
6353
+ if (series.trendline && SHAPES_WITH_TRENDLINE.has(shape) && spec.kind !== "stock") children.push(trendlineElement(series.trendline));
6354
+ if (series.errorBars !== void 0 || series.xErrorBars !== void 0) {
6355
+ if (!SHAPES_WITH_ERR_BARS.has(shape)) throw new Error(`chart: series '${series.name}' sets error bars, which a ${kind} series cannot carry (bar / column / line / area / scatter / bubble only)`);
6356
+ if (series.xErrorBars !== void 0 && !isXy) throw new Error(`chart: series '${series.name}' sets xErrorBars, which only scatter / bubble series have an x channel for`);
6357
+ if (series.xErrorBars !== void 0) children.push(errBarsElement(series.xErrorBars, "x"));
6358
+ if (series.errorBars !== void 0) children.push(errBarsElement(series.errorBars, isXy ? "y" : null));
6359
+ }
6360
+ children.push(...channels);
6361
+ if (shape === "line") children.push(valNode(c("smooth"), series.smooth === true ? "1" : "0"));
6362
+ else if (shape === "scatter") {
6363
+ const smooth = series.smooth ?? (scatterStyle === "smooth" || scatterStyle === "smoothMarker");
6364
+ children.push(valNode(c("smooth"), smooth ? "1" : "0"));
6365
+ }
5307
6366
  return elem(c("ser"), { children });
5308
6367
  };
5309
6368
  const CAT_AX_ID = 111111111;
@@ -5369,9 +6428,13 @@ const axisTxPrElement = (style, rotationDeg) => {
5369
6428
  };
5370
6429
  const catAxis = (spec) => {
5371
6430
  const catOrientation = spec.categoryAxisOrientation ?? "minMax";
6431
+ const dateAxis = spec.categoryAxisDate;
6432
+ const scalingChildren = [valNode(c("orientation"), catOrientation)];
6433
+ if (spec.categoryAxisScaling?.max !== void 0) scalingChildren.push(valNode(c("max"), spec.categoryAxisScaling.max));
6434
+ if (spec.categoryAxisScaling?.min !== void 0) scalingChildren.push(valNode(c("min"), spec.categoryAxisScaling.min));
5372
6435
  const children = [
5373
6436
  valNode(c("axId"), CAT_AX_ID),
5374
- elem(c("scaling"), { children: [valNode(c("orientation"), catOrientation)] }),
6437
+ elem(c("scaling"), { children: scalingChildren }),
5375
6438
  valNode(c("delete"), spec.categoryAxisHidden ? "1" : "0"),
5376
6439
  valNode(c("axPos"), isHorizontalBar(spec) ? "l" : "b")
5377
6440
  ];
@@ -5382,11 +6445,21 @@ const catAxis = (spec) => {
5382
6445
  if (spec.categoryAxisMajorTickMark !== void 0) children.push(valNode(c("majorTickMark"), spec.categoryAxisMajorTickMark));
5383
6446
  if (spec.categoryAxisMinorTickMark !== void 0) children.push(valNode(c("minorTickMark"), spec.categoryAxisMinorTickMark));
5384
6447
  if (spec.categoryAxisTickLabelPos !== void 0) children.push(valNode(c("tickLblPos"), spec.categoryAxisTickLabelPos));
5385
- const catLine = lineSpPr(spec.categoryAxisLineColor, spec.categoryAxisLineWidthEmu, "chart: categoryAxisLineWidthEmu");
6448
+ const catLine = lineSpPr(spec.categoryAxisLineColor, spec.categoryAxisLineWidthEmu, "chart: categoryAxisLineWidthEmu", spec.categoryAxisLineHidden === true);
5386
6449
  if (catLine !== null) children.push(catLine);
5387
6450
  const catTxPr = axisTxPrElement(spec.categoryAxisLabelStyle, spec.categoryAxisLabelRotationDeg);
5388
6451
  if (catTxPr) children.push(catTxPr);
5389
6452
  children.push(valNode(c("crossAx"), VAL_AX_ID));
6453
+ if (dateAxis !== void 0) {
6454
+ children.push(valNode(c("auto"), "0"));
6455
+ if (spec.categoryAxisLabelOffset !== void 0) children.push(valNode(c("lblOffset"), spec.categoryAxisLabelOffset));
6456
+ if (dateAxis.baseTimeUnit !== void 0) children.push(valNode(c("baseTimeUnit"), dateAxis.baseTimeUnit));
6457
+ if (dateAxis.majorUnit !== void 0) children.push(valNode(c("majorUnit"), dateAxis.majorUnit));
6458
+ if (dateAxis.majorTimeUnit !== void 0) children.push(valNode(c("majorTimeUnit"), dateAxis.majorTimeUnit));
6459
+ if (dateAxis.minorUnit !== void 0) children.push(valNode(c("minorUnit"), dateAxis.minorUnit));
6460
+ if (dateAxis.minorTimeUnit !== void 0) children.push(valNode(c("minorTimeUnit"), dateAxis.minorTimeUnit));
6461
+ return elem(c("dateAx"), { children });
6462
+ }
5390
6463
  if (spec.categoryAxisLabelAlign !== void 0) children.push(valNode(c("lblAlgn"), spec.categoryAxisLabelAlign));
5391
6464
  if (spec.categoryAxisLabelOffset !== void 0) children.push(valNode(c("lblOffset"), spec.categoryAxisLabelOffset));
5392
6465
  if (spec.categoryAxisTickLabelSkip !== void 0) children.push(valNode(c("tickLblSkip"), spec.categoryAxisTickLabelSkip));
@@ -5413,7 +6486,7 @@ const valueAxisElement = (f, ids) => {
5413
6486
  if (f.majorTickMark !== void 0) children.push(valNode(c("majorTickMark"), f.majorTickMark));
5414
6487
  if (f.minorTickMark !== void 0) children.push(valNode(c("minorTickMark"), f.minorTickMark));
5415
6488
  if (f.tickLabelPos !== void 0) children.push(valNode(c("tickLblPos"), f.tickLabelPos));
5416
- const axisLine = lineSpPr(f.lineColor, f.lineWidthEmu, `chart: ${f.widthFields.line}`);
6489
+ const axisLine = lineSpPr(f.lineColor, f.lineWidthEmu, `chart: ${f.widthFields.line}`, f.lineHidden === true);
5417
6490
  if (axisLine !== null) children.push(axisLine);
5418
6491
  const valTxPr = axisTxPrElement(f.labelStyle, f.labelRotationDeg);
5419
6492
  if (valTxPr) children.push(valTxPr);
@@ -5424,7 +6497,7 @@ const valueAxisElement = (f, ids) => {
5424
6497
  if (f.crossBetween !== void 0) children.push(valNode(c("crossBetween"), f.crossBetween));
5425
6498
  if (f.scaling?.majorUnit !== void 0) children.push(valNode(c("majorUnit"), f.scaling.majorUnit));
5426
6499
  if (f.scaling?.minorUnit !== void 0) children.push(valNode(c("minorUnit"), f.scaling.minorUnit));
5427
- if (f.scaling?.displayUnits !== void 0) children.push(elem(c("dispUnits"), { children: [valNode(c("builtInUnit"), f.scaling.displayUnits)] }));
6500
+ if (f.scaling?.displayUnits !== void 0) children.push(elem(c("dispUnits"), { children: [valNode(c("builtInUnit"), f.scaling.displayUnits), ...f.scaling.displayUnitsLabel === true ? [elem(c("dispUnitsLbl"))] : []] }));
5428
6501
  return elem(c("valAx"), { children });
5429
6502
  };
5430
6503
  const isHorizontalBar = (spec) => spec.kind === "bar";
@@ -5446,6 +6519,7 @@ const valAxis = (spec) => valueAxisElement({
5446
6519
  tickLabelPos: spec.valueAxisTickLabelPos,
5447
6520
  lineColor: spec.valueAxisLineColor,
5448
6521
  lineWidthEmu: spec.valueAxisLineWidthEmu,
6522
+ lineHidden: spec.valueAxisLineHidden,
5449
6523
  widthFields: {
5450
6524
  majorGridline: "valueAxisMajorGridlineWidthEmu",
5451
6525
  minorGridline: "valueAxisMinorGridlineWidthEmu",
@@ -5460,11 +6534,78 @@ const valAxis = (spec) => valueAxisElement({
5460
6534
  crossAxId: CAT_AX_ID,
5461
6535
  axPos: isHorizontalBar(spec) ? "b" : "l"
5462
6536
  });
6537
+ /**
6538
+ * The horizontal axis of a scatter / bubble chart. Both of their axes are
6539
+ * `<c:valAx>`; this one takes the spec's `categoryAxis*` fields, so an
6540
+ * author formats "the axis along the bottom" the same way for every kind.
6541
+ * It keeps the category axis' id, which the y axis already crosses.
6542
+ */
6543
+ const xValAxis = (spec) => valueAxisElement({
6544
+ scaling: {
6545
+ ...spec.categoryAxisScaling,
6546
+ ...spec.categoryAxisNumberFormat !== void 0 ? { numberFormat: spec.categoryAxisNumberFormat } : {}
6547
+ },
6548
+ orientation: spec.categoryAxisOrientation,
6549
+ hidden: spec.categoryAxisHidden,
6550
+ majorGridlines: spec.categoryAxisMajorGridlines,
6551
+ majorGridlineColor: spec.categoryAxisMajorGridlineColor,
6552
+ majorGridlineWidthEmu: spec.categoryAxisMajorGridlineWidthEmu,
6553
+ minorGridlines: spec.categoryAxisMinorGridlines,
6554
+ minorGridlineColor: spec.categoryAxisMinorGridlineColor,
6555
+ minorGridlineWidthEmu: spec.categoryAxisMinorGridlineWidthEmu,
6556
+ title: spec.categoryAxisTitle,
6557
+ titleStyle: spec.categoryAxisTitleStyle,
6558
+ titleRotationDeg: spec.categoryAxisTitleRotationDeg,
6559
+ majorTickMark: spec.categoryAxisMajorTickMark,
6560
+ minorTickMark: spec.categoryAxisMinorTickMark,
6561
+ tickLabelPos: spec.categoryAxisTickLabelPos,
6562
+ lineColor: spec.categoryAxisLineColor,
6563
+ lineWidthEmu: spec.categoryAxisLineWidthEmu,
6564
+ lineHidden: spec.categoryAxisLineHidden,
6565
+ widthFields: {
6566
+ majorGridline: "categoryAxisMajorGridlineWidthEmu",
6567
+ minorGridline: "categoryAxisMinorGridlineWidthEmu",
6568
+ line: "categoryAxisLineWidthEmu"
6569
+ },
6570
+ labelStyle: spec.categoryAxisLabelStyle,
6571
+ labelRotationDeg: spec.categoryAxisLabelRotationDeg,
6572
+ crosses: void 0,
6573
+ crossBetween: "midCat"
6574
+ }, {
6575
+ axId: CAT_AX_ID,
6576
+ crossAxId: VAL_AX_ID,
6577
+ axPos: "b"
6578
+ });
6579
+ const SER_AX_ID = 555555555;
6580
+ /** `<c:serAx>` — the depth axis of a 3-D or surface chart; it crosses the value axis. */
6581
+ const serAxis = (spec) => {
6582
+ const s = spec.seriesAxis ?? {};
6583
+ const children = [
6584
+ valNode(c("axId"), SER_AX_ID),
6585
+ elem(c("scaling"), { children: [valNode(c("orientation"), s.orientation ?? "minMax")] }),
6586
+ valNode(c("delete"), s.hidden ? "1" : "0"),
6587
+ valNode(c("axPos"), "b")
6588
+ ];
6589
+ if (s.majorGridlines) children.push(elem(c("majorGridlines")));
6590
+ if (s.title !== void 0) children.push(titleElement(s.title, s.titleStyle));
6591
+ if (s.tickLabelPos !== void 0) children.push(valNode(c("tickLblPos"), s.tickLabelPos));
6592
+ const line = lineSpPr(s.lineColor, void 0, "chart: seriesAxis");
6593
+ if (line !== null) children.push(line);
6594
+ const txPr = axisTxPrElement(s.labelStyle, void 0);
6595
+ if (txPr !== null) children.push(txPr);
6596
+ children.push(valNode(c("crossAx"), VAL_AX_ID));
6597
+ if (s.tickLabelSkip !== void 0) children.push(valNode(c("tickLblSkip"), s.tickLabelSkip));
6598
+ return elem(c("serAx"), { children });
6599
+ };
5463
6600
  const buildDLblsFromLabels = (dl, pointLabels = void 0) => {
5464
6601
  const children = [];
5465
6602
  pointLabels?.forEach((pl, i) => {
5466
6603
  if (pl === null) return;
5467
- children.push(elem(c("dLbl"), { children: [valNode(c("idx"), i), ...dLblGroupChildren(pl)] }));
6604
+ children.push(elem(c("dLbl"), { children: [
6605
+ valNode(c("idx"), i),
6606
+ ...pl.text !== void 0 ? [elem(c("tx"), { children: [richText(pl.text)] })] : [],
6607
+ ...dLblGroupChildren(pl)
6608
+ ] }));
5468
6609
  });
5469
6610
  if (dl) {
5470
6611
  children.push(...dLblGroupChildren(dl));
@@ -5475,93 +6616,220 @@ const buildDLblsFromLabels = (dl, pointLabels = void 0) => {
5475
6616
  const dLblGroupChildren = (dl) => {
5476
6617
  const children = [];
5477
6618
  if (dl.numberFormat !== void 0) children.push(elem(c("numFmt"), { attrs: [attr(qname("", "formatCode", ""), dl.numberFormat), attr(qname("", "sourceLinked", ""), "0")] }));
6619
+ if (dl.fillColor !== void 0) children.push(solidFillSpPr(dl.fillColor));
5478
6620
  if (dl.textStyle !== void 0) {
5479
6621
  const txPr = axisTxPrElement(dl.textStyle, void 0);
5480
6622
  if (txPr !== null) children.push(txPr);
5481
6623
  }
5482
6624
  if (dl.position !== void 0) children.push(valNode(c("dLblPos"), dl.position));
5483
- children.push(valNode(c("showLegendKey"), "0"), valNode(c("showVal"), dl.showValue ? "1" : "0"), valNode(c("showCatName"), dl.showCategory ? "1" : "0"), valNode(c("showSerName"), dl.showSeriesName ? "1" : "0"), valNode(c("showPercent"), dl.showPercent ? "1" : "0"), valNode(c("showBubbleSize"), "0"));
6625
+ children.push(valNode(c("showLegendKey"), dl.showLegendKey ? "1" : "0"), valNode(c("showVal"), dl.showValue ? "1" : "0"), valNode(c("showCatName"), dl.showCategory ? "1" : "0"), valNode(c("showSerName"), dl.showSeriesName ? "1" : "0"), valNode(c("showPercent"), dl.showPercent ? "1" : "0"), valNode(c("showBubbleSize"), dl.showBubbleSize ? "1" : "0"));
5484
6626
  if (dl.separator !== void 0) children.push(elem(c("separator"), { children: [text(dl.separator)] }));
5485
6627
  return children;
5486
6628
  };
5487
6629
  const dLblsElement = (spec) => buildDLblsFromLabels(spec.dataLabels);
5488
- const buildBarChart = (spec, sheet, direction, seriesIndices, axes) => {
5489
- const ser = seriesIndices.map((i) => seriesElement(spec, i, sheet));
5490
- const dl = dLblsElement(spec);
6630
+ const groupSeries = (g) => g.seriesIndices.map((i) => seriesElement(g.spec, i, g.layout));
6631
+ const groupDLbls = (g) => {
6632
+ const dl = dLblsElement(g.spec);
6633
+ return dl ? [dl] : [];
6634
+ };
6635
+ const isThreeD = (spec) => spec.view3D !== void 0;
6636
+ /**
6637
+ * Whether the chart carries a series (depth) axis. `<c:line3DChart>` and
6638
+ * the surface elements require three axes; 3-D bar / area charts only lay
6639
+ * their series out in depth — and so only have the axis — under the
6640
+ * `standard` grouping.
6641
+ */
6642
+ const hasSeriesAxis = (spec) => {
6643
+ if (spec.kind === "surface") return true;
6644
+ if (!isThreeD(spec)) return false;
6645
+ if (spec.kind === "line") return true;
6646
+ return (spec.kind === "bar" || spec.kind === "column" || spec.kind === "area") && spec.grouping === "standard";
6647
+ };
6648
+ const axIdNodes = (g) => [
6649
+ valNode(c("axId"), g.axes.cat),
6650
+ valNode(c("axId"), g.axes.val),
6651
+ ...hasSeriesAxis(g.spec) ? [valNode(c("axId"), SER_AX_ID)] : []
6652
+ ];
6653
+ const gapDepthNodes = (spec) => spec.gapDepthPct !== void 0 ? [valNode(c("gapDepth"), gapAmountPercent(spec.gapDepthPct, "chart: gapDepthPct"))] : [];
6654
+ const buildBarChart = (g, direction) => {
6655
+ const { spec } = g;
5491
6656
  const grouping = spec.grouping ?? "clustered";
5492
6657
  const children = [
5493
6658
  valNode(c("barDir"), direction),
5494
6659
  valNode(c("grouping"), grouping),
5495
6660
  valNode(c("varyColors"), spec.varyColors ? "1" : "0"),
5496
- ...ser,
5497
- ...dl ? [dl] : []
6661
+ ...groupSeries(g),
6662
+ ...groupDLbls(g)
5498
6663
  ];
5499
6664
  if (spec.gapWidthPct !== void 0) children.push(valNode(c("gapWidth"), gapAmountPercent(spec.gapWidthPct, "chart: gapWidthPct")));
6665
+ if (isThreeD(spec)) {
6666
+ children.push(...gapDepthNodes(spec));
6667
+ if (spec.bar3DShape !== void 0) children.push(valNode(c("shape"), spec.bar3DShape));
6668
+ children.push(...axIdNodes(g));
6669
+ return elem(c("bar3DChart"), { children });
6670
+ }
5500
6671
  const overlapPct = spec.overlapPct ?? (grouping === "stacked" || grouping === "percentStacked" ? 100 : void 0);
5501
6672
  if (overlapPct !== void 0) children.push(valNode(c("overlap"), overlapPercent(overlapPct, "chart: overlapPct")));
5502
- children.push(valNode(c("axId"), axes.cat), valNode(c("axId"), axes.val));
5503
- return elem(c(direction === "col" ? "barChart" : "barChart"), { children });
6673
+ children.push(...axIdNodes(g));
6674
+ return elem(c("barChart"), { children });
5504
6675
  };
5505
6676
  const lineAreaGrouping = (spec) => spec.grouping === "stacked" || spec.grouping === "percentStacked" ? spec.grouping : "standard";
5506
- const buildLineChart = (spec, sheet, seriesIndices, axes) => {
5507
- const ser = seriesIndices.map((i) => seriesElement(spec, i, sheet));
5508
- const dl = dLblsElement(spec);
6677
+ const upDownBarsElement = (bars) => {
6678
+ const bar = (name, color) => elem(c(name), { children: color !== void 0 ? [solidFillSpPr(color)] : [] });
6679
+ return elem(c("upDownBars"), { children: [
6680
+ ...bars.gapWidthPct !== void 0 ? [valNode(c("gapWidth"), gapAmountPercent(bars.gapWidthPct, "chart: upDownBars.gapWidthPct"))] : [],
6681
+ bar("upBars", bars.upColor),
6682
+ bar("downBars", bars.downColor)
6683
+ ] });
6684
+ };
6685
+ const buildLineChart = (g) => {
6686
+ const { spec } = g;
5509
6687
  const children = [
5510
6688
  valNode(c("grouping"), lineAreaGrouping(spec)),
5511
6689
  valNode(c("varyColors"), spec.varyColors ? "1" : "0"),
5512
- ...ser,
5513
- ...dl ? [dl] : []
6690
+ ...groupSeries(g),
6691
+ ...groupDLbls(g)
5514
6692
  ];
5515
6693
  if (spec.dropLines) children.push(elem(c("dropLines")));
6694
+ if (isThreeD(spec)) {
6695
+ if (spec.hiLowLines || spec.upDownBars !== void 0) throw new Error("chart: hiLowLines / upDownBars are not available on a 3-D line chart");
6696
+ children.push(...gapDepthNodes(spec), ...axIdNodes(g));
6697
+ return elem(c("line3DChart"), { children });
6698
+ }
5516
6699
  if (spec.hiLowLines) children.push(elem(c("hiLowLines")));
5517
- children.push(valNode(c("marker"), spec.lineMarkers === false ? "0" : "1"), valNode(c("axId"), axes.cat), valNode(c("axId"), axes.val));
6700
+ if (spec.upDownBars !== void 0) children.push(upDownBarsElement(spec.upDownBars));
6701
+ children.push(valNode(c("marker"), spec.lineMarkers === false ? "0" : "1"), ...axIdNodes(g));
5518
6702
  return elem(c("lineChart"), { children });
5519
6703
  };
5520
- const buildPieChart = (spec, sheet) => {
5521
- if (spec.series.length !== 1) throw new Error("pie chart requires exactly one series");
5522
- const ser = seriesElement(spec, 0, sheet);
5523
- const dl = dLblsElement(spec);
6704
+ const buildAreaChart = (g) => {
6705
+ const { spec } = g;
5524
6706
  const children = [
5525
- valNode(c("varyColors"), "1"),
5526
- ser,
5527
- ...dl ? [dl] : []
6707
+ valNode(c("grouping"), lineAreaGrouping(spec)),
6708
+ valNode(c("varyColors"), spec.varyColors ? "1" : "0"),
6709
+ ...groupSeries(g),
6710
+ ...groupDLbls(g)
5528
6711
  ];
5529
- if (spec.firstSliceAngleDeg !== void 0) children.push(valNode(c("firstSliceAng"), firstSliceAngle(spec.firstSliceAngleDeg, "chart: firstSliceAngleDeg")));
5530
- return elem(c("pieChart"), { children });
6712
+ if (spec.dropLines && spec.kind === "area") children.push(elem(c("dropLines")));
6713
+ if (isThreeD(spec)) {
6714
+ children.push(...gapDepthNodes(spec), ...axIdNodes(g));
6715
+ return elem(c("area3DChart"), { children });
6716
+ }
6717
+ children.push(...axIdNodes(g));
6718
+ return elem(c("areaChart"), { children });
5531
6719
  };
5532
- const buildDoughnutChart = (spec, sheet) => {
5533
- if (spec.series.length !== 1) throw new Error("doughnut chart requires exactly one series");
5534
- const ser = seriesElement(spec, 0, sheet);
5535
- const dl = dLblsElement(spec);
6720
+ const requireSingleSeries = (spec) => {
6721
+ if (spec.series.length !== 1) throw new Error(`${spec.kind} chart requires exactly one series`);
6722
+ };
6723
+ const firstSliceAngNodes = (spec) => spec.firstSliceAngleDeg !== void 0 ? [valNode(c("firstSliceAng"), firstSliceAngle(spec.firstSliceAngleDeg, "chart: firstSliceAngleDeg"))] : [];
6724
+ const buildOfPieChart = (g, ofPie) => {
5536
6725
  const children = [
6726
+ valNode(c("ofPieType"), ofPie.type),
5537
6727
  valNode(c("varyColors"), "1"),
5538
- ser,
5539
- ...dl ? [dl] : []
6728
+ ...groupSeries(g),
6729
+ ...groupDLbls(g)
5540
6730
  ];
5541
- if (spec.firstSliceAngleDeg !== void 0) children.push(valNode(c("firstSliceAng"), firstSliceAngle(spec.firstSliceAngleDeg, "chart: firstSliceAngleDeg")));
5542
- children.push(valNode(c("holeSize"), holeSizePercent(spec.holeSizePct ?? 50, "chart: holeSizePct")));
5543
- return elem(c("doughnutChart"), { children });
5544
- };
5545
- const buildAreaChart = (spec, sheet, seriesIndices, axes) => {
5546
- const ser = seriesIndices.map((i) => seriesElement(spec, i, sheet));
5547
- const dl = dLblsElement(spec);
5548
- return elem(c("areaChart"), { children: [
5549
- valNode(c("grouping"), lineAreaGrouping(spec)),
5550
- valNode(c("varyColors"), spec.varyColors ? "1" : "0"),
5551
- ...ser,
5552
- ...dl ? [dl] : [],
5553
- valNode(c("axId"), axes.cat),
5554
- valNode(c("axId"), axes.val)
6731
+ if (ofPie.gapWidthPct !== void 0) children.push(valNode(c("gapWidth"), gapAmountPercent(ofPie.gapWidthPct, "chart: ofPie.gapWidthPct")));
6732
+ if (ofPie.customSplit !== void 0 && ofPie.splitType !== "cust") throw new Error("chart: ofPie.customSplit requires ofPie.splitType 'cust'");
6733
+ if (ofPie.splitType !== void 0) children.push(valNode(c("splitType"), ofPie.splitType));
6734
+ if (ofPie.splitPos !== void 0) children.push(valNode(c("splitPos"), ofPie.splitPos));
6735
+ if (ofPie.customSplit !== void 0) children.push(elem(c("custSplit"), { children: ofPie.customSplit.map((idx) => valNode(c("secondPiePt"), idx)) }));
6736
+ if (ofPie.secondPieSizePct !== void 0) children.push(valNode(c("secondPieSize"), boundedInt(ofPie.secondPieSizePct, "secondPieSize", "chart: ofPie.secondPieSizePct")));
6737
+ if (ofPie.seriesLines) children.push(elem(c("serLines")));
6738
+ return elem(c("ofPieChart"), { children });
6739
+ };
6740
+ const buildPieChart = (g) => {
6741
+ const { spec } = g;
6742
+ requireSingleSeries(spec);
6743
+ if (spec.ofPie !== void 0) {
6744
+ if (isThreeD(spec)) throw new Error("chart: ofPie and view3D cannot be combined");
6745
+ return buildOfPieChart(g, spec.ofPie);
6746
+ }
6747
+ const children = [
6748
+ valNode(c("varyColors"), "1"),
6749
+ ...groupSeries(g),
6750
+ ...groupDLbls(g)
6751
+ ];
6752
+ if (isThreeD(spec)) {
6753
+ if (spec.firstSliceAngleDeg !== void 0) throw new Error("chart: a 3-D pie has no firstSliceAngleDeg; rotate it with view3D.rotY");
6754
+ return elem(c("pie3DChart"), { children });
6755
+ }
6756
+ children.push(...firstSliceAngNodes(spec));
6757
+ return elem(c("pieChart"), { children });
6758
+ };
6759
+ const buildDoughnutChart = (g) => {
6760
+ const { spec } = g;
6761
+ requireSingleSeries(spec);
6762
+ return elem(c("doughnutChart"), { children: [
6763
+ valNode(c("varyColors"), "1"),
6764
+ ...groupSeries(g),
6765
+ ...groupDLbls(g),
6766
+ ...firstSliceAngNodes(spec),
6767
+ valNode(c("holeSize"), holeSizePercent(spec.holeSizePct ?? 50, "chart: holeSizePct"))
5555
6768
  ] });
5556
6769
  };
5557
- /** One combo plot group, dispatched by its effective kind. */
5558
- const buildComboGroupChart = (spec, sheet, kind, seriesIndices, axes) => {
6770
+ const buildScatterChart = (g) => elem(c("scatterChart"), { children: [
6771
+ valNode(c("scatterStyle"), g.spec.scatterStyle ?? "marker"),
6772
+ valNode(c("varyColors"), g.spec.varyColors ? "1" : "0"),
6773
+ ...groupSeries(g),
6774
+ ...groupDLbls(g),
6775
+ ...axIdNodes(g)
6776
+ ] });
6777
+ const buildBubbleChart = (g) => {
6778
+ const { spec } = g;
6779
+ const children = [
6780
+ valNode(c("varyColors"), spec.varyColors ? "1" : "0"),
6781
+ ...groupSeries(g),
6782
+ ...groupDLbls(g)
6783
+ ];
6784
+ if (spec.bubbleScale !== void 0) children.push(valNode(c("bubbleScale"), boundedInt(spec.bubbleScale, "bubbleScale", "chart: bubbleScale")));
6785
+ if (spec.showNegativeBubbles !== void 0) children.push(valNode(c("showNegBubbles"), spec.showNegativeBubbles ? "1" : "0"));
6786
+ if (spec.bubbleSizeRepresents !== void 0) children.push(valNode(c("sizeRepresents"), spec.bubbleSizeRepresents === "width" ? "w" : "area"));
6787
+ children.push(...axIdNodes(g));
6788
+ return elem(c("bubbleChart"), { children });
6789
+ };
6790
+ const buildRadarChart = (g) => elem(c("radarChart"), { children: [
6791
+ valNode(c("radarStyle"), g.spec.radarStyle ?? "standard"),
6792
+ valNode(c("varyColors"), g.spec.varyColors ? "1" : "0"),
6793
+ ...groupSeries(g),
6794
+ ...groupDLbls(g),
6795
+ ...axIdNodes(g)
6796
+ ] });
6797
+ const STOCK_SERIES_WITH_OPEN = 4;
6798
+ const STOCK_SERIES_WITHOUT_OPEN = 3;
6799
+ const buildStockChart = (g) => {
6800
+ const { spec } = g;
6801
+ const count = spec.series.length;
6802
+ if (count !== STOCK_SERIES_WITHOUT_OPEN && count !== STOCK_SERIES_WITH_OPEN) throw new Error(`stock chart requires 3 series (high, low, close) or 4 (open, high, low, close); got ${count}`);
6803
+ const children = [...groupSeries(g), ...groupDLbls(g)];
6804
+ if (spec.dropLines) children.push(elem(c("dropLines")));
6805
+ if (spec.hiLowLines !== false) children.push(elem(c("hiLowLines")));
6806
+ if (spec.upDownBars !== void 0 && count !== STOCK_SERIES_WITH_OPEN) throw new Error("stock chart: upDownBars require the 4-series form (open, high, low, close)");
6807
+ if (count === STOCK_SERIES_WITH_OPEN) children.push(upDownBarsElement(spec.upDownBars ?? {}));
6808
+ children.push(...axIdNodes(g));
6809
+ return elem(c("stockChart"), { children });
6810
+ };
6811
+ const buildSurfaceChart = (g) => {
6812
+ const { spec } = g;
6813
+ const children = [];
6814
+ if (spec.surfaceWireframe !== void 0) children.push(valNode(c("wireframe"), spec.surfaceWireframe ? "1" : "0"));
6815
+ children.push(...groupSeries(g), ...axIdNodes(g));
6816
+ return elem(c(spec.surfaceContour === true ? "surfaceChart" : "surface3DChart"), { children });
6817
+ };
6818
+ /** One plot group, dispatched by its effective kind. */
6819
+ const buildPlotGroup = (g, kind) => {
5559
6820
  switch (kind) {
5560
- case "column": return buildBarChart(spec, sheet, "col", seriesIndices, axes);
5561
- case "bar": return buildBarChart(spec, sheet, "bar", seriesIndices, axes);
5562
- case "line": return buildLineChart(spec, sheet, seriesIndices, axes);
5563
- case "area": return buildAreaChart(spec, sheet, seriesIndices, axes);
5564
- default: throw new Error(`combo chart: series chartKind '${kind}' is not authorable`);
6821
+ case "column": return buildBarChart(g, "col");
6822
+ case "bar": return buildBarChart(g, "bar");
6823
+ case "line": return buildLineChart(g);
6824
+ case "area": return buildAreaChart(g);
6825
+ case "pie": return buildPieChart(g);
6826
+ case "doughnut": return buildDoughnutChart(g);
6827
+ case "scatter": return buildScatterChart(g);
6828
+ case "bubble": return buildBubbleChart(g);
6829
+ case "radar": return buildRadarChart(g);
6830
+ case "stock": return buildStockChart(g);
6831
+ case "surface": return buildSurfaceChart(g);
6832
+ default: throw new Error(`unsupported chart kind: ${String(kind)}`);
5565
6833
  }
5566
6834
  };
5567
6835
  /**
@@ -5590,6 +6858,7 @@ const secondaryValAxis = (spec) => {
5590
6858
  tickLabelPos: s.tickLabelPos,
5591
6859
  lineColor: s.lineColor,
5592
6860
  lineWidthEmu: s.lineWidthEmu,
6861
+ lineHidden: void 0,
5593
6862
  widthFields: {
5594
6863
  majorGridline: "secondaryValueAxis.majorGridlineWidthEmu",
5595
6864
  minorGridline: "secondaryValueAxis.minorGridlineWidthEmu",
@@ -5640,7 +6909,20 @@ const rPrAttrsFromStyle = (style) => {
5640
6909
  children
5641
6910
  };
5642
6911
  };
5643
- const titleElement = (title, style, rotationDeg) => {
6912
+ const manualLayoutElement = (position, size, target) => elem(c("layout"), { children: [elem(c("manualLayout"), { children: [
6913
+ ...target !== void 0 ? [valNode(c("layoutTarget"), target)] : [],
6914
+ valNode(c("xMode"), "edge"),
6915
+ valNode(c("yMode"), "edge"),
6916
+ valNode(c("x"), position.x),
6917
+ valNode(c("y"), position.y),
6918
+ ...size !== void 0 ? [valNode(c("w"), size.w), valNode(c("h"), size.h)] : []
6919
+ ] })] });
6920
+ const richText = (value) => elem(c("rich"), { children: [
6921
+ elem(a("bodyPr")),
6922
+ elem(a("lstStyle")),
6923
+ elem(a("p"), { children: [elem(a("r"), { children: [elem(a("t"), { children: [text(value)] })] })] })
6924
+ ] });
6925
+ const titleElement = (title, style, rotationDeg, placement) => {
5644
6926
  const pPr = elem(a("pPr"), { children: [elem(a("defRPr"))] });
5645
6927
  const { attrs: runAttrs, children: runChildren } = rPrAttrsFromStyle(style);
5646
6928
  const runRPr = elem(a("rPr"), {
@@ -5662,7 +6944,95 @@ const titleElement = (title, style, rotationDeg) => {
5662
6944
  elem(a("lstStyle")),
5663
6945
  para
5664
6946
  ] });
5665
- return elem(c("title"), { children: [elem(c("tx"), { children: [rich] }), valNode(c("overlay"), "0")] });
6947
+ return elem(c("title"), { children: [
6948
+ elem(c("tx"), { children: [rich] }),
6949
+ ...placement?.layout !== void 0 ? [manualLayoutElement(placement.layout)] : [],
6950
+ valNode(c("overlay"), placement?.overlay === true ? "1" : "0")
6951
+ ] });
6952
+ };
6953
+ const view3DDefaults = (spec) => {
6954
+ if (spec.kind === "surface" && spec.surfaceContour === true) return {
6955
+ rotX: 90,
6956
+ rotY: 0,
6957
+ rightAngleAxes: false,
6958
+ perspective: 0
6959
+ };
6960
+ if (spec.kind === "pie") return {
6961
+ rotX: 30,
6962
+ rotY: 0,
6963
+ rightAngleAxes: false
6964
+ };
6965
+ if (spec.kind === "surface") return {
6966
+ rotX: 15,
6967
+ rotY: 20,
6968
+ rightAngleAxes: false,
6969
+ perspective: 30
6970
+ };
6971
+ return {
6972
+ rotX: 15,
6973
+ rotY: 20,
6974
+ rightAngleAxes: true
6975
+ };
6976
+ };
6977
+ const view3DElement = (spec) => {
6978
+ const v = {
6979
+ ...view3DDefaults(spec),
6980
+ ...spec.view3D
6981
+ };
6982
+ const children = [];
6983
+ if (v.rotX !== void 0) children.push(valNode(c("rotX"), boundedInt(v.rotX, "rotX", "chart: view3D.rotX")));
6984
+ if (v.heightPercent !== void 0) children.push(valNode(c("hPercent"), boundedInt(v.heightPercent, "heightPercent", "chart: view3D.heightPercent")));
6985
+ if (v.rotY !== void 0) children.push(valNode(c("rotY"), boundedInt(v.rotY, "rotY", "chart: view3D.rotY")));
6986
+ if (v.depthPercent !== void 0) children.push(valNode(c("depthPercent"), boundedInt(v.depthPercent, "depthPercent", "chart: view3D.depthPercent")));
6987
+ if (v.rightAngleAxes !== void 0) children.push(valNode(c("rAngAx"), v.rightAngleAxes ? "1" : "0"));
6988
+ if (v.perspective !== void 0) children.push(valNode(c("perspective"), boundedInt(v.perspective, "perspective", "chart: view3D.perspective")));
6989
+ return elem(c("view3D"), { children });
6990
+ };
6991
+ const KINDS_WITH_VIEW_3D = new Set([
6992
+ "bar",
6993
+ "column",
6994
+ "line",
6995
+ "area",
6996
+ "pie",
6997
+ "surface"
6998
+ ]);
6999
+ const AXISLESS_KINDS = new Set(["pie", "doughnut"]);
7000
+ const XY_KINDS = new Set(["scatter", "bubble"]);
7001
+ const validateSpec = (spec, usesComboFields) => {
7002
+ if (usesComboFields && !COMBO_KINDS.has(spec.kind)) throw new Error(`chart kind '${spec.kind}' does not support per-series chartKind / secondaryAxis (combo charts require a bar / column / line / area base kind)`);
7003
+ if (spec.view3D !== void 0) {
7004
+ if (!KINDS_WITH_VIEW_3D.has(spec.kind)) throw new Error(`chart kind '${spec.kind}' has no 3-D variant; view3D applies to bar / column / line / area / pie / surface`);
7005
+ if (usesComboFields) throw new Error("chart: view3D cannot be combined with a combo chart");
7006
+ }
7007
+ if ((spec.bar3DShape !== void 0 || spec.gapDepthPct !== void 0) && spec.view3D === void 0) throw new Error("chart: bar3DShape / gapDepthPct require view3D");
7008
+ if (spec.ofPie !== void 0 && spec.kind !== "pie") throw new Error(`chart: ofPie applies to kind 'pie', not '${spec.kind}'`);
7009
+ if (spec.dataTable !== void 0 && (AXISLESS_KINDS.has(spec.kind) || XY_KINDS.has(spec.kind))) throw new Error(`chart kind '${spec.kind}' cannot show a data table`);
7010
+ if (spec.categoryAxisDate !== void 0) {
7011
+ if (AXISLESS_KINDS.has(spec.kind) || XY_KINDS.has(spec.kind)) throw new Error(`chart kind '${spec.kind}' has no category axis to make a date axis of`);
7012
+ if (spec.categoryGroupLevels !== void 0) throw new Error("chart: a date axis cannot have categoryGroupLevels");
7013
+ spec.categories.forEach((category, i) => {
7014
+ if (category.trim() === "" || !Number.isFinite(Number(category))) throw new Error(`chart: categories[${i}] is ${JSON.stringify(category)}; a date axis needs date serial numbers (e.g. "45292" for 2024-01-01)`);
7015
+ });
7016
+ }
7017
+ if (spec.categoryAxisScaling !== void 0 && spec.categoryAxisDate === void 0 && !XY_KINDS.has(spec.kind)) throw new Error("chart: categoryAxisScaling needs a numeric horizontal axis — a scatter / bubble chart or a date axis");
7018
+ spec.categoryGroupLevels?.forEach((level, i) => {
7019
+ if (level.length !== spec.categories.length) throw new Error(`chart: categoryGroupLevels[${i}] has ${level.length} entries for ${spec.categories.length} categories`);
7020
+ });
7021
+ if (XY_KINDS.has(spec.kind)) spec.series.forEach((series) => {
7022
+ if (series.xValues === void 0) throw new Error(`chart: ${spec.kind} series '${series.name}' needs xValues`);
7023
+ if (spec.kind === "bubble" && series.bubbleSizes === void 0) throw new Error(`chart: bubble series '${series.name}' needs bubbleSizes`);
7024
+ });
7025
+ };
7026
+ const dataTableElement = (table) => {
7027
+ const children = [
7028
+ valNode(c("showHorzBorder"), table.showHorizontalBorder === false ? "0" : "1"),
7029
+ valNode(c("showVertBorder"), table.showVerticalBorder === false ? "0" : "1"),
7030
+ valNode(c("showOutline"), table.showOutline === false ? "0" : "1"),
7031
+ valNode(c("showKeys"), table.showKeys === false ? "0" : "1")
7032
+ ];
7033
+ const txPr = axisTxPrElement(table.textStyle, void 0);
7034
+ if (txPr !== null) children.push(txPr);
7035
+ return elem(c("dTable"), { children });
5666
7036
  };
5667
7037
  /**
5668
7038
  * Builds a complete `<c:chartSpace>` document for `spec`. The caller
@@ -5670,55 +7040,48 @@ const titleElement = (title, style, rotationDeg) => {
5670
7040
  * `r:id="rId1"` for the embedded workbook.
5671
7041
  */
5672
7042
  const buildChartSpaceDoc = (spec) => {
5673
- const sheet = "Sheet1";
5674
7043
  const usesComboFields = spec.series.some((series) => series.chartKind !== void 0 || series.secondaryAxis === true);
5675
- if (usesComboFields && !COMBO_KINDS.has(spec.kind)) throw new Error(`chart kind '${spec.kind}' does not support per-series chartKind / secondaryAxis (combo charts require a bar / column / line / area base kind)`);
5676
- const allIndices = spec.series.map((_, i) => i);
7044
+ validateSpec(spec, usesComboFields);
7045
+ const layout = layoutChartSheet(spec);
5677
7046
  let plottedGroups;
5678
7047
  let hasSecondary = false;
5679
- switch (spec.kind) {
5680
- case "column":
5681
- case "bar":
5682
- case "line":
5683
- case "area":
5684
- if (usesComboFields) {
5685
- const groups = comboPlotGroups(spec);
5686
- hasSecondary = groups.some((group) => group.secondary);
5687
- plottedGroups = groups.map((group) => buildComboGroupChart(spec, sheet, group.kind, group.indices, group.secondary ? SECONDARY_AXES : PRIMARY_AXES));
5688
- } else plottedGroups = [buildComboGroupChart(spec, sheet, spec.kind, allIndices, PRIMARY_AXES)];
5689
- break;
5690
- case "pie":
5691
- plottedGroups = [buildPieChart(spec, sheet)];
5692
- break;
5693
- case "doughnut":
5694
- plottedGroups = [buildDoughnutChart(spec, sheet)];
5695
- break;
5696
- case "scatter":
5697
- case "radar":
5698
- case "bubble": throw new Error(`chart kind '${spec.kind}' is read-only; authoring scatter / radar / bubble charts is not yet supported`);
5699
- default: {
5700
- const exhaustive = spec.kind;
5701
- throw new Error(`unsupported chart kind: ${String(exhaustive)}`);
5702
- }
5703
- }
5704
- const axisless = spec.kind === "pie" || spec.kind === "doughnut";
5705
- const plotAreaChildren = [elem(c("layout")), ...plottedGroups];
5706
- if (!axisless) {
5707
- plotAreaChildren.push(catAxis(spec), valAxis(spec));
7048
+ if (usesComboFields) {
7049
+ const groups = comboPlotGroups(spec);
7050
+ hasSecondary = groups.some((group) => group.secondary);
7051
+ plottedGroups = groups.map((group) => buildPlotGroup({
7052
+ spec,
7053
+ layout,
7054
+ seriesIndices: group.indices,
7055
+ axes: group.secondary ? SECONDARY_AXES : PRIMARY_AXES
7056
+ }, group.kind));
7057
+ } else plottedGroups = [buildPlotGroup({
7058
+ spec,
7059
+ layout,
7060
+ seriesIndices: spec.series.map((_, i) => i),
7061
+ axes: PRIMARY_AXES
7062
+ }, spec.kind)];
7063
+ const plotLayout = spec.plotAreaLayout;
7064
+ const plotAreaChildren = [plotLayout !== void 0 ? manualLayoutElement(plotLayout, plotLayout, plotLayout.target) : elem(c("layout")), ...plottedGroups];
7065
+ if (!AXISLESS_KINDS.has(spec.kind)) {
7066
+ plotAreaChildren.push(XY_KINDS.has(spec.kind) ? xValAxis(spec) : catAxis(spec), valAxis(spec));
7067
+ if (hasSeriesAxis(spec)) plotAreaChildren.push(serAxis(spec));
5708
7068
  if (hasSecondary) plotAreaChildren.push(secondaryValAxis(spec), secondaryCatAxis(spec));
5709
7069
  }
7070
+ if (spec.dataTable !== void 0) plotAreaChildren.push(dataTableElement(spec.dataTable));
5710
7071
  if (spec.plotAreaFill !== void 0 || spec.plotAreaStrokeColor !== void 0) plotAreaChildren.push(spPrChildren(spec.plotAreaFill, spec.plotAreaStrokeColor));
5711
7072
  const plotArea = elem(c("plotArea"), { children: plotAreaChildren });
5712
7073
  const chartChildren = [];
5713
- if (spec.title !== void 0) {
5714
- const titleEl = titleElement(spec.title, spec.titleStyle);
5715
- if (spec.titleOverlay !== void 0) titleEl.children = [...titleEl.children.filter((c2) => !(c2.kind === "element" && c2.name.namespaceURI === NS_C$1 && c2.name.localName === "overlay")), valNode(c("overlay"), spec.titleOverlay ? "1" : "0")];
5716
- chartChildren.push(titleEl);
5717
- }
5718
- chartChildren.push(valNode(c("autoTitleDeleted"), spec.title !== void 0 ? "0" : "1"), plotArea);
7074
+ if (spec.title !== void 0) chartChildren.push(titleElement(spec.title, spec.titleStyle, void 0, {
7075
+ ...spec.titleOverlay !== void 0 ? { overlay: spec.titleOverlay } : {},
7076
+ ...spec.titleLayout !== void 0 ? { layout: spec.titleLayout } : {}
7077
+ }));
7078
+ chartChildren.push(valNode(c("autoTitleDeleted"), spec.title !== void 0 ? "0" : "1"));
7079
+ if (spec.view3D !== void 0 || spec.kind === "surface") chartChildren.push(view3DElement(spec));
7080
+ chartChildren.push(plotArea);
5719
7081
  if (spec.legend !== void 0 && spec.legend.position !== null) {
5720
7082
  const legendChildren = [valNode(c("legendPos"), spec.legend.position)];
5721
7083
  for (const idx of spec.legend.hiddenIndices ?? []) legendChildren.push(elem(c("legendEntry"), { children: [valNode(c("idx"), idx), valNode(c("delete"), "1")] }));
7084
+ if (spec.legend.layout !== void 0) legendChildren.push(manualLayoutElement(spec.legend.layout, spec.legend.layout));
5722
7085
  legendChildren.push(valNode(c("overlay"), spec.legend.overlay ? "1" : "0"));
5723
7086
  if (spec.legend.textStyle !== void 0) {
5724
7087
  const txPr = axisTxPrElement(spec.legend.textStyle, void 0);
@@ -5852,15 +7215,15 @@ const KIND_MAP = [
5852
7215
  },
5853
7216
  {
5854
7217
  localName: "stockChart",
5855
- kind: "line"
7218
+ kind: "stock"
5856
7219
  },
5857
7220
  {
5858
7221
  localName: "surfaceChart",
5859
- kind: "column"
7222
+ kind: "surface"
5860
7223
  },
5861
7224
  {
5862
7225
  localName: "surface3DChart",
5863
- kind: "column"
7226
+ kind: "surface"
5864
7227
  }
5865
7228
  ];
5866
7229
  const findFirst = (parent, names) => {
@@ -6293,6 +7656,10 @@ const readDataLabelsGroup = (host, inherited) => {
6293
7656
  const separator = readDataLabelSeparator(host);
6294
7657
  const txPrEl = firstChildElement(host, qname("c", "txPr", NS_C));
6295
7658
  const textStyle = txPrEl ? readLabelStyle(txPrEl) : void 0;
7659
+ const showBubbleSize = readToggle("showBubbleSize", inherited?.showBubbleSize ?? false);
7660
+ const showLegendKey = readToggle("showLegendKey", inherited?.showLegendKey ?? false);
7661
+ const spPr = firstChildElement(host, NAME_SP_PR_C);
7662
+ const fillColor = spPr !== null ? readSolidSrgb(spPr) : void 0;
6296
7663
  return {
6297
7664
  showValue: readToggle("showVal", inherited?.showValue ?? false),
6298
7665
  showCategory: readToggle("showCatName", inherited?.showCategory ?? false),
@@ -6301,9 +7668,28 @@ const readDataLabelsGroup = (host, inherited) => {
6301
7668
  ...numberFormat !== void 0 ? { numberFormat } : {},
6302
7669
  ...position !== void 0 ? { position } : {},
6303
7670
  ...separator !== void 0 ? { separator } : {},
6304
- ...textStyle !== void 0 ? { textStyle } : {}
7671
+ ...textStyle !== void 0 ? { textStyle } : {},
7672
+ ...showBubbleSize ? { showBubbleSize } : {},
7673
+ ...showLegendKey ? { showLegendKey } : {},
7674
+ ...fillColor !== void 0 ? { fillColor } : {}
6305
7675
  };
6306
7676
  };
7677
+ const readRichText = (host) => {
7678
+ const tx = firstChildElement(host, NAME_TX);
7679
+ const rich = tx !== null ? firstChildElement(tx, NAME_RICH) : null;
7680
+ if (rich === null) return void 0;
7681
+ const paragraphs = [];
7682
+ for (const p of allChildElements(rich, NAME_P_DML)) {
7683
+ let line = "";
7684
+ for (const r of allChildElements(p, NAME_R_DML)) {
7685
+ const t = firstChildElement(r, NAME_T);
7686
+ if (t === null) continue;
7687
+ for (const child of t.children) if (child.kind === "text" || child.kind === "cdata") line += child.data;
7688
+ }
7689
+ paragraphs.push(line);
7690
+ }
7691
+ return paragraphs.join("\n");
7692
+ };
6307
7693
  const readSeriesLevelDataLabels = (dLbls) => {
6308
7694
  const group = readDataLabelsGroup(dLbls, void 0);
6309
7695
  const leaderEl = firstChildElement(dLbls, qname("c", "showLeaderLines", NS_C));
@@ -6326,7 +7712,15 @@ const readPointDataLabels = (dLbls, pointCount, seriesLabels) => {
6326
7712
  const idx = readPointIndex(dLbl, pointCount);
6327
7713
  if (idx === null) continue;
6328
7714
  const deleteEl = firstChildElement(dLbl, qname("c", "delete", NS_C));
6329
- out[idx] = deleteEl !== null && readXmlBool(deleteEl) ? DELETED_POINT_LABEL : readDataLabelsGroup(dLbl, seriesLabels);
7715
+ if (deleteEl !== null && readXmlBool(deleteEl)) out[idx] = DELETED_POINT_LABEL;
7716
+ else {
7717
+ const group = readDataLabelsGroup(dLbl, seriesLabels);
7718
+ const literal = readRichText(dLbl);
7719
+ out[idx] = literal !== void 0 ? {
7720
+ ...group,
7721
+ text: literal
7722
+ } : group;
7723
+ }
6330
7724
  any = true;
6331
7725
  }
6332
7726
  if (!any) return void 0;
@@ -6340,6 +7734,7 @@ const readValueAxisScaling = (valAx) => {
6340
7734
  let minorUnit;
6341
7735
  let logBase;
6342
7736
  let displayUnits;
7737
+ let displayUnitsLabel = false;
6343
7738
  const scaling = firstChildElement(valAx, qname("c", "scaling", NS_C));
6344
7739
  const readNumOn = (parent, local) => {
6345
7740
  const el = firstChildElement(parent, qname("c", local, NS_C));
@@ -6376,23 +7771,300 @@ const readValueAxisScaling = (valAx) => {
6376
7771
  break;
6377
7772
  }
6378
7773
  }
7774
+ displayUnitsLabel = firstChildElement(dispUnits, qname("c", "dispUnitsLbl", NS_C)) !== null;
7775
+ }
7776
+ let numberFormat;
7777
+ const nfEl = firstChildElement(valAx, qname("c", "numFmt", NS_C));
7778
+ if (nfEl) {
7779
+ const fc = getAttrValue(nfEl, qname("", "formatCode", ""));
7780
+ if (fc !== null && fc.length > 0 && fc !== "General") numberFormat = fc;
7781
+ }
7782
+ if (min !== void 0 || max !== void 0 || majorUnit !== void 0 || minorUnit !== void 0 || numberFormat !== void 0 || logBase !== void 0 || displayUnits !== void 0) return {
7783
+ ...min !== void 0 ? { min } : {},
7784
+ ...max !== void 0 ? { max } : {},
7785
+ ...majorUnit !== void 0 ? { majorUnit } : {},
7786
+ ...minorUnit !== void 0 ? { minorUnit } : {},
7787
+ ...numberFormat !== void 0 ? { numberFormat } : {},
7788
+ ...logBase !== void 0 ? { logBase } : {},
7789
+ ...displayUnits !== void 0 ? { displayUnits } : {},
7790
+ ...displayUnits !== void 0 && displayUnitsLabel ? { displayUnitsLabel } : {}
7791
+ };
7792
+ };
7793
+ const childVal = (parent, local) => {
7794
+ const el = firstChildElement(parent, qname("c", local, NS_C));
7795
+ return el !== null ? getAttrValue(el, ATTR_VAL) : null;
7796
+ };
7797
+ const childNumber = (parent, local) => {
7798
+ const raw = childVal(parent, local);
7799
+ if (raw === null) return void 0;
7800
+ const n = Number.parseFloat(raw);
7801
+ return Number.isFinite(n) ? n : void 0;
7802
+ };
7803
+ const childBool = (parent, local) => {
7804
+ const el = firstChildElement(parent, qname("c", local, NS_C));
7805
+ return el !== null ? readXmlBool(el) : void 0;
7806
+ };
7807
+ const childToken = (parent, local, allowed) => {
7808
+ const raw = childVal(parent, local);
7809
+ return allowed.find((token) => token === raw);
7810
+ };
7811
+ const ALPHA_OPAQUE = 1e5;
7812
+ const readSeriesFillOpacity = (ser) => {
7813
+ const spPr = firstChildElement(ser, NAME_SP_PR_C);
7814
+ const fill = spPr !== null ? firstChildElement(spPr, NAME_SOLID_FILL$1) : null;
7815
+ const srgb = fill !== null ? firstChildElement(fill, NAME_SRGB_CLR) : null;
7816
+ const alpha = srgb !== null ? firstChildElement(srgb, qname("a", "alpha", NS_A)) : null;
7817
+ const raw = alpha !== null ? getAttrValue(alpha, ATTR_VAL) : null;
7818
+ if (raw === null || !/^\d+$/.test(raw)) return void 0;
7819
+ const n = Number.parseInt(raw, 10);
7820
+ return n <= ALPHA_OPAQUE ? n / ALPHA_OPAQUE : void 0;
7821
+ };
7822
+ const readErrorBarAmount = (errBars) => {
7823
+ const type = childToken(errBars, "errValType", [
7824
+ "cust",
7825
+ "fixedVal",
7826
+ "percentage",
7827
+ "stdDev",
7828
+ "stdErr"
7829
+ ]);
7830
+ if (type === void 0) return void 0;
7831
+ if (type === "stdErr") return { type };
7832
+ if (type === "cust") {
7833
+ const side = (local) => {
7834
+ const el = firstChildElement(errBars, qname("c", local, NS_C));
7835
+ return el !== null ? readNumChannel(el) ?? void 0 : void 0;
7836
+ };
7837
+ const plus = side("plus");
7838
+ const minus = side("minus");
7839
+ return {
7840
+ type,
7841
+ ...plus !== void 0 ? { plus } : {},
7842
+ ...minus !== void 0 ? { minus } : {}
7843
+ };
6379
7844
  }
6380
- let numberFormat;
6381
- const nfEl = firstChildElement(valAx, qname("c", "numFmt", NS_C));
6382
- if (nfEl) {
6383
- const fc = getAttrValue(nfEl, qname("", "formatCode", ""));
6384
- if (fc !== null && fc.length > 0 && fc !== "General") numberFormat = fc;
7845
+ const value = childNumber(errBars, "val");
7846
+ return value !== void 0 ? {
7847
+ type,
7848
+ value
7849
+ } : void 0;
7850
+ };
7851
+ const readErrorBars = (ser) => {
7852
+ const out = {};
7853
+ for (const el of allChildElements(ser, qname("c", "errBars", NS_C))) {
7854
+ const barType = childToken(el, "errBarType", [
7855
+ "both",
7856
+ "minus",
7857
+ "plus"
7858
+ ]);
7859
+ const amount = readErrorBarAmount(el);
7860
+ if (barType === void 0 || amount === void 0) continue;
7861
+ const noEndCap = childBool(el, "noEndCap");
7862
+ const spPr = firstChildElement(el, NAME_SP_PR_C);
7863
+ const ln = spPr !== null ? firstChildElement(spPr, qname("a", "ln", NS_A)) : null;
7864
+ const color = readSolidSrgb(ln);
7865
+ const w = ln !== null ? getAttrValue(ln, qname("", "w", "")) : null;
7866
+ const bars = {
7867
+ barType,
7868
+ amount,
7869
+ ...noEndCap !== void 0 ? { noEndCap } : {},
7870
+ ...color !== void 0 ? { color } : {},
7871
+ ...w !== null && /^\d+$/.test(w) ? { lineWidthEmu: Number.parseInt(w, 10) } : {}
7872
+ };
7873
+ if (childVal(el, "errDir") === "x") out.xErrorBars ??= bars;
7874
+ else out.errorBars ??= bars;
6385
7875
  }
6386
- if (min !== void 0 || max !== void 0 || majorUnit !== void 0 || minorUnit !== void 0 || numberFormat !== void 0 || logBase !== void 0 || displayUnits !== void 0) return {
6387
- ...min !== void 0 ? { min } : {},
6388
- ...max !== void 0 ? { max } : {},
7876
+ return out;
7877
+ };
7878
+ const readView3D = (chart) => {
7879
+ const el = firstChildElement(chart, qname("c", "view3D", NS_C));
7880
+ if (el === null) return void 0;
7881
+ const rotX = childNumber(el, "rotX");
7882
+ const rotY = childNumber(el, "rotY");
7883
+ const rightAngleAxes = childBool(el, "rAngAx");
7884
+ const perspective = childNumber(el, "perspective");
7885
+ const depthPercent = childNumber(el, "depthPercent");
7886
+ const heightPercent = childNumber(el, "hPercent");
7887
+ return {
7888
+ ...rotX !== void 0 ? { rotX } : {},
7889
+ ...rotY !== void 0 ? { rotY } : {},
7890
+ ...rightAngleAxes !== void 0 ? { rightAngleAxes } : {},
7891
+ ...perspective !== void 0 ? { perspective } : {},
7892
+ ...depthPercent !== void 0 ? { depthPercent } : {},
7893
+ ...heightPercent !== void 0 ? { heightPercent } : {}
7894
+ };
7895
+ };
7896
+ const readOfPie = (group) => {
7897
+ const type = childToken(group, "ofPieType", ["pie", "bar"]);
7898
+ if (type === void 0) return void 0;
7899
+ const splitType = childToken(group, "splitType", [
7900
+ "auto",
7901
+ "cust",
7902
+ "percent",
7903
+ "pos",
7904
+ "val"
7905
+ ]);
7906
+ const splitPos = childNumber(group, "splitPos");
7907
+ const secondPieSizePct = childNumber(group, "secondPieSize");
7908
+ const gapWidthPct = childNumber(group, "gapWidth");
7909
+ const custSplit = firstChildElement(group, qname("c", "custSplit", NS_C));
7910
+ const customSplit = [];
7911
+ if (custSplit !== null) for (const pt of allChildElements(custSplit, qname("c", "secondPiePt", NS_C))) {
7912
+ const idx = parsePointIndex(getAttrValue(pt, ATTR_VAL), MAX_PT_COUNT);
7913
+ if (idx !== null) customSplit.push(idx);
7914
+ }
7915
+ const seriesLines = firstChildElement(group, qname("c", "serLines", NS_C)) !== null;
7916
+ return {
7917
+ type,
7918
+ ...splitType !== void 0 ? { splitType } : {},
7919
+ ...splitPos !== void 0 ? { splitPos } : {},
7920
+ ...custSplit !== null ? { customSplit } : {},
7921
+ ...secondPieSizePct !== void 0 ? { secondPieSizePct } : {},
7922
+ ...gapWidthPct !== void 0 ? { gapWidthPct } : {},
7923
+ ...seriesLines ? { seriesLines } : {}
7924
+ };
7925
+ };
7926
+ const readUpDownBars = (group) => {
7927
+ const el = firstChildElement(group, qname("c", "upDownBars", NS_C));
7928
+ if (el === null) return void 0;
7929
+ const barColor = (local) => {
7930
+ const bar = firstChildElement(el, qname("c", local, NS_C));
7931
+ return readSolidSrgb(bar !== null ? firstChildElement(bar, NAME_SP_PR_C) : null);
7932
+ };
7933
+ const gapWidthPct = childNumber(el, "gapWidth");
7934
+ const upColor = barColor("upBars");
7935
+ const downColor = barColor("downBars");
7936
+ return {
7937
+ ...gapWidthPct !== void 0 ? { gapWidthPct } : {},
7938
+ ...upColor !== void 0 ? { upColor } : {},
7939
+ ...downColor !== void 0 ? { downColor } : {}
7940
+ };
7941
+ };
7942
+ const readDataTable = (plotArea) => {
7943
+ const el = firstChildElement(plotArea, qname("c", "dTable", NS_C));
7944
+ if (el === null) return void 0;
7945
+ const showHorizontalBorder = childBool(el, "showHorzBorder");
7946
+ const showVerticalBorder = childBool(el, "showVertBorder");
7947
+ const showOutline = childBool(el, "showOutline");
7948
+ const showKeys = childBool(el, "showKeys");
7949
+ const txPr = firstChildElement(el, qname("c", "txPr", NS_C));
7950
+ const textStyle = txPr !== null ? readLabelStyle(txPr) : void 0;
7951
+ return {
7952
+ ...showHorizontalBorder !== void 0 ? { showHorizontalBorder } : {},
7953
+ ...showVerticalBorder !== void 0 ? { showVerticalBorder } : {},
7954
+ ...showOutline !== void 0 ? { showOutline } : {},
7955
+ ...showKeys !== void 0 ? { showKeys } : {},
7956
+ ...textStyle !== void 0 ? { textStyle } : {}
7957
+ };
7958
+ };
7959
+ const TIME_UNITS = [
7960
+ "days",
7961
+ "months",
7962
+ "years"
7963
+ ];
7964
+ const readDateAxis = (dateAx) => {
7965
+ const baseTimeUnit = childToken(dateAx, "baseTimeUnit", TIME_UNITS);
7966
+ const majorUnit = childNumber(dateAx, "majorUnit");
7967
+ const majorTimeUnit = childToken(dateAx, "majorTimeUnit", TIME_UNITS);
7968
+ const minorUnit = childNumber(dateAx, "minorUnit");
7969
+ const minorTimeUnit = childToken(dateAx, "minorTimeUnit", TIME_UNITS);
7970
+ return {
7971
+ ...baseTimeUnit !== void 0 ? { baseTimeUnit } : {},
6389
7972
  ...majorUnit !== void 0 ? { majorUnit } : {},
7973
+ ...majorTimeUnit !== void 0 ? { majorTimeUnit } : {},
6390
7974
  ...minorUnit !== void 0 ? { minorUnit } : {},
6391
- ...numberFormat !== void 0 ? { numberFormat } : {},
6392
- ...logBase !== void 0 ? { logBase } : {},
6393
- ...displayUnits !== void 0 ? { displayUnits } : {}
7975
+ ...minorTimeUnit !== void 0 ? { minorTimeUnit } : {}
7976
+ };
7977
+ };
7978
+ const withoutNumberFormat = (scaling) => {
7979
+ if (scaling === void 0) return void 0;
7980
+ const { numberFormat: _numberFormat, ...rest } = scaling;
7981
+ return Object.keys(rest).length > 0 ? rest : void 0;
7982
+ };
7983
+ const minMaxOnly = (scaling) => {
7984
+ if (scaling?.min === void 0 && scaling?.max === void 0) return void 0;
7985
+ return {
7986
+ ...scaling.min !== void 0 ? { min: scaling.min } : {},
7987
+ ...scaling.max !== void 0 ? { max: scaling.max } : {}
7988
+ };
7989
+ };
7990
+ const isAxisLineHidden = (axis) => {
7991
+ const spPr = firstChildElement(axis, NAME_SP_PR_C);
7992
+ const ln = spPr !== null ? firstChildElement(spPr, qname("a", "ln", NS_A)) : null;
7993
+ return ln !== null && firstChildElement(ln, qname("a", "noFill", NS_A)) !== null;
7994
+ };
7995
+ const readSeriesAxis = (plotArea) => {
7996
+ const el = firstChildElement(plotArea, qname("c", "serAx", NS_C));
7997
+ if (el === null) return void 0;
7998
+ const hidden = childBool(el, "delete");
7999
+ const title = readTitle(el);
8000
+ const titleEl = firstChildElement(el, NAME_TITLE);
8001
+ const titleStyle = titleEl !== null ? readTitleStyleOf(titleEl) : void 0;
8002
+ const txPr = firstChildElement(el, qname("c", "txPr", NS_C));
8003
+ const labelStyle = txPr !== null ? readLabelStyle(txPr) : void 0;
8004
+ const majorGridlines = firstChildElement(el, qname("c", "majorGridlines", NS_C)) !== null;
8005
+ const scaling = firstChildElement(el, qname("c", "scaling", NS_C));
8006
+ const orientation = scaling !== null ? childToken(scaling, "orientation", ["minMax", "maxMin"]) : void 0;
8007
+ const tickLabelPos = childToken(el, "tickLblPos", [
8008
+ "none",
8009
+ "low",
8010
+ "high",
8011
+ "nextTo"
8012
+ ]);
8013
+ const tickLabelSkip = childNumber(el, "tickLblSkip");
8014
+ const spPr = firstChildElement(el, NAME_SP_PR_C);
8015
+ const lineColor = readSolidSrgb(spPr !== null ? firstChildElement(spPr, qname("a", "ln", NS_A)) : null);
8016
+ const fields = {
8017
+ ...hidden === true ? { hidden } : {},
8018
+ ...title !== void 0 ? { title } : {},
8019
+ ...titleStyle !== void 0 ? { titleStyle } : {},
8020
+ ...labelStyle !== void 0 ? { labelStyle } : {},
8021
+ ...majorGridlines ? { majorGridlines } : {},
8022
+ ...orientation === "maxMin" ? { orientation } : {},
8023
+ ...tickLabelPos !== void 0 ? { tickLabelPos } : {},
8024
+ ...tickLabelSkip !== void 0 ? { tickLabelSkip } : {},
8025
+ ...lineColor !== void 0 ? { lineColor } : {}
8026
+ };
8027
+ return Object.keys(fields).length > 0 ? fields : void 0;
8028
+ };
8029
+ const readManualLayout = (host) => {
8030
+ const layout = firstChildElement(host, qname("c", "layout", NS_C));
8031
+ const manual = layout !== null ? firstChildElement(layout, qname("c", "manualLayout", NS_C)) : null;
8032
+ if (manual === null) return void 0;
8033
+ if (childVal(manual, "xMode") !== "edge" || childVal(manual, "yMode") !== "edge") return void 0;
8034
+ const sizeMode = (local) => (childVal(manual, local) ?? "factor") === "factor";
8035
+ if (!sizeMode("wMode") || !sizeMode("hMode")) return void 0;
8036
+ const x = childNumber(manual, "x");
8037
+ const y = childNumber(manual, "y");
8038
+ if (x === void 0 || y === void 0) return void 0;
8039
+ const w = childNumber(manual, "w");
8040
+ const h = childNumber(manual, "h");
8041
+ const target = childToken(manual, "layoutTarget", ["inner", "outer"]);
8042
+ return {
8043
+ x,
8044
+ y,
8045
+ ...w !== void 0 ? { w } : {},
8046
+ ...h !== void 0 ? { h } : {},
8047
+ ...target !== void 0 ? { target } : {}
8048
+ };
8049
+ };
8050
+ const readBoxLayout = (host) => {
8051
+ const layout = readManualLayout(host);
8052
+ if (layout === void 0 || layout.w === void 0 || layout.h === void 0) return void 0;
8053
+ return {
8054
+ x: layout.x,
8055
+ y: layout.y,
8056
+ w: layout.w,
8057
+ h: layout.h,
8058
+ ...layout.target !== void 0 ? { target: layout.target } : {}
6394
8059
  };
6395
8060
  };
8061
+ const readCategoryGroupLevels = (cat) => {
8062
+ const multi = firstChildElement(cat, NAME_MULTI_LVL_STR_REF);
8063
+ const cache = multi !== null ? firstChildElement(multi, NAME_MULTI_LVL_STR_CACHE) : null;
8064
+ if (cache === null) return void 0;
8065
+ const outer = allChildElements(cache, NAME_LVL).slice(1).map((lvl) => readPtArray(lvl, cache));
8066
+ return outer.length > 0 ? outer : void 0;
8067
+ };
6396
8068
  /**
6397
8069
  * Parses a `<c:chartSpace>` element into a typed `ChartSpec`. Throws if
6398
8070
  * the root or any required child is missing. Returns `null` only when
@@ -6445,6 +8117,7 @@ const readChartSpec = (root) => {
6445
8117
  const groupUsesSecondaryAxis = (group) => groupAxisIds(group).some((id) => secondaryValAxisIds.has(id));
6446
8118
  const series = [];
6447
8119
  let categoriesFromFirst = null;
8120
+ let categoryGroupLevels;
6448
8121
  const serEntries = [];
6449
8122
  for (const group of plotGroups) {
6450
8123
  const secondary = groupUsesSecondaryAxis(group.element);
@@ -6459,6 +8132,7 @@ const readChartSpec = (root) => {
6459
8132
  const cat = firstChildElement(ser, NAME_CAT);
6460
8133
  if (cat !== null && categoriesFromFirst === null) {
6461
8134
  categoriesFromFirst = readStringRef(cat) ?? null;
8135
+ categoryGroupLevels = readCategoryGroupLevels(cat);
6462
8136
  if (categoriesFromFirst === null) {
6463
8137
  const nums = readNumRef(cat);
6464
8138
  if (nums !== null) categoriesFromFirst = nums.map((n) => n === null || !Number.isFinite(n) ? "" : String(n));
@@ -6481,6 +8155,8 @@ const readChartSpec = (root) => {
6481
8155
  const smoothEl = firstChildElement(ser, qname("c", "smooth", NS_C));
6482
8156
  const smooth = smoothEl !== null && readXmlBool(smoothEl);
6483
8157
  const trendline = readTrendline(ser);
8158
+ const fillOpacity = readSeriesFillOpacity(ser);
8159
+ const { errorBars, xErrorBars } = readErrorBars(ser);
6484
8160
  const serDLblsEl = firstChildElement(ser, NAME_D_LBLS);
6485
8161
  const serDataLabels = serDLblsEl !== null && hasDataLabelGroupChild(serDLblsEl) ? readSeriesLevelDataLabels(serDLblsEl) : void 0;
6486
8162
  const pointDataLabels = serDLblsEl !== null ? readPointDataLabels(serDLblsEl, pointCount, serDataLabels) : void 0;
@@ -6505,7 +8181,10 @@ const readChartSpec = (root) => {
6505
8181
  ...pointDataLabels !== void 0 ? { pointDataLabels } : {},
6506
8182
  ...smoothEl !== null ? { smooth } : {},
6507
8183
  ...trendline !== void 0 ? { trendline } : {},
6508
- ...serDataLabels !== void 0 ? { dataLabels: serDataLabels } : {}
8184
+ ...serDataLabels !== void 0 ? { dataLabels: serDataLabels } : {},
8185
+ ...fillOpacity !== void 0 ? { fillOpacity } : {},
8186
+ ...errorBars !== void 0 ? { errorBars } : {},
8187
+ ...xErrorBars !== void 0 ? { xErrorBars } : {}
6509
8188
  });
6510
8189
  }
6511
8190
  const categories = categoriesFromFirst ?? [];
@@ -6525,6 +8204,22 @@ const readChartSpec = (root) => {
6525
8204
  valAx = secValAx;
6526
8205
  secValAx = null;
6527
8206
  }
8207
+ const isXyKind = kind === "scatter" || kind === "bubble";
8208
+ let xValAx = null;
8209
+ if (isXyKind) {
8210
+ const [xId, yId] = groupAxisIds(plotted);
8211
+ const valAxById = /* @__PURE__ */ new Map();
8212
+ for (const el of allChildElements(plotArea, NAME_VAL_AX)) {
8213
+ const id = childVal(el, "axId");
8214
+ if (id !== null) valAxById.set(id, el);
8215
+ }
8216
+ const x = xId !== void 0 ? valAxById.get(xId) : void 0;
8217
+ const y = yId !== void 0 ? valAxById.get(yId) : void 0;
8218
+ if (x !== void 0 && y !== void 0) {
8219
+ xValAx = x;
8220
+ valAx = y;
8221
+ }
8222
+ }
6528
8223
  const valueAxis = valAx !== null ? readValueAxisScaling(valAx) : void 0;
6529
8224
  let grouping;
6530
8225
  if (kind === "column" || kind === "bar" || kind === "area" || kind === "line") {
@@ -6641,11 +8336,7 @@ const readChartSpec = (root) => {
6641
8336
  const v = getAttrValue(srgb, ATTR_VAL);
6642
8337
  return v !== null ? `#${v.toUpperCase()}` : void 0;
6643
8338
  };
6644
- const catAx = findFirst(plotArea, [
6645
- "catAx",
6646
- "dateAx",
6647
- "serAx"
6648
- ]);
8339
+ const catAx = xValAx ?? findFirst(plotArea, ["catAx", "dateAx"]);
6649
8340
  const isHidden = (axis) => {
6650
8341
  const d = firstChildElement(axis, qname("c", "delete", NS_C));
6651
8342
  if (!d) return void 0;
@@ -6939,9 +8630,12 @@ const readChartSpec = (root) => {
6939
8630
  const n = Number.parseInt(idxV, 10);
6940
8631
  if (Number.isFinite(n) && n >= 0) hiddenIndices.push(n);
6941
8632
  }
8633
+ const position = tok === "r" || tok === "t" || tok === "b" || tok === "l" || tok === "tr" ? tok : "r";
8634
+ const legendLayout = readBoxLayout(legendEl);
6942
8635
  legend = {
6943
- position: tok === "r" || tok === "t" || tok === "b" || tok === "l" || tok === "tr" ? tok : "r",
8636
+ position,
6944
8637
  ...overlay ? { overlay } : {},
8638
+ ...legendLayout !== void 0 ? { layout: legendLayout } : {},
6945
8639
  ...textStyle !== void 0 ? { textStyle } : {},
6946
8640
  ...hiddenIndices.length > 0 ? { hiddenIndices } : {}
6947
8641
  };
@@ -7012,6 +8706,38 @@ const readChartSpec = (root) => {
7012
8706
  else if (v === "w") bubbleSizeRepresents = "width";
7013
8707
  }
7014
8708
  }
8709
+ const plottedName = plotted.name.localName;
8710
+ const view3DEl = readView3D(chart);
8711
+ const view3D = plottedName.endsWith("3DChart") || kind === "surface" ? view3DEl : void 0;
8712
+ const bar3DShape = plottedName === "bar3DChart" ? childToken(plotted, "shape", [
8713
+ "box",
8714
+ "cone",
8715
+ "coneToMax",
8716
+ "cylinder",
8717
+ "pyramid",
8718
+ "pyramidToMax"
8719
+ ]) : void 0;
8720
+ const gapDepthPct = view3D !== void 0 ? childNumber(plotted, "gapDepth") : void 0;
8721
+ const bubble3D = kind === "bubble" && allChildElements(plotted, NAME_SER).some((ser) => childBool(ser, "bubble3D") === true);
8722
+ const showNegativeBubbles = kind === "bubble" ? childBool(plotted, "showNegBubbles") : void 0;
8723
+ const ofPie = plottedName === "ofPieChart" ? readOfPie(plotted) : void 0;
8724
+ const surfaceContour = plottedName === "surfaceChart";
8725
+ const surfaceWireframe = kind === "surface" ? childBool(plotted, "wireframe") : void 0;
8726
+ const upDownBars = readUpDownBars(plotted);
8727
+ const dataTable = readDataTable(plotArea);
8728
+ const seriesAxis = readSeriesAxis(plotArea);
8729
+ const plotAreaLayout = readBoxLayout(plotArea);
8730
+ const chartTitleEl = firstChildElement(chart, NAME_TITLE);
8731
+ const titlePosition = chartTitleEl !== null ? readManualLayout(chartTitleEl) : void 0;
8732
+ const titleLayout = titlePosition !== void 0 ? {
8733
+ x: titlePosition.x,
8734
+ y: titlePosition.y
8735
+ } : void 0;
8736
+ const categoryAxisDate = catAx !== null && catAx.name.localName === "dateAx" ? readDateAxis(catAx) : void 0;
8737
+ const horizontalScaling = catAx !== null ? readValueAxisScaling(catAx) : void 0;
8738
+ const categoryAxisScaling = isXyKind ? withoutNumberFormat(horizontalScaling) : categoryAxisDate !== void 0 ? minMaxOnly(horizontalScaling) : void 0;
8739
+ const valueAxisLineHidden = valAx !== null && isAxisLineHidden(valAx);
8740
+ const categoryAxisLineHidden = catAx !== null && isAxisLineHidden(catAx);
7015
8741
  return {
7016
8742
  kind,
7017
8743
  categories,
@@ -7089,80 +8815,28 @@ const readChartSpec = (root) => {
7089
8815
  ...scatterStyle !== void 0 ? { scatterStyle } : {},
7090
8816
  ...radarStyle !== void 0 ? { radarStyle } : {},
7091
8817
  ...bubbleScale !== void 0 ? { bubbleScale } : {},
7092
- ...bubbleSizeRepresents !== void 0 ? { bubbleSizeRepresents } : {}
8818
+ ...bubbleSizeRepresents !== void 0 ? { bubbleSizeRepresents } : {},
8819
+ ...bubble3D === true ? { bubble3D } : {},
8820
+ ...showNegativeBubbles !== void 0 ? { showNegativeBubbles } : {},
8821
+ ...view3D !== void 0 ? { view3D } : {},
8822
+ ...bar3DShape !== void 0 ? { bar3DShape } : {},
8823
+ ...gapDepthPct !== void 0 ? { gapDepthPct } : {},
8824
+ ...seriesAxis !== void 0 ? { seriesAxis } : {},
8825
+ ...ofPie !== void 0 ? { ofPie } : {},
8826
+ ...surfaceContour ? { surfaceContour } : {},
8827
+ ...surfaceWireframe !== void 0 ? { surfaceWireframe } : {},
8828
+ ...upDownBars !== void 0 ? { upDownBars } : {},
8829
+ ...dataTable !== void 0 ? { dataTable } : {},
8830
+ ...categoryAxisDate !== void 0 ? { categoryAxisDate } : {},
8831
+ ...categoryAxisScaling !== void 0 ? { categoryAxisScaling } : {},
8832
+ ...categoryGroupLevels !== void 0 ? { categoryGroupLevels } : {},
8833
+ ...plotAreaLayout !== void 0 ? { plotAreaLayout } : {},
8834
+ ...titleLayout !== void 0 ? { titleLayout } : {},
8835
+ ...valueAxisLineHidden ? { valueAxisLineHidden } : {},
8836
+ ...categoryAxisLineHidden ? { categoryAxisLineHidden } : {}
7093
8837
  };
7094
8838
  };
7095
8839
  //#endregion
7096
- //#region src/internal/chartml/embedded-xlsx.ts
7097
- const TEXT_ENCODER = new TextEncoder();
7098
- const encode = (s) => TEXT_ENCODER.encode(s);
7099
- const xmlEscape = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
7100
- const colLetter = (col) => {
7101
- let n = col;
7102
- let out = "";
7103
- while (true) {
7104
- out = String.fromCharCode(65 + n % 26) + out;
7105
- if (n < 26) return out;
7106
- n = Math.floor(n / 26) - 1;
7107
- }
7108
- };
7109
- const cellRef = (row, col) => `${colLetter(col)}${row + 1}`;
7110
- /**
7111
- * Builds the bytes of a fresh xlsx whose only sheet is laid out as
7112
- *
7113
- * | | seriesNames[0] | seriesNames[1] | ...
7114
- * |-------|----------------|----------------|----
7115
- * | row0 | row0.values[0] | row0.values[1] | ...
7116
- * | row1 | row1.values[0] | ... | ...
7117
- *
7118
- * Header row is row 1 in the sheet (1-indexed). The first column carries
7119
- * category labels; subsequent columns carry series values.
7120
- */
7121
- const buildEmbeddedXlsx = (seriesNames, rows) => {
7122
- const sheetXmlParts = [];
7123
- sheetXmlParts.push("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n", "<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">", "<sheetData>");
7124
- sheetXmlParts.push("<row r=\"1\">");
7125
- sheetXmlParts.push(`<c r="${cellRef(0, 0)}" t="inlineStr"><is><t></t></is></c>`);
7126
- for (let i = 0; i < seriesNames.length; i++) sheetXmlParts.push(`<c r="${cellRef(0, i + 1)}" t="inlineStr"><is><t>${xmlEscape(seriesNames[i] ?? "")}</t></is></c>`);
7127
- sheetXmlParts.push("</row>");
7128
- for (let r = 0; r < rows.length; r++) {
7129
- const row = rows[r];
7130
- const rowIdx = r + 1;
7131
- sheetXmlParts.push(`<row r="${rowIdx + 1}">`);
7132
- sheetXmlParts.push(`<c r="${cellRef(rowIdx, 0)}" t="inlineStr"><is><t>${xmlEscape(row.label)}</t></is></c>`);
7133
- for (let i = 0; i < row.values.length; i++) {
7134
- const v = row.values[i];
7135
- if (v === null || v === void 0) continue;
7136
- sheetXmlParts.push(`<c r="${cellRef(rowIdx, i + 1)}"><v>${v}</v></c>`);
7137
- }
7138
- sheetXmlParts.push("</row>");
7139
- }
7140
- sheetXmlParts.push("</sheetData></worksheet>");
7141
- const sheetXml = sheetXmlParts.join("");
7142
- return writeZip([
7143
- {
7144
- name: "[Content_Types].xml",
7145
- data: encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/><Default Extension=\"xml\" ContentType=\"application/xml\"/><Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/><Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/></Types>")
7146
- },
7147
- {
7148
- name: "_rels/.rels",
7149
- data: encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/></Relationships>")
7150
- },
7151
- {
7152
- name: "xl/workbook.xml",
7153
- data: encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"><sheets><sheet name=\"Sheet1\" sheetId=\"1\" r:id=\"rId1\"/></sheets></workbook>")
7154
- },
7155
- {
7156
- name: "xl/_rels/workbook.xml.rels",
7157
- data: encode("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/></Relationships>")
7158
- },
7159
- {
7160
- name: "xl/worksheets/sheet1.xml",
7161
- data: encode(sheetXml)
7162
- }
7163
- ]);
7164
- };
7165
- //#endregion
7166
8840
  //#region src/api/fn/slide-background.ts
7167
8841
  const setSlideBackgroundXml = (slide, configure) => {
7168
8842
  const cSld = firstChildElement(slide[SLIDE_DOCUMENT].root, NAME_CSLD);
@@ -8138,12 +9812,22 @@ const validateChartSpecColors = (spec) => {
8138
9812
  checkChartColor(spec.categoryAxisLineColor, "addSlideChart: categoryAxisLineColor");
8139
9813
  checkChartColor(spec.secondaryValueAxis?.majorGridlineColor, "addSlideChart: secondaryValueAxis.majorGridlineColor");
8140
9814
  checkChartColor(spec.secondaryValueAxis?.lineColor, "addSlideChart: secondaryValueAxis.lineColor");
9815
+ checkChartColor(spec.dataLabels?.fillColor, "addSlideChart: dataLabels.fillColor");
9816
+ checkChartColor(spec.upDownBars?.upColor, "addSlideChart: upDownBars.upColor");
9817
+ checkChartColor(spec.upDownBars?.downColor, "addSlideChart: upDownBars.downColor");
9818
+ checkChartColor(spec.seriesAxis?.lineColor, "addSlideChart: seriesAxis.lineColor");
8141
9819
  spec.series.forEach((series, i) => {
8142
9820
  checkChartColor(series.color, `addSlideChart: series[${i}].color`);
8143
9821
  checkChartColor(series.lineColor, `addSlideChart: series[${i}].lineColor`);
8144
9822
  checkChartColor(series.markerColor, `addSlideChart: series[${i}].markerColor`);
8145
9823
  checkChartColor(series.markerLineColor, `addSlideChart: series[${i}].markerLineColor`);
8146
9824
  checkChartColor(series.trendline?.color, `addSlideChart: series[${i}].trendline.color`);
9825
+ checkChartColor(series.errorBars?.color, `addSlideChart: series[${i}].errorBars.color`);
9826
+ checkChartColor(series.xErrorBars?.color, `addSlideChart: series[${i}].xErrorBars.color`);
9827
+ checkChartColor(series.dataLabels?.fillColor, `addSlideChart: series[${i}].dataLabels.fillColor`);
9828
+ series.pointDataLabels?.forEach((label, j) => {
9829
+ checkChartColor(label?.fillColor, `addSlideChart: series[${i}].pointDataLabels[${j}].fillColor`);
9830
+ });
8147
9831
  series.pointColors?.forEach((c, j) => {
8148
9832
  checkChartColor(c, `addSlideChart: series[${i}].pointColors[${j}]`);
8149
9833
  });
@@ -8154,9 +9838,10 @@ const validateChartSpecAxes = (spec) => {
8154
9838
  };
8155
9839
  /**
8156
9840
  * Adds a chart to the slide. Returns the new shape handle (kind
8157
- * `graphicFrame`). Authorable chart kinds: `bar`, `column`, `line`,
8158
- * `pie`, `doughnut`, `area`. `scatter`, `radar` and `bubble` are read +
8159
- * render only and are rejected here — see `ChartKind`.
9841
+ * `graphicFrame`). Every `ChartKind` is authorable, and the `view3D` /
9842
+ * `ofPie` / `surfaceContour` modifiers reach the remaining plot-group
9843
+ * elements (3-D bar / line / area / pie, pie-of-pie, contour) — see the
9844
+ * table on `ChartKind`.
8160
9845
  *
8161
9846
  * Side effects:
8162
9847
  *
@@ -8170,9 +9855,15 @@ const validateChartSpecAxes = (spec) => {
8170
9855
  *
8171
9856
  * Constraints:
8172
9857
  *
8173
- * - `pie` charts require exactly one series.
8174
- * - All series should have at most `categories.length` values; missing
8175
- * values are treated as blanks (gaps in the visualization).
9858
+ * - `pie` / `doughnut` charts require exactly one series; `stock`
9859
+ * charts exactly three (high, low, close) or four (open first).
9860
+ * - `scatter` / `bubble` series carry their own `xValues` (and
9861
+ * `bubbleSizes`); `categories` is unused for them.
9862
+ * - All other series should have at most `categories.length` values;
9863
+ * missing values are treated as blanks (gaps in the visualization).
9864
+ * - A spec whose fields contradict each other (e.g. `view3D` on a
9865
+ * scatter chart, error bars on a pie) throws instead of writing a
9866
+ * chart PowerPoint would repair.
8176
9867
  */
8177
9868
  const withChartDefaultTextColor = (spec, color) => {
8178
9869
  if (color === null) return spec;
@@ -8203,6 +9894,7 @@ const withChartDefaultTextColor = (spec, color) => {
8203
9894
  };
8204
9895
  };
8205
9896
  const addSlideChart = (slide, opts) => {
9897
+ validateChartSpecEnums(opts.spec, "addSlideChart");
8206
9898
  validateChartSpecColors(opts.spec);
8207
9899
  validateChartSpecAxes(opts.spec);
8208
9900
  const spec = withChartDefaultTextColor(opts.spec, resolveDeckBodyTextColor(slide));
@@ -8210,11 +9902,7 @@ const addSlideChart = (slide, opts) => {
8210
9902
  const chartN = allocateChartIndex(pkg);
8211
9903
  const chartPartName = partName(`/ppt/charts/chart${chartN}.xml`);
8212
9904
  const xlsxPartName = partName(`/ppt/embeddings/Microsoft_Excel_Worksheet${chartN}.xlsx`);
8213
- const xlsxRows = spec.categories.map((label, i) => ({
8214
- label,
8215
- values: spec.series.map((s) => s.values[i] ?? null)
8216
- }));
8217
- const xlsxBytes = buildEmbeddedXlsx(spec.series.map((s) => s.name), xlsxRows);
9905
+ const xlsxBytes = buildEmbeddedXlsx(layoutChartSheet(spec).grid);
8218
9906
  const chartBytes = encode$1(serializeXml(buildChartSpaceDoc(spec)));
8219
9907
  pkg.addPart(chartPartName, CHART_CONTENT_TYPE, chartBytes);
8220
9908
  pkg.addPart(xlsxPartName, EMBEDDED_XLSX_CONTENT_TYPE, xlsxBytes);
@@ -8288,6 +9976,7 @@ const resolveChartPartName = (slide, shape) => {
8288
9976
  * fresh data."
8289
9977
  */
8290
9978
  const setChartSpec = (chart, spec) => {
9979
+ validateChartSpecEnums(spec, "setChartSpec");
8291
9980
  validateChartSpecColors(spec);
8292
9981
  validateChartSpecAxes(spec);
8293
9982
  const slide = chart.shape[SHAPE_SLIDE];
@@ -8304,12 +9993,7 @@ const setChartSpec = (chart, spec) => {
8304
9993
  if (xlsxRel) {
8305
9994
  const xlsxName = xlsxRel.target.startsWith("/") ? partName(xlsxRel.target) : resolveTarget(resolved.partName, xlsxRel.target);
8306
9995
  const xlsxPart = pkg.getPart(xlsxName);
8307
- const rows = spec.categories.map((label, i) => ({
8308
- label,
8309
- values: spec.series.map((s) => s.values[i] ?? null)
8310
- }));
8311
- const xlsxBytes = buildEmbeddedXlsx(spec.series.map((s) => s.name), rows);
8312
- if (xlsxPart) xlsxPart.data = xlsxBytes;
9996
+ if (xlsxPart) xlsxPart.data = buildEmbeddedXlsx(layoutChartSheet(spec).grid);
8313
9997
  }
8314
9998
  }
8315
9999
  };
@@ -8464,7 +10148,9 @@ const getPresentationChartKindCounts = (pres) => {
8464
10148
  area: 0,
8465
10149
  scatter: 0,
8466
10150
  radar: 0,
8467
- bubble: 0
10151
+ bubble: 0,
10152
+ stock: 0,
10153
+ surface: 0
8468
10154
  };
8469
10155
  for (const slide of getSlides(pres)) for (const chart of getSlideCharts(slide)) {
8470
10156
  if (chart.spec === null) continue;
@@ -9798,6 +11484,7 @@ const ensureCellTxBody = (cell) => {
9798
11484
  txBody = elem(NAME_A_TX_BODY_TBL);
9799
11485
  txBody.children.push(elem(qname("a", "bodyPr", NS.dml)));
9800
11486
  txBody.children.push(elem(qname("a", "lstStyle", NS.dml)));
11487
+ txBody.children.push(elem(qname("a", "p", NS.dml)));
9801
11488
  tc.children.unshift(txBody);
9802
11489
  }
9803
11490
  return txBody;
@@ -9825,7 +11512,7 @@ const setTableCellText = (cell, text) => {
9825
11512
  * `getTableCellParagraphs`.
9826
11513
  */
9827
11514
  const setTableCellParagraphs = (cell, paragraphs) => {
9828
- const built = buildTextBodyParagraphs(paragraphs);
11515
+ const built = buildTextBodyParagraphs(paragraphs, "setTableCellParagraphs");
9829
11516
  replaceTextBodyParagraphs(ensureCellTxBody(cell), built);
9830
11517
  commitTableCell(cell);
9831
11518
  };
@@ -10029,6 +11716,9 @@ const writeBorderLn = (tcPr, local, border) => {
10029
11716
  * cardinal four — a strikethrough cell can have only a diagonal.
10030
11717
  */
10031
11718
  const setTableCellBorders = (cell, sides) => {
11719
+ if (sides !== null) {
11720
+ for (const [side, border] of Object.entries(sides)) if (border?.dash != null) oneOf(border.dash, LINE_DASHES, `setTableCellBorders: ${side}.dash`);
11721
+ }
10032
11722
  const tcPr = ensureCellTcPr(cell);
10033
11723
  if (sides === null) for (const local of Object.values(BORDER_SIDE_LOCALS)) writeBorderLn(tcPr, local, null);
10034
11724
  else for (const [key, local] of Object.entries(BORDER_SIDE_LOCALS)) {
@@ -10061,6 +11751,7 @@ const getTableCellTextDirection = (cell) => {
10061
11751
  * default horizontal direction. Creates `<a:tcPr>` if absent.
10062
11752
  */
10063
11753
  const setTableCellTextDirection = (cell, direction) => {
11754
+ if (direction !== null) oneOf(direction, TEXT_DIRECTIONS, "setTableCellTextDirection: direction");
10064
11755
  const tcPr = ensureCellTcPr(cell);
10065
11756
  tcPr.attrs = tcPr.attrs.filter((a) => !(a.name.namespaceURI === "" && a.name.localName === "vert"));
10066
11757
  if (direction !== null && direction !== "horz") tcPr.attrs.push(attr(qname("", "vert", ""), direction));
@@ -10086,10 +11777,15 @@ const getTableCellAnchor = (cell) => {
10086
11777
  * default (`ctr`). Creates `<a:tcPr>` if absent.
10087
11778
  */
10088
11779
  const setTableCellAnchor = (cell, anchor) => {
11780
+ if (anchor !== null) oneOf(anchor, [
11781
+ "top",
11782
+ "center",
11783
+ "bottom"
11784
+ ], "setTableCellAnchor: anchor");
10089
11785
  const tcPr = ensureCellTcPr(cell);
10090
11786
  tcPr.attrs = tcPr.attrs.filter((a) => !(a.name.namespaceURI === "" && a.name.localName === "anchor"));
10091
11787
  if (anchor !== null) {
10092
- const mapped = anchor === "top" ? "t" : anchor === "center" ? "ctr" : "b";
11788
+ const mapped = TEXT_ANCHORS[anchor];
10093
11789
  tcPr.attrs.push(attr(qname("", "anchor", ""), mapped));
10094
11790
  }
10095
11791
  commitTableCell(cell);
@@ -10237,12 +11933,14 @@ const getTableCellFill = (cell) => {
10237
11933
  };
10238
11934
  /** Applies a TextFormat to every run in the cell's text. */
10239
11935
  const setTableCellTextFormat = (cell, format) => {
10240
- applyFormatToAllRuns(ensureCellTxBody(cell), format);
11936
+ validateFormatEnums(format, "setTableCellTextFormat");
11937
+ applyValidatedFormatToAllRuns(ensureCellTxBody(cell), format);
10241
11938
  commitTableCell(cell);
10242
11939
  };
10243
11940
  /** Sets horizontal alignment on every paragraph in the cell. */
10244
11941
  const setTableCellAlignment = (cell, align) => {
10245
- applyAlignmentToAllParagraphs(ensureCellTxBody(cell), align);
11942
+ const token = alignToken(align, "setTableCellAlignment");
11943
+ applyAlignmentTokenToAllParagraphs(ensureCellTxBody(cell), token);
10246
11944
  commitTableCell(cell);
10247
11945
  };
10248
11946
  /** Zero-based (row, col) of the cell. */
@@ -10397,7 +12095,7 @@ const PRES_PART = partName("/ppt/presentation.xml");
10397
12095
  const PRES_RELS = partName("/ppt/_rels/presentation.xml.rels");
10398
12096
  const NAME_SLD_ID_LST = qname("p", "sldIdLst", NS.pml);
10399
12097
  const NAME_SLD_ID = qname("p", "sldId", NS.pml);
10400
- const ATTR_ID = qname("", "id", "");
12098
+ const ATTR_ID$1 = qname("", "id", "");
10401
12099
  const ATTR_R_ID = qname("r", "id", NS.officeDocRels);
10402
12100
  const decoder = new TextDecoder();
10403
12101
  const decode = (b) => decoder.decode(b);
@@ -10444,7 +12142,7 @@ const validatePresentationPackage = (pkg) => {
10444
12142
  const seenRIds = /* @__PURE__ */ new Set();
10445
12143
  const slidePartNames = [];
10446
12144
  if (sldIdLst !== null) for (const sldId of allChildElements(sldIdLst, NAME_SLD_ID)) {
10447
- const idRaw = getAttrValue(sldId, ATTR_ID);
12145
+ const idRaw = getAttrValue(sldId, ATTR_ID$1);
10448
12146
  const rIdRaw = getAttrValue(sldId, ATTR_R_ID);
10449
12147
  if (idRaw === null) {
10450
12148
  issues.push({
@@ -10548,7 +12246,7 @@ const validatePresentationPackage = (pkg) => {
10548
12246
  });
10549
12247
  for (const rel of slideRels.items) {
10550
12248
  if (rel.targetMode === "External") continue;
10551
- if (rel.type !== REL_TYPES.image && rel.type !== REL_TYPES.chart && rel.type !== REL_TYPES.notesSlide && rel.type !== REL_TYPES.comments && rel.type !== REL_TYPES.oleObject && rel.type !== REL_TYPES.package) continue;
12249
+ if (rel.type !== REL_TYPES.image && rel.type !== REL_TYPES.media && rel.type !== REL_TYPES.video && rel.type !== REL_TYPES.audio && rel.type !== REL_TYPES.chart && rel.type !== REL_TYPES.notesSlide && rel.type !== REL_TYPES.comments && rel.type !== REL_TYPES.oleObject && rel.type !== REL_TYPES.package) continue;
10552
12250
  const targetName = targetPartName(slideName, rel);
10553
12251
  if (pkg.getPart(targetName) === null) issues.push({
10554
12252
  severity: "error",
@@ -10582,7 +12280,7 @@ const validatePresentationPackage = (pkg) => {
10582
12280
  if (!nvHost) continue;
10583
12281
  const cNvPr = firstChildElement(nvHost, qname("p", "cNvPr", NS.pml));
10584
12282
  if (!cNvPr) continue;
10585
- const id = getAttrValue(cNvPr, ATTR_ID);
12283
+ const id = getAttrValue(cNvPr, ATTR_ID$1);
10586
12284
  if (id === null) continue;
10587
12285
  seenShapeIds.set(id, (seenShapeIds.get(id) ?? 0) + 1);
10588
12286
  }
@@ -10593,6 +12291,23 @@ const validatePresentationPackage = (pkg) => {
10593
12291
  message: `duplicate shape id="${id}" appears ${count}× in slide ${slideName}`,
10594
12292
  partName: slideName
10595
12293
  });
12294
+ const timing = firstChildElement(slideRoot, qname("p", "timing", NS.pml));
12295
+ const checkMediaNodes = (host) => {
12296
+ for (const child of host.children) {
12297
+ if (child.kind !== "element") continue;
12298
+ if (!isMediaTimingNode(child)) {
12299
+ checkMediaNodes(child);
12300
+ continue;
12301
+ }
12302
+ const target = mediaTimingNodeTarget(child);
12303
+ if (target !== null && !seenShapeIds.has(String(target))) issues.push({
12304
+ severity: "error",
12305
+ message: `media time node in slide ${slideName} targets missing shape id="${target}"`,
12306
+ partName: slideName
12307
+ });
12308
+ }
12309
+ };
12310
+ if (timing) checkMediaNodes(timing);
10596
12311
  }
10597
12312
  for (const part of pkg.parts) {
10598
12313
  if (part.contentType !== "application/vnd.openxmlformats-officedocument.drawingml.chart+xml") continue;
@@ -10940,8 +12655,9 @@ const getSlideTransition = (slide) => {
10940
12655
  };
10941
12656
  /** Sets the slide's transition effect. */
10942
12657
  const setSlideTransition = (slide, options) => {
12658
+ const transition = buildTransition(options);
10943
12659
  removeTransition(slide);
10944
- insertAfterClrMapOvr(slide, buildTransition(options));
12660
+ insertAfterClrMapOvr(slide, transition);
10945
12661
  commitSlideData(slide);
10946
12662
  refreshSlideData(slide);
10947
12663
  };
@@ -11514,6 +13230,7 @@ const NAME_SLD_ID_LST_FN = qname("p", "sldIdLst", NS.pml);
11514
13230
  * §19.2.1.26; we insert at the correct position when bootstrapping.
11515
13231
  */
11516
13232
  const setSlideSize = (pres, opts) => {
13233
+ if (opts.type !== void 0) oneOf(opts.type, SLIDE_SIZE_TYPES, "setSlideSize: type");
11517
13234
  const presPart = pres[INTERNAL_PACKAGE].getPart(PRES_PART_NAME);
11518
13235
  if (!presPart) throw new Error("presentation.xml is missing");
11519
13236
  const doc = parseXml(decode$1(presPart.data));
@@ -12066,6 +13783,83 @@ const setShapeImageCrop = (shape, crop) => {
12066
13783
  commitAndRefresh(shape);
12067
13784
  };
12068
13785
  //#endregion
13786
+ //#region src/api/fn/_media-timing.ts
13787
+ const NAME_TIMING = qname("p", "timing", NS.pml);
13788
+ const NAME_TN_LST = qname("p", "tnLst", NS.pml);
13789
+ const NAME_PAR = qname("p", "par", NS.pml);
13790
+ const NAME_C_TN = qname("p", "cTn", NS.pml);
13791
+ const NAME_CHILD_TN_LST = qname("p", "childTnLst", NS.pml);
13792
+ const NAME_EXT_LST$1 = qname("p", "extLst", NS.pml);
13793
+ const ATTR_ID = qname("", "id", "");
13794
+ const findSlideTiming = (slide) => firstChildElement(slide[SLIDE_DOCUMENT].root, NAME_TIMING);
13795
+ const insertSlideTiming = (slide, timing) => {
13796
+ const root = slide[SLIDE_DOCUMENT].root;
13797
+ const extLst = firstChildElement(root, NAME_EXT_LST$1);
13798
+ if (extLst === null) root.children.push(timing);
13799
+ else root.children.splice(root.children.indexOf(extLst), 0, timing);
13800
+ };
13801
+ /** The root time node's `<p:childTnLst>` — where media nodes and sequences live. */
13802
+ const rootChildTnLst = (timing) => {
13803
+ const tnLst = firstChildElement(timing, NAME_TN_LST);
13804
+ const par = tnLst ? firstChildElement(tnLst, NAME_PAR) : null;
13805
+ const cTn = par ? firstChildElement(par, NAME_C_TN) : null;
13806
+ return cTn ? firstChildElement(cTn, NAME_CHILD_TN_LST) : null;
13807
+ };
13808
+ const maxCTnId = (el) => {
13809
+ let max = 0;
13810
+ const walk = (e) => {
13811
+ if (e.name.namespaceURI === NS.pml && e.name.localName === "cTn") {
13812
+ const n = Number.parseInt(getAttrValue(e, ATTR_ID) ?? "", 10);
13813
+ if (Number.isFinite(n) && n > max) max = n;
13814
+ }
13815
+ for (const c of e.children) if (c.kind === "element") walk(c);
13816
+ };
13817
+ walk(el);
13818
+ return max;
13819
+ };
13820
+ /** Adds the media time node for shape `spid`. The caller commits the slide. */
13821
+ const addMediaTimingNode = (slide, kind, spid) => {
13822
+ const timing = findSlideTiming(slide);
13823
+ if (timing === null) {
13824
+ insertSlideTiming(slide, buildTimingRoot([buildMediaTimingNode(kind, spid, 2)]));
13825
+ return;
13826
+ }
13827
+ const node = buildMediaTimingNode(kind, spid, maxCTnId(timing) + 1);
13828
+ const childTnLst = rootChildTnLst(timing);
13829
+ if (childTnLst !== null) {
13830
+ childTnLst.children.push(node);
13831
+ return;
13832
+ }
13833
+ const fresh = buildTimingRoot([node]);
13834
+ const rest = timing.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.pml && c.name.localName === "tnLst"));
13835
+ timing.children = [...fresh.children, ...rest];
13836
+ };
13837
+ /**
13838
+ * Removes the media nodes targeting any of `spids`, and the whole `<p:timing>`
13839
+ * when that leaves the root without children (an empty `<p:childTnLst>` is
13840
+ * schema-invalid and an empty root animates nothing). The caller commits.
13841
+ */
13842
+ const removeMediaTimingNodes = (slide, spids) => {
13843
+ const timing = findSlideTiming(slide);
13844
+ const childTnLst = timing ? rootChildTnLst(timing) : null;
13845
+ if (timing === null || childTnLst === null) return;
13846
+ childTnLst.children = childTnLst.children.filter((c) => {
13847
+ if (c.kind !== "element" || !isMediaTimingNode(c)) return true;
13848
+ const target = mediaTimingNodeTarget(c);
13849
+ return target === null || !spids.has(target);
13850
+ });
13851
+ if (!childTnLst.children.some((c) => c.kind === "element")) {
13852
+ const root = slide[SLIDE_DOCUMENT].root;
13853
+ root.children = root.children.filter((c) => c !== timing);
13854
+ }
13855
+ };
13856
+ /** Media nodes at the timing root, in document order. */
13857
+ const mediaTimingNodes = (timing) => {
13858
+ const childTnLst = rootChildTnLst(timing);
13859
+ if (childTnLst === null) return [];
13860
+ return childTnLst.children.filter((c) => c.kind === "element" && isMediaTimingNode(c));
13861
+ };
13862
+ //#endregion
12069
13863
  //#region src/api/fn/shape-animation.ts
12070
13864
  NS.pml;
12071
13865
  const ATTR_ID_FN = qname("", "id", "");
@@ -12085,18 +13879,6 @@ const findDescendant = (el, pred) => {
12085
13879
  return null;
12086
13880
  };
12087
13881
  const isPml = (el, local) => el.name.namespaceURI === NS.pml && el.name.localName === local;
12088
- const maxCTnId = (el) => {
12089
- let max = 0;
12090
- const walk = (e) => {
12091
- if (isPml(e, "cTn")) {
12092
- const n = Number.parseInt(getAttrValue(e, ATTR_ID_FN) ?? "", 10);
12093
- if (Number.isFinite(n) && n > max) max = n;
12094
- }
12095
- for (const c of e.children) if (c.kind === "element") walk(c);
12096
- };
12097
- walk(el);
12098
- return max;
12099
- };
12100
13882
  const shiftCTnIds = (el, offset) => {
12101
13883
  const walk = (e) => {
12102
13884
  if (isPml(e, "cTn")) {
@@ -12130,29 +13912,40 @@ const setGrpId = (el, grpId) => {
12130
13912
  value: grpId
12131
13913
  } : a);
12132
13914
  };
13915
+ const isMainSeqCTn = (e) => isPml(e, "cTn") && getAttrValue(e, qname("", "nodeType", "")) === "mainSeq";
12133
13916
  const mergeEffectInto = (existing, fresh) => {
12134
- const existingMainSeqChildTnLst = (() => {
12135
- const mainSeq = findDescendant(existing, (e) => isPml(e, "cTn") && getAttrValue(e, qname("", "nodeType", "")) === "mainSeq");
12136
- return mainSeq ? firstChildElement(mainSeq, qname("p", "childTnLst", NS.pml)) : null;
12137
- })();
12138
- if (!existingMainSeqChildTnLst) return false;
12139
- const freshMainSeq = findDescendant(fresh, (e) => isPml(e, "cTn") && getAttrValue(e, qname("", "nodeType", "")) === "mainSeq");
13917
+ const freshMainSeq = findDescendant(fresh, isMainSeqCTn);
12140
13918
  const freshChildTnLst = freshMainSeq ? firstChildElement(freshMainSeq, qname("p", "childTnLst", NS.pml)) : null;
12141
13919
  const newPar = freshChildTnLst ? freshChildTnLst.children.find((c) => c.kind === "element" && isPml(c, "par")) : null;
12142
13920
  const freshBldP = findDescendant(fresh, (e) => isPml(e, "bldP"));
12143
13921
  if (!newPar || !freshBldP) return false;
12144
- const offset = maxCTnId(existing) - 2;
12145
- if (offset > 0) shiftCTnIds(newPar, offset);
12146
13922
  const newGrpId = String(maxGrpId(existing) + 1);
12147
13923
  const effectCTn = findDescendant(newPar, (e) => getAttrValue(e, qname("", "presetID", "")) !== null);
13924
+ const existingMainSeq = findDescendant(existing, isMainSeqCTn);
13925
+ const existingMainSeqChildTnLst = existingMainSeq ? firstChildElement(existingMainSeq, qname("p", "childTnLst", NS.pml)) : null;
13926
+ if (existingMainSeqChildTnLst) {
13927
+ const offset = maxCTnId(existing) - 2;
13928
+ if (offset > 0) shiftCTnIds(newPar, offset);
13929
+ existingMainSeqChildTnLst.children.push(newPar);
13930
+ } else {
13931
+ const rootList = rootChildTnLst(existing);
13932
+ const freshSeq = rootChildTnLst(fresh)?.children.find((c) => c.kind === "element" && isPml(c, "seq"));
13933
+ if (!rootList || !freshSeq) return false;
13934
+ shiftCTnIds(freshSeq, maxCTnId(existing) - 1);
13935
+ rootList.children.unshift(freshSeq);
13936
+ }
12148
13937
  if (effectCTn) setGrpId(effectCTn, newGrpId);
12149
13938
  setGrpId(freshBldP, newGrpId);
12150
- existingMainSeqChildTnLst.children.push(newPar);
12151
13939
  const existingBldLst = findDescendant(existing, (e) => isPml(e, "bldLst"));
12152
13940
  if (existingBldLst) existingBldLst.children.push(freshBldP);
12153
- else existing.children.push(elem(qname("p", "bldLst", NS.pml), { children: [freshBldP] }));
13941
+ else insertBldLst(existing, elem(qname("p", "bldLst", NS.pml), { children: [freshBldP] }));
12154
13942
  return true;
12155
13943
  };
13944
+ const insertBldLst = (timing, bldLst) => {
13945
+ const extLst = firstChildElement(timing, qname("p", "extLst", NS.pml));
13946
+ if (extLst === null) timing.children.push(bldLst);
13947
+ else timing.children.splice(timing.children.indexOf(extLst), 0, bldLst);
13948
+ };
12156
13949
  /**
12157
13950
  * Sets a single click-triggered animation effect on the given shape.
12158
13951
  *
@@ -12240,7 +14033,12 @@ const findShapesWithAnimation = (slide) => {
12240
14033
  return out;
12241
14034
  };
12242
14035
  const clearSlideAnimations = (slide) => {
12243
- removeExistingTiming(slide);
14036
+ const existing = findTiming(slide);
14037
+ const mediaNodes = existing ? mediaTimingNodes(existing) : [];
14038
+ if (existing !== null && mediaNodes.length > 0) {
14039
+ const root = slide[SLIDE_DOCUMENT].root;
14040
+ root.children[root.children.indexOf(existing)] = buildTimingRoot(mediaNodes);
14041
+ } else removeExistingTiming(slide);
12244
14042
  commitSlideData(slide);
12245
14043
  refreshSlideData(slide);
12246
14044
  };
@@ -12585,35 +14383,23 @@ const ensurePPr = (paragraph) => {
12585
14383
  paragraph.children.unshift(fresh);
12586
14384
  return fresh;
12587
14385
  };
12588
- const alignTokenForFn = (a) => {
12589
- switch (a) {
12590
- case "left":
12591
- case "l": return "l";
12592
- case "center":
12593
- case "ctr": return "ctr";
12594
- case "right":
12595
- case "r": return "r";
12596
- case "justify":
12597
- case "just": return "just";
12598
- case "distribute":
12599
- case "dist": return "dist";
12600
- default: return a;
12601
- }
12602
- };
12603
14386
  /**
12604
14387
  * Sets the horizontal alignment of a single paragraph. Same token set
12605
14388
  * as `setShapeAlignment`. Other paragraphs are untouched.
12606
14389
  */
12607
14390
  const setParagraphAlignment = (shape, paragraphIndex, align) => {
14391
+ const token = alignToken(align, "setParagraphAlignment");
12608
14392
  const pPr = ensurePPr(requireParagraph(shape, paragraphIndex));
12609
14393
  pPr.attrs = pPr.attrs.filter((a) => a.name.localName !== "algn");
12610
- pPr.attrs.push(attr(ATTR_ALGN_FN, alignTokenForFn(align)));
14394
+ pPr.attrs.push(attr(ATTR_ALGN_FN, token));
12611
14395
  commitAndRefresh(shape);
12612
14396
  };
12613
14397
  /**
12614
14398
  * Sets the paragraph's nesting level (`<a:pPr lvl="N"/>`). Levels are
12615
14399
  * 0-indexed; PowerPoint accepts 0 through 8. Pass `0` to clear an
12616
14400
  * existing level — `<a:pPr lvl="0"/>` is the same as omitting the attr.
14401
+ * Indents matching the previous level's default bullet pair follow the level;
14402
+ * other indent values are preserved.
12617
14403
  *
12618
14404
  * Used in tandem with bullets to author nested lists:
12619
14405
  *
@@ -12624,8 +14410,10 @@ const setParagraphAlignment = (shape, paragraphIndex, align) => {
12624
14410
  const setParagraphLevel = (shape, paragraphIndex, level) => {
12625
14411
  if (!Number.isInteger(level) || level < 0 || level > 8) throw new RangeError(`paragraph level must be an integer in [0, 8], got ${level}`);
12626
14412
  const pPr = ensurePPr(requireParagraph(shape, paragraphIndex));
14413
+ const previousLevel = Number.parseInt(getAttrValue(pPr, ATTR_LVL) ?? "0", 10);
12627
14414
  pPr.attrs = pPr.attrs.filter((a) => a.name.localName !== "lvl");
12628
14415
  if (level > 0) pPr.attrs.push(attr(ATTR_LVL, String(level)));
14416
+ updateBulletIndentForLevel(pPr, Number.isFinite(previousLevel) ? previousLevel : 0, level);
12629
14417
  commitAndRefresh(shape);
12630
14418
  };
12631
14419
  /**
@@ -15304,8 +17092,7 @@ const setShapeText = (shape, value, options = {}) => {
15304
17092
  if (shape[SHAPE_SNAPSHOT].kind !== "shape") throw new Error(`setShapeText only works on text-bearing shapes; ${shape[SHAPE_SNAPSHOT].kind} is not one`);
15305
17093
  const txBody = firstChildElement(shape[SHAPE_ELEMENT], NAME_TX_BODY);
15306
17094
  if (txBody === null) throw new Error(`shape "${shape[SHAPE_SNAPSHOT].name}" has no <p:txBody>`);
15307
- setTextBody(txBody, value);
15308
- if (options.bullets !== void 0) applyBulletToAllParagraphs(txBody, options.bullets);
17095
+ setTextBody(txBody, value, options.bullets);
15309
17096
  commitAndRefresh(shape);
15310
17097
  };
15311
17098
  /**
@@ -15348,6 +17135,7 @@ const requireBodyPr = (shape) => {
15348
17135
  * Throws for non-text-bearing shape kinds.
15349
17136
  */
15350
17137
  const setShapeTextWrap = (shape, wrap) => {
17138
+ oneOf(wrap, ["none", "square"], "setShapeTextWrap: wrap");
15351
17139
  const bodyPr = requireBodyPr(shape);
15352
17140
  const ATTR_WRAP = qname("", "wrap", "");
15353
17141
  bodyPr.attrs = bodyPr.attrs.filter((a) => !(a.name.namespaceURI === "" && a.name.localName === "wrap"));
@@ -15375,9 +17163,18 @@ const getShapeTextWrap = (shape) => {
15375
17163
  * non-text-bearing shape kinds.
15376
17164
  */
15377
17165
  const setShapeTextAutoFit = (shape, mode) => {
17166
+ oneOf(mode, [
17167
+ "none",
17168
+ "normal",
17169
+ "shape"
17170
+ ], "setShapeTextAutoFit: mode");
15378
17171
  const bodyPr = requireBodyPr(shape);
15379
17172
  bodyPr.children = bodyPr.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.dml && AUTO_FIT_LOCALS.has(c.name.localName)));
15380
- const local = mode === "none" ? "noAutofit" : mode === "normal" ? "normAutofit" : "spAutoFit";
17173
+ const local = {
17174
+ none: "noAutofit",
17175
+ normal: "normAutofit",
17176
+ shape: "spAutoFit"
17177
+ }[mode];
15381
17178
  bodyPr.children.push(elem(qname("a", local, NS.dml)));
15382
17179
  commitAndRefresh(shape);
15383
17180
  };
@@ -15570,6 +17367,7 @@ const getShapeTextDirection = (shape) => {
15570
17367
  * horizontal direction. Throws for non-text-bearing shape kinds.
15571
17368
  */
15572
17369
  const setShapeTextDirection = (shape, direction) => {
17370
+ if (direction !== null) oneOf(direction, TEXT_DIRECTIONS, "setShapeTextDirection: direction");
15573
17371
  const bodyPr = requireBodyPr(shape);
15574
17372
  bodyPr.attrs = bodyPr.attrs.filter((a) => !(a.name.namespaceURI === "" && a.name.localName === "vert"));
15575
17373
  if (direction !== null && direction !== "horz") bodyPr.attrs.push(attr(qname("", "vert", ""), direction));
@@ -15686,13 +17484,18 @@ const getShapeBodyPrEffective = (pres, shape) => {
15686
17484
  return result;
15687
17485
  };
15688
17486
  const setShapeTextAnchor = (shape, anchor) => {
17487
+ oneOf(anchor, [
17488
+ "top",
17489
+ "center",
17490
+ "bottom"
17491
+ ], "setShapeTextAnchor: anchor");
15689
17492
  const txBody = requireTxBody(shape);
15690
17493
  let bodyPr = firstChildElement(txBody, NAME_A_BODY_PR);
15691
17494
  if (bodyPr === null) {
15692
17495
  bodyPr = elem(NAME_A_BODY_PR);
15693
17496
  txBody.children.unshift(bodyPr);
15694
17497
  }
15695
- const token = anchor === "top" ? "t" : anchor === "center" ? "ctr" : "b";
17498
+ const token = TEXT_ANCHORS[anchor];
15696
17499
  const ATTR_ANCHOR = qname("", "anchor", "");
15697
17500
  bodyPr.attrs = bodyPr.attrs.filter((a) => !(a.name.namespaceURI === "" && a.name.localName === "anchor"));
15698
17501
  bodyPr.attrs.push(attr(ATTR_ANCHOR, token));
@@ -15756,7 +17559,7 @@ const setShapeAlignment = (shape, align) => {
15756
17559
  * updates compose.
15757
17560
  */
15758
17561
  const setShapeTextFormat = (shape, format) => {
15759
- applyFormatToAllRuns(requireTxBody(shape), format);
17562
+ applyFormatToAllRuns(requireTxBody(shape), format, "setShapeTextFormat");
15760
17563
  commitAndRefresh(shape);
15761
17564
  };
15762
17565
  /**
@@ -15791,7 +17594,8 @@ const copyShape = (targetSlide, sourceShape) => {
15791
17594
  const pkg = targetSlide[INTERNAL_PACKAGE];
15792
17595
  const sourceEl = sourceShape[SHAPE_ELEMENT];
15793
17596
  const cloned = cloneXmlElement(sourceEl);
15794
- rewriteCNvPrId(cloned, nextShapeId(targetSlide));
17597
+ const newId = nextShapeId(targetSlide);
17598
+ rewriteCNvPrId(cloned, newId);
15795
17599
  const sourceRels = pkg.getRels(sourceSlide[SLIDE_PART_NAME]);
15796
17600
  if (sourceRels) {
15797
17601
  const targetRels = pkg.getRels(targetSlide[SLIDE_PART_NAME]) ?? emptyRels();
@@ -15811,6 +17615,8 @@ const copyShape = (targetSlide, sourceShape) => {
15811
17615
  });
15812
17616
  pkg.setRels(targetSlide[SLIDE_PART_NAME], targetRels);
15813
17617
  }
17618
+ const media = cloned.name.localName === "pic" ? readPictureMediaRef(cloned) : null;
17619
+ if (media !== null) addMediaTimingNode(targetSlide, media.kind, newId);
15814
17620
  return appendAndReturnNewShape(targetSlide, cloned);
15815
17621
  };
15816
17622
  /** Recursively clone an XML element (no parent, deep). */
@@ -15995,7 +17801,13 @@ const sendShapeBackward = (shape) => {
15995
17801
  */
15996
17802
  const clearSlideShapes = (slide) => {
15997
17803
  const spTree = requireSpTree(slide);
15998
- spTree.children = spTree.children.filter((c) => !(c.kind === "element" && c.name.namespaceURI === NS.pml && SHAPE_CHILD_LOCALS.has(c.name.localName)));
17804
+ const removedIds = /* @__PURE__ */ new Set();
17805
+ spTree.children = spTree.children.filter((c) => {
17806
+ const isShape = c.kind === "element" && c.name.namespaceURI === NS.pml && SHAPE_CHILD_LOCALS.has(c.name.localName);
17807
+ if (isShape) collectShapeIds(c, removedIds);
17808
+ return !isShape;
17809
+ });
17810
+ removeMediaTimingNodes(slide, removedIds);
15999
17811
  commitSlideData(slide);
16000
17812
  rebuildShapesFromDocument(slide);
16001
17813
  };
@@ -16009,9 +17821,20 @@ const removeShape = (shape) => {
16009
17821
  const idx = spTree.children.indexOf(shape[SHAPE_ELEMENT]);
16010
17822
  if (idx < 0) return;
16011
17823
  spTree.children.splice(idx, 1);
17824
+ const removedIds = /* @__PURE__ */ new Set();
17825
+ collectShapeIds(shape[SHAPE_ELEMENT], removedIds);
17826
+ removeMediaTimingNodes(slide, removedIds);
16012
17827
  commitSlideData(slide);
16013
17828
  rebuildShapesFromDocument(slide);
16014
17829
  };
17830
+ const collectShapeIds = (el, into) => {
17831
+ if (el.name.namespaceURI === NS.pml && el.name.localName === "cNvPr") {
17832
+ const id = Number.parseInt(getAttrValue(el, qname("", "id", "")) ?? "", 10);
17833
+ if (Number.isFinite(id)) into.add(id);
17834
+ return;
17835
+ }
17836
+ for (const c of el.children) if (c.kind === "element") collectShapeIds(c, into);
17837
+ };
16015
17838
  //#endregion
16016
17839
  //#region src/api/fn/shape-authoring.ts
16017
17840
  /**
@@ -16839,7 +18662,7 @@ const ensureSldIdLst = (presentationRoot) => {
16839
18662
  const allocateSldId = (sldIdLst) => {
16840
18663
  let max = 255;
16841
18664
  for (const sldId of allChildElements(sldIdLst, NAME_SLD_ID$1)) {
16842
- const raw = getAttrValue(sldId, ATTR_ID$1);
18665
+ const raw = getAttrValue(sldId, ATTR_ID$2);
16843
18666
  if (raw === null) continue;
16844
18667
  const n = Number.parseInt(raw, 10);
16845
18668
  if (Number.isFinite(n) && n > max) max = n;
@@ -16970,7 +18793,7 @@ const addSlide = (pres, options) => {
16970
18793
  targetMode: "Internal"
16971
18794
  });
16972
18795
  pkg.setRels(PRES_PART_NAME, presRels);
16973
- sldIdLst.children.push(elem(NAME_SLD_ID$1, { attrs: [attr(ATTR_ID$1, String(newSldId)), attr(ATTR_R_ID$1, newRId)] }));
18796
+ sldIdLst.children.push(elem(NAME_SLD_ID$1, { attrs: [attr(ATTR_ID$2, String(newSldId)), attr(ATTR_R_ID$1, newRId)] }));
16974
18797
  presPart.data = encode$1(serializeXml(presDoc));
16975
18798
  pres._slidesCache = null;
16976
18799
  const slides = getSlides(pres);
@@ -17149,7 +18972,7 @@ const duplicateSlide = (pres, slide) => {
17149
18972
  targetMode: "Internal"
17150
18973
  });
17151
18974
  pkg.setRels(PRES_PART_NAME, presRels);
17152
- sldIdLst.children.push(elem(NAME_SLD_ID$1, { attrs: [attr(ATTR_ID$1, String(newSldId)), attr(ATTR_R_ID$1, newRId)] }));
18975
+ sldIdLst.children.push(elem(NAME_SLD_ID$1, { attrs: [attr(ATTR_ID$2, String(newSldId)), attr(ATTR_R_ID$1, newRId)] }));
17153
18976
  presPart.data = encode$1(serializeXml(presDoc));
17154
18977
  pres._slidesCache = null;
17155
18978
  const slides = getSlides(pres);
@@ -17179,6 +19002,12 @@ const collectRelRefs = (el, into) => {
17179
19002
  for (const a of el.attrs) if (a.name.namespaceURI === NS.officeDocRels) into.add(a.value);
17180
19003
  for (const c of el.children) if (c.kind === "element") collectRelRefs(c, into);
17181
19004
  };
19005
+ const IMPORTED_MEDIA_REL_TYPES = new Set([
19006
+ REL_TYPES.image,
19007
+ REL_TYPES.media,
19008
+ REL_TYPES.video,
19009
+ REL_TYPES.audio
19010
+ ]);
17182
19011
  const pruneDanglingGraphicFrames = (el, keptRelIds) => {
17183
19012
  el.children = el.children.filter((c) => {
17184
19013
  if (c.kind !== "element") return true;
@@ -17200,8 +19029,8 @@ const pruneDanglingGraphicFrames = (el, keptRelIds) => {
17200
19029
  *
17201
19030
  * Limitations (v1):
17202
19031
  *
17203
- * - Only `image` rels are copied across. Other rels (charts, embedded
17204
- * workbooks, oleObjects, comments) are dropped from the imported
19032
+ * - Only image / video / audio rels are copied across. Other rels (charts,
19033
+ * embedded workbooks, oleObjects, comments) are dropped from the imported
17205
19034
  * slide. A diagnostic message is appended for each dropped rel.
17206
19035
  * - Hyperlinks (external URLs) are preserved.
17207
19036
  * - Slide → notesSlide is dropped (notes don't follow imports).
@@ -17233,31 +19062,42 @@ const importSlide = (targetPres, sourceSlide, targetLayout) => {
17233
19062
  target: `../slideLayouts/${basename(layoutPartName)}`,
17234
19063
  targetMode: "Internal"
17235
19064
  });
19065
+ const importedMedia = /* @__PURE__ */ new Map();
17236
19066
  if (sourceRels !== null) for (const rel of sourceRels.items) {
17237
19067
  if (rel.type === REL_TYPES.slideLayout) continue;
17238
19068
  if (rel.type === REL_TYPES.notesSlide) continue;
17239
- if (rel.type === REL_TYPES.image && rel.targetMode === "Internal") {
19069
+ if (IMPORTED_MEDIA_REL_TYPES.has(rel.type)) {
19070
+ if (rel.targetMode === "External") {
19071
+ newRels.items.push({ ...rel });
19072
+ continue;
19073
+ }
17240
19074
  const mediaName = rel.target.startsWith("/") ? partName(rel.target) : resolveTarget(sourcePartName, rel.target);
17241
- const mediaPart = sourcePkg.getPart(mediaName);
17242
- if (!mediaPart) continue;
17243
- const dotIdx = mediaName.lastIndexOf(".");
17244
- const extension = dotIdx >= 0 ? mediaName.slice(dotIdx + 1) : "bin";
17245
- let nextN = 1;
17246
- const re = /^\/ppt\/media\/image(\d+)\./;
17247
- for (const p of targetPkg.parts) {
17248
- const m = p.name.match(re);
17249
- if (m?.[1] !== void 0) {
17250
- const n = Number.parseInt(m[1], 10);
17251
- if (Number.isFinite(n) && n >= nextN) nextN = n + 1;
19075
+ let target = importedMedia.get(mediaName);
19076
+ if (target === void 0) {
19077
+ const mediaPart = sourcePkg.getPart(mediaName);
19078
+ if (!mediaPart) continue;
19079
+ const dotIdx = mediaName.lastIndexOf(".");
19080
+ const extension = dotIdx >= 0 ? mediaName.slice(dotIdx + 1) : "bin";
19081
+ const stem = rel.type === REL_TYPES.image ? "image" : "media";
19082
+ let nextN = 1;
19083
+ const re = new RegExp(`^/ppt/media/${stem}(\\d+)\\.`);
19084
+ for (const p of targetPkg.parts) {
19085
+ const m = p.name.match(re);
19086
+ if (m?.[1] !== void 0) {
19087
+ const n = Number.parseInt(m[1], 10);
19088
+ if (Number.isFinite(n) && n >= nextN) nextN = n + 1;
19089
+ }
17252
19090
  }
19091
+ const newMediaName = partName(`/ppt/media/${stem}${nextN}.${extension}`);
19092
+ setOpcDefault(targetPkg, extension.toLowerCase(), mediaPart.contentType);
19093
+ targetPkg.addPart(newMediaName, mediaPart.contentType, new Uint8Array(mediaPart.data));
19094
+ target = `../media/${stem}${nextN}.${extension}`;
19095
+ importedMedia.set(mediaName, target);
17253
19096
  }
17254
- const newMediaName = partName(`/ppt/media/image${nextN}.${extension}`);
17255
- setOpcDefault(targetPkg, extension.toLowerCase(), mediaPart.contentType);
17256
- targetPkg.addPart(newMediaName, mediaPart.contentType, new Uint8Array(mediaPart.data));
17257
19097
  newRels.items.push({
17258
19098
  id: rel.id,
17259
- type: REL_TYPES.image,
17260
- target: `../media/image${nextN}.${extension}`,
19099
+ type: rel.type,
19100
+ target,
17261
19101
  targetMode: "Internal"
17262
19102
  });
17263
19103
  continue;
@@ -17293,7 +19133,7 @@ const importSlide = (targetPres, sourceSlide, targetLayout) => {
17293
19133
  targetMode: "Internal"
17294
19134
  });
17295
19135
  targetPkg.setRels(PRES_PART_NAME, presRels);
17296
- sldIdLst.children.push(elem(NAME_SLD_ID$1, { attrs: [attr(ATTR_ID$1, String(newSldId)), attr(ATTR_R_ID$1, newRId)] }));
19136
+ sldIdLst.children.push(elem(NAME_SLD_ID$1, { attrs: [attr(ATTR_ID$2, String(newSldId)), attr(ATTR_R_ID$1, newRId)] }));
17297
19137
  presPart.data = encode$1(serializeXml(presDoc));
17298
19138
  targetPres._slidesCache = null;
17299
19139
  const slides = getSlides(targetPres);
@@ -17436,9 +19276,204 @@ const ungroupShapes = (group) => {
17436
19276
  });
17437
19277
  };
17438
19278
  //#endregion
19279
+ //#region src/api/fn/media.ts
19280
+ const DEFAULT_POSTER_BASE64 = "iVBORw0KGgoAAAANSUhEUgAAAUAAAAC0AQMAAADfKmdSAAAABlBMVEUmJib///+/9FOwAAAAvUlEQVR42u3XMQ7DIBAEQOfnfhpP4QmUFAgiJUqdKa6xtFtPA8J36+tKkiRJkiR5RF4Mm8KucCrcCg/DpnAoXAq3wnMr7AqnwqXwMGwKu8KpcCukK//ApnAoXAq3QjnNF3aFU+FSeBg2hUPhVLgV/r/yH2wKRzls1YfZ5Rc+yh9F+cOd5R/XXT0AVvmQatWDlEczD3teH7yQypcmr2Fe7FoVuHxwneGCxJWrvBZy0eTqymU4fxhJkiRJkjwqbzMmJGbQfp8bAAAAAElFTkSuQmCC";
19281
+ const defaultPoster = () => Uint8Array.from(atob(DEFAULT_POSTER_BASE64), (ch) => ch.charCodeAt(0));
19282
+ const YOUTUBE_HOSTS = new Set([
19283
+ "youtube.com",
19284
+ "www.youtube.com",
19285
+ "m.youtube.com"
19286
+ ]);
19287
+ const YOUTUBE_SHORT_HOST = "youtu.be";
19288
+ const YOUTUBE_ID = /^[A-Za-z0-9_-]+$/;
19289
+ const youtubeVideoId = (url) => {
19290
+ const segments = url.pathname.split("/").filter((s) => s !== "");
19291
+ if (url.hostname === YOUTUBE_SHORT_HOST) return segments[0] ?? null;
19292
+ if (!YOUTUBE_HOSTS.has(url.hostname)) return null;
19293
+ if (segments[0] === "watch") return url.searchParams.get("v");
19294
+ if (segments[0] === "shorts" || segments[0] === "live") return segments[1] ?? null;
19295
+ return null;
19296
+ };
19297
+ const resolveOnlineVideoUrl = (input) => {
19298
+ let url;
19299
+ try {
19300
+ url = new URL(input);
19301
+ } catch {
19302
+ throw new Error(`addSlideMedia: url is not an absolute URL: ${JSON.stringify(input)}`);
19303
+ }
19304
+ if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error(`addSlideMedia: url must be http(s), got ${JSON.stringify(input)}`);
19305
+ const id = youtubeVideoId(url);
19306
+ if (id === null || !YOUTUBE_ID.test(id)) return url.href;
19307
+ return `https://www.youtube.com/embed/${id}?feature=oembed`;
19308
+ };
19309
+ const MEDIA_DIR = "/ppt/media/";
19310
+ const nextMediaPartName = (pkg, stem, extension) => {
19311
+ let nextN = 1;
19312
+ const pattern = new RegExp(`^/ppt/media/${stem}(\\d+)\\.`);
19313
+ for (const p of pkg.parts) {
19314
+ const m = p.name.match(pattern);
19315
+ if (m?.[1] !== void 0) {
19316
+ const n = Number.parseInt(m[1], 10);
19317
+ if (n >= nextN) nextN = n + 1;
19318
+ }
19319
+ }
19320
+ return partName(`${MEDIA_DIR}${stem}${nextN}.${extension}`);
19321
+ };
19322
+ const bytesEqual = (a, b) => {
19323
+ if (a.length !== b.length) return false;
19324
+ for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
19325
+ return true;
19326
+ };
19327
+ const internClipPart = (pkg, extension, contentType, bytes) => {
19328
+ for (const p of pkg.parts) if (p.name.startsWith(MEDIA_DIR) && p.contentType === contentType && bytesEqual(p.data, bytes)) return p.name;
19329
+ const name = nextMediaPartName(pkg, "media", extension);
19330
+ setOpcDefault(pkg, extension, contentType);
19331
+ pkg.addPart(name, contentType, bytes);
19332
+ return name;
19333
+ };
19334
+ const resolveSource = (source) => {
19335
+ switch (source.kind) {
19336
+ case "online": return { url: resolveOnlineVideoUrl(source.url) };
19337
+ case "video": {
19338
+ const format = source.format ?? detectVideoFormat(source.data);
19339
+ if (format === null) throw new Error("addSlideMedia: could not detect the video format. Pass options.format explicitly.");
19340
+ const contentType = contentTypeForVideoFormat(format);
19341
+ return {
19342
+ data: source.data,
19343
+ extension: format,
19344
+ contentType
19345
+ };
19346
+ }
19347
+ case "audio": {
19348
+ const format = source.format ?? detectAudioFormat(source.data);
19349
+ if (format === null) throw new Error("addSlideMedia: could not detect the audio format. Pass options.format explicitly.");
19350
+ const contentType = contentTypeForAudioFormat(format);
19351
+ return {
19352
+ data: source.data,
19353
+ extension: format,
19354
+ contentType
19355
+ };
19356
+ }
19357
+ }
19358
+ };
19359
+ const DEFAULT_NAME_PREFIX = {
19360
+ video: "Video",
19361
+ audio: "Audio",
19362
+ online: "Online Media"
19363
+ };
19364
+ /**
19365
+ * Adds a video, an audio clip or an online (URL) video to the slide. Returns
19366
+ * the new picture shape — the clip's poster frame.
19367
+ *
19368
+ * Embedded clips are stored once per package: adding the same bytes again
19369
+ * reuses the existing `/ppt/media/mediaN.<ext>` part. The container format is
19370
+ * detected from the bytes (mp4 / m4v / mov / webm / avi / wmv, mp3 / wav / m4a /
19371
+ * ogg / wma); pass `format` for anything the signature check cannot tell.
19372
+ * Whether a clip plays depends on the codecs of the viewing application.
19373
+ *
19374
+ * The shape is an ordinary picture: `getShapeImageBytes` / `setShapeImage`
19375
+ * read and replace the poster, `getShapeMedia` reads the clip.
19376
+ */
19377
+ const addSlideMedia = (slide, opts) => {
19378
+ const x = emuCoordinate(opts.x, "addSlideMedia: x");
19379
+ const y = emuCoordinate(opts.y, "addSlideMedia: y");
19380
+ const w = emuExtent(opts.w, "addSlideMedia: w");
19381
+ const h = emuExtent(opts.h, "addSlideMedia: h");
19382
+ const source = resolveSource(opts);
19383
+ const poster = opts.poster ?? defaultPoster();
19384
+ const posterFormat = opts.posterFormat ?? detectImageFormat(poster);
19385
+ if (posterFormat === null) throw new Error("addSlideMedia: could not detect the poster image format. Pass options.posterFormat explicitly.");
19386
+ const pkg = slide[INTERNAL_PACKAGE];
19387
+ const slidePartName = slide[SLIDE_PART_NAME];
19388
+ const rels = pkg.getRels(slidePartName) ?? emptyRels();
19389
+ const usedIds = rels.items.map((r) => r.id);
19390
+ const relate = (type, target, targetMode) => {
19391
+ const existing = rels.items.find((r) => r.type === type && r.target === target && r.targetMode === targetMode);
19392
+ if (existing) return existing.id;
19393
+ const id = nextRelId(usedIds);
19394
+ usedIds.push(id);
19395
+ rels.items.push({
19396
+ id,
19397
+ type,
19398
+ target,
19399
+ targetMode
19400
+ });
19401
+ return id;
19402
+ };
19403
+ const relativeTarget = (name) => `../media/${name.slice(11)}`;
19404
+ const kind = opts.kind === "audio" ? "audio" : "video";
19405
+ const fileRelType = kind === "audio" ? REL_TYPES.audio : REL_TYPES.video;
19406
+ let rLink;
19407
+ let rMedia;
19408
+ if ("url" in source) rLink = relate(fileRelType, source.url, "External");
19409
+ else {
19410
+ const clipPart = internClipPart(pkg, source.extension, source.contentType, source.data);
19411
+ rMedia = relate(REL_TYPES.media, relativeTarget(clipPart), "Internal");
19412
+ rLink = relate(fileRelType, relativeTarget(clipPart), "Internal");
19413
+ }
19414
+ const posterExtension = extensionForFormat(posterFormat);
19415
+ const posterContentType = contentTypeForFormat(posterFormat);
19416
+ const posterPart = nextMediaPartName(pkg, "image", posterExtension);
19417
+ setOpcDefault(pkg, posterExtension, posterContentType);
19418
+ pkg.addPart(posterPart, posterContentType, poster);
19419
+ const rPoster = relate(REL_TYPES.image, relativeTarget(posterPart), "Internal");
19420
+ pkg.setRels(slidePartName, rels);
19421
+ const id = nextShapeId(slide);
19422
+ const pic = buildMediaPicture({
19423
+ id,
19424
+ name: opts.name ?? `${DEFAULT_NAME_PREFIX[opts.kind]} ${id}`,
19425
+ kind,
19426
+ rLink,
19427
+ ...rMedia !== void 0 ? { rMedia } : {},
19428
+ rEmbed: rPoster,
19429
+ x,
19430
+ y,
19431
+ w,
19432
+ h
19433
+ });
19434
+ addMediaTimingNode(slide, kind, id);
19435
+ return appendAndReturnNewShape(slide, pic);
19436
+ };
19437
+ /**
19438
+ * Returns the clip behind a media picture, or `null` when the shape is not
19439
+ * one. Reads PowerPoint-, PptxGenJS- and python-pptx-authored media alike: the
19440
+ * embedded part is taken from `<p14:media r:embed>` when present and from the
19441
+ * DrawingML `r:link` otherwise; a relationship with an external target is
19442
+ * reported as `'online'`.
19443
+ */
19444
+ const getShapeMedia = (shape) => {
19445
+ if (shape[SHAPE_SNAPSHOT].kind !== "picture") return null;
19446
+ const ref = readPictureMediaRef(shape[SHAPE_ELEMENT]);
19447
+ if (ref === null) return null;
19448
+ const slide = shape[SHAPE_SLIDE];
19449
+ const pkg = slide[INTERNAL_PACKAGE];
19450
+ const rels = pkg.getRels(slide[SLIDE_PART_NAME]);
19451
+ if (rels === null) return null;
19452
+ const relsById = new Map(rels.items.map((r) => [r.id, r]));
19453
+ for (const rId of [ref.mediaRId, ref.fileRId]) {
19454
+ const rel = rId === null ? void 0 : relsById.get(rId);
19455
+ if (rel === void 0) continue;
19456
+ if (rel.targetMode === "External") return {
19457
+ kind: "online",
19458
+ url: rel.target
19459
+ };
19460
+ const name = rel.target.startsWith("/") ? partName(rel.target) : resolveTarget(slide[SLIDE_PART_NAME], rel.target);
19461
+ const part = pkg.getPart(name);
19462
+ if (part) return {
19463
+ kind: ref.kind,
19464
+ partName: part.name,
19465
+ contentType: part.contentType,
19466
+ bytes: part.data
19467
+ };
19468
+ }
19469
+ return null;
19470
+ };
19471
+ /** Every shape on the slide that `getShapeMedia` reports a clip for. */
19472
+ const findShapesWithMedia = (slide) => slide[SLIDE_SHAPES].filter((shape) => getShapeMedia(shape) !== null);
19473
+ //#endregion
17439
19474
  //#region src/api/index.ts
17440
- const VERSION = "0.16.1";
19475
+ const VERSION = "0.18.0";
17441
19476
  //#endregion
17442
- export { slideHasAnimations as $, getTableCellMargins as $a, clearSlideHyperlinks as $i, getShapeText as $n, getSlideLayouts as $o, getShapeRunCount as $r, getCommentAuthor as $s, getShapeStrokeColorResolved as $t, getPresentationTextLength as A, clearSlideTransition as Aa, getShapeImageContrast as Ai, findShapesAtPoint as An, setTableStyleFlags as Ao, setShapeSize as Ar, getSlideLayoutBackgroundImageBytes as As, setShapeTextBodyRotationDeg as At, getSlideText as B, listPackageParts as Ba, isShapeImageGrayscale as Bi, getShapeCenter as Bn, setCoreProperties as Bo, getParagraphAlignment as Br, setSlideBackgroundImage as Bs, getShapeEffectsEffective as Bt, findSlideByTitle as C, getSlidesWithOverlap as Ca, pt as Cc, findSlidesByLayoutName as Ci, getSlideLayout as Cn, setTableCellMargins as Co, setShapeGradientFill as Cr, getSlideBackground as Cs, getShapeTextWrap as Ct, getOutlineText as D, removeSlideNotes as Da, getShapeImageBiLevelThreshold as Di, setSlideLayout as Dn, setTableCellTextFormat as Do, setShapePatternFill as Dr, getSlideColorMapOverride as Ds, setShapeText as Dt, getAllShapes as E, hasSlideNotes as Ea, getPresentationImageCountsBySlide as Ei, replaceTokensInSlide as En, setTableCellTextDirection as Eo, setShapeNoStroke as Er, getSlideBackgroundPatternFill as Es, setShapeParagraphs as Et, getSlideIndex as F, getMediaParts as Fa, getShapeImageLinkUrl as Fi, getMaxShapeIdInPresentation as Fn, getCoreProperties as Fo, setShapeStrokeDash as Fr, getSlideMasterBackgroundGradientFill as Fs, setShapeTextWrap as Ft, isSlideHidden as G, clearTableCellFill as Ga, SLIDE_SIZE_16_10 as Gi, getShapeKind as Gn, findSlideLayoutByPartName as Go, getParagraphIndent as Gr, clearAllSlideComments as Gs, getShapeFill as Gt, getSlideXmlString as H, setMediaPartBytes as Ha, setShapeImageContrast as Hi, getShapeDescription as Hn, touchModified as Ho, getParagraphBulletImageBytes as Hr, setShapeClickAction as Hs, setShapeShadow as Ht, getSlideInfo as I, getOrphanMediaPartNames as Ia, getShapeImageOpacity as Ii, getShapeAdjustValues as In, getExtendedProperties as Io, setShapeStrokeJoin as Ir, getSlideMasterBackgroundImageBytes as Is, clearShapeEffects as It, replaceTextInSlide as J, getTableCell as Ja, getSlideSize as Ji, getShapePlaceholderType as Jn, getSlideLayoutPartName as Jo, getParagraphSpacing as Jr, findCommentsAfter as Js, getShapeFillEffective as Jt, replaceTextInNotes as K, getPresentationTableCountsBySlide as Ka, SLIDE_SIZE_16_9 as Ki, getShapeName as Kn, findSlideLayoutByType as Ko, getParagraphLevel as Kr, clearSlideComments as Ks, getShapeFillColor as Kt, getSlideLayoutCount as L, getPackageSize as La, getShapeImagePartName as Li, getShapeAltTitle as Ln, getPresentationCreated as Lo, getShapeRunFormat as Lr, getSlideMasterBackgroundPatternFill as Ls, findShapesByEffect as Lt, getShapeAt as M, setSlideTransition as Ma, getShapeImageDuotone as Mi, getGroupChildren as Mn, getThumbnail as Mo, setShapeStrokeArrow as Mr, getSlideLayoutBackgroundShapes as Ms, setShapeTextDirection as Mt, getSlideAt as N, _internalPackageOf as Na, getShapeImageFillBytes as Ni, getGroupTransform as Nn, removeThumbnail as No, setShapeStrokeCap as Nr, getSlideLayoutShapes as Ns, setShapeTextFormat as Nt, getPresentationShapeCountsBySlide as O, replaceHyperlink as Oa, getShapeImageBrightness as Oi, translateShapes as On, setTableColumnWidth as Oo, setShapePosition as Or, getSlideLayoutBackground as Os, setShapeTextAnchor as Ot, getSlideCount as P, compactPackage as Pa, getShapeImageFormat as Pi, getMaxShapeId as Pn, setThumbnail as Po, setShapeStrokeCompound as Pr, getSlideMasterBackground as Ps, setShapeTextMargins as Pt, setSlideHidden as Q, getTableCellFill as Qa, clearAllSlideNotes as Qi, getShapeSize as Qn, getSlideLayoutUsageCountsByType as Qo, getShapeRunClickAction as Qr, findSlidesWithCommentsByAuthor as Qs, getShapeStrokeColor as Qt, getSlideOutline as R, getPresentationSummary as Ra, hasShapeImage as Ri, getShapeBounds as Rn, getPresentationModified as Ro, resolveDrawingColor as Rr, getSlideMasterShapes as Rs, getShapeEffect as Rt, findSlideByText as S, getSlidesWithNotes as Sa, mm as Sc, findShapesOutsideCanvas as Si, getShapesBounds as Sn, setTableCellFill as So, setShapeFlip as Sr, clearSlideBackground as Ss, getShapeTextMargins as St, findSlidesByText as T, getVisibleSlides as Ta, findSlidesByLayoutType as Ti, getSlidesWithEmptyPlaceholders as Tn, setTableCellText as To, setShapeNoFill as Tr, getSlideBackgroundImageBytes as Ts, setShapeBullets as Tt, getSlides as U, slidesUsingMediaPart as Ua, setShapeImageCrop as Ui, getShapeFlip as Un, findLayoutsWithPlaceholderType as Uo, getParagraphBulletStyle as Ur, setShapeImage as Us, getShapeGradientFill as Ut, getSlideTextLength as V, readPackagePart as Va, setShapeImageBrightness as Vi, getShapeCustomGeometry as Vn, setExtendedProperties as Vo, getParagraphBullet as Vr, getShapeClickAction as Vs, setShapeGlow as Vt, getSlidesByLayout as W, validatePresentation as Wa, setShapeImageOpacity as Wi, getShapeId as Wn, findSlideLayout as Wo, getParagraphEndFormat as Wr, addSlideComment as Ws, getShapeGradientFillEffective as Wt, replaceTokensInPresentation as X, getTableCellAnchor as Xa, appendSlideNotes as Xi, getShapePreset as Xn, getSlideLayoutType as Xo, getShapeParagraphCount as Xr, findCommentsByAuthor as Xs, getShapeStroke as Xt, replaceTextInSlideNotes as Y, getTableCellAlignment as Ya, setSlideSize as Yi, getShapePosition as Yn, getSlideLayoutPlaceholders as Yo, getShapeHyperlinkTooltip as Yr, findCommentsBefore as Ys, getShapeFillOpacity as Yt, searchSlides as Z, getTableCellBorders as Za, clearAllHyperlinks as Zi, getShapeRotation as Zn, getSlideLayoutUsageCounts as Zo, getShapeParagraphElements as Zr, findCommentsByText as Zs, getShapeStrokeCap as Zt, sortSlides as _, getSlideNotesLength as _a, loadPresentation as _c, findShapesWithAnimation as _i, findSlidePlaceholderByIdx as _n, removeTableColumn as _o, getShapePatternFill as _r, getShapeChartSpec as _s, getShapeTextAutoFit as _t, addContentSlide as a, getAllHyperlinks as aa, getCommentsSortedByDate as ac, setParagraphBullet as ai, findEmptyPlaceholders as an, getTableCells as ao, isShapeHidden as ar, setShapeRunFormat as as, bringShapeForward as at, setSlideSections as b, getSlidesWithHyperlinks as ba, emu as bc, findFlippedShapes as bi, getShapeSlide as bn, setTableCellAnchor as bo, setShapeAdjustValues as br, getEffectiveColorMap as bs, getShapeTextColumns as bt, addSlideAt as c, getAllTables as ca, getPresentationCommenters as cc, setParagraphSpacing as ci, findShapeByText as cn, getTableRowHeights as co, pointInShape as cr, findChartsBySeriesName as cs, copyShape as ct, duplicateSlideAt as d, getHiddenSlides as da, removeSlideComment as dc, getSlideBody as di, findShapesByKind as dn, getTableStyleId as do, setShapeBounds as dr, getPresentationChartCountsBySlide as ds, sendShapeBackward as dt, findSlidesByHyperlink as ea, getCommentAuthors as ec, getShapeRunHyperlink as ei, getShapeStrokeCompound as en, getTableCellParagraphs as eo, getSlideMasterCount as er, getUnusedSlideLayouts as es, addSlideImage as et, importSlide as f, getPresentationHyperlinkCountsBySlide as fa, getPresentationFonts as fc, getSlideTitle as fi, findShapesByName as fn, insertTableColumn as fo, setShapeDescription as fr, getPresentationChartKindCounts as fs, sendShapeToBack as ft, reverseSlides as g, getSlideNotes as ga, createPresentation as gc, clearSlideAnimations as gi, findSlidePlaceholder as gn, mergeTableCells as go, clearShapeStroke as gr, getShapeChartSeriesValues as gs, getShapeTextAnchor as gt, removeSlide as h, getPresentationNotesText as ha, setPresentationTheme as hc, setSlideTitle as hi, findShapesWithHyperlinks as hn, isTableShape as ho, clearShapeFill as hr, getShapeChartSeriesNames as hs, getShapeBodyPrEffective as ht, addBlankSlide as i, getAllComments as ia, getCommentText as ic, setParagraphAlignment as ii, getShapeStrokeWidth as in, getTableCellTextDirection as io, getUnusedSlideMasters as ir, setShapeHyperlink as is, addSlideTextBox as it, getPresentationTextLengthsBySlide as j, getSlideTransition as ja, getShapeImageCrop as ji, findShapesInRect as jn, setTableStyleId as jo, setShapeStroke as jr, getSlideLayoutBackgroundPatternFill as js, setShapeTextColumns as jt, getPresentationText as k, setSlideNotes as ka, getShapeImageBytes as ki, centerShapeOnSlide as kn, setTableRowHeight as ko, setShapeRotation as kr, getSlideLayoutBackgroundGradientFill as ks, setShapeTextAutoFit as kt, addTitleSlide as l, getDistinctHyperlinkUrls as la, getSlideCommentAuthors as lc, setShapeRunHyperlink as li, findShapeInPresentation as ln, getTableSize as lo, renameShape as lr, findChartsWithDataLabels as ls, getShapeZIndex as lt, moveSlide as m, getPresentationNotesLengthsBySlide as ma, setPresentationFonts as mc, setSlidePlaceholders as mi, findShapesByText as mn, isChartShape as mo, shapesOverlap as mr, getShapeChartKind as ms, appendShapeText as mt, groupShapes as n, findSlidesWithChartTrendlines as na, getCommentPosition as nc, getShapeRunText as ni, getShapeStrokeJoin as nn, getTableCellSpan as no, getSlideMasterPartNames as nr, getShapeHyperlink as ns, addSlideShape as nt, addSectionHeaderSlide as o, getAllImages as oa, getPresentationCommentCountsByAuthor as oc, setParagraphLevel as oi, findShapeById as on, getTableColumnWidths as oo, isShapePlaceholder as or, addSlideChart as os, bringShapeToFront as ot, mergePresentations as p, getPresentationNotesLength as pa, getPresentationTheme as pc, setSlideBody as pi, findShapesByPreset as pn, insertTableRow as po, setShapeHidden as pr, getShapeChartCategories as ps, setShapeZIndex as pt, replaceTextInPresentation as q, getSlideTables as qa, SLIDE_SIZE_4_3 as qi, getShapePlaceholderIdx as qn, getSlideLayoutName as qo, getParagraphLineSpacing as qr, findCommentAuthorByName as qs, getShapeFillColorResolved as qt, ungroupShapes as r, getAllCharts as ra, getCommentSlide as rc, isParagraphBulletPicture as ri, getShapeStrokeOpacity as rn, getTableCellText as ro, getSlideMasterUsageCounts as rr, getShapeRunFormatEffective as rs, addSlideTable as rt, addSlide as s, getAllNotes as sa, getPresentationCommentCountsBySlide as sc, setParagraphLineSpacing as si, findShapeByName as sn, getTableDimensions as so, isShapeTextBox as sr, findChartByKind as ss, clearSlideShapes as st, VERSION as t, findSlidesWithChartKind as ta, getCommentDate as tc, getShapeRunHyperlinkTooltip as ti, getShapeStrokeEffective as tn, getTableCellPosition as to, getSlideMasterPartName as tr, getParagraphPropertiesEffective as ts, addSlideLine as tt, duplicateSlide as u, getEmptySlides as ua, getSlideComments as uc, setShapeRunText as ui, findShapesByHyperlink as un, getTableStyleFlags as uo, setShapeAltTitle as ur, findChartsWithTrendlines as us, removeShape as ut, swapSlides as v, getSlidesWithCharts as va, savePresentation as vc, getShapeAnimation as vi, findSlidePlaceholders as vn, removeTableRow as vo, getShapeStrokeArrow as vr, getSlideCharts as vs, getShapeTextAutoFitParams as vt, findSlidesByNotes as w, getSlidesWithTables as wa, findSlidesByLayoutPartName as wi, getSlideShapes as wn, setTableCellParagraphs as wo, setShapeImageFill as wr, getSlideBackgroundGradientFill as ws, setShapeAlignment as wt, findSlideByPartName as x, getSlidesWithImages as xa, inches as xc, findOverlappingShapePairs as xi, getShapeXmlString as xn, setTableCellBorders as xo, setShapeFill as xr, resolveDeckBodyTextColor as xs, getShapeTextDirection as xt, getSlideSections as y, getSlidesWithComments as ya, cm as yc, setShapeAnimation as yi, getShapeIndex as yn, setTableCellAlignment as yo, getShapeStrokeDash as yr, setChartSpec as ys, getShapeTextBodyRotationDeg as yt, getSlidePartName as z, getSlideMediaPartNames as za, hasShapeText as zi, getShapeBoundsResolved as zn, incrementRevision as zo, resolveDrawingColorOpacity as zr, setSlideBackground as zs, getShapeEffects as zt };
19477
+ export { replaceTokensInPresentation as $, getTableCellAnchor as $a, appendSlideNotes as $i, getShapePreset as $n, getSlideLayoutType as $o, getShapeParagraphCount as $r, findCommentsByAuthor as $s, getShapeStroke as $t, getOutlineText as A, removeSlideNotes as Aa, getShapeImageBiLevelThreshold as Ai, setSlideLayout as An, setTableCellTextFormat as Ao, setShapePatternFill as Ar, getSlideColorMapOverride as As, setShapeText as At, getSlideLayoutCount as B, getPackageSize as Ba, getShapeImagePartName as Bi, getShapeAltTitle as Bn, getPresentationCreated as Bo, getShapeRunFormat as Br, getSlideMasterBackgroundPatternFill as Bs, findShapesByEffect as Bt, setSlideSections as C, getSlidesWithHyperlinks as Ca, emu as Cc, findFlippedShapes as Ci, getShapeSlide as Cn, setTableCellAnchor as Co, setShapeAdjustValues as Cr, getEffectiveColorMap as Cs, getShapeTextColumns as Ct, findSlidesByNotes as D, getSlidesWithTables as Da, findSlidesByLayoutPartName as Di, getSlideShapes as Dn, setTableCellParagraphs as Do, setShapeImageFill as Dr, getSlideBackgroundGradientFill as Ds, setShapeAlignment as Dt, findSlideByTitle as E, getSlidesWithOverlap as Ea, pt as Ec, findSlidesByLayoutName as Ei, getSlideLayout as En, setTableCellMargins as Eo, setShapeGradientFill as Er, getSlideBackground as Es, getShapeTextWrap as Et, getShapeAt as F, setSlideTransition as Fa, getShapeImageDuotone as Fi, getGroupChildren as Fn, getThumbnail as Fo, setShapeStrokeArrow as Fr, getSlideLayoutBackgroundShapes as Fs, setShapeTextDirection as Ft, getSlideXmlString as G, setMediaPartBytes as Ga, setShapeImageContrast as Gi, getShapeDescription as Gn, touchModified as Go, getParagraphBulletImageBytes as Gr, setShapeClickAction as Gs, setShapeShadow as Gt, getSlidePartName as H, getSlideMediaPartNames as Ha, hasShapeText as Hi, getShapeBoundsResolved as Hn, incrementRevision as Ho, resolveDrawingColorOpacity as Hr, setSlideBackground as Hs, getShapeEffects as Ht, getSlideAt as I, _internalPackageOf as Ia, getShapeImageFillBytes as Ii, getGroupTransform as In, removeThumbnail as Io, setShapeStrokeCap as Ir, getSlideLayoutShapes as Is, setShapeTextFormat as It, isSlideHidden as J, clearTableCellFill as Ja, SLIDE_SIZE_16_10 as Ji, getShapeKind as Jn, findSlideLayoutByPartName as Jo, getParagraphIndent as Jr, clearAllSlideComments as Js, getShapeFill as Jt, getSlides as K, slidesUsingMediaPart as Ka, setShapeImageCrop as Ki, getShapeFlip as Kn, findLayoutsWithPlaceholderType as Ko, getParagraphBulletStyle as Kr, setShapeImage as Ks, getShapeGradientFill as Kt, getSlideCount as L, compactPackage as La, getShapeImageFormat as Li, getMaxShapeId as Ln, setThumbnail as Lo, setShapeStrokeCompound as Lr, getSlideMasterBackground as Ls, setShapeTextMargins as Lt, getPresentationText as M, setSlideNotes as Ma, getShapeImageBytes as Mi, centerShapeOnSlide as Mn, setTableRowHeight as Mo, setShapeRotation as Mr, getSlideLayoutBackgroundGradientFill as Ms, setShapeTextAutoFit as Mt, getPresentationTextLength as N, clearSlideTransition as Na, getShapeImageContrast as Ni, findShapesAtPoint as Nn, setTableStyleFlags as No, setShapeSize as Nr, getSlideLayoutBackgroundImageBytes as Ns, setShapeTextBodyRotationDeg as Nt, findSlidesByText as O, getVisibleSlides as Oa, findSlidesByLayoutType as Oi, getSlidesWithEmptyPlaceholders as On, setTableCellText as Oo, setShapeNoFill as Or, getSlideBackgroundImageBytes as Os, setShapeBullets as Ot, getPresentationTextLengthsBySlide as P, getSlideTransition as Pa, getShapeImageCrop as Pi, findShapesInRect as Pn, setTableStyleId as Po, setShapeStroke as Pr, getSlideLayoutBackgroundPatternFill as Ps, setShapeTextColumns as Pt, replaceTextInSlideNotes as Q, getTableCellAlignment as Qa, setSlideSize as Qi, getShapePosition as Qn, getSlideLayoutPlaceholders as Qo, getShapeHyperlinkTooltip as Qr, findCommentsBefore as Qs, getShapeFillOpacity as Qt, getSlideIndex as R, getMediaParts as Ra, getShapeImageLinkUrl as Ri, getMaxShapeIdInPresentation as Rn, getCoreProperties as Ro, setShapeStrokeDash as Rr, getSlideMasterBackgroundGradientFill as Rs, setShapeTextWrap as Rt, getSlideSections as S, getSlidesWithComments as Sa, cm as Sc, setShapeAnimation as Si, getShapeIndex as Sn, setTableCellAlignment as So, getShapeStrokeDash as Sr, setChartSpec as Ss, getShapeTextBodyRotationDeg as St, findSlideByText as T, getSlidesWithNotes as Ta, mm as Tc, findShapesOutsideCanvas as Ti, getShapesBounds as Tn, setTableCellFill as To, setShapeFlip as Tr, clearSlideBackground as Ts, getShapeTextMargins as Tt, getSlideText as U, listPackageParts as Ua, isShapeImageGrayscale as Ui, getShapeCenter as Un, setCoreProperties as Uo, getParagraphAlignment as Ur, setSlideBackgroundImage as Us, getShapeEffectsEffective as Ut, getSlideOutline as V, getPresentationSummary as Va, hasShapeImage as Vi, getShapeBounds as Vn, getPresentationModified as Vo, resolveDrawingColor as Vr, getSlideMasterShapes as Vs, getShapeEffect as Vt, getSlideTextLength as W, readPackagePart as Wa, setShapeImageBrightness as Wi, getShapeCustomGeometry as Wn, setExtendedProperties as Wo, getParagraphBullet as Wr, getShapeClickAction as Ws, setShapeGlow as Wt, replaceTextInPresentation as X, getSlideTables as Xa, SLIDE_SIZE_4_3 as Xi, getShapePlaceholderIdx as Xn, getSlideLayoutName as Xo, getParagraphLineSpacing as Xr, findCommentAuthorByName as Xs, getShapeFillColorResolved as Xt, replaceTextInNotes as Y, getPresentationTableCountsBySlide as Ya, SLIDE_SIZE_16_9 as Yi, getShapeName as Yn, findSlideLayoutByType as Yo, getParagraphLevel as Yr, clearSlideComments as Ys, getShapeFillColor as Yt, replaceTextInSlide as Z, getTableCell as Za, getSlideSize as Zi, getShapePlaceholderType as Zn, getSlideLayoutPartName as Zo, getParagraphSpacing as Zr, findCommentsAfter as Zs, getShapeFillEffective as Zt, moveSlide as _, getPresentationNotesLengthsBySlide as _a, setPresentationFonts as _c, setSlidePlaceholders as _i, findShapesByText as _n, isChartShape as _o, shapesOverlap as _r, getShapeChartKind as _s, appendShapeText as _t, groupShapes as a, findSlidesWithChartTrendlines as aa, getCommentPosition as ac, getShapeRunText as ai, getShapeStrokeJoin as an, getTableCellSpan as ao, getSlideMasterPartNames as ar, getShapeHyperlink as as, addSlideShape as at, sortSlides as b, getSlideNotesLength as ba, loadPresentation as bc, findShapesWithAnimation as bi, findSlidePlaceholderByIdx as bn, removeTableColumn as bo, getShapePatternFill as br, getShapeChartSpec as bs, getShapeTextAutoFit as bt, addContentSlide as c, getAllHyperlinks as ca, getCommentsSortedByDate as cc, setParagraphBullet as ci, findEmptyPlaceholders as cn, getTableCells as co, isShapeHidden as cr, setShapeRunFormat as cs, bringShapeForward as ct, addSlideAt as d, getAllTables as da, getPresentationCommenters as dc, setParagraphSpacing as di, findShapeByText as dn, getTableRowHeights as do, pointInShape as dr, findChartsBySeriesName as ds, copyShape as dt, clearAllHyperlinks as ea, findCommentsByText as ec, getShapeParagraphElements as ei, getShapeStrokeCap as en, getTableCellBorders as eo, getShapeRotation as er, getSlideLayoutUsageCounts as es, searchSlides as et, addTitleSlide as f, getDistinctHyperlinkUrls as fa, getSlideCommentAuthors as fc, setShapeRunHyperlink as fi, findShapeInPresentation as fn, getTableSize as fo, renameShape as fr, findChartsWithDataLabels as fs, getShapeZIndex as ft, mergePresentations as g, getPresentationNotesLength as ga, getPresentationTheme as gc, setSlideBody as gi, findShapesByPreset as gn, insertTableRow as go, setShapeHidden as gr, getShapeChartCategories as gs, setShapeZIndex as gt, importSlide as h, getPresentationHyperlinkCountsBySlide as ha, getPresentationFonts as hc, getSlideTitle as hi, findShapesByName as hn, insertTableColumn as ho, setShapeDescription as hr, getPresentationChartKindCounts as hs, sendShapeToBack as ht, getShapeMedia as i, findSlidesWithChartKind as ia, getCommentDate as ic, getShapeRunHyperlinkTooltip as ii, getShapeStrokeEffective as in, getTableCellPosition as io, getSlideMasterPartName as ir, getParagraphPropertiesEffective as is, addSlideLine as it, getPresentationShapeCountsBySlide as j, replaceHyperlink as ja, getShapeImageBrightness as ji, translateShapes as jn, setTableColumnWidth as jo, setShapePosition as jr, getSlideLayoutBackground as js, setShapeTextAnchor as jt, getAllShapes as k, hasSlideNotes as ka, getPresentationImageCountsBySlide as ki, replaceTokensInSlide as kn, setTableCellTextDirection as ko, setShapeNoStroke as kr, getSlideBackgroundPatternFill as ks, setShapeParagraphs as kt, addSectionHeaderSlide as l, getAllImages as la, getPresentationCommentCountsByAuthor as lc, setParagraphLevel as li, findShapeById as ln, getTableColumnWidths as lo, isShapePlaceholder as lr, addSlideChart as ls, bringShapeToFront as lt, duplicateSlideAt as m, getHiddenSlides as ma, removeSlideComment as mc, getSlideBody as mi, findShapesByKind as mn, getTableStyleId as mo, setShapeBounds as mr, getPresentationChartCountsBySlide as ms, sendShapeBackward as mt, addSlideMedia as n, clearSlideHyperlinks as na, getCommentAuthor as nc, getShapeRunCount as ni, getShapeStrokeColorResolved as nn, getTableCellMargins as no, getShapeText as nr, getSlideLayouts as ns, slideHasAnimations as nt, ungroupShapes as o, getAllCharts as oa, getCommentSlide as oc, isParagraphBulletPicture as oi, getShapeStrokeOpacity as on, getTableCellText as oo, getSlideMasterUsageCounts as or, getShapeRunFormatEffective as os, addSlideTable as ot, duplicateSlide as p, getEmptySlides as pa, getSlideComments as pc, setShapeRunText as pi, findShapesByHyperlink as pn, getTableStyleFlags as po, setShapeAltTitle as pr, findChartsWithTrendlines as ps, removeShape as pt, getSlidesByLayout as q, validatePresentation as qa, setShapeImageOpacity as qi, getShapeId as qn, findSlideLayout as qo, getParagraphEndFormat as qr, addSlideComment as qs, getShapeGradientFillEffective as qt, findShapesWithMedia as r, findSlidesByHyperlink as ra, getCommentAuthors as rc, getShapeRunHyperlink as ri, getShapeStrokeCompound as rn, getTableCellParagraphs as ro, getSlideMasterCount as rr, getUnusedSlideLayouts as rs, addSlideImage as rt, addBlankSlide as s, getAllComments as sa, getCommentText as sc, setParagraphAlignment as si, getShapeStrokeWidth as sn, getTableCellTextDirection as so, getUnusedSlideMasters as sr, setShapeHyperlink as ss, addSlideTextBox as st, VERSION as t, clearAllSlideNotes as ta, findSlidesWithCommentsByAuthor as tc, getShapeRunClickAction as ti, getShapeStrokeColor as tn, getTableCellFill as to, getShapeSize as tr, getSlideLayoutUsageCountsByType as ts, setSlideHidden as tt, addSlide as u, getAllNotes as ua, getPresentationCommentCountsBySlide as uc, setParagraphLineSpacing as ui, findShapeByName as un, getTableDimensions as uo, isShapeTextBox as ur, findChartByKind as us, clearSlideShapes as ut, removeSlide as v, getPresentationNotesText as va, setPresentationTheme as vc, setSlideTitle as vi, findShapesWithHyperlinks as vn, isTableShape as vo, clearShapeFill as vr, getShapeChartSeriesNames as vs, getShapeBodyPrEffective as vt, findSlideByPartName as w, getSlidesWithImages as wa, inches as wc, findOverlappingShapePairs as wi, getShapeXmlString as wn, setTableCellBorders as wo, setShapeFill as wr, resolveDeckBodyTextColor as ws, getShapeTextDirection as wt, swapSlides as x, getSlidesWithCharts as xa, savePresentation as xc, getShapeAnimation as xi, findSlidePlaceholders as xn, removeTableRow as xo, getShapeStrokeArrow as xr, getSlideCharts as xs, getShapeTextAutoFitParams as xt, reverseSlides as y, getSlideNotes as ya, createPresentation as yc, clearSlideAnimations as yi, findSlidePlaceholder as yn, mergeTableCells as yo, clearShapeStroke as yr, getShapeChartSeriesValues as ys, getShapeTextAnchor as yt, getSlideInfo as z, getOrphanMediaPartNames as za, getShapeImageOpacity as zi, getShapeAdjustValues as zn, getExtendedProperties as zo, setShapeStrokeJoin as zr, getSlideMasterBackgroundImageBytes as zs, clearShapeEffects as zt };
17443
19478
 
17444
- //# sourceMappingURL=api-Dt6q_IAv.js.map
19479
+ //# sourceMappingURL=api-0CdoUwvg.js.map