@yinyoudexing/xml2word 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -104,8 +104,11 @@ fs.writeFileSync("out.docx", buf);
104
104
 
105
105
  ## HTML 支持范围(当前版本)
106
106
 
107
- - 支持:`p/span/strong/br`、`h1~h6`、`ul/ol/li`、`table/tr/td/th`
108
- - 支持:`text-align`、`font-size(pt/px)`、`color(rgb/#)`、`font-family`
107
+ - 支持:`div/p/span/strong/em/u/br`、`h1~h6`、`ul/ol/li`、`table/tr/td/th`
108
+ - 支持:`img(src=dataURL)`、`canvas(data-image=dataURL)`
109
+ - 支持:`text-align`、`vertical-align`、`font-size(pt/px)`、`color(rgb/#)`、`font-family`
110
+ - 支持:`background-color/background`(段落/单元格底色)、`white-space: nowrap`(表格单元格)
111
+ - 支持:表格边框(solid/dashed/dotted/double)、表格按内容估算列宽
109
112
  - 支持分页标记(会插入 Word 分页符):
110
113
  - `<div class="page-break"></div>`
111
114
  - `<hr class="page-break" />`
@@ -113,6 +116,6 @@ fs.writeFileSync("out.docx", buf);
113
116
  - 会跳过:`canvas`、编辑器辅助 DOM(如 ProseMirror widget)
114
117
 
115
118
  限制(需要额外实现才能完全还原):
116
- - 图片:HTML `<img>` 需要额外提供图片二进制并写入 docx 的 media 关系
119
+ - CSS 选择器:不解析 `<style>`,只读取标签上的 `style=""` 行内样式
117
120
  - 复杂 CSS:比如浮动/定位/复杂布局无法直接映射到 Word
118
121
  - 精准“自动分页”:如果需要指定分页位置,请在 HTML 中插入分页标记
@@ -22,10 +22,9 @@ ${bodyXml}
22
22
  <w:sectPr>
23
23
  <w:headerReference w:type="default" r:id="rId6"/>
24
24
  <w:footerReference w:type="default" r:id="rId7"/>
25
- <w:pgSz w:w="12240" w:h="15840"/>
25
+ <w:pgSz w:w="11906" w:h="16838"/>
26
26
  <w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="708" w:footer="708" w:gutter="0"/>
27
27
  <w:cols w:space="708"/>
28
- <w:docGrid w:linePitch="360"/>
29
28
  </w:sectPr>
30
29
  </w:body>
31
30
  </w:document>
@@ -497,4 +496,4 @@ export {
497
496
  createDocxZipUint8Array,
498
497
  createDocxZipWithAssetsUint8Array
499
498
  };
500
- //# sourceMappingURL=createDocxZip-BWHSZ7VQ.js.map
499
+ //# sourceMappingURL=createDocxZip-5CCNW5LX.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/createDocxZip.ts","../src/lib/normalizeDocumentXml.ts","../src/lib/validateXml.ts"],"sourcesContent":["import JSZip from \"jszip\";\nimport type { XmlToDocxOptions } from \"../index.js\";\nimport { normalizeDocumentXml } from \"./normalizeDocumentXml.js\";\nimport { validateXmlIfNeeded } from \"./validateXml.js\";\n\nexport type DocxAsset = {\n relationshipId: string;\n relationshipType: string;\n target: string;\n data: Uint8Array;\n contentType?: string;\n};\n\nconst STYLES_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:styles xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n <w:docDefaults>\n <w:rPrDefault>\n <w:rPr>\n <w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:eastAsia=\"FangSong_GB2312\" w:cs=\"Times New Roman\"/>\n <w:sz w:val=\"28\"/>\n <w:szCs w:val=\"28\"/>\n <w:lang w:val=\"en-US\" w:eastAsia=\"zh-CN\"/>\n </w:rPr>\n </w:rPrDefault>\n <w:pPrDefault>\n <w:pPr>\n <w:spacing w:before=\"0\" w:after=\"160\" w:line=\"360\" w:lineRule=\"auto\"/>\n </w:pPr>\n </w:pPrDefault>\n </w:docDefaults>\n\n <w:style w:type=\"paragraph\" w:default=\"1\" w:styleId=\"Normal\">\n <w:name w:val=\"Normal\"/>\n <w:qFormat/>\n <w:pPr>\n <w:spacing w:before=\"0\" w:after=\"160\" w:line=\"360\" w:lineRule=\"auto\"/>\n </w:pPr>\n <w:rPr>\n <w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:eastAsia=\"FangSong_GB2312\" w:cs=\"Times New Roman\"/>\n <w:sz w:val=\"28\"/>\n <w:szCs w:val=\"28\"/>\n </w:rPr>\n </w:style>\n\n <w:style w:type=\"paragraph\" w:styleId=\"Heading1\">\n <w:name w:val=\"heading 1\"/>\n <w:basedOn w:val=\"Normal\"/>\n <w:next w:val=\"Normal\"/>\n <w:uiPriority w:val=\"9\"/>\n <w:qFormat/>\n <w:pPr>\n <w:keepNext/>\n <w:keepLines/>\n <w:outlineLvl w:val=\"0\"/>\n <w:spacing w:before=\"240\" w:after=\"120\" w:line=\"360\" w:lineRule=\"auto\"/>\n </w:pPr>\n <w:rPr>\n <w:b/>\n <w:sz w:val=\"44\"/>\n <w:szCs w:val=\"44\"/>\n </w:rPr>\n </w:style>\n\n <w:style w:type=\"paragraph\" w:styleId=\"Heading2\">\n <w:name w:val=\"heading 2\"/>\n <w:basedOn w:val=\"Normal\"/>\n <w:next w:val=\"Normal\"/>\n <w:uiPriority w:val=\"9\"/>\n <w:qFormat/>\n <w:pPr>\n <w:keepNext/>\n <w:keepLines/>\n <w:outlineLvl w:val=\"1\"/>\n <w:spacing w:before=\"200\" w:after=\"100\" w:line=\"360\" w:lineRule=\"auto\"/>\n </w:pPr>\n <w:rPr>\n <w:b/>\n <w:sz w:val=\"32\"/>\n <w:szCs w:val=\"32\"/>\n </w:rPr>\n </w:style>\n\n <w:style w:type=\"paragraph\" w:styleId=\"Heading3\">\n <w:name w:val=\"heading 3\"/>\n <w:basedOn w:val=\"Normal\"/>\n <w:next w:val=\"Normal\"/>\n <w:uiPriority w:val=\"9\"/>\n <w:qFormat/>\n <w:pPr>\n <w:keepNext/>\n <w:keepLines/>\n <w:outlineLvl w:val=\"2\"/>\n <w:spacing w:before=\"180\" w:after=\"90\" w:line=\"360\" w:lineRule=\"auto\"/>\n </w:pPr>\n <w:rPr>\n <w:b/>\n <w:sz w:val=\"28\"/>\n <w:szCs w:val=\"28\"/>\n </w:rPr>\n </w:style>\n\n <w:style w:type=\"paragraph\" w:styleId=\"Heading4\">\n <w:name w:val=\"heading 4\"/>\n <w:basedOn w:val=\"Normal\"/>\n <w:next w:val=\"Normal\"/>\n <w:uiPriority w:val=\"9\"/>\n <w:qFormat/>\n <w:pPr>\n <w:keepNext/>\n <w:keepLines/>\n <w:outlineLvl w:val=\"3\"/>\n <w:spacing w:before=\"160\" w:after=\"80\" w:line=\"360\" w:lineRule=\"auto\"/>\n </w:pPr>\n <w:rPr>\n <w:b/>\n <w:sz w:val=\"24\"/>\n <w:szCs w:val=\"24\"/>\n </w:rPr>\n </w:style>\n\n <w:style w:type=\"paragraph\" w:styleId=\"Heading5\">\n <w:name w:val=\"heading 5\"/>\n <w:basedOn w:val=\"Normal\"/>\n <w:next w:val=\"Normal\"/>\n <w:uiPriority w:val=\"9\"/>\n <w:qFormat/>\n <w:pPr>\n <w:keepNext/>\n <w:keepLines/>\n <w:outlineLvl w:val=\"4\"/>\n <w:spacing w:before=\"140\" w:after=\"70\" w:line=\"360\" w:lineRule=\"auto\"/>\n </w:pPr>\n <w:rPr>\n <w:b/>\n <w:sz w:val=\"22\"/>\n <w:szCs w:val=\"22\"/>\n </w:rPr>\n </w:style>\n\n <w:style w:type=\"paragraph\" w:styleId=\"Heading6\">\n <w:name w:val=\"heading 6\"/>\n <w:basedOn w:val=\"Normal\"/>\n <w:next w:val=\"Normal\"/>\n <w:uiPriority w:val=\"9\"/>\n <w:qFormat/>\n <w:pPr>\n <w:keepNext/>\n <w:keepLines/>\n <w:outlineLvl w:val=\"5\"/>\n <w:spacing w:before=\"120\" w:after=\"60\" w:line=\"360\" w:lineRule=\"auto\"/>\n </w:pPr>\n <w:rPr>\n <w:b/>\n <w:sz w:val=\"22\"/>\n <w:szCs w:val=\"22\"/>\n </w:rPr>\n </w:style>\n</w:styles>\n`;\n\nconst SETTINGS_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:settings xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n <w:themeFontLang w:val=\"en-US\" w:eastAsia=\"zh-CN\"/>\n <w:defaultTabStop w:val=\"720\"/>\n <w:compat/>\n</w:settings>\n`;\n\nconst NUMBERING_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:numbering xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n <w:abstractNum w:abstractNumId=\"1\">\n <w:multiLevelType w:val=\"hybridMultilevel\"/>\n <w:lvl w:ilvl=\"0\">\n <w:start w:val=\"1\"/>\n <w:numFmt w:val=\"bullet\"/>\n <w:lvlText w:val=\"•\"/>\n <w:lvlJc w:val=\"left\"/>\n <w:pPr><w:ind w:left=\"720\" w:hanging=\"360\"/></w:pPr>\n <w:rPr><w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:eastAsia=\"FangSong_GB2312\" w:cs=\"Times New Roman\"/></w:rPr>\n </w:lvl>\n <w:lvl w:ilvl=\"1\">\n <w:start w:val=\"1\"/>\n <w:numFmt w:val=\"bullet\"/>\n <w:lvlText w:val=\"○\"/>\n <w:lvlJc w:val=\"left\"/>\n <w:pPr><w:ind w:left=\"1440\" w:hanging=\"360\"/></w:pPr>\n <w:rPr><w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:eastAsia=\"FangSong_GB2312\" w:cs=\"Times New Roman\"/></w:rPr>\n </w:lvl>\n <w:lvl w:ilvl=\"2\">\n <w:start w:val=\"1\"/>\n <w:numFmt w:val=\"bullet\"/>\n <w:lvlText w:val=\"■\"/>\n <w:lvlJc w:val=\"left\"/>\n <w:pPr><w:ind w:left=\"2160\" w:hanging=\"360\"/></w:pPr>\n <w:rPr><w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:eastAsia=\"FangSong_GB2312\" w:cs=\"Times New Roman\"/></w:rPr>\n </w:lvl>\n </w:abstractNum>\n <w:abstractNum w:abstractNumId=\"2\">\n <w:multiLevelType w:val=\"hybridMultilevel\"/>\n <w:lvl w:ilvl=\"0\">\n <w:start w:val=\"1\"/>\n <w:numFmt w:val=\"decimal\"/>\n <w:lvlText w:val=\"%1.\"/>\n <w:lvlJc w:val=\"left\"/>\n <w:pPr><w:ind w:left=\"720\" w:hanging=\"360\"/></w:pPr>\n <w:rPr><w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:eastAsia=\"FangSong_GB2312\" w:cs=\"Times New Roman\"/></w:rPr>\n </w:lvl>\n <w:lvl w:ilvl=\"1\">\n <w:start w:val=\"1\"/>\n <w:numFmt w:val=\"decimal\"/>\n <w:lvlText w:val=\"%1.%2.\"/>\n <w:lvlJc w:val=\"left\"/>\n <w:pPr><w:ind w:left=\"1440\" w:hanging=\"360\"/></w:pPr>\n <w:rPr><w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:eastAsia=\"FangSong_GB2312\" w:cs=\"Times New Roman\"/></w:rPr>\n </w:lvl>\n <w:lvl w:ilvl=\"2\">\n <w:start w:val=\"1\"/>\n <w:numFmt w:val=\"decimal\"/>\n <w:lvlText w:val=\"%1.%2.%3.\"/>\n <w:lvlJc w:val=\"left\"/>\n <w:pPr><w:ind w:left=\"2160\" w:hanging=\"360\"/></w:pPr>\n <w:rPr><w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:eastAsia=\"FangSong_GB2312\" w:cs=\"Times New Roman\"/></w:rPr>\n </w:lvl>\n </w:abstractNum>\n <w:num w:numId=\"1\"><w:abstractNumId w:val=\"1\"/></w:num>\n <w:num w:numId=\"2\"><w:abstractNumId w:val=\"2\"/></w:num>\n</w:numbering>\n`;\n\nconst HEADER1_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:hdr xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">\n <w:p>\n <w:pPr><w:jc w:val=\"center\"/></w:pPr>\n <w:r><w:t></w:t></w:r>\n </w:p>\n</w:hdr>\n`;\n\nconst FOOTER1_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:ftr xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">\n <w:p>\n <w:pPr><w:jc w:val=\"right\"/></w:pPr>\n <w:r><w:t>第 </w:t></w:r>\n <w:r><w:fldChar w:fldCharType=\"begin\"/></w:r>\n <w:r><w:instrText xml:space=\"preserve\"> PAGE </w:instrText></w:r>\n <w:r><w:fldChar w:fldCharType=\"separate\"/></w:r>\n <w:r><w:t>1</w:t></w:r>\n <w:r><w:fldChar w:fldCharType=\"end\"/></w:r>\n <w:r><w:t> 页 / 共 </w:t></w:r>\n <w:r><w:fldChar w:fldCharType=\"begin\"/></w:r>\n <w:r><w:instrText xml:space=\"preserve\"> NUMPAGES </w:instrText></w:r>\n <w:r><w:fldChar w:fldCharType=\"separate\"/></w:r>\n <w:r><w:t>1</w:t></w:r>\n <w:r><w:fldChar w:fldCharType=\"end\"/></w:r>\n <w:r><w:t> 页</w:t></w:r>\n </w:p>\n</w:ftr>\n`;\n\nconst THEME_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<a:theme xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" name=\"Office Theme\">\n <a:themeElements>\n <a:clrScheme name=\"Office\">\n <a:dk1><a:sysClr val=\"windowText\" lastClr=\"000000\"/></a:dk1>\n <a:lt1><a:sysClr val=\"window\" lastClr=\"FFFFFF\"/></a:lt1>\n <a:dk2><a:srgbClr val=\"1F497D\"/></a:dk2>\n <a:lt2><a:srgbClr val=\"EEECE1\"/></a:lt2>\n <a:accent1><a:srgbClr val=\"4F81BD\"/></a:accent1>\n <a:accent2><a:srgbClr val=\"C0504D\"/></a:accent2>\n <a:accent3><a:srgbClr val=\"9BBB59\"/></a:accent3>\n <a:accent4><a:srgbClr val=\"8064A2\"/></a:accent4>\n <a:accent5><a:srgbClr val=\"4BACC6\"/></a:accent5>\n <a:accent6><a:srgbClr val=\"F79646\"/></a:accent6>\n <a:hlink><a:srgbClr val=\"0000FF\"/></a:hlink>\n <a:folHlink><a:srgbClr val=\"800080\"/></a:folHlink>\n </a:clrScheme>\n <a:fontScheme name=\"Office\">\n <a:majorFont>\n <a:latin typeface=\"Times New Roman\"/>\n <a:ea typeface=\"FangSong_GB2312\"/>\n <a:cs typeface=\"Times New Roman\"/>\n </a:majorFont>\n <a:minorFont>\n <a:latin typeface=\"Times New Roman\"/>\n <a:ea typeface=\"FangSong_GB2312\"/>\n <a:cs typeface=\"Times New Roman\"/>\n </a:minorFont>\n </a:fontScheme>\n <a:fmtScheme name=\"Office\">\n <a:fillStyleLst>\n <a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n <a:gradFill rotWithShape=\"1\"><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"/></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"/></a:gs></a:gsLst><a:lin ang=\"16200000\" scaled=\"1\"/></a:gradFill>\n <a:gradFill rotWithShape=\"1\"><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"/></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"/></a:gs></a:gsLst><a:lin ang=\"16200000\" scaled=\"1\"/></a:gradFill>\n </a:fillStyleLst>\n <a:lnStyleLst>\n <a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:prstDash val=\"solid\"/></a:ln>\n <a:ln w=\"25400\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:prstDash val=\"solid\"/></a:ln>\n <a:ln w=\"38100\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:prstDash val=\"solid\"/></a:ln>\n </a:lnStyleLst>\n <a:effectStyleLst>\n <a:effectStyle><a:effectLst/></a:effectStyle>\n <a:effectStyle><a:effectLst/></a:effectStyle>\n <a:effectStyle><a:effectLst/></a:effectStyle>\n </a:effectStyleLst>\n <a:bgFillStyleLst>\n <a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n <a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n <a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n </a:bgFillStyleLst>\n </a:fmtScheme>\n </a:themeElements>\n <a:objectDefaults/>\n <a:extraClrSchemeLst/>\n</a:theme>\n`;\n\nconst FONT_TABLE_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:fonts xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n <w:font w:name=\"Times New Roman\">\n <w:charset w:val=\"00\"/>\n <w:family w:val=\"roman\"/>\n <w:pitch w:val=\"variable\"/>\n </w:font>\n <w:font w:name=\"FangSong_GB2312\">\n <w:charset w:val=\"86\"/>\n <w:family w:val=\"auto\"/>\n <w:pitch w:val=\"variable\"/>\n </w:font>\n</w:fonts>\n`;\n\nfunction buildContentTypesXml(assets: DocxAsset[]): string {\n const defaults = new Map<string, string>();\n defaults.set(\"rels\", \"application/vnd.openxmlformats-package.relationships+xml\");\n defaults.set(\"xml\", \"application/xml\");\n\n for (const asset of assets) {\n if (!asset.contentType) continue;\n const extMatch = asset.target.match(/\\.([a-zA-Z0-9]+)$/);\n if (!extMatch) continue;\n const ext = extMatch[1].toLowerCase();\n defaults.set(ext, asset.contentType);\n }\n\n const defaultLines = [...defaults.entries()]\n .sort((a, b) => a[0].localeCompare(b[0]))\n .map(([ext, ct]) => ` <Default Extension=\"${ext}\" ContentType=\"${ct}\"/>`)\n .join(\"\\n\");\n\n const overrides = [\n ' <Override PartName=\"/word/document.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"/>',\n ' <Override PartName=\"/word/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\"/>',\n ' <Override PartName=\"/word/settings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml\"/>',\n ' <Override PartName=\"/word/theme/theme1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.theme+xml\"/>',\n ' <Override PartName=\"/word/fontTable.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml\"/>',\n ' <Override PartName=\"/word/numbering.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml\"/>',\n ' <Override PartName=\"/word/header1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml\"/>',\n ' <Override PartName=\"/word/footer1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml\"/>',\n ].join(\"\\n\");\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\\n${defaultLines}\\n${overrides}\\n</Types>\\n`;\n}\n\nconst ROOT_RELS_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\"\n Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\"\n Target=\"word/document.xml\"/>\n</Relationships>\n`;\n\nfunction buildDocumentRelsXml(assets: DocxAsset[]): string {\n const relLines = [\n ' <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>',\n ' <Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/>',\n ' <Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\" Target=\"theme/theme1.xml\"/>',\n ' <Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable\" Target=\"fontTable.xml\"/>',\n ' <Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/>',\n ' <Relationship Id=\"rId6\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header\" Target=\"header1.xml\"/>',\n ' <Relationship Id=\"rId7\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer\" Target=\"footer1.xml\"/>',\n ...assets.map(\n (a) =>\n ` <Relationship Id=\"${a.relationshipId}\" Type=\"${a.relationshipType}\" Target=\"${a.target}\"/>`,\n ),\n ].join(\"\\n\");\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\\n${relLines}\\n</Relationships>\\n`;\n}\n\nexport async function createDocxZipUint8Array(\n xml: string,\n options: XmlToDocxOptions = {},\n): Promise<Uint8Array> {\n const documentXml = normalizeDocumentXml(xml, options.inputKind ?? \"auto\");\n validateXmlIfNeeded(documentXml, options.validateXml ?? true);\n\n const zip = new JSZip();\n zip.file(\"[Content_Types].xml\", buildContentTypesXml([]));\n\n const relsFolder = zip.folder(\"_rels\");\n relsFolder?.file(\".rels\", ROOT_RELS_XML);\n\n const wordFolder = zip.folder(\"word\");\n wordFolder?.file(\"document.xml\", documentXml);\n wordFolder?.file(\"styles.xml\", STYLES_XML);\n wordFolder?.file(\"settings.xml\", SETTINGS_XML);\n wordFolder?.file(\"fontTable.xml\", FONT_TABLE_XML);\n wordFolder?.folder(\"theme\")?.file(\"theme1.xml\", THEME_XML);\n wordFolder?.file(\"numbering.xml\", NUMBERING_XML);\n wordFolder?.file(\"header1.xml\", HEADER1_XML);\n wordFolder?.file(\"footer1.xml\", FOOTER1_XML);\n\n const wordRelsFolder = wordFolder?.folder(\"_rels\");\n wordRelsFolder?.file(\"document.xml.rels\", buildDocumentRelsXml([]));\n\n return zip.generateAsync({ type: \"uint8array\" });\n}\n\nexport async function createDocxZipWithAssetsUint8Array(\n xml: string,\n options: XmlToDocxOptions,\n assets: DocxAsset[],\n): Promise<Uint8Array> {\n const documentXml = normalizeDocumentXml(xml, options.inputKind ?? \"auto\");\n validateXmlIfNeeded(documentXml, options.validateXml ?? true);\n\n const zip = new JSZip();\n zip.file(\"[Content_Types].xml\", buildContentTypesXml(assets));\n\n const relsFolder = zip.folder(\"_rels\");\n relsFolder?.file(\".rels\", ROOT_RELS_XML);\n\n const wordFolder = zip.folder(\"word\");\n wordFolder?.file(\"document.xml\", documentXml);\n wordFolder?.file(\"styles.xml\", STYLES_XML);\n wordFolder?.file(\"settings.xml\", SETTINGS_XML);\n wordFolder?.file(\"fontTable.xml\", FONT_TABLE_XML);\n wordFolder?.folder(\"theme\")?.file(\"theme1.xml\", THEME_XML);\n wordFolder?.file(\"numbering.xml\", NUMBERING_XML);\n wordFolder?.file(\"header1.xml\", HEADER1_XML);\n wordFolder?.file(\"footer1.xml\", FOOTER1_XML);\n\n const wordRelsFolder = wordFolder?.folder(\"_rels\");\n wordRelsFolder?.file(\"document.xml.rels\", buildDocumentRelsXml(assets));\n\n if (assets.length) {\n for (const asset of assets) {\n const targetPath = asset.target.replace(/^\\.\\//, \"\");\n const normalized = targetPath.startsWith(\"word/\") ? targetPath.slice(\"word/\".length) : targetPath;\n wordFolder?.file(normalized, asset.data);\n }\n }\n\n return zip.generateAsync({ type: \"uint8array\" });\n}\n","import type { XmlToDocxInputKind } from \"../index.js\";\n\nconst WORD_MAIN_NS = \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\";\n\nfunction hasWordDocumentRoot(xml: string): boolean {\n return /<w:document[\\s>]/.test(xml);\n}\n\nfunction ensureXmlDeclaration(xml: string): string {\n if (/^\\s*<\\?xml\\b/.test(xml)) return xml;\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n${xml}`;\n}\n\nfunction wrapBodyXml(bodyXml: string): string {\n const xml = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:document\n xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n>\n <w:body>\n${bodyXml}\n <w:sectPr>\n <w:headerReference w:type=\"default\" r:id=\"rId6\"/>\n <w:footerReference w:type=\"default\" r:id=\"rId7\"/>\n <w:pgSz w:w=\"12240\" w:h=\"15840\"/>\n <w:pgMar w:top=\"1440\" w:right=\"1440\" w:bottom=\"1440\" w:left=\"1440\" w:header=\"708\" w:footer=\"708\" w:gutter=\"0\"/>\n <w:cols w:space=\"708\"/>\n <w:docGrid w:linePitch=\"360\"/>\n </w:sectPr>\n </w:body>\n</w:document>\n`;\n return xml;\n}\n\nfunction ensureWordNamespace(xml: string): string {\n const hasWNamespace =\n /xmlns:w\\s*=\\s*[\"']http:\\/\\/schemas\\.openxmlformats\\.org\\/wordprocessingml\\/2006\\/main[\"']/.test(\n xml,\n );\n if (hasWNamespace) return xml;\n\n return xml.replace(\n /<w:document\\b/,\n `<w:document xmlns:w=\"${WORD_MAIN_NS}\"`,\n );\n}\n\nexport function normalizeDocumentXml(xml: string, inputKind: XmlToDocxInputKind): string {\n const trimmed = xml.trim();\n if (!trimmed) {\n throw new Error(\"XML is empty.\");\n }\n\n if (inputKind === \"document\") {\n const withDecl = ensureXmlDeclaration(trimmed);\n const withNs = ensureWordNamespace(withDecl);\n if (!hasWordDocumentRoot(withNs)) {\n throw new Error('inputKind=\"document\" requires a <w:document> root.');\n }\n return withNs;\n }\n\n if (inputKind === \"body\") {\n return wrapBodyXml(trimmed);\n }\n\n if (hasWordDocumentRoot(trimmed)) {\n const withDecl = ensureXmlDeclaration(trimmed);\n return ensureWordNamespace(withDecl);\n }\n\n return wrapBodyXml(trimmed);\n}\n","import { XMLValidator } from \"fast-xml-parser\";\n\nexport function validateXmlIfNeeded(xml: string, validateXml: boolean): void {\n if (!validateXml) return;\n\n const result = XMLValidator.validate(xml);\n if (result === true) return;\n\n const err = (result as { err?: { msg?: string; line?: number; col?: number } }).err;\n const msg = err?.msg ?? \"Invalid XML.\";\n const line = err?.line;\n const col = err?.col;\n\n const location =\n typeof line === \"number\" && typeof col === \"number\" ? ` (line ${line}, col ${col})` : \"\";\n throw new Error(`${msg}${location}`);\n}\n\n"],"mappings":";AAAA,OAAO,WAAW;;;ACElB,IAAM,eAAe;AAErB,SAAS,oBAAoB,KAAsB;AACjD,SAAO,mBAAmB,KAAK,GAAG;AACpC;AAEA,SAAS,qBAAqB,KAAqB;AACjD,MAAI,eAAe,KAAK,GAAG,EAAG,QAAO;AACrC,SAAO;AAAA,EAA4D,GAAG;AACxE;AAEA,SAAS,YAAY,SAAyB;AAC5C,QAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMZ,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYP,SAAO;AACT;AAEA,SAAS,oBAAoB,KAAqB;AAChD,QAAM,gBACJ,4FAA4F;AAAA,IAC1F;AAAA,EACF;AACF,MAAI,cAAe,QAAO;AAE1B,SAAO,IAAI;AAAA,IACT;AAAA,IACA,wBAAwB,YAAY;AAAA,EACtC;AACF;AAEO,SAAS,qBAAqB,KAAa,WAAuC;AACvF,QAAM,UAAU,IAAI,KAAK;AACzB,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,eAAe;AAAA,EACjC;AAEA,MAAI,cAAc,YAAY;AAC5B,UAAM,WAAW,qBAAqB,OAAO;AAC7C,UAAM,SAAS,oBAAoB,QAAQ;AAC3C,QAAI,CAAC,oBAAoB,MAAM,GAAG;AAChC,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AACA,WAAO;AAAA,EACT;AAEA,MAAI,cAAc,QAAQ;AACxB,WAAO,YAAY,OAAO;AAAA,EAC5B;AAEA,MAAI,oBAAoB,OAAO,GAAG;AAChC,UAAM,WAAW,qBAAqB,OAAO;AAC7C,WAAO,oBAAoB,QAAQ;AAAA,EACrC;AAEA,SAAO,YAAY,OAAO;AAC5B;;;ACzEA,SAAS,oBAAoB;AAEtB,SAAS,oBAAoB,KAAa,aAA4B;AAC3E,MAAI,CAAC,YAAa;AAElB,QAAM,SAAS,aAAa,SAAS,GAAG;AACxC,MAAI,WAAW,KAAM;AAErB,QAAM,MAAO,OAAmE;AAChF,QAAM,MAAM,KAAK,OAAO;AACxB,QAAM,OAAO,KAAK;AAClB,QAAM,MAAM,KAAK;AAEjB,QAAM,WACJ,OAAO,SAAS,YAAY,OAAO,QAAQ,WAAW,UAAU,IAAI,SAAS,GAAG,MAAM;AACxF,QAAM,IAAI,MAAM,GAAG,GAAG,GAAG,QAAQ,EAAE;AACrC;;;AFHA,IAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmJnB,IAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQrB,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6DtB,IAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASpB,IAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBpB,IAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyDlB,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAevB,SAAS,qBAAqB,QAA6B;AACzD,QAAM,WAAW,oBAAI,IAAoB;AACzC,WAAS,IAAI,QAAQ,0DAA0D;AAC/E,WAAS,IAAI,OAAO,iBAAiB;AAErC,aAAW,SAAS,QAAQ;AAC1B,QAAI,CAAC,MAAM,YAAa;AACxB,UAAM,WAAW,MAAM,OAAO,MAAM,mBAAmB;AACvD,QAAI,CAAC,SAAU;AACf,UAAM,MAAM,SAAS,CAAC,EAAE,YAAY;AACpC,aAAS,IAAI,KAAK,MAAM,WAAW;AAAA,EACrC;AAEA,QAAM,eAAe,CAAC,GAAG,SAAS,QAAQ,CAAC,EACxC,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EACvC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,yBAAyB,GAAG,kBAAkB,EAAE,KAAK,EACxE,KAAK,IAAI;AAEZ,QAAM,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AAEX,SAAO;AAAA;AAAA,EAA0I,YAAY;AAAA,EAAK,SAAS;AAAA;AAAA;AAC7K;AAEA,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQtB,SAAS,qBAAqB,QAA6B;AACzD,QAAM,WAAW;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG,OAAO;AAAA,MACR,CAAC,MACC,uBAAuB,EAAE,cAAc,WAAW,EAAE,gBAAgB,aAAa,EAAE,MAAM;AAAA,IAC7F;AAAA,EACF,EAAE,KAAK,IAAI;AACX,SAAO;AAAA;AAAA,EAAkJ,QAAQ;AAAA;AAAA;AACnK;AAEA,eAAsB,wBACpB,KACA,UAA4B,CAAC,GACR;AACrB,QAAM,cAAc,qBAAqB,KAAK,QAAQ,aAAa,MAAM;AACzE,sBAAoB,aAAa,QAAQ,eAAe,IAAI;AAE5D,QAAM,MAAM,IAAI,MAAM;AACtB,MAAI,KAAK,uBAAuB,qBAAqB,CAAC,CAAC,CAAC;AAExD,QAAM,aAAa,IAAI,OAAO,OAAO;AACrC,cAAY,KAAK,SAAS,aAAa;AAEvC,QAAM,aAAa,IAAI,OAAO,MAAM;AACpC,cAAY,KAAK,gBAAgB,WAAW;AAC5C,cAAY,KAAK,cAAc,UAAU;AACzC,cAAY,KAAK,gBAAgB,YAAY;AAC7C,cAAY,KAAK,iBAAiB,cAAc;AAChD,cAAY,OAAO,OAAO,GAAG,KAAK,cAAc,SAAS;AACzD,cAAY,KAAK,iBAAiB,aAAa;AAC/C,cAAY,KAAK,eAAe,WAAW;AAC3C,cAAY,KAAK,eAAe,WAAW;AAE3C,QAAM,iBAAiB,YAAY,OAAO,OAAO;AACjD,kBAAgB,KAAK,qBAAqB,qBAAqB,CAAC,CAAC,CAAC;AAElE,SAAO,IAAI,cAAc,EAAE,MAAM,aAAa,CAAC;AACjD;AAEA,eAAsB,kCACpB,KACA,SACA,QACqB;AACrB,QAAM,cAAc,qBAAqB,KAAK,QAAQ,aAAa,MAAM;AACzE,sBAAoB,aAAa,QAAQ,eAAe,IAAI;AAE5D,QAAM,MAAM,IAAI,MAAM;AACtB,MAAI,KAAK,uBAAuB,qBAAqB,MAAM,CAAC;AAE5D,QAAM,aAAa,IAAI,OAAO,OAAO;AACrC,cAAY,KAAK,SAAS,aAAa;AAEvC,QAAM,aAAa,IAAI,OAAO,MAAM;AACpC,cAAY,KAAK,gBAAgB,WAAW;AAC5C,cAAY,KAAK,cAAc,UAAU;AACzC,cAAY,KAAK,gBAAgB,YAAY;AAC7C,cAAY,KAAK,iBAAiB,cAAc;AAChD,cAAY,OAAO,OAAO,GAAG,KAAK,cAAc,SAAS;AACzD,cAAY,KAAK,iBAAiB,aAAa;AAC/C,cAAY,KAAK,eAAe,WAAW;AAC3C,cAAY,KAAK,eAAe,WAAW;AAE3C,QAAM,iBAAiB,YAAY,OAAO,OAAO;AACjD,kBAAgB,KAAK,qBAAqB,qBAAqB,MAAM,CAAC;AAEtE,MAAI,OAAO,QAAQ;AACjB,eAAW,SAAS,QAAQ;AAC1B,YAAM,aAAa,MAAM,OAAO,QAAQ,SAAS,EAAE;AACnD,YAAM,aAAa,WAAW,WAAW,OAAO,IAAI,WAAW,MAAM,QAAQ,MAAM,IAAI;AACvF,kBAAY,KAAK,YAAY,MAAM,IAAI;AAAA,IACzC;AAAA,EACF;AAEA,SAAO,IAAI,cAAc,EAAE,MAAM,aAAa,CAAC;AACjD;","names":[]}
1
+ {"version":3,"sources":["../src/lib/createDocxZip.ts","../src/lib/normalizeDocumentXml.ts","../src/lib/validateXml.ts"],"sourcesContent":["import JSZip from \"jszip\";\nimport type { XmlToDocxOptions } from \"../index.js\";\nimport { normalizeDocumentXml } from \"./normalizeDocumentXml.js\";\nimport { validateXmlIfNeeded } from \"./validateXml.js\";\n\nexport type DocxAsset = {\n relationshipId: string;\n relationshipType: string;\n target: string;\n data: Uint8Array;\n contentType?: string;\n};\n\nconst STYLES_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:styles xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n <w:docDefaults>\n <w:rPrDefault>\n <w:rPr>\n <w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:eastAsia=\"FangSong_GB2312\" w:cs=\"Times New Roman\"/>\n <w:sz w:val=\"28\"/>\n <w:szCs w:val=\"28\"/>\n <w:lang w:val=\"en-US\" w:eastAsia=\"zh-CN\"/>\n </w:rPr>\n </w:rPrDefault>\n <w:pPrDefault>\n <w:pPr>\n <w:spacing w:before=\"0\" w:after=\"160\" w:line=\"360\" w:lineRule=\"auto\"/>\n </w:pPr>\n </w:pPrDefault>\n </w:docDefaults>\n\n <w:style w:type=\"paragraph\" w:default=\"1\" w:styleId=\"Normal\">\n <w:name w:val=\"Normal\"/>\n <w:qFormat/>\n <w:pPr>\n <w:spacing w:before=\"0\" w:after=\"160\" w:line=\"360\" w:lineRule=\"auto\"/>\n </w:pPr>\n <w:rPr>\n <w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:eastAsia=\"FangSong_GB2312\" w:cs=\"Times New Roman\"/>\n <w:sz w:val=\"28\"/>\n <w:szCs w:val=\"28\"/>\n </w:rPr>\n </w:style>\n\n <w:style w:type=\"paragraph\" w:styleId=\"Heading1\">\n <w:name w:val=\"heading 1\"/>\n <w:basedOn w:val=\"Normal\"/>\n <w:next w:val=\"Normal\"/>\n <w:uiPriority w:val=\"9\"/>\n <w:qFormat/>\n <w:pPr>\n <w:keepNext/>\n <w:keepLines/>\n <w:outlineLvl w:val=\"0\"/>\n <w:spacing w:before=\"240\" w:after=\"120\" w:line=\"360\" w:lineRule=\"auto\"/>\n </w:pPr>\n <w:rPr>\n <w:b/>\n <w:sz w:val=\"44\"/>\n <w:szCs w:val=\"44\"/>\n </w:rPr>\n </w:style>\n\n <w:style w:type=\"paragraph\" w:styleId=\"Heading2\">\n <w:name w:val=\"heading 2\"/>\n <w:basedOn w:val=\"Normal\"/>\n <w:next w:val=\"Normal\"/>\n <w:uiPriority w:val=\"9\"/>\n <w:qFormat/>\n <w:pPr>\n <w:keepNext/>\n <w:keepLines/>\n <w:outlineLvl w:val=\"1\"/>\n <w:spacing w:before=\"200\" w:after=\"100\" w:line=\"360\" w:lineRule=\"auto\"/>\n </w:pPr>\n <w:rPr>\n <w:b/>\n <w:sz w:val=\"32\"/>\n <w:szCs w:val=\"32\"/>\n </w:rPr>\n </w:style>\n\n <w:style w:type=\"paragraph\" w:styleId=\"Heading3\">\n <w:name w:val=\"heading 3\"/>\n <w:basedOn w:val=\"Normal\"/>\n <w:next w:val=\"Normal\"/>\n <w:uiPriority w:val=\"9\"/>\n <w:qFormat/>\n <w:pPr>\n <w:keepNext/>\n <w:keepLines/>\n <w:outlineLvl w:val=\"2\"/>\n <w:spacing w:before=\"180\" w:after=\"90\" w:line=\"360\" w:lineRule=\"auto\"/>\n </w:pPr>\n <w:rPr>\n <w:b/>\n <w:sz w:val=\"28\"/>\n <w:szCs w:val=\"28\"/>\n </w:rPr>\n </w:style>\n\n <w:style w:type=\"paragraph\" w:styleId=\"Heading4\">\n <w:name w:val=\"heading 4\"/>\n <w:basedOn w:val=\"Normal\"/>\n <w:next w:val=\"Normal\"/>\n <w:uiPriority w:val=\"9\"/>\n <w:qFormat/>\n <w:pPr>\n <w:keepNext/>\n <w:keepLines/>\n <w:outlineLvl w:val=\"3\"/>\n <w:spacing w:before=\"160\" w:after=\"80\" w:line=\"360\" w:lineRule=\"auto\"/>\n </w:pPr>\n <w:rPr>\n <w:b/>\n <w:sz w:val=\"24\"/>\n <w:szCs w:val=\"24\"/>\n </w:rPr>\n </w:style>\n\n <w:style w:type=\"paragraph\" w:styleId=\"Heading5\">\n <w:name w:val=\"heading 5\"/>\n <w:basedOn w:val=\"Normal\"/>\n <w:next w:val=\"Normal\"/>\n <w:uiPriority w:val=\"9\"/>\n <w:qFormat/>\n <w:pPr>\n <w:keepNext/>\n <w:keepLines/>\n <w:outlineLvl w:val=\"4\"/>\n <w:spacing w:before=\"140\" w:after=\"70\" w:line=\"360\" w:lineRule=\"auto\"/>\n </w:pPr>\n <w:rPr>\n <w:b/>\n <w:sz w:val=\"22\"/>\n <w:szCs w:val=\"22\"/>\n </w:rPr>\n </w:style>\n\n <w:style w:type=\"paragraph\" w:styleId=\"Heading6\">\n <w:name w:val=\"heading 6\"/>\n <w:basedOn w:val=\"Normal\"/>\n <w:next w:val=\"Normal\"/>\n <w:uiPriority w:val=\"9\"/>\n <w:qFormat/>\n <w:pPr>\n <w:keepNext/>\n <w:keepLines/>\n <w:outlineLvl w:val=\"5\"/>\n <w:spacing w:before=\"120\" w:after=\"60\" w:line=\"360\" w:lineRule=\"auto\"/>\n </w:pPr>\n <w:rPr>\n <w:b/>\n <w:sz w:val=\"22\"/>\n <w:szCs w:val=\"22\"/>\n </w:rPr>\n </w:style>\n</w:styles>\n`;\n\nconst SETTINGS_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:settings xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n <w:themeFontLang w:val=\"en-US\" w:eastAsia=\"zh-CN\"/>\n <w:defaultTabStop w:val=\"720\"/>\n <w:compat/>\n</w:settings>\n`;\n\nconst NUMBERING_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:numbering xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n <w:abstractNum w:abstractNumId=\"1\">\n <w:multiLevelType w:val=\"hybridMultilevel\"/>\n <w:lvl w:ilvl=\"0\">\n <w:start w:val=\"1\"/>\n <w:numFmt w:val=\"bullet\"/>\n <w:lvlText w:val=\"•\"/>\n <w:lvlJc w:val=\"left\"/>\n <w:pPr><w:ind w:left=\"720\" w:hanging=\"360\"/></w:pPr>\n <w:rPr><w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:eastAsia=\"FangSong_GB2312\" w:cs=\"Times New Roman\"/></w:rPr>\n </w:lvl>\n <w:lvl w:ilvl=\"1\">\n <w:start w:val=\"1\"/>\n <w:numFmt w:val=\"bullet\"/>\n <w:lvlText w:val=\"○\"/>\n <w:lvlJc w:val=\"left\"/>\n <w:pPr><w:ind w:left=\"1440\" w:hanging=\"360\"/></w:pPr>\n <w:rPr><w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:eastAsia=\"FangSong_GB2312\" w:cs=\"Times New Roman\"/></w:rPr>\n </w:lvl>\n <w:lvl w:ilvl=\"2\">\n <w:start w:val=\"1\"/>\n <w:numFmt w:val=\"bullet\"/>\n <w:lvlText w:val=\"■\"/>\n <w:lvlJc w:val=\"left\"/>\n <w:pPr><w:ind w:left=\"2160\" w:hanging=\"360\"/></w:pPr>\n <w:rPr><w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:eastAsia=\"FangSong_GB2312\" w:cs=\"Times New Roman\"/></w:rPr>\n </w:lvl>\n </w:abstractNum>\n <w:abstractNum w:abstractNumId=\"2\">\n <w:multiLevelType w:val=\"hybridMultilevel\"/>\n <w:lvl w:ilvl=\"0\">\n <w:start w:val=\"1\"/>\n <w:numFmt w:val=\"decimal\"/>\n <w:lvlText w:val=\"%1.\"/>\n <w:lvlJc w:val=\"left\"/>\n <w:pPr><w:ind w:left=\"720\" w:hanging=\"360\"/></w:pPr>\n <w:rPr><w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:eastAsia=\"FangSong_GB2312\" w:cs=\"Times New Roman\"/></w:rPr>\n </w:lvl>\n <w:lvl w:ilvl=\"1\">\n <w:start w:val=\"1\"/>\n <w:numFmt w:val=\"decimal\"/>\n <w:lvlText w:val=\"%1.%2.\"/>\n <w:lvlJc w:val=\"left\"/>\n <w:pPr><w:ind w:left=\"1440\" w:hanging=\"360\"/></w:pPr>\n <w:rPr><w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:eastAsia=\"FangSong_GB2312\" w:cs=\"Times New Roman\"/></w:rPr>\n </w:lvl>\n <w:lvl w:ilvl=\"2\">\n <w:start w:val=\"1\"/>\n <w:numFmt w:val=\"decimal\"/>\n <w:lvlText w:val=\"%1.%2.%3.\"/>\n <w:lvlJc w:val=\"left\"/>\n <w:pPr><w:ind w:left=\"2160\" w:hanging=\"360\"/></w:pPr>\n <w:rPr><w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:eastAsia=\"FangSong_GB2312\" w:cs=\"Times New Roman\"/></w:rPr>\n </w:lvl>\n </w:abstractNum>\n <w:num w:numId=\"1\"><w:abstractNumId w:val=\"1\"/></w:num>\n <w:num w:numId=\"2\"><w:abstractNumId w:val=\"2\"/></w:num>\n</w:numbering>\n`;\n\nconst HEADER1_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:hdr xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">\n <w:p>\n <w:pPr><w:jc w:val=\"center\"/></w:pPr>\n <w:r><w:t></w:t></w:r>\n </w:p>\n</w:hdr>\n`;\n\nconst FOOTER1_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:ftr xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">\n <w:p>\n <w:pPr><w:jc w:val=\"right\"/></w:pPr>\n <w:r><w:t>第 </w:t></w:r>\n <w:r><w:fldChar w:fldCharType=\"begin\"/></w:r>\n <w:r><w:instrText xml:space=\"preserve\"> PAGE </w:instrText></w:r>\n <w:r><w:fldChar w:fldCharType=\"separate\"/></w:r>\n <w:r><w:t>1</w:t></w:r>\n <w:r><w:fldChar w:fldCharType=\"end\"/></w:r>\n <w:r><w:t> 页 / 共 </w:t></w:r>\n <w:r><w:fldChar w:fldCharType=\"begin\"/></w:r>\n <w:r><w:instrText xml:space=\"preserve\"> NUMPAGES </w:instrText></w:r>\n <w:r><w:fldChar w:fldCharType=\"separate\"/></w:r>\n <w:r><w:t>1</w:t></w:r>\n <w:r><w:fldChar w:fldCharType=\"end\"/></w:r>\n <w:r><w:t> 页</w:t></w:r>\n </w:p>\n</w:ftr>\n`;\n\nconst THEME_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<a:theme xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" name=\"Office Theme\">\n <a:themeElements>\n <a:clrScheme name=\"Office\">\n <a:dk1><a:sysClr val=\"windowText\" lastClr=\"000000\"/></a:dk1>\n <a:lt1><a:sysClr val=\"window\" lastClr=\"FFFFFF\"/></a:lt1>\n <a:dk2><a:srgbClr val=\"1F497D\"/></a:dk2>\n <a:lt2><a:srgbClr val=\"EEECE1\"/></a:lt2>\n <a:accent1><a:srgbClr val=\"4F81BD\"/></a:accent1>\n <a:accent2><a:srgbClr val=\"C0504D\"/></a:accent2>\n <a:accent3><a:srgbClr val=\"9BBB59\"/></a:accent3>\n <a:accent4><a:srgbClr val=\"8064A2\"/></a:accent4>\n <a:accent5><a:srgbClr val=\"4BACC6\"/></a:accent5>\n <a:accent6><a:srgbClr val=\"F79646\"/></a:accent6>\n <a:hlink><a:srgbClr val=\"0000FF\"/></a:hlink>\n <a:folHlink><a:srgbClr val=\"800080\"/></a:folHlink>\n </a:clrScheme>\n <a:fontScheme name=\"Office\">\n <a:majorFont>\n <a:latin typeface=\"Times New Roman\"/>\n <a:ea typeface=\"FangSong_GB2312\"/>\n <a:cs typeface=\"Times New Roman\"/>\n </a:majorFont>\n <a:minorFont>\n <a:latin typeface=\"Times New Roman\"/>\n <a:ea typeface=\"FangSong_GB2312\"/>\n <a:cs typeface=\"Times New Roman\"/>\n </a:minorFont>\n </a:fontScheme>\n <a:fmtScheme name=\"Office\">\n <a:fillStyleLst>\n <a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n <a:gradFill rotWithShape=\"1\"><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"/></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"/></a:gs></a:gsLst><a:lin ang=\"16200000\" scaled=\"1\"/></a:gradFill>\n <a:gradFill rotWithShape=\"1\"><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"/></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"/></a:gs></a:gsLst><a:lin ang=\"16200000\" scaled=\"1\"/></a:gradFill>\n </a:fillStyleLst>\n <a:lnStyleLst>\n <a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:prstDash val=\"solid\"/></a:ln>\n <a:ln w=\"25400\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:prstDash val=\"solid\"/></a:ln>\n <a:ln w=\"38100\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:prstDash val=\"solid\"/></a:ln>\n </a:lnStyleLst>\n <a:effectStyleLst>\n <a:effectStyle><a:effectLst/></a:effectStyle>\n <a:effectStyle><a:effectLst/></a:effectStyle>\n <a:effectStyle><a:effectLst/></a:effectStyle>\n </a:effectStyleLst>\n <a:bgFillStyleLst>\n <a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n <a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n <a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n </a:bgFillStyleLst>\n </a:fmtScheme>\n </a:themeElements>\n <a:objectDefaults/>\n <a:extraClrSchemeLst/>\n</a:theme>\n`;\n\nconst FONT_TABLE_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:fonts xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n <w:font w:name=\"Times New Roman\">\n <w:charset w:val=\"00\"/>\n <w:family w:val=\"roman\"/>\n <w:pitch w:val=\"variable\"/>\n </w:font>\n <w:font w:name=\"FangSong_GB2312\">\n <w:charset w:val=\"86\"/>\n <w:family w:val=\"auto\"/>\n <w:pitch w:val=\"variable\"/>\n </w:font>\n</w:fonts>\n`;\n\nfunction buildContentTypesXml(assets: DocxAsset[]): string {\n const defaults = new Map<string, string>();\n defaults.set(\"rels\", \"application/vnd.openxmlformats-package.relationships+xml\");\n defaults.set(\"xml\", \"application/xml\");\n\n for (const asset of assets) {\n if (!asset.contentType) continue;\n const extMatch = asset.target.match(/\\.([a-zA-Z0-9]+)$/);\n if (!extMatch) continue;\n const ext = extMatch[1].toLowerCase();\n defaults.set(ext, asset.contentType);\n }\n\n const defaultLines = [...defaults.entries()]\n .sort((a, b) => a[0].localeCompare(b[0]))\n .map(([ext, ct]) => ` <Default Extension=\"${ext}\" ContentType=\"${ct}\"/>`)\n .join(\"\\n\");\n\n const overrides = [\n ' <Override PartName=\"/word/document.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"/>',\n ' <Override PartName=\"/word/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\"/>',\n ' <Override PartName=\"/word/settings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml\"/>',\n ' <Override PartName=\"/word/theme/theme1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.theme+xml\"/>',\n ' <Override PartName=\"/word/fontTable.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml\"/>',\n ' <Override PartName=\"/word/numbering.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml\"/>',\n ' <Override PartName=\"/word/header1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml\"/>',\n ' <Override PartName=\"/word/footer1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml\"/>',\n ].join(\"\\n\");\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\\n${defaultLines}\\n${overrides}\\n</Types>\\n`;\n}\n\nconst ROOT_RELS_XML = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\"\n Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\"\n Target=\"word/document.xml\"/>\n</Relationships>\n`;\n\nfunction buildDocumentRelsXml(assets: DocxAsset[]): string {\n const relLines = [\n ' <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>',\n ' <Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/>',\n ' <Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\" Target=\"theme/theme1.xml\"/>',\n ' <Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable\" Target=\"fontTable.xml\"/>',\n ' <Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/>',\n ' <Relationship Id=\"rId6\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header\" Target=\"header1.xml\"/>',\n ' <Relationship Id=\"rId7\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer\" Target=\"footer1.xml\"/>',\n ...assets.map(\n (a) =>\n ` <Relationship Id=\"${a.relationshipId}\" Type=\"${a.relationshipType}\" Target=\"${a.target}\"/>`,\n ),\n ].join(\"\\n\");\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\\n${relLines}\\n</Relationships>\\n`;\n}\n\nexport async function createDocxZipUint8Array(\n xml: string,\n options: XmlToDocxOptions = {},\n): Promise<Uint8Array> {\n const documentXml = normalizeDocumentXml(xml, options.inputKind ?? \"auto\");\n validateXmlIfNeeded(documentXml, options.validateXml ?? true);\n\n const zip = new JSZip();\n zip.file(\"[Content_Types].xml\", buildContentTypesXml([]));\n\n const relsFolder = zip.folder(\"_rels\");\n relsFolder?.file(\".rels\", ROOT_RELS_XML);\n\n const wordFolder = zip.folder(\"word\");\n wordFolder?.file(\"document.xml\", documentXml);\n wordFolder?.file(\"styles.xml\", STYLES_XML);\n wordFolder?.file(\"settings.xml\", SETTINGS_XML);\n wordFolder?.file(\"fontTable.xml\", FONT_TABLE_XML);\n wordFolder?.folder(\"theme\")?.file(\"theme1.xml\", THEME_XML);\n wordFolder?.file(\"numbering.xml\", NUMBERING_XML);\n wordFolder?.file(\"header1.xml\", HEADER1_XML);\n wordFolder?.file(\"footer1.xml\", FOOTER1_XML);\n\n const wordRelsFolder = wordFolder?.folder(\"_rels\");\n wordRelsFolder?.file(\"document.xml.rels\", buildDocumentRelsXml([]));\n\n return zip.generateAsync({ type: \"uint8array\" });\n}\n\nexport async function createDocxZipWithAssetsUint8Array(\n xml: string,\n options: XmlToDocxOptions,\n assets: DocxAsset[],\n): Promise<Uint8Array> {\n const documentXml = normalizeDocumentXml(xml, options.inputKind ?? \"auto\");\n validateXmlIfNeeded(documentXml, options.validateXml ?? true);\n\n const zip = new JSZip();\n zip.file(\"[Content_Types].xml\", buildContentTypesXml(assets));\n\n const relsFolder = zip.folder(\"_rels\");\n relsFolder?.file(\".rels\", ROOT_RELS_XML);\n\n const wordFolder = zip.folder(\"word\");\n wordFolder?.file(\"document.xml\", documentXml);\n wordFolder?.file(\"styles.xml\", STYLES_XML);\n wordFolder?.file(\"settings.xml\", SETTINGS_XML);\n wordFolder?.file(\"fontTable.xml\", FONT_TABLE_XML);\n wordFolder?.folder(\"theme\")?.file(\"theme1.xml\", THEME_XML);\n wordFolder?.file(\"numbering.xml\", NUMBERING_XML);\n wordFolder?.file(\"header1.xml\", HEADER1_XML);\n wordFolder?.file(\"footer1.xml\", FOOTER1_XML);\n\n const wordRelsFolder = wordFolder?.folder(\"_rels\");\n wordRelsFolder?.file(\"document.xml.rels\", buildDocumentRelsXml(assets));\n\n if (assets.length) {\n for (const asset of assets) {\n const targetPath = asset.target.replace(/^\\.\\//, \"\");\n const normalized = targetPath.startsWith(\"word/\") ? targetPath.slice(\"word/\".length) : targetPath;\n wordFolder?.file(normalized, asset.data);\n }\n }\n\n return zip.generateAsync({ type: \"uint8array\" });\n}\n","import type { XmlToDocxInputKind } from \"../index.js\";\n\nconst WORD_MAIN_NS = \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\";\n\nfunction hasWordDocumentRoot(xml: string): boolean {\n return /<w:document[\\s>]/.test(xml);\n}\n\nfunction ensureXmlDeclaration(xml: string): string {\n if (/^\\s*<\\?xml\\b/.test(xml)) return xml;\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n${xml}`;\n}\n\nfunction wrapBodyXml(bodyXml: string): string {\n const xml = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:document\n xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n>\n <w:body>\n${bodyXml}\n <w:sectPr>\n <w:headerReference w:type=\"default\" r:id=\"rId6\"/>\n <w:footerReference w:type=\"default\" r:id=\"rId7\"/>\n <w:pgSz w:w=\"11906\" w:h=\"16838\"/>\n <w:pgMar w:top=\"1440\" w:right=\"1440\" w:bottom=\"1440\" w:left=\"1440\" w:header=\"708\" w:footer=\"708\" w:gutter=\"0\"/>\n <w:cols w:space=\"708\"/>\n </w:sectPr>\n </w:body>\n</w:document>\n`;\n return xml;\n}\n\nfunction ensureWordNamespace(xml: string): string {\n const hasWNamespace =\n /xmlns:w\\s*=\\s*[\"']http:\\/\\/schemas\\.openxmlformats\\.org\\/wordprocessingml\\/2006\\/main[\"']/.test(\n xml,\n );\n if (hasWNamespace) return xml;\n\n return xml.replace(\n /<w:document\\b/,\n `<w:document xmlns:w=\"${WORD_MAIN_NS}\"`,\n );\n}\n\nexport function normalizeDocumentXml(xml: string, inputKind: XmlToDocxInputKind): string {\n const trimmed = xml.trim();\n if (!trimmed) {\n throw new Error(\"XML is empty.\");\n }\n\n if (inputKind === \"document\") {\n const withDecl = ensureXmlDeclaration(trimmed);\n const withNs = ensureWordNamespace(withDecl);\n if (!hasWordDocumentRoot(withNs)) {\n throw new Error('inputKind=\"document\" requires a <w:document> root.');\n }\n return withNs;\n }\n\n if (inputKind === \"body\") {\n return wrapBodyXml(trimmed);\n }\n\n if (hasWordDocumentRoot(trimmed)) {\n const withDecl = ensureXmlDeclaration(trimmed);\n return ensureWordNamespace(withDecl);\n }\n\n return wrapBodyXml(trimmed);\n}\n","import { XMLValidator } from \"fast-xml-parser\";\n\nexport function validateXmlIfNeeded(xml: string, validateXml: boolean): void {\n if (!validateXml) return;\n\n const result = XMLValidator.validate(xml);\n if (result === true) return;\n\n const err = (result as { err?: { msg?: string; line?: number; col?: number } }).err;\n const msg = err?.msg ?? \"Invalid XML.\";\n const line = err?.line;\n const col = err?.col;\n\n const location =\n typeof line === \"number\" && typeof col === \"number\" ? ` (line ${line}, col ${col})` : \"\";\n throw new Error(`${msg}${location}`);\n}\n\n"],"mappings":"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","names":[]}