superdoc 1.13.0-next.12 → 1.13.0-next.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/chunks/{helpers-DTjYh3Fu.cjs → DocxZipper-Bs5-dXNA.cjs} +246 -489
  2. package/dist/chunks/{helpers-DFNWSYpB.es.js → DocxZipper-lmCBVhg-.es.js} +243 -311
  3. package/dist/chunks/{PdfViewer-Ce8mJaNh.cjs → PdfViewer-DXuJUsot.cjs} +9 -9
  4. package/dist/chunks/{PdfViewer-BY01oNeC.es.js → PdfViewer-VeBGZkjF.es.js} +9 -9
  5. package/dist/chunks/{SuperConverter-cCtwPuPC.cjs → SuperConverter-BTeUEvqK.cjs} +178 -469
  6. package/dist/chunks/{SuperConverter-Dux7hvIY.es.js → SuperConverter-BehGjQTV.es.js} +179 -470
  7. package/dist/chunks/{comments-store-_bERwKQj.es.js → comments-store-BARewqVr.es.js} +4 -4
  8. package/dist/chunks/{comments-store-M-sNLSDo.cjs → comments-store-D20t39V5.cjs} +4 -4
  9. package/dist/chunks/helpers-BGD_wEOi.es.js +325 -0
  10. package/dist/chunks/helpers-Cs_Zz44i.cjs +517 -0
  11. package/dist/chunks/{src-BS9k_Tm_.cjs → src-DDa9uH3u.cjs} +15 -15
  12. package/dist/chunks/{src-cSv7yD90.es.js → src-DcFr6MxX.es.js} +9 -9
  13. package/dist/chunks/{vue-DBUiP_Rf.cjs → vue-D6hUziY_.cjs} +1 -1
  14. package/dist/chunks/{vue--Hddm509.es.js → vue-DMMnFUp6.es.js} +1 -1
  15. package/dist/chunks/{xml-js-XW5hGFSq.cjs → xml-js--DznO7Gk.cjs} +1 -1
  16. package/dist/chunks/{xml-js-BYjoxUnf.es.js → xml-js-DLE8mr0n.es.js} +1 -1
  17. package/dist/chunks/{zipper-asS9R-qe.es.js → zipper-BJHqrQMq.es.js} +1 -1
  18. package/dist/chunks/{zipper-Cklov3Aa.cjs → zipper-BlH3x8l-.cjs} +1 -1
  19. package/dist/super-editor/converter.cjs +4 -4
  20. package/dist/super-editor/converter.es.js +4 -4
  21. package/dist/super-editor/core/DocxZipper.d.ts.map +1 -1
  22. package/dist/super-editor/core/super-converter/SuperConverter.d.ts.map +1 -1
  23. package/dist/super-editor/core/super-converter/helpers.d.ts +7 -0
  24. package/dist/super-editor/core/super-converter/helpers.d.ts.map +1 -1
  25. package/dist/super-editor/core/super-converter/v3/handlers/wp/helpers/metafile-converter.d.ts.map +1 -1
  26. package/dist/super-editor/docx-zipper.cjs +4 -4
  27. package/dist/super-editor/docx-zipper.es.js +4 -4
  28. package/dist/super-editor/file-zipper.cjs +2 -2
  29. package/dist/super-editor/file-zipper.es.js +2 -2
  30. package/dist/super-editor/src/core/DocxZipper.d.ts.map +1 -1
  31. package/dist/super-editor/src/core/super-converter/SuperConverter.d.ts.map +1 -1
  32. package/dist/super-editor/src/core/super-converter/helpers.d.ts +7 -0
  33. package/dist/super-editor/src/core/super-converter/helpers.d.ts.map +1 -1
  34. package/dist/super-editor/src/core/super-converter/v3/handlers/wp/helpers/metafile-converter.d.ts.map +1 -1
  35. package/dist/super-editor/tsconfig.types.tsbuildinfo +1 -1
  36. package/dist/super-editor.cjs +8 -8
  37. package/dist/super-editor.es.js +8 -8
  38. package/dist/superdoc.cjs +12 -12
  39. package/dist/superdoc.es.js +12 -12
  40. package/dist/superdoc.umd.js +2256 -4859
  41. package/dist/superdoc.umd.js.map +1 -1
  42. package/package.json +3 -3
  43. package/dist/chunks/DocxZipper-BRbF0v1D.cjs +0 -256
  44. package/dist/chunks/DocxZipper-DP4evZmt.es.js +0 -251
  45. /package/dist/chunks/{jszip-DmQt_IET.es.js → jszip-ChlR43oI.es.js} +0 -0
  46. /package/dist/chunks/{jszip-Dmo1nQ1j.cjs → jszip-DCT9QYaK.cjs} +0 -0
  47. /package/dist/chunks/{uuid-CzripdPy.es.js → uuid-2IzDu5nl.es.js} +0 -0
  48. /package/dist/chunks/{uuid-LBaLT4fl.cjs → uuid-CHj_rjgt.cjs} +0 -0
@@ -1,4 +1,7 @@
1
- const require_xml_js = require("./xml-js-XW5hGFSq.cjs");
1
+ const require_rolldown_runtime = require("./rolldown-runtime-Dp2H1eGw.cjs");
2
+ const require_jszip = require("./jszip-DCT9QYaK.cjs");
3
+ const require_xml_js = require("./xml-js--DznO7Gk.cjs");
4
+ const require_helpers = require("./helpers-Cs_Zz44i.cjs");
2
5
  var buffer = {};
3
6
  var base64Js = {};
4
7
  base64Js.byteLength = byteLength;
@@ -1394,10 +1397,10 @@ ieee754.write = function(buffer$1, value, offset, isLE, mLen, nBytes) {
1394
1397
  }
1395
1398
  })(buffer);
1396
1399
  var Buffer = buffer.Buffer;
1397
- var Blob$1 = buffer.Blob;
1400
+ var Blob = buffer.Blob;
1398
1401
  var BlobOptions = buffer.BlobOptions;
1399
1402
  var Buffer$1 = buffer.Buffer;
1400
- var File = buffer.File;
1403
+ var File$1 = buffer.File;
1401
1404
  var FileOptions = buffer.FileOptions;
1402
1405
  var INSPECT_MAX_BYTES = buffer.INSPECT_MAX_BYTES;
1403
1406
  var SlowBuffer = buffer.SlowBuffer;
@@ -1411,508 +1414,262 @@ var kMaxLength = buffer.kMaxLength;
1411
1414
  var kStringMaxLength = buffer.kStringMaxLength;
1412
1415
  var resolveObjectURL = buffer.resolveObjectURL;
1413
1416
  var transcode = buffer.transcode;
1414
- var import_lib = require_xml_js.require_lib();
1415
- var PIXELS_PER_INCH = 96;
1416
- function inchesToTwips(inches) {
1417
- if (inches == null) return;
1418
- if (typeof inches === "string") inches = parseFloat(inches);
1419
- return Math.round(Number(inches) * 1440);
1417
+ const isXmlLike = (name) => /\.xml$|\.rels$/i.test(name);
1418
+ function sniffEncoding(u8) {
1419
+ if (u8.length >= 2) {
1420
+ const b0 = u8[0], b1 = u8[1];
1421
+ if (b0 === 255 && b1 === 254) return "utf-16le";
1422
+ if (b0 === 254 && b1 === 255) return "utf-16be";
1423
+ }
1424
+ let nul = 0;
1425
+ for (let i$1 = 0; i$1 < Math.min(64, u8.length); i$1++) if (u8[i$1] === 0) nul++;
1426
+ if (nul > 16) return "utf-16le";
1427
+ return "utf-8";
1420
1428
  }
1421
- function twipsToInches(twips) {
1422
- if (twips == null) return;
1423
- const value = Number(twips);
1424
- if (Number.isNaN(value)) return;
1425
- return value / 1440;
1429
+ function stripBOM(str) {
1430
+ return str && str.charCodeAt(0) === 65279 ? str.slice(1) : str;
1426
1431
  }
1427
- function twipsToPixels(twips) {
1428
- if (twips == null) return;
1429
- return inchesToPixels(twipsToInches(twips));
1432
+ function ensureXmlString(content) {
1433
+ if (typeof content === "string") return stripBOM(content);
1434
+ let u8 = null;
1435
+ if (content && typeof content === "object") {
1436
+ if (content instanceof Uint8Array) u8 = content;
1437
+ else if (typeof Buffer !== "undefined" && Buffer.isBuffer && Buffer.isBuffer(content)) u8 = new Uint8Array(content.buffer, content.byteOffset, content.byteLength);
1438
+ else if (ArrayBuffer.isView && ArrayBuffer.isView(content)) u8 = new Uint8Array(content.buffer, content.byteOffset, content.byteLength);
1439
+ else if (content.constructor && (content instanceof ArrayBuffer || content.constructor.name === "ArrayBuffer")) u8 = new Uint8Array(content);
1440
+ }
1441
+ if (!u8) throw new Error("Unsupported content type for XML");
1442
+ const enc = sniffEncoding(u8);
1443
+ return stripBOM(new TextDecoder(enc).decode(u8));
1430
1444
  }
1431
- function pixelsToTwips(pixels) {
1432
- return inchesToTwips(pixelsToInches(pixels));
1433
- }
1434
- function inchesToPixels(inches) {
1435
- if (inches == null) return;
1436
- const pixels = inches * 96;
1437
- return Math.round(pixels * 1e3) / 1e3;
1438
- }
1439
- function pixelsToInches(pixels) {
1440
- if (pixels == null) return;
1441
- return Number(pixels) / 96;
1442
- }
1443
- function twipsToLines(twips) {
1444
- if (twips == null) return;
1445
- return twips / 240;
1446
- }
1447
- function linesToTwips(lines) {
1448
- if (lines == null) return;
1449
- return lines * 240;
1450
- }
1451
- function halfPointToPoints(halfPoints) {
1452
- if (halfPoints == null) return;
1453
- return Math.round(halfPoints) / 2;
1454
- }
1455
- function emuToPixels(emu) {
1456
- if (emu == null) return;
1457
- if (typeof emu === "string") emu = parseFloat(emu);
1458
- const pixels = emu * 96 / 914400;
1459
- return Math.round(pixels);
1460
- }
1461
- function pixelsToEmu(px) {
1462
- if (px == null) return;
1463
- if (typeof px === "string") px = parseFloat(px);
1464
- return Math.round(px * 9525);
1465
- }
1466
- function eighthPointsToPixels(eighthPoints) {
1467
- if (eighthPoints == null) return;
1468
- return parseFloat(eighthPoints) / 8 * 1.3333;
1469
- }
1470
- function pointsToTwips(points) {
1471
- if (points == null) return;
1472
- return points * 20;
1473
- }
1474
- function pixelsToEightPoints(pixels) {
1475
- if (pixels == null) return;
1476
- return Math.round(pixels * 6);
1477
- }
1478
- function twipsToPt(twips) {
1479
- if (twips == null) return;
1480
- return twips / 20;
1481
- }
1482
- function ptToTwips(pt) {
1483
- if (pt == null) return;
1484
- return pt * 20;
1485
- }
1486
- function rotToDegrees(rot) {
1487
- if (rot == null) return;
1488
- return rot / 6e4;
1489
- }
1490
- function degreesToRot(degrees) {
1491
- if (degrees == null) return;
1492
- return degrees * 6e4;
1493
- }
1494
- function pixelsToPolygonUnits(pixels) {
1495
- if (pixels == null) return;
1496
- const pu = pixels * 96;
1497
- return Math.round(pu);
1498
- }
1499
- function polygonUnitsToPixels(pu) {
1500
- if (pu == null) return;
1501
- const pixels = Number(pu) / 96;
1502
- return Math.round(pixels * 1e3) / 1e3;
1503
- }
1504
- function polygonToObj(polygonNode) {
1505
- if (!polygonNode) return null;
1506
- const points = [];
1507
- polygonNode.elements.forEach((element) => {
1508
- if (["wp:start", "wp:lineTo"].includes(element.name)) {
1509
- const { x, y } = element.attributes;
1510
- points.push([polygonUnitsToPixels(x), polygonUnitsToPixels(y)]);
1511
- }
1512
- });
1513
- if (points.length > 1) {
1514
- const firstPoint = points[0];
1515
- const lastPoint = points[points.length - 1];
1516
- if (firstPoint[0] === lastPoint[0] && firstPoint[1] === lastPoint[1]) points.pop();
1517
- }
1518
- return points;
1519
- }
1520
- function objToPolygon(points) {
1521
- if (!points || !Array.isArray(points)) return null;
1522
- const polygonNode = {
1523
- name: "wp:wrapPolygon",
1524
- type: "wp:wrapPolygon",
1525
- attributes: { edited: "0" },
1526
- elements: []
1527
- };
1528
- points.forEach((point, index) => {
1529
- const [x, y] = point;
1530
- const tagName = index === 0 ? "wp:start" : "wp:lineTo";
1531
- const pointNode = {
1532
- name: tagName,
1533
- type: tagName,
1534
- attributes: {
1535
- x: pixelsToPolygonUnits(x),
1536
- y: pixelsToPolygonUnits(y)
1445
+ var import_lib = /* @__PURE__ */ require_rolldown_runtime.__toESM(require_xml_js.require_lib(), 1);
1446
+ var import_jszip_min = /* @__PURE__ */ require_rolldown_runtime.__toESM(require_jszip.require_jszip_min(), 1);
1447
+ var DocxZipper = class {
1448
+ constructor(params = {}) {
1449
+ this.debug = params.debug || false;
1450
+ this.zip = new import_jszip_min.default();
1451
+ this.files = [];
1452
+ this.media = {};
1453
+ this.mediaFiles = {};
1454
+ this.fonts = {};
1455
+ }
1456
+ async getDocxData(file, isNode = false) {
1457
+ const extractedFiles = await this.unzip(file);
1458
+ const files = Object.entries(extractedFiles.files);
1459
+ for (const [, zipEntry] of files) {
1460
+ const name = zipEntry.name;
1461
+ if (isXmlLike(name)) {
1462
+ const content = ensureXmlString(await zipEntry.async("uint8array"));
1463
+ this.files.push({
1464
+ name,
1465
+ content
1466
+ });
1467
+ } else if (name.startsWith("word/media") && name !== "word/media/" || zipEntry.name.startsWith("media") && zipEntry.name !== "media/" || name.startsWith("media") && name !== "media/" || name.startsWith("word/embeddings") && name !== "word/embeddings/") if (isNode) {
1468
+ const fileBase64 = (await zipEntry.async("nodebuffer")).toString("base64");
1469
+ this.mediaFiles[name] = fileBase64;
1470
+ } else {
1471
+ const fileBase64 = await zipEntry.async("base64");
1472
+ const extension = this.getFileExtension(name)?.toLowerCase();
1473
+ if (new Set([
1474
+ "png",
1475
+ "jpg",
1476
+ "jpeg",
1477
+ "gif",
1478
+ "bmp",
1479
+ "tiff",
1480
+ "emf",
1481
+ "wmf",
1482
+ "svg",
1483
+ "webp"
1484
+ ]).has(extension)) {
1485
+ this.mediaFiles[name] = `data:image/${extension};base64,${fileBase64}`;
1486
+ const blob = await zipEntry.async("blob");
1487
+ const fileObj = new File([blob], name, { type: blob.type });
1488
+ const imageUrl = URL.createObjectURL(fileObj);
1489
+ this.media[name] = imageUrl;
1490
+ } else this.mediaFiles[name] = fileBase64;
1537
1491
  }
1538
- };
1539
- polygonNode.elements.push(pointNode);
1540
- });
1541
- if (points.length > 0) {
1542
- const [startX, startY] = points[0];
1543
- const closePointNode = {
1544
- name: "wp:lineTo",
1545
- type: "wp:lineTo",
1546
- attributes: {
1547
- x: pixelsToPolygonUnits(startX),
1548
- y: pixelsToPolygonUnits(startY)
1492
+ else if (name.startsWith("word/fonts") && name !== "word/fonts/") {
1493
+ const uint8array = await zipEntry.async("uint8array");
1494
+ this.fonts[name] = uint8array;
1549
1495
  }
1496
+ }
1497
+ return this.files;
1498
+ }
1499
+ getFileExtension(fileName) {
1500
+ const fileSplit = fileName.split(".");
1501
+ if (fileSplit.length < 2) return null;
1502
+ return fileSplit[fileSplit.length - 1];
1503
+ }
1504
+ async updateContentTypes(docx, media, fromJson, updatedDocs = {}) {
1505
+ const additionalPartNames = Object.keys(updatedDocs || {});
1506
+ const imageExts = new Set([
1507
+ "png",
1508
+ "jpg",
1509
+ "jpeg",
1510
+ "gif",
1511
+ "bmp",
1512
+ "tiff",
1513
+ "emf",
1514
+ "wmf",
1515
+ "svg",
1516
+ "webp"
1517
+ ]);
1518
+ const newMediaTypes = Object.keys(media).map((name) => this.getFileExtension(name)).filter((ext) => ext && imageExts.has(ext));
1519
+ const contentTypesPath = "[Content_Types].xml";
1520
+ let contentTypesXml;
1521
+ if (fromJson) if (Array.isArray(docx.files)) contentTypesXml = docx.files.find((file) => file.name === contentTypesPath)?.content || "";
1522
+ else contentTypesXml = docx.files?.[contentTypesPath] || "";
1523
+ else contentTypesXml = await docx.file(contentTypesPath).async("string");
1524
+ let typesString = "";
1525
+ const defaultMediaTypes = require_helpers.getContentTypesFromXml(contentTypesXml);
1526
+ const seenTypes = /* @__PURE__ */ new Set();
1527
+ for (let type of newMediaTypes) {
1528
+ if (defaultMediaTypes.includes(type)) continue;
1529
+ if (seenTypes.has(type)) continue;
1530
+ const newContentType = `<Default Extension="${type}" ContentType="image/${type}"/>`;
1531
+ typesString += newContentType;
1532
+ seenTypes.add(type);
1533
+ }
1534
+ const types = JSON.parse(import_lib.xml2json(contentTypesXml, null, 2)).elements?.find((el) => el.name === "Types") || {};
1535
+ const hasComments = types.elements?.some((el) => el.name === "Override" && el.attributes.PartName === "/word/comments.xml");
1536
+ const hasCommentsExtended = types.elements?.some((el) => el.name === "Override" && el.attributes.PartName === "/word/commentsExtended.xml");
1537
+ const hasCommentsIds = types.elements?.some((el) => el.name === "Override" && el.attributes.PartName === "/word/commentsIds.xml");
1538
+ const hasCommentsExtensible = types.elements?.some((el) => el.name === "Override" && el.attributes.PartName === "/word/commentsExtensible.xml");
1539
+ const hasFile = (filename) => {
1540
+ if (updatedDocs && Object.prototype.hasOwnProperty.call(updatedDocs, filename)) return true;
1541
+ if (!docx?.files) return false;
1542
+ if (!fromJson) return Boolean(docx.files[filename]);
1543
+ if (Array.isArray(docx.files)) return docx.files.some((file) => file.name === filename);
1544
+ return Boolean(docx.files[filename]);
1550
1545
  };
1551
- polygonNode.elements.push(closePointNode);
1552
- }
1553
- return polygonNode;
1554
- }
1555
- var REMOTE_RESOURCE_PATTERN = /^https?:|^blob:|^file:/i;
1556
- var DATA_URI_PATTERN = /^data:/i;
1557
- var getArrayBufferFromUrl = async (input) => {
1558
- if (input == null) return /* @__PURE__ */ new ArrayBuffer(0);
1559
- if (input instanceof ArrayBuffer) return input;
1560
- if (ArrayBuffer.isView(input)) {
1561
- const view = input;
1562
- return view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength);
1563
- }
1564
- if (typeof Blob !== "undefined" && input instanceof Blob) return await input.arrayBuffer();
1565
- if (typeof input !== "string") throw new TypeError("Unsupported media input type");
1566
- const trimmed = input.trim();
1567
- const shouldFetchRemote = REMOTE_RESOURCE_PATTERN.test(trimmed);
1568
- const isDataUri = DATA_URI_PATTERN.test(trimmed);
1569
- if (shouldFetchRemote) {
1570
- if (typeof fetch !== "function") throw new Error(`Fetch API is not available to retrieve media: ${trimmed}`);
1571
- const response = await fetch(trimmed);
1572
- if (!response.ok) throw new Error(`Fetch failed: ${response.status} ${response.statusText}`);
1573
- return await response.arrayBuffer();
1574
- }
1575
- const base64Payload = isDataUri ? trimmed.split(",", 2)[1] : trimmed.replace(/\s/g, "");
1576
- try {
1577
- if (typeof globalThis.atob === "function") {
1578
- const binary = globalThis.atob(base64Payload);
1579
- const bytes = new Uint8Array(binary.length);
1580
- for (let i$1 = 0; i$1 < binary.length; i$1++) bytes[i$1] = binary.charCodeAt(i$1);
1581
- return bytes.buffer;
1546
+ if (hasFile("word/comments.xml")) {
1547
+ const commentsDef = `<Override PartName="/word/comments.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml" />`;
1548
+ if (!hasComments) typesString += commentsDef;
1582
1549
  }
1583
- } catch (err) {
1584
- console.warn("atob failed, falling back to Buffer:", err);
1585
- }
1586
- const buf = Buffer.from(base64Payload, "base64");
1587
- return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
1588
- };
1589
- var getContentTypesFromXml = (contentTypesXml) => {
1590
- try {
1591
- return ((0, import_lib.xml2js)(contentTypesXml, { compact: false })?.elements?.[0]?.elements || []).filter((el) => el?.name === "Default").map((el) => el.attributes?.Extension).filter(Boolean);
1592
- } catch (err) {
1593
- console.warn("[super-editor] Failed to parse [Content_Types].xml", err);
1594
- return [];
1595
- }
1596
- };
1597
- var resolveOpcTargetPath = (target, baseDir = "word") => {
1598
- if (!target) return null;
1599
- if (target.includes("://")) return null;
1600
- if (target.startsWith("/")) return target.slice(1);
1601
- const segments = `${baseDir}/${target}`.split("/");
1602
- const resolved = [];
1603
- for (const seg of segments) if (seg === "..") resolved.pop();
1604
- else if (seg !== "." && seg !== "") resolved.push(seg);
1605
- return resolved.join("/");
1606
- };
1607
- var DOCX_HIGHLIGHT_KEYWORD_MAP = new Map([
1608
- ["yellow", "FFFF00"],
1609
- ["green", "00FF00"],
1610
- ["blue", "0000FF"],
1611
- ["cyan", "00FFFF"],
1612
- ["magenta", "FF00FF"],
1613
- ["red", "FF0000"],
1614
- ["darkYellow", "808000"],
1615
- ["darkGreen", "008000"],
1616
- ["darkBlue", "000080"],
1617
- ["darkCyan", "008080"],
1618
- ["darkMagenta", "800080"],
1619
- ["darkGray", "808080"],
1620
- ["darkRed", "800000"],
1621
- ["lightGray", "C0C0C0"],
1622
- ["black", "000000"],
1623
- ["white", "FFFFFF"]
1624
- ]);
1625
- var normalizeHexColor = (hex) => {
1626
- if (!hex) return null;
1627
- let value = hex.replace("#", "").trim();
1628
- if (!value) return null;
1629
- value = value.toUpperCase();
1630
- if (value.length === 3) value = value.split("").map((c) => c + c).join("");
1631
- if (value.length === 8) value = value.slice(0, 6);
1632
- return value;
1633
- };
1634
- var getHexColorFromDocxSystem = (docxColor) => {
1635
- const hex = DOCX_HIGHLIGHT_KEYWORD_MAP.get(docxColor);
1636
- return hex ? `#${hex}` : null;
1637
- };
1638
- var getDocxHighlightKeywordFromHex = (hexColor) => {
1639
- if (!hexColor) return null;
1640
- if (DOCX_HIGHLIGHT_KEYWORD_MAP.has(hexColor)) return hexColor;
1641
- const normalized = normalizeHexColor(hexColor);
1642
- if (!normalized) return null;
1643
- for (const [keyword, hex] of DOCX_HIGHLIGHT_KEYWORD_MAP.entries()) if (hex === normalized) return keyword;
1644
- return null;
1645
- };
1646
- function isValidHexColor(color) {
1647
- if (!color || typeof color !== "string") return false;
1648
- switch (color.length) {
1649
- case 3: return /^[0-9A-F]{3}$/i.test(color);
1650
- case 6: return /^[0-9A-F]{6}$/i.test(color);
1651
- case 8: return /^[0-9A-F]{8}$/i.test(color);
1652
- default: return false;
1550
+ if (hasFile("word/commentsExtended.xml")) {
1551
+ const commentsExtendedDef = `<Override PartName="/word/commentsExtended.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml" />`;
1552
+ if (!hasCommentsExtended) typesString += commentsExtendedDef;
1553
+ }
1554
+ if (hasFile("word/commentsIds.xml")) {
1555
+ const commentsIdsDef = `<Override PartName="/word/commentsIds.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.commentsIds+xml" />`;
1556
+ if (!hasCommentsIds) typesString += commentsIdsDef;
1557
+ }
1558
+ if (hasFile("word/commentsExtensible.xml")) {
1559
+ const commentsExtendedDef = `<Override PartName="/word/commentsExtensible.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtensible+xml" />`;
1560
+ if (!hasCommentsExtensible) typesString += commentsExtendedDef;
1561
+ }
1562
+ const hasFootnotes = types.elements?.some((el) => el.name === "Override" && el.attributes.PartName === "/word/footnotes.xml");
1563
+ if (hasFile("word/footnotes.xml")) {
1564
+ const footnotesDef = `<Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml" />`;
1565
+ if (!hasFootnotes) typesString += footnotesDef;
1566
+ }
1567
+ const partNames = new Set(additionalPartNames);
1568
+ if (docx?.files) if (fromJson && Array.isArray(docx.files)) docx.files.forEach((file) => partNames.add(file.name));
1569
+ else Object.keys(docx.files).forEach((key) => partNames.add(key));
1570
+ partNames.forEach((name) => {
1571
+ if (name.includes(".rels")) return;
1572
+ if (!name.includes("header") && !name.includes("footer")) return;
1573
+ const hasExtensible = types.elements?.some((el) => el.name === "Override" && el.attributes.PartName === `/${name}`);
1574
+ const extendedDef = `<Override PartName="/${name}" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.${name.includes("header") ? "header" : "footer"}+xml"/>`;
1575
+ if (!hasExtensible) typesString += extendedDef;
1576
+ });
1577
+ const beginningString = "<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">";
1578
+ let updatedContentTypesXml = contentTypesXml.replace(beginningString, `${beginningString}${typesString}`);
1579
+ let relationshipsXml = updatedDocs["word/_rels/document.xml.rels"];
1580
+ if (!relationshipsXml) if (fromJson) if (Array.isArray(docx.files)) relationshipsXml = docx.files.find((file) => file.name === "word/_rels/document.xml.rels")?.content;
1581
+ else relationshipsXml = docx.files?.["word/_rels/document.xml.rels"];
1582
+ else relationshipsXml = await docx.file("word/_rels/document.xml.rels")?.async("string");
1583
+ if (relationshipsXml) try {
1584
+ (import_lib.xml2js(relationshipsXml, { compact: false }).elements?.find((el) => el.name === "Relationships"))?.elements?.forEach((rel) => {
1585
+ const type = rel.attributes?.Type;
1586
+ const target = rel.attributes?.Target;
1587
+ if (!type || !target) return;
1588
+ const isHeader = type.includes("/header");
1589
+ const isFooter = type.includes("/footer");
1590
+ if (!isHeader && !isFooter) return;
1591
+ let sanitizedTarget = target.replace(/^\.\//, "");
1592
+ if (sanitizedTarget.startsWith("../")) sanitizedTarget = sanitizedTarget.slice(3);
1593
+ if (sanitizedTarget.startsWith("/")) sanitizedTarget = sanitizedTarget.slice(1);
1594
+ const partName = sanitizedTarget.startsWith("word/") ? sanitizedTarget : `word/${sanitizedTarget}`;
1595
+ partNames.add(partName);
1596
+ });
1597
+ } catch (error) {
1598
+ console.warn("Failed to parse document relationships while updating content types", error);
1599
+ }
1600
+ partNames.forEach((name) => {
1601
+ if (name.includes(".rels")) return;
1602
+ if (!name.includes("header") && !name.includes("footer")) return;
1603
+ if (updatedContentTypesXml.includes(`PartName="/${name}"`)) return;
1604
+ const extendedDef = `<Override PartName="/${name}" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.${name.includes("header") ? "header" : "footer"}+xml"/>`;
1605
+ updatedContentTypesXml = updatedContentTypesXml.replace("</Types>", `${extendedDef}</Types>`);
1606
+ });
1607
+ if (fromJson) return updatedContentTypesXml;
1608
+ docx.file(contentTypesPath, updatedContentTypesXml);
1609
+ }
1610
+ async unzip(file) {
1611
+ return await this.zip.loadAsync(file);
1612
+ }
1613
+ async updateZip({ docx, updatedDocs, originalDocxFile, media, fonts, isHeadless, compression = "DEFLATE" }) {
1614
+ let zip;
1615
+ if (originalDocxFile) zip = await this.exportFromOriginalFile(originalDocxFile, updatedDocs, media);
1616
+ else zip = await this.exportFromCollaborativeDocx(docx, updatedDocs, media, fonts);
1617
+ const exportType = isHeadless ? "nodebuffer" : "blob";
1618
+ return await zip.generateAsync({
1619
+ type: exportType,
1620
+ compression,
1621
+ compressionOptions: compression === "DEFLATE" ? { level: 6 } : void 0
1622
+ });
1623
+ }
1624
+ async exportFromCollaborativeDocx(docx, updatedDocs, media, fonts) {
1625
+ const zip = new import_jszip_min.default();
1626
+ for (const file of docx) {
1627
+ const content = file.content;
1628
+ zip.file(file.name, content);
1629
+ }
1630
+ Object.keys(updatedDocs).forEach((key) => {
1631
+ const content = updatedDocs[key];
1632
+ zip.file(key, content);
1633
+ });
1634
+ Object.keys(media).forEach((path) => {
1635
+ const value = media[path];
1636
+ const binaryData = typeof value === "string" ? require_helpers.base64ToUint8Array(value) : value;
1637
+ zip.file(path, binaryData);
1638
+ });
1639
+ for (const [fontName, fontUintArray] of Object.entries(fonts)) zip.file(fontName, fontUintArray);
1640
+ await this.updateContentTypes(zip, media, false, updatedDocs);
1641
+ return zip;
1642
+ }
1643
+ async exportFromOriginalFile(originalDocxFile, updatedDocs, media) {
1644
+ const unzippedOriginalDocx = await this.unzip(originalDocxFile);
1645
+ const filePromises = [];
1646
+ unzippedOriginalDocx.forEach((relativePath, zipEntry) => {
1647
+ const promise = zipEntry.async("string").then((content) => {
1648
+ unzippedOriginalDocx.file(zipEntry.name, content);
1649
+ });
1650
+ filePromises.push(promise);
1651
+ });
1652
+ await Promise.all(filePromises);
1653
+ Object.keys(updatedDocs).forEach((key) => {
1654
+ unzippedOriginalDocx.file(key, updatedDocs[key]);
1655
+ });
1656
+ Object.keys(media).forEach((path) => {
1657
+ unzippedOriginalDocx.file(path, media[path]);
1658
+ });
1659
+ await this.updateContentTypes(unzippedOriginalDocx, media, false, updatedDocs);
1660
+ return unzippedOriginalDocx;
1653
1661
  }
1654
- }
1655
- var componentToHex = (val) => {
1656
- const a = Number(val).toString(16);
1657
- return a.length === 1 ? "0" + a : a;
1658
- };
1659
- var rgbToHex = (rgb) => {
1660
- return "#" + rgb.match(/\d+/g).map(componentToHex).join("");
1661
- };
1662
- var DEFAULT_SHADING_FOREGROUND_COLOR = "#000000";
1663
- var hexToRgb = (hex) => {
1664
- const normalized = normalizeHexColor(hex);
1665
- if (!normalized) return null;
1666
- return {
1667
- r: Number.parseInt(normalized.slice(0, 2), 16),
1668
- g: Number.parseInt(normalized.slice(2, 4), 16),
1669
- b: Number.parseInt(normalized.slice(4, 6), 16)
1670
- };
1671
- };
1672
- var clamp01 = (value) => {
1673
- if (!Number.isFinite(value)) return 0;
1674
- return Math.min(1, Math.max(0, value));
1675
1662
  };
1676
- var blendHexColors = (backgroundHex, foregroundHex, foregroundRatio) => {
1677
- const background = hexToRgb(backgroundHex);
1678
- const foreground = hexToRgb(foregroundHex);
1679
- if (!background || !foreground) return null;
1680
- const ratio = clamp01(foregroundRatio);
1681
- const r = Math.round(background.r * (1 - ratio) + foreground.r * ratio);
1682
- const g = Math.round(background.g * (1 - ratio) + foreground.g * ratio);
1683
- const b = Math.round(background.b * (1 - ratio) + foreground.b * ratio);
1684
- const toByte = (n) => n.toString(16).padStart(2, "0").toUpperCase();
1685
- return `${toByte(r)}${toByte(g)}${toByte(b)}`;
1686
- };
1687
- var resolveShadingFillColor = (shading) => {
1688
- if (!shading || typeof shading !== "object") return null;
1689
- const fill = normalizeHexColor(shading.fill);
1690
- if (!fill) return null;
1691
- const pctMatch = (typeof shading.val === "string" ? shading.val.trim().toLowerCase() : "").match(/^pct(\d{1,3})$/);
1692
- if (!pctMatch) return fill;
1693
- const pct = Number.parseInt(pctMatch[1], 10);
1694
- if (!Number.isFinite(pct) || pct < 0 || pct > 100) return fill;
1695
- return blendHexColors(fill, normalizeHexColor(shading.color) ?? DEFAULT_SHADING_FOREGROUND_COLOR, pct / 100) ?? fill;
1696
- };
1697
- var deobfuscateFont = (arrayBuffer, guidHex) => {
1698
- const dta = new Uint8Array(arrayBuffer);
1699
- const guidStr = guidHex.replace(/[-{}]/g, "");
1700
- if (guidStr.length !== 32) {
1701
- console.error("Invalid GUID");
1702
- return;
1703
- }
1704
- const guidBytes = new Uint8Array(16);
1705
- for (let i$1 = 0, j = 0; i$1 < 32; i$1 += 2, j++) {
1706
- const hexByte = guidStr[i$1] + guidStr[i$1 + 1];
1707
- guidBytes[j] = parseInt(hexByte, 16);
1708
- }
1709
- for (let i$1 = 0; i$1 < 32; i$1++) {
1710
- const gi = 15 - i$1 % 16;
1711
- dta[i$1] ^= guidBytes[gi];
1712
- }
1713
- return dta.buffer;
1714
- };
1715
- function convertSizeToCSS(value, type) {
1716
- if (typeof value === "string" && value.endsWith("%")) type = "pct";
1717
- if (value === null || value === void 0) value = 0;
1718
- switch (type) {
1719
- case "dxa":
1720
- case null:
1721
- case void 0: return `${twipsToPixels(value)}px`;
1722
- case "nil": return "0";
1723
- case "auto": return null;
1724
- case "pct":
1725
- let percent;
1726
- if (typeof value === "number") percent = value * .02;
1727
- else if (value.endsWith("%")) percent = parseFloat(value.slice(0, -1));
1728
- else percent = parseFloat(value) * .02;
1729
- return `${percent}%`;
1730
- default: return null;
1731
- }
1732
- }
1663
+ var DocxZipper_default = DocxZipper;
1733
1664
  Object.defineProperty(exports, "Buffer", {
1734
1665
  enumerable: true,
1735
1666
  get: function() {
1736
1667
  return Buffer;
1737
1668
  }
1738
1669
  });
1739
- Object.defineProperty(exports, "convertSizeToCSS", {
1740
- enumerable: true,
1741
- get: function() {
1742
- return convertSizeToCSS;
1743
- }
1744
- });
1745
- Object.defineProperty(exports, "degreesToRot", {
1746
- enumerable: true,
1747
- get: function() {
1748
- return degreesToRot;
1749
- }
1750
- });
1751
- Object.defineProperty(exports, "deobfuscateFont", {
1752
- enumerable: true,
1753
- get: function() {
1754
- return deobfuscateFont;
1755
- }
1756
- });
1757
- Object.defineProperty(exports, "eighthPointsToPixels", {
1758
- enumerable: true,
1759
- get: function() {
1760
- return eighthPointsToPixels;
1761
- }
1762
- });
1763
- Object.defineProperty(exports, "emuToPixels", {
1764
- enumerable: true,
1765
- get: function() {
1766
- return emuToPixels;
1767
- }
1768
- });
1769
- Object.defineProperty(exports, "getArrayBufferFromUrl", {
1770
- enumerable: true,
1771
- get: function() {
1772
- return getArrayBufferFromUrl;
1773
- }
1774
- });
1775
- Object.defineProperty(exports, "getContentTypesFromXml", {
1776
- enumerable: true,
1777
- get: function() {
1778
- return getContentTypesFromXml;
1779
- }
1780
- });
1781
- Object.defineProperty(exports, "getDocxHighlightKeywordFromHex", {
1782
- enumerable: true,
1783
- get: function() {
1784
- return getDocxHighlightKeywordFromHex;
1785
- }
1786
- });
1787
- Object.defineProperty(exports, "getHexColorFromDocxSystem", {
1788
- enumerable: true,
1789
- get: function() {
1790
- return getHexColorFromDocxSystem;
1791
- }
1792
- });
1793
- Object.defineProperty(exports, "halfPointToPoints", {
1794
- enumerable: true,
1795
- get: function() {
1796
- return halfPointToPoints;
1797
- }
1798
- });
1799
- Object.defineProperty(exports, "inchesToPixels", {
1800
- enumerable: true,
1801
- get: function() {
1802
- return inchesToPixels;
1803
- }
1804
- });
1805
- Object.defineProperty(exports, "inchesToTwips", {
1806
- enumerable: true,
1807
- get: function() {
1808
- return inchesToTwips;
1809
- }
1810
- });
1811
- Object.defineProperty(exports, "isValidHexColor", {
1812
- enumerable: true,
1813
- get: function() {
1814
- return isValidHexColor;
1815
- }
1816
- });
1817
- Object.defineProperty(exports, "linesToTwips", {
1818
- enumerable: true,
1819
- get: function() {
1820
- return linesToTwips;
1821
- }
1822
- });
1823
- Object.defineProperty(exports, "normalizeHexColor", {
1824
- enumerable: true,
1825
- get: function() {
1826
- return normalizeHexColor;
1827
- }
1828
- });
1829
- Object.defineProperty(exports, "objToPolygon", {
1830
- enumerable: true,
1831
- get: function() {
1832
- return objToPolygon;
1833
- }
1834
- });
1835
- Object.defineProperty(exports, "pixelsToEightPoints", {
1836
- enumerable: true,
1837
- get: function() {
1838
- return pixelsToEightPoints;
1839
- }
1840
- });
1841
- Object.defineProperty(exports, "pixelsToEmu", {
1842
- enumerable: true,
1843
- get: function() {
1844
- return pixelsToEmu;
1845
- }
1846
- });
1847
- Object.defineProperty(exports, "pixelsToTwips", {
1848
- enumerable: true,
1849
- get: function() {
1850
- return pixelsToTwips;
1851
- }
1852
- });
1853
- Object.defineProperty(exports, "pointsToTwips", {
1854
- enumerable: true,
1855
- get: function() {
1856
- return pointsToTwips;
1857
- }
1858
- });
1859
- Object.defineProperty(exports, "polygonToObj", {
1860
- enumerable: true,
1861
- get: function() {
1862
- return polygonToObj;
1863
- }
1864
- });
1865
- Object.defineProperty(exports, "ptToTwips", {
1866
- enumerable: true,
1867
- get: function() {
1868
- return ptToTwips;
1869
- }
1870
- });
1871
- Object.defineProperty(exports, "resolveOpcTargetPath", {
1872
- enumerable: true,
1873
- get: function() {
1874
- return resolveOpcTargetPath;
1875
- }
1876
- });
1877
- Object.defineProperty(exports, "resolveShadingFillColor", {
1878
- enumerable: true,
1879
- get: function() {
1880
- return resolveShadingFillColor;
1881
- }
1882
- });
1883
- Object.defineProperty(exports, "rgbToHex", {
1884
- enumerable: true,
1885
- get: function() {
1886
- return rgbToHex;
1887
- }
1888
- });
1889
- Object.defineProperty(exports, "rotToDegrees", {
1890
- enumerable: true,
1891
- get: function() {
1892
- return rotToDegrees;
1893
- }
1894
- });
1895
- Object.defineProperty(exports, "twipsToInches", {
1896
- enumerable: true,
1897
- get: function() {
1898
- return twipsToInches;
1899
- }
1900
- });
1901
- Object.defineProperty(exports, "twipsToLines", {
1902
- enumerable: true,
1903
- get: function() {
1904
- return twipsToLines;
1905
- }
1906
- });
1907
- Object.defineProperty(exports, "twipsToPixels", {
1908
- enumerable: true,
1909
- get: function() {
1910
- return twipsToPixels;
1911
- }
1912
- });
1913
- Object.defineProperty(exports, "twipsToPt", {
1670
+ Object.defineProperty(exports, "DocxZipper_default", {
1914
1671
  enumerable: true,
1915
1672
  get: function() {
1916
- return twipsToPt;
1673
+ return DocxZipper_default;
1917
1674
  }
1918
1675
  });