@office-open/core 0.10.15 → 0.11.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.
- package/README.md +2 -1
- package/dist/chart/index.d.mts +2 -2
- package/dist/chart/index.mjs +2 -2
- package/dist/chart-Kf_utasF.mjs +1780 -0
- package/dist/chart-Kf_utasF.mjs.map +1 -0
- package/dist/color-mapping-CFF0vRSe.mjs +117 -0
- package/dist/color-mapping-CFF0vRSe.mjs.map +1 -0
- package/dist/descriptor/index.d.mts +2 -2
- package/dist/descriptor/index.mjs +1 -1
- package/dist/{descriptor-BjNkn5jo.mjs → descriptor-BX8xW8na.mjs} +6 -2
- package/dist/{descriptor-BjNkn5jo.mjs.map → descriptor-BX8xW8na.mjs.map} +1 -1
- package/dist/drawing/index.d.mts +2 -0
- package/dist/drawing/index.mjs +2 -0
- package/dist/{drawingml-sj1J3lb0.mjs → drawing-FBzd2I0m.mjs} +2596 -1518
- package/dist/drawing-FBzd2I0m.mjs.map +1 -0
- package/dist/{converters-C_Y2QX1w.mjs → generators-CElPsAhd.mjs} +699 -258
- package/dist/generators-CElPsAhd.mjs.map +1 -0
- package/dist/index-BsTUn4K1.d.mts +28 -0
- package/dist/index-BsTUn4K1.d.mts.map +1 -0
- package/dist/index-C0ClOhmZ.d.mts +869 -0
- package/dist/index-C0ClOhmZ.d.mts.map +1 -0
- package/dist/{index-BVK2dv6C.d.mts → index-CLX7gU9J.d.mts} +8 -3
- package/dist/index-CLX7gU9J.d.mts.map +1 -0
- package/dist/index-Cgz88FU0.d.mts +308 -0
- package/dist/index-Cgz88FU0.d.mts.map +1 -0
- package/dist/{index-CE53SwpZ.d.mts → index-CnjCK-lF.d.mts} +497 -351
- package/dist/index-CnjCK-lF.d.mts.map +1 -0
- package/dist/{index-BfHfKuKy.d.mts → index-DpPeyf5f.d.mts} +61 -20
- package/dist/index-DpPeyf5f.d.mts.map +1 -0
- package/dist/index-DxwLMnBF.d.mts +384 -0
- package/dist/index-DxwLMnBF.d.mts.map +1 -0
- package/dist/index.d.mts +175 -22
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +523 -70
- package/dist/index.mjs.map +1 -1
- package/dist/patch/index.mjs +1 -1
- package/dist/{patch-BmRfghOo.mjs → patch-3KLx2yEP.mjs} +4 -4
- package/dist/patch-3KLx2yEP.mjs.map +1 -0
- package/dist/smartart/index.d.mts +2 -2
- package/dist/smartart/index.mjs +2 -2
- package/dist/smartart-BxnkROOp.mjs +1649 -0
- package/dist/smartart-BxnkROOp.mjs.map +1 -0
- package/dist/style-matrix-DAP6XrLv.mjs +123 -0
- package/dist/style-matrix-DAP6XrLv.mjs.map +1 -0
- package/dist/theme/index.d.mts +4 -2
- package/dist/theme/index.mjs +3 -2
- package/dist/theme-OAuRcA9_.mjs +460 -0
- package/dist/theme-OAuRcA9_.mjs.map +1 -0
- package/dist/theme-options-BbWccl85.d.mts +109 -0
- package/dist/theme-options-BbWccl85.d.mts.map +1 -0
- package/dist/util/index.d.mts +3 -3
- package/dist/util/index.mjs +3 -3
- package/dist/{util-Tq9PSjK0.mjs → util-C94-JKtp.mjs} +175 -429
- package/dist/util-C94-JKtp.mjs.map +1 -0
- package/dist/{values-8di32lIe.d.mts → values-aVoirbWB.d.mts} +4 -2
- package/dist/values-aVoirbWB.d.mts.map +1 -0
- package/dist/vector/index.d.mts +2 -0
- package/dist/vector/index.mjs +2 -0
- package/dist/vector-TpjW6ZSc.mjs +3092 -0
- package/dist/vector-TpjW6ZSc.mjs.map +1 -0
- package/package.json +15 -7
- package/dist/chart-DIGJna_6.mjs +0 -582
- package/dist/chart-DIGJna_6.mjs.map +0 -1
- package/dist/converters-C_Y2QX1w.mjs.map +0 -1
- package/dist/drawingml/index.d.mts +0 -2
- package/dist/drawingml/index.mjs +0 -2
- package/dist/drawingml-sj1J3lb0.mjs.map +0 -1
- package/dist/index-BVK2dv6C.d.mts.map +0 -1
- package/dist/index-BfHfKuKy.d.mts.map +0 -1
- package/dist/index-CE53SwpZ.d.mts.map +0 -1
- package/dist/index-D6VE-MnJ.d.mts +0 -43
- package/dist/index-D6VE-MnJ.d.mts.map +0 -1
- package/dist/index-DE4CLElr.d.mts +0 -145
- package/dist/index-DE4CLElr.d.mts.map +0 -1
- package/dist/index-DlPA26cw.d.mts +0 -91
- package/dist/index-DlPA26cw.d.mts.map +0 -1
- package/dist/patch-BmRfghOo.mjs.map +0 -1
- package/dist/smartart-B7ukZ-Tw.mjs +0 -305
- package/dist/smartart-B7ukZ-Tw.mjs.map +0 -1
- package/dist/theme-CiNzdl-9.mjs +0 -177
- package/dist/theme-CiNzdl-9.mjs.map +0 -1
- package/dist/util-Tq9PSjK0.mjs.map +0 -1
- package/dist/values-8di32lIe.d.mts.map +0 -1
|
@@ -1,5 +1,418 @@
|
|
|
1
1
|
import { sha1 } from "@noble/hashes/legacy.js";
|
|
2
2
|
import { bytesToHex } from "@noble/hashes/utils.js";
|
|
3
|
+
//#region src/util/values.ts
|
|
4
|
+
/**
|
|
5
|
+
* Validates and converts a number to an integer (decimal number).
|
|
6
|
+
*
|
|
7
|
+
* Reference: ST_DecimalNumber in OOXML specification
|
|
8
|
+
*
|
|
9
|
+
* @param val - The number to validate and convert
|
|
10
|
+
* @returns The floored integer value
|
|
11
|
+
* @throws Error if the value is NaN
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const num = decimalNumber(10.7); // Returns 10
|
|
16
|
+
* const negative = decimalNumber(-5.3); // Returns -5
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
const decimalNumber = (val) => {
|
|
20
|
+
if (!Number.isFinite(val)) throw new Error(`Invalid value '${val}' specified. Must be a finite number.`);
|
|
21
|
+
return Math.floor(val);
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Validates and converts a number to a positive integer (unsigned decimal number).
|
|
25
|
+
*
|
|
26
|
+
* Reference: ST_UnsignedDecimalNumber in OOXML specification
|
|
27
|
+
*
|
|
28
|
+
* @param val - The number to validate and convert
|
|
29
|
+
* @returns The floored positive integer value
|
|
30
|
+
* @throws Error if the value is NaN or negative
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* const num = unsignedDecimalNumber(10.7); // Returns 10
|
|
35
|
+
* const invalid = unsignedDecimalNumber(-5); // Throws Error
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
const unsignedDecimalNumber = (val) => {
|
|
39
|
+
const value = decimalNumber(val);
|
|
40
|
+
if (value < 0) throw new Error(`Invalid value '${val}' specified. Must be a positive integer.`);
|
|
41
|
+
return value;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Validates and normalizes a hexadecimal binary value.
|
|
45
|
+
*
|
|
46
|
+
* The xsd:hexBinary type represents binary data as a sequence of binary octets
|
|
47
|
+
* using hexadecimal encoding, where each binary octet is a two-character
|
|
48
|
+
* hexadecimal number. Both lowercase and uppercase letters A-F are permitted.
|
|
49
|
+
*
|
|
50
|
+
* @param val - The hexadecimal string to validate
|
|
51
|
+
* @param length - The expected length in bytes (not characters)
|
|
52
|
+
* @returns The validated hexadecimal string
|
|
53
|
+
* @throws Error if the value is not a valid hex string of the expected length
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* hexBinary("0FB8", 2); // Valid: 2 bytes = 4 characters
|
|
58
|
+
* hexBinary("ABC", 2); // Invalid: wrong length
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
const hexBinary = (val, length) => {
|
|
62
|
+
const expectedLength = length * 2;
|
|
63
|
+
if (val.length !== expectedLength || isNaN(Number(`0x${val}`))) throw new Error(`Invalid hex value '${val}'. Expected ${expectedLength} digit hex value`);
|
|
64
|
+
return val;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Validates a long hexadecimal number (4 bytes / 8 characters).
|
|
68
|
+
*
|
|
69
|
+
* Reference: ST_LongHexNumber in OOXML specification
|
|
70
|
+
*
|
|
71
|
+
* @param val - The hexadecimal string to validate
|
|
72
|
+
* @returns The validated hexadecimal string
|
|
73
|
+
* @throws Error if the value is not a valid 8-character hex string
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* const hex = longHexNumber("ABCD1234"); // Valid
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
const longHexNumber = (val) => hexBinary(val, 4);
|
|
81
|
+
/**
|
|
82
|
+
* Validates a short hexadecimal number (2 bytes / 4 characters).
|
|
83
|
+
*
|
|
84
|
+
* Reference: ST_ShortHexNumber in OOXML specification
|
|
85
|
+
*
|
|
86
|
+
* @param val - The hexadecimal string to validate
|
|
87
|
+
* @returns The validated hexadecimal string
|
|
88
|
+
* @throws Error if the value is not a valid 4-character hex string
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* const hex = shortHexNumber("AB12"); // Valid
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
const shortHexNumber = (val) => hexBinary(val, 2);
|
|
96
|
+
/**
|
|
97
|
+
* Validates a single-byte hexadecimal number (1 byte / 2 characters).
|
|
98
|
+
*
|
|
99
|
+
* Reference: ST_UcharHexNumber in OOXML specification
|
|
100
|
+
*
|
|
101
|
+
* @param val - The hexadecimal string to validate
|
|
102
|
+
* @returns The validated hexadecimal string
|
|
103
|
+
* @throws Error if the value is not a valid 2-character hex string
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```typescript
|
|
107
|
+
* const hex = uCharHexNumber("FF"); // Valid
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
const uCharHexNumber = (val) => hexBinary(val, 1);
|
|
111
|
+
/**
|
|
112
|
+
* Normalizes a universal measure value by parsing and reformatting.
|
|
113
|
+
*
|
|
114
|
+
* Ensures the numeric portion is properly formatted while preserving the unit.
|
|
115
|
+
*
|
|
116
|
+
* Reference: ST_UniversalMeasure in OOXML specification
|
|
117
|
+
*
|
|
118
|
+
* @param val - The universal measure string to normalize
|
|
119
|
+
* @returns The normalized universal measure
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* const measure = universalMeasureValue("10.500mm"); // Returns "10.5mm"
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
const universalMeasureValue = (val) => {
|
|
127
|
+
const unit = val.slice(-2);
|
|
128
|
+
const amount = val.substring(0, val.length - 2);
|
|
129
|
+
return `${Number(amount)}${unit}`;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Validates and normalizes a positive universal measure value.
|
|
133
|
+
*
|
|
134
|
+
* Reference: ST_PositiveUniversalMeasure in OOXML specification
|
|
135
|
+
*
|
|
136
|
+
* @param val - The positive universal measure string to validate
|
|
137
|
+
* @returns The normalized positive universal measure
|
|
138
|
+
* @throws Error if the value is negative
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* const measure = positiveUniversalMeasureValue("10.5mm"); // Valid
|
|
143
|
+
* const invalid = positiveUniversalMeasureValue("-5mm"); // Throws Error
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
const positiveUniversalMeasureValue = (val) => {
|
|
147
|
+
const value = universalMeasureValue(val);
|
|
148
|
+
if (parseFloat(value) < 0) throw new Error(`Invalid value '${value}' specified. Expected a positive number.`);
|
|
149
|
+
return value;
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Validates and normalizes a hexadecimal color value.
|
|
153
|
+
*
|
|
154
|
+
* Accepts either "auto" or a 6-character RGB hex value (with or without # prefix).
|
|
155
|
+
* The # prefix is commonly used but technically invalid in OOXML, so it is stripped
|
|
156
|
+
* for strict compliance.
|
|
157
|
+
*
|
|
158
|
+
* Reference: ST_HexColor in OOXML specification
|
|
159
|
+
*
|
|
160
|
+
* @param val - The color value to validate ("auto" or hex color)
|
|
161
|
+
* @returns The normalized color value
|
|
162
|
+
* @throws Error if the hex color is invalid
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```typescript
|
|
166
|
+
* const color1 = hexColorValue("auto"); // Returns "auto"
|
|
167
|
+
* const color2 = hexColorValue("FF0000"); // Returns "FF0000"
|
|
168
|
+
* const color3 = hexColorValue("#00FF00"); // Returns "00FF00" (# stripped)
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
const hexColorValue = (val) => {
|
|
172
|
+
if (val === "auto") return val;
|
|
173
|
+
return hexBinary(stripColorHashPrefix(val), 3);
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Strips the leading "#" prefix from a color string if present.
|
|
177
|
+
*
|
|
178
|
+
* Hex color values in OOXML do not include the "#" prefix, but user input
|
|
179
|
+
* commonly includes it. This helper normalizes color strings for OOXML output.
|
|
180
|
+
*
|
|
181
|
+
* @param color - The color string (with or without "#" prefix)
|
|
182
|
+
* @returns The color string without the "#" prefix
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* stripColorHashPrefix("#FF0000"); // Returns "FF0000"
|
|
187
|
+
* stripColorHashPrefix("00FF00"); // Returns "00FF00"
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
const stripColorHashPrefix = (color) => color.charAt(0) === "#" ? color.substring(1) : color;
|
|
191
|
+
/**
|
|
192
|
+
* Parses an ST_OnOff / xsd:boolean attribute value.
|
|
193
|
+
*
|
|
194
|
+
* Accepts the full union lexical space leniently on read: true/false, 1/0
|
|
195
|
+
* (number or string — nativeTypeAttributes coerces 1/0 to numbers), and
|
|
196
|
+
* on/off (legal only in wml's ST_OnOff union, not in xsd:boolean). Emission
|
|
197
|
+
* stays per-schema canonical ("1"/"0").
|
|
198
|
+
*
|
|
199
|
+
* Reference: ST_OnOff in shared-commonSimpleTypes.xsd
|
|
200
|
+
*
|
|
201
|
+
* @param raw - The raw attribute value (string, number, or boolean)
|
|
202
|
+
* @returns The parsed boolean, or undefined when unrecognized
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```typescript
|
|
206
|
+
* parseOnOff("1"); // true
|
|
207
|
+
* parseOnOff("off"); // false
|
|
208
|
+
* parseOnOff(1); // true (nativeTypeAttributes number coercion)
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
const parseOnOff = (raw) => {
|
|
212
|
+
if (raw === void 0) return void 0;
|
|
213
|
+
if (typeof raw === "boolean") return raw;
|
|
214
|
+
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;
|
|
217
|
+
};
|
|
218
|
+
/**
|
|
219
|
+
* Validates a signed TWIP measurement value.
|
|
220
|
+
*
|
|
221
|
+
* Accepts either a universal measure string or a numeric TWIP value.
|
|
222
|
+
*
|
|
223
|
+
* Reference: ST_SignedTwipsMeasure in OOXML specification
|
|
224
|
+
*
|
|
225
|
+
* @param val - The measurement value (universal measure or number)
|
|
226
|
+
* @returns The normalized measurement value
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* ```typescript
|
|
230
|
+
* const measure1 = signedTwipsMeasureValue("10mm");
|
|
231
|
+
* const measure2 = signedTwipsMeasureValue(1440); // 1 inch in TWIP
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
const signedTwipsMeasureValue = (val) => typeof val === "string" ? universalMeasureValue(val) : decimalNumber(val);
|
|
235
|
+
/**
|
|
236
|
+
* Validates a half-point (HPS) measurement value.
|
|
237
|
+
*
|
|
238
|
+
* Accepts either a positive universal measure string or a positive number.
|
|
239
|
+
* HPS (half-points) are commonly used for font sizes.
|
|
240
|
+
*
|
|
241
|
+
* Reference: ST_HpsMeasure in OOXML specification
|
|
242
|
+
*
|
|
243
|
+
* @param val - The measurement value (positive universal measure or number)
|
|
244
|
+
* @returns The normalized measurement value
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* ```typescript
|
|
248
|
+
* const fontSize1 = hpsMeasureValue("12pt");
|
|
249
|
+
* const fontSize2 = hpsMeasureValue(24); // 12pt in half-points
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
const hpsMeasureValue = (val) => typeof val === "string" ? positiveUniversalMeasureValue(val) : unsignedDecimalNumber(val);
|
|
253
|
+
/**
|
|
254
|
+
* Validates a signed half-point (HPS) measurement value.
|
|
255
|
+
*
|
|
256
|
+
* Accepts either a universal measure string or a numeric value.
|
|
257
|
+
*
|
|
258
|
+
* Reference: ST_SignedHpsMeasure in OOXML specification
|
|
259
|
+
*
|
|
260
|
+
* @param val - The measurement value (universal measure or number)
|
|
261
|
+
* @returns The normalized measurement value
|
|
262
|
+
*
|
|
263
|
+
* @example
|
|
264
|
+
* ```typescript
|
|
265
|
+
* const spacing1 = signedHpsMeasureValue("6pt");
|
|
266
|
+
* const spacing2 = signedHpsMeasureValue(-12); // Negative spacing
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
269
|
+
const signedHpsMeasureValue = (val) => typeof val === "string" ? universalMeasureValue(val) : decimalNumber(val);
|
|
270
|
+
/**
|
|
271
|
+
* Validates a positive TWIP measurement value.
|
|
272
|
+
*
|
|
273
|
+
* Accepts either a positive universal measure string or a positive number.
|
|
274
|
+
*
|
|
275
|
+
* Reference: ST_TwipsMeasure in OOXML specification
|
|
276
|
+
*
|
|
277
|
+
* @param val - The measurement value (positive universal measure or number)
|
|
278
|
+
* @returns The normalized measurement value
|
|
279
|
+
*
|
|
280
|
+
* @example
|
|
281
|
+
* ```typescript
|
|
282
|
+
* const width1 = twipsMeasureValue("25.4mm");
|
|
283
|
+
* const width2 = twipsMeasureValue(1440); // 1 inch in TWIP
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
const twipsMeasureValue = (val) => typeof val === "string" ? positiveUniversalMeasureValue(val) : unsignedDecimalNumber(val);
|
|
287
|
+
/**
|
|
288
|
+
* Normalizes a percentage value by parsing and reformatting.
|
|
289
|
+
*
|
|
290
|
+
* Reference: ST_Percentage in OOXML specification
|
|
291
|
+
*
|
|
292
|
+
* @param val - The percentage string to normalize
|
|
293
|
+
* @returns The normalized percentage
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* ```typescript
|
|
297
|
+
* const percent = percentageValue("50.000%"); // Returns "50%"
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
const percentageValue = (val) => {
|
|
301
|
+
const percent = val.substring(0, val.length - 1);
|
|
302
|
+
return `${Number(percent)}%`;
|
|
303
|
+
};
|
|
304
|
+
/**
|
|
305
|
+
* Validates a measurement value that can be expressed as a number, percentage, or universal measure.
|
|
306
|
+
*
|
|
307
|
+
* Reference: ST_MeasurementOrPercent in OOXML specification
|
|
308
|
+
*
|
|
309
|
+
* @param val - The measurement value (number, percentage, or universal measure)
|
|
310
|
+
* @returns The normalized measurement value
|
|
311
|
+
*
|
|
312
|
+
* @example
|
|
313
|
+
* ```typescript
|
|
314
|
+
* const measure1 = measurementOrPercentValue(100); // Unqualified number
|
|
315
|
+
* const measure2 = measurementOrPercentValue("50%"); // Percentage
|
|
316
|
+
* const measure3 = measurementOrPercentValue("10mm"); // Universal measure
|
|
317
|
+
* ```
|
|
318
|
+
*/
|
|
319
|
+
const measurementOrPercentValue = (val) => {
|
|
320
|
+
if (typeof val === "number") return decimalNumber(val);
|
|
321
|
+
if (val.slice(-1) === "%") return percentageValue(val);
|
|
322
|
+
return universalMeasureValue(val);
|
|
323
|
+
};
|
|
324
|
+
/**
|
|
325
|
+
* Validates an eighth-point measurement value.
|
|
326
|
+
*
|
|
327
|
+
* Eighth-points are used for fine-grained measurements in text formatting.
|
|
328
|
+
*
|
|
329
|
+
* Reference: ST_EighthPointMeasure in OOXML specification
|
|
330
|
+
*
|
|
331
|
+
* @param val - The measurement value in eighth-points
|
|
332
|
+
* @returns The validated positive integer value
|
|
333
|
+
*
|
|
334
|
+
* @example
|
|
335
|
+
* ```typescript
|
|
336
|
+
* const measure = eighthPointMeasureValue(16); // 2 points
|
|
337
|
+
* ```
|
|
338
|
+
*/
|
|
339
|
+
const eighthPointMeasureValue = unsignedDecimalNumber;
|
|
340
|
+
/**
|
|
341
|
+
* Validates a point measurement value.
|
|
342
|
+
*
|
|
343
|
+
* Reference: ST_PointMeasure in OOXML specification
|
|
344
|
+
*
|
|
345
|
+
* @param val - The measurement value in points
|
|
346
|
+
* @returns The validated positive integer value
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* ```typescript
|
|
350
|
+
* const fontSize = pointMeasureValue(12); // 12pt
|
|
351
|
+
* ```
|
|
352
|
+
*/
|
|
353
|
+
const pointMeasureValue = unsignedDecimalNumber;
|
|
354
|
+
/**
|
|
355
|
+
* Converts a JavaScript Date object to an ISO 8601 date-time string.
|
|
356
|
+
*
|
|
357
|
+
* The format is CCYY-MM-DDThh:mm:ss.sssZ where T is a literal and Z indicates UTC.
|
|
358
|
+
* This matches the xsd:dateTime format required by OOXML.
|
|
359
|
+
*
|
|
360
|
+
* Reference: ST_DateTime in OOXML specification
|
|
361
|
+
*
|
|
362
|
+
* @param val - The Date object to convert
|
|
363
|
+
* @returns An ISO 8601 formatted date-time string
|
|
364
|
+
*
|
|
365
|
+
* @example
|
|
366
|
+
* ```typescript
|
|
367
|
+
* const now = new Date();
|
|
368
|
+
* const timestamp = dateTimeValue(now); // Returns "2024-01-15T10:30:00.000Z"
|
|
369
|
+
* ```
|
|
370
|
+
*/
|
|
371
|
+
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
|
+
//#endregion
|
|
3
416
|
//#region \0polyfill-node.global.js
|
|
4
417
|
var _polyfill_node_global_default = typeof _polyfill_node_global_default !== "undefined" ? _polyfill_node_global_default : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};
|
|
5
418
|
//#endregion
|
|
@@ -1294,83 +1707,256 @@ function encodeBase64(bytes) {
|
|
|
1294
1707
|
return btoa(binary);
|
|
1295
1708
|
}
|
|
1296
1709
|
//#endregion
|
|
1297
|
-
//#region src/util/
|
|
1710
|
+
//#region src/util/converters.ts
|
|
1298
1711
|
/**
|
|
1299
|
-
*
|
|
1300
|
-
*
|
|
1301
|
-
* Accepts the full range of binary inputs (Buffer/Uint8Array/ArrayBuffer/
|
|
1302
|
-
* DataView/number[]/string/base64 data URL/…) and normalizes to `Uint8Array`.
|
|
1303
|
-
* Centralized here so every entry point (packer, patch, descriptor helpers)
|
|
1304
|
-
* shares one definition instead of re-declaring per module.
|
|
1712
|
+
* Apply `fn` to `value` unless it is `undefined`; `undefined` passes through.
|
|
1305
1713
|
*
|
|
1306
|
-
*
|
|
1714
|
+
* Lets an optional field (e.g. `radius?: number | UniversalMeasure`) be threaded
|
|
1715
|
+
* through a conversion without a per-call ternary.
|
|
1307
1716
|
*/
|
|
1308
|
-
const
|
|
1309
|
-
/** Test whether a string is a base64 data URL (`data:[mime];base64,...`). */
|
|
1310
|
-
function isBase64DataURL(input) {
|
|
1311
|
-
return DATA_URL_RE.test(input);
|
|
1312
|
-
}
|
|
1313
|
-
/** Normalize any supported binary input to a `Uint8Array`. */
|
|
1314
|
-
function toUint8Array(data, options) {
|
|
1315
|
-
if (data instanceof Uint8Array) return data;
|
|
1316
|
-
if (data instanceof ArrayBuffer) return new Uint8Array(data);
|
|
1317
|
-
if (data instanceof DataView) return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
1318
|
-
if (typeof data === "string") {
|
|
1319
|
-
const match = data.match(DATA_URL_RE);
|
|
1320
|
-
if (match) return decodeBase64(data.slice(match[0].length));
|
|
1321
|
-
if (options?.encoding === "base64") return decodeBase64(data);
|
|
1322
|
-
return new TextEncoder().encode(data);
|
|
1323
|
-
}
|
|
1324
|
-
if (Array.isArray(data)) return new Uint8Array(data);
|
|
1325
|
-
if (data instanceof Blob) throw new TypeError("Blob input requires async processing");
|
|
1326
|
-
if (data instanceof ReadableStream) throw new TypeError("ReadableStream input requires async processing");
|
|
1327
|
-
throw new TypeError(`Unsupported data type: ${typeof data}`);
|
|
1328
|
-
}
|
|
1329
|
-
//#endregion
|
|
1330
|
-
//#region src/util/generators.ts
|
|
1717
|
+
const mapOptional = (value, fn) => value === void 0 ? void 0 : fn(value);
|
|
1331
1718
|
/**
|
|
1332
|
-
*
|
|
1333
|
-
*
|
|
1334
|
-
* @module
|
|
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.
|
|
1335
1721
|
*/
|
|
1722
|
+
const emitPercent = (percent) => Math.round(percent * 1e3);
|
|
1336
1723
|
/**
|
|
1337
|
-
*
|
|
1724
|
+
* Convert OOXML ST_Percentage scalar (1/1000) to public percent.
|
|
1338
1725
|
*/
|
|
1339
|
-
const
|
|
1340
|
-
let currentCount = initial;
|
|
1341
|
-
return () => ++currentCount;
|
|
1342
|
-
};
|
|
1343
|
-
const URL_ALPHABET = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
1726
|
+
const parsePercent = (value) => value / 1e3;
|
|
1344
1727
|
/**
|
|
1345
|
-
*
|
|
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.
|
|
1346
1730
|
*/
|
|
1347
|
-
const
|
|
1348
|
-
const bytes = new Uint8Array(21);
|
|
1349
|
-
crypto.getRandomValues(bytes);
|
|
1350
|
-
let id = "";
|
|
1351
|
-
for (const byte of bytes) id += URL_ALPHABET[byte & 63];
|
|
1352
|
-
return id.toLowerCase();
|
|
1353
|
-
};
|
|
1731
|
+
const emitAngle = (degrees) => Math.round(degrees * 6e4);
|
|
1354
1732
|
/**
|
|
1355
|
-
*
|
|
1733
|
+
* Convert OOXML ST_Angle / ST_FixedAngle scalar (1/60000) to public degrees.
|
|
1356
1734
|
*/
|
|
1357
|
-
const
|
|
1358
|
-
return bytesToHex(sha1(data instanceof ArrayBuffer ? new Uint8Array(data) : typeof data === "string" ? new TextEncoder().encode(data) : data));
|
|
1359
|
-
};
|
|
1735
|
+
const parseAngle = (value) => value / 6e4;
|
|
1360
1736
|
/**
|
|
1361
|
-
*
|
|
1737
|
+
* Converts millimeters to TWIP (twentieths of a point).
|
|
1362
1738
|
*/
|
|
1363
|
-
const
|
|
1364
|
-
//#endregion
|
|
1365
|
-
//#region src/util/mappings.ts
|
|
1739
|
+
const convertMillimetersToTwip = (millimeters) => Math.floor(millimeters / 25.4 * 72 * 20);
|
|
1366
1740
|
/**
|
|
1367
|
-
*
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
*
|
|
1372
|
-
|
|
1373
|
-
|
|
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).
|
|
1750
|
+
*
|
|
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.
|
|
1772
|
+
*/
|
|
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;
|
|
1782
|
+
/**
|
|
1783
|
+
* Parse a UniversalMeasure string into its numeric value and unit.
|
|
1784
|
+
*
|
|
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
|
|
1788
|
+
*
|
|
1789
|
+
* @example
|
|
1790
|
+
* ```typescript
|
|
1791
|
+
* parseUniversalMeasure("2.54cm"); // { value: 2.54, unit: "cm" }
|
|
1792
|
+
* parseUniversalMeasure("-10mm"); // { value: -10, unit: "mm" }
|
|
1793
|
+
* ```
|
|
1794
|
+
*/
|
|
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}'`);
|
|
1800
|
+
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"
|
|
1374
1960
|
*/
|
|
1375
1961
|
/** Invert a Record<K, V> into Record<V, K>. */
|
|
1376
1962
|
function invertMap(map) {
|
|
@@ -1571,219 +2157,74 @@ const xsdTextCaps = bidi({
|
|
|
1571
2157
|
small: "small"
|
|
1572
2158
|
});
|
|
1573
2159
|
//#endregion
|
|
1574
|
-
//#region src/util/
|
|
1575
|
-
/**
|
|
1576
|
-
* OOXML unit conversion utilities.
|
|
1577
|
-
*
|
|
1578
|
-
* @module
|
|
1579
|
-
*/
|
|
1580
|
-
/**
|
|
1581
|
-
* Converts millimeters to TWIP (twentieths of a point).
|
|
1582
|
-
*/
|
|
1583
|
-
const convertMillimetersToTwip = (millimeters) => Math.floor(millimeters / 25.4 * 72 * 20);
|
|
1584
|
-
/**
|
|
1585
|
-
* Converts inches to TWIP (twentieths of a point).
|
|
1586
|
-
*/
|
|
1587
|
-
const convertInchesToTwip = (inches) => Math.floor(inches * 72 * 20);
|
|
1588
|
-
/**
|
|
1589
|
-
* Converts pixels to EMU (96 DPI).
|
|
1590
|
-
*/
|
|
1591
|
-
const convertPixelsToEmu = (pixels) => Math.round(pixels * 9525);
|
|
1592
|
-
/**
|
|
1593
|
-
* Converts EMU to pixels (96 DPI).
|
|
1594
|
-
*
|
|
1595
|
-
* Returns a possibly fractional (sub-pixel) value. The integer rounding that
|
|
1596
|
-
* lived here before permanently discarded sub-pixel precision, which made an
|
|
1597
|
-
* EMU → pixel → EMU round-trip lossy (e.g. 5521960 EMU → 580 px → 5524500 EMU).
|
|
1598
|
-
* Keeping the fraction lets convertPixelsToEmu restore the exact original EMU.
|
|
1599
|
-
* Callers needing an integer pixel for display should Math.round the result.
|
|
1600
|
-
*/
|
|
1601
|
-
const convertEmuToPixels = (emus) => emus / 9525;
|
|
1602
|
-
/**
|
|
1603
|
-
* Converts inches to EMU.
|
|
1604
|
-
*/
|
|
1605
|
-
const convertInchesToEmu = (inches) => Math.round(inches * 914400);
|
|
1606
|
-
/**
|
|
1607
|
-
* Converts EMU to inches.
|
|
1608
|
-
*/
|
|
1609
|
-
const convertEmuToInches = (emus) => emus / 914400;
|
|
1610
|
-
/**
|
|
1611
|
-
* Converts points to EMU.
|
|
1612
|
-
*/
|
|
1613
|
-
const convertPointsToEmu = (points) => Math.round(points * 12700);
|
|
1614
|
-
/**
|
|
1615
|
-
* Converts EMU to points.
|
|
1616
|
-
*/
|
|
1617
|
-
const convertEmuToPoints = (emus) => emus / 12700;
|
|
1618
|
-
/**
|
|
1619
|
-
* Parse a UniversalMeasure string into its numeric value and unit.
|
|
1620
|
-
*
|
|
1621
|
-
* @param measure - A universal measure string like "2.54cm", "-10mm", "1in"
|
|
1622
|
-
* @returns The parsed value and unit
|
|
1623
|
-
* @throws Error if the format is invalid
|
|
1624
|
-
*
|
|
1625
|
-
* @example
|
|
1626
|
-
* ```typescript
|
|
1627
|
-
* parseUniversalMeasure("2.54cm"); // { value: 2.54, unit: "cm" }
|
|
1628
|
-
* parseUniversalMeasure("-10mm"); // { value: -10, unit: "mm" }
|
|
1629
|
-
* ```
|
|
1630
|
-
*/
|
|
1631
|
-
const parseUniversalMeasure = (measure) => {
|
|
1632
|
-
const match = measure.match(/^(-?[0-9]+(?:\.[0-9]+)?)(mm|cm|in|pt|pc|pi|px)$/);
|
|
1633
|
-
if (!match) throw new Error(`Invalid universal measure: '${measure}'`);
|
|
1634
|
-
const [, value, unit] = match;
|
|
1635
|
-
if (value === void 0 || unit === void 0) throw new Error(`Invalid universal measure: '${measure}'`);
|
|
1636
|
-
return {
|
|
1637
|
-
value: parseFloat(value),
|
|
1638
|
-
unit
|
|
1639
|
-
};
|
|
1640
|
-
};
|
|
2160
|
+
//#region src/util/data-type.ts
|
|
1641
2161
|
/**
|
|
1642
|
-
*
|
|
1643
|
-
*
|
|
1644
|
-
* Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc).
|
|
2162
|
+
* Binary input normalization.
|
|
1645
2163
|
*
|
|
1646
|
-
*
|
|
1647
|
-
*
|
|
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.
|
|
1648
2168
|
*
|
|
1649
|
-
* @
|
|
1650
|
-
* ```typescript
|
|
1651
|
-
* convertUniversalMeasureToTwip("1in"); // 1440
|
|
1652
|
-
* convertUniversalMeasureToTwip("2.54cm"); // ~1440 (1 inch)
|
|
1653
|
-
* convertUniversalMeasureToTwip("72pt"); // 1440 (1 inch = 72pt = 1440 twips)
|
|
1654
|
-
* ```
|
|
2169
|
+
* @module
|
|
1655
2170
|
*/
|
|
1656
|
-
const
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
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);
|
|
1666
2186
|
}
|
|
1667
|
-
|
|
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
|
+
}
|
|
2192
|
+
//#endregion
|
|
2193
|
+
//#region src/util/generators.ts
|
|
1668
2194
|
/**
|
|
1669
|
-
*
|
|
1670
|
-
*
|
|
1671
|
-
* If the value is already a number, it is returned as-is (assumed to be in twips).
|
|
1672
|
-
* If the value is a UniversalMeasure string, it is converted to twips.
|
|
1673
|
-
*
|
|
1674
|
-
* Useful for accepting both `number` and `UniversalMeasure` inputs where
|
|
1675
|
-
* the XSD type is a union (e.g., ST_TwipsMeasure, ST_SignedTwipsMeasure).
|
|
1676
|
-
*
|
|
1677
|
-
* @param val - A numeric twip value or a universal measure string
|
|
1678
|
-
* @returns The value in TWIP
|
|
2195
|
+
* Unique ID generation utilities.
|
|
1679
2196
|
*
|
|
1680
|
-
* @
|
|
1681
|
-
* ```typescript
|
|
1682
|
-
* convertToTwip(1440); // 1440 (already twips)
|
|
1683
|
-
* convertToTwip("1in"); // 1440
|
|
1684
|
-
* convertToTwip("2.54cm"); // ~1440
|
|
1685
|
-
* ```
|
|
2197
|
+
* @module
|
|
1686
2198
|
*/
|
|
1687
|
-
const convertToTwip = (val) => typeof val === "string" ? convertUniversalMeasureToTwip(val) : val;
|
|
1688
2199
|
/**
|
|
1689
|
-
*
|
|
1690
|
-
*
|
|
1691
|
-
* Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc).
|
|
1692
|
-
*
|
|
1693
|
-
* @param measure - A universal measure string like "2.54cm", "1in", "12pt"
|
|
1694
|
-
* @returns The value in EMU
|
|
1695
|
-
*
|
|
1696
|
-
* @example
|
|
1697
|
-
* ```typescript
|
|
1698
|
-
* convertUniversalMeasureToEmu("1in"); // 914400
|
|
1699
|
-
* convertUniversalMeasureToEmu("2.54cm"); // 914400
|
|
1700
|
-
* convertUniversalMeasureToEmu("12pt"); // 152400
|
|
1701
|
-
* ```
|
|
2200
|
+
* Creates a unique numeric ID generator with sequential numbering.
|
|
1702
2201
|
*/
|
|
1703
|
-
const
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
case "mm": return Math.round(value * 36e3);
|
|
1707
|
-
case "cm": return Math.round(value * 36e4);
|
|
1708
|
-
case "in": return convertInchesToEmu(value);
|
|
1709
|
-
case "pt": return convertPointsToEmu(value);
|
|
1710
|
-
case "pc":
|
|
1711
|
-
case "pi": return convertPointsToEmu(value * 12);
|
|
1712
|
-
case "px": return convertPixelsToEmu(value);
|
|
1713
|
-
}
|
|
2202
|
+
const uniqueNumericIdCreator = (initial = 0) => {
|
|
2203
|
+
let currentCount = initial;
|
|
2204
|
+
return () => ++currentCount;
|
|
1714
2205
|
};
|
|
2206
|
+
const URL_ALPHABET = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
1715
2207
|
/**
|
|
1716
|
-
*
|
|
1717
|
-
*
|
|
1718
|
-
* Numbers are returned as-is (assumed EMU). Strings are parsed as
|
|
1719
|
-
* UniversalMeasure via {@link convertUniversalMeasureToEmu} — including the
|
|
1720
|
-
* project-only `px` unit (96 DPI). The result is always an EMU number written to
|
|
1721
|
-
* XML, so px never appears verbatim in the document.
|
|
1722
|
-
*
|
|
1723
|
-
* Useful for DrawingML fields where the XSD type is a union (e.g., ST_Coordinate).
|
|
1724
|
-
*
|
|
1725
|
-
* @param val - A numeric EMU value, or a UniversalMeasure string (incl. `${n}px`)
|
|
1726
|
-
* @returns The value in EMU
|
|
1727
|
-
*
|
|
1728
|
-
* @example
|
|
1729
|
-
* ```typescript
|
|
1730
|
-
* convertToEmu(914400); // 914400 (already EMU)
|
|
1731
|
-
* convertToEmu("1in"); // 914400
|
|
1732
|
-
* convertToEmu("2.54cm"); // 914400
|
|
1733
|
-
* convertToEmu("200px"); // 1905000 (200 * 9525)
|
|
1734
|
-
* ```
|
|
1735
|
-
*/
|
|
1736
|
-
const convertToEmu = (val) => typeof val === "string" ? convertUniversalMeasureToEmu(val) : val;
|
|
1737
|
-
/**
|
|
1738
|
-
* Converts a UniversalMeasure string to points (1pt = 1/72 inch).
|
|
1739
|
-
*
|
|
1740
|
-
* Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc),
|
|
1741
|
-
* px (96 DPI).
|
|
2208
|
+
* Generates a unique lowercase alphanumeric ID using crypto.getRandomValues.
|
|
1742
2209
|
*/
|
|
1743
|
-
const
|
|
1744
|
-
const
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
case "pt": return value;
|
|
1750
|
-
case "pc":
|
|
1751
|
-
case "pi": return value * 12;
|
|
1752
|
-
case "px": return value / 96 * 72;
|
|
1753
|
-
}
|
|
2210
|
+
const uniqueId = () => {
|
|
2211
|
+
const bytes = new Uint8Array(21);
|
|
2212
|
+
crypto.getRandomValues(bytes);
|
|
2213
|
+
let id = "";
|
|
2214
|
+
for (const byte of bytes) id += URL_ALPHABET[byte & 63];
|
|
2215
|
+
return id.toLowerCase();
|
|
1754
2216
|
};
|
|
1755
2217
|
/**
|
|
1756
|
-
*
|
|
1757
|
-
*
|
|
1758
|
-
* Numbers are returned as-is (assumed to be in points). Strings are parsed as
|
|
1759
|
-
* UniversalMeasure. Useful for SpreadsheetML fields where a number is points.
|
|
1760
|
-
*/
|
|
1761
|
-
const convertToPt = (val) => typeof val === "string" ? convertUniversalMeasureToPt(val) : val;
|
|
1762
|
-
/**
|
|
1763
|
-
* Converts a UniversalMeasure string to inches.
|
|
1764
|
-
*
|
|
1765
|
-
* Supports units: mm, cm, in, pt, pc, pi, px (96 DPI).
|
|
2218
|
+
* Generates a SHA-1 hash of the provided data.
|
|
1766
2219
|
*/
|
|
1767
|
-
const
|
|
1768
|
-
|
|
1769
|
-
switch (unit) {
|
|
1770
|
-
case "mm": return value / 25.4;
|
|
1771
|
-
case "cm": return value * 10 / 25.4;
|
|
1772
|
-
case "in": return value;
|
|
1773
|
-
case "pt": return value / 72;
|
|
1774
|
-
case "pc":
|
|
1775
|
-
case "pi": return value * 12 / 72;
|
|
1776
|
-
case "px": return value / 96;
|
|
1777
|
-
}
|
|
2220
|
+
const hashedId = (data) => {
|
|
2221
|
+
return bytesToHex(sha1(data instanceof ArrayBuffer ? new Uint8Array(data) : typeof data === "string" ? new TextEncoder().encode(data) : data));
|
|
1778
2222
|
};
|
|
1779
2223
|
/**
|
|
1780
|
-
*
|
|
1781
|
-
*
|
|
1782
|
-
* Numbers are returned as-is (assumed to be in inches). Useful for SpreadsheetML
|
|
1783
|
-
* page-margin fields where a number is inches.
|
|
2224
|
+
* Generates a UUID v4-style unique identifier using crypto.randomUUID.
|
|
1784
2225
|
*/
|
|
1785
|
-
const
|
|
2226
|
+
const uniqueUuid = () => crypto.randomUUID();
|
|
1786
2227
|
//#endregion
|
|
1787
|
-
export {
|
|
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 };
|
|
1788
2229
|
|
|
1789
|
-
//# sourceMappingURL=
|
|
2230
|
+
//# sourceMappingURL=generators-CElPsAhd.mjs.map
|