documents.js 1.40.0 → 1.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -6,17 +6,26 @@ let odf_js = require("odf.js");
6
6
  let fflate = require("fflate");
7
7
  //#region src/model/content.ts
8
8
  const CONTENT_FORMAT_VERSION = 1;
9
- const ContentDocumentSchema = zod.z.discriminatedUnion("kind", [zod.z.object({
10
- kind: zod.z.literal("wordprocessing"),
11
- formatVersion: zod.z.literal(1),
12
- metadata: document_content_model.LayoutMetadataSchema,
13
- sections: zod.z.array(document_content_model.ContentSectionSchema)
14
- }), zod.z.object({
15
- kind: zod.z.literal("presentation"),
16
- formatVersion: zod.z.literal(1),
17
- metadata: document_content_model.LayoutMetadataSchema,
18
- slides: zod.z.array(document_content_model.ContentSlideSchema)
19
- })]);
9
+ const ContentDocumentSchema = zod.z.discriminatedUnion("kind", [
10
+ zod.z.object({
11
+ kind: zod.z.literal("wordprocessing"),
12
+ formatVersion: zod.z.literal(1),
13
+ metadata: document_content_model.LayoutMetadataSchema,
14
+ sections: zod.z.array(document_content_model.ContentSectionSchema)
15
+ }),
16
+ zod.z.object({
17
+ kind: zod.z.literal("presentation"),
18
+ formatVersion: zod.z.literal(1),
19
+ metadata: document_content_model.LayoutMetadataSchema,
20
+ slides: zod.z.array(document_content_model.ContentSlideSchema)
21
+ }),
22
+ zod.z.object({
23
+ kind: zod.z.literal("spreadsheet"),
24
+ formatVersion: zod.z.literal(1),
25
+ metadata: document_content_model.LayoutMetadataSchema,
26
+ sheets: zod.z.array(document_content_model.ContentSheetSchema)
27
+ })
28
+ ]);
20
29
  //#endregion
21
30
  //#region src/model/geometry.ts
22
31
  function flipY(box, containerHeightPt) {
@@ -301,11 +310,11 @@ function ensureContentTypeOverride(pkg, partPath, contentType) {
301
310
  //#endregion
302
311
  //#region src/opc/media.ts
303
312
  const IMAGE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
304
- function escapeRegExp(value) {
313
+ function escapeRegExp$1(value) {
305
314
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
306
315
  }
307
316
  function nextMediaIndex(pkg, mediaDir, fileNamePrefix, extension) {
308
- const pattern = new RegExp(`^${escapeRegExp(fileNamePrefix)}(\\d+)\\.${escapeRegExp(extension)}$`);
317
+ const pattern = new RegExp(`^${escapeRegExp$1(fileNamePrefix)}(\\d+)\\.${escapeRegExp$1(extension)}$`);
309
318
  const prefix = `${mediaDir}/`;
310
319
  let max = 0;
311
320
  for (const path of Object.keys(pkg.parts)) {
@@ -319,7 +328,7 @@ function nextMediaIndex(pkg, mediaDir, fileNamePrefix, extension) {
319
328
  }
320
329
  return max + 1;
321
330
  }
322
- function addImageMedia(pkg, fromPartPath, mediaDir, format, bytes) {
331
+ function addImageMedia$1(pkg, fromPartPath, mediaDir, format, bytes) {
323
332
  const extension = format === "jpeg" ? "jpeg" : "png";
324
333
  const fileNamePrefix = "image";
325
334
  const partPath = `${mediaDir}/${fileNamePrefix}${nextMediaIndex(pkg, mediaDir, fileNamePrefix, extension)}.${extension}`;
@@ -401,7 +410,7 @@ function buildInlineDrawing(relationshipId, widthPt, heightPt, id, altText) {
401
410
  }, [inline]);
402
411
  }
403
412
  function insertImageMedia(context, documentRoot, image) {
404
- const { relationshipId } = addImageMedia(context.pkg, context.partPath, context.mediaDir, image.format, image.bytes);
413
+ const { relationshipId } = addImageMedia$1(context.pkg, context.partPath, context.mediaDir, image.format, image.bytes);
405
414
  const id = nextDrawingId(documentRoot);
406
415
  return buildInlineDrawing(relationshipId, image.widthPt, image.heightPt, id, image.altText);
407
416
  }
@@ -521,7 +530,7 @@ function needsSpacePreserve(text) {
521
530
  }
522
531
  //#endregion
523
532
  //#region src/edit/docx/run.ts
524
- function directChild$5(parent, tag) {
533
+ function directChild$8(parent, tag) {
525
534
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
526
535
  }
527
536
  function appendUElement(rPr, value) {
@@ -530,7 +539,7 @@ function appendUElement(rPr, value) {
530
539
  return created;
531
540
  }
532
541
  function findOrCreateT(run) {
533
- const existing = directChild$5(run, "w:t");
542
+ const existing = directChild$8(run, "w:t");
534
543
  if (existing !== void 0) return existing;
535
544
  const created = el("w:t");
536
545
  run.children.push(created);
@@ -550,7 +559,7 @@ var DocxRun = class {
550
559
  }
551
560
  rPr(create) {
552
561
  const node = this.live();
553
- return create ? ensureFirstChild(node, "w:rPr") : directChild$5(node, "w:rPr");
562
+ return create ? ensureFirstChild(node, "w:rPr") : directChild$8(node, "w:rPr");
554
563
  }
555
564
  get text() {
556
565
  return (0, ooxml_js.textContent)(this.live());
@@ -574,14 +583,14 @@ var DocxRun = class {
574
583
  }
575
584
  get underline() {
576
585
  const rPr = this.rPr(false);
577
- const uElement = rPr === void 0 ? void 0 : directChild$5(rPr, "w:u");
586
+ const uElement = rPr === void 0 ? void 0 : directChild$8(rPr, "w:u");
578
587
  if (uElement === void 0) return false;
579
588
  for (const a of uElement.attributes) if (a.name === "w:val") return a.value !== "none";
580
589
  return true;
581
590
  }
582
591
  set underline(value) {
583
592
  const rPr = this.rPr(true);
584
- const existing = directChild$5(rPr, "w:u");
593
+ const existing = directChild$8(rPr, "w:u");
585
594
  if (existing === void 0) {
586
595
  appendUElement(rPr, value);
587
596
  return;
@@ -655,7 +664,7 @@ function buildRun$1(init = {}) {
655
664
  }
656
665
  //#endregion
657
666
  //#region src/edit/docx/paragraph.ts
658
- function directChild$4(parent, tag) {
667
+ function directChild$7(parent, tag) {
659
668
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
660
669
  }
661
670
  var DocxParagraph = class {
@@ -674,7 +683,7 @@ var DocxParagraph = class {
674
683
  }
675
684
  pPr(create) {
676
685
  const node = this.live();
677
- return create ? ensureFirstChild(node, "w:pPr") : directChild$4(node, "w:pPr");
686
+ return create ? ensureFirstChild(node, "w:pPr") : directChild$7(node, "w:pPr");
678
687
  }
679
688
  get text() {
680
689
  return (0, ooxml_js.textContent)(this.live());
@@ -711,7 +720,7 @@ var DocxParagraph = class {
711
720
  set styleId(value) {
712
721
  if (value === void 0) {
713
722
  const pPr = this.pPr(false);
714
- const existing = pPr === void 0 ? void 0 : directChild$4(pPr, "w:pStyle");
723
+ const existing = pPr === void 0 ? void 0 : directChild$7(pPr, "w:pStyle");
715
724
  if (existing !== void 0 && pPr !== void 0) removeChild(pPr.children, existing);
716
725
  return;
717
726
  }
@@ -723,7 +732,7 @@ var DocxParagraph = class {
723
732
  set alignment(value) {
724
733
  if (value === void 0) {
725
734
  const pPr = this.pPr(false);
726
- const existing = pPr === void 0 ? void 0 : directChild$4(pPr, "w:jc");
735
+ const existing = pPr === void 0 ? void 0 : directChild$7(pPr, "w:jc");
727
736
  if (existing !== void 0 && pPr !== void 0) removeChild(pPr.children, existing);
728
737
  return;
729
738
  }
@@ -731,12 +740,12 @@ var DocxParagraph = class {
731
740
  }
732
741
  get list() {
733
742
  const pPr = this.pPr(false);
734
- const numPr = pPr === void 0 ? void 0 : directChild$4(pPr, "w:numPr");
743
+ const numPr = pPr === void 0 ? void 0 : directChild$7(pPr, "w:numPr");
735
744
  if (numPr === void 0) return;
736
- const numIdElement = directChild$4(numPr, "w:numId");
745
+ const numIdElement = directChild$7(numPr, "w:numId");
737
746
  const numId = numIdElement === void 0 ? void 0 : (0, ooxml_js.attr)(numIdElement, "w:val");
738
747
  if (numId === void 0) return;
739
- const ilvlElement = directChild$4(numPr, "w:ilvl");
748
+ const ilvlElement = directChild$7(numPr, "w:ilvl");
740
749
  const ilvl = ilvlElement === void 0 ? void 0 : (0, ooxml_js.attr)(ilvlElement, "w:val");
741
750
  return {
742
751
  numId,
@@ -746,7 +755,7 @@ var DocxParagraph = class {
746
755
  set list(value) {
747
756
  const pPr = this.pPr(true);
748
757
  if (value === void 0) {
749
- const existing = directChild$4(pPr, "w:numPr");
758
+ const existing = directChild$7(pPr, "w:numPr");
750
759
  if (existing !== void 0) removeChild(pPr.children, existing);
751
760
  return;
752
761
  }
@@ -780,7 +789,7 @@ function buildParagraph$1(init = {}) {
780
789
  const CONTENT_TYPES_NS$1 = "http://schemas.openxmlformats.org/package/2006/content-types";
781
790
  const RELS_NS$1 = "http://schemas.openxmlformats.org/package/2006/relationships";
782
791
  const WORDML_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
783
- function declaration$2() {
792
+ function declaration$3() {
784
793
  return {
785
794
  type: "declaration",
786
795
  attributes: [
@@ -849,23 +858,23 @@ function createEmptyDocxPackage() {
849
858
  return { parts: {
850
859
  "[Content_Types].xml": {
851
860
  kind: "xml",
852
- nodes: [declaration$2(), contentTypes]
861
+ nodes: [declaration$3(), contentTypes]
853
862
  },
854
863
  "_rels/.rels": {
855
864
  kind: "xml",
856
- nodes: [declaration$2(), rootRels]
865
+ nodes: [declaration$3(), rootRels]
857
866
  },
858
867
  "word/document.xml": {
859
868
  kind: "xml",
860
- nodes: [declaration$2(), document]
869
+ nodes: [declaration$3(), document]
861
870
  },
862
871
  "word/_rels/document.xml.rels": {
863
872
  kind: "xml",
864
- nodes: [declaration$2(), documentRels]
873
+ nodes: [declaration$3(), documentRels]
865
874
  },
866
875
  "word/styles.xml": {
867
876
  kind: "xml",
868
- nodes: [declaration$2(), styles]
877
+ nodes: [declaration$3(), styles]
869
878
  }
870
879
  } };
871
880
  }
@@ -1156,7 +1165,7 @@ const SLIDE_LAYOUT_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/
1156
1165
  const THEME_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
1157
1166
  const NOTES_MASTER_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster";
1158
1167
  const MIN_MASTER_OR_LAYOUT_ID = 2147483648;
1159
- function declaration$1() {
1168
+ function declaration$2() {
1160
1169
  return {
1161
1170
  type: "declaration",
1162
1171
  attributes: [
@@ -1306,7 +1315,7 @@ function ensureNotesMaster(pkg) {
1306
1315
  });
1307
1316
  pkg.parts[NOTES_MASTER_PART_PATH] = {
1308
1317
  kind: "xml",
1309
- nodes: [declaration$1(), buildNotesMaster()]
1318
+ nodes: [declaration$2(), buildNotesMaster()]
1310
1319
  };
1311
1320
  ensureContentTypeOverride(pkg, NOTES_MASTER_PART_PATH, NOTES_MASTER_CONTENT_TYPE);
1312
1321
  const presentationToNotesMasterTarget = buildRelativeTarget(PRESENTATION_PART_PATH$1, NOTES_MASTER_PART_PATH);
@@ -1345,15 +1354,15 @@ function createEmptyPptxPackage() {
1345
1354
  const pkg = { parts: {
1346
1355
  "[Content_Types].xml": {
1347
1356
  kind: "xml",
1348
- nodes: [declaration$1(), contentTypes]
1357
+ nodes: [declaration$2(), contentTypes]
1349
1358
  },
1350
1359
  "_rels/.rels": {
1351
1360
  kind: "xml",
1352
- nodes: [declaration$1(), rootRels]
1361
+ nodes: [declaration$2(), rootRels]
1353
1362
  },
1354
1363
  [PRESENTATION_PART_PATH$1]: {
1355
1364
  kind: "xml",
1356
- nodes: [declaration$1(), el("p:presentation", {
1365
+ nodes: [declaration$2(), el("p:presentation", {
1357
1366
  "xmlns:p": PML_NS,
1358
1367
  "xmlns:r": R_NS
1359
1368
  })]
@@ -1366,7 +1375,7 @@ function createEmptyPptxPackage() {
1366
1375
  });
1367
1376
  pkg.parts[SLIDE_LAYOUT_PART_PATH] = {
1368
1377
  kind: "xml",
1369
- nodes: [declaration$1(), buildSlideLayout()]
1378
+ nodes: [declaration$2(), buildSlideLayout()]
1370
1379
  };
1371
1380
  ensureContentTypeOverride(pkg, SLIDE_LAYOUT_PART_PATH, SLIDE_LAYOUT_CONTENT_TYPE);
1372
1381
  const masterToLayoutTarget = buildRelativeTarget(SLIDE_MASTER_PART_PATH, SLIDE_LAYOUT_PART_PATH);
@@ -1381,12 +1390,12 @@ function createEmptyPptxPackage() {
1381
1390
  });
1382
1391
  pkg.parts[SLIDE_MASTER_PART_PATH] = {
1383
1392
  kind: "xml",
1384
- nodes: [declaration$1(), buildSlideMaster(masterToLayoutRelId)]
1393
+ nodes: [declaration$2(), buildSlideMaster(masterToLayoutRelId)]
1385
1394
  };
1386
1395
  ensureContentTypeOverride(pkg, SLIDE_MASTER_PART_PATH, SLIDE_MASTER_CONTENT_TYPE);
1387
1396
  pkg.parts[THEME_PART_PATH] = {
1388
1397
  kind: "xml",
1389
- nodes: [declaration$1(), buildTheme()]
1398
+ nodes: [declaration$2(), buildTheme()]
1390
1399
  };
1391
1400
  ensureContentTypeOverride(pkg, THEME_PART_PATH, THEME_CONTENT_TYPE);
1392
1401
  const presentationToMasterTarget = buildRelativeTarget(PRESENTATION_PART_PATH$1, SLIDE_MASTER_PART_PATH);
@@ -1411,7 +1420,7 @@ function createEmptyPptxPackage() {
1411
1420
  }
1412
1421
  //#endregion
1413
1422
  //#region src/edit/pptx/shape.ts
1414
- function directChild$3(parent, tag) {
1423
+ function directChild$6(parent, tag) {
1415
1424
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
1416
1425
  }
1417
1426
  function parseEmuAttr(element, name) {
@@ -1432,7 +1441,7 @@ var PptxShape = class {
1432
1441
  }
1433
1442
  spPrElement(create) {
1434
1443
  const node = this.live();
1435
- const existing = directChild$3(node, "p:spPr");
1444
+ const existing = directChild$6(node, "p:spPr");
1436
1445
  if (existing !== void 0 || !create) return existing;
1437
1446
  const created = el("p:spPr");
1438
1447
  node.children.push(created);
@@ -1440,10 +1449,10 @@ var PptxShape = class {
1440
1449
  }
1441
1450
  get frame() {
1442
1451
  const spPr = this.spPrElement(false);
1443
- const xfrm = spPr === void 0 ? void 0 : directChild$3(spPr, "a:xfrm");
1452
+ const xfrm = spPr === void 0 ? void 0 : directChild$6(spPr, "a:xfrm");
1444
1453
  if (xfrm === void 0) return;
1445
- const off = directChild$3(xfrm, "a:off");
1446
- const ext = directChild$3(xfrm, "a:ext");
1454
+ const off = directChild$6(xfrm, "a:off");
1455
+ const ext = directChild$6(xfrm, "a:ext");
1447
1456
  if (off === void 0 || ext === void 0) return;
1448
1457
  const x = parseEmuAttr(off, "x");
1449
1458
  const y = parseEmuAttr(off, "y");
@@ -1459,7 +1468,7 @@ var PptxShape = class {
1459
1468
  }
1460
1469
  set frame(value) {
1461
1470
  const spPr = this.spPrElement(true);
1462
- let xfrm = directChild$3(spPr, "a:xfrm");
1471
+ let xfrm = directChild$6(spPr, "a:xfrm");
1463
1472
  if (xfrm === void 0) {
1464
1473
  xfrm = el("a:xfrm");
1465
1474
  spPr.children.unshift(xfrm);
@@ -1473,12 +1482,12 @@ var PptxShape = class {
1473
1482
  })];
1474
1483
  }
1475
1484
  get text() {
1476
- const txBody = directChild$3(this.live(), "p:txBody");
1485
+ const txBody = directChild$6(this.live(), "p:txBody");
1477
1486
  return txBody === void 0 ? "" : (0, ooxml_js.textContent)(txBody);
1478
1487
  }
1479
1488
  set text(value) {
1480
1489
  const node = this.live();
1481
- let txBody = directChild$3(node, "p:txBody");
1490
+ let txBody = directChild$6(node, "p:txBody");
1482
1491
  if (txBody === void 0) {
1483
1492
  txBody = el("p:txBody", {}, [el("a:bodyPr"), el("a:lstStyle")]);
1484
1493
  node.children.push(txBody);
@@ -1489,7 +1498,7 @@ var PptxShape = class {
1489
1498
  }
1490
1499
  setParagraphs(paragraphs) {
1491
1500
  const node = this.live();
1492
- let txBody = directChild$3(node, "p:txBody");
1501
+ let txBody = directChild$6(node, "p:txBody");
1493
1502
  if (txBody === void 0) {
1494
1503
  txBody = el("p:txBody", {}, [el("a:bodyPr"), el("a:lstStyle")]);
1495
1504
  node.children.push(txBody);
@@ -1595,17 +1604,17 @@ function nextShapeId(slideRoot) {
1595
1604
  return max + 1;
1596
1605
  }
1597
1606
  function insertPictureShapeMedia(context, slideRoot, frame, image) {
1598
- const { relationshipId } = addImageMedia(context.pkg, context.partPath, context.mediaDir, image.format, image.bytes);
1607
+ const { relationshipId } = addImageMedia$1(context.pkg, context.partPath, context.mediaDir, image.format, image.bytes);
1599
1608
  return buildPictureShape(frame, relationshipId, nextShapeId(slideRoot));
1600
1609
  }
1601
1610
  //#endregion
1602
1611
  //#region src/edit/pptx/slide.ts
1603
- function directChild$2(parent, tag) {
1612
+ function directChild$5(parent, tag) {
1604
1613
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
1605
1614
  }
1606
1615
  function findSpTree(slideRoot) {
1607
- const cSld = directChild$2(slideRoot, "p:cSld");
1608
- const spTree = cSld === void 0 ? void 0 : directChild$2(cSld, "p:spTree");
1616
+ const cSld = directChild$5(slideRoot, "p:cSld");
1617
+ const spTree = cSld === void 0 ? void 0 : directChild$5(cSld, "p:spTree");
1609
1618
  if (spTree === void 0) throw new Error("slide has no p:cSld/p:spTree element");
1610
1619
  return spTree;
1611
1620
  }
@@ -1737,7 +1746,7 @@ const PRESENTATION_PART_PATH = "ppt/presentation.xml";
1737
1746
  const MEDIA_DIR = "ppt/media";
1738
1747
  const SLIDE_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.slide+xml";
1739
1748
  const SLIDE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide";
1740
- function directChild$1(parent, tag) {
1749
+ function directChild$4(parent, tag) {
1741
1750
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
1742
1751
  }
1743
1752
  function attrValue(element, name) {
@@ -1749,12 +1758,12 @@ function findPresentationRoot(pkg) {
1749
1758
  return root;
1750
1759
  }
1751
1760
  function findSldIdLst(presentationRoot) {
1752
- const sldIdLst = directChild$1(presentationRoot, "p:sldIdLst");
1761
+ const sldIdLst = directChild$4(presentationRoot, "p:sldIdLst");
1753
1762
  if (sldIdLst === void 0) throw new Error(`${PRESENTATION_PART_PATH} has no p:sldIdLst element`);
1754
1763
  return sldIdLst;
1755
1764
  }
1756
1765
  function findSldSz(presentationRoot) {
1757
- const sldSz = directChild$1(presentationRoot, "p:sldSz");
1766
+ const sldSz = directChild$4(presentationRoot, "p:sldSz");
1758
1767
  if (sldSz === void 0) throw new Error(`${PRESENTATION_PART_PATH} has no p:sldSz element`);
1759
1768
  return sldSz;
1760
1769
  }
@@ -1915,12 +1924,12 @@ function buildPptxPackage(content) {
1915
1924
  if (firstSlide !== void 0) editor.slideSize = firstSlide.size;
1916
1925
  for (const slide of content.slides) {
1917
1926
  const pptxSlide = editor.addSlide();
1918
- for (const shape of slide.shapes) appendShape(pptxSlide, shape);
1927
+ for (const shape of slide.shapes) appendShape$1(pptxSlide, shape);
1919
1928
  if (slide.notes.length > 0) pptxSlide.notes = slide.notes;
1920
1929
  }
1921
1930
  return editor.toPackage();
1922
1931
  }
1923
- function appendShape(slide, shape) {
1932
+ function appendShape$1(slide, shape) {
1924
1933
  const [onlyBlock] = shape.blocks;
1925
1934
  if (shape.blocks.length === 1 && onlyBlock?.kind === "image") {
1926
1935
  slide.addImage({
@@ -1953,12 +1962,12 @@ function appendShape(slide, shape) {
1953
1962
  }
1954
1963
  //#endregion
1955
1964
  //#region src/edit/odt/automatic-styles.ts
1956
- const CONTENT_PART_PATH$1 = "content.xml";
1965
+ const CONTENT_PART_PATH$2 = "content.xml";
1957
1966
  function ensureAutomaticStyles(pkg) {
1958
- const part = pkg.parts[CONTENT_PART_PATH$1];
1959
- if (part?.kind !== "xml") throw new Error(`ensureAutomaticStyles: package has no ${CONTENT_PART_PATH$1} part`);
1967
+ const part = pkg.parts[CONTENT_PART_PATH$2];
1968
+ if (part?.kind !== "xml") throw new Error(`ensureAutomaticStyles: package has no ${CONTENT_PART_PATH$2} part`);
1960
1969
  const root = part.nodes.find((n) => n.type === "element");
1961
- if (root === void 0) throw new Error(`ensureAutomaticStyles: ${CONTENT_PART_PATH$1} has no root element`);
1970
+ if (root === void 0) throw new Error(`ensureAutomaticStyles: ${CONTENT_PART_PATH$2} has no root element`);
1962
1971
  for (const child of root.children) if (child.type === "element" && child.tag === "office:automatic-styles") return child;
1963
1972
  const created = el("office:automatic-styles");
1964
1973
  const insertBeforeTags = /* @__PURE__ */ new Set([
@@ -2052,7 +2061,7 @@ function applyStyleChange(pkg, element, family, change) {
2052
2061
  ...readCurrentStyleProperties(pkg, element, family),
2053
2062
  ...change
2054
2063
  };
2055
- const name = odf_js.StyleRegistry.forPart(pkg, CONTENT_PART_PATH$1).intern({
2064
+ const name = odf_js.StyleRegistry.forPart(pkg, CONTENT_PART_PATH$2).intern({
2056
2065
  family,
2057
2066
  properties: merged
2058
2067
  });
@@ -2283,7 +2292,7 @@ function buildList(pkg) {
2283
2292
  }
2284
2293
  //#endregion
2285
2294
  //#region src/edit/odt/scaffold.ts
2286
- const CONTENT_NS_PREFIXES = [
2295
+ const CONTENT_NS_PREFIXES$1 = [
2287
2296
  "office",
2288
2297
  "style",
2289
2298
  "text",
@@ -2293,7 +2302,7 @@ const CONTENT_NS_PREFIXES = [
2293
2302
  "svg",
2294
2303
  "xlink"
2295
2304
  ];
2296
- const STYLES_NS_PREFIXES = [
2305
+ const STYLES_NS_PREFIXES$1 = [
2297
2306
  "office",
2298
2307
  "style",
2299
2308
  "text",
@@ -2303,16 +2312,16 @@ const STYLES_NS_PREFIXES = [
2303
2312
  "svg",
2304
2313
  "xlink"
2305
2314
  ];
2306
- const META_NS_PREFIXES = [
2315
+ const META_NS_PREFIXES$1 = [
2307
2316
  "office",
2308
2317
  "meta",
2309
2318
  "dc"
2310
2319
  ];
2311
- const ODF_VERSION = "1.3";
2312
- const PAGE_LAYOUT_NAME = "PM1";
2313
- const MASTER_PAGE_NAME = "Standard";
2320
+ const ODF_VERSION$1 = "1.3";
2321
+ const PAGE_LAYOUT_NAME$1 = "PM1";
2322
+ const MASTER_PAGE_NAME$1 = "Standard";
2314
2323
  const DEFAULT_MARGIN_PT = 72;
2315
- function declaration() {
2324
+ function declaration$1() {
2316
2325
  return {
2317
2326
  type: "declaration",
2318
2327
  attributes: [
@@ -2331,8 +2340,8 @@ function declaration() {
2331
2340
  ]
2332
2341
  };
2333
2342
  }
2334
- function buildPageLayout() {
2335
- return el("style:page-layout", { "style:name": PAGE_LAYOUT_NAME }, [el("style:page-layout-properties", {
2343
+ function buildPageLayout$1() {
2344
+ return el("style:page-layout", { "style:name": PAGE_LAYOUT_NAME$1 }, [el("style:page-layout-properties", {
2336
2345
  "fo:page-width": `${document_content_model.PAGE_SIZE_LETTER.widthPt}pt`,
2337
2346
  "fo:page-height": `${document_content_model.PAGE_SIZE_LETTER.heightPt}pt`,
2338
2347
  "fo:margin-top": `${DEFAULT_MARGIN_PT}pt`,
@@ -2341,44 +2350,44 @@ function buildPageLayout() {
2341
2350
  "fo:margin-left": `${DEFAULT_MARGIN_PT}pt`
2342
2351
  })]);
2343
2352
  }
2344
- function buildStylesXml() {
2353
+ function buildStylesXml$1() {
2345
2354
  return el("office:document-styles", {
2346
- ...(0, odf_js.xmlnsAttributes)([...STYLES_NS_PREFIXES]),
2347
- "office:version": ODF_VERSION
2355
+ ...(0, odf_js.xmlnsAttributes)([...STYLES_NS_PREFIXES$1]),
2356
+ "office:version": ODF_VERSION$1
2348
2357
  }, [
2349
2358
  el("office:styles"),
2350
- el("office:automatic-styles", {}, [buildPageLayout()]),
2359
+ el("office:automatic-styles", {}, [buildPageLayout$1()]),
2351
2360
  el("office:master-styles", {}, [el("style:master-page", {
2352
- "style:name": MASTER_PAGE_NAME,
2353
- "style:page-layout-name": PAGE_LAYOUT_NAME
2361
+ "style:name": MASTER_PAGE_NAME$1,
2362
+ "style:page-layout-name": PAGE_LAYOUT_NAME$1
2354
2363
  })])
2355
2364
  ]);
2356
2365
  }
2357
- function buildContentXml() {
2366
+ function buildContentXml$1() {
2358
2367
  return el("office:document-content", {
2359
- ...(0, odf_js.xmlnsAttributes)([...CONTENT_NS_PREFIXES]),
2360
- "office:version": ODF_VERSION
2368
+ ...(0, odf_js.xmlnsAttributes)([...CONTENT_NS_PREFIXES$1]),
2369
+ "office:version": ODF_VERSION$1
2361
2370
  }, [el("office:automatic-styles"), el("office:body", {}, [el("office:text")])]);
2362
2371
  }
2363
- function buildMetaXml() {
2372
+ function buildMetaXml$1() {
2364
2373
  return el("office:document-meta", {
2365
- ...(0, odf_js.xmlnsAttributes)([...META_NS_PREFIXES]),
2366
- "office:version": ODF_VERSION
2374
+ ...(0, odf_js.xmlnsAttributes)([...META_NS_PREFIXES$1]),
2375
+ "office:version": ODF_VERSION$1
2367
2376
  }, [el("office:meta")]);
2368
2377
  }
2369
2378
  function createEmptyOdtPackage() {
2370
2379
  const pkg = { parts: {
2371
2380
  "content.xml": {
2372
2381
  kind: "xml",
2373
- nodes: [declaration(), buildContentXml()]
2382
+ nodes: [declaration$1(), buildContentXml$1()]
2374
2383
  },
2375
2384
  "styles.xml": {
2376
2385
  kind: "xml",
2377
- nodes: [declaration(), buildStylesXml()]
2386
+ nodes: [declaration$1(), buildStylesXml$1()]
2378
2387
  },
2379
2388
  "meta.xml": {
2380
2389
  kind: "xml",
2381
- nodes: [declaration(), buildMetaXml()]
2390
+ nodes: [declaration$1(), buildMetaXml$1()]
2382
2391
  }
2383
2392
  } };
2384
2393
  (0, odf_js.setDocumentMediaType)(pkg, odf_js.ODF_MEDIA_TYPES.odt);
@@ -2499,20 +2508,20 @@ function buildTable(pkg, init) {
2499
2508
  }
2500
2509
  //#endregion
2501
2510
  //#region src/edit/odt/editor.ts
2502
- const CONTENT_PART_PATH = "content.xml";
2511
+ const CONTENT_PART_PATH$1 = "content.xml";
2503
2512
  function findContentRoot(pkg) {
2504
- const part = pkg.parts[CONTENT_PART_PATH];
2513
+ const part = pkg.parts[CONTENT_PART_PATH$1];
2505
2514
  const root = part?.kind === "xml" ? part.nodes.find((n) => n.type === "element") : void 0;
2506
- if (root === void 0) throw new Error(`package has no root element at ${CONTENT_PART_PATH}`);
2515
+ if (root === void 0) throw new Error(`package has no root element at ${CONTENT_PART_PATH$1}`);
2507
2516
  return root;
2508
2517
  }
2509
- function directChild(parent, tag) {
2518
+ function directChild$3(parent, tag) {
2510
2519
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
2511
2520
  }
2512
2521
  function findOfficeText(contentRoot) {
2513
- const body = directChild(contentRoot, "office:body");
2514
- const text = body === void 0 ? void 0 : directChild(body, "office:text");
2515
- if (text === void 0) throw new Error(`${CONTENT_PART_PATH} has no office:body/office:text element`);
2522
+ const body = directChild$3(contentRoot, "office:body");
2523
+ const text = body === void 0 ? void 0 : directChild$3(body, "office:text");
2524
+ if (text === void 0) throw new Error(`${CONTENT_PART_PATH$1} has no office:body/office:text element`);
2516
2525
  return text;
2517
2526
  }
2518
2527
  var OdtBodyImpl = class {
@@ -2643,6 +2652,474 @@ function appendBlock(body, block) {
2643
2652
  else if (block.kind === "table") appendTable(body, block);
2644
2653
  }
2645
2654
  //#endregion
2655
+ //#region src/edit/odp/scaffold.ts
2656
+ const CONTENT_NS_PREFIXES = [
2657
+ "office",
2658
+ "style",
2659
+ "text",
2660
+ "table",
2661
+ "draw",
2662
+ "presentation",
2663
+ "fo",
2664
+ "svg",
2665
+ "xlink"
2666
+ ];
2667
+ const STYLES_NS_PREFIXES = [
2668
+ "office",
2669
+ "style",
2670
+ "text",
2671
+ "table",
2672
+ "draw",
2673
+ "presentation",
2674
+ "fo",
2675
+ "svg",
2676
+ "xlink"
2677
+ ];
2678
+ const META_NS_PREFIXES = [
2679
+ "office",
2680
+ "meta",
2681
+ "dc"
2682
+ ];
2683
+ const ODF_VERSION = "1.3";
2684
+ const MASTER_PAGE_NAME = "Standard";
2685
+ function declaration() {
2686
+ return {
2687
+ type: "declaration",
2688
+ attributes: [
2689
+ {
2690
+ name: "version",
2691
+ value: "1.0"
2692
+ },
2693
+ {
2694
+ name: "encoding",
2695
+ value: "UTF-8"
2696
+ },
2697
+ {
2698
+ name: "standalone",
2699
+ value: "yes"
2700
+ }
2701
+ ]
2702
+ };
2703
+ }
2704
+ function buildPageLayout() {
2705
+ return el("style:page-layout", { "style:name": "PM1" }, [el("style:page-layout-properties", {
2706
+ "fo:page-width": `${document_content_model.SLIDE_SIZE_WIDESCREEN.widthPt}pt`,
2707
+ "fo:page-height": `${document_content_model.SLIDE_SIZE_WIDESCREEN.heightPt}pt`
2708
+ })]);
2709
+ }
2710
+ function buildStylesXml() {
2711
+ return el("office:document-styles", {
2712
+ ...(0, odf_js.xmlnsAttributes)([...STYLES_NS_PREFIXES]),
2713
+ "office:version": ODF_VERSION
2714
+ }, [
2715
+ el("office:styles"),
2716
+ el("office:automatic-styles", {}, [buildPageLayout()]),
2717
+ el("office:master-styles", {}, [el("style:master-page", {
2718
+ "style:name": MASTER_PAGE_NAME,
2719
+ "style:page-layout-name": "PM1"
2720
+ })])
2721
+ ]);
2722
+ }
2723
+ function buildContentXml() {
2724
+ return el("office:document-content", {
2725
+ ...(0, odf_js.xmlnsAttributes)([...CONTENT_NS_PREFIXES]),
2726
+ "office:version": ODF_VERSION
2727
+ }, [el("office:automatic-styles"), el("office:body", {}, [el("office:presentation")])]);
2728
+ }
2729
+ function buildMetaXml() {
2730
+ return el("office:document-meta", {
2731
+ ...(0, odf_js.xmlnsAttributes)([...META_NS_PREFIXES]),
2732
+ "office:version": ODF_VERSION
2733
+ }, [el("office:meta")]);
2734
+ }
2735
+ function createEmptyOdpPackage() {
2736
+ const pkg = { parts: {
2737
+ "content.xml": {
2738
+ kind: "xml",
2739
+ nodes: [declaration(), buildContentXml()]
2740
+ },
2741
+ "styles.xml": {
2742
+ kind: "xml",
2743
+ nodes: [declaration(), buildStylesXml()]
2744
+ },
2745
+ "meta.xml": {
2746
+ kind: "xml",
2747
+ nodes: [declaration(), buildMetaXml()]
2748
+ }
2749
+ } };
2750
+ (0, odf_js.setDocumentMediaType)(pkg, odf_js.ODF_MEDIA_TYPES.odp);
2751
+ (0, odf_js.syncManifest)(pkg);
2752
+ return pkg;
2753
+ }
2754
+ //#endregion
2755
+ //#region src/odf-package/media.ts
2756
+ const PICTURES_DIR = "Pictures";
2757
+ function escapeRegExp(value) {
2758
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2759
+ }
2760
+ function nextPictureIndex(pkg, extension) {
2761
+ const pattern = new RegExp(`^image(\\d+)\\.${escapeRegExp(extension)}$`);
2762
+ const prefix = `${PICTURES_DIR}/`;
2763
+ let max = 0;
2764
+ for (const path of Object.keys(pkg.parts)) {
2765
+ if (!path.startsWith(prefix)) continue;
2766
+ const match = pattern.exec(path.slice(prefix.length));
2767
+ if (match === null) continue;
2768
+ const digits = match[1];
2769
+ if (digits === void 0) continue;
2770
+ const n = Number.parseInt(digits, 10);
2771
+ if (n > max) max = n;
2772
+ }
2773
+ return max + 1;
2774
+ }
2775
+ function addImageMedia(pkg, imageBytes, format) {
2776
+ const index = nextPictureIndex(pkg, format);
2777
+ const partPath = `${PICTURES_DIR}/image${index}.${format}`;
2778
+ pkg.parts[partPath] = {
2779
+ kind: "binary",
2780
+ base64: (0, odf_js.bytesToBase64)(imageBytes)
2781
+ };
2782
+ (0, odf_js.syncManifest)(pkg);
2783
+ return { partPath };
2784
+ }
2785
+ //#endregion
2786
+ //#region src/edit/odp/shape.ts
2787
+ function directChild$2(parent, tag) {
2788
+ for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
2789
+ }
2790
+ function buildTransformAttr(frame, rotationDeg) {
2791
+ const angleRad = -rotationDeg * Math.PI / 180;
2792
+ const localCenter = {
2793
+ xPt: frame.widthPt / 2,
2794
+ yPt: frame.heightPt / 2
2795
+ };
2796
+ const rotatedCenter = (0, odf_js.applyOdfTransform)([{
2797
+ kind: "rotate",
2798
+ angleRad
2799
+ }], localCenter);
2800
+ const desiredCenter = {
2801
+ xPt: frame.xPt + frame.widthPt / 2,
2802
+ yPt: frame.yPt + frame.heightPt / 2
2803
+ };
2804
+ const txPt = desiredCenter.xPt - rotatedCenter.xPt;
2805
+ const tyPt = desiredCenter.yPt - rotatedCenter.yPt;
2806
+ return `rotate(${angleRad}) translate(${(0, odf_js.formatOdfLength)(txPt)} ${(0, odf_js.formatOdfLength)(tyPt)})`;
2807
+ }
2808
+ var OdpShape = class {
2809
+ container;
2810
+ node;
2811
+ pkg;
2812
+ removed = false;
2813
+ constructor(container, node, pkg) {
2814
+ this.container = container;
2815
+ this.node = node;
2816
+ this.pkg = pkg;
2817
+ }
2818
+ live() {
2819
+ if (this.removed) throw new Error("this OdpShape has been removed from its slide and can no longer be used");
2820
+ return this.node;
2821
+ }
2822
+ get name() {
2823
+ return (0, ooxml_js.attr)(this.live(), "draw:name");
2824
+ }
2825
+ get frame() {
2826
+ return (0, odf_js.resolveOdfShapeGeometry)(this.live())?.frame;
2827
+ }
2828
+ set frame(value) {
2829
+ this.applyGeometry(value, this.rotationDeg);
2830
+ }
2831
+ get rotationDeg() {
2832
+ return (0, odf_js.resolveOdfShapeGeometry)(this.live())?.rotationDeg;
2833
+ }
2834
+ set rotationDeg(value) {
2835
+ const currentFrame = this.frame;
2836
+ if (currentFrame === void 0) throw new Error("cannot set rotationDeg on a shape with no resolvable frame (missing svg:width/svg:height)");
2837
+ this.applyGeometry(currentFrame, value);
2838
+ }
2839
+ applyGeometry(frame, rotationDeg) {
2840
+ const node = this.live();
2841
+ setAttr(node, "svg:width", (0, odf_js.formatOdfLength)(frame.widthPt));
2842
+ setAttr(node, "svg:height", (0, odf_js.formatOdfLength)(frame.heightPt));
2843
+ if (rotationDeg === void 0 || rotationDeg === 0) {
2844
+ removeAttr(node, "draw:transform");
2845
+ setAttr(node, "svg:x", (0, odf_js.formatOdfLength)(frame.xPt));
2846
+ setAttr(node, "svg:y", (0, odf_js.formatOdfLength)(frame.yPt));
2847
+ } else {
2848
+ removeAttr(node, "svg:x");
2849
+ removeAttr(node, "svg:y");
2850
+ setAttr(node, "draw:transform", buildTransformAttr(frame, rotationDeg));
2851
+ }
2852
+ }
2853
+ textBox(create) {
2854
+ const node = this.live();
2855
+ const existing = directChild$2(node, "draw:text-box");
2856
+ if (existing !== void 0 || !create) return existing;
2857
+ const created = el("draw:text-box");
2858
+ node.children.push(created);
2859
+ return created;
2860
+ }
2861
+ paragraphs() {
2862
+ const textBox = this.textBox(false);
2863
+ if (textBox === void 0) return [];
2864
+ const out = [];
2865
+ for (const child of textBox.children) if (child.type === "element" && child.tag === "text:p") out.push(new OdtParagraph(textBox.children, child, this.pkg));
2866
+ return out;
2867
+ }
2868
+ appendParagraph(init) {
2869
+ const textBox = this.textBox(true);
2870
+ const paragraphElement = buildParagraph(this.pkg, init);
2871
+ textBox.children.push(paragraphElement);
2872
+ return new OdtParagraph(textBox.children, paragraphElement, this.pkg);
2873
+ }
2874
+ get text() {
2875
+ return this.paragraphs().map((p) => p.text).join("\n");
2876
+ }
2877
+ set text(value) {
2878
+ const textBox = this.textBox(true);
2879
+ textBox.children = [buildParagraph(this.pkg, { text: value })];
2880
+ }
2881
+ addList() {
2882
+ const textBox = this.textBox(true);
2883
+ const listElement = buildList(this.pkg);
2884
+ textBox.children.push(listElement);
2885
+ return new OdtList(textBox.children, listElement, this.pkg);
2886
+ }
2887
+ remove() {
2888
+ removeChild(this.container, this.live());
2889
+ this.removed = true;
2890
+ }
2891
+ };
2892
+ function buildTextBoxFrame(pkg, frame, text) {
2893
+ return el("draw:frame", {
2894
+ "svg:x": (0, odf_js.formatOdfLength)(frame.xPt),
2895
+ "svg:y": (0, odf_js.formatOdfLength)(frame.yPt),
2896
+ "svg:width": (0, odf_js.formatOdfLength)(frame.widthPt),
2897
+ "svg:height": (0, odf_js.formatOdfLength)(frame.heightPt)
2898
+ }, [el("draw:text-box", {}, [buildParagraph(pkg, { text })])]);
2899
+ }
2900
+ function buildImageFrame(partPath, frame) {
2901
+ return el("draw:frame", {
2902
+ "svg:x": (0, odf_js.formatOdfLength)(frame.xPt),
2903
+ "svg:y": (0, odf_js.formatOdfLength)(frame.yPt),
2904
+ "svg:width": (0, odf_js.formatOdfLength)(frame.widthPt),
2905
+ "svg:height": (0, odf_js.formatOdfLength)(frame.heightPt)
2906
+ }, [el("draw:image", { "xlink:href": partPath })]);
2907
+ }
2908
+ //#endregion
2909
+ //#region src/edit/odp/image.ts
2910
+ function insertImageFrameMedia(context, frame, image) {
2911
+ const { partPath } = addImageMedia(context.pkg, image.bytes, image.format);
2912
+ return buildImageFrame(partPath, frame);
2913
+ }
2914
+ //#endregion
2915
+ //#region src/edit/odp/slide.ts
2916
+ function directChild$1(parent, tag) {
2917
+ for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
2918
+ }
2919
+ const NOTES_FRAME_X_PT = 20;
2920
+ const NOTES_FRAME_Y_PT = 400;
2921
+ const NOTES_FRAME_WIDTH_PT = 300;
2922
+ const NOTES_FRAME_HEIGHT_PT = 100;
2923
+ function buildNotesElement(pkg, value) {
2924
+ const textBox = el("draw:text-box", {}, value.split("\n").map((line) => buildParagraph(pkg, { text: line })));
2925
+ return el("presentation:notes", {}, [el("draw:frame", {
2926
+ "svg:x": (0, odf_js.formatOdfLength)(NOTES_FRAME_X_PT),
2927
+ "svg:y": (0, odf_js.formatOdfLength)(NOTES_FRAME_Y_PT),
2928
+ "svg:width": (0, odf_js.formatOdfLength)(NOTES_FRAME_WIDTH_PT),
2929
+ "svg:height": (0, odf_js.formatOdfLength)(NOTES_FRAME_HEIGHT_PT)
2930
+ }, [textBox])]);
2931
+ }
2932
+ var OdpSlide = class {
2933
+ container;
2934
+ node;
2935
+ context;
2936
+ removed = false;
2937
+ constructor(container, node, context) {
2938
+ this.container = container;
2939
+ this.node = node;
2940
+ this.context = context;
2941
+ }
2942
+ live() {
2943
+ if (this.removed) throw new Error("this OdpSlide has been removed from the presentation and can no longer be used");
2944
+ return this.node;
2945
+ }
2946
+ shapes() {
2947
+ const node = this.live();
2948
+ const out = [];
2949
+ for (const child of node.children) if (child.type === "element" && child.tag === "draw:frame") out.push(new OdpShape(node.children, child, this.context.pkg));
2950
+ return out;
2951
+ }
2952
+ addTextBox(init) {
2953
+ const node = this.live();
2954
+ const frameElement = buildTextBoxFrame(this.context.pkg, init.frame, init.text);
2955
+ node.children.push(frameElement);
2956
+ return new OdpShape(node.children, frameElement, this.context.pkg);
2957
+ }
2958
+ addImage(init) {
2959
+ const node = this.live();
2960
+ const frameElement = insertImageFrameMedia({ pkg: this.context.pkg }, init.frame, init);
2961
+ node.children.push(frameElement);
2962
+ return new OdpShape(node.children, frameElement, this.context.pkg);
2963
+ }
2964
+ get notes() {
2965
+ const notesElement = directChild$1(this.live(), "presentation:notes");
2966
+ if (notesElement === void 0) return "";
2967
+ return (0, ooxml_js.elementsWithTag)(notesElement.children, "text:p").map((p) => decodeOdfText(p.children)).join("\n");
2968
+ }
2969
+ set notes(value) {
2970
+ const node = this.live();
2971
+ const existing = directChild$1(node, "presentation:notes");
2972
+ const notesElement = buildNotesElement(this.context.pkg, value);
2973
+ if (existing === void 0) node.children.push(notesElement);
2974
+ else existing.children = notesElement.children;
2975
+ }
2976
+ remove() {
2977
+ removeChild(this.container, this.live());
2978
+ this.removed = true;
2979
+ }
2980
+ };
2981
+ //#endregion
2982
+ //#region src/edit/odp/editor.ts
2983
+ const CONTENT_PART_PATH = "content.xml";
2984
+ const STYLES_PART_PATH = "styles.xml";
2985
+ function directChild(parent, tag) {
2986
+ for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
2987
+ }
2988
+ function findRoot(pkg, partPath) {
2989
+ const part = pkg.parts[partPath];
2990
+ const root = part?.kind === "xml" ? part.nodes.find((n) => n.type === "element") : void 0;
2991
+ if (root === void 0) throw new Error(`package has no root element at ${partPath}`);
2992
+ return root;
2993
+ }
2994
+ function findOfficePresentation(pkg) {
2995
+ const body = directChild(findRoot(pkg, CONTENT_PART_PATH), "office:body");
2996
+ const presentation = body === void 0 ? void 0 : directChild(body, "office:presentation");
2997
+ if (presentation === void 0) throw new Error(`${CONTENT_PART_PATH} has no office:body/office:presentation element`);
2998
+ return presentation;
2999
+ }
3000
+ function findPageLayoutProperties(pkg) {
3001
+ const pageLayout = directChild(findRoot(pkg, STYLES_PART_PATH), "office:automatic-styles")?.children.find((c) => c.type === "element" && c.tag === "style:page-layout" && (0, ooxml_js.attr)(c, "style:name") === "PM1");
3002
+ const properties = pageLayout === void 0 ? void 0 : directChild(pageLayout, "style:page-layout-properties");
3003
+ if (properties === void 0) throw new Error(`${STYLES_PART_PATH} has no style:page-layout[style:name="PM1"]/style:page-layout-properties element`);
3004
+ return properties;
3005
+ }
3006
+ var OdpEditor = class {
3007
+ pkg;
3008
+ constructor(pkg) {
3009
+ this.pkg = pkg;
3010
+ }
3011
+ slides() {
3012
+ const presentation = findOfficePresentation(this.pkg);
3013
+ const out = [];
3014
+ for (const child of presentation.children) if (child.type === "element" && child.tag === "draw:page") {
3015
+ const context = { pkg: this.pkg };
3016
+ out.push(new OdpSlide(presentation.children, child, context));
3017
+ }
3018
+ return out;
3019
+ }
3020
+ addSlide() {
3021
+ const presentation = findOfficePresentation(this.pkg);
3022
+ const pageElement = el("draw:page", { "draw:master-page-name": MASTER_PAGE_NAME });
3023
+ presentation.children.push(pageElement);
3024
+ const context = { pkg: this.pkg };
3025
+ return new OdpSlide(presentation.children, pageElement, context);
3026
+ }
3027
+ removeSlideAt(index) {
3028
+ const presentation = findOfficePresentation(this.pkg);
3029
+ const target = presentation.children.filter((c) => c.type === "element" && c.tag === "draw:page")[index];
3030
+ if (target === void 0) throw new Error(`slide index ${index} does not exist`);
3031
+ const listIndex = presentation.children.indexOf(target);
3032
+ presentation.children.splice(listIndex, 1);
3033
+ }
3034
+ moveSlide(from, to) {
3035
+ const presentation = findOfficePresentation(this.pkg);
3036
+ const pageIndices = [];
3037
+ presentation.children.forEach((child, i) => {
3038
+ if (child.type === "element" && child.tag === "draw:page") pageIndices.push(i);
3039
+ });
3040
+ const fromChildIndex = pageIndices[from];
3041
+ if (fromChildIndex === void 0) throw new Error(`slide index ${from} does not exist`);
3042
+ const [moved] = presentation.children.splice(fromChildIndex, 1);
3043
+ if (moved === void 0) throw new Error(`slide index ${from} does not exist`);
3044
+ const updatedIndices = [];
3045
+ presentation.children.forEach((child, i) => {
3046
+ if (child.type === "element" && child.tag === "draw:page") updatedIndices.push(i);
3047
+ });
3048
+ const insertAt = to < updatedIndices.length ? updatedIndices[to] ?? presentation.children.length : presentation.children.length;
3049
+ presentation.children.splice(insertAt, 0, moved);
3050
+ }
3051
+ get slideSize() {
3052
+ const properties = findPageLayoutProperties(this.pkg);
3053
+ const widthValue = (0, ooxml_js.attr)(properties, "fo:page-width");
3054
+ const heightValue = (0, ooxml_js.attr)(properties, "fo:page-height");
3055
+ const widthPt = widthValue === void 0 ? void 0 : (0, odf_js.parseOdfLength)(widthValue);
3056
+ const heightPt = heightValue === void 0 ? void 0 : (0, odf_js.parseOdfLength)(heightValue);
3057
+ return {
3058
+ widthPt: widthPt ?? 0,
3059
+ heightPt: heightPt ?? 0
3060
+ };
3061
+ }
3062
+ set slideSize(size) {
3063
+ const properties = findPageLayoutProperties(this.pkg);
3064
+ properties.attributes = [{
3065
+ name: "fo:page-width",
3066
+ value: (0, odf_js.formatOdfLength)(size.widthPt)
3067
+ }, {
3068
+ name: "fo:page-height",
3069
+ value: (0, odf_js.formatOdfLength)(size.heightPt)
3070
+ }];
3071
+ }
3072
+ toPackage() {
3073
+ return this.pkg;
3074
+ }
3075
+ toBytes() {
3076
+ return (0, odf_js.encodePackage)(this.pkg);
3077
+ }
3078
+ };
3079
+ function openOdp(bytes) {
3080
+ return new OdpEditor((0, odf_js.decodePackage)(bytes));
3081
+ }
3082
+ function createOdp() {
3083
+ return new OdpEditor(createEmptyOdpPackage());
3084
+ }
3085
+ //#endregion
3086
+ //#region src/edit/odp/content.ts
3087
+ function buildOdpPackage(content) {
3088
+ if (content.kind !== "presentation") throw new Error("buildOdpPackage requires a presentation ContentDocument");
3089
+ const editor = createOdp();
3090
+ const firstSlide = content.slides[0];
3091
+ if (firstSlide !== void 0) editor.slideSize = firstSlide.size;
3092
+ for (const slide of content.slides) {
3093
+ const odpSlide = editor.addSlide();
3094
+ for (const shape of slide.shapes) appendShape(odpSlide, shape);
3095
+ if (slide.notes.length > 0) odpSlide.notes = slide.notes;
3096
+ }
3097
+ return editor.toPackage();
3098
+ }
3099
+ function appendShape(slide, shape) {
3100
+ const [onlyBlock] = shape.blocks;
3101
+ if (shape.blocks.length === 1 && onlyBlock?.kind === "image") {
3102
+ const imageShape = slide.addImage({
3103
+ frame: shape.frame,
3104
+ format: onlyBlock.format,
3105
+ bytes: (0, odf_js.base64ToBytes)(onlyBlock.base64),
3106
+ altText: onlyBlock.altText
3107
+ });
3108
+ if (shape.rotationDeg !== void 0) imageShape.rotationDeg = shape.rotationDeg;
3109
+ return;
3110
+ }
3111
+ const textShape = slide.addTextBox({
3112
+ frame: shape.frame,
3113
+ text: ""
3114
+ });
3115
+ if (shape.rotationDeg !== void 0) textShape.rotationDeg = shape.rotationDeg;
3116
+ textShape.paragraphs()[0]?.remove();
3117
+ for (const block of shape.blocks) {
3118
+ if (block.kind !== "paragraph") continue;
3119
+ populateParagraph(textShape.appendParagraph(), block);
3120
+ }
3121
+ }
3122
+ //#endregion
2646
3123
  //#region src/bytes/crc32.ts
2647
3124
  const CRC32_POLYNOMIAL = 3988292384;
2648
3125
  const BYTE_VALUES = 256;
@@ -7448,6 +7925,17 @@ function readOdpContent(pkg) {
7448
7925
  };
7449
7926
  }
7450
7927
  //#endregion
7928
+ //#region src/odf/ods/read.ts
7929
+ function readOdsContent(pkg) {
7930
+ const odsDoc = (0, odf_js.readOds)(pkg);
7931
+ return {
7932
+ kind: "spreadsheet",
7933
+ formatVersion: 1,
7934
+ metadata: { ...odsDoc.metadata },
7935
+ sheets: odsDoc.sheets
7936
+ };
7937
+ }
7938
+ //#endregion
7451
7939
  //#region src/pdf/text-layout.ts
7452
7940
  const WORD_OR_WHITESPACE_PATTERN = /\n|\s+|\S+/g;
7453
7941
  function atomizeRuns(runs, measurer) {
@@ -8075,6 +8563,410 @@ function convertPresentationToLayout(doc, options) {
8075
8563
  };
8076
8564
  }
8077
8565
  //#endregion
8566
+ //#region src/layout/sheets.ts
8567
+ const DEFAULT_COLUMN_WIDTH_PT = 64;
8568
+ const DEFAULT_ROW_HEIGHT_PT = 15;
8569
+ const NOMINAL_CELL_TEXT_SIZE_PT = 10;
8570
+ const HEADER_LABEL_SIZE_PT = 8;
8571
+ const CELL_TEXT_PADDING_PT = 2;
8572
+ const HEADER_LABEL_PADDING_PT = 2;
8573
+ const MINIMUM_SCALE = .01;
8574
+ const NUMERIC_OVERFLOW_TEXT = "###";
8575
+ const GRIDLINE_COLOR = (0, document_content_model.rgbHexToColor)("#D0D0D0");
8576
+ const GRIDLINE_WIDTH_PT = .5;
8577
+ const HEADER_LABEL_COLOR = (0, document_content_model.rgbHexToColor)("#606060");
8578
+ function columnLetters(index) {
8579
+ let n = index + 1;
8580
+ let letters = "";
8581
+ while (n > 0) {
8582
+ const remainder = (n - 1) % 26;
8583
+ letters = String.fromCharCode(65 + remainder) + letters;
8584
+ n = Math.floor((n - 1) / 26);
8585
+ }
8586
+ return letters;
8587
+ }
8588
+ function resolvePrintRange(sheet) {
8589
+ if (sheet.printSettings.printRange !== void 0) return sheet.printSettings.printRange;
8590
+ if (sheet.cells.length === 0) return;
8591
+ let startRow = Number.POSITIVE_INFINITY;
8592
+ let startColumn = Number.POSITIVE_INFINITY;
8593
+ let endRow = Number.NEGATIVE_INFINITY;
8594
+ let endColumn = Number.NEGATIVE_INFINITY;
8595
+ for (const cell of sheet.cells) {
8596
+ startRow = Math.min(startRow, cell.row);
8597
+ startColumn = Math.min(startColumn, cell.column);
8598
+ endRow = Math.max(endRow, cell.row + (cell.rowSpan ?? 1) - 1);
8599
+ endColumn = Math.max(endColumn, cell.column + (cell.colSpan ?? 1) - 1);
8600
+ }
8601
+ return {
8602
+ startRow,
8603
+ startColumn,
8604
+ endRow,
8605
+ endColumn
8606
+ };
8607
+ }
8608
+ function resolveAxis(entries, start, end, defaultSizePt) {
8609
+ const sorted = [...entries].sort((a, b) => a.index - b.index);
8610
+ const resolved = [];
8611
+ let pointer = 0;
8612
+ let currentSizePt = defaultSizePt;
8613
+ let currentHidden = false;
8614
+ for (let index = start; index <= end; index++) {
8615
+ while (pointer < sorted.length && sorted[pointer].index <= index) {
8616
+ currentSizePt = sorted[pointer].sizePt;
8617
+ currentHidden = sorted[pointer].hidden ?? false;
8618
+ pointer++;
8619
+ }
8620
+ resolved.push({
8621
+ index,
8622
+ sizePt: currentHidden ? 0 : currentSizePt,
8623
+ hidden: currentHidden
8624
+ });
8625
+ }
8626
+ return resolved;
8627
+ }
8628
+ function computeHeaderGutter(printSettings, range, measurer) {
8629
+ if (!printSettings.headers) return {
8630
+ widthPt: 0,
8631
+ heightPt: 0
8632
+ };
8633
+ const widestRowLabel = String(range.endRow + 1);
8634
+ return {
8635
+ widthPt: measurer.widthOfTextAtSize(widestRowLabel, document_content_model.DEFAULT_LAYOUT_FONT, HEADER_LABEL_SIZE_PT) + 4,
8636
+ heightPt: measurer.lineHeightAtSize(document_content_model.DEFAULT_LAYOUT_FONT, HEADER_LABEL_SIZE_PT)
8637
+ };
8638
+ }
8639
+ function resolveScale(printSettings, availableWidthPt, availableHeightPt, totalContentWidthPt, totalContentHeightPt) {
8640
+ if (printSettings.scale !== void 0) return Math.max(printSettings.scale / 100, MINIMUM_SCALE);
8641
+ if (printSettings.fitToPages !== void 0) {
8642
+ const budgetWidthPt = availableWidthPt * printSettings.fitToPages.width;
8643
+ const budgetHeightPt = availableHeightPt * printSettings.fitToPages.height;
8644
+ const widthRatio = totalContentWidthPt > 0 ? budgetWidthPt / totalContentWidthPt : 1;
8645
+ const heightRatio = totalContentHeightPt > 0 ? budgetHeightPt / totalContentHeightPt : 1;
8646
+ return Math.max(Math.min(widthRatio, heightRatio, 1), MINIMUM_SCALE);
8647
+ }
8648
+ return 1;
8649
+ }
8650
+ function partitionIndices(indices, sizeOf, availablePt, manualBreaks) {
8651
+ const bands = [];
8652
+ let current = [];
8653
+ let currentSizePt = 0;
8654
+ for (const index of indices) {
8655
+ if (manualBreaks.has(index) && current.length > 0) {
8656
+ bands.push(current);
8657
+ current = [];
8658
+ currentSizePt = 0;
8659
+ }
8660
+ const sizePt = sizeOf(index);
8661
+ if (current.length > 0 && currentSizePt + sizePt > availablePt) {
8662
+ bands.push(current);
8663
+ current = [];
8664
+ currentSizePt = 0;
8665
+ }
8666
+ current.push(index);
8667
+ currentSizePt += sizePt;
8668
+ }
8669
+ if (current.length > 0) bands.push(current);
8670
+ return bands;
8671
+ }
8672
+ function cellStyledRuns(cell) {
8673
+ if (cell.runs !== void 0 && cell.runs.length > 0) return toStyledRuns(cell.runs.map((run) => run.sizePt === void 0 ? {
8674
+ ...run,
8675
+ sizePt: NOMINAL_CELL_TEXT_SIZE_PT
8676
+ } : run));
8677
+ return [{
8678
+ text: cell.displayText,
8679
+ font: document_content_model.DEFAULT_LAYOUT_FONT,
8680
+ sizePt: NOMINAL_CELL_TEXT_SIZE_PT,
8681
+ color: document_content_model.COLOR_BLACK
8682
+ }];
8683
+ }
8684
+ function isNumericLikeValue(kind) {
8685
+ return kind === "number" || kind === "percentage" || kind === "currency" || kind === "date" || kind === "time";
8686
+ }
8687
+ function defaultAlignmentForValue(kind) {
8688
+ if (isNumericLikeValue(kind)) return "right";
8689
+ if (kind === "boolean" || kind === "error") return "center";
8690
+ return "left";
8691
+ }
8692
+ function isCellVisuallyEmpty(cell) {
8693
+ return cell === void 0 || cell.value.kind === "empty" && cell.displayText.length === 0;
8694
+ }
8695
+ function truncateFragmentsToWidth(fragments, measurer, maxWidthPt) {
8696
+ const result = [];
8697
+ for (const fragment of fragments) {
8698
+ if (fragment.xOffsetPt >= maxWidthPt) break;
8699
+ const remainingWidthPt = maxWidthPt - fragment.xOffsetPt;
8700
+ if (measurer.widthOfTextAtSize(fragment.text, fragment.font, fragment.sizePt) <= remainingWidthPt) {
8701
+ result.push(fragment);
8702
+ continue;
8703
+ }
8704
+ const chars = Array.from(fragment.text);
8705
+ let width = 0;
8706
+ let fitCount = 0;
8707
+ for (const char of chars) {
8708
+ const charWidthPt = measurer.widthOfTextAtSize(char, fragment.font, fragment.sizePt);
8709
+ if (width + charWidthPt > remainingWidthPt) break;
8710
+ width += charWidthPt;
8711
+ fitCount++;
8712
+ }
8713
+ if (fitCount > 0) result.push({
8714
+ ...fragment,
8715
+ text: chars.slice(0, fitCount).join("")
8716
+ });
8717
+ break;
8718
+ }
8719
+ return result;
8720
+ }
8721
+ function buildPositionedAxis(repeatIndices, repeatSizePtOf, bandIndices, bandSizePtOf) {
8722
+ const indices = [...repeatIndices, ...bandIndices];
8723
+ const sizesPt = [...repeatIndices.map(repeatSizePtOf), ...bandIndices.map(bandSizePtOf)];
8724
+ const offsetsPt = [0];
8725
+ let running = 0;
8726
+ for (const size of sizesPt) {
8727
+ running += size;
8728
+ offsetsPt.push(running);
8729
+ }
8730
+ return {
8731
+ indices,
8732
+ sizesPt,
8733
+ offsetsPt,
8734
+ positionByIndex: new Map(indices.map((index, position) => [index, position]))
8735
+ };
8736
+ }
8737
+ function axisSpanSizePt(axis, startIndex, span) {
8738
+ const startPosition = axis.positionByIndex.get(startIndex);
8739
+ if (startPosition === void 0) return 0;
8740
+ return sumColumnWidthsPt(axis.sizesPt, startPosition, span);
8741
+ }
8742
+ function renderCellText(cell, rowCells, columnAxis, rowAxis, gridLeftXPt, gridTopYDownPt, pageHeightPt, measurer, out) {
8743
+ const columnPosition = columnAxis.positionByIndex.get(cell.column);
8744
+ const rowPosition = rowAxis.positionByIndex.get(cell.row);
8745
+ if (columnPosition === void 0 || rowPosition === void 0) return;
8746
+ const ownWidthPt = axisSpanSizePt(columnAxis, cell.column, cell.colSpan ?? 1);
8747
+ const heightPt = axisSpanSizePt(rowAxis, cell.row, cell.rowSpan ?? 1);
8748
+ const xLeftPt = gridLeftXPt + columnAxis.offsetsPt[columnPosition];
8749
+ const yTopDownPt = gridTopYDownPt + rowAxis.offsetsPt[rowPosition];
8750
+ const alignment = defaultAlignmentForValue(cell.value.kind);
8751
+ const numericLike = isNumericLikeValue(cell.value.kind);
8752
+ const styledRuns = cellStyledRuns(cell);
8753
+ const naturalLine = wrapRunsToWidth(styledRuns, measurer, Number.POSITIVE_INFINITY)[0];
8754
+ let availableWidthPt = Math.max(0, ownWidthPt - 4);
8755
+ let fragments = naturalLine.fragments;
8756
+ let lineWidthPt = naturalLine.widthPt;
8757
+ if (lineWidthPt > availableWidthPt) if (numericLike) {
8758
+ const overflowLine = wrapRunsToWidth([{
8759
+ text: NUMERIC_OVERFLOW_TEXT,
8760
+ font: styledRuns[0].font,
8761
+ sizePt: styledRuns[0].sizePt,
8762
+ color: styledRuns[0].color
8763
+ }], measurer, Number.POSITIVE_INFINITY)[0];
8764
+ fragments = overflowLine.fragments;
8765
+ lineWidthPt = overflowLine.widthPt;
8766
+ } else if (cell.value.kind === "string") {
8767
+ let spillColumn = cell.column + (cell.colSpan ?? 1);
8768
+ while (lineWidthPt > availableWidthPt) {
8769
+ const neighborPosition = columnAxis.positionByIndex.get(spillColumn);
8770
+ if (neighborPosition === void 0 || !isCellVisuallyEmpty(rowCells?.get(spillColumn))) break;
8771
+ availableWidthPt += columnAxis.sizesPt[neighborPosition];
8772
+ spillColumn++;
8773
+ }
8774
+ if (lineWidthPt > availableWidthPt) fragments = truncateFragmentsToWidth(fragments, measurer, availableWidthPt);
8775
+ } else fragments = truncateFragmentsToWidth(fragments, measurer, availableWidthPt);
8776
+ const alignOffsetPt = alignmentOffsetPt(alignment, availableWidthPt, lineWidthPt);
8777
+ const textStartXPt = xLeftPt + CELL_TEXT_PADDING_PT + alignOffsetPt;
8778
+ const lineHeightPt = lineNaturalHeightPt(naturalLine, measurer, styledRuns[0]);
8779
+ const baselineYDownPt = yTopDownPt + Math.max(CELL_TEXT_PADDING_PT, heightPt - CELL_TEXT_PADDING_PT - lineHeightPt) + naturalLine.ascentPt;
8780
+ for (const fragment of fragments) {
8781
+ const textItem = {
8782
+ kind: "text",
8783
+ text: fragment.text,
8784
+ xPt: textStartXPt + fragment.xOffsetPt,
8785
+ yPt: pageHeightPt - baselineYDownPt,
8786
+ font: fragment.font,
8787
+ sizePt: fragment.sizePt,
8788
+ color: fragment.color,
8789
+ underline: fragment.underline,
8790
+ sourcePath: fragment.sourcePath
8791
+ };
8792
+ out.push(textItem);
8793
+ }
8794
+ }
8795
+ function renderHeaderLabels(gutter, columnAxis, rowAxis, gridLeftXPt, gridTopYDownPt, pageHeightPt, measurer, out) {
8796
+ const labelFont = document_content_model.DEFAULT_LAYOUT_FONT;
8797
+ const lineHeightPt = measurer.lineHeightAtSize(labelFont, HEADER_LABEL_SIZE_PT);
8798
+ const ascentPt = measurer.ascenderAtSize(labelFont, HEADER_LABEL_SIZE_PT);
8799
+ columnAxis.indices.forEach((columnIndex, position) => {
8800
+ const label = columnLetters(columnIndex);
8801
+ const widthPt = columnAxis.sizesPt[position];
8802
+ const labelWidthPt = measurer.widthOfTextAtSize(label, labelFont, HEADER_LABEL_SIZE_PT);
8803
+ const xPt = gridLeftXPt + columnAxis.offsetsPt[position] + alignmentOffsetPt("center", widthPt, labelWidthPt);
8804
+ const baselineYDownPt = gridTopYDownPt - gutter.heightPt + (gutter.heightPt - lineHeightPt) / 2 + ascentPt;
8805
+ out.push({
8806
+ kind: "text",
8807
+ text: label,
8808
+ xPt,
8809
+ yPt: pageHeightPt - baselineYDownPt,
8810
+ font: labelFont,
8811
+ sizePt: HEADER_LABEL_SIZE_PT,
8812
+ color: HEADER_LABEL_COLOR
8813
+ });
8814
+ });
8815
+ rowAxis.indices.forEach((rowIndex, position) => {
8816
+ const label = String(rowIndex + 1);
8817
+ const heightPt = rowAxis.sizesPt[position];
8818
+ const labelWidthPt = measurer.widthOfTextAtSize(label, labelFont, HEADER_LABEL_SIZE_PT);
8819
+ const xPt = gridLeftXPt - gutter.widthPt + Math.max(HEADER_LABEL_PADDING_PT, gutter.widthPt - HEADER_LABEL_PADDING_PT - labelWidthPt);
8820
+ const baselineYDownPt = gridTopYDownPt + rowAxis.offsetsPt[position] + Math.max(0, (heightPt - lineHeightPt) / 2) + ascentPt;
8821
+ out.push({
8822
+ kind: "text",
8823
+ text: label,
8824
+ xPt,
8825
+ yPt: pageHeightPt - baselineYDownPt,
8826
+ font: labelFont,
8827
+ sizePt: HEADER_LABEL_SIZE_PT,
8828
+ color: HEADER_LABEL_COLOR
8829
+ });
8830
+ });
8831
+ }
8832
+ function renderGridlines(gridLeftXPt, gridTopYDownPt, gridWidthPt, gridHeightPt, columnOffsetsPt, rowOffsetsPt, pageHeightPt, out) {
8833
+ for (const offsetPt of columnOffsetsPt) {
8834
+ const xPt = gridLeftXPt + offsetPt;
8835
+ const line = {
8836
+ kind: "line",
8837
+ x1Pt: xPt,
8838
+ y1Pt: pageHeightPt - gridTopYDownPt,
8839
+ x2Pt: xPt,
8840
+ y2Pt: pageHeightPt - (gridTopYDownPt + gridHeightPt),
8841
+ color: GRIDLINE_COLOR,
8842
+ widthPt: GRIDLINE_WIDTH_PT
8843
+ };
8844
+ out.push(line);
8845
+ }
8846
+ for (const offsetPt of rowOffsetsPt) {
8847
+ const yDownPt = gridTopYDownPt + offsetPt;
8848
+ const line = {
8849
+ kind: "line",
8850
+ x1Pt: gridLeftXPt,
8851
+ y1Pt: pageHeightPt - yDownPt,
8852
+ x2Pt: gridLeftXPt + gridWidthPt,
8853
+ y2Pt: pageHeightPt - yDownPt,
8854
+ color: GRIDLINE_COLOR,
8855
+ widthPt: GRIDLINE_WIDTH_PT
8856
+ };
8857
+ out.push(line);
8858
+ }
8859
+ }
8860
+ function bandableIndices(start, end, repeat) {
8861
+ const indices = [];
8862
+ for (let i = start; i <= end; i++) {
8863
+ if (repeat !== void 0 && i >= repeat.start && i <= repeat.end) continue;
8864
+ indices.push(i);
8865
+ }
8866
+ return indices;
8867
+ }
8868
+ function rangeIndices(start, end) {
8869
+ const indices = [];
8870
+ for (let i = start; i <= end; i++) indices.push(i);
8871
+ return indices;
8872
+ }
8873
+ function convertSheetToPages(sheet, measurer, signal, out) {
8874
+ throwIfAborted(signal);
8875
+ const range = resolvePrintRange(sheet);
8876
+ if (range === void 0) return;
8877
+ const { printSettings } = sheet;
8878
+ const { pageSize, margins } = printSettings;
8879
+ const pageContentWidthPt = Math.max(0, pageSize.widthPt - margins.leftPt - margins.rightPt);
8880
+ const pageContentHeightPt = Math.max(0, pageSize.heightPt - margins.topPt - margins.bottomPt);
8881
+ const columnEntries = resolveAxis(sheet.columns.map((c) => ({
8882
+ index: c.index,
8883
+ sizePt: c.widthPt,
8884
+ hidden: c.hidden
8885
+ })), range.startColumn, range.endColumn, DEFAULT_COLUMN_WIDTH_PT);
8886
+ const rowEntries = resolveAxis(sheet.rows.map((r) => ({
8887
+ index: r.index,
8888
+ sizePt: r.heightPt,
8889
+ hidden: r.hidden
8890
+ })), range.startRow, range.endRow, DEFAULT_ROW_HEIGHT_PT);
8891
+ const columnSizeByIndex = new Map(columnEntries.map((e) => [e.index, e.sizePt]));
8892
+ const rowSizeByIndex = new Map(rowEntries.map((e) => [e.index, e.sizePt]));
8893
+ const hiddenColumnIndices = new Set(columnEntries.filter((e) => e.hidden).map((e) => e.index));
8894
+ const hiddenRowIndices = new Set(rowEntries.filter((e) => e.hidden).map((e) => e.index));
8895
+ const gutter = computeHeaderGutter(printSettings, range, measurer);
8896
+ const repeatColumns = printSettings.repeatColumns;
8897
+ const repeatRows = printSettings.repeatRows;
8898
+ const repeatColumnIndices = repeatColumns === void 0 ? [] : rangeIndices(repeatColumns.start, repeatColumns.end);
8899
+ const repeatRowIndices = repeatRows === void 0 ? [] : rangeIndices(repeatRows.start, repeatRows.end);
8900
+ const repeatColumnsWidthPt = repeatColumnIndices.reduce((sum, i) => sum + (columnSizeByIndex.get(i) ?? 0), 0);
8901
+ const repeatRowsHeightPt = repeatRowIndices.reduce((sum, i) => sum + (rowSizeByIndex.get(i) ?? 0), 0);
8902
+ const bandableColumnIndices = bandableIndices(range.startColumn, range.endColumn, repeatColumns);
8903
+ const bandableRowIndices = bandableIndices(range.startRow, range.endRow, repeatRows);
8904
+ const availableWidthPt = Math.max(0, pageContentWidthPt - gutter.widthPt - repeatColumnsWidthPt);
8905
+ const availableHeightPt = Math.max(0, pageContentHeightPt - gutter.heightPt - repeatRowsHeightPt);
8906
+ const scale = resolveScale(printSettings, availableWidthPt, availableHeightPt, bandableColumnIndices.reduce((sum, i) => sum + (columnSizeByIndex.get(i) ?? 0), 0), bandableRowIndices.reduce((sum, i) => sum + (rowSizeByIndex.get(i) ?? 0), 0));
8907
+ const descaledAvailableWidthPt = availableWidthPt / scale;
8908
+ const descaledAvailableHeightPt = availableHeightPt / scale;
8909
+ const manualBreakColumns = new Set(printSettings.manualBreaks?.columns ?? []);
8910
+ const manualBreakRows = new Set(printSettings.manualBreaks?.rows ?? []);
8911
+ throwIfAborted(signal);
8912
+ const columnBands = partitionIndices(bandableColumnIndices, (i) => columnSizeByIndex.get(i) ?? 0, descaledAvailableWidthPt, manualBreakColumns);
8913
+ const rowBands = partitionIndices(bandableRowIndices, (i) => rowSizeByIndex.get(i) ?? 0, descaledAvailableHeightPt, manualBreakRows);
8914
+ const cellsByRow = /* @__PURE__ */ new Map();
8915
+ for (const cell of sheet.cells) {
8916
+ let row = cellsByRow.get(cell.row);
8917
+ if (row === void 0) {
8918
+ row = /* @__PURE__ */ new Map();
8919
+ cellsByRow.set(cell.row, row);
8920
+ }
8921
+ row.set(cell.column, cell);
8922
+ }
8923
+ const scaledSizeOf = (sizeByIndex) => (index) => (sizeByIndex.get(index) ?? 0) * scale;
8924
+ const unscaledSizeOf = (sizeByIndex) => (index) => sizeByIndex.get(index) ?? 0;
8925
+ const bandPairs = printSettings.pageOrder === "overThenDown" ? rowBands.flatMap((rowBand) => columnBands.map((columnBand) => ({
8926
+ columnBand,
8927
+ rowBand
8928
+ }))) : columnBands.flatMap((columnBand) => rowBands.map((rowBand) => ({
8929
+ columnBand,
8930
+ rowBand
8931
+ })));
8932
+ for (const { columnBand, rowBand } of bandPairs) {
8933
+ throwIfAborted(signal);
8934
+ const columnAxis = buildPositionedAxis(repeatColumnIndices, unscaledSizeOf(columnSizeByIndex), columnBand, scaledSizeOf(columnSizeByIndex));
8935
+ const rowAxis = buildPositionedAxis(repeatRowIndices, unscaledSizeOf(rowSizeByIndex), rowBand, scaledSizeOf(rowSizeByIndex));
8936
+ const gridLeftXPt = margins.leftPt + gutter.widthPt;
8937
+ const gridTopYDownPt = margins.topPt + gutter.heightPt;
8938
+ const gridWidthPt = columnAxis.offsetsPt[columnAxis.offsetsPt.length - 1];
8939
+ const gridHeightPt = rowAxis.offsetsPt[rowAxis.offsetsPt.length - 1];
8940
+ const items = [];
8941
+ if (printSettings.gridlines) renderGridlines(gridLeftXPt, gridTopYDownPt, gridWidthPt, gridHeightPt, columnAxis.offsetsPt, rowAxis.offsetsPt, pageSize.heightPt, items);
8942
+ if (printSettings.headers) renderHeaderLabels(gutter, columnAxis, rowAxis, gridLeftXPt, gridTopYDownPt, pageSize.heightPt, measurer, items);
8943
+ for (const rowIndex of rowAxis.indices) {
8944
+ const rowCells = cellsByRow.get(rowIndex);
8945
+ if (rowCells === void 0) continue;
8946
+ for (const [columnIndex, cell] of rowCells) {
8947
+ throwIfAborted(signal);
8948
+ if (!columnAxis.positionByIndex.has(columnIndex) || hiddenColumnIndices.has(columnIndex) || hiddenRowIndices.has(cell.row)) continue;
8949
+ renderCellText(cell, rowCells, columnAxis, rowAxis, gridLeftXPt, gridTopYDownPt, pageSize.heightPt, measurer, items);
8950
+ }
8951
+ }
8952
+ out.push({
8953
+ widthPt: pageSize.widthPt,
8954
+ heightPt: pageSize.heightPt,
8955
+ items
8956
+ });
8957
+ }
8958
+ }
8959
+ function convertSpreadsheetToLayout(doc, options) {
8960
+ const pages = [];
8961
+ for (const sheet of doc.sheets) convertSheetToPages(sheet, options.measurer, options.signal, pages);
8962
+ return {
8963
+ formatVersion: document_content_model.LAYOUT_FORMAT_VERSION,
8964
+ metadata: doc.metadata,
8965
+ pages,
8966
+ images: {}
8967
+ };
8968
+ }
8969
+ //#endregion
8078
8970
  //#region src/layout/reconstruct.ts
8079
8971
  const ZERO_MARGINS = {
8080
8972
  topPt: 0,
@@ -8443,6 +9335,17 @@ function odpToPdf(bytes, options) {
8443
9335
  onSubstitution: options?.onSubstitution
8444
9336
  });
8445
9337
  }
9338
+ function odsToPdf(bytes, options) {
9339
+ const content = readOdsContent((0, odf_js.decodePackage)(bytes));
9340
+ if (content.kind !== "spreadsheet") throw new Error("readOdsContent returned a non-spreadsheet ContentDocument");
9341
+ return writePdf(convertSpreadsheetToLayout(content, {
9342
+ measurer: createStandardFontMeasurer(),
9343
+ signal: options?.signal
9344
+ }), {
9345
+ signal: options?.signal,
9346
+ onSubstitution: options?.onSubstitution
9347
+ });
9348
+ }
8446
9349
  function pdfToDocx(bytes, options) {
8447
9350
  const content = reconstructWordprocessing(readPdf(bytes, {
8448
9351
  signal: options?.signal,
@@ -8464,6 +9367,13 @@ function pdfToOdt(bytes, options) {
8464
9367
  }), { signal: options?.signal });
8465
9368
  return (0, odf_js.encodePackage)(buildOdtPackage(content));
8466
9369
  }
9370
+ function pdfToOdp(bytes, options) {
9371
+ const content = reconstructPresentation(readPdf(bytes, {
9372
+ signal: options?.signal,
9373
+ sink: options?.sink
9374
+ }), { signal: options?.signal });
9375
+ return (0, odf_js.encodePackage)(buildOdpPackage(content));
9376
+ }
8467
9377
  //#endregion
8468
9378
  //#region src/convert/codec.ts
8469
9379
  const docxPdfCodec = zod.z.codec(DocxBytesSchema, PdfBytesSchema, {
@@ -8478,6 +9388,10 @@ const odtPdfCodec = zod.z.codec(OdtBytesSchema, PdfBytesSchema, {
8478
9388
  decode: (odtBytes) => odtToPdf(odtBytes),
8479
9389
  encode: (pdfBytes) => pdfToOdt(pdfBytes)
8480
9390
  });
9391
+ const odpPdfCodec = zod.z.codec(OdpBytesSchema, PdfBytesSchema, {
9392
+ decode: (odpBytes) => odpToPdf(odpBytes),
9393
+ encode: (pdfBytes) => pdfToOdp(pdfBytes)
9394
+ });
8481
9395
  //#endregion
8482
9396
  //#region src/convert/local.ts
8483
9397
  const SUPPORTED_CONVERSIONS = [
@@ -8497,6 +9411,10 @@ const SUPPORTED_CONVERSIONS = [
8497
9411
  source: "odp",
8498
9412
  target: "pdf"
8499
9413
  },
9414
+ {
9415
+ source: "ods",
9416
+ target: "pdf"
9417
+ },
8500
9418
  {
8501
9419
  source: "pdf",
8502
9420
  target: "docx"
@@ -8508,6 +9426,10 @@ const SUPPORTED_CONVERSIONS = [
8508
9426
  {
8509
9427
  source: "pdf",
8510
9428
  target: "odt"
9429
+ },
9430
+ {
9431
+ source: "pdf",
9432
+ target: "odp"
8511
9433
  }
8512
9434
  ];
8513
9435
  function substitutionDiagnostic(substitution, context) {
@@ -8585,6 +9507,19 @@ function createLocalDocumentConverter() {
8585
9507
  diagnostics
8586
9508
  });
8587
9509
  }
9510
+ if (source.format === "ods" && targetFormat === "pdf") {
9511
+ const bytes = odsToPdf(source.bytes, {
9512
+ signal: options.signal,
9513
+ onSubstitution: (s, c) => diagnostics.push(substitutionDiagnostic(s, c))
9514
+ });
9515
+ return Promise.resolve({
9516
+ document: {
9517
+ format: "pdf",
9518
+ bytes
9519
+ },
9520
+ diagnostics
9521
+ });
9522
+ }
8588
9523
  if (source.format === "pdf" && targetFormat === "docx") {
8589
9524
  const bytes = pdfToDocx(source.bytes, {
8590
9525
  signal: options.signal,
@@ -8624,6 +9559,19 @@ function createLocalDocumentConverter() {
8624
9559
  diagnostics
8625
9560
  });
8626
9561
  }
9562
+ if (source.format === "pdf" && targetFormat === "odp") {
9563
+ const bytes = pdfToOdp(source.bytes, {
9564
+ signal: options.signal,
9565
+ sink: (d) => diagnostics.push(fromPdfDiagnostic(d))
9566
+ });
9567
+ return Promise.resolve({
9568
+ document: {
9569
+ format: "odp",
9570
+ bytes
9571
+ },
9572
+ diagnostics
9573
+ });
9574
+ }
8627
9575
  return Promise.reject(/* @__PURE__ */ new Error(`unsupported conversion: ${source.format} -> ${targetFormat}`));
8628
9576
  }
8629
9577
  };
@@ -8684,6 +9632,12 @@ Object.defineProperty(exports, "ContentBlockSchema", {
8684
9632
  return document_content_model.ContentBlockSchema;
8685
9633
  }
8686
9634
  });
9635
+ Object.defineProperty(exports, "ContentCellValueSchema", {
9636
+ enumerable: true,
9637
+ get: function() {
9638
+ return document_content_model.ContentCellValueSchema;
9639
+ }
9640
+ });
8687
9641
  exports.ContentDocumentSchema = ContentDocumentSchema;
8688
9642
  Object.defineProperty(exports, "ContentImageBlockSchema", {
8689
9643
  enumerable: true,
@@ -8721,6 +9675,48 @@ Object.defineProperty(exports, "ContentShapeSchema", {
8721
9675
  return document_content_model.ContentShapeSchema;
8722
9676
  }
8723
9677
  });
9678
+ Object.defineProperty(exports, "ContentSheetCellSchema", {
9679
+ enumerable: true,
9680
+ get: function() {
9681
+ return document_content_model.ContentSheetCellSchema;
9682
+ }
9683
+ });
9684
+ Object.defineProperty(exports, "ContentSheetColumnSchema", {
9685
+ enumerable: true,
9686
+ get: function() {
9687
+ return document_content_model.ContentSheetColumnSchema;
9688
+ }
9689
+ });
9690
+ Object.defineProperty(exports, "ContentSheetPrintRangeSchema", {
9691
+ enumerable: true,
9692
+ get: function() {
9693
+ return document_content_model.ContentSheetPrintRangeSchema;
9694
+ }
9695
+ });
9696
+ Object.defineProperty(exports, "ContentSheetPrintSettingsSchema", {
9697
+ enumerable: true,
9698
+ get: function() {
9699
+ return document_content_model.ContentSheetPrintSettingsSchema;
9700
+ }
9701
+ });
9702
+ Object.defineProperty(exports, "ContentSheetRepeatRangeSchema", {
9703
+ enumerable: true,
9704
+ get: function() {
9705
+ return document_content_model.ContentSheetRepeatRangeSchema;
9706
+ }
9707
+ });
9708
+ Object.defineProperty(exports, "ContentSheetRowSchema", {
9709
+ enumerable: true,
9710
+ get: function() {
9711
+ return document_content_model.ContentSheetRowSchema;
9712
+ }
9713
+ });
9714
+ Object.defineProperty(exports, "ContentSheetSchema", {
9715
+ enumerable: true,
9716
+ get: function() {
9717
+ return document_content_model.ContentSheetSchema;
9718
+ }
9719
+ });
8724
9720
  Object.defineProperty(exports, "ContentSlideSchema", {
8725
9721
  enumerable: true,
8726
9722
  get: function() {
@@ -8773,6 +9769,9 @@ Object.defineProperty(exports, "LAYOUT_FORMAT_VERSION", {
8773
9769
  exports.NOOP_DIAGNOSTIC_SINK = NOOP_DIAGNOSTIC_SINK;
8774
9770
  exports.OdgBytesSchema = OdgBytesSchema;
8775
9771
  exports.OdpBytesSchema = OdpBytesSchema;
9772
+ exports.OdpEditor = OdpEditor;
9773
+ exports.OdpShape = OdpShape;
9774
+ exports.OdpSlide = OdpSlide;
8776
9775
  exports.OdsBytesSchema = OdsBytesSchema;
8777
9776
  exports.OdtBytesSchema = OdtBytesSchema;
8778
9777
  exports.OdtEditor = OdtEditor;
@@ -8887,6 +9886,7 @@ Object.defineProperty(exports, "base64ToBytes", {
8887
9886
  }
8888
9887
  });
8889
9888
  exports.buildDocxPackage = buildDocxPackage;
9889
+ exports.buildOdpPackage = buildOdpPackage;
8890
9890
  exports.buildOdtPackage = buildOdtPackage;
8891
9891
  exports.buildPptxPackage = buildPptxPackage;
8892
9892
  Object.defineProperty(exports, "buildXml", {
@@ -8920,9 +9920,11 @@ Object.defineProperty(exports, "compactPackageCodec", {
8920
9920
  }
8921
9921
  });
8922
9922
  exports.convertPresentationToLayout = convertPresentationToLayout;
9923
+ exports.convertSpreadsheetToLayout = convertSpreadsheetToLayout;
8923
9924
  exports.convertWordprocessingToLayout = convertWordprocessingToLayout;
8924
9925
  exports.createDocx = createDocx;
8925
9926
  exports.createLocalDocumentConverter = createLocalDocumentConverter;
9927
+ exports.createOdp = createOdp;
8926
9928
  exports.createOdt = createOdt;
8927
9929
  exports.createPptx = createPptx;
8928
9930
  Object.defineProperty(exports, "decodeCompactPackage", {
@@ -8989,10 +9991,13 @@ Object.defineProperty(exports, "isXmlNode", {
8989
9991
  return ooxml_js.isXmlNode;
8990
9992
  }
8991
9993
  });
9994
+ exports.odpPdfCodec = odpPdfCodec;
8992
9995
  exports.odpToPdf = odpToPdf;
9996
+ exports.odsToPdf = odsToPdf;
8993
9997
  exports.odtPdfCodec = odtPdfCodec;
8994
9998
  exports.odtToPdf = odtToPdf;
8995
9999
  exports.openDocx = openDocx;
10000
+ exports.openOdp = openOdp;
8996
10001
  exports.openOdt = openOdt;
8997
10002
  exports.openPptx = openPptx;
8998
10003
  Object.defineProperty(exports, "packageCodec", {
@@ -9015,12 +10020,14 @@ Object.defineProperty(exports, "parseXml", {
9015
10020
  });
9016
10021
  exports.pdfCodec = pdfCodec;
9017
10022
  exports.pdfToDocx = pdfToDocx;
10023
+ exports.pdfToOdp = pdfToOdp;
9018
10024
  exports.pdfToOdt = pdfToOdt;
9019
10025
  exports.pdfToPptx = pdfToPptx;
9020
10026
  exports.pptxPdfCodec = pptxPdfCodec;
9021
10027
  exports.pptxToPdf = pptxToPdf;
9022
10028
  exports.readDocxContent = readDocxContent;
9023
10029
  exports.readOdpContent = readOdpContent;
10030
+ exports.readOdsContent = readOdsContent;
9024
10031
  exports.readOdtContent = readOdtContent;
9025
10032
  exports.readPdf = readPdf;
9026
10033
  exports.readPptxContent = readPptxContent;