@office-open/docx 0.10.2 → 0.10.3

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.
@@ -1,6 +1,6 @@
1
- import { DOCX_PARTS, Relationships, TargetModeType, ThemeColor, appPropertiesDesc, blipDesc, buildContentTypeOverrides, convertEmuToPixels, convertInchesToTwip, convertPixelsToEmu, convertToEmu, convertToTwip, convertUniversalMeasureToEmu, customGeometryDesc, customPropertiesDesc, decimalNumber, derivePasswordHash, effectListDesc, eighthPointMeasureValue, fillDesc, hexColorValue, hpsMeasureValue, measurementOrPercentValue, outlineDesc, parseColorChoice, pointMeasureValue, presetGeometryDesc, signedTwipsMeasureValue, toUint8Array, twipsMeasureValue, uCharHexNumber, uniqueId, uniqueNumericIdCreator, uniqueUuid, xsdVerticalMergeRev } from "@office-open/core";
2
- import { attr, attrBool, attrMeasure, attrNum, children, colorAttr, element, escapeXml, findChild, findDeep, stringify, textOf } from "@office-open/xml";
3
- import { calculateEffectExtent, createColorElement, createEffectDag, createScene3D, createShape3D, customGeometryDesc as customGeometryDesc$1, effectListDesc as effectListDesc$1, extractBlipFillMedia, fillDesc as fillDesc$1, outlineDesc as outlineDesc$1, presetGeometryDesc as presetGeometryDesc$1, scene3DDesc, shape3DDesc, transform2DDesc } from "@office-open/core/drawingml";
1
+ import { DOCX_PARTS, Media, Relationships, TargetModeType, ThemeColor, appPropertiesDesc, blipDesc, buildContentTypeOverrides, convertEmuToPixels, convertInchesToTwip, convertPixelsToEmu, convertToEmu, convertToTwip, convertUniversalMeasureToEmu, customGeometryDesc, customPropertiesDesc, decimalNumber, derivePasswordHash, effectListDesc, eighthPointMeasureValue, fillDesc, hexColorValue, hpsMeasureValue, measurementOrPercentValue, outlineDesc, parseColorChoice, pointMeasureValue, presetGeometryDesc, signedTwipsMeasureValue, toUint8Array, twipsMeasureValue, uCharHexNumber, uniqueId, uniqueNumericIdCreator, uniqueUuid, xsdVerticalMergeRev } from "@office-open/core";
2
+ import { calculateEffectExtent, createColorElement, createEffectDag, createScene3D, createShape3D, customGeometryDesc as customGeometryDesc$1, effectListDesc as effectListDesc$1, fillDesc as fillDesc$1, outlineDesc as outlineDesc$1, presetGeometryDesc as presetGeometryDesc$1, scene3DDesc, shape3DDesc, transform2DDesc } from "@office-open/core/drawingml";
3
+ import { attr, attrBool, attrMeasure, attrNum, children, colorAttr, element, escapeXml, findChild, findFirst, stringify, textOf } from "@office-open/xml";
4
4
  import { chartSpaceDesc } from "@office-open/core/chart";
5
5
  import { createDataModel } from "@office-open/core/smartart";
6
6
  //#region src/parts/paragraph/formatting/alignment.ts
@@ -295,95 +295,6 @@ const createTransformation = (options) => ({
295
295
  rotation: options.rotation ? options.rotation * 6e4 : void 0,
296
296
  ...options.effectExtent ? { effectExtent: options.effectExtent } : {}
297
297
  });
298
- /**
299
- * Manages embedded media (images) in a document.
300
- *
301
- * Media stores all images referenced in the document and provides
302
- * access to their data for packaging into the DOCX file. Each image
303
- * is stored with a unique key for retrieval.
304
- *
305
- * @example
306
- * ```typescript
307
- * const media = new Media();
308
- * media.addImage("image1", {
309
- * type: "png",
310
- * fileName: "image1.png",
311
- * transformation: {
312
- * pixels: { x: 200, y: 100 },
313
- * emus: { x: 1828800, y: 914400 }
314
- * },
315
- * data: imageBuffer
316
- * });
317
- * const allImages = media.Array;
318
- * ```
319
- */
320
- var Media = class {
321
- map;
322
- nextMediaCounter = 0;
323
- constructor() {
324
- this.map = /* @__PURE__ */ new Map();
325
- }
326
- /**
327
- * Allocates the next sequential media file name (Office-style `image1.png`,
328
- * `image2.png`, …). The counter is package-global because media is shared
329
- * across the document, headers, and footers, matching MS Office's numbering.
330
- *
331
- * Deterministic across runs (unlike random ids) so round-trip output is stable
332
- * and diffable. Callers pair this with {@link findByContent} to reuse an
333
- * existing entry for byte-identical content before allocating a new name.
334
- *
335
- * @param type - File extension / image type token (e.g. "png", "jpg")
336
- * @returns A sequential file name like `image3.png`
337
- */
338
- nextMediaName(type) {
339
- return `image${++this.nextMediaCounter}.${type}`;
340
- }
341
- /**
342
- * Adds an image to the media collection.
343
- *
344
- * @param key - Unique identifier for this image
345
- * @param mediaData - Complete image data including file name, transformation, and raw data
346
- */
347
- addImage(key, mediaData) {
348
- this.map.set(key, mediaData);
349
- }
350
- /**
351
- * Finds an existing image with byte-identical content (content-based dedup).
352
- *
353
- * Returns the matching entry's key (fileName) so callers reuse it instead of
354
- * registering a duplicate — e.g. a VML fallback image that mirrors the Choice
355
- * blip should share one relationship/file, matching Office's output.
356
- *
357
- * @param data - Raw image bytes to search for
358
- * @returns The matching entry's key, or `undefined` if no match
359
- */
360
- findByContent(data) {
361
- for (const [key, md] of this.map) {
362
- const existing = toUint8Array(md.data);
363
- if (existing.length !== data.length) continue;
364
- let match = true;
365
- for (let i = 0; i < existing.length; i++) if (existing[i] !== data[i]) {
366
- match = false;
367
- break;
368
- }
369
- if (match) return key;
370
- }
371
- }
372
- /**
373
- * Gets all images as an array.
374
- *
375
- * @returns Read-only array of all media data in the collection
376
- */
377
- get array() {
378
- return [...this.map.values()];
379
- }
380
- };
381
- //#endregion
382
- //#region src/shared/media/data.ts
383
- /**
384
- * @ignore
385
- */
386
- const WORKAROUND2 = "";
387
298
  //#endregion
388
299
  //#region src/parts/paragraph/run/image-run.ts
389
300
  const createImageData$1 = (data, transformation, key, sourceRectangle, nonVisualProperties) => ({
@@ -558,7 +469,7 @@ const createBodyProperties = (options = {}) => {
558
469
  * (noAutofit/normAutofit/spAutoFit). prstTxWarp/scene3d/text-3D are not yet
559
470
  * parsed (later phase).
560
471
  */
561
- const parseBodyProperties = (el) => {
472
+ const parseBodyProperties = (el, ctx) => {
562
473
  const result = {};
563
474
  const rotation = attrNum(el, "rot");
564
475
  if (rotation !== void 0) result.rotation = rotation;
@@ -610,6 +521,31 @@ const parseBodyProperties = (el) => {
610
521
  result.normAutofit = normOpts;
611
522
  } else if (findChild(el, "a:spAutoFit")) result.spAutoFit = true;
612
523
  }
524
+ const prstTxWarp = findChild(el, "a:prstTxWarp");
525
+ if (prstTxWarp) {
526
+ const preset = attr(prstTxWarp, "prst") ?? "";
527
+ const avLst = findChild(prstTxWarp, "a:avLst");
528
+ const adjustments = [];
529
+ for (const gd of avLst?.elements ?? []) if (gd.type === "element" && gd.name === "a:gd") adjustments.push({
530
+ name: attr(gd, "name") ?? "",
531
+ formula: attr(gd, "fmla") ?? ""
532
+ });
533
+ result.prstTxWarp = {
534
+ preset,
535
+ ...adjustments.length > 0 ? { adjustments } : {}
536
+ };
537
+ }
538
+ const scene3d = findChild(el, "a:scene3d");
539
+ if (scene3d) result.scene3d = scene3DDesc.parse(scene3d, ctx);
540
+ const sp3d = findChild(el, "a:sp3d");
541
+ if (sp3d) result.sp3d = shape3DDesc.parse(sp3d, ctx);
542
+ else {
543
+ const flatTx = findChild(el, "a:flatTx");
544
+ if (flatTx) {
545
+ const z = attrNum(flatTx, "z");
546
+ result.flatTx = z !== void 0 ? { z } : {};
547
+ }
548
+ }
613
549
  return result;
614
550
  };
615
551
  //#endregion
@@ -1356,15 +1292,15 @@ const objectDesc = {
1356
1292
  const styleHeight = typeof heightVal === "number" ? `${heightVal}px` : heightVal;
1357
1293
  const shapeChildren = [];
1358
1294
  if (opts.iconImage) {
1359
- const iconFileName = ctx.file.media.nextMediaName(opts.iconImage.type);
1360
- const iconMediaData = {
1361
- type: opts.iconImage.type,
1362
- ...createImageData$1(toUint8Array(opts.iconImage.data), {
1295
+ const rawData = toUint8Array(opts.iconImage.data);
1296
+ const iconType = opts.iconImage.type;
1297
+ const { fileName: iconFileName } = ctx.file.media.addMedia(rawData, iconType, (fileName) => ({
1298
+ type: iconType,
1299
+ ...createImageData$1(rawData, {
1363
1300
  width: widthVal,
1364
1301
  height: heightVal
1365
- }, iconFileName)
1366
- };
1367
- ctx.file.media.addImage(iconFileName, iconMediaData);
1302
+ }, fileName)
1303
+ }));
1368
1304
  const titleAttr = opts.iconImage.title ? ` o:title="${opts.iconImage.title}"` : "";
1369
1305
  shapeChildren.push(`<v:imagedata r:id="{${iconFileName}}"${titleAttr}/>`);
1370
1306
  }
@@ -2392,9 +2328,6 @@ function stringifyRunProperties(opts) {
2392
2328
  *
2393
2329
  * @module
2394
2330
  */
2395
- function escapeAttr$2(s) {
2396
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
2397
- }
2398
2331
  const ALTCHUNK_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk";
2399
2332
  function wrapHtmlDocument(fragment) {
2400
2333
  if (/<(!DOCTYPE|html|HTML)/i.test(fragment)) return fragment;
@@ -2406,8 +2339,8 @@ const altChunkDesc = {
2406
2339
  const relId = uniqueId();
2407
2340
  const extension = opts.extension;
2408
2341
  const partPath = `afchunks/afchunk${relId}.${extension}`;
2409
- const rawData = typeof opts.data === "string" ? new TextEncoder().encode(opts.data) : opts.data;
2410
- const data = opts.contentType === "text/html" && typeof opts.data === "string" ? new TextEncoder().encode(wrapHtmlDocument(opts.data)) : rawData;
2342
+ const rawData = typeof opts.data === "string" ? toUint8Array(opts.data) : opts.data;
2343
+ const data = opts.contentType === "text/html" && typeof opts.data === "string" ? toUint8Array(wrapHtmlDocument(opts.data)) : rawData;
2411
2344
  ctx.fileData.document.relationships.addRelationship(relId, ALTCHUNK_REL_TYPE, partPath);
2412
2345
  ctx.fileData.altChunks.addAltChunk(relId, {
2413
2346
  key: relId,
@@ -2479,28 +2412,25 @@ const subDocDesc = {
2479
2412
  return { data: new Uint8Array(0) };
2480
2413
  }
2481
2414
  };
2482
- function escapeXml$2(s) {
2483
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
2484
- }
2485
2415
  function sdtListItemXml(item, forceValue) {
2486
2416
  const attrs = [];
2487
- if (item.displayText !== void 0) attrs.push(`w:displayText="${escapeXml$2(item.displayText)}"`);
2417
+ if (item.displayText !== void 0) attrs.push(`w:displayText="${escapeXml(item.displayText)}"`);
2488
2418
  const value = item.value ?? (forceValue ? item.displayText : void 0);
2489
- if (value !== void 0) attrs.push(`w:value="${escapeXml$2(value)}"`);
2419
+ if (value !== void 0) attrs.push(`w:value="${escapeXml(value)}"`);
2490
2420
  return `<w:listItem ${attrs.join(" ")}/>`;
2491
2421
  }
2492
2422
  function sdtListTypeXml(name, options) {
2493
2423
  const parts = [];
2494
2424
  if (options.items) for (const item of options.items) parts.push(sdtListItemXml(item, name === "w:dropDownList"));
2495
2425
  const attrs = [];
2496
- if (options.lastValue !== void 0) attrs.push(`w:lastValue="${escapeXml$2(options.lastValue)}"`);
2426
+ if (options.lastValue !== void 0) attrs.push(`w:lastValue="${escapeXml(options.lastValue)}"`);
2497
2427
  const attrStr = attrs.length ? " " + attrs.join(" ") : "";
2498
2428
  return parts.length ? `<${name}${attrStr}>${parts.join("")}</${name}>` : `<${name}${attrStr}/>`;
2499
2429
  }
2500
2430
  function sdtDateXml(options) {
2501
2431
  const parts = [];
2502
- if (options.dateFormat !== void 0) parts.push(`<w:dateFormat w:val="${escapeXml$2(options.dateFormat)}"/>`);
2503
- if (options.languageId !== void 0) parts.push(`<w:lid w:val="${escapeXml$2(options.languageId)}"/>`);
2432
+ if (options.dateFormat !== void 0) parts.push(`<w:dateFormat w:val="${escapeXml(options.dateFormat)}"/>`);
2433
+ if (options.languageId !== void 0) parts.push(`<w:lid w:val="${escapeXml(options.languageId)}"/>`);
2504
2434
  if (options.storeMappedDataAs !== void 0) parts.push(`<w:storeMappedDataAs w:val="${options.storeMappedDataAs}"/>`);
2505
2435
  if (options.calendar !== void 0) parts.push(`<w:calendar w:val="${options.calendar}"/>`);
2506
2436
  const attrs = [];
@@ -2509,14 +2439,14 @@ function sdtDateXml(options) {
2509
2439
  return parts.length ? `<w:date${attrStr}>${parts.join("")}</w:date>` : `<w:date${attrStr}/>`;
2510
2440
  }
2511
2441
  function sdtDataBindingXml(options) {
2512
- const attrs = [`w:xpath="${escapeXml$2(options.xpath)}"`, `w:storeItemID="${escapeXml$2(options.storeItemID)}"`];
2513
- if (options.prefixMappings !== void 0) attrs.push(`w:prefixMappings="${escapeXml$2(options.prefixMappings)}"`);
2442
+ const attrs = [`w:xpath="${escapeXml(options.xpath)}"`, `w:storeItemID="${escapeXml(options.storeItemID)}"`];
2443
+ if (options.prefixMappings !== void 0) attrs.push(`w:prefixMappings="${escapeXml(options.prefixMappings)}"`);
2514
2444
  return `<w:dataBinding ${attrs.join(" ")}/>`;
2515
2445
  }
2516
2446
  function sdtDocPartXml(name, options) {
2517
2447
  const parts = [];
2518
- if (options.gallery !== void 0) parts.push(`<w:docPartGallery w:val="${escapeXml$2(options.gallery)}"/>`);
2519
- if (options.category !== void 0) parts.push(`<w:docPartCategory w:val="${escapeXml$2(options.category)}"/>`);
2448
+ if (options.gallery !== void 0) parts.push(`<w:docPartGallery w:val="${escapeXml(options.gallery)}"/>`);
2449
+ if (options.category !== void 0) parts.push(`<w:docPartCategory w:val="${escapeXml(options.category)}"/>`);
2520
2450
  if (options.unique !== void 0) parts.push(options.unique ? "<w:docPartUnique/>" : "<w:docPartUnique w:val=\"0\"/>");
2521
2451
  return parts.length ? `<${name}>${parts.join("")}</${name}>` : `<${name}/>`;
2522
2452
  }
@@ -2543,18 +2473,18 @@ const DEFAULT_UNCHECKED = {
2543
2473
  function sdtCheckboxXml(opts) {
2544
2474
  const checked = opts.checkedState ?? DEFAULT_CHECKED;
2545
2475
  const unchecked = opts.uncheckedState ?? DEFAULT_UNCHECKED;
2546
- return `<w14:checkbox ${W14_NS}>${(opts.checked ? "<w14:checked/>" : "<w14:checked w14:val=\"0\"/>") + `<w14:checkedState w14:val="${escapeXml$2(checked.val)}" w14:font="${escapeXml$2(checked.font ?? CHECKBOX_FONT)}"/><w14:uncheckedState w14:val="${escapeXml$2(unchecked.val)}" w14:font="${escapeXml$2(unchecked.font ?? CHECKBOX_FONT)}"/>`}</w14:checkbox>`;
2476
+ return `<w14:checkbox ${W14_NS}>${(opts.checked ? "<w14:checked/>" : "<w14:checked w14:val=\"0\"/>") + `<w14:checkedState w14:val="${escapeXml(checked.val)}" w14:font="${escapeXml(checked.font ?? CHECKBOX_FONT)}"/><w14:uncheckedState w14:val="${escapeXml(unchecked.val)}" w14:font="${escapeXml(unchecked.font ?? CHECKBOX_FONT)}"/>`}</w14:checkbox>`;
2547
2477
  }
2548
2478
  /** Build the run that renders a checkbox content control's current state symbol. */
2549
2479
  function checkboxSymbolRunInner(cb) {
2550
2480
  const symbol = cb.checked ?? false ? cb.checkedState ?? DEFAULT_CHECKED : cb.uncheckedState ?? DEFAULT_UNCHECKED;
2551
- const font = escapeXml$2(symbol.font ?? CHECKBOX_FONT);
2552
- return `<w:r><w:rPr><w:rFonts w:ascii="${font}" w:hAnsi="${font}"/></w:rPr><w:t>${escapeXml$2(String.fromCodePoint(parseInt(symbol.val, 16)))}</w:t></w:r>`;
2481
+ const font = escapeXml(symbol.font ?? CHECKBOX_FONT);
2482
+ return `<w:r><w:rPr><w:rFonts w:ascii="${font}" w:hAnsi="${font}"/></w:rPr><w:t>${escapeXml(String.fromCodePoint(parseInt(symbol.val, 16)))}</w:t></w:r>`;
2553
2483
  }
2554
2484
  function stringifySdtPr(opts) {
2555
2485
  const parts = [];
2556
- if (opts.alias !== void 0) parts.push(`<w:alias w:val="${escapeXml$2(opts.alias)}"/>`);
2557
- if (opts.tag !== void 0) parts.push(`<w:tag w:val="${escapeXml$2(opts.tag)}"/>`);
2486
+ if (opts.alias !== void 0) parts.push(`<w:alias w:val="${escapeXml(opts.alias)}"/>`);
2487
+ if (opts.tag !== void 0) parts.push(`<w:tag w:val="${escapeXml(opts.tag)}"/>`);
2558
2488
  if (opts.id !== void 0) parts.push(`<w:id w:val="${opts.id}"/>`);
2559
2489
  if (opts.lock !== void 0) parts.push(`<w:lock w:val="${opts.lock}"/>`);
2560
2490
  if (opts.temporary !== void 0) parts.push(onOffAttr("w:temporary", opts.temporary));
@@ -2787,10 +2717,10 @@ const sdtBlockDesc = {
2787
2717
  };
2788
2718
  function buildCustomXmlPropertiesXml(pr) {
2789
2719
  const parts = ["<w:customXmlPr>"];
2790
- if (pr.placeholder !== void 0) parts.push(`<w:placeholder w:val="${escapeAttr$2(pr.placeholder)}"/>`);
2720
+ if (pr.placeholder !== void 0) parts.push(`<w:placeholder w:val="${escapeXml(pr.placeholder)}"/>`);
2791
2721
  if (pr.attributes) for (const attr of pr.attributes) {
2792
- const attrParts = [`w:name="${escapeAttr$2(attr.name)}"`, `w:val="${escapeAttr$2(attr.val)}"`];
2793
- if (attr.uri !== void 0) attrParts.push(`w:uri="${escapeAttr$2(attr.uri)}"`);
2722
+ const attrParts = [`w:name="${escapeXml(attr.name)}"`, `w:val="${escapeXml(attr.val)}"`];
2723
+ if (attr.uri !== void 0) attrParts.push(`w:uri="${escapeXml(attr.uri)}"`);
2794
2724
  parts.push(`<w:attr ${attrParts.join(" ")}/>`);
2795
2725
  }
2796
2726
  parts.push("</w:customXmlPr>");
@@ -2799,10 +2729,14 @@ function buildCustomXmlPropertiesXml(pr) {
2799
2729
  /**
2800
2730
  * Serialize the common customXml shell (element/uri/customXmlPr) wrapping
2801
2731
  * arbitrary content. Shared by all four customXml levels (block/run/row/cell).
2732
+ *
2733
+ * @deprecated Microsoft Word removed support for `w:customXml` inline markup on
2734
+ * 2010-01-10 (i4i Inc. v. Microsoft ruling); Word deletes these elements on
2735
+ * open. Prefer content controls (`w:sdt`) or a `customXml` part.
2802
2736
  */
2803
2737
  function stringifyCustomXmlShell(opts, contentXml) {
2804
- const attrs = [`w:element="${escapeAttr$2(opts.element)}"`];
2805
- if (opts.uri !== void 0) attrs.push(`w:uri="${escapeAttr$2(opts.uri)}"`);
2738
+ const attrs = [`w:element="${escapeXml(opts.element)}"`];
2739
+ if (opts.uri !== void 0) attrs.push(`w:uri="${escapeXml(opts.uri)}"`);
2806
2740
  const prXml = opts.customXmlPr ? buildCustomXmlPropertiesXml(opts.customXmlPr) : "";
2807
2741
  return `<w:customXml ${attrs.join(" ")}>${prXml}${contentXml}</w:customXml>`;
2808
2742
  }
@@ -4264,15 +4198,15 @@ function stringifyMathInput(value) {
4264
4198
  if ("integral" in value) return stringifyNAry(value.integral, "∫");
4265
4199
  if ("limitLower" in value) {
4266
4200
  const opts = value.limitLower;
4267
- return `<m:limLow>${opts.properties ? "" : ""}<m:e>${stringifyChildren(opts.children)}</m:e><m:lim>${stringifyChildren(opts.limit)}</m:lim></m:limLow>`;
4201
+ return `<m:limLow><m:e>${stringifyChildren(opts.children)}</m:e><m:lim>${stringifyChildren(opts.limit)}</m:lim></m:limLow>`;
4268
4202
  }
4269
4203
  if ("limitUpper" in value) {
4270
4204
  const opts = value.limitUpper;
4271
- return `<m:limUpp>${opts.properties ? "" : ""}<m:e>${stringifyChildren(opts.children)}</m:e><m:lim>${stringifyChildren(opts.limit)}</m:lim></m:limUpp>`;
4205
+ return `<m:limUpp><m:e>${stringifyChildren(opts.children)}</m:e><m:lim>${stringifyChildren(opts.limit)}</m:lim></m:limUpp>`;
4272
4206
  }
4273
4207
  if ("function" in value) {
4274
4208
  const opts = value.function;
4275
- return `<m:func>${opts.properties ? "" : ""}<m:fName>${stringifyChildren(opts.name)}</m:fName><m:e>${stringifyChildren(opts.children)}</m:e></m:func>`;
4209
+ return `<m:func><m:fName>${stringifyChildren(opts.name)}</m:fName><m:e>${stringifyChildren(opts.children)}</m:e></m:func>`;
4276
4210
  }
4277
4211
  if ("matrix" in value) {
4278
4212
  const opts = value.matrix;
@@ -4836,13 +4770,17 @@ function stringifyBodyChild(child, ctx) {
4836
4770
  if ("customXml" in child) return customXmlBlockDesc.stringify(child.customXml, ctx) ?? "";
4837
4771
  if ("bookmarkStart" in child) {
4838
4772
  const bs = child.bookmarkStart;
4839
- const bsDisp = bs.displacedByCustomXml ? ` w:displacedByCustomXml="${bs.displacedByCustomXml}"` : "";
4840
- return `<w:bookmarkStart w:id="${bs.id}" w:name="${bs.name}"${bsDisp}/>`;
4773
+ const a = [`w:id="${bs.id}"`, `w:name="${escapeXml(bs.name)}"`];
4774
+ if (bs.displacedByCustomXml) a.push(`w:displacedByCustomXml="${bs.displacedByCustomXml}"`);
4775
+ if (bs.colFirst !== void 0) a.push(`w:colFirst="${bs.colFirst}"`);
4776
+ if (bs.colLast !== void 0) a.push(`w:colLast="${bs.colLast}"`);
4777
+ return `<w:bookmarkStart ${a.join(" ")}/>`;
4841
4778
  }
4842
4779
  if ("bookmarkEnd" in child) {
4843
4780
  const be = child.bookmarkEnd;
4844
- const beDisp = be.displacedByCustomXml ? ` w:displacedByCustomXml="${be.displacedByCustomXml}"` : "";
4845
- return `<w:bookmarkEnd w:id="${be.id}"${beDisp}/>`;
4781
+ const a = [`w:id="${be.id}"`];
4782
+ if (be.displacedByCustomXml) a.push(`w:displacedByCustomXml="${be.displacedByCustomXml}"`);
4783
+ return `<w:bookmarkEnd ${a.join(" ")}/>`;
4846
4784
  }
4847
4785
  if ("rawXml" in child) return child.rawXml;
4848
4786
  throw new Error("Unknown section child type");
@@ -4851,21 +4789,25 @@ function stringifyBodyChild(child, ctx) {
4851
4789
  const vmlStyleMap = styleToKeyMap;
4852
4790
  function stringifyDocumentBackground(opts, ctx) {
4853
4791
  if (opts.rawXml) {
4854
- if (opts.rawMedia) for (const m of opts.rawMedia) ctx.file.media.addImage(m.fileName, {
4855
- type: m.type,
4856
- data: toUint8Array(m.data),
4857
- fileName: m.fileName,
4858
- transformation: {
4859
- emus: {
4860
- x: 0,
4861
- y: 0
4862
- },
4863
- pixels: {
4864
- x: 0,
4865
- y: 0
4792
+ if (opts.rawMedia) for (const m of opts.rawMedia) {
4793
+ const data = toUint8Array(m.data);
4794
+ const entry = ctx.file.media.addMedia(data, m.type, (fileName) => ({
4795
+ type: m.type,
4796
+ data,
4797
+ fileName,
4798
+ transformation: {
4799
+ emus: {
4800
+ x: 0,
4801
+ y: 0
4802
+ },
4803
+ pixels: {
4804
+ x: 0,
4805
+ y: 0
4806
+ }
4866
4807
  }
4867
- }
4868
- });
4808
+ }), m.fileName);
4809
+ if (entry.fileName !== m.fileName) opts.rawXml = opts.rawXml.split(`{${m.fileName}}`).join(`{${entry.fileName}}`);
4810
+ }
4869
4811
  return opts.rawXml;
4870
4812
  }
4871
4813
  const attrs = [];
@@ -4875,12 +4817,12 @@ function stringifyDocumentBackground(opts, ctx) {
4875
4817
  if (opts.themeTint !== void 0) attrs.push(`w:themeTint="${uCharHexNumber(opts.themeTint)}"`);
4876
4818
  const attrStr = attrs.join(" ");
4877
4819
  if (opts.image) {
4878
- const fileName = ctx.file.media.nextMediaName(opts.image.type);
4879
- const rawData = toUint8Array(opts.image.data);
4880
- ctx.file.media.addImage(fileName, {
4881
- type: opts.image.type,
4820
+ const image = opts.image;
4821
+ const rawData = toUint8Array(image.data);
4822
+ const { fileName } = ctx.file.media.addMedia(rawData, image.type, (name) => ({
4823
+ type: image.type,
4882
4824
  data: rawData,
4883
- fileName,
4825
+ fileName: name,
4884
4826
  transformation: {
4885
4827
  emus: {
4886
4828
  x: 0,
@@ -4891,7 +4833,7 @@ function stringifyDocumentBackground(opts, ctx) {
4891
4833
  y: 0
4892
4834
  }
4893
4835
  }
4894
- });
4836
+ }));
4895
4837
  return `<w:background ${attrStr}>${`<v:background id="_x0000_s1025"><v:fill r:id="{${fileName}}" o:title="${fileName}" recolor="t" type="frame"/></v:background>`}</w:background>`;
4896
4838
  }
4897
4839
  return `<w:background ${attrStr}/>`;
@@ -5334,6 +5276,12 @@ function parseMoveRangeStart(el) {
5334
5276
  if (author !== void 0) m.author = author;
5335
5277
  const date = attr(el, "w:date");
5336
5278
  if (date !== void 0) m.date = date;
5279
+ const disp = attr(el, "w:displacedByCustomXml");
5280
+ if (disp === "before" || disp === "after") m.displacedByCustomXml = disp;
5281
+ const colFirst = attrNum(el, "w:colFirst");
5282
+ if (colFirst !== void 0) m.colFirst = colFirst;
5283
+ const colLast = attrNum(el, "w:colLast");
5284
+ if (colLast !== void 0) m.colLast = colLast;
5337
5285
  return m;
5338
5286
  }
5339
5287
  /** Parse a customXml range start (Ins/Del/MoveFrom/MoveTo). */
@@ -5347,6 +5295,15 @@ function parseCustomXmlRangeStart(el) {
5347
5295
  if (date !== void 0) m.date = date;
5348
5296
  return m;
5349
5297
  }
5298
+ /** Parse a CT_MarkupRange end marker (id + displacedByCustomXml). */
5299
+ function parseMarkupRangeOptions(el) {
5300
+ const id = attrNum(el, "w:id");
5301
+ if (id === void 0) return void 0;
5302
+ const m = { id };
5303
+ const disp = attr(el, "w:displacedByCustomXml");
5304
+ if (disp === "before" || disp === "after") m.displacedByCustomXml = disp;
5305
+ return m;
5306
+ }
5350
5307
  /**
5351
5308
  * Parse a w:p element into ParagraphOptions.
5352
5309
  */
@@ -5508,6 +5465,10 @@ function parseRunLevelChildren(elements, ctx) {
5508
5465
  };
5509
5466
  const disp = attr(child, "w:displacedByCustomXml");
5510
5467
  if (disp === "before" || disp === "after") bookmarkStart.displacedByCustomXml = disp;
5468
+ const colFirst = attrNum(child, "w:colFirst");
5469
+ if (colFirst !== void 0) bookmarkStart.colFirst = colFirst;
5470
+ const colLast = attrNum(child, "w:colLast");
5471
+ if (colLast !== void 0) bookmarkStart.colLast = colLast;
5511
5472
  childList.push({ bookmarkStart });
5512
5473
  }
5513
5474
  break;
@@ -5523,13 +5484,13 @@ function parseRunLevelChildren(elements, ctx) {
5523
5484
  break;
5524
5485
  }
5525
5486
  case "w:commentRangeStart": {
5526
- const id = attrNum(child, "w:id");
5527
- if (id !== void 0) childList.push({ commentRangeStart: id });
5487
+ const m = parseMarkupRangeOptions(child);
5488
+ if (m) childList.push({ commentRangeStart: m });
5528
5489
  break;
5529
5490
  }
5530
5491
  case "w:commentRangeEnd": {
5531
- const id = attrNum(child, "w:id");
5532
- if (id !== void 0) childList.push({ commentRangeEnd: id });
5492
+ const m = parseMarkupRangeOptions(child);
5493
+ if (m) childList.push({ commentRangeEnd: m });
5533
5494
  break;
5534
5495
  }
5535
5496
  case "w:commentReference": {
@@ -5721,8 +5682,8 @@ function parseRunLevelChildren(elements, ctx) {
5721
5682
  break;
5722
5683
  }
5723
5684
  case "w:moveFromRangeEnd": {
5724
- const id = attrNum(child, "w:id");
5725
- if (id !== void 0) childList.push({ moveFromRangeEnd: id });
5685
+ const m = parseMarkupRangeOptions(child);
5686
+ if (m) childList.push({ moveFromRangeEnd: m });
5726
5687
  break;
5727
5688
  }
5728
5689
  case "w:moveToRangeStart": {
@@ -5731,8 +5692,8 @@ function parseRunLevelChildren(elements, ctx) {
5731
5692
  break;
5732
5693
  }
5733
5694
  case "w:moveToRangeEnd": {
5734
- const id = attrNum(child, "w:id");
5735
- if (id !== void 0) childList.push({ moveToRangeEnd: id });
5695
+ const m = parseMarkupRangeOptions(child);
5696
+ if (m) childList.push({ moveToRangeEnd: m });
5736
5697
  break;
5737
5698
  }
5738
5699
  case "w:customXmlInsRangeStart": {
@@ -5841,7 +5802,7 @@ function parseParagraph(el, ctx) {
5841
5802
  * based on the graphicData URI.
5842
5803
  */
5843
5804
  function parseDrawingRun(el, ctx) {
5844
- const graphicData = findDeep(el, "a:graphicData")[0];
5805
+ const graphicData = findFirst(el, "a:graphicData");
5845
5806
  if (!graphicData) return void 0;
5846
5807
  const uri = attr(graphicData, "uri") ?? "";
5847
5808
  if (uri.includes("/chart")) return parseChartDrawing(el, ctx);
@@ -5907,8 +5868,8 @@ function readGrpSpLocks(cNvGrpSpPr) {
5907
5868
  * Returns `null` when the drawing has neither wrapper.
5908
5869
  */
5909
5870
  function parseAnchorOrInline(el) {
5910
- const inline = findDeep(el, "wp:inline")[0];
5911
- const anchor = inline ? void 0 : findDeep(el, "wp:anchor")[0];
5871
+ const inline = findFirst(el, "wp:inline");
5872
+ const anchor = inline ? void 0 : findFirst(el, "wp:anchor");
5912
5873
  const parent = inline ?? anchor;
5913
5874
  if (!parent) return null;
5914
5875
  const info = {};
@@ -5987,7 +5948,7 @@ function parseAnchorOrInline(el) {
5987
5948
  function parseImageRun(el, ctx) {
5988
5949
  const info = parseAnchorOrInline(el);
5989
5950
  if (!info) return void 0;
5990
- const blip = findDeep(el, "a:blip")[0];
5951
+ const blip = findFirst(el, "a:blip");
5991
5952
  if (!blip) return void 0;
5992
5953
  const rEmbed = attr(blip, "r:embed");
5993
5954
  if (!rEmbed) return void 0;
@@ -6007,14 +5968,14 @@ function parseImageRun(el, ctx) {
6007
5968
  if (info.altText) imageOpts.altText = info.altText;
6008
5969
  if (info.floating) imageOpts.floating = info.floating;
6009
5970
  if (info.graphicFrameLocks !== void 0) imageOpts.graphicFrameLocks = info.graphicFrameLocks;
6010
- const blipFill = findDeep(el, "pic:blipFill")[0];
5971
+ const blipFill = findFirst(el, "pic:blipFill");
6011
5972
  if (blipFill) {
6012
5973
  const srcRect = readSourceRectangle(blipFill);
6013
5974
  if (srcRect) imageOpts.sourceRectangle = srcRect;
6014
5975
  }
6015
5976
  const cNvPr = readPicCnvPr(el);
6016
5977
  if (cNvPr) imageOpts.nonVisualProperties = cNvPr;
6017
- const picSpPr = findDeep(el, "pic:spPr")[0];
5978
+ const picSpPr = findFirst(el, "pic:spPr");
6018
5979
  if (picSpPr) {
6019
5980
  const fill = readShapeFill(picSpPr, ctx);
6020
5981
  if (fill) imageOpts.fill = fill;
@@ -6065,7 +6026,7 @@ function readSourceRectangle(parent) {
6065
6026
  * undefined when there is no non-visual properties block.
6066
6027
  */
6067
6028
  function readPicCnvPr(el) {
6068
- const nvPicPr = findDeep(el, "pic:nvPicPr")[0];
6029
+ const nvPicPr = findFirst(el, "pic:nvPicPr");
6069
6030
  if (!nvPicPr) return void 0;
6070
6031
  const result = {};
6071
6032
  const cNvPr = findChild(nvPicPr, "pic:cNvPr");
@@ -6090,7 +6051,7 @@ function readPicCnvPr(el) {
6090
6051
  * through the shared descriptor.
6091
6052
  */
6092
6053
  function readShapeFill(parent, ctx) {
6093
- if (!(findChild(parent, "a:noFill") ?? findChild(parent, "a:solidFill") ?? findChild(parent, "a:gradFill") ?? findChild(parent, "a:pattFill") ?? findChild(parent, "a:grpFill"))) return void 0;
6054
+ if (!(findChild(parent, "a:noFill") ?? findChild(parent, "a:solidFill") ?? findChild(parent, "a:gradFill") ?? findChild(parent, "a:pattFill") ?? findChild(parent, "a:grpFill") ?? findChild(parent, "a:blipFill"))) return void 0;
6094
6055
  return fillDesc.parse(parent, ctx);
6095
6056
  }
6096
6057
  /**
@@ -6129,7 +6090,7 @@ function parseShapeStyle(styleEl, ctx) {
6129
6090
  */
6130
6091
  function parseWpsShapeCore(wspEl, ctx) {
6131
6092
  const result = {};
6132
- const txbxContent = findDeep(wspEl, "w:txbxContent")[0];
6093
+ const txbxContent = findFirst(wspEl, "w:txbxContent");
6133
6094
  const children = [];
6134
6095
  if (txbxContent) {
6135
6096
  for (const child of txbxContent.elements ?? []) if (child.name === "w:p") children.push(parseParagraph(child, ctx));
@@ -6167,9 +6128,13 @@ function parseWpsShapeCore(wspEl, ctx) {
6167
6128
  if (custGeom) result.customGeometry = customGeometryDesc.parse(custGeom, ctx);
6168
6129
  const prstGeom = findChild(spPr, "a:prstGeom");
6169
6130
  if (prstGeom) result.presetGeometry = presetGeometryDesc.parse(prstGeom, ctx);
6131
+ const scene3d = findChild(spPr, "a:scene3d");
6132
+ if (scene3d) result.scene3d = scene3DDesc.parse(scene3d, ctx);
6133
+ const sp3d = findChild(spPr, "a:sp3d");
6134
+ if (sp3d) result.shape3d = shape3DDesc.parse(sp3d, ctx);
6170
6135
  }
6171
6136
  const bodyPr = findChild(wspEl, "wps:bodyPr");
6172
- if (bodyPr) result.bodyProperties = parseBodyProperties(bodyPr);
6137
+ if (bodyPr) result.bodyProperties = parseBodyProperties(bodyPr, ctx);
6173
6138
  const styleEl = findChild(wspEl, "wps:style");
6174
6139
  if (styleEl) result.style = parseShapeStyle(styleEl, ctx);
6175
6140
  return result;
@@ -6251,7 +6216,7 @@ function parseWpsChildMediaData(wspEl, ctx) {
6251
6216
  * to the same image collapse to one media entry.
6252
6217
  */
6253
6218
  function parsePicChildMediaData(picEl, ctx) {
6254
- const blip = findDeep(picEl, "a:blip")[0];
6219
+ const blip = findFirst(picEl, "a:blip");
6255
6220
  if (!blip) return void 0;
6256
6221
  const rEmbed = attr(blip, "r:embed");
6257
6222
  if (!rEmbed) return void 0;
@@ -6285,7 +6250,7 @@ function parsePicChildMediaData(picEl, ctx) {
6285
6250
  * Parse a standalone wps shape drawing (graphicData URI wordprocessingShape).
6286
6251
  */
6287
6252
  function parseWpsShapeDrawing(el, ctx) {
6288
- const wsp = findDeep(el, "wps:wsp")[0];
6253
+ const wsp = findFirst(el, "wps:wsp");
6289
6254
  if (!wsp) return void 0;
6290
6255
  const info = parseAnchorOrInline(el) ?? {};
6291
6256
  const shape = {
@@ -6305,7 +6270,7 @@ function parseWpsShapeDrawing(el, ctx) {
6305
6270
  * Parse a wpg group drawing (graphicData URI wordprocessingGroup).
6306
6271
  */
6307
6272
  function parseWpgGroupDrawing(el, ctx) {
6308
- const wgp = findDeep(el, "wpg:wgp")[0];
6273
+ const wgp = findFirst(el, "wpg:wgp");
6309
6274
  if (!wgp) return void 0;
6310
6275
  const info = parseAnchorOrInline(el) ?? {};
6311
6276
  const grpSpPr = findChild(wgp, "wpg:grpSpPr");
@@ -6434,8 +6399,8 @@ function readWrap(anchor) {
6434
6399
  }
6435
6400
  }
6436
6401
  function getDrawingExtent(el) {
6437
- const inline = findDeep(el, "wp:inline")[0];
6438
- const anchor = inline ? void 0 : findDeep(el, "wp:anchor")[0];
6402
+ const inline = findFirst(el, "wp:inline");
6403
+ const anchor = inline ? void 0 : findFirst(el, "wp:anchor");
6439
6404
  const parent = inline ?? anchor;
6440
6405
  if (!parent) return {};
6441
6406
  const extent = findChild(parent, "wp:extent");
@@ -6458,7 +6423,7 @@ function lookupRId(map, rId) {
6458
6423
  if (rId.startsWith("rIdrId")) return map.get(rId.slice(3));
6459
6424
  }
6460
6425
  function parseChartDrawing(el, ctx) {
6461
- const chartRef = findDeep(el, "c:chart")[0];
6426
+ const chartRef = findFirst(el, "c:chart");
6462
6427
  if (!chartRef) return void 0;
6463
6428
  const rId = attr(chartRef, "r:id");
6464
6429
  const chartPath = lookupRId(ctx.docx.partRefs.charts, rId);
@@ -6480,9 +6445,9 @@ function parseChartXml(el) {
6480
6445
  const opts = {};
6481
6446
  const titleEl = findChild(chart, "c:title");
6482
6447
  if (titleEl) {
6483
- const rich = findDeep(titleEl, "c:rich")[0];
6448
+ const rich = findFirst(titleEl, "c:rich");
6484
6449
  if (rich) {
6485
- const t = findDeep(rich, "a:t")[0];
6450
+ const t = findFirst(rich, "a:t");
6486
6451
  if (t) {
6487
6452
  const title = textOf(t);
6488
6453
  if (title) opts.title = title;
@@ -6551,7 +6516,7 @@ function parseChartXml(el) {
6551
6516
  function extractStrCache(parent, containerName) {
6552
6517
  const container = findChild(parent, containerName);
6553
6518
  if (!container) return [];
6554
- const cache = findDeep(container, "c:strCache")[0];
6519
+ const cache = findFirst(container, "c:strCache");
6555
6520
  if (!cache) return [];
6556
6521
  const values = [];
6557
6522
  for (const pt of cache.elements ?? []) {
@@ -6567,7 +6532,7 @@ function extractStrCache(parent, containerName) {
6567
6532
  function extractNumCache(parent) {
6568
6533
  const valEl = findChild(parent, "c:val");
6569
6534
  if (!valEl) return [];
6570
- const cache = findDeep(valEl, "c:numCache")[0];
6535
+ const cache = findFirst(valEl, "c:numCache");
6571
6536
  if (!cache) return [];
6572
6537
  const values = [];
6573
6538
  for (const pt of cache.elements ?? []) {
@@ -6581,7 +6546,7 @@ function extractNumCache(parent) {
6581
6546
  return values;
6582
6547
  }
6583
6548
  function parseSmartArtDrawing(el, ctx) {
6584
- const relIds = findDeep(el, "dgm:relIds")[0];
6549
+ const relIds = findFirst(el, "dgm:relIds");
6585
6550
  if (!relIds) return void 0;
6586
6551
  const rId = attr(relIds, "r:dm");
6587
6552
  const dataPath = lookupRId(ctx.docx.partRefs.diagramData, rId);
@@ -6620,7 +6585,7 @@ function parseSmartArtDataXml(el) {
6620
6585
  if (color) opts.color = color;
6621
6586
  }
6622
6587
  } else if (type === "node" && modelId) {
6623
- const t = findDeep(pt, "a:t")[0];
6588
+ const t = findFirst(pt, "a:t");
6624
6589
  nodeMap.set(modelId, t ? textOf(t) ?? "" : "");
6625
6590
  }
6626
6591
  }
@@ -6833,7 +6798,7 @@ function stringifyWpsShape(opts, ctx) {
6833
6798
  if (opts.customGeometry) spPrParts.push(customGeometryDesc$1.stringify(opts.customGeometry, NOOP_CTX) ?? "");
6834
6799
  else if (opts.presetGeometry) spPrParts.push(presetGeometryDesc$1.stringify(opts.presetGeometry, NOOP_CTX) ?? "");
6835
6800
  else spPrParts.push("<a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom>");
6836
- if (opts.fill) spPrParts.push(fillDesc$1.stringify(opts.fill, NOOP_CTX) ?? "");
6801
+ if (opts.fill) spPrParts.push(fillDesc$1.stringify(opts.fill, ctx) ?? "");
6837
6802
  if (opts.outline) spPrParts.push(outlineDesc$1.stringify(opts.outline, NOOP_CTX) ?? "");
6838
6803
  if (opts.effectDag) spPrParts.push(createEffectDag(opts.effectDag));
6839
6804
  else if (opts.effects) spPrParts.push(effectListDesc$1.stringify(opts.effects, NOOP_CTX) ?? "");
@@ -6880,7 +6845,7 @@ function stringifyWpgGroup(opts, ctx) {
6880
6845
  const transform = opts.transformation;
6881
6846
  const grpSpPrParts = [];
6882
6847
  grpSpPrParts.push(stringifyGroupTransform2D(transform, opts.childOffset, opts.childExtent));
6883
- if (opts.fill) grpSpPrParts.push(fillDesc$1.stringify(opts.fill, NOOP_CTX) ?? "");
6848
+ if (opts.fill) grpSpPrParts.push(fillDesc$1.stringify(opts.fill, ctx) ?? "");
6884
6849
  if (opts.effects) grpSpPrParts.push(effectListDesc$1.stringify(opts.effects, NOOP_CTX) ?? "");
6885
6850
  const childXml = opts.children.map((child) => stringifyGroupChild(child, ctx)).join("");
6886
6851
  return "<wpg:wgp>" + stringifyCnvGrpSpPr(opts.groupShapeLocks) + `<wpg:grpSpPr>${grpSpPrParts.join("")}</wpg:grpSpPr>` + childXml + "</wpg:wgp>";
@@ -6920,7 +6885,7 @@ function stringifyGroupChild(child, ctx) {
6920
6885
  function stringifyNestedGroup(grp, ctx) {
6921
6886
  const grpSpPrParts = [];
6922
6887
  grpSpPrParts.push(stringifyGroupTransform2D(grp.transformation, grp.childOffset, grp.childExtent));
6923
- if (grp.fill) grpSpPrParts.push(fillDesc$1.stringify(grp.fill, NOOP_CTX) ?? "");
6888
+ if (grp.fill) grpSpPrParts.push(fillDesc$1.stringify(grp.fill, ctx) ?? "");
6924
6889
  if (grp.effects) grpSpPrParts.push(effectListDesc$1.stringify(grp.effects, NOOP_CTX) ?? "");
6925
6890
  return "<wpg:grpSp><wpg:cNvPr id=\"0\" name=\"\"/>" + stringifyCnvGrpSpPr(grp.groupShapeLocks) + `<wpg:grpSpPr>${grpSpPrParts.join("")}</wpg:grpSpPr>` + grp.children.map((c) => stringifyGroupChild(c, ctx)).join("") + "</wpg:grpSp>";
6926
6891
  }
@@ -7086,24 +7051,6 @@ function stringifyAnchor(opts, hlIds, ctx) {
7086
7051
  const drawingDesc = {
7087
7052
  kind: "custom",
7088
7053
  stringify(opts, ctx) {
7089
- if (opts.fill) {
7090
- const media = extractBlipFillMedia(opts.fill, (type) => ctx.file.media.nextMediaName(type));
7091
- if (media) ctx.file.media.addImage(media.fileName, {
7092
- data: media.data,
7093
- fileName: media.fileName,
7094
- type: media.type,
7095
- transformation: {
7096
- pixels: {
7097
- x: 0,
7098
- y: 0
7099
- },
7100
- emus: {
7101
- x: 0,
7102
- y: 0
7103
- }
7104
- }
7105
- });
7106
- }
7107
7054
  const hlIds = registerHyperlinks(opts.docProperties?.hyperlink, ctx);
7108
7055
  if (opts.floating) return stringifyAnchor(opts, hlIds, ctx);
7109
7056
  return stringifyInline(opts, hlIds, ctx);
@@ -7298,15 +7245,10 @@ function registerVmlFallbackMedia(opts, ctx) {
7298
7245
  if (!opts.vmlFallbackMedia) return;
7299
7246
  for (const m of opts.vmlFallbackMedia) {
7300
7247
  const data = toUint8Array(m.data);
7301
- const existing = ctx.file.media.findByContent(data);
7302
- if (existing) {
7303
- if (opts.vmlFallback) opts.vmlFallback = opts.vmlFallback.split(`{${m.fileName}}`).join(`{${existing}}`);
7304
- continue;
7305
- }
7306
- ctx.file.media.addImage(m.fileName, {
7248
+ const entry = ctx.file.media.addMedia(data, m.type, (fileName) => ({
7307
7249
  type: m.type,
7308
7250
  data,
7309
- fileName: m.fileName,
7251
+ fileName,
7310
7252
  transformation: {
7311
7253
  emus: {
7312
7254
  x: 0,
@@ -7317,12 +7259,109 @@ function registerVmlFallbackMedia(opts, ctx) {
7317
7259
  y: 0
7318
7260
  }
7319
7261
  }
7320
- });
7262
+ }), m.fileName);
7263
+ if (entry.fileName !== m.fileName && opts.vmlFallback) opts.vmlFallback = opts.vmlFallback.split(`{${m.fileName}}`).join(`{${entry.fileName}}`);
7321
7264
  }
7322
7265
  }
7323
7266
  /**
7324
7267
  * Build the rPr XML for a break/tab run from its structured run properties.
7325
7268
  */
7269
+ /** Shared attribute string for CT_MarkupRange end markers (commentRange, move range end). */
7270
+ function buildMarkupRangeAttrs(m) {
7271
+ const a = [`w:id="${m.id}"`];
7272
+ if (m.displacedByCustomXml) a.push(`w:displacedByCustomXml="${m.displacedByCustomXml}"`);
7273
+ return a.join(" ");
7274
+ }
7275
+ /** Shared attribute string for w:bookmarkStart (CT_Bookmark). */
7276
+ function buildBookmarkStartAttrs(bs) {
7277
+ const a = [`w:id="${bs.id}"`, `w:name="${escapeXml(bs.name)}"`];
7278
+ if (bs.displacedByCustomXml) a.push(`w:displacedByCustomXml="${bs.displacedByCustomXml}"`);
7279
+ if (bs.colFirst !== void 0) a.push(`w:colFirst="${bs.colFirst}"`);
7280
+ if (bs.colLast !== void 0) a.push(`w:colLast="${bs.colLast}"`);
7281
+ return a.join(" ");
7282
+ }
7283
+ /** Shared attribute string for w:moveFromRangeStart / w:moveToRangeStart (CT_MoveBookmark). */
7284
+ function buildMoveRangeStartAttrs(m) {
7285
+ const a = [`w:id="${m.id}"`];
7286
+ if (m.name) a.push(`w:name="${escapeXml(m.name)}"`);
7287
+ if (m.author) a.push(`w:author="${escapeXml(m.author)}"`);
7288
+ if (m.date) a.push(`w:date="${m.date}"`);
7289
+ if (m.displacedByCustomXml) a.push(`w:displacedByCustomXml="${m.displacedByCustomXml}"`);
7290
+ if (m.colFirst !== void 0) a.push(`w:colFirst="${m.colFirst}"`);
7291
+ if (m.colLast !== void 0) a.push(`w:colLast="${m.colLast}"`);
7292
+ return a.join(" ");
7293
+ }
7294
+ /** Stringify inline run/text content — the `wrap` shared by every sugar child. */
7295
+ function stringifyInlineWrap(wrap, ctx) {
7296
+ const parts = [];
7297
+ for (const item of wrap ?? []) parts.push(typeof item === "string" ? stringifyRunInline({ text: item }, ctx) : stringifyRunInline(item, ctx));
7298
+ return parts.join("");
7299
+ }
7300
+ /**
7301
+ * Expand a `{ comment }` sugar child: allocate the comment id, register the
7302
+ * comment entry (side effect, consumed when word/comments.xml is stringified),
7303
+ * and emit the range markers + anchored content + reference with one shared id.
7304
+ *
7305
+ * The caller never supplies an id — the library owns id allocation and pairing.
7306
+ */
7307
+ function stringifyCommentChild(c, ctx) {
7308
+ const id = ctx.file.comments.nextId++;
7309
+ ctx.file.comments.entries.push({
7310
+ id,
7311
+ author: c.author,
7312
+ initials: c.initials,
7313
+ date: c.date,
7314
+ children: c.children
7315
+ });
7316
+ return `<w:commentRangeStart w:id="${id}"/>` + stringifyInlineWrap(c.wrap, ctx) + `<w:commentRangeEnd w:id="${id}"/><w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="${id}"/></w:r>`;
7317
+ }
7318
+ /**
7319
+ * Expand a `{ bookmark }` sugar child: allocate the bookmark id and emit the
7320
+ * paired bookmarkStart/bookmarkEnd with the anchored content between them.
7321
+ * Bookmarks are pure markup — the only effect is the two markers.
7322
+ */
7323
+ function stringifyBookmarkChild(b, ctx) {
7324
+ const id = ctx.file.markupIds.rangeNext++;
7325
+ const startAttrs = buildBookmarkStartAttrs({
7326
+ id,
7327
+ name: b.name,
7328
+ displacedByCustomXml: b.displacedByCustomXml,
7329
+ colFirst: b.colFirst,
7330
+ colLast: b.colLast
7331
+ });
7332
+ const endAttrs = buildMarkupRangeAttrs({
7333
+ id,
7334
+ displacedByCustomXml: b.displacedByCustomXml
7335
+ });
7336
+ return `<w:bookmarkStart ${startAttrs}/>${stringifyInlineWrap(b.wrap, ctx)}<w:bookmarkEnd ${endAttrs}/>`;
7337
+ }
7338
+ /**
7339
+ * Expand a `{ moveFrom }` / `{ moveTo }` sugar child: allocate the range id and
7340
+ * the move-run id, then emit the paired range markers with the moved run between
7341
+ * them. The move run (CT_TrackChange) carries the moved content.
7342
+ */
7343
+ function stringifyMoveRangeChild(kind, opts, ctx) {
7344
+ const rangeId = ctx.file.markupIds.rangeNext++;
7345
+ const runId = ctx.file.markupIds.moveRunNext++;
7346
+ const isMoveFrom = kind === "moveFrom";
7347
+ const startTag = isMoveFrom ? "w:moveFromRangeStart" : "w:moveToRangeStart";
7348
+ const endTag = isMoveFrom ? "w:moveFromRangeEnd" : "w:moveToRangeEnd";
7349
+ const runTag = isMoveFrom ? "w:moveFrom" : "w:moveTo";
7350
+ const rangeStartAttrs = buildMoveRangeStartAttrs({
7351
+ id: rangeId,
7352
+ name: opts.name,
7353
+ author: opts.author,
7354
+ date: opts.date,
7355
+ displacedByCustomXml: opts.displacedByCustomXml,
7356
+ colFirst: opts.colFirst,
7357
+ colLast: opts.colLast
7358
+ });
7359
+ const endAttrs = buildMarkupRangeAttrs({
7360
+ id: rangeId,
7361
+ displacedByCustomXml: opts.displacedByCustomXml
7362
+ });
7363
+ return `<${startTag} ${rangeStartAttrs}/><${runTag} w:id="${runId}" w:author="${escapeXml(opts.author)}" w:date="${opts.date}">${stringifyInlineWrap(opts.wrap, ctx)}</${runTag}><${endTag} ${endAttrs}/>`;
7364
+ }
7326
7365
  function runPropertiesXml(child) {
7327
7366
  return stringifyRunProperties(child) ?? "";
7328
7367
  }
@@ -7338,19 +7377,13 @@ function stringifyChildDispatch(child, ctx) {
7338
7377
  const ref = child.endnoteReference;
7339
7378
  return `<w:r><w:rPr><w:rStyle w:val="EndnoteReference"/></w:rPr><w:endnoteReference w:id="${typeof ref === "number" ? ref : ref.id}"${typeof ref === "object" && ref.customMarkFollows ? " w:customMarkFollows=\"true\"" : ""}/></w:r>`;
7340
7379
  }
7341
- if ("commentRangeStart" in child) return `<w:commentRangeStart w:id="${child.commentRangeStart}"/>`;
7342
- if ("commentRangeEnd" in child) return `<w:commentRangeEnd w:id="${child.commentRangeEnd}"/>`;
7380
+ if ("comment" in child) return stringifyCommentChild(child.comment, ctx);
7381
+ if ("commentRangeStart" in child) return `<w:commentRangeStart ${buildMarkupRangeAttrs(child.commentRangeStart)}/>`;
7382
+ if ("commentRangeEnd" in child) return `<w:commentRangeEnd ${buildMarkupRangeAttrs(child.commentRangeEnd)}/>`;
7343
7383
  if ("commentReference" in child) return `<w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="${child.commentReference}"/></w:r>`;
7344
- if ("bookmarkStart" in child) {
7345
- const bs = child.bookmarkStart;
7346
- const bsDisp = bs.displacedByCustomXml ? ` w:displacedByCustomXml="${bs.displacedByCustomXml}"` : "";
7347
- return `<w:bookmarkStart w:id="${bs.id}" w:name="${bs.name}"${bsDisp}/>`;
7348
- }
7349
- if ("bookmarkEnd" in child) {
7350
- const be = child.bookmarkEnd;
7351
- const beDisp = be.displacedByCustomXml ? ` w:displacedByCustomXml="${be.displacedByCustomXml}"` : "";
7352
- return `<w:bookmarkEnd w:id="${be.id}"${beDisp}/>`;
7353
- }
7384
+ if ("bookmarkStart" in child) return `<w:bookmarkStart ${buildBookmarkStartAttrs(child.bookmarkStart)}/>`;
7385
+ if ("bookmarkEnd" in child) return `<w:bookmarkEnd ${buildMarkupRangeAttrs(child.bookmarkEnd)}/>`;
7386
+ if ("bookmark" in child) return stringifyBookmarkChild(child.bookmark, ctx);
7354
7387
  if ("symbolRun" in child) {
7355
7388
  const opts = child.symbolRun;
7356
7389
  return `<w:r>${stringifyRunProperties(opts) ?? ""}<w:sym w:char="${opts.char}" w:font="${opts.symbolfont ?? "Wingdings"}"/></w:r>`;
@@ -7377,27 +7410,29 @@ function stringifyChildDispatch(child, ctx) {
7377
7410
  }
7378
7411
  if ("image" in child) {
7379
7412
  const opts = child.image;
7380
- const key = ctx.file.media.nextMediaName(opts.type);
7381
7413
  const rawData = toUint8Array(opts.data);
7382
7414
  let mediaData;
7383
7415
  if (opts.type === "svg") {
7384
7416
  const fallbackData = toUint8Array(opts.fallback.data);
7385
- mediaData = {
7417
+ const fallbackType = opts.fallback.type;
7418
+ const fallback = ctx.file.media.addMedia(fallbackData, fallbackType, (fileName) => ({
7419
+ type: fallbackType,
7420
+ ...createImageData(fallbackData, opts.transformation, fileName)
7421
+ }));
7422
+ mediaData = ctx.file.media.addMedia(rawData, "svg", (fileName) => ({
7386
7423
  type: "svg",
7387
- ...createImageData(rawData, opts.transformation, key, opts.sourceRectangle, opts.nonVisualProperties),
7424
+ ...createImageData(rawData, opts.transformation, fileName, opts.sourceRectangle, opts.nonVisualProperties),
7388
7425
  useLocalDpi: opts.useLocalDpi,
7389
- fallback: {
7390
- type: opts.fallback.type,
7391
- ...createImageData(fallbackData, opts.transformation, ctx.file.media.nextMediaName(opts.fallback.type))
7392
- }
7393
- };
7394
- } else mediaData = {
7395
- type: opts.type,
7396
- ...createImageData(rawData, opts.transformation, key, opts.sourceRectangle, opts.nonVisualProperties),
7397
- useLocalDpi: opts.useLocalDpi
7398
- };
7399
- ctx.file.media.addImage(mediaData.fileName, mediaData);
7400
- if (mediaData.type === "svg") ctx.file.media.addImage(mediaData.fallback.fileName, mediaData.fallback);
7426
+ fallback
7427
+ }));
7428
+ } else {
7429
+ const type = opts.type;
7430
+ mediaData = ctx.file.media.addMedia(rawData, type, (fileName) => ({
7431
+ type,
7432
+ ...createImageData(rawData, opts.transformation, fileName, opts.sourceRectangle, opts.nonVisualProperties),
7433
+ useLocalDpi: opts.useLocalDpi
7434
+ }));
7435
+ }
7401
7436
  return wrapDrawingRun(drawingDesc.stringify({
7402
7437
  mediaData,
7403
7438
  docProperties: opts.altText,
@@ -7499,7 +7534,7 @@ function stringifyChildDispatch(child, ctx) {
7499
7534
  registerMedia(c.children);
7500
7535
  continue;
7501
7536
  }
7502
- ctx.file.media.addImage(c.fileName, c);
7537
+ ctx.file.media.addMedia(c.data, c.type, () => c, c.fileName);
7503
7538
  }
7504
7539
  };
7505
7540
  registerMedia(opts.children);
@@ -7545,6 +7580,7 @@ function stringifyChildDispatch(child, ctx) {
7545
7580
  if ("hyperlink" in child) {
7546
7581
  const hl = child.hyperlink;
7547
7582
  const childParts = [];
7583
+ if (child.text !== void 0) childParts.push(stringifyRunInline({ text: child.text }, ctx));
7548
7584
  if (hl.children) for (const rc of hl.children) if (typeof rc === "string") childParts.push(stringifyRunInline({ text: rc }, ctx));
7549
7585
  else childParts.push(stringifyRunInline(rc, ctx));
7550
7586
  const body = childParts.join("");
@@ -7583,24 +7619,12 @@ function stringifyChildDispatch(child, ctx) {
7583
7619
  return `<w:permStart ${a.join(" ")}/>`;
7584
7620
  }
7585
7621
  if ("permEnd" in child) return `<w:permEnd w:id="${child.permEnd}"/>`;
7586
- if ("moveFromRangeStart" in child) {
7587
- const m = child.moveFromRangeStart;
7588
- const a = [`w:id="${m.id}"`];
7589
- if (m.name) a.push(`w:name="${escapeXml(m.name)}"`);
7590
- if (m.author) a.push(`w:author="${escapeXml(m.author)}"`);
7591
- if (m.date) a.push(`w:date="${m.date}"`);
7592
- return `<w:moveFromRangeStart ${a.join(" ")}/>`;
7593
- }
7594
- if ("moveFromRangeEnd" in child) return `<w:moveFromRangeEnd w:id="${child.moveFromRangeEnd}"/>`;
7595
- if ("moveToRangeStart" in child) {
7596
- const m = child.moveToRangeStart;
7597
- const a = [`w:id="${m.id}"`];
7598
- if (m.name) a.push(`w:name="${escapeXml(m.name)}"`);
7599
- if (m.author) a.push(`w:author="${escapeXml(m.author)}"`);
7600
- if (m.date) a.push(`w:date="${m.date}"`);
7601
- return `<w:moveToRangeStart ${a.join(" ")}/>`;
7602
- }
7603
- if ("moveToRangeEnd" in child) return `<w:moveToRangeEnd w:id="${child.moveToRangeEnd}"/>`;
7622
+ if ("moveFromRangeStart" in child) return `<w:moveFromRangeStart ${buildMoveRangeStartAttrs(child.moveFromRangeStart)}/>`;
7623
+ if ("moveFromRangeEnd" in child) return `<w:moveFromRangeEnd ${buildMarkupRangeAttrs(child.moveFromRangeEnd)}/>`;
7624
+ if ("moveToRangeStart" in child) return `<w:moveToRangeStart ${buildMoveRangeStartAttrs(child.moveToRangeStart)}/>`;
7625
+ if ("moveToRangeEnd" in child) return `<w:moveToRangeEnd ${buildMarkupRangeAttrs(child.moveToRangeEnd)}/>`;
7626
+ if ("moveFrom" in child) return stringifyMoveRangeChild("moveFrom", child.moveFrom, ctx);
7627
+ if ("moveTo" in child) return stringifyMoveRangeChild("moveTo", child.moveTo, ctx);
7604
7628
  if ("movedFrom" in child) {
7605
7629
  const { id, author, date, children } = child.movedFrom;
7606
7630
  const body = children.map((c) => stringifyRunInline(typeof c === "string" ? { text: c } : c, ctx)).join("");
@@ -9822,10 +9846,6 @@ const HeaderFooterType = {
9822
9846
  const createHeaderFooterReference = (type, options) => `<${type} r:id="rId${options.id}" w:type="${options.type || HeaderFooterReferenceType.DEFAULT}"/>`;
9823
9847
  //#endregion
9824
9848
  //#region src/parts/styles/factory.ts
9825
- /** Escape special XML characters. */
9826
- function esc(s) {
9827
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
9828
- }
9829
9849
  /**
9830
9850
  * Build CT_Style style-level children (name…rsid), shared by paragraph/character/table styles.
9831
9851
  * Order follows CT_Style sequence: name, aliases, basedOn, next, link, autoRedefine, hidden,
@@ -9833,11 +9853,11 @@ function esc(s) {
9833
9853
  * personalReply, rsid.
9834
9854
  */
9835
9855
  function stringifyStyleLevelChildren(opts) {
9836
- const parts = [`<w:name w:val="${esc(opts.name ?? opts.id ?? "")}"/>`];
9837
- if (opts.aliases) parts.push(`<w:aliases w:val="${esc(opts.aliases)}"/>`);
9838
- if (opts.basedOn) parts.push(`<w:basedOn w:val="${esc(opts.basedOn)}"/>`);
9839
- if (opts.next) parts.push(`<w:next w:val="${esc(opts.next)}"/>`);
9840
- if (opts.link) parts.push(`<w:link w:val="${esc(opts.link)}"/>`);
9856
+ const parts = [`<w:name w:val="${escapeXml(opts.name ?? opts.id ?? "")}"/>`];
9857
+ if (opts.aliases) parts.push(`<w:aliases w:val="${escapeXml(opts.aliases)}"/>`);
9858
+ if (opts.basedOn) parts.push(`<w:basedOn w:val="${escapeXml(opts.basedOn)}"/>`);
9859
+ if (opts.next) parts.push(`<w:next w:val="${escapeXml(opts.next)}"/>`);
9860
+ if (opts.link) parts.push(`<w:link w:val="${escapeXml(opts.link)}"/>`);
9841
9861
  if (opts.autoRedefine) parts.push("<w:autoRedefine/>");
9842
9862
  if (opts.hidden) parts.push("<w:hidden/>");
9843
9863
  if (opts.uiPriority !== void 0) parts.push(`<w:uiPriority w:val="${opts.uiPriority}"/>`);
@@ -9851,6 +9871,17 @@ function stringifyStyleLevelChildren(opts) {
9851
9871
  if (opts.rsid) parts.push(`<w:rsid w:val="${opts.rsid}"/>`);
9852
9872
  return parts.join("");
9853
9873
  }
9874
+ /**
9875
+ * Build the `<w:style>` opening tag: type/styleId plus the optional w:default
9876
+ * and w:customStyle element attributes (CT_Style). Shared by paragraph/
9877
+ * character/table styles.
9878
+ */
9879
+ function styleOpenTag(type, opts) {
9880
+ let attrs = ` w:type="${type}" w:styleId="${escapeXml(opts.id ?? "")}"`;
9881
+ if (opts.default) attrs += " w:default=\"1\"";
9882
+ if (opts.customStyle) attrs += " w:customStyle=\"1\"";
9883
+ return `<w:style${attrs}>`;
9884
+ }
9854
9885
  /** Build `<w:style>` XML for a paragraph style. */
9855
9886
  function stringifyParagraphStyle(opts) {
9856
9887
  const children = [stringifyStyleLevelChildren(opts)];
@@ -9858,14 +9889,14 @@ function stringifyParagraphStyle(opts) {
9858
9889
  if (pPr) children.push(pPr);
9859
9890
  const rPr = stringifyRunProperties(opts.run);
9860
9891
  if (rPr) children.push(rPr);
9861
- return `<w:style w:type="paragraph" w:styleId="${esc(opts.id)}">${children.join("")}</w:style>`;
9892
+ return `${styleOpenTag("paragraph", opts)}${children.join("")}</w:style>`;
9862
9893
  }
9863
9894
  /** Build `<w:style>` XML for a character style. */
9864
9895
  function stringifyCharacterStyle(opts) {
9865
9896
  const children = [stringifyStyleLevelChildren(opts)];
9866
9897
  const rPr = stringifyRunProperties(opts.run);
9867
9898
  if (rPr) children.push(rPr);
9868
- return `<w:style w:type="character" w:styleId="${esc(opts.id)}">${children.join("")}</w:style>`;
9899
+ return `${styleOpenTag("character", opts)}${children.join("")}</w:style>`;
9869
9900
  }
9870
9901
  /** Build `<w:tblStylePr>` XML for a conditional table style format. */
9871
9902
  function stringifyConditionalTableStyle(opts) {
@@ -9908,7 +9939,16 @@ function stringifyTableStyle(opts) {
9908
9939
  if (tcPr) children.push(tcPr);
9909
9940
  }
9910
9941
  for (const cf of opts.conditionalFormats ?? []) children.push(stringifyConditionalTableStyle(cf));
9911
- return `<w:style w:type="table" w:styleId="${esc(opts.id)}">${children.join("")}</w:style>`;
9942
+ return `${styleOpenTag("table", opts)}${children.join("")}</w:style>`;
9943
+ }
9944
+ /** Build `<w:style type="numbering">` XML for a numbering style. */
9945
+ function stringifyNumberingStyle(opts) {
9946
+ const children = [stringifyStyleLevelChildren(opts)];
9947
+ const pPr = stringifyParagraphProperties(opts.paragraph).xml;
9948
+ if (pPr) children.push(pPr);
9949
+ const rPr = stringifyRunProperties(opts.run);
9950
+ if (rPr) children.push(rPr);
9951
+ return `${styleOpenTag("numbering", opts)}${children.join("")}</w:style>`;
9912
9952
  }
9913
9953
  /** Resolve a user override for heading level N (1-9) from default styles options. */
9914
9954
  function headingOverride(options, level) {
@@ -9925,45 +9965,6 @@ function headingOverride(options, level) {
9925
9965
  default: return;
9926
9966
  }
9927
9967
  }
9928
- /**
9929
- * Maps DefaultStylesOptions override fields to every built-in styleId the
9930
- * factory (re)emits when that field is provided — the main style plus its
9931
- * linked character style (e.g. heading1 -> Heading1 + Heading1Char).
9932
- */
9933
- const DEFAULT_STYLE_FIELDS = [
9934
- ["title", ["Title", "TitleChar"]],
9935
- ["subtitle", ["Subtitle", "SubtitleChar"]],
9936
- ["heading1", ["Heading1", "Heading1Char"]],
9937
- ["heading2", ["Heading2", "Heading2Char"]],
9938
- ["heading3", ["Heading3", "Heading3Char"]],
9939
- ["heading4", ["Heading4", "Heading4Char"]],
9940
- ["heading5", ["Heading5", "Heading5Char"]],
9941
- ["heading6", ["Heading6", "Heading6Char"]],
9942
- ["heading7", ["Heading7", "Heading7Char"]],
9943
- ["heading8", ["Heading8", "Heading8Char"]],
9944
- ["heading9", ["Heading9", "Heading9Char"]],
9945
- ["listParagraph", ["ListParagraph"]],
9946
- ["quote", ["Quote", "QuoteChar"]],
9947
- ["strong", ["Strong"]],
9948
- ["emphasis", ["Emphasis"]]
9949
- ];
9950
- /**
9951
- * Reverse map: main built-in styleId -> the DefaultStylesOptions field that
9952
- * overrides it. Linked char ids (Heading1Char, TitleChar, ...) are excluded —
9953
- * they ride along with their main style.
9954
- */
9955
- const STYLE_ID_TO_DEFAULT_FIELD = Object.fromEntries(DEFAULT_STYLE_FIELDS.map(([field, [mainId]]) => [mainId, field]));
9956
- /**
9957
- * Collect every styleId the factory (re)emits for the default-styles fields the
9958
- * user explicitly provided — including linked character styles, so the
9959
- * round-trip path drops the matching verbatim entries (no duplicate styleId).
9960
- */
9961
- function collectDefaultOverrideIds(defaultOpts) {
9962
- const ids = /* @__PURE__ */ new Set();
9963
- if (!defaultOpts) return ids;
9964
- for (const [field, styleIds] of DEFAULT_STYLE_FIELDS) if (defaultOpts[field] !== void 0) for (const id of styleIds) ids.add(id);
9965
- return ids;
9966
- }
9967
9968
  /** Build `<w:docDefaults>` XML matching Word's default settings. */
9968
9969
  function stringifyDocDefaults(opts) {
9969
9970
  const children = [];
@@ -9992,6 +9993,10 @@ var DefaultStylesFactory = class {
9992
9993
  }
9993
9994
  build(options) {
9994
9995
  const importedStyles = [];
9996
+ const paragraphStyles = [];
9997
+ const characterStyles = [];
9998
+ const tableStyles = [];
9999
+ const numberingStyles = [];
9995
10000
  const initialAttributes = {
9996
10001
  "xmlns:mc": "http://schemas.openxmlformats.org/markup-compatibility/2006",
9997
10002
  "xmlns:r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
@@ -10002,70 +10007,76 @@ var DefaultStylesFactory = class {
10002
10007
  };
10003
10008
  importedStyles.push({ _raw: stringifyDocDefaults(options.document ?? {}) });
10004
10009
  importedStyles.push({ _raw: "<w:latentStyles w:defLockedState=\"0\" w:defUIPriority=\"99\" w:defSemiHidden=\"0\" w:defUnhideWhenUsed=\"0\" w:defQFormat=\"0\" w:count=\"376\"><w:lsdException w:name=\"Normal\" w:uiPriority=\"0\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 1\" w:uiPriority=\"9\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 2\" w:semiHidden=\"1\" w:uiPriority=\"9\" w:unhideWhenUsed=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 3\" w:semiHidden=\"1\" w:uiPriority=\"9\" w:unhideWhenUsed=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 4\" w:semiHidden=\"1\" w:uiPriority=\"9\" w:unhideWhenUsed=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 5\" w:semiHidden=\"1\" w:uiPriority=\"9\" w:unhideWhenUsed=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 6\" w:semiHidden=\"1\" w:uiPriority=\"9\" w:unhideWhenUsed=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 7\" w:semiHidden=\"1\" w:uiPriority=\"9\" w:unhideWhenUsed=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 8\" w:semiHidden=\"1\" w:uiPriority=\"9\" w:unhideWhenUsed=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"heading 9\" w:semiHidden=\"1\" w:uiPriority=\"9\" w:unhideWhenUsed=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"Default Paragraph Font\" w:semiHidden=\"1\" w:uiPriority=\"1\" w:unhideWhenUsed=\"1\"/><w:lsdException w:name=\"Normal Table\" w:semiHidden=\"1\" w:uiPriority=\"99\" w:unhideWhenUsed=\"1\"/><w:lsdException w:name=\"No List\" w:semiHidden=\"1\" w:uiPriority=\"99\" w:unhideWhenUsed=\"1\"/><w:lsdException w:name=\"Subtitle\" w:uiPriority=\"11\" w:qFormat=\"1\"/><w:lsdException w:name=\"Strong\" w:uiPriority=\"22\" w:qFormat=\"1\"/><w:lsdException w:name=\"Emphasis\" w:uiPriority=\"20\" w:qFormat=\"1\"/><w:lsdException w:name=\"Hyperlink\" w:semiHidden=\"1\" w:unhideWhenUsed=\"1\"/><w:lsdException w:name=\"FollowedHyperlink\" w:semiHidden=\"1\" w:unhideWhenUsed=\"1\"/><w:lsdException w:name=\"No Spacing\" w:uiPriority=\"1\" w:qFormat=\"1\"/><w:lsdException w:name=\"Revision\" w:semiHidden=\"1\"/></w:latentStyles>" });
10005
- importedStyles.push({ _raw: "<w:style w:type=\"paragraph\" w:default=\"1\" w:styleId=\"Normal\"><w:name w:val=\"Normal\"/><w:qFormat/><w:pPr><w:widowControl w:val=\"0\"/></w:pPr></w:style>" });
10010
+ paragraphStyles.push({
10011
+ id: "Normal",
10012
+ name: "Normal",
10013
+ default: true,
10014
+ quickFormat: true,
10015
+ paragraph: { widowControl: false }
10016
+ });
10006
10017
  const headings = [
10007
10018
  {
10008
10019
  id: "Heading1",
10009
10020
  name: "heading 1",
10010
10021
  link: "Heading1Char",
10011
- sz: "48",
10012
- before: "480",
10013
- after: "80",
10014
- outlineLvl: "0"
10022
+ sz: 48,
10023
+ before: 480,
10024
+ after: 80,
10025
+ outlineLvl: 0
10015
10026
  },
10016
10027
  {
10017
10028
  id: "Heading2",
10018
10029
  name: "heading 2",
10019
10030
  link: "Heading2Char",
10020
- sz: "40",
10021
- before: "160",
10022
- after: "80",
10023
- outlineLvl: "1"
10031
+ sz: 40,
10032
+ before: 160,
10033
+ after: 80,
10034
+ outlineLvl: 1
10024
10035
  },
10025
10036
  {
10026
10037
  id: "Heading3",
10027
10038
  name: "heading 3",
10028
10039
  link: "Heading3Char",
10029
- sz: "32",
10030
- before: "160",
10031
- after: "80",
10032
- outlineLvl: "2"
10040
+ sz: 32,
10041
+ before: 160,
10042
+ after: 80,
10043
+ outlineLvl: 2
10033
10044
  },
10034
10045
  {
10035
10046
  id: "Heading4",
10036
10047
  name: "heading 4",
10037
10048
  link: "Heading4Char",
10038
- sz: "28",
10039
- before: "80",
10040
- after: "40",
10041
- outlineLvl: "3"
10049
+ sz: 28,
10050
+ before: 80,
10051
+ after: 40,
10052
+ outlineLvl: 3
10042
10053
  },
10043
10054
  {
10044
10055
  id: "Heading5",
10045
10056
  name: "heading 5",
10046
10057
  link: "Heading5Char",
10047
- sz: "24",
10048
- before: "80",
10049
- after: "40",
10050
- outlineLvl: "4"
10058
+ sz: 24,
10059
+ before: 80,
10060
+ after: 40,
10061
+ outlineLvl: 4
10051
10062
  },
10052
10063
  {
10053
10064
  id: "Heading6",
10054
10065
  name: "heading 6",
10055
10066
  link: "Heading6Char",
10056
10067
  sz: void 0,
10057
- before: "40",
10058
- after: "0",
10059
- outlineLvl: "5"
10068
+ before: 40,
10069
+ after: 0,
10070
+ outlineLvl: 5
10060
10071
  },
10061
10072
  {
10062
10073
  id: "Heading7",
10063
10074
  name: "heading 7",
10064
10075
  link: "Heading7Char",
10065
10076
  sz: void 0,
10066
- before: "40",
10067
- after: "0",
10068
- outlineLvl: "6"
10077
+ before: 40,
10078
+ after: 0,
10079
+ outlineLvl: 6
10069
10080
  },
10070
10081
  {
10071
10082
  id: "Heading8",
@@ -10073,8 +10084,8 @@ var DefaultStylesFactory = class {
10073
10084
  link: "Heading8Char",
10074
10085
  sz: void 0,
10075
10086
  before: void 0,
10076
- after: "0",
10077
- outlineLvl: "7"
10087
+ after: 0,
10088
+ outlineLvl: 7
10078
10089
  },
10079
10090
  {
10080
10091
  id: "Heading9",
@@ -10082,15 +10093,16 @@ var DefaultStylesFactory = class {
10082
10093
  link: "Heading9Char",
10083
10094
  sz: void 0,
10084
10095
  before: void 0,
10085
- after: "0",
10086
- outlineLvl: "8"
10096
+ after: 0,
10097
+ outlineLvl: 8
10087
10098
  }
10088
10099
  ];
10089
10100
  for (let headingIdx = 0; headingIdx < headings.length; headingIdx++) {
10090
10101
  const h = headings[headingIdx];
10102
+ const outlineLvl = h.outlineLvl;
10091
10103
  const headingOverrideOpts = headingOverride(options, headingIdx + 1);
10092
10104
  if (headingOverrideOpts) {
10093
- importedStyles.push({ _raw: stringifyParagraphStyle({
10105
+ paragraphStyles.push({
10094
10106
  id: h.id,
10095
10107
  name: headingOverrideOpts.name ?? h.name,
10096
10108
  basedOn: headingOverrideOpts.basedOn ?? "Normal",
@@ -10105,42 +10117,124 @@ var DefaultStylesFactory = class {
10105
10117
  ...headingOverrideOpts.paragraph
10106
10118
  },
10107
10119
  run: headingOverrideOpts.run
10108
- }) });
10109
- importedStyles.push({ _raw: stringifyCharacterStyle({
10120
+ });
10121
+ characterStyles.push({
10110
10122
  id: h.link,
10111
10123
  name: `${h.name} Char`,
10112
10124
  basedOn: "DefaultParagraphFont",
10113
10125
  link: h.id,
10114
10126
  run: headingOverrideOpts.run
10115
- }) });
10127
+ });
10116
10128
  continue;
10117
10129
  }
10118
- const pPrParts = [`<w:keepNext/>`, `<w:keepLines/>`];
10119
- if (h.before || h.after) {
10120
- const sp = [];
10121
- if (h.before) sp.push(`w:before="${h.before}"`);
10122
- if (h.after) sp.push(`w:after="${h.after}"`);
10123
- pPrParts.push(`<w:spacing ${sp.join(" ")}/>`);
10130
+ const accentRange = outlineLvl < 6;
10131
+ const runProps = {
10132
+ font: accentRange ? {
10133
+ asciiTheme: "majorHAnsi",
10134
+ eastAsiaTheme: "majorEastAsia",
10135
+ hAnsiTheme: "majorHAnsi",
10136
+ cstheme: "majorBidi"
10137
+ } : { cstheme: "majorBidi" },
10138
+ color: accentRange ? {
10139
+ val: "0F4761",
10140
+ themeColor: "accent1",
10141
+ themeShade: "BF"
10142
+ } : {
10143
+ val: "595959",
10144
+ themeColor: "text1",
10145
+ themeTint: "A6"
10146
+ }
10147
+ };
10148
+ if (h.sz) {
10149
+ const sizePt = h.sz / 2;
10150
+ runProps.size = sizePt;
10151
+ runProps.sizeComplexScript = sizePt;
10124
10152
  }
10125
- pPrParts.push(`<w:outlineLvl w:val="${h.outlineLvl}"/>`);
10126
- const rPrParts = [];
10127
- if (parseInt(h.outlineLvl) < 6) {
10128
- rPrParts.push(`<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi"/>`);
10129
- rPrParts.push(`<w:color w:val="0F4761" w:themeColor="accent1" w:themeShade="BF"/>`);
10130
- } else {
10131
- rPrParts.push(`<w:rFonts w:cstheme="majorBidi"/>`);
10132
- rPrParts.push(`<w:color w:val="595959" w:themeColor="text1" w:themeTint="A6"/>`);
10153
+ if (outlineLvl >= 5) {
10154
+ runProps.bold = true;
10155
+ runProps.boldComplexScript = true;
10156
+ }
10157
+ paragraphStyles.push({
10158
+ id: h.id,
10159
+ name: h.name,
10160
+ basedOn: "Normal",
10161
+ next: "Normal",
10162
+ link: h.link,
10163
+ uiPriority: 9,
10164
+ semiHidden: outlineLvl > 0,
10165
+ unhideWhenUsed: outlineLvl > 0,
10166
+ quickFormat: true,
10167
+ paragraph: {
10168
+ keepNext: true,
10169
+ keepLines: true,
10170
+ spacing: {
10171
+ before: h.before,
10172
+ after: h.after
10173
+ },
10174
+ outlineLevel: outlineLvl
10175
+ },
10176
+ run: runProps
10177
+ });
10178
+ characterStyles.push({
10179
+ id: h.link,
10180
+ name: `${h.name} Char`,
10181
+ basedOn: "DefaultParagraphFont",
10182
+ link: h.id,
10183
+ uiPriority: 9,
10184
+ semiHidden: outlineLvl > 0,
10185
+ run: runProps
10186
+ });
10187
+ }
10188
+ characterStyles.push({
10189
+ id: "DefaultParagraphFont",
10190
+ name: "Default Paragraph Font",
10191
+ default: true,
10192
+ uiPriority: 1,
10193
+ semiHidden: true,
10194
+ unhideWhenUsed: true
10195
+ });
10196
+ tableStyles.push({
10197
+ id: "NormalTable",
10198
+ name: "Normal Table",
10199
+ default: true,
10200
+ uiPriority: 99,
10201
+ semiHidden: true,
10202
+ unhideWhenUsed: true,
10203
+ table: {
10204
+ indent: {
10205
+ size: 0,
10206
+ type: WidthType.DXA
10207
+ },
10208
+ cellMargin: {
10209
+ top: {
10210
+ size: 0,
10211
+ type: WidthType.DXA
10212
+ },
10213
+ left: {
10214
+ size: 108,
10215
+ type: WidthType.DXA
10216
+ },
10217
+ bottom: {
10218
+ size: 0,
10219
+ type: WidthType.DXA
10220
+ },
10221
+ right: {
10222
+ size: 108,
10223
+ type: WidthType.DXA
10224
+ }
10225
+ }
10133
10226
  }
10134
- if (h.sz) rPrParts.push(`<w:sz w:val="${h.sz}"/><w:szCs w:val="${h.sz}"/>`);
10135
- if (parseInt(h.outlineLvl) >= 5) rPrParts.push(`<w:b/><w:bCs/>`);
10136
- importedStyles.push({ _raw: `<w:style w:type="paragraph" w:styleId="${h.id}"><w:name w:val="${h.name}"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:link w:val="${h.link}"/><w:uiPriority w:val="9"/>` + (parseInt(h.outlineLvl) > 0 ? `<w:semiHidden/><w:unhideWhenUsed/>` : "") + `<w:qFormat/><w:pPr>${pPrParts.join("")}</w:pPr><w:rPr>${rPrParts.join("")}</w:rPr></w:style>` });
10137
- importedStyles.push({ _raw: `<w:style w:type="character" w:styleId="${h.link}"><w:name w:val="${h.name} Char"/><w:basedOn w:val="DefaultParagraphFont"/><w:link w:val="${h.id}"/><w:uiPriority w:val="9"/>` + (parseInt(h.outlineLvl) > 0 ? `<w:semiHidden/>` : "") + `<w:rPr>${rPrParts.join("")}</w:rPr></w:style>` });
10138
- }
10139
- importedStyles.push({ _raw: "<w:style w:type=\"character\" w:default=\"1\" w:styleId=\"DefaultParagraphFont\"><w:name w:val=\"Default Paragraph Font\"/><w:uiPriority w:val=\"1\"/><w:semiHidden/><w:unhideWhenUsed/></w:style>" });
10140
- importedStyles.push({ _raw: "<w:style w:type=\"table\" w:default=\"1\" w:styleId=\"NormalTable\"><w:name w:val=\"Normal Table\"/><w:uiPriority w:val=\"99\"/><w:semiHidden/><w:unhideWhenUsed/><w:tblPr><w:tblInd w:w=\"0\" w:type=\"dxa\"/><w:tblCellMar><w:top w:w=\"0\" w:type=\"dxa\"/><w:left w:w=\"108\" w:type=\"dxa\"/><w:bottom w:w=\"0\" w:type=\"dxa\"/><w:right w:w=\"108\" w:type=\"dxa\"/></w:tblCellMar></w:tblPr></w:style>" });
10141
- importedStyles.push({ _raw: "<w:style w:type=\"numbering\" w:default=\"1\" w:styleId=\"NoList\"><w:name w:val=\"No List\"/><w:uiPriority w:val=\"99\"/><w:semiHidden/><w:unhideWhenUsed/></w:style>" });
10227
+ });
10228
+ numberingStyles.push({
10229
+ id: "NoList",
10230
+ name: "No List",
10231
+ default: true,
10232
+ uiPriority: 99,
10233
+ semiHidden: true,
10234
+ unhideWhenUsed: true
10235
+ });
10142
10236
  if (options.title) {
10143
- importedStyles.push({ _raw: stringifyParagraphStyle({
10237
+ paragraphStyles.push({
10144
10238
  id: "Title",
10145
10239
  name: options.title.name ?? "Title",
10146
10240
  basedOn: options.title.basedOn ?? "Normal",
@@ -10150,20 +10244,57 @@ var DefaultStylesFactory = class {
10150
10244
  quickFormat: options.title.quickFormat ?? true,
10151
10245
  paragraph: options.title.paragraph,
10152
10246
  run: options.title.run
10153
- }) });
10154
- importedStyles.push({ _raw: stringifyCharacterStyle({
10247
+ });
10248
+ characterStyles.push({
10155
10249
  id: "TitleChar",
10156
10250
  name: "Title Char",
10157
10251
  basedOn: "DefaultParagraphFont",
10158
10252
  link: "Title",
10159
10253
  run: options.title.run
10160
- }) });
10254
+ });
10161
10255
  } else {
10162
- importedStyles.push({ _raw: "<w:style w:type=\"paragraph\" w:styleId=\"Title\"><w:name w:val=\"Title\"/><w:basedOn w:val=\"Normal\"/><w:next w:val=\"Normal\"/><w:link w:val=\"TitleChar\"/><w:uiPriority w:val=\"10\"/><w:qFormat/><w:pPr><w:spacing w:after=\"80\" w:line=\"240\" w:lineRule=\"auto\"/><w:contextualSpacing/><w:jc w:val=\"center\"/></w:pPr><w:rPr><w:rFonts w:asciiTheme=\"majorHAnsi\" w:eastAsiaTheme=\"majorEastAsia\" w:hAnsiTheme=\"majorHAnsi\" w:cstheme=\"majorBidi\"/><w:spacing w:val=\"-10\"/><w:kern w:val=\"28\"/><w:sz w:val=\"56\"/><w:szCs w:val=\"56\"/></w:rPr></w:style>" });
10163
- importedStyles.push({ _raw: "<w:style w:type=\"character\" w:styleId=\"TitleChar\"><w:name w:val=\"Title Char\"/><w:basedOn w:val=\"DefaultParagraphFont\"/><w:link w:val=\"Title\"/><w:uiPriority w:val=\"10\"/><w:rPr><w:rFonts w:asciiTheme=\"majorHAnsi\" w:eastAsiaTheme=\"majorEastAsia\" w:hAnsiTheme=\"majorHAnsi\" w:cstheme=\"majorBidi\"/><w:spacing w:val=\"-10\"/><w:kern w:val=\"28\"/><w:sz w:val=\"56\"/><w:szCs w:val=\"56\"/></w:rPr></w:style>" });
10256
+ const titleRun = {
10257
+ font: {
10258
+ asciiTheme: "majorHAnsi",
10259
+ eastAsiaTheme: "majorEastAsia",
10260
+ hAnsiTheme: "majorHAnsi",
10261
+ cstheme: "majorBidi"
10262
+ },
10263
+ characterSpacing: -10,
10264
+ kern: 28,
10265
+ size: 28,
10266
+ sizeComplexScript: 28
10267
+ };
10268
+ paragraphStyles.push({
10269
+ id: "Title",
10270
+ name: "Title",
10271
+ basedOn: "Normal",
10272
+ next: "Normal",
10273
+ link: "TitleChar",
10274
+ uiPriority: 10,
10275
+ quickFormat: true,
10276
+ paragraph: {
10277
+ spacing: {
10278
+ after: 80,
10279
+ line: 240,
10280
+ lineRule: "auto"
10281
+ },
10282
+ contextualSpacing: true,
10283
+ alignment: AlignmentType.CENTER
10284
+ },
10285
+ run: titleRun
10286
+ });
10287
+ characterStyles.push({
10288
+ id: "TitleChar",
10289
+ name: "Title Char",
10290
+ basedOn: "DefaultParagraphFont",
10291
+ link: "Title",
10292
+ uiPriority: 10,
10293
+ run: titleRun
10294
+ });
10164
10295
  }
10165
10296
  if (options.subtitle) {
10166
- importedStyles.push({ _raw: stringifyParagraphStyle({
10297
+ paragraphStyles.push({
10167
10298
  id: "Subtitle",
10168
10299
  name: options.subtitle.name ?? "Subtitle",
10169
10300
  basedOn: options.subtitle.basedOn ?? "Normal",
@@ -10173,19 +10304,52 @@ var DefaultStylesFactory = class {
10173
10304
  quickFormat: options.subtitle.quickFormat ?? true,
10174
10305
  paragraph: options.subtitle.paragraph,
10175
10306
  run: options.subtitle.run
10176
- }) });
10177
- importedStyles.push({ _raw: stringifyCharacterStyle({
10307
+ });
10308
+ characterStyles.push({
10178
10309
  id: "SubtitleChar",
10179
10310
  name: "Subtitle Char",
10180
10311
  basedOn: "DefaultParagraphFont",
10181
10312
  link: "Subtitle",
10182
10313
  run: options.subtitle.run
10183
- }) });
10314
+ });
10184
10315
  } else {
10185
- importedStyles.push({ _raw: "<w:style w:type=\"paragraph\" w:styleId=\"Subtitle\"><w:name w:val=\"Subtitle\"/><w:basedOn w:val=\"Normal\"/><w:next w:val=\"Normal\"/><w:link w:val=\"SubtitleChar\"/><w:uiPriority w:val=\"11\"/><w:qFormat/><w:pPr><w:jc w:val=\"center\"/></w:pPr><w:rPr><w:rFonts w:asciiTheme=\"majorHAnsi\" w:eastAsiaTheme=\"majorEastAsia\" w:hAnsiTheme=\"majorHAnsi\" w:cstheme=\"majorBidi\"/><w:color w:val=\"595959\" w:themeColor=\"text1\" w:themeTint=\"A6\"/><w:spacing w:val=\"15\"/><w:sz w:val=\"28\"/><w:szCs w:val=\"28\"/></w:rPr></w:style>" });
10186
- importedStyles.push({ _raw: "<w:style w:type=\"character\" w:styleId=\"SubtitleChar\"><w:name w:val=\"Subtitle Char\"/><w:basedOn w:val=\"DefaultParagraphFont\"/><w:link w:val=\"Subtitle\"/><w:uiPriority w:val=\"11\"/><w:rPr><w:rFonts w:asciiTheme=\"majorHAnsi\" w:eastAsiaTheme=\"majorEastAsia\" w:hAnsiTheme=\"majorHAnsi\" w:cstheme=\"majorBidi\"/><w:color w:val=\"595959\" w:themeColor=\"text1\" w:themeTint=\"A6\"/><w:spacing w:val=\"15\"/><w:sz w:val=\"28\"/><w:szCs w:val=\"28\"/></w:rPr></w:style>" });
10316
+ const subtitleRun = {
10317
+ font: {
10318
+ asciiTheme: "majorHAnsi",
10319
+ eastAsiaTheme: "majorEastAsia",
10320
+ hAnsiTheme: "majorHAnsi",
10321
+ cstheme: "majorBidi"
10322
+ },
10323
+ color: {
10324
+ val: "595959",
10325
+ themeColor: "text1",
10326
+ themeTint: "A6"
10327
+ },
10328
+ characterSpacing: 15,
10329
+ size: 14,
10330
+ sizeComplexScript: 14
10331
+ };
10332
+ paragraphStyles.push({
10333
+ id: "Subtitle",
10334
+ name: "Subtitle",
10335
+ basedOn: "Normal",
10336
+ next: "Normal",
10337
+ link: "SubtitleChar",
10338
+ uiPriority: 11,
10339
+ quickFormat: true,
10340
+ paragraph: { alignment: AlignmentType.CENTER },
10341
+ run: subtitleRun
10342
+ });
10343
+ characterStyles.push({
10344
+ id: "SubtitleChar",
10345
+ name: "Subtitle Char",
10346
+ basedOn: "DefaultParagraphFont",
10347
+ link: "Subtitle",
10348
+ uiPriority: 11,
10349
+ run: subtitleRun
10350
+ });
10187
10351
  }
10188
- if (options.listParagraph) importedStyles.push({ _raw: stringifyParagraphStyle({
10352
+ if (options.listParagraph) paragraphStyles.push({
10189
10353
  id: "ListParagraph",
10190
10354
  name: options.listParagraph.name ?? "List Paragraph",
10191
10355
  basedOn: options.listParagraph.basedOn ?? "Normal",
@@ -10193,9 +10357,19 @@ var DefaultStylesFactory = class {
10193
10357
  quickFormat: options.listParagraph.quickFormat ?? true,
10194
10358
  paragraph: options.listParagraph.paragraph,
10195
10359
  run: options.listParagraph.run
10196
- }) });
10197
- else importedStyles.push({ _raw: "<w:style w:type=\"paragraph\" w:styleId=\"ListParagraph\"><w:name w:val=\"List Paragraph\"/><w:basedOn w:val=\"Normal\"/><w:uiPriority w:val=\"34\"/><w:qFormat/><w:pPr><w:ind w:left=\"720\"/><w:contextualSpacing/></w:pPr></w:style>" });
10198
- if (options.strong) importedStyles.push({ _raw: stringifyParagraphStyle({
10360
+ });
10361
+ else paragraphStyles.push({
10362
+ id: "ListParagraph",
10363
+ name: "List Paragraph",
10364
+ basedOn: "Normal",
10365
+ uiPriority: 34,
10366
+ quickFormat: true,
10367
+ paragraph: {
10368
+ indent: { left: 720 },
10369
+ contextualSpacing: true
10370
+ }
10371
+ });
10372
+ if (options.strong) paragraphStyles.push({
10199
10373
  id: "Strong",
10200
10374
  name: options.strong.name ?? "Strong",
10201
10375
  basedOn: options.strong.basedOn ?? "Normal",
@@ -10203,8 +10377,8 @@ var DefaultStylesFactory = class {
10203
10377
  quickFormat: options.strong.quickFormat ?? true,
10204
10378
  paragraph: options.strong.paragraph,
10205
10379
  run: options.strong.run
10206
- }) });
10207
- if (options.emphasis) importedStyles.push({ _raw: stringifyParagraphStyle({
10380
+ });
10381
+ if (options.emphasis) paragraphStyles.push({
10208
10382
  id: "Emphasis",
10209
10383
  name: options.emphasis.name ?? "Emphasis",
10210
10384
  basedOn: options.emphasis.basedOn ?? "Normal",
@@ -10212,9 +10386,18 @@ var DefaultStylesFactory = class {
10212
10386
  quickFormat: options.emphasis.quickFormat ?? true,
10213
10387
  paragraph: options.emphasis.paragraph,
10214
10388
  run: options.emphasis.run
10215
- }) });
10389
+ });
10390
+ const quoteRun = {
10391
+ italic: true,
10392
+ italicComplexScript: true,
10393
+ color: {
10394
+ val: "404040",
10395
+ themeColor: "text1",
10396
+ themeTint: "BF"
10397
+ }
10398
+ };
10216
10399
  if (options.quote) {
10217
- importedStyles.push({ _raw: stringifyParagraphStyle({
10400
+ paragraphStyles.push({
10218
10401
  id: "Quote",
10219
10402
  name: options.quote.name ?? "Quote",
10220
10403
  basedOn: options.quote.basedOn ?? "Normal",
@@ -10224,21 +10407,89 @@ var DefaultStylesFactory = class {
10224
10407
  quickFormat: options.quote.quickFormat ?? true,
10225
10408
  paragraph: options.quote.paragraph,
10226
10409
  run: options.quote.run
10227
- }) });
10228
- importedStyles.push({ _raw: stringifyCharacterStyle({
10410
+ });
10411
+ characterStyles.push({
10229
10412
  id: "QuoteChar",
10230
10413
  name: "Quote Char",
10231
10414
  basedOn: "DefaultParagraphFont",
10232
10415
  link: "Quote",
10233
10416
  run: options.quote.run
10234
- }) });
10417
+ });
10235
10418
  } else {
10236
- importedStyles.push({ _raw: "<w:style w:type=\"paragraph\" w:styleId=\"Quote\"><w:name w:val=\"Quote\"/><w:basedOn w:val=\"Normal\"/><w:next w:val=\"Normal\"/><w:link w:val=\"QuoteChar\"/><w:uiPriority w:val=\"29\"/><w:qFormat/><w:pPr><w:spacing w:before=\"160\"/><w:jc w:val=\"center\"/></w:pPr><w:rPr><w:i/><w:iCs/><w:color w:val=\"404040\" w:themeColor=\"text1\" w:themeTint=\"BF\"/></w:rPr></w:style>" });
10237
- importedStyles.push({ _raw: "<w:style w:type=\"character\" w:styleId=\"QuoteChar\"><w:name w:val=\"Quote Char\"/><w:basedOn w:val=\"DefaultParagraphFont\"/><w:link w:val=\"Quote\"/><w:uiPriority w:val=\"29\"/><w:rPr><w:i/><w:iCs/><w:color w:val=\"404040\" w:themeColor=\"text1\" w:themeTint=\"BF\"/></w:rPr></w:style>" });
10419
+ paragraphStyles.push({
10420
+ id: "Quote",
10421
+ name: "Quote",
10422
+ basedOn: "Normal",
10423
+ next: "Normal",
10424
+ link: "QuoteChar",
10425
+ uiPriority: 29,
10426
+ quickFormat: true,
10427
+ paragraph: {
10428
+ spacing: { before: 160 },
10429
+ alignment: AlignmentType.CENTER
10430
+ },
10431
+ run: quoteRun
10432
+ });
10433
+ characterStyles.push({
10434
+ id: "QuoteChar",
10435
+ name: "Quote Char",
10436
+ basedOn: "DefaultParagraphFont",
10437
+ link: "Quote",
10438
+ uiPriority: 29,
10439
+ run: quoteRun
10440
+ });
10238
10441
  }
10239
- importedStyles.push({ _raw: "<w:style w:type=\"paragraph\" w:styleId=\"IntenseQuote\"><w:name w:val=\"Intense Quote\"/><w:basedOn w:val=\"Normal\"/><w:next w:val=\"Normal\"/><w:link w:val=\"IntenseQuoteChar\"/><w:uiPriority w:val=\"30\"/><w:qFormat/><w:pPr><w:pBdr><w:top w:val=\"single\" w:sz=\"4\" w:space=\"10\" w:color=\"0F4761\" w:themeColor=\"accent1\" w:themeShade=\"BF\"/><w:bottom w:val=\"single\" w:sz=\"4\" w:space=\"10\" w:color=\"0F4761\" w:themeColor=\"accent1\" w:themeShade=\"BF\"/></w:pBdr><w:spacing w:before=\"360\" w:after=\"360\"/><w:ind w:left=\"864\" w:right=\"864\"/><w:jc w:val=\"center\"/></w:pPr><w:rPr><w:i/><w:iCs/><w:color w:val=\"0F4761\" w:themeColor=\"accent1\" w:themeShade=\"BF\"/></w:rPr></w:style>" });
10240
- importedStyles.push({ _raw: "<w:style w:type=\"character\" w:styleId=\"IntenseQuoteChar\"><w:name w:val=\"Intense Quote Char\"/><w:basedOn w:val=\"DefaultParagraphFont\"/><w:link w:val=\"IntenseQuote\"/><w:uiPriority w:val=\"30\"/><w:rPr><w:i/><w:iCs/><w:color w:val=\"0F4761\" w:themeColor=\"accent1\" w:themeShade=\"BF\"/></w:rPr></w:style>" });
10241
- importedStyles.push({ _raw: stringifyCharacterStyle({
10442
+ const intenseQuoteRun = {
10443
+ italic: true,
10444
+ italicComplexScript: true,
10445
+ color: {
10446
+ val: "0F4761",
10447
+ themeColor: "accent1",
10448
+ themeShade: "BF"
10449
+ }
10450
+ };
10451
+ const intenseQuoteBorder = {
10452
+ style: BorderStyle.SINGLE,
10453
+ size: 4,
10454
+ space: 10,
10455
+ color: "0F4761",
10456
+ themeColor: "accent1",
10457
+ themeShade: "BF"
10458
+ };
10459
+ paragraphStyles.push({
10460
+ id: "IntenseQuote",
10461
+ name: "Intense Quote",
10462
+ basedOn: "Normal",
10463
+ next: "Normal",
10464
+ link: "IntenseQuoteChar",
10465
+ uiPriority: 30,
10466
+ quickFormat: true,
10467
+ paragraph: {
10468
+ border: {
10469
+ top: intenseQuoteBorder,
10470
+ bottom: intenseQuoteBorder
10471
+ },
10472
+ spacing: {
10473
+ before: 360,
10474
+ after: 360
10475
+ },
10476
+ indent: {
10477
+ left: 864,
10478
+ right: 864
10479
+ },
10480
+ alignment: AlignmentType.CENTER
10481
+ },
10482
+ run: intenseQuoteRun
10483
+ });
10484
+ characterStyles.push({
10485
+ id: "IntenseQuoteChar",
10486
+ name: "Intense Quote Char",
10487
+ basedOn: "DefaultParagraphFont",
10488
+ link: "IntenseQuote",
10489
+ uiPriority: 30,
10490
+ run: intenseQuoteRun
10491
+ });
10492
+ characterStyles.push({
10242
10493
  id: "Hyperlink",
10243
10494
  name: "Hyperlink",
10244
10495
  basedOn: "DefaultParagraphFont",
@@ -10249,8 +10500,8 @@ var DefaultStylesFactory = class {
10249
10500
  underline: { type: "single" }
10250
10501
  },
10251
10502
  ...options.hyperlink
10252
- }) });
10253
- importedStyles.push({ _raw: stringifyCharacterStyle({
10503
+ });
10504
+ characterStyles.push({
10254
10505
  id: "FootnoteReference",
10255
10506
  name: "footnote reference",
10256
10507
  basedOn: "DefaultParagraphFont",
@@ -10258,8 +10509,8 @@ var DefaultStylesFactory = class {
10258
10509
  unhideWhenUsed: true,
10259
10510
  run: { superScript: true },
10260
10511
  ...options.footnoteReference
10261
- }) });
10262
- importedStyles.push({ _raw: stringifyParagraphStyle({
10512
+ });
10513
+ paragraphStyles.push({
10263
10514
  id: "FootnoteText",
10264
10515
  name: "footnote text",
10265
10516
  basedOn: "Normal",
@@ -10274,8 +10525,8 @@ var DefaultStylesFactory = class {
10274
10525
  } },
10275
10526
  run: { size: 20 },
10276
10527
  ...options.footnoteText
10277
- }) });
10278
- importedStyles.push({ _raw: stringifyCharacterStyle({
10528
+ });
10529
+ characterStyles.push({
10279
10530
  id: "FootnoteTextChar",
10280
10531
  name: "Footnote Text Char",
10281
10532
  basedOn: "DefaultParagraphFont",
@@ -10283,8 +10534,8 @@ var DefaultStylesFactory = class {
10283
10534
  semiHidden: true,
10284
10535
  run: { size: 20 },
10285
10536
  ...options.footnoteTextChar
10286
- }) });
10287
- importedStyles.push({ _raw: stringifyCharacterStyle({
10537
+ });
10538
+ characterStyles.push({
10288
10539
  id: "EndnoteReference",
10289
10540
  name: "endnote reference",
10290
10541
  basedOn: "DefaultParagraphFont",
@@ -10292,8 +10543,8 @@ var DefaultStylesFactory = class {
10292
10543
  unhideWhenUsed: true,
10293
10544
  run: { superScript: true },
10294
10545
  ...options.endnoteReference
10295
- }) });
10296
- importedStyles.push({ _raw: stringifyParagraphStyle({
10546
+ });
10547
+ paragraphStyles.push({
10297
10548
  id: "EndnoteText",
10298
10549
  name: "endnote text",
10299
10550
  basedOn: "Normal",
@@ -10308,8 +10559,8 @@ var DefaultStylesFactory = class {
10308
10559
  } },
10309
10560
  run: { size: 20 },
10310
10561
  ...options.endnoteText
10311
- }) });
10312
- importedStyles.push({ _raw: stringifyCharacterStyle({
10562
+ });
10563
+ characterStyles.push({
10313
10564
  id: "EndnoteTextChar",
10314
10565
  name: "Endnote Text Char",
10315
10566
  basedOn: "DefaultParagraphFont",
@@ -10317,10 +10568,31 @@ var DefaultStylesFactory = class {
10317
10568
  semiHidden: true,
10318
10569
  run: { size: 20 },
10319
10570
  ...options.endnoteTextChar
10320
- }) });
10321
- importedStyles.push({ _raw: "<w:style w:type=\"character\" w:styleId=\"IntenseReference\"><w:name w:val=\"Intense Reference\"/><w:basedOn w:val=\"DefaultParagraphFont\"/><w:uiPriority w:val=\"32\"/><w:qFormat/><w:rPr><w:b/><w:bCs/><w:smallCaps/><w:color w:val=\"0F4761\" w:themeColor=\"accent1\" w:themeShade=\"BF\"/><w:spacing w:val=\"5\"/></w:rPr></w:style>" });
10571
+ });
10572
+ characterStyles.push({
10573
+ id: "IntenseReference",
10574
+ name: "Intense Reference",
10575
+ basedOn: "DefaultParagraphFont",
10576
+ uiPriority: 32,
10577
+ quickFormat: true,
10578
+ run: {
10579
+ bold: true,
10580
+ boldComplexScript: true,
10581
+ smallCaps: true,
10582
+ color: {
10583
+ val: "0F4761",
10584
+ themeColor: "accent1",
10585
+ themeShade: "BF"
10586
+ },
10587
+ characterSpacing: 5
10588
+ }
10589
+ });
10322
10590
  return {
10323
10591
  importedStyles,
10592
+ paragraphStyles,
10593
+ characterStyles,
10594
+ tableStyles,
10595
+ numberingStyles,
10324
10596
  initialAttributes
10325
10597
  };
10326
10598
  }
@@ -10370,42 +10642,10 @@ var Styles = class {
10370
10642
  }
10371
10643
  this.parts.push(style._raw);
10372
10644
  }
10373
- if (options.paragraphStyles) for (const style of options.paragraphStyles) this.parts.push(stringifyParagraphStyle({
10374
- id: style.id,
10375
- name: style.name ?? style.id,
10376
- aliases: style.aliases,
10377
- basedOn: style.basedOn,
10378
- next: style.next,
10379
- link: style.link,
10380
- autoRedefine: style.autoRedefine,
10381
- quickFormat: style.quickFormat,
10382
- semiHidden: style.semiHidden,
10383
- uiPriority: style.uiPriority,
10384
- unhideWhenUsed: style.unhideWhenUsed,
10385
- locked: style.locked,
10386
- personal: style.personal,
10387
- personalCompose: style.personalCompose,
10388
- personalReply: style.personalReply,
10389
- paragraph: style.paragraph,
10390
- run: style.run
10391
- }));
10392
- if (options.characterStyles) for (const style of options.characterStyles) this.parts.push(stringifyCharacterStyle({
10393
- id: style.id,
10394
- name: style.name ?? style.id,
10395
- aliases: style.aliases,
10396
- basedOn: style.basedOn,
10397
- link: style.link,
10398
- autoRedefine: style.autoRedefine,
10399
- semiHidden: style.semiHidden,
10400
- uiPriority: style.uiPriority,
10401
- unhideWhenUsed: style.unhideWhenUsed,
10402
- locked: style.locked,
10403
- personal: style.personal,
10404
- personalCompose: style.personalCompose,
10405
- personalReply: style.personalReply,
10406
- run: style.run
10407
- }));
10645
+ if (options.paragraphStyles) for (const style of options.paragraphStyles) this.parts.push(stringifyParagraphStyle(style));
10646
+ if (options.characterStyles) for (const style of options.characterStyles) this.parts.push(stringifyCharacterStyle(style));
10408
10647
  if (options.tableStyles) for (const style of options.tableStyles) this.parts.push(stringifyTableStyle(style));
10648
+ if (options.numberingStyles) for (const style of options.numberingStyles) this.parts.push(stringifyNumberingStyle(style));
10409
10649
  }
10410
10650
  /**
10411
10651
  * Serialize to word/styles.xml content (with XML declaration).
@@ -10416,25 +10656,6 @@ var Styles = class {
10416
10656
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:styles${attrParts.join("")}>${this.parts.join("")}</w:styles>`;
10417
10657
  }
10418
10658
  };
10419
- /** Style IDs generated by DefaultStylesFactory — skip these during parsing. */
10420
- const BUILTIN_STYLE_IDS = new Set([
10421
- "Title",
10422
- "Heading1",
10423
- "Heading2",
10424
- "Heading3",
10425
- "Heading4",
10426
- "Heading5",
10427
- "Heading6",
10428
- "Strong",
10429
- "ListParagraph",
10430
- "Hyperlink",
10431
- "FootnoteText",
10432
- "FootnoteTextChar",
10433
- "EndnoteText",
10434
- "EndnoteTextChar",
10435
- "FootnoteReference",
10436
- "EndnoteReference"
10437
- ]);
10438
10659
  /**
10439
10660
  * Build a cache of style elements keyed by styleId.
10440
10661
  */
@@ -10472,6 +10693,7 @@ function parseStyleDefinitions(el, parseParagraphProperties, ctx) {
10472
10693
  const paragraphStyles = [];
10473
10694
  const characterStyles = [];
10474
10695
  const tableStyles = [];
10696
+ const numberingStyles = [];
10475
10697
  for (const child of el.elements ?? []) if (child.name === "w:docDefaults") {
10476
10698
  const defOpts = parseDocDefaults(child, parseParagraphProperties, ctx);
10477
10699
  if (defOpts) opts.default = defOpts;
@@ -10480,28 +10702,18 @@ function parseStyleDefinitions(el, parseParagraphProperties, ctx) {
10480
10702
  else if (child.name === "w:style") {
10481
10703
  const styleOpts = parseStyleElement(child, parseParagraphProperties, ctx);
10482
10704
  if (!styleOpts?._type || !styleOpts.id) continue;
10483
- if (styleOpts._type === "table") {
10484
- delete styleOpts._type;
10485
- tableStyles.push(styleOpts);
10486
- continue;
10487
- }
10488
- (opts.importedStyles ??= []).push({ _raw: stringifyElement(child) });
10489
- const defaultField = STYLE_ID_TO_DEFAULT_FIELD[styleOpts.id];
10490
- if (defaultField) {
10491
- const { _type: _omitType, id: _omitId, ...rest } = styleOpts;
10492
- opts.default ??= {};
10493
- opts.default[defaultField] = rest;
10494
- continue;
10495
- }
10496
- if (BUILTIN_STYLE_IDS.has(styleOpts.id)) continue;
10497
10705
  const type = styleOpts._type;
10498
10706
  delete styleOpts._type;
10499
- if (type === "paragraph") paragraphStyles.push(styleOpts);
10707
+ if (type === "table") tableStyles.push(styleOpts);
10708
+ else if (type === "numbering") numberingStyles.push(styleOpts);
10709
+ else if (type === "paragraph") paragraphStyles.push(styleOpts);
10500
10710
  else if (type === "character") characterStyles.push(styleOpts);
10501
10711
  }
10502
10712
  if (paragraphStyles.length > 0) opts.paragraphStyles = paragraphStyles;
10503
10713
  if (characterStyles.length > 0) opts.characterStyles = characterStyles;
10504
10714
  if (tableStyles.length > 0) opts.tableStyles = tableStyles;
10715
+ if (numberingStyles.length > 0) opts.numberingStyles = numberingStyles;
10716
+ opts.roundTripped = true;
10505
10717
  return Object.keys(opts).length > 0 ? opts : void 0;
10506
10718
  }
10507
10719
  function parseDocDefaults(el, parseParagraphProperties, ctx) {
@@ -10531,7 +10743,7 @@ function parseStyleElement(el, parseParagraphProperties, ctx) {
10531
10743
  const id = attr(el, "w:styleId");
10532
10744
  if (id) opts.id = id;
10533
10745
  if (attrBool(el, "w:default")) opts.default = true;
10534
- if (attrBool(el, "w:customStyle")) opts.customStyle = "1";
10746
+ if (attrBool(el, "w:customStyle")) opts.customStyle = true;
10535
10747
  const nameEl = findChild(el, "w:name");
10536
10748
  if (nameEl) {
10537
10749
  const name = attr(nameEl, "w:val");
@@ -10648,9 +10860,6 @@ function parseStyleElement(el, parseParagraphProperties, ctx) {
10648
10860
  *
10649
10861
  * @module
10650
10862
  */
10651
- function escapeAttr$1(s) {
10652
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
10653
- }
10654
10863
  /** Derive the namespace-prefixed val attribute from the element tag. */
10655
10864
  function valAttr(tag) {
10656
10865
  return `${tag.split(":")[0]}:val`;
@@ -10662,12 +10871,12 @@ function numVal(tag, val) {
10662
10871
  return val !== void 0 ? `<${tag} ${valAttr(tag)}="${val}"/>` : "";
10663
10872
  }
10664
10873
  function strVal(tag, val) {
10665
- return val !== void 0 ? `<${tag} ${valAttr(tag)}="${escapeAttr$1(val)}"/>` : "";
10874
+ return val !== void 0 ? `<${tag} ${valAttr(tag)}="${escapeXml(val)}"/>` : "";
10666
10875
  }
10667
10876
  /** Build attribute string from key-value pairs, skipping undefined. */
10668
10877
  function attrStr(attrs) {
10669
10878
  const parts = [];
10670
- for (const [k, v] of Object.entries(attrs)) if (v !== void 0) parts.push(`${k}="${escapeAttr$1(String(v))}"`);
10879
+ for (const [k, v] of Object.entries(attrs)) if (v !== void 0) parts.push(`${k}="${escapeXml(String(v))}"`);
10671
10880
  return parts.join(" ");
10672
10881
  }
10673
10882
  /** Self-closing element with attributes only. */
@@ -10677,7 +10886,7 @@ function attrEl(tag, attrs) {
10677
10886
  }
10678
10887
  function compatSetting(name, val, uri) {
10679
10888
  const u = uri ?? "http://schemas.microsoft.com/office/word";
10680
- return `<w:compatSetting w:name="${escapeAttr$1(name)}" w:uri="${u}" w:val="${val}"/>`;
10889
+ return `<w:compatSetting w:name="${escapeXml(name)}" w:uri="${u}" w:val="${val}"/>`;
10681
10890
  }
10682
10891
  /** Read a CT_OnOff child as boolean (presence true unless val is explicitly false). */
10683
10892
  function readOnOff(el) {
@@ -12447,9 +12656,6 @@ const fontTableDesc = {
12447
12656
  };
12448
12657
  //#endregion
12449
12658
  //#region src/parts/bibliography.ts
12450
- function escapeXml$1(s) {
12451
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
12452
- }
12453
12659
  const SOURCE_FIELDS = [
12454
12660
  ["SourceType", "type"],
12455
12661
  ["Title", "title"],
@@ -12472,13 +12678,13 @@ const bibliographyDesc = {
12472
12678
  kind: "custom",
12473
12679
  stringify(opts, _ctx) {
12474
12680
  const attrParts = ["xmlns:b=\"http://schemas.openxmlformats.org/officeDocument/2006/bibliography\""];
12475
- if (opts.styleName !== void 0) attrParts.push(`StyleName="${escapeXml$1(opts.styleName)}"`);
12681
+ if (opts.styleName !== void 0) attrParts.push(`StyleName="${escapeXml(opts.styleName)}"`);
12476
12682
  const parts = [`<b:Sources ${attrParts.join(" ")}>`];
12477
12683
  for (const source of opts.sources) {
12478
12684
  const sourceParts = [];
12479
12685
  for (const [tagName, key] of SOURCE_FIELDS) {
12480
12686
  const value = source[key];
12481
- if (value !== void 0) sourceParts.push(`<b:${tagName}>${escapeXml$1(value)}</b:${tagName}>`);
12687
+ if (value !== void 0) sourceParts.push(`<b:${tagName}>${escapeXml(value)}</b:${tagName}>`);
12482
12688
  }
12483
12689
  parts.push(`<b:Source>${sourceParts.join("")}</b:Source>`);
12484
12690
  }
@@ -12565,15 +12771,12 @@ const DocPartBehavior = {
12565
12771
  PAGE: "pg"
12566
12772
  };
12567
12773
  const GLOSSARY_NS = "xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\"";
12568
- function glossaryEscapeAttr(text) {
12569
- return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
12570
- }
12571
12774
  function docPartPrXml(part) {
12572
12775
  const prParts = [];
12573
- prParts.push(`<w:name w:val="${glossaryEscapeAttr(part.name)}"${part.decorated ? " w:decorated=\"1\"" : ""}/>`);
12776
+ prParts.push(`<w:name w:val="${escapeXml(part.name)}"${part.decorated ? " w:decorated=\"1\"" : ""}/>`);
12574
12777
  if (part.category || part.gallery) {
12575
12778
  const catParts = [];
12576
- if (part.category) catParts.push(`<w:name w:val="${glossaryEscapeAttr(part.category)}"/>`);
12779
+ if (part.category) catParts.push(`<w:name w:val="${escapeXml(part.category)}"/>`);
12577
12780
  catParts.push(`<w:gallery w:val="${part.gallery}"/>`);
12578
12781
  prParts.push(`<w:category>${catParts.join("")}</w:category>`);
12579
12782
  }
@@ -12586,8 +12789,8 @@ function docPartPrXml(part) {
12586
12789
  const behaviorXml = part.behaviors.map((b) => `<w:behavior w:val="${b}"/>`).join("");
12587
12790
  prParts.push(`<w:behaviors>${behaviorXml}</w:behaviors>`);
12588
12791
  }
12589
- if (part.description) prParts.push(`<w:description w:val="${glossaryEscapeAttr(part.description)}"/>`);
12590
- if (part.guid) prParts.push(`<w:guid w:val="${glossaryEscapeAttr(part.guid)}"/>`);
12792
+ if (part.description) prParts.push(`<w:description w:val="${escapeXml(part.description)}"/>`);
12793
+ if (part.guid) prParts.push(`<w:guid w:val="${escapeXml(part.guid)}"/>`);
12591
12794
  return `<w:docPartPr>${prParts.join("")}</w:docPartPr>`;
12592
12795
  }
12593
12796
  const glossaryDesc = {
@@ -12663,18 +12866,15 @@ const glossaryDesc = {
12663
12866
  };
12664
12867
  //#endregion
12665
12868
  //#region src/parts/comments.ts
12666
- function escapeAttr(s) {
12667
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
12668
- }
12669
12869
  const COMMENTS_NS = "xmlns:aink=\"http://schemas.microsoft.com/office/drawing/2016/ink\" xmlns:am3d=\"http://schemas.microsoft.com/office/drawing/2017/model3d\" xmlns:cx=\"http://schemas.microsoft.com/office/drawing/2014/chartex\" xmlns:cx1=\"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex\" xmlns:cx2=\"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex\" xmlns:cx3=\"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex\" xmlns:cx4=\"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex\" xmlns:cx5=\"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex\" xmlns:cx6=\"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex\" xmlns:cx7=\"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex\" xmlns:cx8=\"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" xmlns:w16cex=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" xmlns:w16sdtdh=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" xmlns:wne=\"http://schemas.openxmlformats.org/office/word/2006/wordml\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\"";
12670
12870
  function stringifyComment(opts, ctx) {
12671
12871
  const dateStr = typeof opts.date === "string" ? opts.date : (opts.date ?? /* @__PURE__ */ new Date()).toISOString();
12672
12872
  const attrs = [
12673
12873
  `w:id="${opts.id}"`,
12674
- `w:author="${escapeAttr(opts.author ?? "")}"`,
12675
- `w:date="${escapeAttr(dateStr)}"`
12874
+ `w:author="${escapeXml(opts.author ?? "")}"`,
12875
+ `w:date="${escapeXml(dateStr)}"`
12676
12876
  ];
12677
- if (opts.initials !== void 0) attrs.push(`w:initials="${escapeAttr(opts.initials)}"`);
12877
+ if (opts.initials !== void 0) attrs.push(`w:initials="${escapeXml(opts.initials)}"`);
12678
12878
  const parts = [];
12679
12879
  for (const child of opts.children) parts.push(stringifyParagraphInline(child, ctx));
12680
12880
  return `<w:comment ${attrs.join(" ")}>${parts.join("")}</w:comment>`;
@@ -12911,8 +13111,26 @@ function buildContentTypesFromRegistry(facts, dynamic = {}) {
12911
13111
  partName: sd.path.startsWith("/") ? sd.path : `/${sd.path}`,
12912
13112
  contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"
12913
13113
  });
13114
+ const defaults = [{
13115
+ extension: "rels",
13116
+ contentType: "application/vnd.openxmlformats-package.relationships+xml"
13117
+ }, {
13118
+ extension: "xml",
13119
+ contentType: "application/xml"
13120
+ }];
13121
+ const haveExt = new Set(["rels", "xml"]);
13122
+ for (const ac of dynamic.altChunks ?? []) {
13123
+ const ext = (ac.path.split(".").pop() ?? "").toLowerCase();
13124
+ if (ext && !haveExt.has(ext) && ALTCHUNK_DEFAULTS[ext]) {
13125
+ defaults.push({
13126
+ extension: ext,
13127
+ contentType: ALTCHUNK_DEFAULTS[ext]
13128
+ });
13129
+ haveExt.add(ext);
13130
+ }
13131
+ }
12914
13132
  return {
12915
- defaults: [...STANDARD_DEFAULTS],
13133
+ defaults,
12916
13134
  overrides
12917
13135
  };
12918
13136
  }
@@ -13035,14 +13253,11 @@ function wsOnOff(tag, val) {
13035
13253
  return `<${tag} w:val="${val ? "true" : "false"}"/>`;
13036
13254
  }
13037
13255
  function wsStringVal(tag, val) {
13038
- return `<${tag} w:val="${wsEscapeAttr(val)}"/>`;
13256
+ return `<${tag} w:val="${escapeXml(val)}"/>`;
13039
13257
  }
13040
13258
  function wsNumVal(tag, val) {
13041
13259
  return `<${tag} w:val="${val}"/>`;
13042
13260
  }
13043
- function wsEscapeAttr(s) {
13044
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
13045
- }
13046
13261
  function parseFramesetEl(el) {
13047
13262
  const opts = {};
13048
13263
  const sz = findChild(el, "w:sz");
@@ -13202,8 +13417,8 @@ function wsDivBorderXml(b) {
13202
13417
  ];
13203
13418
  for (const [tag, side] of sides) {
13204
13419
  if (!side) continue;
13205
- const attrParts = [`w:val="${wsEscapeAttr(side.style)}"`];
13206
- if (side.color) attrParts.push(`w:color="${wsEscapeAttr(side.color)}"`);
13420
+ const attrParts = [`w:val="${escapeXml(side.style)}"`];
13421
+ if (side.color) attrParts.push(`w:color="${escapeXml(side.color)}"`);
13207
13422
  if (side.size !== void 0) attrParts.push(`w:sz="${side.size}"`);
13208
13423
  parts.push(`<${tag} ${attrParts.join(" ")}/>`);
13209
13424
  }
@@ -13250,13 +13465,13 @@ function frameXml(f) {
13250
13465
  if (f.size !== void 0) parts.push(wsStringVal("w:sz", f.size));
13251
13466
  if (f.name !== void 0) parts.push(wsStringVal("w:name", f.name));
13252
13467
  if (f.title !== void 0) parts.push(wsStringVal("w:title", f.title));
13253
- if (f.sourceRId !== void 0) parts.push(`<w:sourceFileName r:id="${wsEscapeAttr(f.sourceRId)}"/>`);
13468
+ if (f.sourceRId !== void 0) parts.push(`<w:sourceFileName r:id="${escapeXml(f.sourceRId)}"/>`);
13254
13469
  if (f.marginWidth !== void 0) parts.push(wsNumVal("w:marW", f.marginWidth));
13255
13470
  if (f.marginHeight !== void 0) parts.push(wsNumVal("w:marH", f.marginHeight));
13256
13471
  if (f.scrollbar !== void 0) parts.push(`<w:scrollbar w:val="${f.scrollbar}"/>`);
13257
13472
  if (f.noResizeAllowed) parts.push("<w:noResizeAllowed/>");
13258
13473
  if (f.linkedToFile) parts.push("<w:linkedToFile/>");
13259
- if (f.longDescRId !== void 0) parts.push(`<w:longDesc r:id="${wsEscapeAttr(f.longDescRId)}"/>`);
13474
+ if (f.longDescRId !== void 0) parts.push(`<w:longDesc r:id="${escapeXml(f.longDescRId)}"/>`);
13260
13475
  parts.push("</w:frame>");
13261
13476
  return parts.join("");
13262
13477
  }
@@ -13276,7 +13491,7 @@ const webSettingsDesc = {
13276
13491
  if (typeof ob === "boolean") p.push(wsOnOff("w:optimizeForBrowser", ob));
13277
13492
  else {
13278
13493
  const valAttr = ob.value === false ? " w:val=\"false\"" : "";
13279
- const targetAttr = ob.target ? ` w:target="${wsEscapeAttr(ob.target)}"` : "";
13494
+ const targetAttr = ob.target ? ` w:target="${escapeXml(ob.target)}"` : "";
13280
13495
  p.push(`<w:optimizeForBrowser${valAttr}${targetAttr}/>`);
13281
13496
  }
13282
13497
  }
@@ -13341,6 +13556,6 @@ const webSettingsDesc = {
13341
13556
  }
13342
13557
  };
13343
13558
  //#endregion
13344
- export { PageBorderZOrder as $, stringifyCustomXmlShell as $t, settingsDesc as A, createBodyProperties as An, sectionPageSizeDefaults as At, stringifyConditionalTableStyle as B, TextAlignmentType as Bn, NumberFormat as Bt, footnotesDesc as C, EmphasisMarkType as Cn, parseSdtBlock as Ct, SdtDateMappingType as D, TextVertOverflowType as Dn, sectionPropertiesDesc as Dt, parseTocFieldInstruction as E, TextHorzOverflowType as En, parseSectionPropertiesEl as Et, parseStyleDefinitions as F, createTransformation as Fn, createVerticalPosition as Ft, createHeaderFooterReference as G, TextWrappingSide as Gt, stringifyTableStyle as H, HeadingLevel as Hn, VerticalPositionAlign as Ht, DefaultStylesFactory as I, HighlightColor as In, createHorizontalPosition as It, LineNumberRestartFormat as J, checkboxSymbolRunInner as Jt, SectionType as K, TextWrappingType as Kt, STYLE_ID_TO_DEFAULT_FIELD as L, TextEffect as Ln, HorizontalPositionRelativeFrom as Lt, buildNumberingCache as M, createImageData$1 as Mn, PageOrientation as Mt, buildStyleCache as N, WORKAROUND2 as Nn, PageNumberSeparator as Nt, SdtLock as O, TextVerticalType as On, stringifySectionPropertiesXml as Ot, extractStyleId as P, Media as Pn, createPageNumberType as Pt, PageBorderOffsetFrom as Q, setBodyParseChild as Qt, collectDefaultOverrideIds as R, PageNumber as Rn, VerticalPositionRelativeFrom as Rt, endnotesDesc as S, PositionalTabRelativeTo as Sn, stringifyTableOfContents as St, parseTocFieldFromElements as T, TextBodyWrappingType as Tn, FontWrapper as Tt, HeaderFooterReferenceType as U, LineRuleType as Un, createWrapThrough as Ut, stringifyParagraphStyle as V, TextboxTightWrapType as Vn, SpaceType as Vt, HeaderFooterType as W, AlignmentType as Wn, createWrapTight as Wt, createPageMargin as X, parseCustomXmlProperties as Xt, createLineNumberType as Y, customXmlBlockDesc as Yt, PageBorderDisplay as Z, sdtBlockDesc as Zt, glossaryDesc as _, createFormFieldData as _n, parseParagraph as _t, appPropertiesDesc as a, WidthType as an, LevelFormat as at, CharacterSet as b, PositionalTabAlignment as bn, stringifyDocumentXml as bt, relationshipsDesc as c, TableLayoutType as cn, parseTablePropertiesEl as ct, withAltChunkOverrides as d, RelativeVerticalPosition as dn, tableDesc as dt, stringifySdtPr as en, DocumentGridType as et, withMediaDefaults as f, TableAnchorType as fn, stringifyChildDispatch as ft, DocPartType as g, FormFieldTextType as gn, resetDrawingIdGen as gt, DocPartGallery as h, ProofErrorType as hn, drawingDesc as ht, webSettingsDesc as i, objectDesc as in, parseNumberingDefinitions as it, Styles as j, parseBodyProperties as jn, PageTextDirectionType as jt, StyleLevel as k, VerticalAnchor as kn, sectionMarginDefaults as kt, buildContentTypesFromRegistry as l, OverlapType as ln, parseTableRowPropertiesEl as lt, DocPartBehavior as m, VerticalMergeType as mn, stringifyRunInline as mt, frameXml as n, subDocDesc as nn, DocumentAttributeNamespaces as nt, customPropertiesDesc as o, TABLE_BORDERS_NONE as on, LevelSuffix as ot, commentsDesc as p, TextDirection as pn, stringifyParagraphInline as pt, createSectionType as q, altChunkDesc as qt, framesetXml as r, stringifyElement as rn, Numbering as rt, corePropertiesDesc as s, BorderStyle as sn, parseTableCellPropertiesEl as st, TargetScreenSize as t, stringifySdtShell as tn, createDocumentGrid as tt, contentTypesDesc as u, RelativeHorizontalPosition as un, setTableParseChild as ut, bibliographyDesc as v, parseFormFieldData as vn, parseParagraphProperties as vt, parseToc as w, UnderlineType as wn, parseSdtProperties as wt, EditGroupType as x, PositionalTabLeader as xn, replaceRelsWithPlaceholders as xt, fontTableDesc as y, RubyAlign as yn, stringifyBodyChild as yt, stringifyCharacterStyle as z, breakXml as zn, HorizontalPositionAlign as zt };
13559
+ export { DocumentGridType as $, stringifySdtPr as $t, settingsDesc as A, parseBodyProperties as An, PageTextDirectionType as At, stringifyParagraphStyle as B, HeadingLevel as Bn, SpaceType as Bt, footnotesDesc as C, UnderlineType as Cn, parseSdtProperties as Ct, SdtDateMappingType as D, TextVerticalType as Dn, stringifySectionPropertiesXml as Dt, parseTocFieldInstruction as E, TextVertOverflowType as En, sectionPropertiesDesc as Et, parseStyleDefinitions as F, TextEffect as Fn, createHorizontalPosition as Ft, SectionType as G, TextWrappingType as Gt, HeaderFooterReferenceType as H, AlignmentType as Hn, createWrapThrough as Ht, DefaultStylesFactory as I, PageNumber as In, HorizontalPositionRelativeFrom as It, createLineNumberType as J, customXmlBlockDesc as Jt, createSectionType as K, altChunkDesc as Kt, stringifyCharacterStyle as L, breakXml as Ln, VerticalPositionRelativeFrom as Lt, buildNumberingCache as M, Media as Mn, PageNumberSeparator as Mt, buildStyleCache as N, createTransformation as Nn, createPageNumberType as Nt, SdtLock as O, VerticalAnchor as On, sectionMarginDefaults as Ot, extractStyleId as P, HighlightColor as Pn, createVerticalPosition as Pt, PageBorderZOrder as Q, stringifyCustomXmlShell as Qt, stringifyConditionalTableStyle as R, TextAlignmentType as Rn, HorizontalPositionAlign as Rt, endnotesDesc as S, EmphasisMarkType as Sn, parseSdtBlock as St, parseTocFieldFromElements as T, TextHorzOverflowType as Tn, parseSectionPropertiesEl as Tt, HeaderFooterType as U, createWrapTight as Ut, stringifyTableStyle as V, LineRuleType as Vn, VerticalPositionAlign as Vt, createHeaderFooterReference as W, TextWrappingSide as Wt, PageBorderDisplay as X, sdtBlockDesc as Xt, createPageMargin as Y, parseCustomXmlProperties as Yt, PageBorderOffsetFrom as Z, setBodyParseChild as Zt, glossaryDesc as _, parseFormFieldData as _n, parseParagraphProperties as _t, appPropertiesDesc as a, TABLE_BORDERS_NONE as an, LevelSuffix as at, CharacterSet as b, PositionalTabLeader as bn, replaceRelsWithPlaceholders as bt, relationshipsDesc as c, OverlapType as cn, parseTableRowPropertiesEl as ct, withAltChunkOverrides as d, TableAnchorType as dn, stringifyChildDispatch as dt, stringifySdtShell as en, createDocumentGrid as et, withMediaDefaults as f, TextDirection as fn, stringifyParagraphInline as ft, DocPartType as g, createFormFieldData as gn, parseParagraph as gt, DocPartGallery as h, FormFieldTextType as hn, resetDrawingIdGen as ht, webSettingsDesc as i, WidthType as in, LevelFormat as it, Styles as j, createImageData$1 as jn, PageOrientation as jt, StyleLevel as k, createBodyProperties as kn, sectionPageSizeDefaults as kt, buildContentTypesFromRegistry as l, RelativeHorizontalPosition as ln, setTableParseChild as lt, DocPartBehavior as m, ProofErrorType as mn, drawingDesc as mt, frameXml as n, stringifyElement as nn, Numbering as nt, customPropertiesDesc as o, BorderStyle as on, parseTableCellPropertiesEl as ot, commentsDesc as p, VerticalMergeType as pn, stringifyRunInline as pt, LineNumberRestartFormat as q, checkboxSymbolRunInner as qt, framesetXml as r, objectDesc as rn, parseNumberingDefinitions as rt, corePropertiesDesc as s, TableLayoutType as sn, parseTablePropertiesEl as st, TargetScreenSize as t, subDocDesc as tn, DocumentAttributeNamespaces as tt, contentTypesDesc as u, RelativeVerticalPosition as un, tableDesc as ut, bibliographyDesc as v, RubyAlign as vn, stringifyBodyChild as vt, parseToc as w, TextBodyWrappingType as wn, FontWrapper as wt, EditGroupType as x, PositionalTabRelativeTo as xn, stringifyTableOfContents as xt, fontTableDesc as y, PositionalTabAlignment as yn, stringifyDocumentXml as yt, stringifyNumberingStyle as z, TextboxTightWrapType as zn, NumberFormat as zt };
13345
13560
 
13346
- //# sourceMappingURL=parts-DvRRYUug.mjs.map
13561
+ //# sourceMappingURL=parts-BXGYKB-u.mjs.map