@office-open/core 0.11.0 → 0.12.1

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.
Files changed (85) hide show
  1. package/dist/chart/index.d.mts +2 -2
  2. package/dist/chart/index.mjs +2 -2
  3. package/dist/{chart-Kf_utasF.mjs → chart-BAnjzVoe.mjs} +861 -287
  4. package/dist/chart-BAnjzVoe.mjs.map +1 -0
  5. package/dist/data-type-CZMKVaaT.d.mts.map +1 -1
  6. package/dist/descriptor/index.d.mts +1 -1
  7. package/dist/descriptor/index.mjs +1 -1
  8. package/dist/{descriptor-BX8xW8na.mjs → descriptor-BqaNZrrZ.mjs} +38 -10
  9. package/dist/{descriptor-BX8xW8na.mjs.map → descriptor-BqaNZrrZ.mjs.map} +1 -1
  10. package/dist/drawing/index.d.mts +2 -2
  11. package/dist/drawing/index.mjs +2 -2
  12. package/dist/{drawing-FBzd2I0m.mjs → drawing-BVwCkNXB.mjs} +3062 -3131
  13. package/dist/drawing-BVwCkNXB.mjs.map +1 -0
  14. package/dist/{generators-CElPsAhd.mjs → ext-uri-BHBcIrW7.mjs} +599 -343
  15. package/dist/ext-uri-BHBcIrW7.mjs.map +1 -0
  16. package/dist/index-BAxlDUQ1.d.mts +590 -0
  17. package/dist/index-BAxlDUQ1.d.mts.map +1 -0
  18. package/dist/{index-CLX7gU9J.d.mts → index-BQLIofaF.d.mts} +3 -2
  19. package/dist/index-BQLIofaF.d.mts.map +1 -0
  20. package/dist/{index-k8WKLXnA.d.mts → index-CaNwM5_e.d.mts} +19 -20
  21. package/dist/index-CaNwM5_e.d.mts.map +1 -0
  22. package/dist/{index-CnjCK-lF.d.mts → index-DPkf_CtG.d.mts} +566 -597
  23. package/dist/index-DPkf_CtG.d.mts.map +1 -0
  24. package/dist/{index-BsTUn4K1.d.mts → index-DcukVskh.d.mts} +9 -6
  25. package/dist/index-DcukVskh.d.mts.map +1 -0
  26. package/dist/{index-Cgz88FU0.d.mts → index-Di6XPdGl.d.mts} +26 -12
  27. package/dist/index-Di6XPdGl.d.mts.map +1 -0
  28. package/dist/{index-C0ClOhmZ.d.mts → index-L6AXewfV.d.mts} +11 -8
  29. package/dist/index-L6AXewfV.d.mts.map +1 -0
  30. package/dist/{index-DxwLMnBF.d.mts → index-k1h_t946.d.mts} +219 -99
  31. package/dist/index-k1h_t946.d.mts.map +1 -0
  32. package/dist/index.d.mts +161 -29
  33. package/dist/index.d.mts.map +1 -1
  34. package/dist/index.mjs +873 -87
  35. package/dist/index.mjs.map +1 -1
  36. package/dist/{output-D_G_JR_8.d.mts → output-yyxdkG0C.d.mts} +2 -3
  37. package/dist/output-yyxdkG0C.d.mts.map +1 -0
  38. package/dist/patch/index.d.mts +2 -2
  39. package/dist/patch/index.mjs +2 -2
  40. package/dist/{patch-3KLx2yEP.mjs → patch-AkQY17CD.mjs} +71 -26
  41. package/dist/patch-AkQY17CD.mjs.map +1 -0
  42. package/dist/smartart/index.d.mts +2 -2
  43. package/dist/smartart/index.mjs +1 -1
  44. package/dist/{smartart-BxnkROOp.mjs → smartart-DV6ZcN5R.mjs} +27 -26
  45. package/dist/smartart-DV6ZcN5R.mjs.map +1 -0
  46. package/dist/{style-matrix-DAP6XrLv.mjs → style-matrix-DjhMuuQg.mjs} +4 -4
  47. package/dist/style-matrix-DjhMuuQg.mjs.map +1 -0
  48. package/dist/theme/index.d.mts +4 -4
  49. package/dist/theme/index.mjs +3 -2
  50. package/dist/{theme-OAuRcA9_.mjs → theme-Dx0Db9bX.mjs} +37 -71
  51. package/dist/theme-Dx0Db9bX.mjs.map +1 -0
  52. package/dist/{theme-options-BbWccl85.d.mts → theme-options-kO89NUEX.d.mts} +17 -17
  53. package/dist/theme-options-kO89NUEX.d.mts.map +1 -0
  54. package/dist/util/index.d.mts +3 -3
  55. package/dist/util/index.mjs +3 -3
  56. package/dist/{util-C94-JKtp.mjs → util-ptE16MEk.mjs} +69 -37
  57. package/dist/util-ptE16MEk.mjs.map +1 -0
  58. package/dist/{values-aVoirbWB.d.mts → values-BECDm4zr.d.mts} +15 -31
  59. package/dist/values-BECDm4zr.d.mts.map +1 -0
  60. package/dist/vector/index.d.mts +2 -2
  61. package/dist/vector/index.mjs +2 -2
  62. package/dist/{vector-TpjW6ZSc.mjs → vector-DhLGZjP5.mjs} +104 -147
  63. package/dist/vector-DhLGZjP5.mjs.map +1 -0
  64. package/package.json +3 -3
  65. package/dist/chart-Kf_utasF.mjs.map +0 -1
  66. package/dist/drawing-FBzd2I0m.mjs.map +0 -1
  67. package/dist/generators-CElPsAhd.mjs.map +0 -1
  68. package/dist/index-BsTUn4K1.d.mts.map +0 -1
  69. package/dist/index-C0ClOhmZ.d.mts.map +0 -1
  70. package/dist/index-CLX7gU9J.d.mts.map +0 -1
  71. package/dist/index-Cgz88FU0.d.mts.map +0 -1
  72. package/dist/index-CnjCK-lF.d.mts.map +0 -1
  73. package/dist/index-DpPeyf5f.d.mts +0 -316
  74. package/dist/index-DpPeyf5f.d.mts.map +0 -1
  75. package/dist/index-DxwLMnBF.d.mts.map +0 -1
  76. package/dist/index-k8WKLXnA.d.mts.map +0 -1
  77. package/dist/output-D_G_JR_8.d.mts.map +0 -1
  78. package/dist/patch-3KLx2yEP.mjs.map +0 -1
  79. package/dist/smartart-BxnkROOp.mjs.map +0 -1
  80. package/dist/style-matrix-DAP6XrLv.mjs.map +0 -1
  81. package/dist/theme-OAuRcA9_.mjs.map +0 -1
  82. package/dist/theme-options-BbWccl85.d.mts.map +0 -1
  83. package/dist/util-C94-JKtp.mjs.map +0 -1
  84. package/dist/values-aVoirbWB.d.mts.map +0 -1
  85. package/dist/vector-TpjW6ZSc.mjs.map +0 -1
@@ -170,7 +170,8 @@ const positiveUniversalMeasureValue = (val) => {
170
170
  */
171
171
  const hexColorValue = (val) => {
172
172
  if (val === "auto") return val;
173
- return hexBinary(stripColorHashPrefix(val), 3);
173
+ const color = stripColorHashPrefix(val);
174
+ return hexBinary(color, 3);
174
175
  };
175
176
  /**
176
177
  * Strips the leading "#" prefix from a color string if present.
@@ -212,8 +213,8 @@ const parseOnOff = (raw) => {
212
213
  if (raw === void 0) return void 0;
213
214
  if (typeof raw === "boolean") return raw;
214
215
  const s = String(raw).toLowerCase();
215
- if (s === "1" || s === "true" || s === "on") return true;
216
- if (s === "0" || s === "false" || s === "off") return false;
216
+ if (s === "1" || s === "true" || s === "on" || s === "t") return true;
217
+ if (s === "0" || s === "false" || s === "off" || s === "f") return false;
217
218
  };
218
219
  /**
219
220
  * Validates a signed TWIP measurement value.
@@ -369,49 +370,6 @@ const pointMeasureValue = unsignedDecimalNumber;
369
370
  * ```
370
371
  */
371
372
  const dateTimeValue = (val) => val.toISOString();
372
- /**
373
- * Theme color values used throughout OOXML for referencing document theme colors.
374
- *
375
- * Reference: ST_ThemeColor in OOXML specification
376
- *
377
- * @publicApi
378
- */
379
- const ThemeColor = {
380
- DARK1: "dark1",
381
- LIGHT1: "light1",
382
- DARK2: "dark2",
383
- LIGHT2: "light2",
384
- ACCENT1: "accent1",
385
- ACCENT2: "accent2",
386
- ACCENT3: "accent3",
387
- ACCENT4: "accent4",
388
- ACCENT5: "accent5",
389
- ACCENT6: "accent6",
390
- HYPERLINK: "hyperlink",
391
- FOLLOWED_HYPERLINK: "followedHyperlink",
392
- NONE: "none",
393
- BACKGROUND1: "background1",
394
- TEXT1: "text1",
395
- BACKGROUND2: "background2",
396
- TEXT2: "text2"
397
- };
398
- /**
399
- * Theme font values used for referencing document theme fonts.
400
- *
401
- * Reference: ST_Theme in OOXML specification
402
- *
403
- * @publicApi
404
- */
405
- const ThemeFont = {
406
- MAJOR_EAST_ASIA: "majorEastAsia",
407
- MAJOR_BIDI: "majorBidi",
408
- MAJOR_ASCII: "majorAscii",
409
- MAJOR_H_ANSI: "majorHAnsi",
410
- MINOR_EAST_ASIA: "minorEastAsia",
411
- MINOR_BIDI: "minorBidi",
412
- MINOR_ASCII: "minorAscii",
413
- MINOR_H_ANSI: "minorHAnsi"
414
- };
415
373
  //#endregion
416
374
  //#region \0polyfill-node.global.js
417
375
  var _polyfill_node_global_default = typeof _polyfill_node_global_default !== "undefined" ? _polyfill_node_global_default : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};
@@ -936,18 +894,23 @@ function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
936
894
  byteOffset = +byteOffset;
937
895
  if (isNaN(byteOffset)) byteOffset = dir ? 0 : buffer.length - 1;
938
896
  if (byteOffset < 0) byteOffset = buffer.length + byteOffset;
939
- if (byteOffset >= buffer.length) if (dir) return -1;
940
- else byteOffset = buffer.length - 1;
941
- else if (byteOffset < 0) if (dir) byteOffset = 0;
942
- else return -1;
897
+ if (byteOffset >= buffer.length) {
898
+ if (dir) return -1;
899
+ else byteOffset = buffer.length - 1;
900
+ } else if (byteOffset < 0) {
901
+ if (dir) byteOffset = 0;
902
+ else return -1;
903
+ }
943
904
  if (typeof val === "string") val = Buffer.from(val, encoding);
944
905
  if (internalIsBuffer(val)) {
945
906
  if (val.length === 0) return -1;
946
907
  return arrayIndexOf(buffer, val, byteOffset, encoding, dir);
947
908
  } else if (typeof val === "number") {
948
909
  val = val & 255;
949
- if (Buffer.TYPED_ARRAY_SUPPORT && typeof Uint8Array.prototype.indexOf === "function") if (dir) return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset);
950
- else return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset);
910
+ if (Buffer.TYPED_ARRAY_SUPPORT && typeof Uint8Array.prototype.indexOf === "function") {
911
+ if (dir) return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset);
912
+ else return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset);
913
+ }
951
914
  return arrayIndexOf(buffer, [val], byteOffset, encoding, dir);
952
915
  }
953
916
  throw new TypeError("val must be string, number or Buffer");
@@ -1707,275 +1670,67 @@ function encodeBase64(bytes) {
1707
1670
  return btoa(binary);
1708
1671
  }
1709
1672
  //#endregion
1710
- //#region src/util/converters.ts
1673
+ //#region src/util/data-type.ts
1711
1674
  /**
1712
- * Apply `fn` to `value` unless it is `undefined`; `undefined` passes through.
1675
+ * Binary input normalization.
1713
1676
  *
1714
- * Lets an optional field (e.g. `radius?: number | UniversalMeasure`) be threaded
1715
- * through a conversion without a per-call ternary.
1716
- */
1717
- const mapOptional = (value, fn) => value === void 0 ? void 0 : fn(value);
1718
- /**
1719
- * Convert public percent (100 = 100%) to OOXML ST_Percentage scalar (1/1000).
1720
- * Math.round ensures JSON-first float input produces exact integer output.
1721
- */
1722
- const emitPercent = (percent) => Math.round(percent * 1e3);
1723
- /**
1724
- * Convert OOXML ST_Percentage scalar (1/1000) to public percent.
1725
- */
1726
- const parsePercent = (value) => value / 1e3;
1727
- /**
1728
- * Convert public degrees to OOXML ST_Angle / ST_FixedAngle scalar (1/60000).
1729
- * Math.round ensures JSON-first float input produces exact integer output.
1730
- */
1731
- const emitAngle = (degrees) => Math.round(degrees * 6e4);
1732
- /**
1733
- * Convert OOXML ST_Angle / ST_FixedAngle scalar (1/60000) to public degrees.
1734
- */
1735
- const parseAngle = (value) => value / 6e4;
1736
- /**
1737
- * Converts millimeters to TWIP (twentieths of a point).
1738
- */
1739
- const convertMillimetersToTwip = (millimeters) => Math.floor(millimeters / 25.4 * 72 * 20);
1740
- /**
1741
- * Converts inches to TWIP (twentieths of a point).
1742
- */
1743
- const convertInchesToTwip = (inches) => Math.floor(inches * 72 * 20);
1744
- /**
1745
- * Converts pixels to EMU (96 DPI).
1746
- */
1747
- const convertPixelsToEmu = (pixels) => Math.round(pixels * 9525);
1748
- /**
1749
- * Converts EMU to pixels (96 DPI).
1677
+ * Accepts the full range of binary inputs (Buffer/Uint8Array/ArrayBuffer/
1678
+ * DataView/number[]/string/base64 data URL/…) and normalizes to `Uint8Array`.
1679
+ * Centralized here so every entry point (packer, patch, descriptor helpers)
1680
+ * shares one definition instead of re-declaring per module.
1750
1681
  *
1751
- * Returns a possibly fractional (sub-pixel) value. The integer rounding that
1752
- * lived here before permanently discarded sub-pixel precision, which made an
1753
- * EMU → pixel → EMU round-trip lossy (e.g. 5521960 EMU → 580 px → 5524500 EMU).
1754
- * Keeping the fraction lets convertPixelsToEmu restore the exact original EMU.
1755
- * Callers needing an integer pixel for display should Math.round the result.
1756
- */
1757
- const convertEmuToPixels = (emus) => emus / 9525;
1758
- /**
1759
- * Converts inches to EMU.
1760
- */
1761
- const convertInchesToEmu = (inches) => Math.round(inches * 914400);
1762
- /**
1763
- * Converts EMU to inches.
1764
- */
1765
- const convertEmuToInches = (emus) => emus / 914400;
1766
- /**
1767
- * Converts points to EMU.
1768
- */
1769
- const convertPointsToEmu = (points) => Math.round(points * 12700);
1770
- /**
1771
- * Converts EMU to points.
1682
+ * @module
1772
1683
  */
1773
- const convertEmuToPoints = (emus) => emus / 12700;
1774
- /** Converts EMU to TWIP (1 TWIP = 635 EMU). */
1775
- const convertEmuToTwip = (emus) => Math.round(emus / 635);
1776
- /** Converts TWIP to EMU (1 TWIP = 635 EMU). */
1777
- const convertTwipToEmu = (twips) => twips * 635;
1778
- /** Converts points to TWIP (1 point = 20 TWIP). */
1779
- const convertPointsToTwip = (points) => Math.round(points * 20);
1780
- /** Converts TWIP to points (1 point = 20 TWIP). */
1781
- const convertTwipToPoints = (twips) => twips / 20;
1684
+ const DATA_URL_RE = /^data:([\w.+-]+\/[\w.+-]+)?;base64,/;
1685
+ /** Test whether a string is a base64 data URL (`data:[mime];base64,...`). */
1686
+ function isBase64DataURL(input) {
1687
+ return DATA_URL_RE.test(input);
1688
+ }
1689
+ /** Normalize any supported binary input to a `Uint8Array`. */
1690
+ function toUint8Array(data, options) {
1691
+ if (data instanceof Uint8Array) return data;
1692
+ if (data instanceof ArrayBuffer) return new Uint8Array(data);
1693
+ if (data instanceof DataView) return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
1694
+ if (typeof data === "string") {
1695
+ const match = data.match(DATA_URL_RE);
1696
+ if (match) return decodeBase64(data.slice(match[0].length));
1697
+ if (options?.encoding === "base64") return decodeBase64(data);
1698
+ return new TextEncoder().encode(data);
1699
+ }
1700
+ if (Array.isArray(data)) return new Uint8Array(data);
1701
+ if (data instanceof Blob) throw new TypeError("Blob input requires async processing");
1702
+ if (data instanceof ReadableStream) throw new TypeError("ReadableStream input requires async processing");
1703
+ throw new TypeError(`Unsupported data type: ${typeof data}`);
1704
+ }
1705
+ //#endregion
1706
+ //#region src/util/mappings.ts
1782
1707
  /**
1783
- * Parse a UniversalMeasure string into its numeric value and unit.
1708
+ * Bidirectional mappings between user-friendly values and XSD abbreviated values.
1784
1709
  *
1785
- * @param measure - A universal measure string like "2.54cm", "-10mm", "1in"
1786
- * @returns The parsed value and unit
1787
- * @throws Error if the format is invalid
1710
+ * When XSD uses full English words (e.g. "center", "start"), values are used directly — no mapping needed.
1711
+ * When XSD uses abbreviations (e.g. "ctr", "l", "rnd"), this module maps them to full words.
1788
1712
  *
1789
- * @example
1790
- * ```typescript
1791
- * parseUniversalMeasure("2.54cm"); // { value: 2.54, unit: "cm" }
1792
- * parseUniversalMeasure("-10mm"); // { value: -10, unit: "mm" }
1793
- * ```
1713
+ * Usage in generation (Options → XML): xsdAlign.to("center") → "ctr"
1714
+ * Usage in parsing (XML → Options): xsdAlign.from("ctr") → "center"
1794
1715
  */
1795
- const parseUniversalMeasure = (measure) => {
1796
- const match = measure.match(/^(-?[0-9]+(?:\.[0-9]+)?)(mm|cm|in|pt|pc|pi|px)$/);
1797
- if (!match) throw new Error(`Invalid universal measure: '${measure}'`);
1798
- const [, value, unit] = match;
1799
- if (value === void 0 || unit === void 0) throw new Error(`Invalid universal measure: '${measure}'`);
1716
+ /** Invert a Record<K, V> into Record<V, K>. */
1717
+ function invertMap(map) {
1718
+ const result = {};
1719
+ for (const key of Object.keys(map)) result[map[key]] = key;
1720
+ return result;
1721
+ }
1722
+ /** Create a bidirectional mapping helper from a single forward map. */
1723
+ function bidi(forward) {
1724
+ const reverse = invertMap(forward);
1800
1725
  return {
1801
- value: parseFloat(value),
1802
- unit
1803
- };
1804
- };
1805
- /**
1806
- * Converts a UniversalMeasure string to TWIP (twentieths of a point).
1807
- *
1808
- * Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc).
1809
- *
1810
- * @param measure - A universal measure string like "2.54cm", "1in", "12pt"
1811
- * @returns The value in TWIP
1812
- *
1813
- * @example
1814
- * ```typescript
1815
- * convertUniversalMeasureToTwip("1in"); // 1440
1816
- * convertUniversalMeasureToTwip("2.54cm"); // ~1440 (1 inch)
1817
- * convertUniversalMeasureToTwip("72pt"); // 1440 (1 inch = 72pt = 1440 twips)
1818
- * ```
1819
- */
1820
- const convertUniversalMeasureToTwip = (measure) => {
1821
- const { value, unit } = parseUniversalMeasure(measure);
1822
- switch (unit) {
1823
- case "mm": return convertMillimetersToTwip(value);
1824
- case "cm": return convertMillimetersToTwip(value * 10);
1825
- case "in": return convertInchesToTwip(value);
1826
- case "pt": return Math.floor(value * 20);
1827
- case "pc":
1828
- case "pi": return Math.floor(value * 12 * 20);
1829
- case "px": return Math.round(value * 15);
1830
- }
1831
- };
1832
- /**
1833
- * Converts a measurement value (number or UniversalMeasure) to TWIP.
1834
- *
1835
- * If the value is already a number, it is returned as-is (assumed to be in twips).
1836
- * If the value is a UniversalMeasure string, it is converted to twips.
1837
- *
1838
- * Useful for accepting both `number` and `UniversalMeasure` inputs where
1839
- * the XSD type is a union (e.g., ST_TwipsMeasure, ST_SignedTwipsMeasure).
1840
- *
1841
- * @param val - A numeric twip value or a universal measure string
1842
- * @returns The value in TWIP
1843
- *
1844
- * @example
1845
- * ```typescript
1846
- * convertToTwip(1440); // 1440 (already twips)
1847
- * convertToTwip("1in"); // 1440
1848
- * convertToTwip("2.54cm"); // ~1440
1849
- * ```
1850
- */
1851
- const convertToTwip = (val) => typeof val === "string" ? convertUniversalMeasureToTwip(val) : val;
1852
- /**
1853
- * Converts a UniversalMeasure string to EMU (English Metric Units).
1854
- *
1855
- * Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc).
1856
- *
1857
- * @param measure - A universal measure string like "2.54cm", "1in", "12pt"
1858
- * @returns The value in EMU
1859
- *
1860
- * @example
1861
- * ```typescript
1862
- * convertUniversalMeasureToEmu("1in"); // 914400
1863
- * convertUniversalMeasureToEmu("2.54cm"); // 914400
1864
- * convertUniversalMeasureToEmu("12pt"); // 152400
1865
- * ```
1866
- */
1867
- const convertUniversalMeasureToEmu = (measure) => {
1868
- const { value, unit } = parseUniversalMeasure(measure);
1869
- switch (unit) {
1870
- case "mm": return Math.round(value * 36e3);
1871
- case "cm": return Math.round(value * 36e4);
1872
- case "in": return convertInchesToEmu(value);
1873
- case "pt": return convertPointsToEmu(value);
1874
- case "pc":
1875
- case "pi": return convertPointsToEmu(value * 12);
1876
- case "px": return convertPixelsToEmu(value);
1877
- }
1878
- };
1879
- /**
1880
- * Converts a measurement value (number or UniversalMeasure) to EMU.
1881
- *
1882
- * Numbers are returned as-is (assumed EMU). Strings are parsed as
1883
- * UniversalMeasure via {@link convertUniversalMeasureToEmu} — including the
1884
- * project-only `px` unit (96 DPI). The result is always an EMU number written to
1885
- * XML, so px never appears verbatim in the document.
1886
- *
1887
- * Useful for DrawingML fields where the XSD type is a union (e.g., ST_Coordinate).
1888
- *
1889
- * @param val - A numeric EMU value, or a UniversalMeasure string (incl. `${n}px`)
1890
- * @returns The value in EMU
1891
- *
1892
- * @example
1893
- * ```typescript
1894
- * convertToEmu(914400); // 914400 (already EMU)
1895
- * convertToEmu("1in"); // 914400
1896
- * convertToEmu("2.54cm"); // 914400
1897
- * convertToEmu("200px"); // 1905000 (200 * 9525)
1898
- * ```
1899
- */
1900
- const convertToEmu = (val) => typeof val === "string" ? convertUniversalMeasureToEmu(val) : val;
1901
- /**
1902
- * Converts a UniversalMeasure string to points (1pt = 1/72 inch).
1903
- *
1904
- * Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc),
1905
- * px (96 DPI).
1906
- */
1907
- const convertUniversalMeasureToPt = (measure) => {
1908
- const { value, unit } = parseUniversalMeasure(measure);
1909
- switch (unit) {
1910
- case "mm": return value / 25.4 * 72;
1911
- case "cm": return value * 10 / 25.4 * 72;
1912
- case "in": return value * 72;
1913
- case "pt": return value;
1914
- case "pc":
1915
- case "pi": return value * 12;
1916
- case "px": return value / 96 * 72;
1917
- }
1918
- };
1919
- /**
1920
- * Converts a measurement value (number or UniversalMeasure) to points.
1921
- *
1922
- * Numbers are returned as-is (assumed to be in points). Strings are parsed as
1923
- * UniversalMeasure. Useful for SpreadsheetML fields where a number is points.
1924
- */
1925
- const convertToPt = (val) => typeof val === "string" ? convertUniversalMeasureToPt(val) : val;
1926
- /**
1927
- * Converts a UniversalMeasure string to inches.
1928
- *
1929
- * Supports units: mm, cm, in, pt, pc, pi, px (96 DPI).
1930
- */
1931
- const convertUniversalMeasureToInch = (measure) => {
1932
- const { value, unit } = parseUniversalMeasure(measure);
1933
- switch (unit) {
1934
- case "mm": return value / 25.4;
1935
- case "cm": return value * 10 / 25.4;
1936
- case "in": return value;
1937
- case "pt": return value / 72;
1938
- case "pc":
1939
- case "pi": return value * 12 / 72;
1940
- case "px": return value / 96;
1941
- }
1942
- };
1943
- /**
1944
- * Converts a measurement value (number or UniversalMeasure) to inches.
1945
- *
1946
- * Numbers are returned as-is (assumed to be in inches). Useful for SpreadsheetML
1947
- * page-margin fields where a number is inches.
1948
- */
1949
- const convertToInch = (val) => typeof val === "string" ? convertUniversalMeasureToInch(val) : val;
1950
- //#endregion
1951
- //#region src/util/mappings.ts
1952
- /**
1953
- * Bidirectional mappings between user-friendly values and XSD abbreviated values.
1954
- *
1955
- * When XSD uses full English words (e.g. "center", "start"), values are used directly — no mapping needed.
1956
- * When XSD uses abbreviations (e.g. "ctr", "l", "rnd"), this module maps them to full words.
1957
- *
1958
- * Usage in generation (Options → XML): xsdAlign.to("center") → "ctr"
1959
- * Usage in parsing (XML → Options): xsdAlign.from("ctr") → "center"
1960
- */
1961
- /** Invert a Record<K, V> into Record<V, K>. */
1962
- function invertMap(map) {
1963
- const result = {};
1964
- for (const key of Object.keys(map)) result[map[key]] = key;
1965
- return result;
1966
- }
1967
- /** Create a bidirectional mapping helper from a single forward map. */
1968
- function bidi(forward) {
1969
- const reverse = invertMap(forward);
1970
- return {
1971
- /** User-friendly value → XSD value */
1972
- to: (key) => forward[key] ?? key,
1973
- /** XSD value → user-friendly value */
1974
- from: (xsd) => reverse[xsd] ?? xsd,
1975
- /** The forward map (user → XSD) */
1976
- forward,
1977
- /** The reverse map (XSD → user) */
1978
- reverse
1726
+ /** User-friendly value → XSD value */
1727
+ to: (key) => forward[key] ?? key,
1728
+ /** XSD value → user-friendly value */
1729
+ from: (xsd) => reverse[xsd] ?? xsd,
1730
+ /** The forward map (user → XSD) */
1731
+ forward,
1732
+ /** The reverse map (XSD → user) */
1733
+ reverse
1979
1734
  };
1980
1735
  }
1981
1736
  const xsdRectAlignment = bidi({
@@ -2064,6 +1819,16 @@ const xsdPresetShadow = bidi({
2064
1819
  shadow19: "shdw19",
2065
1820
  shadow20: "shdw20"
2066
1821
  });
1822
+ const xsdLightRigDirection = bidi({
1823
+ topLeft: "tl",
1824
+ top: "t",
1825
+ topRight: "tr",
1826
+ left: "l",
1827
+ right: "r",
1828
+ bottomLeft: "bl",
1829
+ bottom: "b",
1830
+ bottomRight: "br"
1831
+ });
2067
1832
  const xsdMaterialType = bidi({
2068
1833
  legacyMatte: "legacyMatte",
2069
1834
  legacyPlastic: "legacyPlastic",
@@ -2156,39 +1921,493 @@ const xsdTextCaps = bidi({
2156
1921
  all: "all",
2157
1922
  small: "small"
2158
1923
  });
1924
+ const xsdAxisPosition = bidi({
1925
+ bottom: "b",
1926
+ left: "l",
1927
+ right: "r",
1928
+ top: "t"
1929
+ });
1930
+ const xsdLegendPosition = bidi({
1931
+ bottom: "b",
1932
+ topRight: "tr",
1933
+ left: "l",
1934
+ right: "r",
1935
+ top: "t"
1936
+ });
1937
+ const xsdDataLabelPosition = bidi({
1938
+ bottom: "b",
1939
+ center: "ctr",
1940
+ insideBase: "inBase",
1941
+ insideEnd: "inEnd",
1942
+ left: "l",
1943
+ outsideEnd: "outEnd",
1944
+ right: "r",
1945
+ top: "t"
1946
+ });
1947
+ const xsdAxisCrossBetween = bidi({ middleOfCategory: "midCat" });
1948
+ const xsdAxisCrosses = bidi({ zero: "autoZero" });
1949
+ const xsdComments = bidi({
1950
+ none: "commNone",
1951
+ indicator: "commIndicator",
1952
+ comment: "commIndAndComment"
1953
+ });
1954
+ const xsdErrorValueType = bidi({
1955
+ custom: "cust",
1956
+ fixedValue: "fixedVal",
1957
+ standardDeviation: "stdDev",
1958
+ standardError: "stdErr"
1959
+ });
1960
+ const xsdSizeRepresents = bidi({ width: "w" });
1961
+ const xsdSplitType = bidi({
1962
+ custom: "cust",
1963
+ position: "pos",
1964
+ value: "val"
1965
+ });
1966
+ const xsdAxisLabelAlignment = bidi({
1967
+ center: "ctr",
1968
+ left: "l",
1969
+ right: "r"
1970
+ });
1971
+ const xsdAxisOrientation = bidi({
1972
+ ascending: "minMax",
1973
+ descending: "maxMin"
1974
+ });
1975
+ const xsdTrendlineType = bidi({
1976
+ exponential: "exp",
1977
+ logarithmic: "log",
1978
+ movingAverage: "movingAvg",
1979
+ polynomial: "poly"
1980
+ });
1981
+ const xsdTextTabAlignment = bidi({
1982
+ left: "l",
1983
+ center: "ctr",
1984
+ right: "r",
1985
+ decimal: "dec"
1986
+ });
1987
+ const xsdFontAlignment = bidi({
1988
+ top: "t",
1989
+ center: "ctr",
1990
+ bottom: "b"
1991
+ });
1992
+ const xsdAnimLevel = bidi({
1993
+ level: "lvl",
1994
+ center: "ctr"
1995
+ });
1996
+ const xsdHierBranch = bidi({
1997
+ left: "l",
1998
+ right: "r",
1999
+ hanging: "hang",
2000
+ standard: "std",
2001
+ initial: "init"
2002
+ });
2003
+ const xsdHueDirection = bidi({
2004
+ clockwise: "cw",
2005
+ counterClockwise: "ccw"
2006
+ });
2007
+ const xsdDiagramDirection = bidi({
2008
+ normal: "norm",
2009
+ reversed: "rev"
2010
+ });
2011
+ const xsdResizeHandles = bidi({
2012
+ exact: "exact",
2013
+ relative: "rel"
2014
+ });
2015
+ const xsdOnOffStyle = bidi({ default: "def" });
2016
+ const xsdAnimClass = bidi({
2017
+ entrance: "entr",
2018
+ emphasis: "emph",
2019
+ mediaCall: "mediacall"
2020
+ });
2021
+ const xsdAnimCalcMode = bidi({
2022
+ linear: "lin",
2023
+ formula: "fmla"
2024
+ });
2025
+ const xsdAnimValueType = bidi({
2026
+ string: "str",
2027
+ number: "num",
2028
+ color: "clr"
2029
+ });
2030
+ const xsdTextBuild = bidi({
2031
+ paragraph: "p",
2032
+ custom: "cust"
2033
+ });
2034
+ const xsdDiagramBuild = bidi({
2035
+ clockwise: "cw",
2036
+ clockwiseIn: "cwIn",
2037
+ clockwiseOut: "cwOut",
2038
+ counterclockwise: "ccw",
2039
+ counterclockwiseIn: "ccwIn",
2040
+ counterclockwiseOut: "ccwOut",
2041
+ custom: "cust"
2042
+ });
2043
+ const xsdChartBuild = bidi({
2044
+ seriesElement: "seriesEl",
2045
+ categoryElement: "categoryEl"
2046
+ });
2047
+ const xsdAnimationDgmBuild = bidi({
2048
+ levelOne: "lvlOne",
2049
+ levelAtOnce: "lvlAtOnce"
2050
+ });
2051
+ const xsdIterateType = bidi({
2052
+ element: "el",
2053
+ word: "wd",
2054
+ letter: "lt"
2055
+ });
2056
+ const xsdSlideLayoutType = bidi({
2057
+ text: "tx",
2058
+ twoColumnText: "twoColTx",
2059
+ object: "obj",
2060
+ sectionHeader: "secHead",
2061
+ table: "tbl",
2062
+ clipArtAndText: "clipArtAndTx",
2063
+ pictureText: "picTx",
2064
+ twoObjects: "twoObj",
2065
+ twoTextAndTwoObjects: "twoTxTwoObj",
2066
+ objectAndText: "objTx",
2067
+ verticalText: "vertTx",
2068
+ verticalTitleAndText: "vertTitleAndTx"
2069
+ });
2070
+ const xsdTextVerticalType = bidi({
2071
+ horizontal: "horz",
2072
+ vertical: "vert",
2073
+ vertical270: "vert270",
2074
+ wordArtVertical: "wordArtVert",
2075
+ eastAsianVertical: "eaVert",
2076
+ mongolianVertical: "mongolianVert",
2077
+ wordArtVerticalRightToLeft: "wordArtVertRtl"
2078
+ });
2079
+ const xsdDashStyle = bidi({
2080
+ longDash: "lgDash",
2081
+ systemDot: "sysDot",
2082
+ systemDash: "sysDash"
2083
+ });
2084
+ const xsdOrient = bidi({
2085
+ horizontal: "horz",
2086
+ vertical: "vert"
2087
+ });
2088
+ const xsdPlaceholderType = bidi({
2089
+ centerTitle: "ctrTitle",
2090
+ date: "dt",
2091
+ slideNumber: "sldNum",
2092
+ footer: "ftr",
2093
+ header: "hdr",
2094
+ object: "obj",
2095
+ table: "tbl",
2096
+ diagram: "dgm",
2097
+ slideImage: "sldImg",
2098
+ picture: "pic"
2099
+ });
2100
+ const xsdMathStyle = bidi({
2101
+ plain: "p",
2102
+ bold: "b",
2103
+ italic: "i",
2104
+ boldItalic: "bi"
2105
+ });
2106
+ const xsdTableWidthType = bidi({
2107
+ twips: "dxa",
2108
+ percent: "pct"
2109
+ });
2110
+ const xsdJcAlignment = bidi({ numericTab: "numTab" });
2111
+ const xsdConsolidateFunction = bidi({
2112
+ countNumbers: "countNums",
2113
+ standardDeviation: "stdDev",
2114
+ standardDeviationPopulation: "stdDevp",
2115
+ variance: "var",
2116
+ variancePopulation: "varp"
2117
+ });
2118
+ const xsdShadingPattern = bidi({
2119
+ horizontalStripe: "horzStripe",
2120
+ verticalStripe: "vertStripe",
2121
+ reverseDiagonalStripe: "reverseDiagStripe",
2122
+ diagonalStripe: "diagStripe",
2123
+ horizontalCross: "horzCross",
2124
+ diagonalCross: "diagCross",
2125
+ thinHorizontalStripe: "thinHorzStripe",
2126
+ thinVerticalStripe: "thinVertStripe",
2127
+ thinReverseDiagonalStripe: "thinReverseDiagStripe",
2128
+ thinDiagonalStripe: "thinDiagStripe",
2129
+ thinHorizontalCross: "thinHorzCross",
2130
+ thinDiagonalCross: "thinDiagCross",
2131
+ percent5: "pct5",
2132
+ percent10: "pct10",
2133
+ percent12: "pct12",
2134
+ percent15: "pct15",
2135
+ percent20: "pct20",
2136
+ percent25: "pct25",
2137
+ percent30: "pct30",
2138
+ percent35: "pct35",
2139
+ percent37: "pct37",
2140
+ percent40: "pct40",
2141
+ percent45: "pct45",
2142
+ percent50: "pct50",
2143
+ percent55: "pct55",
2144
+ percent60: "pct60",
2145
+ percent62: "pct62",
2146
+ percent65: "pct65",
2147
+ percent70: "pct70",
2148
+ percent75: "pct75",
2149
+ percent80: "pct80",
2150
+ percent85: "pct85",
2151
+ percent87: "pct87",
2152
+ percent90: "pct90",
2153
+ percent95: "pct95"
2154
+ });
2155
+ const xsdTotalsRowFunction = bidi({
2156
+ countNumbers: "countNums",
2157
+ standardDeviation: "stdDev",
2158
+ variance: "var"
2159
+ });
2159
2160
  //#endregion
2160
- //#region src/util/data-type.ts
2161
+ //#region src/util/converters.ts
2161
2162
  /**
2162
- * Binary input normalization.
2163
+ * Apply `fn` to `value` unless it is `undefined`; `undefined` passes through.
2163
2164
  *
2164
- * Accepts the full range of binary inputs (Buffer/Uint8Array/ArrayBuffer/
2165
- * DataView/number[]/string/base64 data URL/…) and normalizes to `Uint8Array`.
2166
- * Centralized here so every entry point (packer, patch, descriptor helpers)
2167
- * shares one definition instead of re-declaring per module.
2165
+ * Lets an optional field (e.g. `radius?: number | UniversalMeasure`) be threaded
2166
+ * through a conversion without a per-call ternary.
2167
+ */
2168
+ const mapOptional = (value, fn) => value === void 0 ? void 0 : fn(value);
2169
+ /**
2170
+ * Convert public percent (100 = 100%) to OOXML ST_Percentage scalar (1/1000).
2171
+ * Math.round ensures JSON-first float input produces exact integer output.
2172
+ */
2173
+ const emitPercent = (percent) => Math.round(percent * 1e3);
2174
+ /**
2175
+ * Convert OOXML ST_Percentage scalar (1/1000) to public percent.
2176
+ */
2177
+ const parsePercent = (value) => value / 1e3;
2178
+ /**
2179
+ * Parse an ST_Percentage attribute that may arrive as either a 1/1000th
2180
+ * integer ("50000" = 50%) or a percent literal ("50%"); both are XSD-valid.
2181
+ * Returns the caller-facing integer percent.
2182
+ */
2183
+ const parsePercentAttr = (raw) => {
2184
+ if (raw === void 0) return void 0;
2185
+ const s = typeof raw === "number" ? String(raw) : raw;
2186
+ return s.endsWith("%") ? Number(s.slice(0, -1)) : parsePercent(Number(s));
2187
+ };
2188
+ /**
2189
+ * Convert public degrees to OOXML ST_Angle / ST_FixedAngle scalar (1/60000).
2190
+ * Math.round ensures JSON-first float input produces exact integer output.
2191
+ */
2192
+ const emitAngle = (degrees) => Math.round(degrees * 6e4);
2193
+ /**
2194
+ * Convert OOXML ST_Angle / ST_FixedAngle scalar (1/60000) to public degrees.
2195
+ */
2196
+ const parseAngle = (value) => value / 6e4;
2197
+ /**
2198
+ * Converts millimeters to TWIP (twentieths of a point).
2199
+ */
2200
+ const convertMillimetersToTwip = (millimeters) => Math.floor(millimeters / 25.4 * 72 * 20);
2201
+ /**
2202
+ * Converts inches to TWIP (twentieths of a point).
2203
+ */
2204
+ const convertInchesToTwip = (inches) => Math.floor(inches * 72 * 20);
2205
+ /**
2206
+ * Converts pixels to EMU (96 DPI).
2207
+ */
2208
+ const convertPixelsToEmu = (pixels) => Math.round(pixels * 9525);
2209
+ /**
2210
+ * Converts EMU to pixels (96 DPI).
2168
2211
  *
2169
- * @module
2212
+ * Returns a possibly fractional (sub-pixel) value. The integer rounding that
2213
+ * lived here before permanently discarded sub-pixel precision, which made an
2214
+ * EMU → pixel → EMU round-trip lossy (e.g. 5521960 EMU → 580 px → 5524500 EMU).
2215
+ * Keeping the fraction lets convertPixelsToEmu restore the exact original EMU.
2216
+ * Callers needing an integer pixel for display should Math.round the result.
2170
2217
  */
2171
- const DATA_URL_RE = /^data:([\w.+-]+\/[\w.+-]+)?;base64,/;
2172
- /** Test whether a string is a base64 data URL (`data:[mime];base64,...`). */
2173
- function isBase64DataURL(input) {
2174
- return DATA_URL_RE.test(input);
2175
- }
2176
- /** Normalize any supported binary input to a `Uint8Array`. */
2177
- function toUint8Array(data, options) {
2178
- if (data instanceof Uint8Array) return data;
2179
- if (data instanceof ArrayBuffer) return new Uint8Array(data);
2180
- if (data instanceof DataView) return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
2181
- if (typeof data === "string") {
2182
- const match = data.match(DATA_URL_RE);
2183
- if (match) return decodeBase64(data.slice(match[0].length));
2184
- if (options?.encoding === "base64") return decodeBase64(data);
2185
- return new TextEncoder().encode(data);
2218
+ const convertEmuToPixels = (emus) => emus / 9525;
2219
+ /**
2220
+ * Converts inches to EMU.
2221
+ */
2222
+ const convertInchesToEmu = (inches) => Math.round(inches * 914400);
2223
+ /**
2224
+ * Converts EMU to inches.
2225
+ */
2226
+ const convertEmuToInches = (emus) => emus / 914400;
2227
+ /**
2228
+ * Converts points to EMU.
2229
+ */
2230
+ const convertPointsToEmu = (points) => Math.round(points * 12700);
2231
+ /**
2232
+ * Converts EMU to points.
2233
+ */
2234
+ const convertEmuToPoints = (emus) => emus / 12700;
2235
+ /** Converts EMU to TWIP (1 TWIP = 635 EMU). */
2236
+ const convertEmuToTwip = (emus) => Math.round(emus / 635);
2237
+ /** Converts TWIP to EMU (1 TWIP = 635 EMU). */
2238
+ const convertTwipToEmu = (twips) => twips * 635;
2239
+ /** Converts points to TWIP (1 point = 20 TWIP). */
2240
+ const convertPointsToTwip = (points) => Math.round(points * 20);
2241
+ /** Converts TWIP to points (1 point = 20 TWIP). */
2242
+ const convertTwipToPoints = (twips) => twips / 20;
2243
+ /**
2244
+ * Parse a UniversalMeasure string into its numeric value and unit.
2245
+ *
2246
+ * @param measure - A universal measure string like "2.54cm", "-10mm", "1in"
2247
+ * @returns The parsed value and unit
2248
+ * @throws Error if the format is invalid
2249
+ *
2250
+ * @example
2251
+ * ```typescript
2252
+ * parseUniversalMeasure("2.54cm"); // { value: 2.54, unit: "cm" }
2253
+ * parseUniversalMeasure("-10mm"); // { value: -10, unit: "mm" }
2254
+ * ```
2255
+ */
2256
+ const parseUniversalMeasure = (measure) => {
2257
+ const match = measure.match(/^(-?[0-9]+(?:\.[0-9]+)?)(mm|cm|in|pt|pc|pi|px)$/);
2258
+ if (!match) throw new Error(`Invalid universal measure: '${measure}'`);
2259
+ const [, value, unit] = match;
2260
+ if (value === void 0 || unit === void 0) throw new Error(`Invalid universal measure: '${measure}'`);
2261
+ return {
2262
+ value: parseFloat(value),
2263
+ unit
2264
+ };
2265
+ };
2266
+ /**
2267
+ * Converts a UniversalMeasure string to TWIP (twentieths of a point).
2268
+ *
2269
+ * Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc).
2270
+ *
2271
+ * @param measure - A universal measure string like "2.54cm", "1in", "12pt"
2272
+ * @returns The value in TWIP
2273
+ *
2274
+ * @example
2275
+ * ```typescript
2276
+ * convertUniversalMeasureToTwip("1in"); // 1440
2277
+ * convertUniversalMeasureToTwip("2.54cm"); // ~1440 (1 inch)
2278
+ * convertUniversalMeasureToTwip("72pt"); // 1440 (1 inch = 72pt = 1440 twips)
2279
+ * ```
2280
+ */
2281
+ const convertUniversalMeasureToTwip = (measure) => {
2282
+ const { value, unit } = parseUniversalMeasure(measure);
2283
+ switch (unit) {
2284
+ case "mm": return convertMillimetersToTwip(value);
2285
+ case "cm": return convertMillimetersToTwip(value * 10);
2286
+ case "in": return convertInchesToTwip(value);
2287
+ case "pt": return Math.floor(value * 20);
2288
+ case "pc":
2289
+ case "pi": return Math.floor(value * 12 * 20);
2290
+ case "px": return Math.round(value * 15);
2186
2291
  }
2187
- if (Array.isArray(data)) return new Uint8Array(data);
2188
- if (data instanceof Blob) throw new TypeError("Blob input requires async processing");
2189
- if (data instanceof ReadableStream) throw new TypeError("ReadableStream input requires async processing");
2190
- throw new TypeError(`Unsupported data type: ${typeof data}`);
2191
- }
2292
+ };
2293
+ /**
2294
+ * Converts a measurement value (number or UniversalMeasure) to TWIP.
2295
+ *
2296
+ * If the value is already a number, it is returned as-is (assumed to be in twips).
2297
+ * If the value is a UniversalMeasure string, it is converted to twips.
2298
+ *
2299
+ * Useful for accepting both `number` and `UniversalMeasure` inputs where
2300
+ * the XSD type is a union (e.g., ST_TwipsMeasure, ST_SignedTwipsMeasure).
2301
+ *
2302
+ * @param val - A numeric twip value or a universal measure string
2303
+ * @returns The value in TWIP
2304
+ *
2305
+ * @example
2306
+ * ```typescript
2307
+ * convertToTwip(1440); // 1440 (already twips)
2308
+ * convertToTwip("1in"); // 1440
2309
+ * convertToTwip("2.54cm"); // ~1440
2310
+ * ```
2311
+ */
2312
+ const convertToTwip = (val) => typeof val === "string" ? convertUniversalMeasureToTwip(val) : val;
2313
+ /**
2314
+ * Converts a UniversalMeasure string to EMU (English Metric Units).
2315
+ *
2316
+ * Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc).
2317
+ *
2318
+ * @param measure - A universal measure string like "2.54cm", "1in", "12pt"
2319
+ * @returns The value in EMU
2320
+ *
2321
+ * @example
2322
+ * ```typescript
2323
+ * convertUniversalMeasureToEmu("1in"); // 914400
2324
+ * convertUniversalMeasureToEmu("2.54cm"); // 914400
2325
+ * convertUniversalMeasureToEmu("12pt"); // 152400
2326
+ * ```
2327
+ */
2328
+ const convertUniversalMeasureToEmu = (measure) => {
2329
+ const { value, unit } = parseUniversalMeasure(measure);
2330
+ switch (unit) {
2331
+ case "mm": return Math.round(value * 36e3);
2332
+ case "cm": return Math.round(value * 36e4);
2333
+ case "in": return convertInchesToEmu(value);
2334
+ case "pt": return convertPointsToEmu(value);
2335
+ case "pc":
2336
+ case "pi": return convertPointsToEmu(value * 12);
2337
+ case "px": return convertPixelsToEmu(value);
2338
+ }
2339
+ };
2340
+ /**
2341
+ * Converts a measurement value (number or UniversalMeasure) to EMU.
2342
+ *
2343
+ * Numbers are returned as-is (assumed EMU). Strings are parsed as
2344
+ * UniversalMeasure via {@link convertUniversalMeasureToEmu} — including the
2345
+ * project-only `px` unit (96 DPI). The result is always an EMU number written to
2346
+ * XML, so px never appears verbatim in the document.
2347
+ *
2348
+ * Useful for DrawingML fields where the XSD type is a union (e.g., ST_Coordinate).
2349
+ *
2350
+ * @param val - A numeric EMU value, or a UniversalMeasure string (incl. `${n}px`)
2351
+ * @returns The value in EMU
2352
+ *
2353
+ * @example
2354
+ * ```typescript
2355
+ * convertToEmu(914400); // 914400 (already EMU)
2356
+ * convertToEmu("1in"); // 914400
2357
+ * convertToEmu("2.54cm"); // 914400
2358
+ * convertToEmu("200px"); // 1905000 (200 * 9525)
2359
+ * ```
2360
+ */
2361
+ const convertToEmu = (val) => typeof val === "string" ? convertUniversalMeasureToEmu(val) : val;
2362
+ /**
2363
+ * Converts a UniversalMeasure string to points (1pt = 1/72 inch).
2364
+ *
2365
+ * Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc),
2366
+ * px (96 DPI).
2367
+ */
2368
+ const convertUniversalMeasureToPt = (measure) => {
2369
+ const { value, unit } = parseUniversalMeasure(measure);
2370
+ switch (unit) {
2371
+ case "mm": return value / 25.4 * 72;
2372
+ case "cm": return value * 10 / 25.4 * 72;
2373
+ case "in": return value * 72;
2374
+ case "pt": return value;
2375
+ case "pc":
2376
+ case "pi": return value * 12;
2377
+ case "px": return value / 96 * 72;
2378
+ }
2379
+ };
2380
+ /**
2381
+ * Converts a measurement value (number or UniversalMeasure) to points.
2382
+ *
2383
+ * Numbers are returned as-is (assumed to be in points). Strings are parsed as
2384
+ * UniversalMeasure. Useful for SpreadsheetML fields where a number is points.
2385
+ */
2386
+ const convertToPt = (val) => typeof val === "string" ? convertUniversalMeasureToPt(val) : val;
2387
+ /**
2388
+ * Converts a UniversalMeasure string to inches.
2389
+ *
2390
+ * Supports units: mm, cm, in, pt, pc, pi, px (96 DPI).
2391
+ */
2392
+ const convertUniversalMeasureToInch = (measure) => {
2393
+ const { value, unit } = parseUniversalMeasure(measure);
2394
+ switch (unit) {
2395
+ case "mm": return value / 25.4;
2396
+ case "cm": return value * 10 / 25.4;
2397
+ case "in": return value;
2398
+ case "pt": return value / 72;
2399
+ case "pc":
2400
+ case "pi": return value * 12 / 72;
2401
+ case "px": return value / 96;
2402
+ }
2403
+ };
2404
+ /**
2405
+ * Converts a measurement value (number or UniversalMeasure) to inches.
2406
+ *
2407
+ * Numbers are returned as-is (assumed to be in inches). Useful for SpreadsheetML
2408
+ * page-margin fields where a number is inches.
2409
+ */
2410
+ const convertToInch = (val) => typeof val === "string" ? convertUniversalMeasureToInch(val) : val;
2192
2411
  //#endregion
2193
2412
  //#region src/util/generators.ts
2194
2413
  /**
@@ -2208,7 +2427,7 @@ const URL_ALPHABET = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvw
2208
2427
  * Generates a unique lowercase alphanumeric ID using crypto.getRandomValues.
2209
2428
  */
2210
2429
  const uniqueId = () => {
2211
- const bytes = new Uint8Array(21);
2430
+ const bytes = /* @__PURE__ */ new Uint8Array(21);
2212
2431
  crypto.getRandomValues(bytes);
2213
2432
  let id = "";
2214
2433
  for (const byte of bytes) id += URL_ALPHABET[byte & 63];
@@ -2218,13 +2437,50 @@ const uniqueId = () => {
2218
2437
  * Generates a SHA-1 hash of the provided data.
2219
2438
  */
2220
2439
  const hashedId = (data) => {
2221
- return bytesToHex(sha1(data instanceof ArrayBuffer ? new Uint8Array(data) : typeof data === "string" ? new TextEncoder().encode(data) : data));
2440
+ const bytes = data instanceof ArrayBuffer ? new Uint8Array(data) : typeof data === "string" ? new TextEncoder().encode(data) : data;
2441
+ return bytesToHex(sha1(bytes));
2222
2442
  };
2223
2443
  /**
2224
2444
  * Generates a UUID v4-style unique identifier using crypto.randomUUID.
2225
2445
  */
2226
2446
  const uniqueUuid = () => crypto.randomUUID();
2227
2447
  //#endregion
2228
- export { Buffer as $, convertInchesToTwip as A, convertTwipToPoints as B, xsdUnderlineStyle as C, convertEmuToPoints as D, convertEmuToPixels as E, convertToEmu as F, emitAngle as G, convertUniversalMeasureToInch as H, convertToInch as I, parseAngle as J, emitPercent as K, convertToPt as L, convertPixelsToEmu as M, convertPointsToEmu as N, convertEmuToTwip as O, convertPointsToTwip as P, encodeBase64 as Q, convertToTwip as R, xsdTextCaps as S, convertEmuToInches as T, convertUniversalMeasureToPt as U, convertUniversalMeasureToEmu as V, convertUniversalMeasureToTwip as W, parseUniversalMeasure as X, parsePercent as Y, decodeBase64 as Z, xsdPresetShadow as _, stripColorHashPrefix as _t, isBase64DataURL as a, hexBinary as at, xsdTextAlign as b, universalMeasureValue as bt, xsdBlendMode as c, longHexNumber as ct, xsdLineCap as d, percentageValue as dt, ThemeColor as et, xsdLineEndSize as f, pointMeasureValue as ft, xsdPenAlignment as g, signedTwipsMeasureValue as gt, xsdPattern as h, signedHpsMeasureValue as ht, uniqueUuid as i, eighthPointMeasureValue as it, convertMillimetersToTwip as j, convertInchesToEmu as k, xsdCompoundLine as l, measurementOrPercentValue as lt, xsdPathFillMode as m, shortHexNumber as mt, uniqueId as n, dateTimeValue as nt, toUint8Array as o, hexColorValue as ot, xsdMaterialType as p, positiveUniversalMeasureValue as pt, mapOptional as q, uniqueNumericIdCreator as r, decimalNumber as rt, invertMap as s, hpsMeasureValue as st, hashedId as t, ThemeFont as tt, xsdEffectContainer as u, parseOnOff as ut, xsdRectAlignment as v, twipsMeasureValue as vt, xsdVerticalMergeRev as w, xsdTextAnchor as x, unsignedDecimalNumber as xt, xsdStrikeStyle as y, uCharHexNumber as yt, convertTwipToEmu as z };
2448
+ //#region src/util/image-type.ts
2449
+ /** Map a media path's file extension to an image type token. */
2450
+ function imageTypeFromPath(path) {
2451
+ switch (path.split(".").pop()?.toLowerCase() ?? "") {
2452
+ case "jpg":
2453
+ case "jpeg": return "jpg";
2454
+ case "png": return "png";
2455
+ case "gif": return "gif";
2456
+ case "bmp": return "bmp";
2457
+ case "tif":
2458
+ case "tiff": return "tif";
2459
+ case "ico": return "ico";
2460
+ case "emf": return "emf";
2461
+ case "wmf": return "wmf";
2462
+ default: return "png";
2463
+ }
2464
+ }
2465
+ //#endregion
2466
+ //#region src/util/ext-uri.ts
2467
+ /**
2468
+ * Extension-uri matching for a:ext/p:ext style extension lists.
2469
+ *
2470
+ * @module
2471
+ */
2472
+ /**
2473
+ * Match an `@uri` attribute against a known extension uri. Producers write
2474
+ * GUID-style uris with or without the enclosing braces and in mixed case —
2475
+ * both spellings denote the same extension, so compare brace-stripped and
2476
+ * case-insensitively.
2477
+ */
2478
+ function extUriMatches(actual, expected) {
2479
+ if (actual === void 0) return false;
2480
+ const norm = (uri) => uri.replace(/^[{]+|[}]+$/g, "").toLowerCase();
2481
+ return norm(actual) === norm(expected);
2482
+ }
2483
+ //#endregion
2484
+ export { xsdDiagramDirection as $, pointMeasureValue as $t, parseAngle as A, xsdTextBuild as At, xsdAxisCrossBetween as B, decodeBase64 as Bt, convertUniversalMeasureToEmu as C, xsdSizeRepresents as Ct, emitAngle as D, xsdTableWidthType as Dt, convertUniversalMeasureToTwip as E, xsdStrikeStyle as Et, xsdAnimCalcMode as F, xsdTrendlineType as Ft, xsdBlendMode as G, eighthPointMeasureValue as Gt, xsdAxisLabelAlignment as H, Buffer as Ht, xsdAnimClass as I, xsdUnderlineStyle as It, xsdCompoundLine as J, hpsMeasureValue as Jt, xsdChartBuild as K, hexBinary as Kt, xsdAnimLevel as L, xsdVerticalMergeRev as Lt, parsePercentAttr as M, xsdTextTabAlignment as Mt, parseUniversalMeasure as N, xsdTextVerticalType as Nt, emitPercent as O, xsdTextAlign as Ot, invertMap as P, xsdTotalsRowFunction as Pt, xsdDiagramBuild as Q, percentageValue as Qt, xsdAnimValueType as R, isBase64DataURL as Rt, convertTwipToPoints as S, xsdShadingPattern as St, convertUniversalMeasureToPt as T, xsdSplitType as Tt, xsdAxisOrientation as U, dateTimeValue as Ut, xsdAxisCrosses as V, encodeBase64 as Vt, xsdAxisPosition as W, decimalNumber as Wt, xsdDashStyle as X, measurementOrPercentValue as Xt, xsdConsolidateFunction as Y, longHexNumber as Yt, xsdDataLabelPosition as Z, parseOnOff as Zt, convertToEmu as _, xsdPenAlignment as _t, uniqueNumericIdCreator as a, twipsMeasureValue as an, xsdIterateType as at, convertToTwip as b, xsdRectAlignment as bt, convertEmuToPixels as c, unsignedDecimalNumber as cn, xsdLightRigDirection as ct, convertInchesToEmu as d, xsdMaterialType as dt, positiveUniversalMeasureValue as en, xsdEffectContainer as et, convertInchesToTwip as f, xsdMathStyle as ft, convertPointsToTwip as g, xsdPattern as gt, convertPointsToEmu as h, xsdPathFillMode as ht, uniqueId as i, stripColorHashPrefix as in, xsdHueDirection as it, parsePercent as j, xsdTextCaps as jt, mapOptional as k, xsdTextAnchor as kt, convertEmuToPoints as l, xsdLineCap as lt, convertPixelsToEmu as m, xsdOrient as mt, imageTypeFromPath as n, signedHpsMeasureValue as nn, xsdFontAlignment as nt, uniqueUuid as o, uCharHexNumber as on, xsdJcAlignment as ot, convertMillimetersToTwip as p, xsdOnOffStyle as pt, xsdComments as q, hexColorValue as qt, hashedId as r, signedTwipsMeasureValue as rn, xsdHierBranch as rt, convertEmuToInches as s, universalMeasureValue as sn, xsdLegendPosition as st, extUriMatches as t, shortHexNumber as tn, xsdErrorValueType as tt, convertEmuToTwip as u, xsdLineEndSize as ut, convertToInch as v, xsdPlaceholderType as vt, convertUniversalMeasureToInch as w, xsdSlideLayoutType as wt, convertTwipToEmu as x, xsdResizeHandles as xt, convertToPt as y, xsdPresetShadow as yt, xsdAnimationDgmBuild as z, toUint8Array as zt };
2229
2485
 
2230
- //# sourceMappingURL=generators-CElPsAhd.mjs.map
2486
+ //# sourceMappingURL=ext-uri-BHBcIrW7.mjs.map