@office-open/core 0.13.2 → 0.14.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/dist/chart/index.d.mts +1 -1
- package/dist/chart/index.mjs +1 -1
- package/dist/{chart-Bn_McAo-.mjs → chart-D0AdnVLT.mjs} +4 -4
- package/dist/{chart-Bn_McAo-.mjs.map → chart-D0AdnVLT.mjs.map} +1 -1
- package/dist/{data-type-CZMKVaaT.d.mts → data-type-BPt5FhW6.d.mts} +3 -2
- package/dist/{data-type-CZMKVaaT.d.mts.map → data-type-BPt5FhW6.d.mts.map} +1 -1
- package/dist/drawing/index.d.mts +1 -1
- package/dist/drawing/index.mjs +1 -1
- package/dist/{drawing-DJ363Awy.mjs → drawing-BP4zc7an.mjs} +2 -2
- package/dist/{drawing-DJ363Awy.mjs.map → drawing-BP4zc7an.mjs.map} +1 -1
- package/dist/{ext-uri-BR1ouCh3.mjs → ext-uri-5jTDczSP.mjs} +29 -2
- package/dist/ext-uri-5jTDczSP.mjs.map +1 -0
- package/dist/{index-CaNwM5_e.d.mts → index-CRgVoXmj.d.mts} +2 -2
- package/dist/{index-CaNwM5_e.d.mts.map → index-CRgVoXmj.d.mts.map} +1 -1
- package/dist/{index-6_MYd0cg.d.mts → index-DgHJCwlm.d.mts} +4 -4
- package/dist/{index-6_MYd0cg.d.mts.map → index-DgHJCwlm.d.mts.map} +1 -1
- package/dist/{index-BDeoFmTS.d.mts → index-DyrVZEy8.d.mts} +2 -2
- package/dist/{index-BDeoFmTS.d.mts.map → index-DyrVZEy8.d.mts.map} +1 -1
- package/dist/{index-Dg0nIw2S.d.mts → index-Qn5Vcn1O.d.mts} +4 -4
- package/dist/{index-Dg0nIw2S.d.mts.map → index-Qn5Vcn1O.d.mts.map} +1 -1
- package/dist/{index-DOtPArpl.d.mts → index-x3qerhXD.d.mts} +2 -2
- package/dist/{index-DOtPArpl.d.mts.map → index-x3qerhXD.d.mts.map} +1 -1
- package/dist/index.d.mts +12 -9
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +135 -23
- package/dist/index.mjs.map +1 -1
- package/dist/patch/index.d.mts +1 -1
- package/dist/smartart/index.d.mts +1 -1
- package/dist/smartart/index.mjs +1 -1
- package/dist/{smartart-D-8KBdQ_.mjs → smartart-CrVPot34.mjs} +4 -4
- package/dist/{smartart-D-8KBdQ_.mjs.map → smartart-CrVPot34.mjs.map} +1 -1
- package/dist/{style-matrix-B6YSVw6a.mjs → style-matrix-B69960kl.mjs} +2 -2
- package/dist/{style-matrix-B6YSVw6a.mjs.map → style-matrix-B69960kl.mjs.map} +1 -1
- package/dist/theme/index.d.mts +3 -3
- package/dist/theme/index.mjs +2 -2
- package/dist/{theme-BdqG5lmO.mjs → theme-BINSAPMD.mjs} +3 -3
- package/dist/{theme-BdqG5lmO.mjs.map → theme-BINSAPMD.mjs.map} +1 -1
- package/dist/{theme-options-wZX4i_xx.d.mts → theme-options-BfGRKvbu.d.mts} +2 -2
- package/dist/{theme-options-wZX4i_xx.d.mts.map → theme-options-BfGRKvbu.d.mts.map} +1 -1
- package/dist/util/index.d.mts +2 -2
- package/dist/util/index.mjs +3 -3
- package/dist/{util-BGfk-gE0.mjs → util-B3K-9ODR.mjs} +17 -20
- package/dist/util-B3K-9ODR.mjs.map +1 -0
- package/package.json +2 -2
- package/dist/ext-uri-BR1ouCh3.mjs.map +0 -1
- package/dist/util-BGfk-gE0.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util-B3K-9ODR.mjs","names":[],"sources":["../src/opc/zip-native.ts","../src/opc/output.ts","../src/opc/packer.ts","../src/util/compile.ts","../src/util/crypto.ts","../src/util/placeholder.ts"],"sourcesContent":["/**\n * Native ZIP reader/writer with automatic fallback to fflate.\n *\n * `node:zlib` resolves in Node and Bun (via its Node compat layer), giving\n * `deflateRawSync` / `inflateRawSync` for DEFLATE/INFLATE and `zlib.crc32`\n * for CRC-32 — ~2-3x faster than fflate's pure-JS implementation. Browsers\n * and Deno lack a resolvable `node:zlib`, so the dynamic import rejects and\n * packer.ts falls back to fflate. We probe via the import itself rather than\n * `process.versions.node`: core's `shims: true` swaps `process` for a browser\n * stub that drops `versions.node`, which would silently disable native zlib\n * in any package consuming core's polyfilled build.\n *\n * @module\n */\n\nimport type * as ZlibNode from \"node:zlib\";\n\nimport { ZipPassThrough, inflateSync } from \"fflate\";\nimport type { FlateError, Zippable, ZipOptions } from \"fflate\";\n\n// ── CRC-32 lookup table ──\n\nconst CRC_TABLE = new Int32Array(256);\nfor (let i = 0; i < 256; i++) {\n let c = i;\n for (let k = 0; k < 8; k++) c = c & 1 ? (c >>> 1) ^ -306674912 : c >>> 1;\n CRC_TABLE[i] = c;\n}\n\nfunction computeCrc32(data: Uint8Array): number {\n let crc = -1;\n // CRC_TABLE is a fixed 256-entry lookup; the index is masked to [0,255], so the\n // access is guaranteed in-bounds — the `!` is a compile-time narrow, not a runtime check.\n for (const byte of data) {\n crc = CRC_TABLE[(crc ^ byte) & 0xff]! ^ (crc >>> 8);\n }\n return ~crc;\n}\n\n// ── Native zlib detection (Node.js ESM) ──\n\ntype DeflateFn = (data: Uint8Array, level: number) => Uint8Array;\ntype AsyncDeflateFn = (data: Uint8Array, level: number) => Promise<Uint8Array>;\ntype InflateFn = (data: Uint8Array) => Uint8Array;\ntype Crc32Fn = (data: Uint8Array) => number;\n\nlet _nativeDeflate: DeflateFn | undefined;\nlet _nativeDeflateAsync: AsyncDeflateFn | undefined;\nlet _nativeInflate: InflateFn | undefined;\nlet _nativeCrc32: Crc32Fn | undefined;\nlet _zlibModule: typeof ZlibNode | undefined;\n\n// Bun-specific fast path: Bun.deflateSync/Bun.inflateSync emit/accept RAW\n// deflate (bit-identical to deflateRawSync output) but skip the node:zlib\n// compat wrapper — ~10x on the small parts that dominate OPC packages, ~2x\n// on inflate, ~1.3x on large buffers. Probed off globalThis since core ships\n// no bun-types dependency.\nconst bunApi = (\n globalThis as {\n Bun?: {\n deflateSync?: (data: Uint8Array, opts?: { level?: number }) => Uint8Array;\n inflateSync?: (data: Uint8Array) => Uint8Array;\n };\n }\n).Bun;\nif (typeof bunApi?.deflateSync === \"function\") {\n _nativeDeflate = (data: Uint8Array, level: number): Uint8Array =>\n bunApi.deflateSync!(data, { level });\n if (typeof bunApi.inflateSync === \"function\") {\n _nativeInflate = (data: Uint8Array): Uint8Array => bunApi.inflateSync!(data);\n }\n}\n\n// `node:zlib` resolves in Node and Bun (via its Node compat layer); in\n// browsers and Deno the dynamic import rejects, so we fall back to fflate.\n// The import itself is the probe — do NOT gate on `process.versions.node`:\n// core's `shims: true` swaps `process` for a browser stub that drops\n// `versions.node`, which would silently disable native zlib in any package\n// that consumes core's polyfilled build.\ntry {\n // top-level await — ESM standard. Resolves to zlib with deflateRawSync;\n // rejects (or yields a stub without it) on incomplete polyfills.\n const zlib = await import(\"node:zlib\");\n if (typeof zlib.deflateRawSync !== \"function\") throw new Error(\"no native deflate\");\n _zlibModule = zlib;\n if (_nativeDeflate === undefined) {\n _nativeDeflate = (data: Uint8Array, level: number): Uint8Array =>\n zlib.deflateRawSync(data, { level });\n }\n _nativeDeflateAsync = (data: Uint8Array, level: number): Promise<Uint8Array> =>\n new Promise<Uint8Array>((resolve, reject) =>\n zlib.deflateRaw(data, { level }, (err, result) => {\n if (err) reject(err);\n else resolve(result);\n }),\n );\n _nativeCrc32 =\n typeof zlib.crc32 === \"function\" ? (data: Uint8Array) => zlib.crc32(data) : computeCrc32;\n // Inflate is optional (deflate presence doesn't guarantee it), so probe\n // separately — inflateZipEntry only uses the native path when this resolves.\n if (typeof zlib.inflateRawSync === \"function\" && _nativeInflate === undefined) {\n _nativeInflate = (data: Uint8Array): Uint8Array => zlib.inflateRawSync(data);\n }\n} catch {\n // Browser/Deno or Node-like runtime without usable zlib — fflate fallback\n}\n\nexport const hasNativeDeflate = (): boolean => _nativeDeflate !== undefined;\n\n// fflate's async zip entries hand every chunk to a dedicated worker via\n// postMessage with a transfer list — one thread spawn per part (~5-10ms each\n// on Node's worker_threads), which dominates the many-small-parts OPC shape.\n// Bun additionally measured worker teardown lag on back-to-back generations\n// (0.4s → 4.4s per drain on a 130-part deck) and embedded-pool crashes.\n// Where a native zlib resolved (Node/Bun), deflate inline on the main thread;\n// only browsers/Deno keep the workers, where spawn is cheap and off-thread\n// deflate keeps the UI responsive.\n/**\n * True when incremental DEFLATE should run on the main thread instead of\n * fflate's per-entry workers (Node/Bun). See {@link ZipStreamWriter} in\n * packer.ts.\n */\nexport const prefersMainThreadDeflate = (): boolean => _nativeDeflate !== undefined;\n\n/**\n * True under Bun. Used to keep Bun off `nativeZipAsync`-backed paths: its\n * node:zlib compat layer schedules async calls poorly (bench: async ~1/3 of\n * its sync throughput), so fflate main-thread deflate is the better trade.\n */\nexport const isBunRuntime = (): boolean => typeof bunApi?.deflateSync === \"function\";\n\n/**\n * Synchronous native CRC-32 (`zlib.crc32`, Node/Bun only) — undefined where no\n * native zlib resolved (browsers/Deno). Used by media dedup as a fast content\n * key; callers keep their own JS fallback. ~59× faster than a JS hash on\n * 100 MB inputs.\n */\nexport function nativeCrc32(data: Uint8Array): number | undefined {\n return _nativeCrc32?.(data);\n}\n\n// ── LE write helpers ──\n\nfunction wU16(b: Uint8Array, o: number, v: number): void {\n b[o] = v & 0xff;\n b[o + 1] = (v >> 8) & 0xff;\n}\n\nfunction wU32(b: Uint8Array, o: number, v: number): void {\n b[o] = v & 0xff;\n b[o + 1] = (v >> 8) & 0xff;\n b[o + 2] = (v >> 16) & 0xff;\n b[o + 3] = (v >> 24) & 0xff;\n}\n\n// ── Per-entry metadata ──\n\ninterface Entry {\n filename: Uint8Array;\n data: Uint8Array;\n uncompressedSize: number;\n crc: number;\n method: number; // 0 = STORE, 8 = DEFLATE\n localOffset: number;\n}\n\n// ── Phase 1 helpers ──\n\nfunction resolveEntryData(\n raw: Zippable[string],\n defaultLevel: number,\n): { data: Uint8Array; level: number } {\n if (Array.isArray(raw)) {\n return { data: raw[0] as Uint8Array, level: (raw[1] as ZipOptions).level ?? defaultLevel };\n }\n return { data: raw as Uint8Array, level: defaultLevel };\n}\n\nfunction compressOne(\n data: Uint8Array,\n level: number,\n deflate: DeflateFn,\n): { compressed: Uint8Array; method: number } {\n if (level === 0) return { compressed: data, method: 0 };\n const compressed = deflate(data, level);\n if (compressed.length >= data.length) return { compressed: data, method: 0 };\n return { compressed, method: 8 };\n}\n\nasync function compressOneAsync(\n data: Uint8Array,\n level: number,\n deflate: AsyncDeflateFn,\n): Promise<{ compressed: Uint8Array; method: number }> {\n if (level === 0) return { compressed: data, method: 0 };\n const compressed = await deflate(data, level);\n if (compressed.length >= data.length) return { compressed: data, method: 0 };\n return { compressed, method: 8 };\n}\n\n// ── Phase 2+3: calculate sizes + write ZIP buffer ──\n\nfunction writeZipBuffer(entries: Entry[]): Uint8Array {\n let totalSize = 0;\n for (const e of entries) {\n totalSize += 30 + e.filename.length + e.data.length;\n }\n const cdOffset = totalSize;\n let cdSize = 0;\n for (const e of entries) {\n cdSize += 46 + e.filename.length;\n }\n totalSize += cdSize + 22;\n\n const buf = new Uint8Array(totalSize);\n let offset = 0;\n\n // Local file headers + data\n for (const e of entries) {\n e.localOffset = offset;\n wU32(buf, offset, 0x04034b50); // signature\n wU16(buf, offset + 4, 20); // version needed\n wU16(buf, offset + 6, 0); // flags\n wU16(buf, offset + 8, e.method); // compression method\n wU16(buf, offset + 10, 0); // mod time\n wU16(buf, offset + 12, 0); // mod date\n wU32(buf, offset + 14, e.crc);\n wU32(buf, offset + 18, e.data.length); // compressed size\n wU32(buf, offset + 22, e.uncompressedSize);\n wU16(buf, offset + 26, e.filename.length);\n wU16(buf, offset + 28, 0); // extra field length\n offset += 30;\n\n buf.set(e.filename, offset);\n offset += e.filename.length;\n\n buf.set(e.data, offset);\n offset += e.data.length;\n }\n\n // Central directory\n for (const e of entries) {\n wU32(buf, offset, 0x02014b50); // signature\n wU16(buf, offset + 4, 20); // version made by\n wU16(buf, offset + 6, 20); // version needed\n wU16(buf, offset + 8, 0); // flags\n wU16(buf, offset + 10, e.method);\n wU16(buf, offset + 12, 0); // mod time\n wU16(buf, offset + 14, 0); // mod date\n wU32(buf, offset + 16, e.crc);\n wU32(buf, offset + 20, e.data.length);\n wU32(buf, offset + 24, e.uncompressedSize);\n wU16(buf, offset + 28, e.filename.length);\n wU16(buf, offset + 30, 0); // extra field length\n wU16(buf, offset + 32, 0); // comment length\n wU16(buf, offset + 34, 0); // disk number start\n wU16(buf, offset + 36, 0); // internal attrs\n wU32(buf, offset + 38, 0); // external attrs\n wU32(buf, offset + 42, e.localOffset);\n offset += 46;\n\n buf.set(e.filename, offset);\n offset += e.filename.length;\n }\n\n // End of Central Directory Record\n wU32(buf, offset, 0x06054b50);\n wU16(buf, offset + 4, 0); // disk number\n wU16(buf, offset + 6, 0); // CD disk\n wU16(buf, offset + 8, entries.length);\n wU16(buf, offset + 10, entries.length);\n wU32(buf, offset + 12, cdSize);\n wU32(buf, offset + 16, cdOffset);\n wU16(buf, offset + 20, 0); // comment length\n\n return buf;\n}\n\n// ── Public API ──\n\nconst textEncoder = new TextEncoder();\nconst textDecoder = new TextDecoder();\n\nexport function nativeZip(files: Zippable, level: number = 6): Uint8Array {\n if (!_nativeDeflate) throw new Error(\"Native deflate not available\");\n const crc = _nativeCrc32 ?? computeCrc32;\n const entries: Entry[] = [];\n\n for (const key of Object.keys(files)) {\n const raw = files[key];\n if (raw === undefined) continue; // Object.keys guarantees presence; guard narrows the type\n const { data, level: entryLevel } = resolveEntryData(raw, level);\n const c = crc(data);\n const { compressed, method } = compressOne(data, entryLevel, _nativeDeflate);\n entries.push({\n filename: textEncoder.encode(key),\n data: compressed,\n uncompressedSize: data.length,\n crc: c,\n method,\n localOffset: 0,\n });\n }\n\n return writeZipBuffer(entries);\n}\n\nexport async function nativeZipAsync(files: Zippable, level: number = 6): Promise<Uint8Array> {\n const deflateAsync = _nativeDeflateAsync;\n if (!deflateAsync) throw new Error(\"Native async deflate not available\");\n const crc = _nativeCrc32 ?? computeCrc32;\n\n // All entries deflate in parallel — node:zlib async calls run on the libuv\n // thread pool, so a multi-part package compresses in roughly one-deflate\n // wall clock instead of the sum (pool size caps true parallelism; task\n // queueing is cheap relative to the deflate work itself). CRC runs inline\n // on the main thread before each entry's first await.\n const entries = (\n await Promise.all(\n Object.keys(files).map(async (key): Promise<Entry | null> => {\n const raw = files[key];\n if (raw === undefined) return null; // Object.keys guarantees presence; guard narrows the type\n const { data, level: entryLevel } = resolveEntryData(raw, level);\n const c = crc(data);\n const { compressed, method } = await compressOneAsync(data, entryLevel, deflateAsync);\n return {\n filename: textEncoder.encode(key),\n data: compressed,\n uncompressedSize: data.length,\n crc: c,\n method,\n localOffset: 0,\n };\n }),\n )\n ).filter((e): e is Entry => e !== null);\n\n return writeZipBuffer(entries);\n}\n\n// Fixed-size chunks fed to the ReadableStream — large enough to amortize the\n// per-enqueue cost, small enough to keep an interactive consumer's first read.\nconst STREAM_CHUNK_SIZE = 1 << 16;\n\n/**\n * Streaming counterpart of {@link nativeZipAsync}: compresses on the libuv\n * thread pool, then emits the finished archive through a `ReadableStream` in\n * fixed-size chunks. Node only — Bun and browsers keep fflate's incremental\n * path (see {@link prefersMainThreadDeflate}). The memory shape matches the\n * fflate stream (entries are fully resident post-compile either way); the win\n * is dropping fflate's per-entry worker spawn, which costs milliseconds per\n * part on Node's worker_threads and dominates small-package streams.\n */\nexport function nativeZipStream(files: Zippable, level: number = 6): ReadableStream<Uint8Array> {\n return new ReadableStream<Uint8Array>({\n async start(controller) {\n try {\n const buf = await nativeZipAsync(files, level);\n for (let o = 0; o < buf.length; o += STREAM_CHUNK_SIZE) {\n controller.enqueue(buf.subarray(o, Math.min(o + STREAM_CHUNK_SIZE, buf.length)));\n }\n controller.close();\n } catch (err) {\n controller.error(err instanceof Error ? err : new Error(String(err)));\n }\n },\n });\n}\n\n// ── LE read helpers (ZIP parsing) ──\n\nfunction rU16(b: Uint8Array, o: number): number {\n return b[o]! | (b[o + 1]! << 8);\n}\n\nfunction rU32(b: Uint8Array, o: number): number {\n return (b[o]! | (b[o + 1]! << 8) | (b[o + 2]! << 16) | (b[o + 3]! << 24)) >>> 0;\n}\n\n// ── ZIP central-directory parsing ──\n\nconst EOCD_MAGIC = 0x06054b50;\nconst CD_MAGIC = 0x02014b50;\n\n/** One archive entry as resolved from the central directory. */\nexport interface ZipEntryMeta {\n name: string;\n method: number;\n compSize: number;\n crc: number;\n dataStart: number;\n}\n\n/** Locate the End-of-Central-Directory record (within a 64 KB comment window). */\nfunction findEocd(b: Uint8Array): number {\n const min = Math.max(0, b.length - 65557); // 22-byte EOCD + up to 65535-byte comment\n for (let i = b.length - 22; i >= min; i--) {\n if (rU32(b, i) === EOCD_MAGIC) return i;\n }\n throw new Error(\"ZIP EOCD record not found\");\n}\n\n/** Walk the central directory and resolve each entry's payload offset. */\nexport function readCentralDirectory(buf: Uint8Array): ZipEntryMeta[] {\n const eocd = findEocd(buf);\n const count = rU16(buf, eocd + 10);\n const cdOffset = rU32(buf, eocd + 16);\n const entries: ZipEntryMeta[] = [];\n let p = cdOffset;\n for (let i = 0; i < count; i++) {\n if (rU32(buf, p) !== CD_MAGIC) throw new Error(`ZIP central directory corrupt at offset ${p}`);\n const method = rU16(buf, p + 10);\n const crc = rU32(buf, p + 16);\n const compSize = rU32(buf, p + 20);\n const nameLen = rU16(buf, p + 28);\n const extraLen = rU16(buf, p + 30);\n const cmtLen = rU16(buf, p + 32);\n const localOff = rU32(buf, p + 42);\n // Uint8Array.toString() yields \"120,46,...\" (comma-joined bytes), not the\n // UTF-8 string — decode explicitly so entry names are real paths.\n const name = textDecoder.decode(buf.subarray(p + 46, p + 46 + nameLen));\n // The local header carries its own name/extra lengths, which can differ\n // from the CD's; read them to locate the entry's payload precisely.\n const lNameLen = rU16(buf, localOff + 26);\n const lExtraLen = rU16(buf, localOff + 28);\n entries.push({\n name,\n method,\n compSize,\n crc,\n dataStart: localOff + 30 + lNameLen + lExtraLen,\n });\n p += 46 + nameLen + extraLen + cmtLen;\n }\n return entries;\n}\n\n/**\n * Inflate a single entry resolved by {@link readCentralDirectory}, without\n * materializing the rest of the archive. Mirrors the per-entry work of the\n * former eager `nativeUnzip`: native zlib inflate + CRC-32 where available\n * (Node/Bun), fflate `inflateSync` elsewhere (no CRC check — fflate parity).\n * STORE entries are copied out of the source buffer.\n */\nexport function inflateZipEntry(buf: Uint8Array, entry: ZipEntryMeta): Uint8Array {\n const raw = buf.subarray(entry.dataStart, entry.dataStart + entry.compSize);\n if (entry.method === 0) return raw.slice();\n if (_nativeInflate) {\n const dec = _nativeInflate(raw);\n // >>> 0 normalizes the signed CRC_TABLE accumulation against zlib's unsigned crc32.\n if ((_nativeCrc32 ?? computeCrc32)(dec) >>> 0 !== entry.crc)\n throw new Error(`ZIP CRC-32 mismatch: ${entry.name}`);\n return dec;\n }\n return inflateSync(raw);\n}\n\n// ── Native streaming DEFLATE entry ──\n\n/**\n * Streaming DEFLATE ZIP entry backed by `zlib.createDeflateRaw` instead of\n * fflate's JS engine or per-entry worker — Node only (constructor throws when\n * no native zlib resolved; callers pick the fflate entries elsewhere).\n *\n * Implements fflate's Zip entry contract by subclassing `ZipPassThrough` and\n * overriding `process` — fflate's documented subclassing point — to feed a\n * libuv-pool deflate stream: zero thread spawn (AsyncZipDeflate costs ~5-10ms\n * per part on worker_threads, dominating the many-small-parts OPC shape) while\n * compression still runs off the main thread, so chunked generation overlaps\n * with deflate. `compression`/`flag` mirror what ZipDeflate sets (flag = the\n * same deflate-level hint bits fflate computes), which Zip reads for the\n * local header.\n */\nexport class NativeZipDeflate extends ZipPassThrough {\n /** General-purpose flag bits, mirroring ZipDeflate's level hint. */\n readonly flag: 0 | 1 | 2 | 3;\n private readonly z: ZlibNode.DeflateRaw;\n\n constructor(filename: string, opts?: { level?: ZipOptions[\"level\"] }) {\n super(filename);\n if (_zlibModule === undefined) throw new Error(\"Native deflate not available\");\n const level = opts?.level;\n this.flag = level === 1 ? 3 : level !== undefined && level < 6 ? 2 : level === 9 ? 1 : 0;\n this.compression = 8;\n this.z = _zlibModule.createDeflateRaw({ level });\n // 'data' arrives on the microtask queue after each libuv-pool flush; Zip\n // buffers entry output until its own ordering pass, so async ondata is\n // contract-legal (AsyncZipDeflate delivers the same way). 'end' fires\n // after the final 'data', closing the entry with an empty final chunk.\n // zlib chunks are never shared-memory buffers; the cast only widens the\n // declared ArrayBufferLike to fflate's ArrayBuffer parameter type.\n this.z.on(\"data\", (dat: Uint8Array) =>\n this.ondata(null, dat as Uint8Array<ArrayBuffer>, false),\n );\n this.z.on(\"error\", (err: Error) => this.ondata(err as FlateError, new Uint8Array(0), true));\n this.z.on(\"end\", () => this.ondata(null, new Uint8Array(0), true));\n }\n\n /** Feed a source chunk; `final` ends the deflate stream. */\n protected process(chunk: Uint8Array<ArrayBuffer>, final: boolean): void {\n // write() backpressure is ignored on purpose: the producer is a\n // synchronous serialize loop, and zlib's internal buffer is bounded by\n // how fast the pool drains — the same regime the worker path had.\n this.z.write(chunk);\n if (final) this.z.end();\n else this.z.flush(); // Z_SYNC_FLUSH — emit each chunk's bytes promptly\n }\n}\n","/**\n * Output type definitions for OOXML document export.\n *\n * @module\n */\n\nimport { strFromU8 } from \"fflate\";\n\nimport { encodeBase64 } from \"../util/base64\";\n\nexport interface OutputByType {\n base64: string;\n string: string;\n text: string;\n binarystring: string;\n array: readonly number[];\n uint8array: Uint8Array;\n arraybuffer: ArrayBuffer;\n blob: Blob;\n nodebuffer: Buffer;\n}\n\nexport type OutputType = keyof OutputByType;\n\n/* V8 ignore start */\nexport const OoxmlMimeType = {\n DOCX: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n PPTX: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n XLSX: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n} as const;\n\nexport const convertOutput = <T extends OutputType>(\n data: Uint8Array,\n type: T,\n mimeType: string = OoxmlMimeType.DOCX,\n): OutputByType[T] => {\n switch (type) {\n case \"nodebuffer\":\n // Zero-copy: wrap the zip output's underlying ArrayBuffer as a Buffer\n // view instead of copying it (~11MB for an image-heavy file) on every\n // generate(). Safe because the source buffer is freshly allocated and\n // never mutated after this point.\n return Buffer.from(data.buffer, data.byteOffset, data.byteLength) as OutputByType[T];\n case \"blob\":\n return new Blob(\n [(data.buffer as ArrayBuffer).slice(data.byteOffset, data.byteOffset + data.byteLength)],\n { type: mimeType },\n ) as OutputByType[T];\n case \"arraybuffer\":\n return data.buffer.slice(\n data.byteOffset,\n data.byteOffset + data.byteLength,\n ) as OutputByType[T];\n case \"uint8array\":\n return data as OutputByType[T];\n case \"base64\":\n return encodeBase64(data) as OutputByType[T];\n case \"string\":\n case \"text\":\n case \"binarystring\":\n return strFromU8(data, true) as OutputByType[T];\n case \"array\":\n return [...data] as unknown as OutputByType[T];\n /* V8 ignore next */\n default:\n return data as unknown as OutputByType[T];\n }\n};\n/* V8 ignore stop */\n","/**\n * Shared packer utilities for OOXML document generation.\n *\n * @module\n */\n\nimport {\n type AsyncZippable,\n type ZipOptions,\n type Zippable,\n AsyncZipDeflate,\n Zip,\n ZipDeflate,\n ZipPassThrough,\n zip,\n zipSync,\n} from \"fflate\";\n\nimport { convertOutput } from \"./output\";\nimport type { OutputByType, OutputType } from \"./output\";\nimport {\n hasNativeDeflate,\n isBunRuntime,\n NativeZipDeflate,\n nativeZip,\n nativeZipAsync,\n nativeZipStream,\n prefersMainThreadDeflate,\n} from \"./zip-native\";\n\nexport type { Zippable, ZipOptions } from \"fflate\";\nexport { strFromU8, unzipSync, zipSync } from \"fflate\";\n\nexport interface XmlifyedFile {\n path: string;\n data: string | Uint8Array;\n}\n\n/** Default DEFLATE level for XML entries (SuperFast, matching MS Office). */\nexport const ZIP_DEFLATE_LEVEL = 1;\n\n/** Default DEFLATE level for compressible media (EMF/WMF/BMP/TIFF/SVG). MS\n * Office uses CompressionOption.Normal (~zlib 6); SuperFast (1) inflates EMF\n * output ~15% (measured against a real Office-generated package). */\nexport const ZIP_MEDIA_LEVEL = 6;\n\n/** Level for already-compressed media — STORE (no compression). */\nexport const ZIP_STORED_LEVEL = 0;\n\n/**\n * Media formats already compressed internally (DEFLATE for PNG, DCT for JPEG,\n * LZW for GIF; video/audio containers carry their own codec streams).\n * Re-compressing via zip DEFLATE wastes CPU and often inflates the data, so\n * MS Office STORE-s these (CompressionOption.NotCompressed → zip method 0).\n * Everything else (EMF/WMF/BMP/TIFF/SVG/WAV…) is compressible → DEFLATE —\n * measured on a real Office package, EMF at zlib level 6 matches Office\n * output where SuperFast inflates ~15%.\n */\nconst PRECOMPRESSED_MEDIA_EXT = new Set([\n \"jpg\",\n \"jpeg\",\n \"png\",\n \"gif\",\n \"mp4\",\n \"mov\",\n \"wmv\",\n \"mpg\",\n \"mpeg\",\n \"mp3\",\n \"wma\",\n \"aac\",\n]);\n\n/**\n * Resolve the ZIP level for a media entry by file-name extension, matching MS\n * Office: already-compressed raster formats → STORE (0), everything else →\n * DEFLATE (`mediaLevel`, default Normal). A `compression.media` override\n * therefore applies only to compressible formats, never forcing DEFLATE onto\n * pre-compressed assets.\n */\nexport const levelForMediaName = (fileName: string, mediaLevel: number): number => {\n const dot = fileName.lastIndexOf(\".\");\n const ext = dot < 0 ? \"\" : fileName.slice(dot + 1).toLowerCase();\n return PRECOMPRESSED_MEDIA_EXT.has(ext) ? ZIP_STORED_LEVEL : mediaLevel;\n};\n\n/** Compression options for ZIP output (zlib levels 0-9, matching fflate). */\nexport interface CompressionOptions {\n /** DEFLATE level for XML files. Default: 1 (SuperFast, matching MS Office). */\n xml?: number;\n /**\n * DEFLATE level for compressible media (EMF/WMF/BMP/TIFF/…). Already-compressed\n * formats (PNG/JPEG/GIF) are always STOREd regardless, matching MS Office.\n * Default: 6 (Normal, matching MS Office for EMF/WMF).\n */\n media?: number;\n}\n\n/** Options for Packer output methods. */\nexport interface PackerOptions<T extends OutputType = \"nodebuffer\"> {\n /** Output format. Defaults to `\"nodebuffer\"` (Node.js Buffer). */\n type?: T;\n /** Custom XML/ZIP file overrides. */\n overrides?: XmlifyedFile[];\n /** Compression levels for ZIP entries. */\n compression?: CompressionOptions;\n}\n\n/**\n * Asynchronously compress files and convert to the requested output format.\n *\n * Where a native zlib resolved (Node/Bun), entries deflate in parallel on the\n * libuv thread pool; elsewhere fflate compresses off the main thread.\n * XML entries use DEFLATE level 1 (SuperFast) by default. Media entries are\n * split by type, matching MS Office: already-compressed formats (PNG/JPEG/GIF)\n * are STOREd, everything else uses the `media` level (default Normal).\n * Set `{ media: ZIP_STORED_LEVEL }` to STORE all compressible media too.\n */\nexport const zipAndConvert = async <T extends OutputType>(\n files: Zippable,\n type: T,\n mimeType: string,\n level: number = ZIP_DEFLATE_LEVEL,\n): Promise<OutputByType[T]> => {\n const zipped = hasNativeDeflate()\n ? await nativeZipAsync(files, level)\n : await new Promise<Uint8Array>((resolve, reject) => {\n zip(\n files as AsyncZippable,\n { level: level as ZipOptions[\"level\"], consume: true },\n (err, data) => {\n if (err) reject(err);\n else resolve(data);\n },\n );\n });\n return convertOutput(zipped, type, mimeType);\n};\n\n/**\n * Synchronously compress files and convert to the requested output format.\n *\n * Uses synchronous DEFLATE compression for maximum throughput.\n * Blocks the event loop — prefer {@link zipAndConvert} in server contexts.\n */\nexport const zipSyncAndConvert = <T extends OutputType>(\n files: Zippable,\n type: T,\n mimeType: string,\n level: number = ZIP_DEFLATE_LEVEL,\n): OutputByType[T] => {\n const zipped = hasNativeDeflate()\n ? nativeZip(files, level)\n : zipSync(files, { level: level as ZipOptions[\"level\"] });\n return convertOutput(zipped, type, mimeType);\n};\n\n/**\n * Create a `ReadableStream<Uint8Array>` from compressed file entries.\n *\n * Uses fflate's `AsyncZipDeflate` for non-blocking DEFLATE compression.\n * `STORED` entries (media) pass through synchronously.\n * Works in both Node.js and browsers (Web Streams API).\n */\nexport const createZipStream = (\n files: Zippable,\n defaultLevel: number = ZIP_DEFLATE_LEVEL,\n): ReadableStream<Uint8Array> => {\n // Node's native zlib compresses the entries in parallel on the libuv pool —\n // vastly faster than fflate's per-entry workers, whose spawn cost dominates\n // small packages (~20 vs ~2700 ops/s on a 12-part stream, measured). Bun\n // stays on fflate main-thread deflate (see isBunRuntime), browsers/Deno on\n // the worker paths below.\n if (hasNativeDeflate() && !isBunRuntime()) {\n return nativeZipStream(files, defaultLevel);\n }\n // Remaining runtimes: Bun deflates on the main thread (its worker teardown\n // lags creation, accumulating cost across back-to-back generations — see\n // prefersMainThreadDeflate); browsers/Deno keep AsyncZipDeflate, where web\n // workers are cheap to spawn and deflate off the main thread for real.\n const mainThread = prefersMainThreadDeflate();\n return new ReadableStream<Uint8Array>({\n start(controller) {\n try {\n const zip = new Zip((err, chunk, _final) => {\n if (err) {\n controller.error(err);\n return;\n }\n controller.enqueue(chunk);\n if (_final) {\n controller.close();\n }\n });\n\n for (const [name, data] of Object.entries(files)) {\n const raw = Array.isArray(data) ? (data[0] as Uint8Array) : (data as Uint8Array);\n const level = Array.isArray(data)\n ? ((data[1] as ZipOptions).level ?? defaultLevel)\n : defaultLevel;\n const workerPath = level !== ZIP_STORED_LEVEL && !mainThread;\n const entry =\n level === ZIP_STORED_LEVEL\n ? new ZipPassThrough(name)\n : workerPath\n ? new AsyncZipDeflate(name, { level: level as ZipOptions[\"level\"] })\n : new ZipDeflate(name, { level: level as ZipOptions[\"level\"] });\n zip.add(entry);\n // AsyncZipDeflate transfers each pushed buffer to its worker\n // (postMessage move semantics), detaching the caller's view —\n // regenerating from the same files would push an already-detached\n // buffer and throw DataCloneError. Only the worker entry needs the\n // copy; pass-through and main-thread entries keep zero-copy.\n entry.push(workerPath ? raw.slice() : raw, true);\n }\n\n zip.end();\n } catch (err) {\n controller.error(err instanceof Error ? err : new Error(String(err)));\n }\n },\n });\n};\n\n// ── Streaming ZIP writer ──\n\n/**\n * Incremental sink for one ZIP part. Feed chunks as they are produced; the\n * entry's local header is emitted on {@link ZipStreamWriter.addPart} and the\n * trailing CRC/sizes on {@link end} — the part's full content never has to\n * exist in memory at once.\n */\nexport interface ZipPartSink {\n /** Append a chunk to the part. */\n push(chunk: Uint8Array): void;\n /** Finalize the part, optionally with a final chunk. Must be called before adding the next one. */\n end(lastChunk?: Uint8Array): void;\n}\n\n/**\n * Incremental ZIP archive writer over fflate's streaming `Zip` — parts are\n * added and completed one at a time; compressed output flows to `ondata` as\n * it is produced. This is the constant-memory counterpart to\n * {@link createZipStream} (which requires the complete `Zippable` up front):\n * serialize each part chunk-wise into the returned sink instead of building\n * the full part string.\n *\n * Parts must be added in order — `[Content_Types].xml` first per OPC. The\n * whole archive finishes when {@link ZipStreamWriter.end} is called.\n */\nexport class ZipStreamWriter {\n private readonly zip: Zip;\n private current: AsyncZipDeflate | NativeZipDeflate | ZipDeflate | ZipPassThrough | undefined;\n // Node streams each part through a native zlib DeflateRaw on the libuv pool\n // (no spawn, compression overlaps with chunk production). Bun deflates on\n // the main thread; browsers/Deno use fflate's per-entry workers.\n private readonly nativeEntry = hasNativeDeflate() && !isBunRuntime();\n private readonly mainThread = prefersMainThreadDeflate();\n\n constructor(\n ondata: (err: Error | null, chunk: Uint8Array, final: boolean) => void,\n private readonly defaultLevel: number = ZIP_DEFLATE_LEVEL,\n ) {\n this.zip = new Zip(ondata);\n }\n\n /** Add a part and return its incremental sink. `end()` the previous first. */\n addPart(name: string, level: number = this.defaultLevel): ZipPartSink {\n if (this.current) throw new Error(`ZipStreamWriter: previous part not finalized`);\n const deflatePath = level !== ZIP_STORED_LEVEL;\n const workerPath = deflatePath && !this.mainThread;\n const entry = !deflatePath\n ? new ZipPassThrough(name)\n : this.nativeEntry\n ? new NativeZipDeflate(name, { level: level as ZipOptions[\"level\"] })\n : workerPath\n ? new AsyncZipDeflate(name, { level: level as ZipOptions[\"level\"] })\n : new ZipDeflate(name, { level: level as ZipOptions[\"level\"] });\n // AsyncZipDeflate hands chunks to a worker; ondata delivery is asynchronous,\n // so ordering between parts is preserved by fflate's internal queue. The\n // worker transfer-detaches every chunk it is handed, so sinks receive\n // copies — a caller-held buffer must survive repeated generations.\n this.zip.add(entry);\n this.current = entry;\n return {\n push: (chunk) => entry.push(workerPath ? chunk.slice() : chunk, false),\n end: (lastChunk?: Uint8Array) => {\n entry.push((workerPath ? lastChunk?.slice() : lastChunk) ?? new Uint8Array(0), true);\n this.current = undefined;\n },\n };\n }\n\n /** Finish the archive (central directory + EOCD). */\n end(): void {\n if (this.current) throw new Error(`ZipStreamWriter: unclosed part at end()`);\n this.zip.end();\n }\n}\n\n// ── Factory function ──\n\n/**\n * Compile function provided by each package to convert a file object into a Zippable map.\n */\nexport type CompileFn<TFile> = (\n file: TFile,\n overrides?: XmlifyedFile[],\n mediaLevel?: number,\n) => Zippable;\n\n/**\n * Packer interface returned by {@link createPacker}.\n *\n * Async methods use fflate Web Workers for non-blocking compression.\n * Sync methods use synchronous compression for maximum throughput in\n * CLI scripts and build tools.\n */\nexport interface Packer<TFile> {\n /** Compile file to Zippable map (synchronous). */\n compile: CompileFn<TFile>;\n\n /** Generic async output — returns the requested OutputType. */\n pack<T extends OutputType = \"nodebuffer\">(\n file: TFile,\n options?: PackerOptions<T>,\n ): Promise<OutputByType[T]>;\n /** Generic sync output — returns the requested OutputType. */\n packSync<T extends OutputType = \"nodebuffer\">(\n file: TFile,\n options?: PackerOptions<T>,\n ): OutputByType[T];\n\n /** Async → `Promise<Uint8Array>` (like `Response.bytes()`). */\n toBytes(file: TFile, options?: PackerOptions): Promise<Uint8Array>;\n /** Sync → `Uint8Array`. */\n toBytesSync(file: TFile, options?: PackerOptions): Uint8Array;\n\n /** Async → `Promise<string>` (raw ZIP content as string). */\n toString(file: TFile, options?: PackerOptions): Promise<string>;\n /** Sync → `string`. */\n toStringSync(file: TFile, options?: PackerOptions): string;\n\n /** Async → `Promise<Buffer>` (Node.js). */\n toBuffer(file: TFile, options?: PackerOptions): Promise<Buffer>;\n /** Sync → `Buffer` (Node.js). */\n toBufferSync(file: TFile, options?: PackerOptions): Buffer;\n\n /** Async → `Promise<string>` (base64-encoded). */\n toBase64(file: TFile, options?: PackerOptions): Promise<string>;\n /** Sync → `string` (base64-encoded). */\n toBase64Sync(file: TFile, options?: PackerOptions): string;\n\n /** Async → `Promise<Blob>` (browser). */\n toBlob(file: TFile, options?: PackerOptions): Promise<Blob>;\n /** Sync → `Blob`. */\n toBlobSync(file: TFile, options?: PackerOptions): Blob;\n\n /** Async → `Promise<ArrayBuffer>`. */\n toArrayBuffer(file: TFile, options?: PackerOptions): Promise<ArrayBuffer>;\n /** Sync → `ArrayBuffer`. */\n toArrayBufferSync(file: TFile, options?: PackerOptions): ArrayBuffer;\n\n /** Streaming output via `ReadableStream<Uint8Array>` (cross-platform, uses Web Workers). */\n toStream(file: TFile, options?: PackerOptions): ReadableStream<Uint8Array>;\n}\n\n/**\n * Create a Packer object with all output format methods.\n *\n * Centralises the ZIP → convert pipeline and the streaming implementation\n * so that each OOXML package only needs to provide a `compile` function and\n * a MIME type.\n */\nexport const createPacker = <TFile>(options: {\n compile: CompileFn<TFile>;\n mimeType: string;\n}): Packer<TFile> => {\n const { compile, mimeType } = options;\n\n const pack = async <T extends OutputType = \"nodebuffer\">(\n file: TFile,\n opts?: PackerOptions<T>,\n ): Promise<OutputByType[T]> => {\n const type = opts?.type ?? (\"nodebuffer\" as T);\n const files = compile(file, opts?.overrides ?? [], opts?.compression?.media ?? ZIP_MEDIA_LEVEL);\n return zipAndConvert(files, type, mimeType, opts?.compression?.xml ?? ZIP_DEFLATE_LEVEL);\n };\n\n const toBytes = (file: TFile, opts?: PackerOptions) =>\n pack(file, { ...opts, type: \"uint8array\" });\n const toString = (file: TFile, opts?: PackerOptions) => pack(file, { ...opts, type: \"string\" });\n const toBuffer = (file: TFile, opts?: PackerOptions) =>\n pack(file, { ...opts, type: \"nodebuffer\" });\n const toBase64 = (file: TFile, opts?: PackerOptions) => pack(file, { ...opts, type: \"base64\" });\n const toBlob = (file: TFile, opts?: PackerOptions) => pack(file, { ...opts, type: \"blob\" });\n const toArrayBuffer = (file: TFile, opts?: PackerOptions) =>\n pack(file, { ...opts, type: \"arraybuffer\" });\n\n // ── Sync methods (zipSync, maximum throughput) ──\n\n const packSync = <T extends OutputType = \"nodebuffer\">(\n file: TFile,\n opts?: PackerOptions<T>,\n ): OutputByType[T] => {\n const type = opts?.type ?? (\"nodebuffer\" as T);\n const files = compile(file, opts?.overrides ?? [], opts?.compression?.media ?? ZIP_MEDIA_LEVEL);\n return zipSyncAndConvert(files, type, mimeType, opts?.compression?.xml ?? ZIP_DEFLATE_LEVEL);\n };\n\n const toBytesSync = (file: TFile, opts?: PackerOptions) =>\n packSync(file, { ...opts, type: \"uint8array\" });\n const toStringSync = (file: TFile, opts?: PackerOptions) =>\n packSync(file, { ...opts, type: \"string\" });\n const toBufferSync = (file: TFile, opts?: PackerOptions) =>\n packSync(file, { ...opts, type: \"nodebuffer\" });\n const toBase64Sync = (file: TFile, opts?: PackerOptions) =>\n packSync(file, { ...opts, type: \"base64\" });\n const toBlobSync = (file: TFile, opts?: PackerOptions) =>\n packSync(file, { ...opts, type: \"blob\" });\n const toArrayBufferSync = (file: TFile, opts?: PackerOptions) =>\n packSync(file, { ...opts, type: \"arraybuffer\" });\n\n // ── Stream ──\n\n const toStream = (file: TFile, opts?: PackerOptions) => {\n const mediaLevel = opts?.compression?.media ?? ZIP_MEDIA_LEVEL;\n let files: Zippable;\n try {\n files = compile(file, opts?.overrides ?? [], mediaLevel);\n } catch (err) {\n return new ReadableStream<Uint8Array>({\n start(controller) {\n controller.error(err instanceof Error ? err : new Error(String(err)));\n },\n });\n }\n return createZipStream(files, opts?.compression?.xml ?? ZIP_DEFLATE_LEVEL);\n };\n\n return {\n compile,\n pack,\n packSync,\n toBytes,\n toBytesSync,\n toString,\n toStringSync,\n toBuffer,\n toBufferSync,\n toBase64,\n toBase64Sync,\n toBlob,\n toBlobSync,\n toArrayBuffer,\n toArrayBufferSync,\n toStream,\n };\n};\n","/**\n * Shared compiler utilities for OOXML document generation.\n *\n * @module\n */\n\nimport { levelForMediaName } from \"../opc/packer\";\nimport type { XmlifyedFile, ZipOptions, Zippable } from \"../opc/packer\";\n\n/** Reusable TextEncoder instance (stateless, safe to share). */\nconst encoder = new TextEncoder();\n\nexport type XmlifyedFileEntry = XmlifyedFile | readonly XmlifyedFile[] | undefined;\n\n/** Add one binary ZIP entry using the shared media compression policy. */\nexport function addBinaryFile(\n files: Zippable,\n path: string,\n data: Uint8Array,\n mediaLevel: number,\n): void {\n files[path] = [data, { level: levelForMediaName(path, mediaLevel) as ZipOptions[\"level\"] }];\n}\n\n/**\n * Convert XML files, overrides, and media into a Zippable structure.\n *\n * Mapping values may be optional arrays so package compilers can pass their\n * natural part mappings without reimplementing flattening and byte encoding.\n */\nexport function compileMapping<T extends object>(\n mapping: T & { [K in keyof T]: XmlifyedFileEntry },\n overrides?: readonly XmlifyedFile[],\n media?: readonly { data: Uint8Array; path: string }[],\n mediaLevel: number = 0,\n): Zippable {\n const files: Zippable = {};\n for (const entry of Object.values(mapping) as XmlifyedFileEntry[]) {\n if (entry === undefined) continue;\n const entries = Array.isArray(entry) ? entry : [entry];\n for (const file of entries) {\n files[file.path] = typeof file.data === \"string\" ? encoder.encode(file.data) : file.data;\n }\n }\n for (const override of overrides ?? []) {\n files[override.path] =\n typeof override.data === \"string\" ? encoder.encode(override.data) : override.data;\n }\n for (const file of media ?? []) {\n addBinaryFile(files, file.path, file.data, mediaLevel);\n }\n return files;\n}\n","/**\n * Password hashing utilities for OOXML document protection.\n *\n * Implements ECMA-376 Agile Encryption password derivation.\n * Passwords are encoded as UTF-16LE per the OOXML specification.\n *\n * Uses `@noble`/hashes for SHA-512 — audited, cross-platform,\n * and comparable in speed to node:crypto for this workload.\n *\n * @module\n */\n\nimport { sha512 } from \"@noble/hashes/sha2.js\";\n\nimport { encodeBase64 } from \"./base64\";\n\n// ── Helpers ──\n\nfunction utf16leEncode(str: string): Uint8Array {\n const bytes = new Uint8Array(str.length * 2);\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n bytes[i * 2] = code & 0xff;\n bytes[i * 2 + 1] = (code >> 8) & 0xff;\n }\n return bytes;\n}\n\n// ── Public API ──\n\nexport function randomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < length; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n return bytes;\n}\n\n/**\n * Computes the ECMA-376 Agile Encryption hash for a password.\n *\n * Algorithm: SHA-512(salt + UTF-16LE(password)), then iterate\n * SHA-512(hash + i.toUint32LE()) spinCount times.\n */\nexport function hashPasswordAgile(password: string, salt: Uint8Array, spinCount: number): string {\n const pwBytes = utf16leEncode(password);\n\n // h = SHA-512(salt + password_utf16le)\n const initial = new Uint8Array(salt.length + pwBytes.length);\n initial.set(salt, 0);\n initial.set(pwBytes, salt.length);\n\n let h = sha512(initial);\n // SHA-512 digest is a fixed 64 bytes, so the counter buffer is allocated\n // once and only the 4 little-endian counter bytes are rewritten per spin.\n const buf = new Uint8Array(h.length + 4);\n for (let i = 0; i < spinCount; i++) {\n buf.set(h, 0);\n buf[h.length] = i & 0xff;\n buf[h.length + 1] = (i >> 8) & 0xff;\n buf[h.length + 2] = (i >> 16) & 0xff;\n buf[h.length + 3] = (i >> 24) & 0xff;\n h = sha512(buf);\n }\n\n return encodeBase64(new Uint8Array(h));\n}\n\n/**\n * Derives a password hash for OOXML document protection.\n *\n * Returns base64-encoded hashValue, saltValue, spinCount, and algorithmName\n * suitable for direct use in document protection options.\n */\nexport function derivePasswordHash(\n password: string,\n spinCount = 100000,\n): { hashValue: string; saltValue: string; spinCount: number; algorithmName: string } {\n const salt = randomBytes(16);\n const hashValue = hashPasswordAgile(password, salt, spinCount);\n return {\n hashValue,\n saltValue: encodeBase64(salt),\n spinCount,\n algorithmName: \"SHA-512\",\n };\n}\n","/**\n * Placeholder detection and replacement utilities for compiler post-processing.\n *\n * Both DOCX and PPTX compilers use placeholder tokens (e.g. `{chart:key}`)\n * in XML strings to defer relationship ID assignment. This module provides\n * fast pre-check utilities and shared replacement functions.\n */\n\nexport type IdFormat = \"rId\" | \"plain\";\n\nexport const formatId = (offset: number, index: number, style: IdFormat): string =>\n style === \"rId\" ? `rId${offset + index}` : `${offset + index}`;\n\n/**\n * Find the next `{key}` placeholder at/after `from`. Returns `[open, close]`\n * brace indices, or undefined when none remain. Mirrors the semantics of\n * `/\\{([^{}]+)\\}/g`: empty keys and keys containing `{` are skipped (the scan\n * restarts after the nested brace), matching what the regex would accept.\n */\nfunction nextPlaceholder(xml: string, from: number): [number, number] | undefined {\n let pos = from;\n for (;;) {\n const open = xml.indexOf(\"{\", pos);\n if (open === -1) return undefined;\n const close = xml.indexOf(\"}\", open + 1);\n if (close === -1) return undefined;\n const keyLen = close - open - 1;\n if (keyLen === 0) {\n pos = open + 1;\n continue;\n }\n const nextOpen = xml.indexOf(\"{\", open + 1);\n if (nextOpen !== -1 && nextOpen < close) {\n // Nested \"{\" inside the candidate key — the regex would restart there.\n pos = open + 1;\n continue;\n }\n return [open, close];\n }\n}\n\n/** Replace `{name}` placeholders with the given values (missing keys stay). */\nexport function replacePlaceholders(xml: string, map: Map<string, string>): string {\n const parts: string[] = [];\n let last = 0;\n let pos = 0;\n for (;;) {\n const found = nextPlaceholder(xml, pos);\n if (found === undefined) break;\n const [open, close] = found;\n const replacement = map.get(xml.substring(open + 1, close));\n if (replacement !== undefined) {\n parts.push(xml.substring(last, open), replacement);\n last = close + 1;\n }\n pos = close + 1;\n }\n if (last === 0) return xml;\n parts.push(xml.substring(last));\n return parts.join(\"\");\n}\n\nexport function hasPlaceholders(xml: string): boolean {\n return xml.includes(\"{\");\n}\n\nexport function collectPlaceholderKeys(xml: string, prefix: string): string[] {\n const keys = new Set<string>();\n const search = `{${prefix}`;\n let pos = 0;\n\n while ((pos = xml.indexOf(search, pos)) !== -1) {\n const keyStart = pos + search.length;\n const keyEnd = xml.indexOf(\"}\", keyStart);\n if (keyEnd === -1) break;\n\n const key = xml.substring(keyStart, keyEnd);\n if (key.length > 0) keys.add(key);\n pos = keyEnd + 1;\n }\n\n return [...keys];\n}\n\nexport function replaceImagePlaceholders(\n xml: string,\n mediaData: { fileName: string }[],\n offset: number,\n idFormat: IdFormat = \"rId\",\n): string {\n if (mediaData.length === 0) return xml;\n const map = new Map<string, string>();\n for (const [i, item] of mediaData.entries()) {\n map.set(item.fileName, formatId(offset, i, idFormat));\n }\n return replacePlaceholders(xml, map);\n}\n\nexport function getReferencedMedia(\n xml: string,\n mediaArray: { fileName: string }[],\n): { fileName: string }[] {\n // Substring search, not brace-pair scanning: callers pass JSON.stringify\n // output (the patch path) where nested object braces would derail a\n // brace-pair walk past the actual placeholder tokens.\n return mediaArray.filter((image) => xml.includes(`{${image.fileName}}`));\n}\n\n/**\n * Combined find + replace for image placeholders in a single pass.\n *\n * Scans XML for `{fileName}` placeholders, replaces them with formatted IDs,\n * and returns the list of referenced media items for relationship registration.\n * More efficient than calling getReferencedMedia() + replaceImagePlaceholders() separately.\n */\nexport function findAndReplaceImagePlaceholders(\n xml: string,\n mediaArray: { fileName: string }[],\n offset: number,\n idFormat: IdFormat = \"rId\",\n sourceRids?: ReadonlyMap<string, string>,\n): { xml: string; referenced: { fileName: string }[] } {\n if (mediaArray.length === 0 || !hasPlaceholders(xml)) {\n return { xml, referenced: [] };\n }\n // Build fileName → mediaItem lookup\n const itemMap = new Map<string, { fileName: string }>();\n for (const item of mediaArray) {\n itemMap.set(item.fileName, item);\n }\n\n const referenced: { fileName: string }[] = [];\n const replaceMap = new Map<string, string>();\n const parts: string[] = [];\n let last = 0;\n let pos = 0;\n\n for (;;) {\n const found = nextPlaceholder(xml, pos);\n if (found === undefined) break;\n const [open, close] = found;\n const key = xml.substring(open + 1, close);\n const item = itemMap.get(key);\n if (item !== undefined) {\n let id = replaceMap.get(key);\n if (id === undefined) {\n // Source round-trip: when the source rels captured the rId for this\n // media file, the body XML must reference that exact rId — the\n // structured compiler's rels will then point to the same target. Using\n // an offset-derived id here would dangle the body's `r:embed` against\n // a rel pointing at a different media item.\n const override = sourceRids?.get(key);\n // Use the referenced-local position (not the global media index) so the\n // generated IDs align with the caller's per-part addRelationship(offset+i)\n // loop. Using the global index desyncs the body's r:embed from the part's\n // .rels when a part references only a subset of the global media array\n // (e.g. headers/footers, whose images sit at high global indices).\n id = override ?? formatId(offset, referenced.length, idFormat);\n replaceMap.set(key, id);\n referenced.push(item);\n }\n parts.push(xml.substring(last, open), id);\n last = close + 1;\n }\n pos = close + 1;\n }\n\n if (last === 0) return { xml, referenced: [] };\n parts.push(xml.substring(last));\n return { xml: parts.join(\"\"), referenced };\n}\n\n/**\n * Replace all placeholder types in a single pass.\n *\n * Combines image, chart, smartart, and arbitrary key-value replacements\n * into one regex scan of the XML string. Used by compilers to avoid\n * multiple full-string passes on large documents.\n */\nexport function replaceAllPlaceholders(\n xml: string,\n entries: Array<{ prefix?: string; key: string; value: string }>,\n): string {\n if (entries.length === 0 || !hasPlaceholders(xml)) return xml;\n const map = new Map<string, string>();\n for (const { prefix, key, value } of entries) {\n map.set(prefix ? `${prefix}${key}` : key, value);\n }\n return replacePlaceholders(xml, map);\n}\n\nexport function replaceChartPlaceholders(\n xml: string,\n chartKeys: string[],\n offset: number,\n idFormat: IdFormat = \"rId\",\n): string {\n if (chartKeys.length === 0) return xml;\n const map = new Map<string, string>();\n for (let i = 0; i < chartKeys.length; i++) {\n map.set(`chart:${chartKeys[i]}`, formatId(offset, i, idFormat));\n }\n return replacePlaceholders(xml, map);\n}\n\nimport type { RelationshipType } from \"../opc/relationships\";\n\nexport interface SmartArtRelOptions {\n pathPrefix: string;\n styleRelType: RelationshipType;\n /**\n * Whether a SmartArt carries the optional diagramDrawing part (the Office\n * render cache). Unset means every SmartArt does — a fresh authoring\n * package never carries it, so round-trip callers pass the source fact.\n */\n hasDrawing?: (key: string) => boolean;\n}\n\nexport function replaceSmartArtPlaceholders(\n xml: string,\n keys: string[],\n dataOffset: number,\n idFormat: IdFormat = \"rId\",\n): string {\n if (keys.length === 0) return xml;\n const count = keys.length;\n const loOffset = dataOffset + count;\n const qsOffset = loOffset + count;\n const csOffset = qsOffset + count;\n\n const map = new Map<string, string>();\n for (let i = 0; i < count; i++) {\n map.set(`smartart:${keys[i]}`, formatId(dataOffset, i, idFormat));\n map.set(`smartart-lo:${keys[i]}`, formatId(loOffset, i, idFormat));\n map.set(`smartart-qs:${keys[i]}`, formatId(qsOffset, i, idFormat));\n map.set(`smartart-cs:${keys[i]}`, formatId(csOffset, i, idFormat));\n }\n return replacePlaceholders(xml, map);\n}\n\nexport function addSmartArtRelationships(\n keys: string[],\n addRel: (id: number, type: RelationshipType, target: string, targetMode?: string) => void,\n baseOffset: number,\n globalStartIndex: number,\n options: SmartArtRelOptions,\n): void {\n const { pathPrefix, styleRelType, hasDrawing } = options;\n const count = keys.length;\n const loOffset = baseOffset + count;\n const qsOffset = loOffset + count;\n const csOffset = qsOffset + count;\n\n for (let i = 0; i < keys.length; i++) {\n const gi = globalStartIndex + i;\n addRel(\n baseOffset + i,\n \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramData\",\n `${pathPrefix}diagrams/data${gi + 1}.xml`,\n );\n addRel(\n loOffset + i,\n \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramLayout\",\n `${pathPrefix}diagrams/layout${gi + 1}.xml`,\n );\n addRel(qsOffset + i, styleRelType, `${pathPrefix}diagrams/quickStyle${gi + 1}.xml`);\n addRel(\n csOffset + i,\n \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramColors\",\n `${pathPrefix}diagrams/colors${gi + 1}.xml`,\n );\n if (hasDrawing === undefined || hasDrawing(keys[i]!)) {\n const drOffset = csOffset + count;\n addRel(\n drOffset + i,\n \"http://schemas.microsoft.com/office/2007/relationships/diagramDrawing\",\n `${pathPrefix}diagrams/drawing${gi + 1}.xml`,\n );\n }\n }\n}\n\n// ── Numbering placeholders (DOCX) ──\n\n/** Replace `{reference-instance}` placeholders with numId values. */\nexport function replaceNumberingPlaceholders(\n xml: string,\n concreteNumberings: readonly { reference: string; instance: number; numId: number }[],\n): string {\n if (concreteNumberings.length === 0) return xml;\n const map = new Map<string, string>();\n for (const { reference, instance, numId } of concreteNumberings) {\n map.set(`${reference}-${instance}`, numId.toString());\n }\n return replacePlaceholders(xml, map);\n}\n\n// ── Media/Video placeholders (PPTX) ──\n\n/** Replace `{media:fileName}` placeholders with relationship IDs. */\nexport function replaceMediaPlaceholders(\n xml: string,\n mediaData: { fileName: string }[],\n offset: number,\n): string {\n return replacePrefixedPlaceholders(xml, mediaData, offset, \"media:\");\n}\n\n/** Replace `{video:fileName}` placeholders with relationship IDs. */\nexport function replaceVideoPlaceholders(\n xml: string,\n mediaData: { fileName: string }[],\n offset: number,\n): string {\n return replacePrefixedPlaceholders(xml, mediaData, offset, \"video:\");\n}\n\n/** Replace `{audio:fileName}` placeholders with relationship IDs. */\nexport function replaceAudioPlaceholders(\n xml: string,\n mediaData: { fileName: string }[],\n offset: number,\n): string {\n return replacePrefixedPlaceholders(xml, mediaData, offset, \"audio:\");\n}\n\n/** Replace `{ole:fileName}` placeholders with relationship IDs. */\nexport function replaceOlePlaceholders(\n xml: string,\n embeddings: { fileName: string }[],\n offset: number,\n): string {\n return replacePrefixedPlaceholders(xml, embeddings, offset, \"ole:\");\n}\n\nfunction replacePrefixedPlaceholders(\n xml: string,\n mediaData: { fileName: string }[],\n offset: number,\n prefix: string,\n): string {\n if (mediaData.length === 0) return xml;\n const map = new Map<string, string>();\n for (const [i, item] of mediaData.entries()) {\n map.set(`${prefix}${item.fileName}`, formatId(offset, i, \"rId\"));\n }\n return replacePlaceholders(xml, map);\n}\n\n/** Collect media items referenced by `{media:...}` placeholders in XML. */\nexport function getMediaRefs(\n xml: string,\n mediaArray: { fileName: string }[],\n): { fileName: string }[] {\n return collectPrefixedRefs(xml, \"media:\", mediaArray);\n}\n\n/** Collect media items referenced by `{video:...}` placeholders in XML. */\nexport function getVideoRefs(\n xml: string,\n mediaArray: { fileName: string }[],\n): { fileName: string }[] {\n return collectPrefixedRefs(xml, \"video:\", mediaArray);\n}\n\n/** Collect media items referenced by `{audio:...}` placeholders in XML. */\nexport function getAudioRefs(\n xml: string,\n mediaArray: { fileName: string }[],\n): { fileName: string }[] {\n return collectPrefixedRefs(xml, \"audio:\", mediaArray);\n}\n\n/** Collect OLE embeddings referenced by `{ole:...}` placeholders in XML. */\nexport function getOleRefs(\n xml: string,\n embeddings: { fileName: string }[],\n): { fileName: string }[] {\n return collectPrefixedRefs(xml, \"ole:\", embeddings);\n}\n\nfunction collectPrefixedRefs(\n xml: string,\n prefix: string,\n mediaArray: { fileName: string }[],\n): { fileName: string }[] {\n const keys = new Set<string>();\n const search = `{${prefix}`;\n let pos = 0;\n while ((pos = xml.indexOf(search, pos)) !== -1) {\n const keyStart = pos + search.length;\n const keyEnd = xml.indexOf(\"}\", keyStart);\n if (keyEnd === -1) break;\n keys.add(xml.substring(keyStart, keyEnd));\n pos = keyEnd + 1;\n }\n return mediaArray.filter((m) => keys.has(m.fileName));\n}\n\n// ── Hyperlink placeholders (PPTX) ──\n\n/** Replace `{prefix:key}` placeholders with relationship IDs. */\nfunction replaceKeyedPlaceholders(\n xml: string,\n items: { key: string }[],\n offset: number,\n prefix: string,\n): string {\n if (items.length === 0) return xml;\n const map = new Map<string, string>();\n for (const [i, item] of items.entries()) {\n map.set(`${prefix}${item.key}`, formatId(offset, i, \"rId\"));\n }\n return replacePlaceholders(xml, map);\n}\n\n/** Replace `{hlink:key}` placeholders with relationship IDs. */\nexport function replaceHyperlinkPlaceholders(\n xml: string,\n hyperlinks: { key: string }[],\n offset: number,\n): string {\n return replaceKeyedPlaceholders(xml, hyperlinks, offset, \"hlink:\");\n}\n\n/** Replace `{img-link:key}` placeholders with relationship IDs. */\nexport function replaceImageLinkPlaceholders(\n xml: string,\n links: { key: string }[],\n offset: number,\n): string {\n return replaceKeyedPlaceholders(xml, links, offset, \"img-link:\");\n}\n\n/** Replace `{ole-link:key}` placeholders with relationship IDs. */\nexport function replaceOleLinkPlaceholders(\n xml: string,\n links: { key: string }[],\n offset: number,\n): string {\n return replaceKeyedPlaceholders(xml, links, offset, \"ole-link:\");\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@office-open/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Shared OOXML infrastructure for office-open — part descriptors, charts, drawings, tables, VML, and unit converters",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chart",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"dependencies": {
|
|
77
77
|
"@noble/hashes": "2.3.0",
|
|
78
78
|
"fflate": "0.8.3",
|
|
79
|
-
"@office-open/xml": "0.
|
|
79
|
+
"@office-open/xml": "0.14.0"
|
|
80
80
|
},
|
|
81
81
|
"scripts": {
|
|
82
82
|
"dev": "basis build --stub",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ext-uri-BR1ouCh3.mjs","names":[],"sources":["../src/util/values.ts","../src/util/base64.ts","../src/util/data-type.ts","../src/util/mappings.ts","../src/util/converters.ts","../src/util/generators.ts","../src/util/image-type.ts","../src/util/ext-uri.ts"],"sourcesContent":["/**\n * Runtime validation and type conversion functions for OOXML specification values.\n *\n * This module provides runtime checks and cleanup for value types in the OOXML spec\n * that aren't easily expressed through the TypeScript type system alone. These\n * validators help prevent silent failures and corrupted documents by enforcing\n * spec-compliant values at runtime.\n *\n * @module\n */\n\n/**\n * A measurement value with optional sign and unit suffix.\n *\n * Supports units: mm (millimeters), cm (centimeters), in (inches), pt (points),\n * pc (picas), pi (picas), and a project-only px (96 DPI pixels).\n *\n * px is NOT part of OOXML's ST_UniversalMeasure (whose pattern is\n * `-?[0-9]+(\\.[0-9]+)?(mm|cm|in|pt|pc|pi)`); it is a project extension so\n * geometry APIs can accept `\"200px\"` alongside `\"5cm\"`. px is converted to EMU\n * (or TWIP) on input and never written to XML verbatim. Note: Word line spacing\n * with lineRule=\"auto\" uses a bare multiple (240ths of a line), not a measure,\n * so px is irrelevant there; spacing before/after and indents accept px and\n * convert it to twips (1px = 15twip).\n *\n * @example\n * ```typescript\n * const measure: UniversalMeasure = \"10.5mm\";\n * const px: UniversalMeasure = \"200px\";\n * const negative: UniversalMeasure = \"-5pt\";\n * ```\n */\nexport type UniversalMeasure =\n `${\"-\" | \"\"}${number}${\"mm\" | \"cm\" | \"in\" | \"pt\" | \"pc\" | \"pi\" | \"px\"}`;\n\n/**\n * A positive measurement value with unit suffix.\n *\n * Same as UniversalMeasure but restricted to positive values only.\n *\n * Reference: ST_PositiveUniversalMeasure in OOXML specification\n *\n * @example\n * ```typescript\n * const measure: PositiveUniversalMeasure = \"10.5mm\";\n * ```\n */\nexport type PositiveUniversalMeasure = `${number}${\"mm\" | \"cm\" | \"in\" | \"pt\" | \"pc\" | \"pi\"}`;\n\n/**\n * A percentage value with optional sign.\n *\n * Pattern: `-?[0-9]+(\\.[0-9]+)?%`\n *\n * Reference: ST_Percentage in OOXML specification\n *\n * @example\n * ```typescript\n * const percent: Percentage = \"50%\";\n * const negative: Percentage = \"-10.5%\";\n * ```\n */\nexport type Percentage = `${\"-\" | \"\"}${number}%`;\n\n/**\n * A positive percentage value.\n *\n * Same as Percentage but restricted to positive values only.\n *\n * Reference: ST_PositivePercentage in OOXML specification\n *\n * @example\n * ```typescript\n * const percent: PositivePercentage = \"50%\";\n * ```\n */\nexport type PositivePercentage = `${number}%`;\n\n/**\n * A relative measurement value using em or ex units.\n *\n * Used in VML text boxes for font-relative measurements.\n *\n * @example\n * ```typescript\n * const measure: RelativeMeasure = \"2em\";\n * const negative: RelativeMeasure = \"-0.5ex\";\n * ```\n */\nexport type RelativeMeasure = `${\"-\" | \"\"}${number}${\"em\" | \"ex\"}`;\n\n// ── Constrained string value domains ──\n//\n// Plain-string aliases over XSD facets that enumeration cannot express\n// (hex digits, GUID shape, base64). The JSON schema generator attaches the\n// matching regex to each alias definition, so schema-driven generation gets\n// a hard constraint where TypeScript alone stays permissive.\n\n/**\n * A 6-digit hex RGB color, without \"#\" (ST_HexColorRGB — 3-byte hexBinary).\n *\n * DrawingML writes it in upper case (\"FF0000\"); the pattern admits both\n * cases since parse keeps source casing verbatim.\n *\n * @example\n * ```typescript\n * const color: HexColor = \"4472C4\";\n * ```\n */\nexport type HexColor = string;\n\n/**\n * An 8-digit hex ARGB color (ST_UnsignedIntHex in sml.xsd — 4-byte\n * hexBinary). SpreadsheetML tab colors carry the alpha channel verbatim\n * (\"FF4472C4\" is opaque blue); most other sml color fields normalize to\n * {@link HexColor} with the library owning the FF prefix.\n *\n * @example\n * ```typescript\n * const tab: ArgbHexColor = \"FF4472C4\";\n * ```\n */\nexport type ArgbHexColor = string;\n\n/**\n * \"auto\" or a 6-digit hex RGB color (ST_HexColor — union of ST_HexColorAuto\n * and ST_HexColorRGB in wml.xsd).\n *\n * @example\n * ```typescript\n * const auto: HexColorOrAuto = \"auto\";\n * const red: HexColorOrAuto = \"FF0000\";\n * ```\n */\nexport type HexColorOrAuto = string;\n\n/**\n * A GUID in braced form (ST_Guid — `{{8-4-4-4-12 hex}}`, upper case per the\n * XSD pattern; Office writes it braced).\n *\n * @example\n * ```typescript\n * const id: Guid = \"{1DF903F5-8FC7-4C6A-9DF9-2AB1D10E6D84}\";\n * ```\n */\nexport type Guid = string;\n\n/**\n * A 20-digit hex Panose-1 font classification string (ST_Panose — 10-byte\n * hexBinary, e.g. \"020F0502020204030204\" for Arial).\n */\nexport type Panose = string;\n\n/**\n * An 8-digit hex number (ST_LongHexNumber in wml.xsd — 4-byte hexBinary).\n * Word revision-save ids (rsid) and font-signature bytes (usb/csb) use it.\n */\nexport type LongHexNumber = string;\n\n/**\n * A 4-digit hex number (ST_ShortHexNumber in wml.xsd — 2-byte hexBinary).\n */\nexport type ShortHexNumber = string;\n\n/**\n * A 2-digit hex byte (ST_UcharHexNumber in wml.xsd — 1-byte hexBinary).\n * Border/shading theme tint and shade percentages use it.\n */\nexport type UcharHexNumber = string;\n\n/**\n * A 4-digit hex number (ST_UnsignedShortHex in sml.xsd — 2-byte hexBinary).\n * The legacy file-sharing reservation password hash uses it.\n */\nexport type UnsignedShortHex = string;\n\n/**\n * Base64-encoded bytes (xsd:base64Binary). Workbook, sheet, and write\n * protection carry password hashes and salts in this form.\n *\n * @example\n * ```typescript\n * const hash: Base64 = \"Hh8eLiw+KTpAPT4nPj8=\";\n * ```\n */\nexport type Base64 = string;\n\n/**\n * An xsd:dateTime timestamp in ISO 8601 form (track-change and comment\n * dates). Office writes the UTC \"Z\" suffix (\"2024-06-01T09:30:00Z\").\n *\n * @example\n * ```typescript\n * const stamp: DateTime = \"2024-06-01T09:30:00Z\";\n * ```\n */\nexport type DateTime = string;\n\n/**\n * Validates and converts a number to an integer (decimal number).\n *\n * Reference: ST_DecimalNumber in OOXML specification\n *\n * @param val - The number to validate and convert\n * @returns The floored integer value\n * @throws Error if the value is NaN\n *\n * @example\n * ```typescript\n * const num = decimalNumber(10.7); // Returns 10\n * const negative = decimalNumber(-5.3); // Returns -5\n * ```\n */\nexport const decimalNumber = (val: number): number => {\n if (!Number.isFinite(val)) {\n throw new Error(`Invalid value '${val}' specified. Must be a finite number.`);\n }\n return Math.floor(val);\n};\n\n/**\n * Validates and converts a number to a positive integer (unsigned decimal number).\n *\n * Reference: ST_UnsignedDecimalNumber in OOXML specification\n *\n * @param val - The number to validate and convert\n * @returns The floored positive integer value\n * @throws Error if the value is NaN or negative\n *\n * @example\n * ```typescript\n * const num = unsignedDecimalNumber(10.7); // Returns 10\n * const invalid = unsignedDecimalNumber(-5); // Throws Error\n * ```\n */\nexport const unsignedDecimalNumber = (val: number): number => {\n const value = decimalNumber(val);\n if (value < 0) {\n throw new Error(`Invalid value '${val}' specified. Must be a positive integer.`);\n }\n return value;\n};\n\n/**\n * Validates and normalizes a hexadecimal binary value.\n *\n * The xsd:hexBinary type represents binary data as a sequence of binary octets\n * using hexadecimal encoding, where each binary octet is a two-character\n * hexadecimal number. Both lowercase and uppercase letters A-F are permitted.\n *\n * @param val - The hexadecimal string to validate\n * @param length - The expected length in bytes (not characters)\n * @returns The validated hexadecimal string\n * @throws Error if the value is not a valid hex string of the expected length\n *\n * @example\n * ```typescript\n * hexBinary(\"0FB8\", 2); // Valid: 2 bytes = 4 characters\n * hexBinary(\"ABC\", 2); // Invalid: wrong length\n * ```\n */\nexport const hexBinary = (val: string, length: number): string => {\n const expectedLength = length * 2;\n if (val.length !== expectedLength || isNaN(Number(`0x${val}`))) {\n throw new Error(`Invalid hex value '${val}'. Expected ${expectedLength} digit hex value`);\n }\n return val;\n};\n\n/**\n * Validates a long hexadecimal number (4 bytes / 8 characters).\n *\n * Reference: ST_LongHexNumber in OOXML specification\n *\n * @param val - The hexadecimal string to validate\n * @returns The validated hexadecimal string\n * @throws Error if the value is not a valid 8-character hex string\n *\n * @example\n * ```typescript\n * const hex = longHexNumber(\"ABCD1234\"); // Valid\n * ```\n */\nexport const longHexNumber = (val: string): string => hexBinary(val, 4);\n\n/**\n * Validates a short hexadecimal number (2 bytes / 4 characters).\n *\n * Reference: ST_ShortHexNumber in OOXML specification\n *\n * @param val - The hexadecimal string to validate\n * @returns The validated hexadecimal string\n * @throws Error if the value is not a valid 4-character hex string\n *\n * @example\n * ```typescript\n * const hex = shortHexNumber(\"AB12\"); // Valid\n * ```\n */\nexport const shortHexNumber = (val: string): string => hexBinary(val, 2);\n\n/**\n * Validates a single-byte hexadecimal number (1 byte / 2 characters).\n *\n * Reference: ST_UcharHexNumber in OOXML specification\n *\n * @param val - The hexadecimal string to validate\n * @returns The validated hexadecimal string\n * @throws Error if the value is not a valid 2-character hex string\n *\n * @example\n * ```typescript\n * const hex = uCharHexNumber(\"FF\"); // Valid\n * ```\n */\nexport const uCharHexNumber = (val: string): string => hexBinary(val, 1);\n\n/**\n * Normalizes a universal measure value by parsing and reformatting.\n *\n * Ensures the numeric portion is properly formatted while preserving the unit.\n *\n * Reference: ST_UniversalMeasure in OOXML specification\n *\n * @param val - The universal measure string to normalize\n * @returns The normalized universal measure\n *\n * @example\n * ```typescript\n * const measure = universalMeasureValue(\"10.500mm\"); // Returns \"10.5mm\"\n * ```\n */\nexport const universalMeasureValue = (val: UniversalMeasure): UniversalMeasure => {\n const unit = val.slice(-2);\n const amount = val.substring(0, val.length - 2);\n return `${Number(amount)}${unit}` as UniversalMeasure;\n};\n\n/**\n * Validates and normalizes a positive universal measure value.\n *\n * Reference: ST_PositiveUniversalMeasure in OOXML specification\n *\n * @param val - The positive universal measure string to validate\n * @returns The normalized positive universal measure\n * @throws Error if the value is negative\n *\n * @example\n * ```typescript\n * const measure = positiveUniversalMeasureValue(\"10.5mm\"); // Valid\n * const invalid = positiveUniversalMeasureValue(\"-5mm\"); // Throws Error\n * ```\n */\nexport const positiveUniversalMeasureValue = (\n val: PositiveUniversalMeasure,\n): PositiveUniversalMeasure => {\n const value = universalMeasureValue(val);\n if (parseFloat(value) < 0) {\n throw new Error(`Invalid value '${value}' specified. Expected a positive number.`);\n }\n return value as PositiveUniversalMeasure;\n};\n\n/**\n * Validates and normalizes a hexadecimal color value.\n *\n * Accepts either \"auto\" or a 6-character RGB hex value (with or without # prefix).\n * The # prefix is commonly used but technically invalid in OOXML, so it is stripped\n * for strict compliance.\n *\n * Reference: ST_HexColor in OOXML specification\n *\n * @param val - The color value to validate (\"auto\" or hex color)\n * @returns The normalized color value\n * @throws Error if the hex color is invalid\n *\n * @example\n * ```typescript\n * const color1 = hexColorValue(\"auto\"); // Returns \"auto\"\n * const color2 = hexColorValue(\"FF0000\"); // Returns \"FF0000\"\n * const color3 = hexColorValue(\"#00FF00\"); // Returns \"00FF00\" (# stripped)\n * ```\n */\nexport const hexColorValue = (val: string): string => {\n if (val === \"auto\") {\n return val;\n }\n // It's super common to see colors prefixed with a pound, but technically invalid here.\n // Most clients work with it, but strip it off anyway for strict compliance.\n const color = stripColorHashPrefix(val);\n return hexBinary(color, 3);\n};\n\n/**\n * Strips the leading \"#\" prefix from a color string if present.\n *\n * Hex color values in OOXML do not include the \"#\" prefix, but user input\n * commonly includes it. This helper normalizes color strings for OOXML output.\n *\n * @param color - The color string (with or without \"#\" prefix)\n * @returns The color string without the \"#\" prefix\n *\n * @example\n * ```typescript\n * stripColorHashPrefix(\"#FF0000\"); // Returns \"FF0000\"\n * stripColorHashPrefix(\"00FF00\"); // Returns \"00FF00\"\n * ```\n */\nexport const stripColorHashPrefix = (color: string): string =>\n color.charAt(0) === \"#\" ? color.substring(1) : color;\n\n/**\n * Parses an ST_OnOff / xsd:boolean attribute value.\n *\n * Accepts the full union lexical space leniently on read: true/false, 1/0\n * (number or string — nativeTypeAttributes coerces 1/0 to numbers), and\n * on/off (legal only in wml's ST_OnOff union, not in xsd:boolean). Emission\n * stays per-schema canonical (\"1\"/\"0\").\n *\n * Reference: ST_OnOff in shared-commonSimpleTypes.xsd\n *\n * @param raw - The raw attribute value (string, number, or boolean)\n * @returns The parsed boolean, or undefined when unrecognized\n *\n * @example\n * ```typescript\n * parseOnOff(\"1\"); // true\n * parseOnOff(\"off\"); // false\n * parseOnOff(1); // true (nativeTypeAttributes number coercion)\n * ```\n */\nexport const parseOnOff = (raw: string | number | boolean | undefined): boolean | undefined => {\n if (raw === undefined) return undefined;\n if (typeof raw === \"boolean\") return raw;\n const s = String(raw).toLowerCase();\n // Full ST_OnOff union across editions — the original 2006 enumeration\n // included the single-letter t/f Word 2007 wrote.\n if (s === \"1\" || s === \"true\" || s === \"on\" || s === \"t\") return true;\n if (s === \"0\" || s === \"false\" || s === \"off\" || s === \"f\") return false;\n return undefined;\n};\n\n/**\n * Validates a signed TWIP measurement value.\n *\n * Accepts either a universal measure string or a numeric TWIP value.\n *\n * Reference: ST_SignedTwipsMeasure in OOXML specification\n *\n * @param val - The measurement value (universal measure or number)\n * @returns The normalized measurement value\n *\n * @example\n * ```typescript\n * const measure1 = signedTwipsMeasureValue(\"10mm\");\n * const measure2 = signedTwipsMeasureValue(1440); // 1 inch in TWIP\n * ```\n */\nexport const signedTwipsMeasureValue = (\n val: UniversalMeasure | number,\n): UniversalMeasure | number =>\n typeof val === \"string\" ? universalMeasureValue(val) : decimalNumber(val);\n\n/**\n * Validates a half-point (HPS) measurement value.\n *\n * Accepts either a positive universal measure string or a positive number.\n * HPS (half-points) are commonly used for font sizes.\n *\n * Reference: ST_HpsMeasure in OOXML specification\n *\n * @param val - The measurement value (positive universal measure or number)\n * @returns The normalized measurement value\n *\n * @example\n * ```typescript\n * const fontSize1 = hpsMeasureValue(\"12pt\");\n * const fontSize2 = hpsMeasureValue(24); // 12pt in half-points\n * ```\n */\nexport const hpsMeasureValue = (val: PositiveUniversalMeasure | number): string | number =>\n typeof val === \"string\" ? positiveUniversalMeasureValue(val) : unsignedDecimalNumber(val);\n\n/**\n * Validates a signed half-point (HPS) measurement value.\n *\n * Accepts either a universal measure string or a numeric value.\n *\n * Reference: ST_SignedHpsMeasure in OOXML specification\n *\n * @param val - The measurement value (universal measure or number)\n * @returns The normalized measurement value\n *\n * @example\n * ```typescript\n * const spacing1 = signedHpsMeasureValue(\"6pt\");\n * const spacing2 = signedHpsMeasureValue(-12); // Negative spacing\n * ```\n */\nexport const signedHpsMeasureValue = (val: UniversalMeasure | number): string | number =>\n typeof val === \"string\" ? universalMeasureValue(val) : decimalNumber(val);\n\n/**\n * Validates a positive TWIP measurement value.\n *\n * Accepts either a positive universal measure string or a positive number.\n *\n * Reference: ST_TwipsMeasure in OOXML specification\n *\n * @param val - The measurement value (positive universal measure or number)\n * @returns The normalized measurement value\n *\n * @example\n * ```typescript\n * const width1 = twipsMeasureValue(\"25.4mm\");\n * const width2 = twipsMeasureValue(1440); // 1 inch in TWIP\n * ```\n */\nexport const twipsMeasureValue = (\n val: PositiveUniversalMeasure | number,\n): PositiveUniversalMeasure | number =>\n typeof val === \"string\" ? positiveUniversalMeasureValue(val) : unsignedDecimalNumber(val);\n\n/**\n * Normalizes a percentage value by parsing and reformatting.\n *\n * Reference: ST_Percentage in OOXML specification\n *\n * @param val - The percentage string to normalize\n * @returns The normalized percentage\n *\n * @example\n * ```typescript\n * const percent = percentageValue(\"50.000%\"); // Returns \"50%\"\n * ```\n */\nexport const percentageValue = (val: Percentage): Percentage => {\n const percent = val.substring(0, val.length - 1);\n return `${Number(percent)}%`;\n};\n\n/**\n * Validates a measurement value that can be expressed as a number, percentage, or universal measure.\n *\n * Reference: ST_MeasurementOrPercent in OOXML specification\n *\n * @param val - The measurement value (number, percentage, or universal measure)\n * @returns The normalized measurement value\n *\n * @example\n * ```typescript\n * const measure1 = measurementOrPercentValue(100); // Unqualified number\n * const measure2 = measurementOrPercentValue(\"50%\"); // Percentage\n * const measure3 = measurementOrPercentValue(\"10mm\"); // Universal measure\n * ```\n */\nexport const measurementOrPercentValue = (\n val: number | Percentage | UniversalMeasure,\n): number | UniversalMeasure | Percentage => {\n if (typeof val === \"number\") {\n return decimalNumber(val);\n }\n if (val.slice(-1) === \"%\") {\n return percentageValue(val as Percentage);\n }\n return universalMeasureValue(val as UniversalMeasure);\n};\n\n/**\n * Validates an eighth-point measurement value.\n *\n * Eighth-points are used for fine-grained measurements in text formatting.\n *\n * Reference: ST_EighthPointMeasure in OOXML specification\n *\n * @param val - The measurement value in eighth-points\n * @returns The validated positive integer value\n *\n * @example\n * ```typescript\n * const measure = eighthPointMeasureValue(16); // 2 points\n * ```\n */\nexport const eighthPointMeasureValue = unsignedDecimalNumber;\n\n/**\n * Validates a point measurement value.\n *\n * Reference: ST_PointMeasure in OOXML specification\n *\n * @param val - The measurement value in points\n * @returns The validated positive integer value\n *\n * @example\n * ```typescript\n * const fontSize = pointMeasureValue(12); // 12pt\n * ```\n */\nexport const pointMeasureValue = unsignedDecimalNumber;\n\n// Cspell:words CCYY\n/**\n * Converts a JavaScript Date object to an ISO 8601 date-time string.\n *\n * The format is CCYY-MM-DDThh:mm:ss.sssZ where T is a literal and Z indicates UTC.\n * This matches the xsd:dateTime format required by OOXML.\n *\n * Reference: ST_DateTime in OOXML specification\n *\n * @param val - The Date object to convert\n * @returns An ISO 8601 formatted date-time string\n *\n * @example\n * ```typescript\n * const now = new Date();\n * const timestamp = dateTimeValue(now); // Returns \"2024-01-15T10:30:00.000Z\"\n * ```\n */\nexport const dateTimeValue = (val: Date): string => val.toISOString();\n\n/**\n * Theme color values used throughout OOXML for referencing document theme colors.\n *\n * Reference: ST_ThemeColor in OOXML specification\n *\n * @publicApi\n */\nexport type ThemeColor =\n | \"dark1\"\n | \"light1\"\n | \"dark2\"\n | \"light2\"\n | \"accent1\"\n | \"accent2\"\n | \"accent3\"\n | \"accent4\"\n | \"accent5\"\n | \"accent6\"\n | \"hyperlink\"\n | \"followedHyperlink\"\n | \"none\"\n | \"background1\"\n | \"text1\"\n | \"background2\"\n | \"text2\";\n\n/**\n * Theme font values used for referencing document theme fonts.\n *\n * Reference: ST_Theme in OOXML specification\n *\n * @publicApi\n */\nexport type ThemeFont =\n | \"majorEastAsia\"\n | \"majorBidi\"\n | \"majorAscii\"\n | \"majorHAnsi\"\n | \"minorEastAsia\"\n | \"minorBidi\"\n | \"minorAscii\"\n | \"minorHAnsi\";\n","/**\n * Shared base64 encode/decode helpers.\n *\n * Both prefer the native `Uint8Array` base64 methods (Node 22+, modern\n * browsers): they avoid the intermediate binary string that `btoa`/`atob`\n * materialize and cannot stack-overflow on large buffers. Node `Buffer` is the\n * secondary path; a manual loop covers older runtimes.\n *\n * @module\n */\n\n/**\n * Decode a base64 string into a `Uint8Array`.\n *\n * Prefers native `Uint8Array.fromBase64` (no intermediate binary string), then\n * Node `Buffer` (zero-copy), then `atob`.\n */\nexport function decodeBase64(input: string): Uint8Array {\n const fromBase64 = (Uint8Array as { fromBase64?: (s: string) => Uint8Array }).fromBase64;\n if (typeof fromBase64 === \"function\") return fromBase64.call(Uint8Array, input);\n if (typeof Buffer !== \"undefined\") return Buffer.from(input, \"base64\");\n return Uint8Array.from(atob(input), (c) => c.codePointAt(0)!);\n}\n\n/**\n * Encode a `Uint8Array` into a base64 string.\n *\n * Prefers native `Uint8Array.prototype.toBase64` (no intermediate binary\n * string), then Node `Buffer` (zero-copy), then a `btoa` fallback.\n *\n * The fallback builds the binary string in a loop rather than\n * `String.fromCharCode(...bytes)` — the spread form places every byte on the\n * call stack and overflows for large buffers (V8 caps function arguments near\n * ~65k).\n */\nexport function encodeBase64(bytes: Uint8Array): string {\n const toBase64 = (Uint8Array.prototype as { toBase64?: () => string }).toBase64;\n if (typeof toBase64 === \"function\") return toBase64.call(bytes);\n if (typeof Buffer !== \"undefined\") return Buffer.from(bytes).toString(\"base64\");\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n}\n","/**\n * Binary input normalization.\n *\n * Accepts the full range of binary inputs (Buffer/Uint8Array/ArrayBuffer/\n * DataView/number[]/string/base64 data URL/…) and normalizes to `Uint8Array`.\n * Centralized here so every entry point (packer, patch, descriptor helpers)\n * shares one definition instead of re-declaring per module.\n *\n * @module\n */\nimport { decodeBase64 } from \"./base64\";\n\n/** Supported binary input shapes. */\nexport type DataType =\n | ArrayBufferLike\n | Blob\n | DataView\n | number[]\n | ReadableStream\n | string\n | Uint8Array;\n\n// Matches data:[<mediatype>][;base64],<data> — a base64 data URL. Mirrors the\n// `isBase64DataURL` check in unjs/undio so plain strings stay UTF-8 text.\nconst DATA_URL_RE = /^data:([\\w.+-]+\\/[\\w.+-]+)?;base64,/;\n\n/** Test whether a string is a base64 data URL (`data:[mime];base64,...`). */\nexport function isBase64DataURL(input: string): boolean {\n return DATA_URL_RE.test(input);\n}\n\n/** Options for {@link toUint8Array}. */\nexport interface ToUint8ArrayOptions {\n /**\n * How to interpret a plain (non-data-URL) string input. Data URLs\n * (`data:...;base64,...`) and binary inputs (Buffer/Uint8Array/ArrayBuffer/\n * DataView/number[]) are auto-detected and ignore this hint.\n *\n * - `\"utf8\"` (default): UTF-8 text.\n * - `\"base64\"`: base64-encoded binary — e.g. an image supplied via\n * `readFileSync(...).toString(\"base64\")`.\n */\n encoding?: \"utf8\" | \"base64\";\n}\n\n/** Normalize any supported binary input to a `Uint8Array`. */\nexport function toUint8Array(data: DataType, options?: ToUint8ArrayOptions): Uint8Array {\n if (data instanceof Uint8Array) return data;\n if (data instanceof ArrayBuffer) return new Uint8Array(data);\n if (data instanceof DataView)\n return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n if (typeof data === \"string\") {\n const match = data.match(DATA_URL_RE);\n if (match) return decodeBase64(data.slice(match[0].length));\n if (options?.encoding === \"base64\") return decodeBase64(data);\n return new TextEncoder().encode(data);\n }\n if (Array.isArray(data)) return new Uint8Array(data);\n if (data instanceof Blob) throw new TypeError(\"Blob input requires async processing\");\n if (data instanceof ReadableStream)\n throw new TypeError(\"ReadableStream input requires async processing\");\n throw new TypeError(`Unsupported data type: ${typeof data}`);\n}\n","/**\n * Bidirectional mappings between user-friendly values and XSD abbreviated values.\n *\n * When XSD uses full English words (e.g. \"center\", \"start\"), values are used directly — no mapping needed.\n * When XSD uses abbreviations (e.g. \"ctr\", \"l\", \"rnd\"), this module maps them to full words.\n *\n * Usage in generation (Options → XML): xsdAlign.to(\"center\") → \"ctr\"\n * Usage in parsing (XML → Options): xsdAlign.from(\"ctr\") → \"center\"\n */\n\n/** Invert a Record<K, V> into Record<V, K>. */\nexport function invertMap<K extends string, V extends string>(map: Record<K, V>): Record<V, K> {\n const result = {} as Record<V, K>;\n for (const key of Object.keys(map) as K[]) {\n result[map[key]] = key;\n }\n return result;\n}\n\n/** Create a bidirectional mapping helper from a single forward map. */\nfunction bidi<K extends string, V extends string>(forward: Record<K, V>) {\n const reverse = invertMap(forward);\n return {\n /** User-friendly value → XSD value */\n to: (key: string): string => (forward as Record<string, string>)[key] ?? key,\n /** XSD value → user-friendly value */\n from: (xsd: string): string => (reverse as Record<string, string>)[xsd] ?? xsd,\n /** The forward map (user → XSD) */\n forward,\n /** The reverse map (XSD → user) */\n reverse,\n };\n}\n\n// ---------------------------------------------------------------------------\n// DrawingML — Direction / Position (ST_RectAlignment)\n// Used by: RectAlignment, TileAlignment, ReflectionAlignment\n// ---------------------------------------------------------------------------\n\nexport const xsdRectAlignment = bidi({\n topLeft: \"tl\",\n top: \"t\",\n topRight: \"tr\",\n left: \"l\",\n center: \"ctr\",\n right: \"r\",\n bottomLeft: \"bl\",\n bottom: \"b\",\n bottomRight: \"br\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// DrawingML — Text alignment (ST_TextAlignType)\n// Used by: TextAlignment (pptx)\n// ---------------------------------------------------------------------------\n\nexport const xsdTextAlign = bidi({\n left: \"l\",\n center: \"ctr\",\n right: \"r\",\n justify: \"just\",\n lowJustification: \"justLow\",\n distribute: \"dist\",\n thaiDistributed: \"thaiDist\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// DrawingML — Text anchoring (ST_TextAnchoringType)\n// Used by: VerticalAnchor (pptx table-cell re-export)\n// ---------------------------------------------------------------------------\n\nexport const xsdTextAnchor = bidi({\n top: \"t\",\n center: \"ctr\",\n bottom: \"b\",\n justify: \"just\",\n distribute: \"dist\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// DrawingML — Line cap (ST_LineCap)\n// ---------------------------------------------------------------------------\n\nexport const xsdLineCap = bidi({\n round: \"rnd\",\n square: \"sq\",\n flat: \"flat\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// DrawingML — Compound line (ST_CompoundLine)\n// ---------------------------------------------------------------------------\n\nexport const xsdCompoundLine = bidi({\n single: \"sng\",\n double: \"dbl\",\n thickThin: \"thickThin\",\n thinThick: \"thinThick\",\n triple: \"tri\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// DrawingML — Pen alignment (ST_PenAlignment)\n// ---------------------------------------------------------------------------\n\nexport const xsdPenAlignment = bidi({\n center: \"ctr\",\n inside: \"in\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// DrawingML — Line end size (ST_LineEndWidth, ST_LineEndLength)\n// ---------------------------------------------------------------------------\n\nexport const xsdLineEndSize = bidi({\n small: \"sm\",\n medium: \"med\",\n large: \"lg\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// DrawingML — Blend mode (ST_BlendMode)\n// ---------------------------------------------------------------------------\n\nexport const xsdBlendMode = bidi({\n over: \"over\",\n multiply: \"mult\",\n screen: \"screen\",\n darken: \"darken\",\n lighten: \"lighten\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// DrawingML — Path fill mode (ST_PathFillMode)\n// ---------------------------------------------------------------------------\n\nexport const xsdPathFillMode = bidi({\n none: \"none\",\n normal: \"norm\",\n lighten: \"lighten\",\n lightenLess: \"lightenLess\",\n darken: \"darken\",\n darkenLess: \"darkenLess\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// DrawingML — Effect container type\n// ---------------------------------------------------------------------------\n\nexport const xsdEffectContainer = bidi({\n sibling: \"sib\",\n tree: \"tree\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// DrawingML — Preset shadow (ST_PresetShadowVal)\n// ---------------------------------------------------------------------------\n\nexport const xsdPresetShadow = bidi({\n shadow1: \"shdw1\",\n shadow2: \"shdw2\",\n shadow3: \"shdw3\",\n shadow4: \"shdw4\",\n shadow5: \"shdw5\",\n shadow6: \"shdw6\",\n shadow7: \"shdw7\",\n shadow8: \"shdw8\",\n shadow9: \"shdw9\",\n shadow10: \"shdw10\",\n shadow11: \"shdw11\",\n shadow12: \"shdw12\",\n shadow13: \"shdw13\",\n shadow14: \"shdw14\",\n shadow15: \"shdw15\",\n shadow16: \"shdw16\",\n shadow17: \"shdw17\",\n shadow18: \"shdw18\",\n shadow19: \"shdw19\",\n shadow20: \"shdw20\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// DrawingML — Preset material type (ST_PresetMaterialType)\n// Only the abbreviated ones need mapping; full-word values pass through.\n// ---------------------------------------------------------------------------\n\nexport const xsdLightRigDirection = bidi({\n topLeft: \"tl\",\n top: \"t\",\n topRight: \"tr\",\n left: \"l\",\n right: \"r\",\n bottomLeft: \"bl\",\n bottom: \"b\",\n bottomRight: \"br\",\n} as const);\n\nexport const xsdMaterialType = bidi({\n legacyMatte: \"legacyMatte\",\n legacyPlastic: \"legacyPlastic\",\n legacyMetal: \"legacyMetal\",\n legacyWireframe: \"legacyWireframe\",\n matte: \"matte\",\n plastic: \"plastic\",\n metal: \"metal\",\n warmMatte: \"warmMatte\",\n translucentPowder: \"translucentPowder\",\n powder: \"powder\",\n darkEdge: \"dkEdge\",\n softEdge: \"softEdge\",\n clear: \"clear\",\n flat: \"flat\",\n softMetal: \"softmetal\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// DrawingML — Preset pattern fill (ST_PresetPatternVal)\n// Only the abbreviated ones are mapped; values already using full words pass through.\n// ---------------------------------------------------------------------------\n\nexport const xsdPattern = bidi({\n percent5: \"pct5\",\n percent10: \"pct10\",\n percent20: \"pct20\",\n percent25: \"pct25\",\n percent30: \"pct30\",\n percent40: \"pct40\",\n percent50: \"pct50\",\n percent60: \"pct60\",\n percent70: \"pct70\",\n percent75: \"pct75\",\n percent80: \"pct80\",\n percent90: \"pct90\",\n horizontal: \"horz\",\n vertical: \"vert\",\n lightHorizontal: \"ltHorz\",\n lightVertical: \"ltVert\",\n darkHorizontal: \"dkHorz\",\n darkVertical: \"dkVert\",\n narrowHorizontal: \"narHorz\",\n narrowVertical: \"narVert\",\n dashedHorizontal: \"dashHorz\",\n dashedVertical: \"dashVert\",\n cross: \"cross\",\n downDiagonal: \"dnDiag\",\n upDiagonal: \"upDiag\",\n lightDownDiagonal: \"ltDnDiag\",\n lightUpDiagonal: \"ltUpDiag\",\n darkDownDiagonal: \"dkDnDiag\",\n darkUpDiagonal: \"dkUpDiag\",\n wideDownDiagonal: \"wdDnDiag\",\n wideUpDiagonal: \"wdUpDiag\",\n dashedDownDiagonal: \"dashDnDiag\",\n dashedUpDiagonal: \"dashUpDiag\",\n diagonalCross: \"diagCross\",\n smallChecker: \"smCheck\",\n largeChecker: \"lgCheck\",\n smallGrid: \"smGrid\",\n largeGrid: \"lgGrid\",\n dotGrid: \"dotGrid\",\n smallConfetti: \"smConfetti\",\n largeConfetti: \"lgConfetti\",\n horizontalBrick: \"horzBrick\",\n diagonalBrick: \"diagBrick\",\n solidDiamond: \"solidDmnd\",\n openDiamond: \"openDmnd\",\n dottedDiamond: \"dotDmnd\",\n plaid: \"plaid\",\n sphere: \"sphere\",\n weave: \"weave\",\n divot: \"divot\",\n shingle: \"shingle\",\n wave: \"wave\",\n trellis: \"trellis\",\n zigZag: \"zigZag\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// DOCX — Vertical merge revision (ST_VerticalMergeRestart)\n// ---------------------------------------------------------------------------\n\nexport const xsdVerticalMergeRev = bidi({\n continue: \"cont\",\n restart: \"rest\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// PPTX — Underline style (ST_TextUnderlineType, abbreviated subset)\n// ---------------------------------------------------------------------------\n\nexport const xsdUnderlineStyle = bidi({\n single: \"sng\",\n double: \"dbl\",\n none: \"none\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// PPTX — Strike style (ST_TextStrikeType)\n// ---------------------------------------------------------------------------\n\nexport const xsdStrikeStyle = bidi({\n singleStrike: \"sngStrike\",\n doubleStrike: \"dblStrike\",\n noStrike: \"noStrike\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// PPTX — Text capitalization (ST_TextCapsType)\n// ---------------------------------------------------------------------------\n\nexport const xsdTextCaps = bidi({\n none: \"none\",\n all: \"all\",\n small: \"small\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// Chart — axis / legend / label placement (c:axPos, c:legendPos, c:dLblPos)\n// Only the abbreviated tokens are mapped; identical values pass through.\n// ---------------------------------------------------------------------------\n\nexport const xsdAxisPosition = bidi({ bottom: \"b\", left: \"l\", right: \"r\", top: \"t\" } as const);\n\nexport const xsdLegendPosition = bidi({\n bottom: \"b\",\n topRight: \"tr\",\n left: \"l\",\n right: \"r\",\n top: \"t\",\n} as const);\n\nexport const xsdDataLabelPosition = bidi({\n bottom: \"b\",\n center: \"ctr\",\n insideBase: \"inBase\",\n insideEnd: \"inEnd\",\n left: \"l\",\n outsideEnd: \"outEnd\",\n right: \"r\",\n top: \"t\",\n} as const);\n\nexport const xsdAxisCrossBetween = bidi({ middleOfCategory: \"midCat\" } as const);\n\nexport const xsdAxisCrosses = bidi({ zero: \"autoZero\" } as const);\n\nexport const xsdComments = bidi({\n none: \"commNone\",\n indicator: \"commIndicator\",\n comment: \"commIndAndComment\",\n} as const);\n\nexport const xsdErrorValueType = bidi({\n custom: \"cust\",\n fixedValue: \"fixedVal\",\n standardDeviation: \"stdDev\",\n standardError: \"stdErr\",\n} as const);\n\nexport const xsdSizeRepresents = bidi({ width: \"w\" } as const);\n\nexport const xsdSplitType = bidi({ custom: \"cust\", position: \"pos\", value: \"val\" } as const);\n\nexport const xsdAxisLabelAlignment = bidi({ center: \"ctr\", left: \"l\", right: \"r\" } as const);\n\nexport const xsdAxisOrientation = bidi({ ascending: \"minMax\", descending: \"maxMin\" } as const);\n\nexport const xsdTrendlineType = bidi({\n exponential: \"exp\",\n logarithmic: \"log\",\n movingAverage: \"movingAvg\",\n polynomial: \"poly\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// Chart / text — tab alignment, font alignment, compound line\n// ---------------------------------------------------------------------------\n\nexport const xsdTextTabAlignment = bidi({\n left: \"l\",\n center: \"ctr\",\n right: \"r\",\n decimal: \"dec\",\n} as const);\n\nexport const xsdFontAlignment = bidi({ top: \"t\", center: \"ctr\", bottom: \"b\" } as const);\n\n// ---------------------------------------------------------------------------\n// Diagram — animation levels, hierarchy branch, hue direction (dgm:)\n// ---------------------------------------------------------------------------\n\nexport const xsdAnimLevel = bidi({ level: \"lvl\", center: \"ctr\" } as const);\n\nexport const xsdHierBranch = bidi({\n left: \"l\",\n right: \"r\",\n hanging: \"hang\",\n standard: \"std\",\n initial: \"init\",\n} as const);\n\nexport const xsdHueDirection = bidi({ clockwise: \"cw\", counterClockwise: \"ccw\" } as const);\n\nexport const xsdDiagramDirection = bidi({ normal: \"norm\", reversed: \"rev\" } as const);\n\nexport const xsdResizeHandles = bidi({ exact: \"exact\", relative: \"rel\" } as const);\n\n// ---------------------------------------------------------------------------\n// PPTX — animation classes, calc modes, slide layouts, text direction\n// ---------------------------------------------------------------------------\n\nexport const xsdAnimClass = bidi({\n entrance: \"entr\",\n emphasis: \"emph\",\n mediaCall: \"mediacall\",\n} as const);\n\nexport const xsdAnimCalcMode = bidi({ linear: \"lin\", formula: \"fmla\" } as const);\n\nexport const xsdAnimValueType = bidi({ string: \"str\", number: \"num\", color: \"clr\" } as const);\n\nexport const xsdTextBuild = bidi({ paragraph: \"p\", custom: \"cust\" } as const);\n\n// Diagram build (p:bldDgm @bld, ST_TLDiagramBuildType) — rotation directions\n// and \"cust\" are abbreviated; the rest pass through verbatim.\nexport const xsdDiagramBuild = bidi({\n clockwise: \"cw\",\n clockwiseIn: \"cwIn\",\n clockwiseOut: \"cwOut\",\n counterclockwise: \"ccw\",\n counterclockwiseIn: \"ccwIn\",\n counterclockwiseOut: \"ccwOut\",\n custom: \"cust\",\n} as const);\n\n// Chart build (p:bldOleChart @bld and a:bldChart @bld — identical token sets,\n// ST_TLOleChartBuildType / ST_AnimationChartBuildType).\nexport const xsdChartBuild = bidi({\n seriesElement: \"seriesEl\",\n categoryElement: \"categoryEl\",\n} as const);\n\n// Diagram sub-build (a:bldDgm @bld, ST_AnimationDgmBuildType).\nexport const xsdAnimationDgmBuild = bidi({\n levelOne: \"lvlOne\",\n levelAtOnce: \"lvlAtOnce\",\n} as const);\n\nexport const xsdIterateType = bidi({ element: \"el\", word: \"wd\", letter: \"lt\" } as const);\n\nexport const xsdSlideLayoutType = bidi({\n text: \"tx\",\n twoColumnText: \"twoColTx\",\n object: \"obj\",\n sectionHeader: \"secHead\",\n table: \"tbl\",\n clipArtAndText: \"clipArtAndTx\",\n pictureText: \"picTx\",\n twoObjects: \"twoObj\",\n twoTextAndTwoObjects: \"twoTxTwoObj\",\n objectAndText: \"objTx\",\n verticalText: \"vertTx\",\n verticalTitleAndText: \"vertTitleAndTx\",\n} as const);\n\nexport const xsdTextVerticalType = bidi({\n horizontal: \"horz\",\n vertical: \"vert\",\n vertical270: \"vert270\",\n wordArtVertical: \"wordArtVert\",\n eastAsianVertical: \"eaVert\",\n mongolianVertical: \"mongolianVert\",\n wordArtVerticalRightToLeft: \"wordArtVertRtl\",\n} as const);\n\nexport const xsdOrient = bidi({ horizontal: \"horz\", vertical: \"vert\" } as const);\n\n// ST_PlaceholderType (p:ph/@type) — identity pairs title/body/subTitle/chart/\n// clipArt/media are omitted.\nexport const xsdPlaceholderType = bidi({\n centerTitle: \"ctrTitle\",\n date: \"dt\",\n slideNumber: \"sldNum\",\n footer: \"ftr\",\n header: \"hdr\",\n object: \"obj\",\n table: \"tbl\",\n diagram: \"dgm\",\n slideImage: \"sldImg\",\n picture: \"pic\",\n} as const);\n\n// ---------------------------------------------------------------------------\n// DOCX / XLSX — math run style, table width unit, totals-row aggregates\n// ---------------------------------------------------------------------------\n\nexport const xsdMathStyle = bidi({ plain: \"p\", bold: \"b\", italic: \"i\", boldItalic: \"bi\" } as const);\n\nexport const xsdTableWidthType = bidi({ twips: \"dxa\", percent: \"pct\" } as const);\n\n// ---------------------------------------------------------------------------\n// DOCX — paragraph/table justification (ST_Jc*) and shading pattern (ST_Shd)\n// ---------------------------------------------------------------------------\n\nexport const xsdJcAlignment = bidi({ numericTab: \"numTab\" } as const);\n\nexport const xsdConsolidateFunction = bidi({\n countNumbers: \"countNums\",\n standardDeviation: \"stdDev\",\n standardDeviationPopulation: \"stdDevp\",\n variance: \"var\",\n variancePopulation: \"varp\",\n} as const);\n\nexport const xsdShadingPattern = bidi({\n horizontalStripe: \"horzStripe\",\n verticalStripe: \"vertStripe\",\n reverseDiagonalStripe: \"reverseDiagStripe\",\n diagonalStripe: \"diagStripe\",\n horizontalCross: \"horzCross\",\n diagonalCross: \"diagCross\",\n thinHorizontalStripe: \"thinHorzStripe\",\n thinVerticalStripe: \"thinVertStripe\",\n thinReverseDiagonalStripe: \"thinReverseDiagStripe\",\n thinDiagonalStripe: \"thinDiagStripe\",\n thinHorizontalCross: \"thinHorzCross\",\n thinDiagonalCross: \"thinDiagCross\",\n percent5: \"pct5\",\n percent10: \"pct10\",\n percent12: \"pct12\",\n percent15: \"pct15\",\n percent20: \"pct20\",\n percent25: \"pct25\",\n percent30: \"pct30\",\n percent35: \"pct35\",\n percent37: \"pct37\",\n percent40: \"pct40\",\n percent45: \"pct45\",\n percent50: \"pct50\",\n percent55: \"pct55\",\n percent60: \"pct60\",\n percent62: \"pct62\",\n percent65: \"pct65\",\n percent70: \"pct70\",\n percent75: \"pct75\",\n percent80: \"pct80\",\n percent85: \"pct85\",\n percent87: \"pct87\",\n percent90: \"pct90\",\n percent95: \"pct95\",\n} as const);\n\nexport const xsdTotalsRowFunction = bidi({\n countNumbers: \"countNums\",\n standardDeviation: \"stdDev\",\n variance: \"var\",\n} as const);\n","/**\n * OOXML unit conversion utilities.\n *\n * @module\n */\nimport type { UniversalMeasure } from \"./values\";\n\n/**\n * Apply `fn` to `value` unless it is `undefined`; `undefined` passes through.\n *\n * Lets an optional field (e.g. `radius?: number | UniversalMeasure`) be threaded\n * through a conversion without a per-call ternary.\n */\nexport const mapOptional = <T, R>(value: T | undefined, fn: (value: T) => R): R | undefined =>\n value === undefined ? undefined : fn(value);\n\n// ---------------------------------------------------------------------------\n// Percent and angle conversions (public API ↔ OOXML scalars)\n// ---------------------------------------------------------------------------\n\n/**\n * Convert public percent (100 = 100%) to OOXML ST_Percentage scalar (1/1000).\n * Math.round ensures JSON-first float input produces exact integer output.\n */\nexport const emitPercent = (percent: number): number => Math.round(percent * 1000);\n\n/**\n * Convert OOXML ST_Percentage scalar (1/1000) to public percent.\n */\nexport const parsePercent = (value: number): number => value / 1000;\n\n/**\n * Parse an ST_Percentage attribute that may arrive as either a 1/1000th\n * integer (\"50000\" = 50%) or a percent literal (\"50%\"); both are XSD-valid.\n * Returns the caller-facing integer percent.\n */\nexport const parsePercentAttr = (raw: string | number | undefined): number | undefined => {\n if (raw === undefined) return undefined;\n const s = typeof raw === \"number\" ? String(raw) : raw;\n return s.endsWith(\"%\") ? Number(s.slice(0, -1)) : parsePercent(Number(s));\n};\n\n/**\n * Convert public degrees to OOXML ST_Angle / ST_FixedAngle scalar (1/60000).\n * Math.round ensures JSON-first float input produces exact integer output.\n */\nexport const emitAngle = (degrees: number): number => Math.round(degrees * 60000);\n\n/**\n * Convert OOXML ST_Angle / ST_FixedAngle scalar (1/60000) to public degrees.\n */\nexport const parseAngle = (value: number): number => value / 60000;\n\n// ---------------------------------------------------------------------------\n// TWIP conversions (1 TWIP = 1/20 point, used in WordprocessingML)\n// ---------------------------------------------------------------------------\n\n/**\n * Converts millimeters to TWIP (twentieths of a point).\n */\nexport const convertMillimetersToTwip = (millimeters: number): number =>\n Math.floor((millimeters / 25.4) * 72 * 20);\n\n/**\n * Converts inches to TWIP (twentieths of a point).\n */\nexport const convertInchesToTwip = (inches: number): number => Math.floor(inches * 72 * 20);\n\n// ---------------------------------------------------------------------------\n// EMU conversions (English Metric Units, used in DrawingML)\n// 1 inch = 914400 EMU, 1 pixel (96 DPI) = 9525 EMU, 1 point = 12700 EMU\n// ---------------------------------------------------------------------------\n\n/**\n * Converts pixels to EMU (96 DPI).\n */\nexport const convertPixelsToEmu = (pixels: number): number => Math.round(pixels * 9525);\n\n/**\n * Converts EMU to pixels (96 DPI).\n *\n * Returns a possibly fractional (sub-pixel) value. The integer rounding that\n * lived here before permanently discarded sub-pixel precision, which made an\n * EMU → pixel → EMU round-trip lossy (e.g. 5521960 EMU → 580 px → 5524500 EMU).\n * Keeping the fraction lets convertPixelsToEmu restore the exact original EMU.\n * Callers needing an integer pixel for display should Math.round the result.\n */\nexport const convertEmuToPixels = (emus: number): number => emus / 9525;\n\n/**\n * Converts inches to EMU.\n */\nexport const convertInchesToEmu = (inches: number): number => Math.round(inches * 914400);\n\n/**\n * Converts EMU to inches.\n */\nexport const convertEmuToInches = (emus: number): number => emus / 914400;\n\n/**\n * Converts points to EMU.\n */\nexport const convertPointsToEmu = (points: number): number => Math.round(points * 12700);\n\n/**\n * Converts EMU to points.\n */\nexport const convertEmuToPoints = (emus: number): number => emus / 12700;\n\n// ---------------------------------------------------------------------------\n// Cross-unit conversions (EMU ↔ TWIP ↔ points)\n// 1 TWIP = 1/20 point = 635 EMU\n// ---------------------------------------------------------------------------\n\n/** Converts EMU to TWIP (1 TWIP = 635 EMU). */\nexport const convertEmuToTwip = (emus: number): number => Math.round(emus / 635);\n\n/** Converts TWIP to EMU (1 TWIP = 635 EMU). */\nexport const convertTwipToEmu = (twips: number): number => twips * 635;\n\n/** Converts points to TWIP (1 point = 20 TWIP). */\nexport const convertPointsToTwip = (points: number): number => Math.round(points * 20);\n\n// ---------------------------------------------------------------------------\n// UniversalMeasure → Twips conversion\n// Used when numeric computation is needed (e.g., landscape width/height swap)\n// ---------------------------------------------------------------------------\n\n/** Parsed result of a UniversalMeasure string. */\ninterface ParsedMeasure {\n value: number;\n unit: \"mm\" | \"cm\" | \"in\" | \"pt\" | \"pc\" | \"pi\" | \"px\";\n}\n\n/**\n * Parse a UniversalMeasure string into its numeric value and unit.\n *\n * @param measure - A universal measure string like \"2.54cm\", \"-10mm\", \"1in\"\n * @returns The parsed value and unit\n * @throws Error if the format is invalid\n *\n * @example\n * ```typescript\n * parseUniversalMeasure(\"2.54cm\"); // { value: 2.54, unit: \"cm\" }\n * parseUniversalMeasure(\"-10mm\"); // { value: -10, unit: \"mm\" }\n * ```\n */\nexport const parseUniversalMeasure = (measure: string): ParsedMeasure => {\n const match = measure.match(/^(-?[0-9]+(?:\\.[0-9]+)?)(mm|cm|in|pt|pc|pi|px)$/);\n if (!match) {\n throw new Error(`Invalid universal measure: '${measure}'`);\n }\n const [, value, unit] = match;\n if (value === undefined || unit === undefined) {\n throw new Error(`Invalid universal measure: '${measure}'`);\n }\n return { value: parseFloat(value), unit: unit as ParsedMeasure[\"unit\"] };\n};\n\n/**\n * Converts a UniversalMeasure string to TWIP (twentieths of a point).\n *\n * Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc).\n *\n * @param measure - A universal measure string like \"2.54cm\", \"1in\", \"12pt\"\n * @returns The value in TWIP\n *\n * @example\n * ```typescript\n * convertUniversalMeasureToTwip(\"1in\"); // 1440\n * convertUniversalMeasureToTwip(\"2.54cm\"); // ~1440 (1 inch)\n * convertUniversalMeasureToTwip(\"72pt\"); // 1440 (1 inch = 72pt = 1440 twips)\n * ```\n */\nexport const convertUniversalMeasureToTwip = (measure: string): number => {\n const { value, unit } = parseUniversalMeasure(measure);\n switch (unit) {\n case \"mm\":\n return convertMillimetersToTwip(value);\n case \"cm\":\n return convertMillimetersToTwip(value * 10);\n case \"in\":\n return convertInchesToTwip(value);\n case \"pt\":\n return Math.floor(value * 20); // 1 point = 20 twips\n case \"pc\":\n case \"pi\":\n return Math.floor(value * 12 * 20); // 1 pica = 12 points = 240 twips\n case \"px\":\n return Math.round(value * 15); // 1px = 15twip (1in = 1440twip = 96px)\n }\n};\n\n/**\n * Converts a measurement value (number or UniversalMeasure) to TWIP.\n *\n * If the value is already a number, it is returned as-is (assumed to be in twips).\n * If the value is a UniversalMeasure string, it is converted to twips.\n *\n * Useful for accepting both `number` and `UniversalMeasure` inputs where\n * the XSD type is a union (e.g., ST_TwipsMeasure, ST_SignedTwipsMeasure).\n *\n * @param val - A numeric twip value or a universal measure string\n * @returns The value in TWIP\n *\n * @example\n * ```typescript\n * convertToTwip(1440); // 1440 (already twips)\n * convertToTwip(\"1in\"); // 1440\n * convertToTwip(\"2.54cm\"); // ~1440\n * ```\n */\nexport const convertToTwip = (val: number | UniversalMeasure): number =>\n typeof val === \"string\" ? convertUniversalMeasureToTwip(val) : val;\n\n// ---------------------------------------------------------------------------\n// UniversalMeasure → EMU conversion\n// Used in DrawingML (PPTX shapes, images, etc.)\n// ---------------------------------------------------------------------------\n\n/**\n * Converts a UniversalMeasure string to EMU (English Metric Units).\n *\n * Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc).\n *\n * @param measure - A universal measure string like \"2.54cm\", \"1in\", \"12pt\"\n * @returns The value in EMU\n *\n * @example\n * ```typescript\n * convertUniversalMeasureToEmu(\"1in\"); // 914400\n * convertUniversalMeasureToEmu(\"2.54cm\"); // 914400\n * convertUniversalMeasureToEmu(\"12pt\"); // 152400\n * ```\n */\nexport const convertUniversalMeasureToEmu = (measure: string): number => {\n const { value, unit } = parseUniversalMeasure(measure);\n switch (unit) {\n case \"mm\":\n return Math.round(value * 36000);\n case \"cm\":\n return Math.round(value * 360000);\n case \"in\":\n return convertInchesToEmu(value);\n case \"pt\":\n return convertPointsToEmu(value);\n case \"pc\":\n case \"pi\":\n return convertPointsToEmu(value * 12); // 1 pica = 12 points\n case \"px\":\n return convertPixelsToEmu(value); // 1px = 9525 EMU (96 DPI)\n }\n};\n\n/**\n * Converts a measurement value (number or UniversalMeasure) to EMU.\n *\n * Numbers are returned as-is (assumed EMU). Strings are parsed as\n * UniversalMeasure via {@link convertUniversalMeasureToEmu} — including the\n * project-only `px` unit (96 DPI). The result is always an EMU number written to\n * XML, so px never appears verbatim in the document.\n *\n * Useful for DrawingML fields where the XSD type is a union (e.g., ST_Coordinate).\n *\n * @param val - A numeric EMU value, or a UniversalMeasure string (incl. `${n}px`)\n * @returns The value in EMU\n *\n * @example\n * ```typescript\n * convertToEmu(914400); // 914400 (already EMU)\n * convertToEmu(\"1in\"); // 914400\n * convertToEmu(\"2.54cm\"); // 914400\n * convertToEmu(\"200px\"); // 1905000 (200 * 9525)\n * ```\n */\nexport const convertToEmu = (val: number | UniversalMeasure): number =>\n typeof val === \"string\" ? convertUniversalMeasureToEmu(val) : val;\n\n// ---------------------------------------------------------------------------\n// UniversalMeasure → Points / Inches conversion\n// Used in SpreadsheetML (row height in points, page margins in inches)\n// ---------------------------------------------------------------------------\n\n/**\n * Converts a UniversalMeasure string to points (1pt = 1/72 inch).\n *\n * Supports units: mm, cm, in, pt, pc (picas, 1pc = 12pt), pi (alias for pc),\n * px (96 DPI).\n */\nexport const convertUniversalMeasureToPt = (measure: string): number => {\n const { value, unit } = parseUniversalMeasure(measure);\n switch (unit) {\n case \"mm\":\n return (value / 25.4) * 72;\n case \"cm\":\n return ((value * 10) / 25.4) * 72;\n case \"in\":\n return value * 72;\n case \"pt\":\n return value;\n case \"pc\":\n case \"pi\":\n return value * 12; // 1 pica = 12 points\n case \"px\":\n return (value / 96) * 72; // 1px = 0.75pt (96 DPI)\n }\n};\n\n/**\n * Converts a measurement value (number or UniversalMeasure) to points.\n *\n * Numbers are returned as-is (assumed to be in points). Strings are parsed as\n * UniversalMeasure. Useful for SpreadsheetML fields where a number is points.\n */\nexport const convertToPt = (val: number | UniversalMeasure): number =>\n typeof val === \"string\" ? convertUniversalMeasureToPt(val) : val;\n\n/**\n * Converts a UniversalMeasure string to inches.\n *\n * Supports units: mm, cm, in, pt, pc, pi, px (96 DPI).\n */\nexport const convertUniversalMeasureToInch = (measure: string): number => {\n const { value, unit } = parseUniversalMeasure(measure);\n switch (unit) {\n case \"mm\":\n return value / 25.4;\n case \"cm\":\n return (value * 10) / 25.4;\n case \"in\":\n return value;\n case \"pt\":\n return value / 72;\n case \"pc\":\n case \"pi\":\n return (value * 12) / 72;\n case \"px\":\n return value / 96;\n }\n};\n\n/**\n * Converts a measurement value (number or UniversalMeasure) to inches.\n *\n * Numbers are returned as-is (assumed to be in inches). Useful for SpreadsheetML\n * page-margin fields where a number is inches.\n */\nexport const convertToInch = (val: number | UniversalMeasure): number =>\n typeof val === \"string\" ? convertUniversalMeasureToInch(val) : val;\n","/**\n * Unique ID generation utilities.\n *\n * @module\n */\n\nimport { sha1 } from \"@noble/hashes/legacy.js\";\nimport { bytesToHex } from \"@noble/hashes/utils.js\";\n\n/**\n * A function that generates unique sequential numeric IDs.\n */\nexport type UniqueNumericIdCreator = () => number;\n\n/**\n * Creates a unique numeric ID generator with sequential numbering.\n */\nexport const uniqueNumericIdCreator = (initial = 0): UniqueNumericIdCreator => {\n let currentCount = initial;\n return () => ++currentCount;\n};\n\nconst URL_ALPHABET = \"useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict\";\n\n/**\n * Generates a unique lowercase alphanumeric ID using crypto.getRandomValues.\n */\nexport const uniqueId = (): string => {\n const bytes = new Uint8Array(21);\n crypto.getRandomValues(bytes);\n let id = \"\";\n // URL_ALPHABET has 64 entries; the index is masked to [0,63], so the access is in-bounds.\n for (const byte of bytes) id += URL_ALPHABET[byte & 63]!;\n return id.toLowerCase();\n};\n\n/**\n * Generates a SHA-1 hash of the provided data.\n */\nexport const hashedId = (data: Uint8Array | ArrayBuffer | string): string => {\n const bytes =\n data instanceof ArrayBuffer\n ? new Uint8Array(data)\n : typeof data === \"string\"\n ? new TextEncoder().encode(data)\n : data;\n return bytesToHex(sha1(bytes));\n};\n\n/**\n * Generates a UUID v4-style unique identifier using crypto.randomUUID.\n */\nexport const uniqueUuid = (): string => crypto.randomUUID();\n","/**\n * Media path extension → image type token.\n *\n * The shared normalization for every package's image-kind media: `jpeg`\n * collapses to `jpg`, `tiff` to `tif`, unknown extensions fall back to `png`.\n * Format packages narrow the superset to their own options union at the\n * consumption site.\n *\n * @module\n */\n\n/** Image type tokens (extension-derived, superset shared by all packages). */\nexport type ImageFileType = \"jpg\" | \"png\" | \"gif\" | \"bmp\" | \"tif\" | \"ico\" | \"emf\" | \"wmf\";\n\n/** Map a media path's file extension to an image type token. */\nexport function imageTypeFromPath(path: string): ImageFileType {\n const ext = path.split(\".\").pop()?.toLowerCase() ?? \"\";\n switch (ext) {\n case \"jpg\":\n case \"jpeg\":\n return \"jpg\";\n case \"png\":\n return \"png\";\n case \"gif\":\n return \"gif\";\n case \"bmp\":\n return \"bmp\";\n case \"tif\":\n case \"tiff\":\n return \"tif\";\n case \"ico\":\n return \"ico\";\n case \"emf\":\n return \"emf\";\n case \"wmf\":\n return \"wmf\";\n default:\n return \"png\";\n }\n}\n","/**\n * Extension-uri matching for a:ext/p:ext style extension lists.\n *\n * @module\n */\n\n/**\n * Match an `@uri` attribute against a known extension uri. Producers write\n * GUID-style uris with or without the enclosing braces and in mixed case —\n * both spellings denote the same extension, so compare brace-stripped and\n * case-insensitively.\n */\nexport function extUriMatches(actual: string | undefined, expected: string): boolean {\n if (actual === undefined) return false;\n const norm = (uri: string) => uri.replace(/^[{]+|[}]+$/g, \"\").toLowerCase();\n return norm(actual) === norm(expected);\n}\n"],"mappings":"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"}
|