@arbidocs/coedit 0.4.96 → 0.4.98

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.
@@ -0,0 +1,1559 @@
1
+ import { strToU8, zipSync, strFromU8, unzipSync, zlibSync } from 'fflate';
2
+ import { readXml } from '@docx-editor.dev/core/store';
3
+
4
+ // src/template/pkg.ts
5
+ var W_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
6
+ var R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
7
+ var TemplateError = class extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "TemplateError";
11
+ }
12
+ };
13
+ function parse(xml, part = "part") {
14
+ const read = readXml(xml, { maxBytes: 64 * 1024 * 1024, maxElements: 2e6 });
15
+ if (!read.ok) throw new TemplateError(`${part} is not readable XML (${read.reason})`);
16
+ const convert = (node) => node.type === "text" ? node.value : { name: node.name, attrs: { ...node.attributes }, children: node.children.map(convert) };
17
+ const root = read.nodes.map(convert).find((n) => typeof n !== "string");
18
+ if (!root) throw new TemplateError(`${part} has no root element`);
19
+ const w = root.attrs["xmlns:w"];
20
+ if (w !== void 0 && w !== W_NS) throw new TemplateError(`${part} binds w: to ${w}`);
21
+ return root;
22
+ }
23
+ var escText = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
24
+ var escAttr = (s) => escText(s).replace(/"/g, "&quot;");
25
+ function serialize(root) {
26
+ const out = ['<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n'];
27
+ const walk2 = (node) => {
28
+ if (typeof node === "string") return void out.push(escText(node));
29
+ out.push("<", node.name);
30
+ for (const [k, v] of Object.entries(node.attrs)) out.push(" ", k, '="', escAttr(v), '"');
31
+ if (node.children.length === 0) return void out.push("/>");
32
+ out.push(">");
33
+ node.children.forEach(walk2);
34
+ out.push("</", node.name, ">");
35
+ };
36
+ walk2(root);
37
+ return out.join("");
38
+ }
39
+ var el = (name, attrs = {}, children = []) => ({
40
+ name,
41
+ attrs,
42
+ children
43
+ });
44
+ var isEl = (n) => typeof n === "object" && n !== null;
45
+ var kids = (e, name) => e.children.filter((c) => isEl(c) && (name === void 0 || c.name === name));
46
+ var kid = (e, name) => e ? kids(e, name)[0] : void 0;
47
+ var val = (e, name) => kid(e, name)?.attrs["w:val"];
48
+ function* walk(e) {
49
+ yield e;
50
+ for (const c of e.children) if (isEl(c)) yield* walk(c);
51
+ }
52
+ var clone = (n) => typeof n === "string" ? n : { name: n.name, attrs: { ...n.attrs }, children: n.children.map(clone) };
53
+ var textOf = (e) => [...walk(e)].filter((x) => x.name === "w:t").map((x) => x.children.filter((c) => typeof c === "string").join("")).join("");
54
+
55
+ // src/template/pkg.ts
56
+ var REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
57
+ var RT = {
58
+ officeDocument: `${REL}/officeDocument`,
59
+ styles: `${REL}/styles`,
60
+ numbering: `${REL}/numbering`,
61
+ theme: `${REL}/theme`,
62
+ fontTable: `${REL}/fontTable`,
63
+ settings: `${REL}/settings`,
64
+ header: `${REL}/header`,
65
+ footer: `${REL}/footer`,
66
+ image: `${REL}/image`,
67
+ glossary: `${REL}/glossaryDocument`,
68
+ attachedTemplate: `${REL}/attachedTemplate`
69
+ };
70
+ var WML = "application/vnd.openxmlformats-officedocument.wordprocessingml";
71
+ var CT = {
72
+ document: `${WML}.document.main+xml`,
73
+ template: `${WML}.template.main+xml`,
74
+ styles: `${WML}.styles+xml`,
75
+ numbering: `${WML}.numbering+xml`,
76
+ settings: `${WML}.settings+xml`,
77
+ fontTable: `${WML}.fontTable+xml`,
78
+ header: `${WML}.header+xml`,
79
+ footer: `${WML}.footer+xml`,
80
+ glossary: `${WML}.document.glossary+xml`,
81
+ theme: "application/vnd.openxmlformats-officedocument.theme+xml",
82
+ rels: "application/vnd.openxmlformats-package.relationships+xml"
83
+ };
84
+ var Pkg = class _Pkg {
85
+ files;
86
+ types;
87
+ constructor(files) {
88
+ this.files = files;
89
+ const ct = this.find("[Content_Types].xml");
90
+ if (!ct) throw new TemplateError("not a Word package: no [Content_Types].xml");
91
+ this.types = parse(strFromU8(files.get(ct)), "[Content_Types].xml");
92
+ }
93
+ static read(bytes) {
94
+ let files;
95
+ try {
96
+ files = unzipSync(bytes);
97
+ } catch {
98
+ throw new TemplateError("not a Word package: not a zip");
99
+ }
100
+ return new _Pkg(new Map(Object.entries(files).filter(([n]) => !n.endsWith("/"))));
101
+ }
102
+ write() {
103
+ this.files.set(
104
+ this.find("[Content_Types].xml") ?? "[Content_Types].xml",
105
+ strToU8(serialize(this.types))
106
+ );
107
+ return zipSync(Object.fromEntries(this.files), { level: 6 });
108
+ }
109
+ /** The stored name of a part, matched case-insensitively as OPC does. */
110
+ find(name) {
111
+ const key = name.replace(/^\//, "").toLowerCase();
112
+ for (const n of this.files.keys()) if (n.toLowerCase() === key) return n;
113
+ return void 0;
114
+ }
115
+ has(name) {
116
+ return this.find(name) !== void 0;
117
+ }
118
+ text(name) {
119
+ const n = this.find(name);
120
+ return n === void 0 ? void 0 : strFromU8(this.files.get(n));
121
+ }
122
+ xml(name) {
123
+ const t = this.text(name);
124
+ return t === void 0 ? void 0 : parse(t, name);
125
+ }
126
+ setXml(name, root, contentType) {
127
+ this.files.set(this.find(name) ?? name, strToU8(serialize(root)));
128
+ if (contentType) this.setContentType(name, contentType);
129
+ }
130
+ setBytes(name, bytes, contentType) {
131
+ this.files.set(this.find(name) ?? name, bytes);
132
+ if (contentType) this.setContentType(name, contentType);
133
+ }
134
+ remove(name) {
135
+ const n = this.find(name);
136
+ if (n === void 0) return;
137
+ this.files.delete(n);
138
+ this.types.children = this.types.children.filter(
139
+ (c) => !(typeof c !== "string" && c.name === "Override" && c.attrs.PartName.toLowerCase() === `/${n.toLowerCase()}`)
140
+ );
141
+ this.files.delete(relsName(n));
142
+ }
143
+ contentType(name) {
144
+ const part = `/${name.replace(/^\//, "")}`.toLowerCase();
145
+ const override = kids(this.types, "Override").find(
146
+ (o) => o.attrs.PartName.toLowerCase() === part
147
+ );
148
+ if (override) return override.attrs.ContentType;
149
+ const ext = part.slice(part.lastIndexOf(".") + 1);
150
+ return kids(this.types, "Default").find((d) => d.attrs.Extension.toLowerCase() === ext)?.attrs.ContentType;
151
+ }
152
+ setContentType(name, type) {
153
+ const part = `/${name.replace(/^\//, "")}`;
154
+ const override = kids(this.types, "Override").find(
155
+ (o) => o.attrs.PartName.toLowerCase() === part.toLowerCase()
156
+ );
157
+ if (override) override.attrs.ContentType = type;
158
+ else this.types.children.push(el("Override", { PartName: part, ContentType: type }));
159
+ }
160
+ /** A `Default` for an extension (media), unless one exists. */
161
+ ensureDefault(ext, type) {
162
+ if (!kids(this.types, "Default").some(
163
+ (d) => d.attrs.Extension.toLowerCase() === ext.toLowerCase()
164
+ ))
165
+ this.types.children.unshift(el("Default", { Extension: ext, ContentType: type }));
166
+ }
167
+ rels(owner) {
168
+ const root = this.xml(relsName(owner));
169
+ if (!root) return [];
170
+ return kids(root, "Relationship").map((r) => ({
171
+ id: r.attrs.Id,
172
+ type: r.attrs.Type,
173
+ target: r.attrs.Target,
174
+ external: r.attrs.TargetMode === "External"
175
+ }));
176
+ }
177
+ setRels(owner, rels) {
178
+ const root = el(
179
+ "Relationships",
180
+ { xmlns: "http://schemas.openxmlformats.org/package/2006/relationships" },
181
+ rels.map(
182
+ (r) => el("Relationship", {
183
+ Id: r.id,
184
+ Type: r.type,
185
+ Target: r.target,
186
+ ...r.external ? { TargetMode: "External" } : {}
187
+ })
188
+ )
189
+ );
190
+ this.setXml(relsName(owner), root);
191
+ }
192
+ /** Add a relationship from `owner`; returns its new id. */
193
+ addRel(owner, type, target, external = false) {
194
+ const rels = this.rels(owner);
195
+ const id = freshId(new Set(rels.map((r) => r.id)), "rIdT");
196
+ rels.push({ id, type, target, external });
197
+ this.setRels(owner, rels);
198
+ return id;
199
+ }
200
+ /** The part a relationship of `owner` points at (internal targets only). */
201
+ target(owner, rel) {
202
+ return resolveTarget(owner, rel.target);
203
+ }
204
+ /** The first internal part of a relationship type from `owner`. */
205
+ partOf(owner, type) {
206
+ const rel = this.rels(owner).find((r) => r.type === type && !r.external);
207
+ return rel && this.find(this.target(owner, rel));
208
+ }
209
+ /** The main document part (`word/document.xml` by convention). */
210
+ get main() {
211
+ const main = this.partOf("", RT.officeDocument);
212
+ if (!main) throw new TemplateError("not a Word package: no main document part");
213
+ return main;
214
+ }
215
+ };
216
+ function relsName(owner) {
217
+ const slash = owner.lastIndexOf("/");
218
+ return `${owner.slice(0, slash + 1)}_rels/${owner.slice(slash + 1)}.rels`;
219
+ }
220
+ function resolveTarget(owner, target) {
221
+ if (target.startsWith("/")) return target.slice(1);
222
+ const base = owner.slice(0, owner.lastIndexOf("/") + 1).split("/").filter(Boolean);
223
+ for (const seg of target.split("/")) {
224
+ if (seg === "..") base.pop();
225
+ else if (seg !== "." && seg !== "") base.push(seg);
226
+ }
227
+ return base.join("/");
228
+ }
229
+ function relativeTarget(owner, part) {
230
+ const from = owner.slice(0, owner.lastIndexOf("/") + 1);
231
+ return part.startsWith(from) ? part.slice(from.length) : `/${part}`;
232
+ }
233
+ function freshId(taken, prefix) {
234
+ for (let i = 1; ; i++) if (!taken.has(`${prefix}${i}`)) return `${prefix}${i}`;
235
+ }
236
+ function freshPartName(pkg, folder, stem, ext) {
237
+ for (let i = 1; ; i++) {
238
+ const name = `${folder}${stem}${i}.${ext}`;
239
+ if (!pkg.has(name)) return name;
240
+ }
241
+ }
242
+
243
+ // src/template/merge.ts
244
+ var nameKey = (s) => s.trim().toLowerCase();
245
+ var SETTINGS_ORDER = [
246
+ "w:writeProtection",
247
+ "w:view",
248
+ "w:zoom",
249
+ "w:removePersonalInformation",
250
+ "w:removeDateAndTime",
251
+ "w:doNotDisplayPageBoundaries",
252
+ "w:displayBackgroundShape",
253
+ "w:printPostScriptOverText",
254
+ "w:printFractionalCharacterWidth",
255
+ "w:printFormsData",
256
+ "w:embedTrueTypeFonts",
257
+ "w:embedSystemFonts",
258
+ "w:saveSubsetFonts",
259
+ "w:saveFormsData",
260
+ "w:mirrorMargins",
261
+ "w:alignBordersAndEdges",
262
+ "w:bordersDoNotSurroundHeader",
263
+ "w:bordersDoNotSurroundFooter",
264
+ "w:gutterAtTop",
265
+ "w:hideSpellingErrors",
266
+ "w:hideGrammaticalErrors",
267
+ "w:activeWritingStyle",
268
+ "w:proofState",
269
+ "w:formsDesign",
270
+ "w:attachedTemplate",
271
+ "w:linkStyles",
272
+ "w:stylePaneFormatFilter",
273
+ "w:stylePaneSortMethod",
274
+ "w:documentType",
275
+ "w:mailMerge",
276
+ "w:revisionView",
277
+ "w:trackRevisions",
278
+ "w:doNotTrackMoves",
279
+ "w:doNotTrackFormatting",
280
+ "w:documentProtection",
281
+ "w:autoFormatOverride",
282
+ "w:styleLockTheme",
283
+ "w:styleLockQFSet",
284
+ "w:defaultTabStop",
285
+ "w:autoHyphenation",
286
+ "w:consecutiveHyphenLimit",
287
+ "w:hyphenationZone",
288
+ "w:doNotHyphenateCaps",
289
+ "w:showEnvelope",
290
+ "w:summaryLength",
291
+ "w:clickAndTypeStyle",
292
+ "w:defaultTableStyle",
293
+ "w:evenAndOddHeaders",
294
+ "w:bookFoldRevPrinting",
295
+ "w:bookFoldPrinting",
296
+ "w:bookFoldPrintingSheets",
297
+ "w:drawingGridHorizontalSpacing",
298
+ "w:drawingGridVerticalSpacing",
299
+ "w:displayHorizontalDrawingGridEvery",
300
+ "w:displayVerticalDrawingGridEvery",
301
+ "w:doNotUseMarginsForDrawingGridOrigin",
302
+ "w:drawingGridHorizontalOrigin",
303
+ "w:drawingGridVerticalOrigin",
304
+ "w:doNotShadeFormData",
305
+ "w:noPunctuationKerning",
306
+ "w:characterSpacingControl",
307
+ "w:printTwoOnOne",
308
+ "w:strictFirstAndLastChars",
309
+ "w:noLineBreaksAfter",
310
+ "w:noLineBreaksBefore",
311
+ "w:savePreviewPicture",
312
+ "w:doNotValidateAgainstSchema",
313
+ "w:saveInvalidXml",
314
+ "w:ignoreMixedContent",
315
+ "w:alwaysShowPlaceholderText",
316
+ "w:doNotDemarcateInvalidXml",
317
+ "w:saveXmlDataOnly",
318
+ "w:useXSLTWhenSaving",
319
+ "w:saveThroughXslt",
320
+ "w:showXMLTags",
321
+ "w:alwaysMergeEmptyNamespace",
322
+ "w:updateFields",
323
+ "w:hdrShapeDefaults",
324
+ "w:footnotePr",
325
+ "w:endnotePr",
326
+ "w:compat",
327
+ "w:docVars",
328
+ "w:rsids",
329
+ "m:mathPr",
330
+ "w:attachedSchema",
331
+ "w:themeFontLang",
332
+ "w:clrSchemeMapping",
333
+ "w:doNotIncludeSubdocsInStats",
334
+ "w:doNotAutoCompressPictures",
335
+ "w:forceUpgrade",
336
+ "w:captions",
337
+ "w:readModeInkLockDown",
338
+ "w:smartTagType",
339
+ "sl:schemaLibrary",
340
+ "w:shapeDefaults",
341
+ "w:doNotEmbedSmartTags",
342
+ "w:decimalSymbol",
343
+ "w:listSeparator"
344
+ ];
345
+ function placeOrdered(parent, child, order) {
346
+ const at = parent.children.findIndex((c) => isEl(c) && c.name === child.name);
347
+ if (at >= 0) return void (parent.children[at] = child);
348
+ const rank = order.indexOf(child.name);
349
+ const before = parent.children.findIndex(
350
+ (c) => isEl(c) && rank >= 0 && order.indexOf(c.name) > rank
351
+ );
352
+ if (before < 0) parent.children.push(child);
353
+ else parent.children.splice(before, 0, child);
354
+ }
355
+ var TEMPLATE_SETTINGS = [
356
+ "w:defaultTabStop",
357
+ "w:characterSpacingControl",
358
+ "w:compat",
359
+ "w:themeFontLang",
360
+ "w:clrSchemeMapping",
361
+ "w:hyphenationZone",
362
+ "w:autoHyphenation",
363
+ "w:defaultTableStyle"
364
+ ];
365
+ var W_DOC_ATTRS = { "xmlns:w": W_NS, "xmlns:r": R_NS };
366
+ function ensurePart(pkg, type, name, contentType, root) {
367
+ const existing = pkg.partOf(pkg.main, type);
368
+ if (existing) return existing;
369
+ const part = pkg.has(name) ? freshPartName(pkg, "word/", name.replace(/^word\/|\d*\.xml$/g, ""), "xml") : name;
370
+ pkg.setXml(part, root(), contentType);
371
+ pkg.addRel(pkg.main, type, relativeTarget(pkg.main, part));
372
+ return part;
373
+ }
374
+ function indexStyles(styles) {
375
+ const byId = /* @__PURE__ */ new Map();
376
+ const byName = /* @__PURE__ */ new Map();
377
+ for (const s of kids(styles, "w:style")) {
378
+ const id = s.attrs["w:styleId"];
379
+ if (!id) continue;
380
+ byId.set(id, s);
381
+ const keys = [val(s, "w:name"), ...val(s, "w:aliases")?.split(",") ?? []];
382
+ for (const k of keys) if (k) byName.set(`${s.attrs["w:type"]}:${nameKey(k)}`, s);
383
+ }
384
+ return { byId, byName };
385
+ }
386
+ var STYLE_REFS = [
387
+ "w:basedOn",
388
+ "w:next",
389
+ "w:link",
390
+ "w:pStyle",
391
+ "w:rStyle",
392
+ "w:tblStyle",
393
+ "w:numStyleLink",
394
+ "w:styleLink"
395
+ ];
396
+ function renameStyleRefs(root, map) {
397
+ if (map.size === 0) return;
398
+ for (const e of walk(root))
399
+ if (STYLE_REFS.includes(e.name) && map.has(e.attrs["w:val"]))
400
+ e.attrs["w:val"] = map.get(e.attrs["w:val"]);
401
+ }
402
+ var numIdsIn = (root) => [...walk(root)].filter((e) => e.name === "w:numId").map((e) => e.attrs["w:val"]);
403
+ function maxId(nodes, attr) {
404
+ return nodes.reduce((m, n) => Math.max(m, Number(n.attrs[attr]) || 0), 0);
405
+ }
406
+ function importNumbering(from, into, numIds, styleNumId) {
407
+ const map = /* @__PURE__ */ new Map();
408
+ if (!from) return map;
409
+ const nums = new Map(kids(from, "w:num").map((n) => [n.attrs["w:numId"], n]));
410
+ const abstracts = new Map(kids(from, "w:abstractNum").map((a) => [a.attrs["w:abstractNumId"], a]));
411
+ const abstractMap = /* @__PURE__ */ new Map();
412
+ let nextNum = maxId(kids(into, "w:num"), "w:numId") + 1;
413
+ let nextAbstract = maxId(kids(into, "w:abstractNum"), "w:abstractNumId") + 1;
414
+ const nsids = new Set(kids(into, "w:abstractNum").map((a) => val(a, "w:nsid")));
415
+ const queue = [...numIds];
416
+ while (queue.length) {
417
+ const id = queue.shift();
418
+ if (map.has(id) || id === "0") continue;
419
+ const num = nums.get(id);
420
+ if (!num) continue;
421
+ const absId = val(num, "w:abstractNumId");
422
+ if (absId !== void 0 && !abstractMap.has(absId)) {
423
+ const abs = abstracts.get(absId);
424
+ if (abs) {
425
+ const copy2 = clone(abs);
426
+ copy2.attrs["w:abstractNumId"] = String(nextAbstract);
427
+ abstractMap.set(absId, String(nextAbstract++));
428
+ const nsid = kid(copy2, "w:nsid");
429
+ if (nsid && nsids.has(nsid.attrs["w:val"])) {
430
+ let n = (parseInt(nsid.attrs["w:val"], 16) || 268435456) + 1;
431
+ while (nsids.has(n.toString(16).toUpperCase().padStart(8, "0"))) n++;
432
+ nsid.attrs["w:val"] = n.toString(16).toUpperCase().padStart(8, "0");
433
+ }
434
+ if (nsid) nsids.add(nsid.attrs["w:val"]);
435
+ for (const l of kids(copy2, "w:lvl"))
436
+ l.children = l.children.filter((c) => !(isEl(c) && c.name === "w:lvlPicBulletId"));
437
+ const firstNum = into.children.findIndex(
438
+ (c) => isEl(c) && (c.name === "w:num" || c.name === "w:numIdMacAtCleanup")
439
+ );
440
+ if (firstNum < 0) into.children.push(copy2);
441
+ else into.children.splice(firstNum, 0, copy2);
442
+ const link = val(copy2, "w:numStyleLink");
443
+ const linked = link ? styleNumId(link) : void 0;
444
+ if (linked) queue.push(linked);
445
+ }
446
+ }
447
+ const copy = clone(num);
448
+ copy.attrs["w:numId"] = String(nextNum);
449
+ map.set(id, String(nextNum++));
450
+ const absRef = kid(copy, "w:abstractNumId");
451
+ if (absRef && abstractMap.has(absRef.attrs["w:val"]))
452
+ absRef.attrs["w:val"] = abstractMap.get(absRef.attrs["w:val"]);
453
+ const cleanup = into.children.findIndex((c) => isEl(c) && c.name === "w:numIdMacAtCleanup");
454
+ if (cleanup < 0) into.children.push(copy);
455
+ else into.children.splice(cleanup, 0, copy);
456
+ }
457
+ return map;
458
+ }
459
+ function applyStyles(doc, tpl, report) {
460
+ const tplStylesPart = tpl.partOf(tpl.main, RT.styles);
461
+ if (!tplStylesPart) return;
462
+ const T = tpl.xml(tplStylesPart);
463
+ const stylesPart = ensurePart(
464
+ doc,
465
+ RT.styles,
466
+ "word/styles.xml",
467
+ CT.styles,
468
+ () => el("w:styles", { ...W_DOC_ATTRS })
469
+ );
470
+ const D = doc.xml(stylesPart);
471
+ for (const [k, v] of Object.entries(T.attrs))
472
+ if (k.startsWith("xmlns:") && !(k in D.attrs)) D.attrs[k] = v;
473
+ for (const name of ["w:latentStyles", "w:docDefaults"]) {
474
+ const t = kid(T, name);
475
+ if (!t) continue;
476
+ const at = D.children.findIndex((c) => isEl(c) && c.name === name);
477
+ if (at >= 0) D.children[at] = clone(t);
478
+ else D.children.unshift(clone(t));
479
+ }
480
+ const dd = kid(D, "w:docDefaults");
481
+ const ls = kid(D, "w:latentStyles");
482
+ D.children = D.children.filter((c) => c !== dd && c !== ls);
483
+ D.children.unshift(...[dd, ls].filter(Boolean));
484
+ const dIndex = indexStyles(D);
485
+ const rename = /* @__PURE__ */ new Map();
486
+ for (const s of kids(T, "w:style")) {
487
+ const id = s.attrs["w:styleId"];
488
+ if (dIndex.byId.has(id)) continue;
489
+ const name = val(s, "w:name");
490
+ const match = name && dIndex.byName.get(`${s.attrs["w:type"]}:${nameKey(name)}`);
491
+ if (match && !kids(T, "w:style").some((o) => o.attrs["w:styleId"] === match.attrs["w:styleId"]))
492
+ rename.set(id, match.attrs["w:styleId"]);
493
+ }
494
+ const imported = kids(T, "w:style").map((s) => {
495
+ const copy = clone(s);
496
+ if (rename.has(copy.attrs["w:styleId"]))
497
+ copy.attrs["w:styleId"] = rename.get(copy.attrs["w:styleId"]);
498
+ renameStyleRefs(copy, rename);
499
+ return copy;
500
+ });
501
+ const tplNumbering = tpl.partOf(tpl.main, RT.numbering);
502
+ const T_num = tplNumbering ? tpl.xml(tplNumbering) : void 0;
503
+ const wanted = imported.flatMap(numIdsIn);
504
+ let numMap = /* @__PURE__ */ new Map();
505
+ if (T_num && wanted.length) {
506
+ const numberingPart = ensurePart(
507
+ doc,
508
+ RT.numbering,
509
+ "word/numbering.xml",
510
+ CT.numbering,
511
+ () => el("w:numbering", { ...W_DOC_ATTRS })
512
+ );
513
+ const D_num = doc.xml(numberingPart);
514
+ const tplStyleNum = (sid) => {
515
+ const st = kids(T, "w:style").find((s) => s.attrs["w:styleId"] === sid);
516
+ return st ? numIdsIn(st)[0] : void 0;
517
+ };
518
+ numMap = importNumbering(T_num, D_num, wanted, tplStyleNum);
519
+ for (const abs of kids(D_num, "w:abstractNum")) renameStyleRefs(abs, rename);
520
+ doc.setXml(numberingPart, D_num);
521
+ }
522
+ for (const s of imported)
523
+ for (const e of walk(s))
524
+ if (e.name === "w:numId" && numMap.has(e.attrs["w:val"]))
525
+ e.attrs["w:val"] = numMap.get(e.attrs["w:val"]);
526
+ for (const s of imported) {
527
+ const id = s.attrs["w:styleId"];
528
+ const at = D.children.findIndex(
529
+ (c) => isEl(c) && c.name === "w:style" && c.attrs["w:styleId"] === id
530
+ );
531
+ if (at >= 0) D.children[at] = s;
532
+ else D.children.push(s);
533
+ }
534
+ for (const s of imported)
535
+ if (s.attrs["w:default"] === "1" || s.attrs["w:default"] === "true") {
536
+ for (const o of kids(D, "w:style"))
537
+ if (o !== s && o.attrs["w:type"] === s.attrs["w:type"] && o.attrs["w:default"])
538
+ delete o.attrs["w:default"];
539
+ }
540
+ doc.setXml(stylesPart, D);
541
+ report.styles = imported.map((s) => s.attrs["w:styleId"]);
542
+ report.renamed = Object.fromEntries(rename);
543
+ report.numbering = Object.fromEntries(numMap);
544
+ }
545
+ function applyTheme(doc, tpl) {
546
+ const t = tpl.partOf(tpl.main, RT.theme);
547
+ if (!t) return;
548
+ const bytes = tpl.files.get(t);
549
+ const d = doc.partOf(doc.main, RT.theme);
550
+ if (d) return void doc.setBytes(d, bytes);
551
+ const name = doc.has("word/theme/theme1.xml") ? freshPartName(doc, "word/theme/", "theme", "xml") : "word/theme/theme1.xml";
552
+ doc.setBytes(name, bytes, CT.theme);
553
+ doc.addRel(doc.main, RT.theme, relativeTarget(doc.main, name));
554
+ }
555
+ function applyFonts(doc, tpl) {
556
+ const t = tpl.partOf(tpl.main, RT.fontTable);
557
+ if (!t) return;
558
+ const T = tpl.xml(t);
559
+ const part = ensurePart(
560
+ doc,
561
+ RT.fontTable,
562
+ "word/fontTable.xml",
563
+ CT.fontTable,
564
+ () => el("w:fonts", { ...W_DOC_ATTRS })
565
+ );
566
+ const D = doc.xml(part);
567
+ for (const f of kids(T, "w:font")) {
568
+ const copy = clone(f);
569
+ copy.children = copy.children.filter((c) => !(isEl(c) && /^w:embed/.test(c.name)));
570
+ const at = D.children.findIndex(
571
+ (c) => isEl(c) && c.name === "w:font" && c.attrs["w:name"] === f.attrs["w:name"]
572
+ );
573
+ if (at >= 0) D.children[at] = copy;
574
+ else D.children.push(copy);
575
+ }
576
+ doc.setXml(part, D);
577
+ }
578
+ function settingsOf(pkg) {
579
+ const part = ensurePart(
580
+ pkg,
581
+ RT.settings,
582
+ "word/settings.xml",
583
+ CT.settings,
584
+ () => el("w:settings", { ...W_DOC_ATTRS })
585
+ );
586
+ return { part, root: pkg.xml(part) };
587
+ }
588
+ function applySettings(doc, tpl, opts) {
589
+ const tPart = tpl.partOf(tpl.main, RT.settings);
590
+ const T = tPart ? tpl.xml(tPart) : void 0;
591
+ const { part, root } = settingsOf(doc);
592
+ if (T)
593
+ for (const name of TEMPLATE_SETTINGS) {
594
+ const t = kid(T, name);
595
+ if (t) placeOrdered(root, clone(t), SETTINGS_ORDER);
596
+ }
597
+ if (opts.furniture && T) {
598
+ const even = kid(T, "w:evenAndOddHeaders");
599
+ root.children = root.children.filter((c) => !(isEl(c) && c.name === "w:evenAndOddHeaders"));
600
+ if (even) placeOrdered(root, clone(even), SETTINGS_ORDER);
601
+ }
602
+ if (opts.attachedTemplate) {
603
+ if (!root.attrs["xmlns:r"]) root.attrs["xmlns:r"] = R_NS;
604
+ const rels = doc.rels(part).filter((r) => r.type !== RT.attachedTemplate);
605
+ doc.setRels(part, rels);
606
+ const id = doc.addRel(part, RT.attachedTemplate, encodeURI(opts.attachedTemplate), true);
607
+ placeOrdered(root, el("w:attachedTemplate", { "r:id": id }), SETTINGS_ORDER);
608
+ }
609
+ doc.setXml(part, root);
610
+ }
611
+ function copyPart(doc, tpl, source, stem) {
612
+ const ext = source.slice(source.lastIndexOf(".") + 1);
613
+ const folder = source.slice(0, source.lastIndexOf("/") + 1);
614
+ const name = freshPartName(doc, folder, stem, ext);
615
+ doc.setBytes(name, tpl.files.get(source), tpl.contentType(source));
616
+ const rels = tpl.rels(source).map((r) => {
617
+ if (r.external) return { ...r };
618
+ const target = tpl.find(tpl.target(source, r));
619
+ if (!target) return { ...r };
620
+ const tExt = target.slice(target.lastIndexOf(".") + 1);
621
+ const tFolder = target.slice(0, target.lastIndexOf("/") + 1);
622
+ const tStem = target.slice(tFolder.length, target.length - tExt.length - 1).replace(/\d+$/, "");
623
+ const copied = freshPartName(doc, tFolder, tStem || "part", tExt);
624
+ doc.setBytes(copied, tpl.files.get(target));
625
+ const type = tpl.contentType(target);
626
+ if (type) {
627
+ if (/^(image|video|audio)\//.test(type)) doc.ensureDefault(tExt, type);
628
+ else doc.setContentType(copied, type);
629
+ }
630
+ return { ...r, target: relativeTarget(name, copied) };
631
+ });
632
+ if (rels.length) doc.setRels(name, rels);
633
+ return name;
634
+ }
635
+ function finalSectPr(body) {
636
+ return kid(body, "w:sectPr");
637
+ }
638
+ function applyFurniture(doc, tpl) {
639
+ const tDoc = tpl.xml(tpl.main);
640
+ const tSect = finalSectPr(kid(tDoc, "w:body"));
641
+ if (!tSect) return;
642
+ const dRoot = doc.xml(doc.main);
643
+ const body = kid(dRoot, "w:body");
644
+ if (!body) throw new TemplateError("the document has no body");
645
+ for (const [k, v] of Object.entries(tDoc.attrs))
646
+ if (k.startsWith("xmlns:") && !(k in dRoot.attrs)) dRoot.attrs[k] = v;
647
+ const old = finalSectPr(body);
648
+ const oldIds = old ? kids(old).filter((c) => c.name === "w:headerReference" || c.name === "w:footerReference").map((c) => c.attrs["r:id"]) : [];
649
+ const stillUsed = new Set(
650
+ [...walk(body)].filter(
651
+ (e) => e !== old && (e.name === "w:headerReference" || e.name === "w:footerReference")
652
+ ).filter((e) => !old || ![...walk(old)].includes(e)).map((e) => e.attrs["r:id"])
653
+ );
654
+ const sect = clone(tSect);
655
+ for (const ref of kids(sect)) {
656
+ if (ref.name !== "w:headerReference" && ref.name !== "w:footerReference") continue;
657
+ const rel = tpl.rels(tpl.main).find((r) => r.id === ref.attrs["r:id"]);
658
+ const source = rel && tpl.find(tpl.target(tpl.main, rel));
659
+ if (!rel || !source) {
660
+ sect.children.splice(sect.children.indexOf(ref), 1);
661
+ continue;
662
+ }
663
+ const copied = copyPart(
664
+ doc,
665
+ tpl,
666
+ source,
667
+ ref.name === "w:headerReference" ? "header" : "footer"
668
+ );
669
+ ref.attrs["r:id"] = doc.addRel(doc.main, rel.type, relativeTarget(doc.main, copied));
670
+ }
671
+ if (old) body.children[body.children.indexOf(old)] = sect;
672
+ else body.children.push(sect);
673
+ const rels = doc.rels(doc.main);
674
+ for (const id of oldIds) {
675
+ if (stillUsed.has(id)) continue;
676
+ const rel = rels.find((r) => r.id === id);
677
+ if (!rel) continue;
678
+ doc.remove(doc.target(doc.main, rel));
679
+ rels.splice(rels.indexOf(rel), 1);
680
+ }
681
+ doc.setRels(doc.main, rels);
682
+ doc.setXml(doc.main, dRoot);
683
+ }
684
+ function applyTemplate(document, template, options = {}) {
685
+ const doc = Pkg.read(document);
686
+ const tpl = Pkg.read(template);
687
+ const report = { styles: [], renamed: {}, numbering: {} };
688
+ applyStyles(doc, tpl, report);
689
+ applyTheme(doc, tpl);
690
+ applyFonts(doc, tpl);
691
+ applySettings(doc, tpl, options);
692
+ if (options.furniture) applyFurniture(doc, tpl);
693
+ return { bytes: doc.write(), report };
694
+ }
695
+ function newFromTemplate(template, options = {}) {
696
+ const pkg = Pkg.read(template);
697
+ const main = pkg.main;
698
+ pkg.setContentType(main, CT.document);
699
+ const rels = pkg.rels(main);
700
+ for (const rel of rels.filter((r) => r.type === RT.glossary || /vbaProject$/.test(r.type))) {
701
+ const target = pkg.find(pkg.target(main, rel));
702
+ if (target) {
703
+ for (const sub of pkg.rels(target)) if (!sub.external) pkg.remove(pkg.target(target, sub));
704
+ pkg.remove(target);
705
+ }
706
+ }
707
+ pkg.setRels(
708
+ main,
709
+ rels.filter((r) => r.type !== RT.glossary && !/vbaProject$/.test(r.type))
710
+ );
711
+ if (options.attachedTemplate) {
712
+ const { part, root } = settingsOf(pkg);
713
+ if (!root.attrs["xmlns:r"]) root.attrs["xmlns:r"] = R_NS;
714
+ pkg.setRels(
715
+ part,
716
+ pkg.rels(part).filter((r) => r.type !== RT.attachedTemplate)
717
+ );
718
+ const id = pkg.addRel(part, RT.attachedTemplate, encodeURI(options.attachedTemplate), true);
719
+ placeOrdered(root, el("w:attachedTemplate", { "r:id": id }), SETTINGS_ORDER);
720
+ pkg.setXml(part, root);
721
+ }
722
+ return pkg.write();
723
+ }
724
+ function composeWithTemplate(content, template, attachedTemplate) {
725
+ return applyTemplate(content, template, { furniture: true, attachedTemplate }).bytes;
726
+ }
727
+ function glossaryOf(pkg) {
728
+ const part = pkg.partOf(pkg.main, RT.glossary) ?? pkg.find("word/glossary/document.xml");
729
+ const root = part ? pkg.xml(part) : void 0;
730
+ return part && root ? { part, root } : void 0;
731
+ }
732
+ function docParts(root) {
733
+ return kids(kid(root, "w:docParts") ?? root, "w:docPart");
734
+ }
735
+ function infoOf(part) {
736
+ const pr = kid(part, "w:docPartPr");
737
+ const name = val(pr, "w:name");
738
+ if (!name) return void 0;
739
+ const category = kid(pr, "w:category");
740
+ return {
741
+ name,
742
+ gallery: val(category, "w:gallery") ?? "docParts",
743
+ category: val(category, "w:name") ?? "General",
744
+ description: val(pr, "w:description") ?? "",
745
+ // One space between paragraphs (and table cells), as a one-line preview reads.
746
+ text: [...walk(kid(part, "w:docPartBody") ?? part)].filter((e) => e.name === "w:p").map(textOf).filter(Boolean).join(" ")
747
+ };
748
+ }
749
+ function listBuildingBlocks(template) {
750
+ const g = glossaryOf(Pkg.read(template));
751
+ if (!g) return [];
752
+ return docParts(g.root).map(infoOf).filter((b) => !!b && b.gallery !== "placeholder");
753
+ }
754
+ var MIN_CONTENT_TYPES = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
755
+ <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="${CT.rels}"/><Default Extension="xml" ContentType="application/xml"/></Types>`;
756
+ function buildingBlockFragment(template, name) {
757
+ const tpl = Pkg.read(template);
758
+ const g = glossaryOf(tpl);
759
+ const part = g && docParts(g.root).find((p) => val(kid(p, "w:docPartPr"), "w:name") === name);
760
+ const body = part && kid(part, "w:docPartBody");
761
+ if (!g || !body) return void 0;
762
+ const out = new Pkg(/* @__PURE__ */ new Map([["[Content_Types].xml", strToU8(MIN_CONTENT_TYPES)]]));
763
+ out.setRels("", [
764
+ { id: "rId1", type: RT.officeDocument, target: "word/document.xml", external: false }
765
+ ]);
766
+ const main = "word/document.xml";
767
+ const blocks = body.children.filter(isEl).map(clone);
768
+ out.setXml(
769
+ main,
770
+ el("w:document", { ...g.root.attrs, "xmlns:w": W_NS, "xmlns:r": R_NS }, [
771
+ el("w:body", {}, blocks)
772
+ ]),
773
+ CT.document
774
+ );
775
+ const rels = [];
776
+ const stylesPart = tpl.partOf(g.part, RT.styles) ?? tpl.partOf(tpl.main, RT.styles);
777
+ if (stylesPart) {
778
+ const styles = tpl.xml(stylesPart);
779
+ styles.children = styles.children.filter((c) => !(isEl(c) && c.name === "w:docDefaults"));
780
+ out.setXml("word/styles.xml", styles, CT.styles);
781
+ rels.push({ id: "rIdStyles", type: RT.styles, target: "styles.xml", external: false });
782
+ }
783
+ const numberingPart = tpl.partOf(g.part, RT.numbering) ?? tpl.partOf(tpl.main, RT.numbering);
784
+ if (numberingPart) {
785
+ out.setBytes("word/numbering.xml", tpl.files.get(numberingPart), CT.numbering);
786
+ rels.push({ id: "rIdNumbering", type: RT.numbering, target: "numbering.xml", external: false });
787
+ }
788
+ const used = /* @__PURE__ */ new Set();
789
+ for (const e of blocks.flatMap((b) => [...walk(b)]))
790
+ for (const [k, v] of Object.entries(e.attrs)) if (k.startsWith("r:")) used.add(v);
791
+ for (const rel of tpl.rels(g.part).filter((r) => used.has(r.id))) {
792
+ if (rel.external) {
793
+ rels.push({ ...rel });
794
+ continue;
795
+ }
796
+ const target = tpl.find(tpl.target(g.part, rel));
797
+ if (!target) continue;
798
+ const file = `word/media/${target.slice(target.lastIndexOf("/") + 1)}`;
799
+ out.setBytes(file, tpl.files.get(target));
800
+ const type = tpl.contentType(target);
801
+ if (type) out.ensureDefault(file.slice(file.lastIndexOf(".") + 1), type);
802
+ rels.push({ ...rel, target: file.slice("word/".length) });
803
+ }
804
+ out.setRels(main, rels);
805
+ return out.write();
806
+ }
807
+ function fragmentClipboardHtml(fragment, covered = true) {
808
+ let binary = "";
809
+ for (let i = 0; i < fragment.length; i += 32768)
810
+ binary += String.fromCharCode(...fragment.subarray(i, i + 32768));
811
+ return `<div data-docx-fragment="${btoa(binary)}" data-docx-fragment-end="${covered ? "covered" : "open"}"></div>`;
812
+ }
813
+
814
+ // src/template/divergence.ts
815
+ var UI_ONLY = /* @__PURE__ */ new Set([
816
+ "w:uiPriority",
817
+ "w:semiHidden",
818
+ "w:unhideWhenUsed",
819
+ "w:qFormat",
820
+ "w:locked",
821
+ "w:personal",
822
+ "w:personalCompose",
823
+ "w:personalReply",
824
+ "w:rsid",
825
+ "w:autoRedefine",
826
+ "w:hidden",
827
+ "w:aliases"
828
+ ]);
829
+ function numberingSignature(numbering, numId) {
830
+ if (!numbering) return `num:${numId}`;
831
+ const num = kids(numbering, "w:num").find((n) => n.attrs["w:numId"] === numId);
832
+ const abs = num && kids(numbering, "w:abstractNum").find(
833
+ (a) => a.attrs["w:abstractNumId"] === val(num, "w:abstractNumId")
834
+ );
835
+ if (!abs) return `num:${numId}`;
836
+ const levels = kids(abs, "w:lvl").map((l) => {
837
+ const c = clone(l);
838
+ c.children = c.children.filter(
839
+ (x) => !(isEl(x) && (x.name === "w:lvlPicBulletId" || x.name === "w:pStyle"))
840
+ );
841
+ return canonical(c);
842
+ });
843
+ return levels.join("|");
844
+ }
845
+ function canonical(e) {
846
+ const c = clone(e);
847
+ for (const x of walk(c)) {
848
+ for (const k of Object.keys(x.attrs))
849
+ if (/^w:rsid/.test(k) || k.startsWith("xmlns")) delete x.attrs[k];
850
+ x.attrs = Object.fromEntries(Object.entries(x.attrs).sort(([a], [b]) => a.localeCompare(b)));
851
+ x.children = x.children.filter((k) => isEl(k) && !UI_ONLY.has(k.name));
852
+ }
853
+ return serialize(c).replace(/^<\?xml[^>]*>\n/, "");
854
+ }
855
+ function styleSignature(style2, numbering) {
856
+ const c = clone(style2);
857
+ for (const x of walk(c))
858
+ if (x.name === "w:numId") x.attrs["w:val"] = numberingSignature(numbering, x.attrs["w:val"]);
859
+ delete c.attrs["w:styleId"];
860
+ return canonical(c);
861
+ }
862
+ function partsOf(bytes) {
863
+ const pkg = Pkg.read(bytes);
864
+ const stylesPart = pkg.partOf(pkg.main, RT.styles);
865
+ const numberingPart = pkg.partOf(pkg.main, RT.numbering);
866
+ return {
867
+ styles: stylesPart ? pkg.xml(stylesPart) : void 0,
868
+ numbering: numberingPart ? pkg.xml(numberingPart) : void 0
869
+ };
870
+ }
871
+ function styleDivergence(document, template) {
872
+ const d = partsOf(document);
873
+ const t = partsOf(template);
874
+ const result = { styles: [], docDefaults: false };
875
+ if (!t.styles) return result;
876
+ const dStyles = d.styles ? kids(d.styles, "w:style") : [];
877
+ const byId = new Map(dStyles.map((s) => [s.attrs["w:styleId"], s]));
878
+ const byName = new Map(
879
+ dStyles.map((s) => [`${s.attrs["w:type"]}:${(val(s, "w:name") ?? "").toLowerCase()}`, s])
880
+ );
881
+ for (const s of kids(t.styles, "w:style")) {
882
+ const id = s.attrs["w:styleId"];
883
+ const name = val(s, "w:name") ?? id;
884
+ const mine = byId.get(id) ?? byName.get(`${s.attrs["w:type"]}:${name.toLowerCase()}`);
885
+ if (!mine) result.styles.push({ styleId: id, name, kind: "missing" });
886
+ else if (styleSignature(mine, d.numbering) !== styleSignature(s, t.numbering))
887
+ result.styles.push({ styleId: mine.attrs["w:styleId"], name, kind: "changed" });
888
+ }
889
+ const dd = d.styles && kid(d.styles, "w:docDefaults");
890
+ const td = kid(t.styles, "w:docDefaults");
891
+ result.docDefaults = (dd ? canonical(dd) : "") !== (td ? canonical(td) : "");
892
+ return result;
893
+ }
894
+ function attachedTemplateOf(document) {
895
+ const pkg = Pkg.read(document);
896
+ const settings = pkg.partOf(pkg.main, RT.settings);
897
+ const root = settings ? pkg.xml(settings) : void 0;
898
+ const id = root && kid(root, "w:attachedTemplate")?.attrs["r:id"];
899
+ const rel = id ? pkg.rels(settings).find((r) => r.id === id) : void 0;
900
+ if (!rel) return void 0;
901
+ const target = decodeURI(rel.target);
902
+ return target.slice(Math.max(target.lastIndexOf("/"), target.lastIndexOf("\\")) + 1);
903
+ }
904
+ var W_DECL = 'xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"';
905
+ var VML_DECL = 'xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w10="urn:schemas-microsoft-com:office:word"';
906
+ var DRAWING_DECL = 'xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"';
907
+ var XML = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n';
908
+ var esc = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
909
+ var STEP = 720;
910
+ function style(s) {
911
+ const type = s.type ?? "paragraph";
912
+ return [
913
+ `<w:style w:type="${type}"`,
914
+ s.isDefault ? ' w:default="1"' : "",
915
+ s.custom ? ' w:customStyle="1"' : "",
916
+ ` w:styleId="${s.id}">`,
917
+ `<w:name w:val="${esc(s.name)}"/>`,
918
+ s.aliases ? `<w:aliases w:val="${esc(s.aliases)}"/>` : "",
919
+ s.basedOn ? `<w:basedOn w:val="${s.basedOn}"/>` : "",
920
+ s.next ? `<w:next w:val="${s.next}"/>` : "",
921
+ s.link ? `<w:link w:val="${s.link}"/>` : "",
922
+ s.uiPriority !== void 0 ? `<w:uiPriority w:val="${s.uiPriority}"/>` : "",
923
+ s.qFormat ? "<w:qFormat/>" : "",
924
+ s.extra ?? "",
925
+ s.pPr ? `<w:pPr>${s.pPr}</w:pPr>` : "",
926
+ s.rPr ? `<w:rPr>${s.rPr}</w:rPr>` : "",
927
+ "</w:style>"
928
+ ].join("");
929
+ }
930
+ var ind = (left, hanging = 0) => `<w:ind w:left="${left}"${hanging ? ` w:hanging="${hanging}"` : ""}/>`;
931
+ var numPr = (numId, ilvl = 0) => `<w:numPr>${ilvl ? `<w:ilvl w:val="${ilvl}"/>` : ""}<w:numId w:val="${numId}"/></w:numPr>`;
932
+ var LEGAL_NUM = { clauses: 1, parties: 2, background: 3, schedules: 4 };
933
+ var LEVEL_TEXT = [STEP, STEP, 2 * STEP, 3 * STEP, 4 * STEP];
934
+ var LEGAL_STYLES = [
935
+ { id: "Normal", name: "Normal", isDefault: true, qFormat: true, uiPriority: 0 },
936
+ {
937
+ id: "DefaultParagraphFont",
938
+ name: "Default Paragraph Font",
939
+ type: "character",
940
+ isDefault: true,
941
+ uiPriority: 1,
942
+ extra: "<w:semiHidden/><w:unhideWhenUsed/>"
943
+ },
944
+ {
945
+ id: "TableNormal",
946
+ name: "Normal Table",
947
+ type: "table",
948
+ isDefault: true,
949
+ uiPriority: 99,
950
+ extra: '<w:semiHidden/><w:unhideWhenUsed/><w:tblPr><w:tblInd w:w="0" w:type="dxa"/><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPr>'
951
+ },
952
+ {
953
+ id: "NoList",
954
+ name: "No List",
955
+ type: "numbering",
956
+ isDefault: true,
957
+ uiPriority: 99,
958
+ extra: "<w:semiHidden/><w:unhideWhenUsed/>"
959
+ },
960
+ {
961
+ id: "Title",
962
+ name: "Title",
963
+ next: "Normal",
964
+ qFormat: true,
965
+ uiPriority: 10,
966
+ pPr: '<w:keepNext/><w:spacing w:after="360"/><w:jc w:val="center"/>',
967
+ rPr: '<w:b/><w:caps/><w:sz w:val="28"/><w:szCs w:val="28"/>'
968
+ },
969
+ ...[1, 2, 3].map((n) => ({
970
+ id: `Heading${n}`,
971
+ name: `heading ${n}`,
972
+ basedOn: "Normal",
973
+ next: "Normal",
974
+ qFormat: true,
975
+ uiPriority: 9,
976
+ pPr: `<w:keepNext/><w:spacing w:before="240"/><w:outlineLvl w:val="${n - 1}"/>`,
977
+ rPr: `<w:b/>${n === 1 ? "<w:caps/>" : ""}${n === 3 ? "<w:i/>" : ""}`
978
+ })),
979
+ {
980
+ id: "Parties",
981
+ name: "Parties",
982
+ basedOn: "Normal",
983
+ custom: true,
984
+ qFormat: true,
985
+ pPr: `${numPr(LEGAL_NUM.parties)}${ind(STEP, STEP)}`
986
+ },
987
+ {
988
+ id: "Background",
989
+ name: "Background",
990
+ basedOn: "Normal",
991
+ custom: true,
992
+ qFormat: true,
993
+ pPr: `${numPr(LEGAL_NUM.background)}${ind(STEP, STEP)}`
994
+ },
995
+ ...[1, 2, 3, 4, 5].map((n) => ({
996
+ id: `Level${n}`,
997
+ name: `Level ${n}`,
998
+ basedOn: "Normal",
999
+ custom: true,
1000
+ qFormat: true,
1001
+ next: `Level${n}`,
1002
+ pPr: `${numPr(LEGAL_NUM.clauses, n - 1)}${n === 1 ? "<w:keepNext/>" : ""}${ind(
1003
+ LEVEL_TEXT[n - 1],
1004
+ STEP
1005
+ )}${n === 1 ? '<w:outlineLvl w:val="0"/>' : ""}`,
1006
+ rPr: n === 1 ? "<w:b/><w:caps/>" : void 0
1007
+ })),
1008
+ ...[1, 2, 3, 4, 5].map((n) => ({
1009
+ id: `Body${n}`,
1010
+ name: `Body ${n}`,
1011
+ basedOn: "Normal",
1012
+ custom: true,
1013
+ qFormat: true,
1014
+ pPr: ind(LEVEL_TEXT[n - 1])
1015
+ })),
1016
+ {
1017
+ id: "Definition",
1018
+ name: "Definition",
1019
+ basedOn: "Normal",
1020
+ custom: true,
1021
+ qFormat: true,
1022
+ pPr: ind(STEP)
1023
+ },
1024
+ {
1025
+ id: "Schedule",
1026
+ name: "Schedule",
1027
+ basedOn: "Normal",
1028
+ next: "Normal",
1029
+ custom: true,
1030
+ qFormat: true,
1031
+ pPr: `${numPr(LEGAL_NUM.schedules)}<w:keepNext/><w:pageBreakBefore/><w:jc w:val="center"/><w:outlineLvl w:val="0"/>`,
1032
+ rPr: "<w:b/><w:caps/>"
1033
+ },
1034
+ {
1035
+ id: "Part",
1036
+ name: "Part",
1037
+ basedOn: "Normal",
1038
+ next: "Normal",
1039
+ custom: true,
1040
+ qFormat: true,
1041
+ pPr: `${numPr(LEGAL_NUM.schedules, 1)}<w:keepNext/><w:jc w:val="center"/><w:outlineLvl w:val="1"/>`,
1042
+ rPr: "<w:b/>"
1043
+ },
1044
+ {
1045
+ id: "BlockText",
1046
+ name: "Block Text",
1047
+ aliases: "Block Quote",
1048
+ basedOn: "Normal",
1049
+ uiPriority: 99,
1050
+ pPr: `<w:ind w:left="${2 * STEP}" w:right="${2 * STEP}"/>`
1051
+ },
1052
+ {
1053
+ id: "Quote",
1054
+ name: "Quote",
1055
+ basedOn: "Normal",
1056
+ next: "Normal",
1057
+ qFormat: true,
1058
+ uiPriority: 29,
1059
+ pPr: `<w:ind w:left="${STEP}" w:right="${STEP}"/>`,
1060
+ rPr: "<w:i/>"
1061
+ },
1062
+ {
1063
+ id: "Marking",
1064
+ name: "Document Marking",
1065
+ basedOn: "Normal",
1066
+ next: "Normal",
1067
+ custom: true,
1068
+ pPr: '<w:jc w:val="right"/>',
1069
+ rPr: "<w:b/><w:caps/>"
1070
+ },
1071
+ {
1072
+ id: "FootnoteText",
1073
+ name: "footnote text",
1074
+ basedOn: "Normal",
1075
+ link: "FootnoteTextChar",
1076
+ uiPriority: 99,
1077
+ pPr: '<w:spacing w:after="0" w:line="240" w:lineRule="auto"/>',
1078
+ rPr: '<w:sz w:val="18"/><w:szCs w:val="18"/>'
1079
+ },
1080
+ {
1081
+ id: "FootnoteTextChar",
1082
+ name: "Footnote Text Char",
1083
+ type: "character",
1084
+ basedOn: "DefaultParagraphFont",
1085
+ link: "FootnoteText",
1086
+ custom: true,
1087
+ uiPriority: 99,
1088
+ rPr: '<w:sz w:val="18"/><w:szCs w:val="18"/>'
1089
+ },
1090
+ {
1091
+ id: "FootnoteReference",
1092
+ name: "footnote reference",
1093
+ type: "character",
1094
+ basedOn: "DefaultParagraphFont",
1095
+ uiPriority: 99,
1096
+ rPr: '<w:vertAlign w:val="superscript"/>'
1097
+ },
1098
+ {
1099
+ id: "EndnoteText",
1100
+ name: "endnote text",
1101
+ basedOn: "FootnoteText",
1102
+ uiPriority: 99
1103
+ },
1104
+ {
1105
+ id: "EndnoteReference",
1106
+ name: "endnote reference",
1107
+ type: "character",
1108
+ basedOn: "DefaultParagraphFont",
1109
+ uiPriority: 99,
1110
+ rPr: '<w:vertAlign w:val="superscript"/>'
1111
+ },
1112
+ {
1113
+ id: "Header",
1114
+ name: "header",
1115
+ basedOn: "Normal",
1116
+ uiPriority: 99,
1117
+ pPr: `<w:tabs><w:tab w:val="center" w:pos="4513"/><w:tab w:val="right" w:pos="9026"/></w:tabs><w:spacing w:after="0"/>`,
1118
+ rPr: '<w:sz w:val="16"/><w:szCs w:val="16"/>'
1119
+ },
1120
+ {
1121
+ id: "Footer",
1122
+ name: "footer",
1123
+ basedOn: "Header",
1124
+ uiPriority: 99
1125
+ },
1126
+ {
1127
+ id: "Hyperlink",
1128
+ name: "Hyperlink",
1129
+ type: "character",
1130
+ basedOn: "DefaultParagraphFont",
1131
+ uiPriority: 99,
1132
+ rPr: '<w:color w:val="0563C1" w:themeColor="hyperlink"/><w:u w:val="single"/>'
1133
+ },
1134
+ {
1135
+ id: "TableGrid",
1136
+ name: "Table Grid",
1137
+ type: "table",
1138
+ basedOn: "TableNormal",
1139
+ uiPriority: 39,
1140
+ pPr: '<w:spacing w:after="0" w:line="240" w:lineRule="auto"/>',
1141
+ extra: '<w:tblPr><w:tblBorders><w:top w:val="single" w:sz="4" w:space="0" w:color="auto"/><w:left w:val="single" w:sz="4" w:space="0" w:color="auto"/><w:bottom w:val="single" w:sz="4" w:space="0" w:color="auto"/><w:right w:val="single" w:sz="4" w:space="0" w:color="auto"/><w:insideH w:val="single" w:sz="4" w:space="0" w:color="auto"/><w:insideV w:val="single" w:sz="4" w:space="0" w:color="auto"/></w:tblBorders></w:tblPr>'
1142
+ }
1143
+ ];
1144
+ var DOC_DEFAULTS = '<w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:asciiTheme="minorHAnsi" w:eastAsiaTheme="minorHAnsi" w:hAnsiTheme="minorHAnsi" w:cstheme="minorBidi"/><w:sz w:val="21"/><w:szCs w:val="21"/><w:lang w:val="en-GB" w:eastAsia="en-US" w:bidi="ar-SA"/></w:rPr></w:rPrDefault><w:pPrDefault><w:pPr><w:spacing w:after="240" w:line="288" w:lineRule="auto"/><w:jc w:val="both"/></w:pPr></w:pPrDefault></w:docDefaults>';
1145
+ var LATENT = '<w:latentStyles w:defLockedState="0" w:defUIPriority="99" w:defSemiHidden="0" w:defUnhideWhenUsed="0" w:defQFormat="0" w:count="376"><w:lsdException w:name="Normal" w:uiPriority="0" w:qFormat="1"/><w:lsdException w:name="heading 1" w:uiPriority="9" w:qFormat="1"/><w:lsdException w:name="heading 2" w:uiPriority="9" w:qFormat="1"/><w:lsdException w:name="heading 3" w:uiPriority="9" w:qFormat="1"/><w:lsdException w:name="Title" w:uiPriority="10" w:qFormat="1"/><w:lsdException w:name="Quote" w:uiPriority="29" w:qFormat="1"/></w:latentStyles>';
1146
+ function legalStylesXml() {
1147
+ return `${XML}<w:styles ${W_DECL}>${DOC_DEFAULTS}${LATENT}${LEGAL_STYLES.map(style).join("")}</w:styles>`;
1148
+ }
1149
+ function lvl(i, l) {
1150
+ return `<w:lvl w:ilvl="${i}"><w:start w:val="${l.start ?? 1}"/><w:numFmt w:val="${l.fmt}"/>${l.pStyle ? `<w:pStyle w:val="${l.pStyle}"/>` : ""}<w:lvlText w:val="${esc(l.text)}"/><w:lvlJc w:val="${l.jc ?? "left"}"/><w:pPr>${ind(
1151
+ l.left,
1152
+ l.hanging ?? 0
1153
+ )}</w:pPr>${l.rPr ? `<w:rPr>${l.rPr}</w:rPr>` : ""}</w:lvl>`;
1154
+ }
1155
+ function abstractNum(id, nsid, name, levels) {
1156
+ return `<w:abstractNum w:abstractNumId="${id}"><w:nsid w:val="${nsid}"/><w:multiLevelType w:val="${levels.length > 1 ? "multilevel" : "singleLevel"}"/><w:name w:val="${esc(name)}"/>${levels.map((l, i) => lvl(i, l)).join("")}</w:abstractNum>`;
1157
+ }
1158
+ var CLAUSE_LEVELS = [
1159
+ { fmt: "decimal", text: "%1.", pStyle: "Level1", left: STEP, hanging: STEP, rPr: "<w:b/>" },
1160
+ {
1161
+ fmt: "decimal",
1162
+ text: "%1.%2",
1163
+ pStyle: "Level2",
1164
+ left: STEP,
1165
+ hanging: STEP,
1166
+ rPr: '<w:b w:val="0"/><w:caps w:val="0"/>'
1167
+ },
1168
+ { fmt: "lowerLetter", text: "(%3)", pStyle: "Level3", left: 2 * STEP, hanging: STEP },
1169
+ { fmt: "lowerRoman", text: "(%4)", pStyle: "Level4", left: 3 * STEP, hanging: STEP },
1170
+ { fmt: "upperLetter", text: "(%5)", pStyle: "Level5", left: 4 * STEP, hanging: STEP }
1171
+ ];
1172
+ function legalNumberingXml() {
1173
+ const abstracts = [
1174
+ abstractNum(0, "4C2A1B01", "Legal clauses", CLAUSE_LEVELS),
1175
+ abstractNum(1, "4C2A1B02", "Parties", [
1176
+ { fmt: "decimal", text: "(%1)", pStyle: "Parties", left: STEP, hanging: STEP }
1177
+ ]),
1178
+ abstractNum(2, "4C2A1B03", "Background", [
1179
+ { fmt: "upperLetter", text: "(%1)", pStyle: "Background", left: STEP, hanging: STEP }
1180
+ ]),
1181
+ abstractNum(3, "4C2A1B04", "Schedules", [
1182
+ { fmt: "decimal", text: "Schedule %1", pStyle: "Schedule", left: 0, jc: "center" },
1183
+ { fmt: "decimal", text: "Part %2", pStyle: "Part", left: 0, jc: "center" }
1184
+ ])
1185
+ ];
1186
+ const nums = [1, 2, 3, 4].map(
1187
+ (n) => `<w:num w:numId="${n}"><w:abstractNumId w:val="${n - 1}"/></w:num>`
1188
+ );
1189
+ return `${XML}<w:numbering ${W_DECL}>${abstracts.join("")}${nums.join("")}</w:numbering>`;
1190
+ }
1191
+ var THEME_COLORS = [
1192
+ ["dk2", "1F2937"],
1193
+ ["lt2", "E7E6E6"],
1194
+ ["accent1", "1F3864"],
1195
+ ["accent2", "7B2C2C"],
1196
+ ["accent3", "2E5A2E"],
1197
+ ["accent4", "7F6000"],
1198
+ ["accent5", "2F5597"],
1199
+ ["accent6", "595959"],
1200
+ ["hlink", "0563C1"],
1201
+ ["folHlink", "954F72"]
1202
+ ];
1203
+ function themeXml(major = "Arial", minor = "Arial") {
1204
+ const font = (f) => `<a:latin typeface="${esc(f)}"/><a:ea typeface=""/><a:cs typeface=""/>`;
1205
+ return `${XML}<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="ARBI Legal"><a:themeElements><a:clrScheme name="ARBI Legal"><a:dk1><a:sysClr val="windowText" lastClr="000000"/></a:dk1><a:lt1><a:sysClr val="window" lastClr="FFFFFF"/></a:lt1>${THEME_COLORS.map(
1206
+ ([k, v]) => `<a:${k}><a:srgbClr val="${v}"/></a:${k}>`
1207
+ ).join(
1208
+ ""
1209
+ )}</a:clrScheme><a:fontScheme name="ARBI Legal"><a:majorFont>${font(major)}</a:majorFont><a:minorFont>${font(
1210
+ minor
1211
+ )}</a:minorFont></a:fontScheme><a:fmtScheme name="Office"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:fillStyleLst><a:lnStyleLst><a:ln w="6350"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln><a:ln w="12700"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln><a:ln w="19050"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements></a:theme>`;
1212
+ }
1213
+ var FONT_TABLE = `${XML}<w:fonts ${W_DECL}><w:font w:name="Arial"><w:panose1 w:val="020B0604020202020204"/><w:charset w:val="00"/><w:family w:val="swiss"/><w:pitch w:val="variable"/></w:font><w:font w:name="Times New Roman"><w:panose1 w:val="02020603050405020304"/><w:charset w:val="00"/><w:family w:val="roman"/><w:pitch w:val="variable"/></w:font></w:fonts>`;
1214
+ function settingsXml(o) {
1215
+ return `${XML}<w:settings ${W_DECL}><w:zoom w:percent="100"/>${o.template ? "" : ""}<w:defaultTabStop w:val="${STEP}"/>${o.evenAndOdd ? "<w:evenAndOddHeaders/>" : ""}<w:characterSpacingControl w:val="doNotCompress"/><w:footnotePr><w:footnote w:id="-1"/><w:footnote w:id="0"/></w:footnotePr><w:endnotePr><w:endnote w:id="-1"/><w:endnote w:id="0"/></w:endnotePr><w:compat><w:compatSetting w:name="compatibilityMode" w:uri="http://schemas.microsoft.com/office/word" w:val="15"/></w:compat><w:themeFontLang w:val="en-GB"/></w:settings>`;
1216
+ }
1217
+ var NOTES = (kind) => `${XML}<w:${kind}s ${W_DECL}><w:${kind} w:type="separator" w:id="-1"><w:p><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr><w:r><w:separator/></w:r></w:p></w:${kind}><w:${kind} w:type="continuationSeparator" w:id="0"><w:p><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr><w:r><w:continuationSeparator/></w:r></w:p></w:${kind}></w:${kind}s>`;
1218
+ var run = (text, rPr = "") => `<w:r>${rPr ? `<w:rPr>${rPr}</w:rPr>` : ""}<w:t xml:space="preserve">${esc(text)}</w:t></w:r>`;
1219
+ var para = (text, styleId, extra = "") => `<w:p>${styleId || extra ? `<w:pPr>${styleId ? `<w:pStyle w:val="${styleId}"/>` : ""}${extra}</w:pPr>` : ""}${text ? run(text) : ""}</w:p>`;
1220
+ var field = (code, shown) => `<w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText xml:space="preserve"> ${code} </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r>${run(
1221
+ shown
1222
+ )}<w:r><w:fldChar w:fldCharType="end"/></w:r>`;
1223
+ function executionTable(rows) {
1224
+ const cell = (xml, w) => `<w:tc><w:tcPr><w:tcW w:w="${w}" w:type="dxa"/></w:tcPr>${xml}</w:tc>`;
1225
+ const lines = (s) => s.split("\n").map((t) => `<w:p><w:pPr><w:jc w:val="left"/></w:pPr>${run(t)}</w:p>`).join("");
1226
+ return `<w:tbl><w:tblPr><w:tblW w:w="9026" w:type="dxa"/><w:tblLook w:val="0000" w:firstRow="0" w:lastRow="0" w:firstColumn="0" w:lastColumn="0" w:noHBand="0" w:noVBand="0"/></w:tblPr><w:tblGrid><w:gridCol w:w="4513"/><w:gridCol w:w="4513"/></w:tblGrid>${rows.map(([l, r]) => `<w:tr>${cell(lines(l), 4513)}${cell(lines(r), 4513)}</w:tr>`).join("")}</w:tbl><w:p/>`;
1227
+ }
1228
+ var SIGN = "\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026";
1229
+ var AGREEMENT_BODY = [
1230
+ para("[Title of agreement]", "Title"),
1231
+ para("This agreement is dated [DATE]"),
1232
+ para("Parties", "Heading1"),
1233
+ para(
1234
+ "[NAME] incorporated and registered in England and Wales with company number [NUMBER] whose registered office is at [ADDRESS]",
1235
+ "Parties"
1236
+ ),
1237
+ para(
1238
+ "[NAME] incorporated and registered in England and Wales with company number [NUMBER] whose registered office is at [ADDRESS]",
1239
+ "Parties"
1240
+ ),
1241
+ para("Background", "Heading1"),
1242
+ para("[Recital]", "Background"),
1243
+ para("Agreed terms", "Heading1"),
1244
+ para("Interpretation", "Level1"),
1245
+ para("The following definitions apply in this agreement.", "Level2"),
1246
+ para("[Term]: [definition].", "Definition"),
1247
+ para("[Clause]", "Level1"),
1248
+ para("[Sub-clause]", "Level2")
1249
+ ].join("");
1250
+ var LEGAL_BUILDING_BLOCKS = [
1251
+ {
1252
+ name: "Individual (signed)",
1253
+ category: "Signature blocks",
1254
+ description: "An individual signing a simple contract.",
1255
+ body: executionTable([["Signed by [NAME]", `${SIGN}
1256
+ [Signature]`]])
1257
+ },
1258
+ {
1259
+ name: "Company: director and secretary",
1260
+ category: "Signature blocks",
1261
+ description: "A company signing by a director and its secretary (Companies Act 2006, s.44(2)(a)).",
1262
+ body: executionTable([
1263
+ [
1264
+ "Signed by [NAME], a director, for and on behalf of [COMPANY NAME] LIMITED",
1265
+ `${SIGN}
1266
+ Director`
1267
+ ],
1268
+ [
1269
+ "Signed by [NAME], the secretary, for and on behalf of [COMPANY NAME] LIMITED",
1270
+ `${SIGN}
1271
+ Secretary`
1272
+ ]
1273
+ ])
1274
+ },
1275
+ {
1276
+ name: "Company: two directors",
1277
+ category: "Signature blocks",
1278
+ description: "A company signing by two directors (Companies Act 2006, s.44(2)(a)).",
1279
+ body: executionTable([
1280
+ [
1281
+ "Signed by [NAME], a director, for and on behalf of [COMPANY NAME] LIMITED",
1282
+ `${SIGN}
1283
+ Director`
1284
+ ],
1285
+ [
1286
+ "Signed by [NAME], a director, for and on behalf of [COMPANY NAME] LIMITED",
1287
+ `${SIGN}
1288
+ Director`
1289
+ ]
1290
+ ])
1291
+ },
1292
+ {
1293
+ name: "Company deed: director and witness",
1294
+ category: "Signature blocks",
1295
+ description: "A company executing a deed by one director in the presence of a witness (Companies Act 2006, ss.44(2)(b) and 46).",
1296
+ body: executionTable([
1297
+ [
1298
+ "Executed as a deed by [COMPANY NAME] LIMITED acting by [NAME], a director, in the presence of:",
1299
+ `${SIGN}
1300
+ Director`
1301
+ ],
1302
+ [
1303
+ "Witness signature\nWitness name\nWitness address\nWitness occupation",
1304
+ `${SIGN}
1305
+ ${SIGN}
1306
+ ${SIGN}
1307
+ ${SIGN}`
1308
+ ]
1309
+ ])
1310
+ },
1311
+ {
1312
+ name: "LLP: two members",
1313
+ category: "Signature blocks",
1314
+ description: "An LLP signing by two members (Limited Liability Partnerships (Application of Companies Act 2006) Regulations 2009, reg.4).",
1315
+ body: executionTable([
1316
+ ["Signed by [NAME], a member, for and on behalf of [LLP NAME] LLP", `${SIGN}
1317
+ Member`],
1318
+ ["Signed by [NAME], a member, for and on behalf of [LLP NAME] LLP", `${SIGN}
1319
+ Member`]
1320
+ ])
1321
+ },
1322
+ {
1323
+ name: "Individual deed with witness",
1324
+ category: "Signature blocks",
1325
+ description: "An individual executing a deed in the presence of a witness.",
1326
+ body: executionTable([
1327
+ ["Signed as a deed by [NAME] in the presence of:", `${SIGN}
1328
+ [Signature]`],
1329
+ [
1330
+ "Witness signature\nWitness name\nWitness address\nWitness occupation",
1331
+ `${SIGN}
1332
+ ${SIGN}
1333
+ ${SIGN}
1334
+ ${SIGN}`
1335
+ ]
1336
+ ])
1337
+ },
1338
+ {
1339
+ name: "Agreement",
1340
+ category: "Documents",
1341
+ description: "The front of an agreement: title, date, parties, background and the first clauses.",
1342
+ body: AGREEMENT_BODY
1343
+ },
1344
+ ...[
1345
+ [
1346
+ "Without prejudice save as to costs",
1347
+ "Settlement correspondence that may be shown to the court on costs."
1348
+ ],
1349
+ ["Privileged & confidential", "Legally privileged communication."],
1350
+ ["Subject to contract", "Negotiations not intended to be binding."],
1351
+ ["Draft for discussion", "A draft that is not final."]
1352
+ ].map(([text, description]) => ({
1353
+ name: text,
1354
+ category: "Headings",
1355
+ description,
1356
+ body: para(text, "Marking")
1357
+ }))
1358
+ ];
1359
+ function glossaryXml(blocks) {
1360
+ const guid = (i) => `{4C2A1B${String(i).padStart(2, "0")}-0000-4000-8000-${String(i).padStart(12, "0")}}`;
1361
+ return `${XML}<w:glossaryDocument ${W_DECL}><w:docParts>${blocks.map(
1362
+ (b, i) => `<w:docPart><w:docPartPr><w:name w:val="${esc(b.name)}"/><w:category><w:name w:val="${esc(
1363
+ b.category
1364
+ )}"/><w:gallery w:val="docParts"/></w:category><w:behaviors><w:behavior w:val="content"/></w:behaviors><w:description w:val="${esc(
1365
+ b.description
1366
+ )}"/><w:guid w:val="${guid(i + 1)}"/></w:docPartPr><w:docPartBody>${b.body}</w:docPartBody></w:docPart>`
1367
+ ).join("")}</w:docParts></w:glossaryDocument>`;
1368
+ }
1369
+ function placeholderPng(w = 160, h = 48, grey = 208) {
1370
+ const crcTable = Array.from({ length: 256 }, (_, n) => {
1371
+ let c = n;
1372
+ for (let k = 0; k < 8; k++) c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
1373
+ return c >>> 0;
1374
+ });
1375
+ const crc = (bytes) => {
1376
+ let c = 4294967295;
1377
+ for (const b of bytes) c = crcTable[(c ^ b) & 255] ^ c >>> 8;
1378
+ return (c ^ 4294967295) >>> 0;
1379
+ };
1380
+ const u32 = (n) => [n >>> 24 & 255, n >>> 16 & 255, n >>> 8 & 255, n & 255];
1381
+ const chunk = (type, data) => {
1382
+ const body = new Uint8Array([...strToU8(type), ...data]);
1383
+ return [...u32(data.length), ...body, ...u32(crc(body))];
1384
+ };
1385
+ const raw = new Uint8Array(h * (w + 1));
1386
+ for (let y = 0; y < h; y++) raw.fill(grey, y * (w + 1) + 1, (y + 1) * (w + 1));
1387
+ return new Uint8Array([
1388
+ 137,
1389
+ 80,
1390
+ 78,
1391
+ 71,
1392
+ 13,
1393
+ 10,
1394
+ 26,
1395
+ 10,
1396
+ ...chunk("IHDR", new Uint8Array([...u32(w), ...u32(h), 8, 0, 0, 0, 0])),
1397
+ ...chunk("IDAT", zlibSync(raw)),
1398
+ ...chunk("IEND", new Uint8Array())
1399
+ ]);
1400
+ }
1401
+ function inlineImage(rId, cx, cy, id, name) {
1402
+ return `<w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="${cx}" cy="${cy}"/><wp:docPr id="${id}" name="${esc(
1403
+ name
1404
+ )}" descr="${esc(name)}"/><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:pic><pic:nvPicPr><pic:cNvPr id="${id}" name="${esc(
1405
+ name
1406
+ )}"/><pic:cNvPicPr/></pic:nvPicPr><pic:blipFill><a:blip r:embed="${rId}"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${cx}" cy="${cy}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>`;
1407
+ }
1408
+ function watermarkXml(text) {
1409
+ return `<w:p><w:pPr><w:pStyle w:val="Header"/></w:pPr><w:r><w:pict><v:shapetype id="_x0000_t136" coordsize="21600,21600" o:spt="136" adj="10800" path="m@7,l@8,m@5,21600l@6,21600e"><v:path textpathok="t" o:connecttype="custom"/><v:textpath on="t" fitshape="t"/><o:lock v:ext="edit" text="t" shapetype="t"/></v:shapetype><v:shape id="PowerPlusWaterMarkObject1" o:spid="_x0000_s1025" type="#_x0000_t136" style="position:absolute;margin-left:0;margin-top:0;width:412.4pt;height:164.95pt;rotation:315;z-index:-251657216;mso-position-horizontal:center;mso-position-horizontal-relative:margin;mso-position-vertical:center;mso-position-vertical-relative:margin" o:allowincell="f" fillcolor="silver" stroked="f"><v:fill opacity=".5"/><v:textpath style="font-family:&quot;Arial&quot;;font-size:1pt" string="${esc(
1410
+ text
1411
+ )}"/><w10:wrap anchorx="margin" anchory="margin"/></v:shape></w:pict></w:r></w:p>`;
1412
+ }
1413
+ var hdr = (kind, body) => `${XML}<w:${kind} ${W_DECL} ${VML_DECL} ${DRAWING_DECL}>${body}</w:${kind}>`;
1414
+ function defaultLegalTemplate(options = {}) {
1415
+ const files = {};
1416
+ const put = (name, xml) => files[name] = strToU8(xml);
1417
+ const overrides = [
1418
+ ["/word/document.xml", options.asDocument ? CT.document : CT.template],
1419
+ ["/word/styles.xml", CT.styles],
1420
+ ["/word/numbering.xml", CT.numbering],
1421
+ ["/word/settings.xml", CT.settings],
1422
+ ["/word/fontTable.xml", CT.fontTable],
1423
+ ["/word/theme/theme1.xml", CT.theme],
1424
+ [
1425
+ "/word/footnotes.xml",
1426
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"
1427
+ ],
1428
+ [
1429
+ "/word/endnotes.xml",
1430
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml"
1431
+ ],
1432
+ ["/docProps/core.xml", "application/vnd.openxmlformats-package.core-properties+xml"]
1433
+ ];
1434
+ const rels = [
1435
+ ["rId1", RT.styles, "styles.xml"],
1436
+ ["rId2", RT.numbering, "numbering.xml"],
1437
+ ["rId3", RT.settings, "settings.xml"],
1438
+ ["rId4", RT.fontTable, "fontTable.xml"],
1439
+ ["rId5", RT.theme, "theme/theme1.xml"],
1440
+ ["rId6", `${RT.styles.replace("styles", "footnotes")}`, "footnotes.xml"],
1441
+ ["rId7", `${RT.styles.replace("styles", "endnotes")}`, "endnotes.xml"]
1442
+ ];
1443
+ put("word/styles.xml", legalStylesXml());
1444
+ put("word/numbering.xml", legalNumberingXml());
1445
+ put("word/fontTable.xml", FONT_TABLE);
1446
+ put("word/theme/theme1.xml", themeXml());
1447
+ put("word/footnotes.xml", NOTES("footnote"));
1448
+ put("word/endnotes.xml", NOTES("endnote"));
1449
+ const refs = [];
1450
+ const footer = para("", "Footer", '<w:jc w:val="center"/>').replace(
1451
+ "</w:p>",
1452
+ `${run("Page ")}${field("PAGE", "1")}${run(" of ")}${field("NUMPAGES", "1")}</w:p>`
1453
+ );
1454
+ put("word/footer1.xml", hdr("ftr", footer));
1455
+ overrides.push(["/word/footer1.xml", CT.footer]);
1456
+ rels.push(["rId20", RT.footer, "footer1.xml"]);
1457
+ refs.push('<w:footerReference w:type="default" r:id="rId20"/>');
1458
+ const mark = options.watermark ? watermarkXml(options.watermark) : "";
1459
+ if (options.letterhead) {
1460
+ files["word/media/letterhead-logo.png"] = placeholderPng();
1461
+ put(
1462
+ "word/header1.xml",
1463
+ hdr(
1464
+ "hdr",
1465
+ `${mark}<w:p><w:pPr><w:pStyle w:val="Header"/><w:jc w:val="right"/></w:pPr>${inlineImage(
1466
+ "rIdLogo",
1467
+ 1828800,
1468
+ 548640,
1469
+ 1,
1470
+ "Logo placeholder"
1471
+ )}</w:p>${para("[Firm name]", "Header", '<w:jc w:val="right"/>')}${para(
1472
+ "[Address line] \xB7 [Telephone] \xB7 [Email] \xB7 [Website]",
1473
+ "Header",
1474
+ '<w:jc w:val="right"/>'
1475
+ )}`
1476
+ )
1477
+ );
1478
+ put(
1479
+ "word/_rels/header1.xml.rels",
1480
+ `${XML}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdLogo" Type="${RT.image}" Target="media/letterhead-logo.png"/></Relationships>`
1481
+ );
1482
+ put(
1483
+ "word/header2.xml",
1484
+ hdr("hdr", `${mark}${para("[Document title]", "Header", '<w:jc w:val="right"/>')}`)
1485
+ );
1486
+ overrides.push(["/word/header1.xml", CT.header], ["/word/header2.xml", CT.header]);
1487
+ rels.push(["rId21", RT.header, "header1.xml"], ["rId22", RT.header, "header2.xml"]);
1488
+ refs.unshift(
1489
+ '<w:headerReference w:type="first" r:id="rId21"/>',
1490
+ '<w:headerReference w:type="default" r:id="rId22"/>'
1491
+ );
1492
+ refs.push('<w:footerReference w:type="first" r:id="rId20"/>');
1493
+ } else if (mark) {
1494
+ put("word/header1.xml", hdr("hdr", mark));
1495
+ overrides.push(["/word/header1.xml", CT.header]);
1496
+ rels.push(["rId21", RT.header, "header1.xml"]);
1497
+ refs.unshift('<w:headerReference w:type="default" r:id="rId21"/>');
1498
+ }
1499
+ const sectPr = `<w:sectPr>${refs.join("")}<w:pgSz w:w="11906" w:h="16838"/><w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="708" w:footer="708" w:gutter="0"/><w:cols w:space="708"/>${options.letterhead ? "<w:titlePg/>" : ""}<w:docGrid w:linePitch="360"/></w:sectPr>`;
1500
+ put(
1501
+ "word/document.xml",
1502
+ `${XML}<w:document ${W_DECL} ${VML_DECL} ${DRAWING_DECL}><w:body>${options.body ?? "<w:p/>"}${sectPr}</w:body></w:document>`
1503
+ );
1504
+ put("word/settings.xml", settingsXml({}));
1505
+ if (options.buildingBlocks !== false) {
1506
+ put("word/glossary/document.xml", glossaryXml(LEGAL_BUILDING_BLOCKS));
1507
+ put("word/glossary/styles.xml", legalStylesXml());
1508
+ put("word/glossary/numbering.xml", legalNumberingXml());
1509
+ put(
1510
+ "word/glossary/_rels/document.xml.rels",
1511
+ `${XML}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="${RT.styles}" Target="styles.xml"/><Relationship Id="rId2" Type="${RT.numbering}" Target="numbering.xml"/></Relationships>`
1512
+ );
1513
+ overrides.push(
1514
+ ["/word/glossary/document.xml", CT.glossary],
1515
+ ["/word/glossary/styles.xml", CT.styles],
1516
+ ["/word/glossary/numbering.xml", CT.numbering]
1517
+ );
1518
+ rels.push(["rId30", RT.glossary, "glossary/document.xml"]);
1519
+ }
1520
+ put(
1521
+ "docProps/core.xml",
1522
+ `${XML}<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:title>ARBI legal template</dc:title></cp:coreProperties>`
1523
+ );
1524
+ put(
1525
+ "word/_rels/document.xml.rels",
1526
+ `${XML}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${rels.map(([id, type, target]) => `<Relationship Id="${id}" Type="${type}" Target="${target}"/>`).join("")}</Relationships>`
1527
+ );
1528
+ put(
1529
+ "_rels/.rels",
1530
+ `${XML}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="${RT.officeDocument}" Target="word/document.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>`
1531
+ );
1532
+ put(
1533
+ "[Content_Types].xml",
1534
+ `${XML}<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="${CT.rels}"/><Default Extension="xml" ContentType="application/xml"/><Default Extension="png" ContentType="image/png"/>${overrides.map(([p, t]) => `<Override PartName="${p}" ContentType="${t}"/>`).join("")}</Types>`
1535
+ );
1536
+ return zipSync(files, { level: 6 });
1537
+ }
1538
+
1539
+ // src/template/numbering.ts
1540
+ function linkedLevelStyles(document) {
1541
+ const pkg = Pkg.read(document);
1542
+ const part = pkg.partOf(pkg.main, RT.numbering);
1543
+ const numbering = part ? pkg.xml(part) : void 0;
1544
+ const out = {};
1545
+ for (const abs of numbering ? kids(numbering, "w:abstractNum") : []) {
1546
+ const levels = kids(abs, "w:lvl").map((l) => ({ ilvl: Number(l.attrs["w:ilvl"]), style: val(l, "w:pStyle") })).sort((a, b) => a.ilvl - b.ilvl);
1547
+ levels.forEach(({ style: style2 }, i) => {
1548
+ if (!style2 || out[style2]) return;
1549
+ const next = levels[i + 1]?.style;
1550
+ const previous = levels[i - 1]?.style;
1551
+ out[style2] = { ...next ? { next } : {}, ...previous ? { previous } : {} };
1552
+ });
1553
+ }
1554
+ return out;
1555
+ }
1556
+
1557
+ export { LEGAL_BUILDING_BLOCKS, LEGAL_NUM, TemplateError, applyTemplate, attachedTemplateOf, buildingBlockFragment, composeWithTemplate, defaultLegalTemplate, fragmentClipboardHtml, linkedLevelStyles, listBuildingBlocks, newFromTemplate, styleDivergence };
1558
+ //# sourceMappingURL=template.js.map
1559
+ //# sourceMappingURL=template.js.map