@w100n/documents 0.3.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/SheetView-3XTEV2VT.css +319 -0
  2. package/dist/SheetView-3XTEV2VT.css.map +1 -0
  3. package/dist/SheetView-JYH2ZUZF.js +928 -0
  4. package/dist/SheetView-JYH2ZUZF.js.map +1 -0
  5. package/dist/TextEditor-X3X62R46.js +982 -0
  6. package/dist/TextEditor-X3X62R46.js.map +1 -0
  7. package/dist/caveat-cyrillic-XVO43JCM.woff2 +0 -0
  8. package/dist/caveat-latin-IUBKKMHQ.woff2 +0 -0
  9. package/dist/caveat-latin-ext-5S7R5SZN.woff2 +0 -0
  10. package/dist/chunk-CE3AADY6.js +3447 -0
  11. package/dist/chunk-CE3AADY6.js.map +1 -0
  12. package/dist/chunk-ISOOUYLI.js +150 -0
  13. package/dist/chunk-ISOOUYLI.js.map +1 -0
  14. package/dist/{chunk-KEV4R7W5.js → chunk-K364NAYP.js} +4 -1
  15. package/dist/chunk-K364NAYP.js.map +1 -0
  16. package/dist/chunk-QDH7EZAF.js +27 -0
  17. package/dist/chunk-QDH7EZAF.js.map +1 -0
  18. package/dist/chunk-SVRYWMES.js +196 -0
  19. package/dist/chunk-SVRYWMES.js.map +1 -0
  20. package/dist/chunk-TDP6OJET.js +31 -0
  21. package/dist/chunk-TDP6OJET.js.map +1 -0
  22. package/dist/chunk-TNSN4ZQ5.js +2909 -0
  23. package/dist/chunk-TNSN4ZQ5.js.map +1 -0
  24. package/dist/collab.cjs +6312 -0
  25. package/dist/collab.cjs.map +1 -0
  26. package/dist/collab.d.cts +39 -0
  27. package/dist/collab.d.ts +39 -0
  28. package/dist/collab.js +30 -0
  29. package/dist/collab.js.map +1 -0
  30. package/dist/grid-EI5JNZAA.js +88 -0
  31. package/dist/grid-EI5JNZAA.js.map +1 -0
  32. package/dist/index.cjs +12265 -407
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.css +3448 -214
  35. package/dist/index.css.map +1 -1
  36. package/dist/index.d.cts +145 -7
  37. package/dist/index.d.ts +145 -7
  38. package/dist/index.js +3469 -340
  39. package/dist/index.js.map +1 -1
  40. package/dist/memory.cjs +59 -7
  41. package/dist/memory.cjs.map +1 -1
  42. package/dist/memory.d.cts +7 -2
  43. package/dist/memory.d.ts +7 -2
  44. package/dist/memory.js +57 -8
  45. package/dist/memory.js.map +1 -1
  46. package/dist/pdfWrite-EM6GJDBF.js +76 -0
  47. package/dist/pdfWrite-EM6GJDBF.js.map +1 -0
  48. package/dist/types-B5oF25dn.d.cts +165 -0
  49. package/dist/types-B5oF25dn.d.ts +165 -0
  50. package/dist/write-DaVtTJCS.d.cts +6 -0
  51. package/dist/write-DaVtTJCS.d.ts +6 -0
  52. package/package.json +45 -3
  53. package/dist/chunk-KEV4R7W5.js.map +0 -1
  54. package/dist/types-DiEpNWSu.d.cts +0 -59
  55. package/dist/types-DiEpNWSu.d.ts +0 -59
@@ -0,0 +1,3447 @@
1
+ 'use client';
2
+ import {
3
+ attr,
4
+ attrs,
5
+ entry,
6
+ escape,
7
+ inflate,
8
+ parse,
9
+ readDocx,
10
+ texts,
11
+ unescape,
12
+ unzip,
13
+ writeDocx,
14
+ zip
15
+ } from "./chunk-TNSN4ZQ5.js";
16
+ import {
17
+ a1,
18
+ box,
19
+ boxes,
20
+ cell,
21
+ plain,
22
+ quoted,
23
+ remapped,
24
+ renamed,
25
+ shifted,
26
+ span,
27
+ squeeze,
28
+ stored
29
+ } from "./chunk-ISOOUYLI.js";
30
+
31
+ // src/collab.ts
32
+ import { getSchema } from "@tiptap/core";
33
+ import { Transform } from "@tiptap/pm/transform";
34
+ import { prosemirrorJSONToYXmlFragment, updateYFragment, yXmlFragmentToProseMirrorRootNode } from "@tiptap/y-tiptap";
35
+ import * as Y2 from "yjs";
36
+
37
+ // package.json
38
+ var version = "0.10.0";
39
+
40
+ // src/editor/extensions.ts
41
+ import { Extension as Extension2, Mark, Node } from "@tiptap/core";
42
+ import Collaboration from "@tiptap/extension-collaboration";
43
+ import CollaborationCaret from "@tiptap/extension-collaboration-caret";
44
+ import Highlight from "@tiptap/extension-highlight";
45
+ import Image from "@tiptap/extension-image";
46
+ import { TaskItem, TaskList } from "@tiptap/extension-list";
47
+ import { TableKit } from "@tiptap/extension-table";
48
+ import { Color, FontFamily, FontSize, TextStyle } from "@tiptap/extension-text-style";
49
+ import { Plugin as Plugin2, PluginKey as PluginKey2, TextSelection } from "@tiptap/pm/state";
50
+ import { StepMap } from "@tiptap/pm/transform";
51
+ import { Decoration as Decoration2, DecorationSet as DecorationSet2 } from "@tiptap/pm/view";
52
+ import StarterKit from "@tiptap/starter-kit";
53
+ import { ySyncPluginKey } from "@tiptap/y-tiptap";
54
+
55
+ // src/editor/pager.ts
56
+ import { Extension } from "@tiptap/core";
57
+ import { Plugin, PluginKey } from "@tiptap/pm/state";
58
+ import { Decoration, DecorationSet } from "@tiptap/pm/view";
59
+ var a4 = { width: 793.73, height: 1122.53, margins: [96, 96, 96, 96] };
60
+ var letter = { width: 816, height: 1056 };
61
+ var paging = new PluginKey("w100n-pager");
62
+ var skip = (el) => el.classList.contains("w100n-text-gap") || el.classList.contains("ProseMirror-gapcursor");
63
+ function measure(view) {
64
+ const { page } = paging.getState(view.state);
65
+ const [top, , bottom] = page.margins;
66
+ const room = page.height - top - bottom;
67
+ const els = [...view.dom.children];
68
+ const gaps = [];
69
+ let i = 0;
70
+ let shift = 0;
71
+ let start = 0;
72
+ let last = 0;
73
+ view.state.doc.forEach((node, offset) => {
74
+ let el = els[i++];
75
+ while (el && skip(el)) {
76
+ if (el.classList.contains("w100n-text-gap")) shift += el.offsetHeight;
77
+ el = els[i++];
78
+ }
79
+ if (!el) return;
80
+ const y = el.offsetTop - shift;
81
+ const end = y + el.offsetHeight;
82
+ if (node.type.name === "pageBreak") {
83
+ gaps.push({ pos: offset + node.nodeSize, height: start + room - end + bottom + 24 + top, page: gaps.length + 1 });
84
+ start = end;
85
+ } else if (end > start + room && y > start) {
86
+ gaps.push({ pos: offset, height: start + room - y + bottom + 24 + top, page: gaps.length + 1 });
87
+ start = y;
88
+ }
89
+ while (end > start + room) start += room;
90
+ last = end;
91
+ });
92
+ gaps.push({ pos: view.state.doc.content.size, height: Math.max(0, start + room - last), page: gaps.length + 1, end: true });
93
+ return gaps.map((g) => ({ ...g, height: Math.max(0, Math.round(g.height)) }));
94
+ }
95
+ var Pager = Extension.create({
96
+ name: "pager",
97
+ addProseMirrorPlugins: () => [new Plugin({
98
+ key: paging,
99
+ state: {
100
+ init: () => ({ set: DecorationSet.empty, page: a4 }),
101
+ apply(tr, value2) {
102
+ const next = tr.getMeta(paging);
103
+ return { set: next?.set ?? value2.set.map(tr.mapping, tr.doc), page: next?.page ?? value2.page };
104
+ }
105
+ },
106
+ props: { decorations: (state) => paging.getState(state).set },
107
+ view(view) {
108
+ let timer = 0;
109
+ let sig = "";
110
+ const run = () => {
111
+ if (!view.dom.isConnected) return;
112
+ const gaps = measure(view);
113
+ const next = gaps.map((g) => `${g.pos}:${g.height}`).join();
114
+ if (next === sig) return;
115
+ sig = next;
116
+ const set = DecorationSet.create(view.state.doc, gaps.map((g) => Decoration.widget(g.pos, () => {
117
+ const el = document.createElement("div");
118
+ el.className = g.end ? "w100n-text-gap is-end" : "w100n-text-gap";
119
+ el.style.height = `${g.height}px`;
120
+ el.dataset.page = String(g.page);
121
+ el.contentEditable = "false";
122
+ return el;
123
+ }, { key: `${g.pos}:${g.height}:${g.page}`, side: -1, ignoreSelection: true })));
124
+ view.dispatch(view.state.tr.setMeta(paging, { set }).setMeta("addToHistory", false));
125
+ };
126
+ const later = (ms) => {
127
+ clearTimeout(timer);
128
+ timer = window.setTimeout(run, ms);
129
+ };
130
+ const watch = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(() => later(200));
131
+ watch?.observe(view.dom);
132
+ later(0);
133
+ return {
134
+ update: (next, prev) => {
135
+ if (paging.getState(next.state).page !== paging.getState(prev).page) later(0);
136
+ else if (next.state.doc !== prev.doc) later(400);
137
+ },
138
+ destroy: () => {
139
+ clearTimeout(timer);
140
+ watch?.disconnect();
141
+ }
142
+ };
143
+ }
144
+ })]
145
+ });
146
+
147
+ // src/editor/extensions.ts
148
+ var notes = new PluginKey2("w100n-notes");
149
+ var blocks = [
150
+ "paragraph",
151
+ "heading",
152
+ "bulletList",
153
+ "orderedList",
154
+ "listItem",
155
+ "taskList",
156
+ "taskItem",
157
+ "blockquote",
158
+ "codeBlock",
159
+ "horizontalRule",
160
+ "table",
161
+ "tableRow",
162
+ "tableHeader",
163
+ "tableCell",
164
+ "pageBreak",
165
+ "toc"
166
+ ];
167
+ var changed = (trs) => {
168
+ const ranges = [];
169
+ trs.forEach((tr, n) => tr.steps.forEach((step, i) => {
170
+ const slice = step.slice;
171
+ if (!slice || !slice.openStart && !slice.openEnd && !slice.content.firstChild?.isBlock) return;
172
+ const after = tr.mapping.slice(i + 1);
173
+ for (const later of trs.slice(n + 1)) after.appendMapping(later.mapping);
174
+ step.getMap().forEach((_a, _b, from, to) => ranges.push([after.map(from, -1), after.map(to, 1)]));
175
+ }));
176
+ return ranges;
177
+ };
178
+ var Blocks = Extension2.create({
179
+ name: "blocks",
180
+ addGlobalAttributes: () => [{
181
+ types: blocks,
182
+ attributes: {
183
+ align: { default: null, parseHTML: (el) => el.style.textAlign || null, renderHTML: (attrs2) => attrs2.align ? { style: `text-align: ${attrs2.align}` } : {} },
184
+ indent: { default: 0, parseHTML: (el) => Number(el.dataset.indent) || 0, renderHTML: (attrs2) => attrs2.indent ? { "data-indent": attrs2.indent, style: `margin-left: ${attrs2.indent * 0.5}in` } : {} },
185
+ ref: { default: null, rendered: false, keepOnSplit: false }
186
+ }
187
+ }],
188
+ addProseMirrorPlugins: () => [new Plugin2({
189
+ appendTransaction(trs, _old, state) {
190
+ const ranges = changed(trs);
191
+ if (!ranges.length) return null;
192
+ const seen2 = /* @__PURE__ */ new Map();
193
+ const drop = [];
194
+ const visit = (node, pos2) => {
195
+ const ref = node.attrs.ref;
196
+ if (!ref) return;
197
+ const first = seen2.get(ref);
198
+ if (!first) seen2.set(ref, { pos: pos2, node });
199
+ else if (!first.node.textContent && node.textContent) {
200
+ drop.push(first.pos);
201
+ seen2.set(ref, { pos: pos2, node });
202
+ } else drop.push(pos2);
203
+ };
204
+ const from = Math.max(0, Math.min(...ranges.map((r) => r[0])));
205
+ const to = Math.min(state.doc.content.size, Math.max(...ranges.map((r) => r[1])));
206
+ const $from = state.doc.resolve(from);
207
+ const $to = state.doc.resolve(to);
208
+ const start = Math.max(0, $from.index(0) - 1);
209
+ const end = Math.min(state.doc.childCount, $to.index(0) + 2);
210
+ let pos = 0;
211
+ for (let i = 0; i < start; i++) pos += state.doc.child(i).nodeSize;
212
+ for (let i = start; i < end; i++) {
213
+ const top = state.doc.child(i);
214
+ visit(top, pos);
215
+ top.descendants((node, at) => visit(node, pos + 1 + at));
216
+ pos += top.nodeSize;
217
+ }
218
+ if (!drop.length) return null;
219
+ const tr = state.tr;
220
+ for (const at of drop) tr.setNodeAttribute(at, "ref", null);
221
+ return tr;
222
+ }
223
+ })]
224
+ });
225
+ var PageBreak = Node.create({
226
+ name: "pageBreak",
227
+ group: "block",
228
+ atom: true,
229
+ selectable: true,
230
+ addOptions: () => ({ label: "" }),
231
+ parseHTML: () => [{ tag: "div[data-page-break]" }],
232
+ renderHTML() {
233
+ return ["div", { "data-page-break": "", "data-label": this.options.label, class: "w100n-text-break", contenteditable: "false" }];
234
+ }
235
+ });
236
+ var headings = (doc, after) => {
237
+ const found = [];
238
+ doc.descendants((node, pos) => {
239
+ if (pos > after && node.type.name === "heading" && node.attrs.level <= 3 && node.textContent.trim()) found.push({ pos, level: node.attrs.level, text: node.textContent.trim() });
240
+ return !node.isTextblock;
241
+ });
242
+ return found;
243
+ };
244
+ function entries(doc, relative2, after) {
245
+ const list = headings(doc, after).map((h) => [h.level, h.text]);
246
+ const top = relative2 && list.length ? Math.min(...list.map(([level]) => level)) - 1 : 0;
247
+ return list.map(([level, text]) => [level - top, text]);
248
+ }
249
+ var Toc = Node.create({
250
+ name: "toc",
251
+ group: "block",
252
+ atom: true,
253
+ selectable: true,
254
+ addOptions: () => ({ relative: false, label: "", empty: "" }),
255
+ addAttributes: () => ({ entries: { default: "[]" }, title: { default: null } }),
256
+ parseHTML: () => [{ tag: "nav[data-toc]" }],
257
+ renderHTML() {
258
+ return ["nav", { "data-toc": "", class: "w100n-text-toc" }];
259
+ },
260
+ addNodeView() {
261
+ return ({ editor, getPos }) => {
262
+ const dom = document.createElement("nav");
263
+ dom.className = "w100n-text-toc";
264
+ dom.contentEditable = "false";
265
+ const paint2 = () => {
266
+ const at = getPos() ?? 0;
267
+ const list = entries(editor.state.doc, this.options.relative, at);
268
+ const head = document.createElement("b");
269
+ head.textContent = this.options.label;
270
+ const items = list.map(([level, text], i) => {
271
+ const go = document.createElement("button");
272
+ go.type = "button";
273
+ go.textContent = text;
274
+ go.dataset.level = String(level);
275
+ go.onclick = () => {
276
+ const hit = headings(editor.state.doc, getPos() ?? 0)[i];
277
+ if (hit) editor.view.nodeDOM(hit.pos)?.scrollIntoView({ behavior: "smooth", block: "start" });
278
+ };
279
+ return go;
280
+ });
281
+ const empty = document.createElement("small");
282
+ empty.textContent = this.options.empty;
283
+ dom.replaceChildren(head, ...items.length ? items : [empty]);
284
+ };
285
+ paint2();
286
+ return {
287
+ dom,
288
+ update: (node) => {
289
+ if (node.type.name !== "toc") return false;
290
+ paint2();
291
+ return true;
292
+ },
293
+ ignoreMutation: () => true
294
+ };
295
+ };
296
+ },
297
+ addProseMirrorPlugins() {
298
+ const relative2 = this.options.relative;
299
+ return [new Plugin2({
300
+ appendTransaction(trs, _old, state) {
301
+ if (!trs.some((tr2) => tr2.docChanged && !tr2.getMeta(ySyncPluginKey))) return null;
302
+ const at = [];
303
+ state.doc.forEach((node, pos) => {
304
+ if (node.type.name === "toc") at.push(pos);
305
+ });
306
+ if (!at.length) return null;
307
+ const tr = state.tr;
308
+ for (const pos of at) {
309
+ const fresh2 = JSON.stringify(entries(state.doc, relative2, pos));
310
+ if (state.doc.nodeAt(pos).attrs.entries !== fresh2) tr.setNodeAttribute(pos, "entries", fresh2);
311
+ }
312
+ return tr.docChanged ? tr : null;
313
+ }
314
+ })];
315
+ }
316
+ });
317
+ var revision = (name, tag) => Mark.create({
318
+ name,
319
+ inclusive: false,
320
+ excludes: "insertion deletion",
321
+ addAttributes: () => ({ id: { default: null }, author: { default: "" }, date: { default: "" } }),
322
+ parseHTML: () => [{ tag: `${tag}[data-rev]` }],
323
+ renderHTML: ({ HTMLAttributes }) => [tag, { "data-rev": HTMLAttributes.id, class: "w100n-text-rev", title: HTMLAttributes.author }, 0]
324
+ });
325
+ var seen = /* @__PURE__ */ new WeakMap();
326
+ function changes(doc) {
327
+ const hit = seen.get(doc);
328
+ if (hit) return hit;
329
+ const out = [];
330
+ doc.descendants((node, pos) => {
331
+ if (!node.isText) return;
332
+ const mark = node.marks.find((m) => m.type.name === "insertion" || m.type.name === "deletion");
333
+ if (!mark) return;
334
+ const last = out[out.length - 1];
335
+ if (last && last.id === mark.attrs.id && last.kind === mark.type.name && last.to === pos) Object.assign(last, { text: last.text + node.text, to: pos + node.nodeSize });
336
+ else out.push({ id: mark.attrs.id, kind: mark.type.name, author: mark.attrs.author, date: mark.attrs.date, text: node.text, from: pos, to: pos + node.nodeSize });
337
+ });
338
+ seen.set(doc, out);
339
+ return out;
340
+ }
341
+ function decide(editor, accept, id) {
342
+ const { state } = editor;
343
+ const tr = state.tr;
344
+ for (const c of changes(state.doc).filter((c2) => !id || c2.id === id).reverse()) {
345
+ if (c.kind === "insertion" === accept) tr.removeMark(c.from, c.to, state.schema.marks[c.kind].create({ id: c.id, author: c.author, date: c.date }));
346
+ else tr.delete(c.from, c.to);
347
+ }
348
+ if (tr.docChanged) editor.view.dispatch(tr);
349
+ }
350
+ var suggesting = new PluginKey2("w100n-suggest");
351
+ var Suggest = Extension2.create({
352
+ name: "suggest",
353
+ addProseMirrorPlugins() {
354
+ const stamp = (state, kind, from, to) => {
355
+ const me = suggesting.getState(state).me;
356
+ const own = [state.doc.resolve(from).nodeBefore, state.doc.resolve(to).nodeAfter].flatMap((n) => n?.marks ?? []).find((m) => m.type.name === kind && m.attrs.author === me);
357
+ return state.schema.marks[kind].create(own ? own.attrs : { id: Math.random().toString(36).slice(2, 10), author: me, date: (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d+Z$/, "Z") });
358
+ };
359
+ const strike = (tr, state, from, to) => {
360
+ const parts2 = [];
361
+ state.doc.nodesBetween(from, to, (node, pos) => {
362
+ if (!node.isText) return;
363
+ const a = Math.max(from, pos), b = Math.min(to, pos + node.nodeSize);
364
+ if (b > a && !node.marks.some((m) => m.type.name === "deletion")) parts2.push({ from: a, to: b, added: node.marks.some((m) => m.type.name === "insertion") });
365
+ });
366
+ const mark = stamp(state, "deletion", from, to);
367
+ for (const p of parts2.reverse()) {
368
+ if (p.added) tr.delete(p.from, p.to);
369
+ else tr.addMark(p.from, p.to, mark);
370
+ }
371
+ };
372
+ const type = (view, from, to, text) => {
373
+ const { state } = view;
374
+ const tr = state.tr;
375
+ if (to > from) strike(tr, state, from, to);
376
+ const at = tr.mapping.map(to);
377
+ const kept = (state.storedMarks ?? state.doc.resolve(from).marks()).filter((m) => m.type.name !== "insertion" && m.type.name !== "deletion");
378
+ tr.insert(at, state.schema.text(text, [...kept, stamp(state, "insertion", from, to)]));
379
+ tr.setSelection(TextSelection.create(tr.doc, at + text.length));
380
+ view.dispatch(tr.scrollIntoView());
381
+ return true;
382
+ };
383
+ return [new Plugin2({
384
+ key: suggesting,
385
+ state: {
386
+ init: () => ({ on: false, me: "" }),
387
+ apply: (tr, value2) => tr.getMeta(suggesting) ?? value2
388
+ },
389
+ props: {
390
+ handleTextInput(view, from, to, text) {
391
+ return suggesting.getState(view.state).on && type(view, from, to, text);
392
+ },
393
+ handlePaste(view, _event, slice) {
394
+ if (!suggesting.getState(view.state).on) return false;
395
+ const { from, to } = view.state.selection;
396
+ return type(view, from, to, slice.content.textBetween(0, slice.content.size, "\n"));
397
+ },
398
+ handleKeyDown(view, event) {
399
+ const { state } = view;
400
+ if (!suggesting.getState(state).on || event.key !== "Backspace" && event.key !== "Delete" || event.metaKey || event.ctrlKey || event.altKey) return false;
401
+ const { from, to, empty, $from } = state.selection;
402
+ const back = event.key === "Backspace";
403
+ let at = from;
404
+ if (empty) {
405
+ const skip2 = (pos) => state.doc.resolve(pos)[back ? "nodeBefore" : "nodeAfter"]?.marks.some((m) => m.type.name === "deletion");
406
+ while (skip2(at)) at += back ? -1 : 1;
407
+ if (back ? at <= $from.start() : at >= $from.end()) return false;
408
+ }
409
+ const tr = state.tr;
410
+ if (empty) strike(tr, state, back ? at - 1 : at, back ? at : at + 1);
411
+ else strike(tr, state, from, to);
412
+ const caret = empty ? tr.mapping.map(back ? at - 1 : at + 1, back ? -1 : 1) : tr.mapping.map(back ? from : to);
413
+ tr.setSelection(TextSelection.create(tr.doc, caret));
414
+ view.dispatch(tr.scrollIntoView());
415
+ return true;
416
+ }
417
+ }
418
+ })];
419
+ }
420
+ });
421
+ var Note = Mark.create({
422
+ name: "comment",
423
+ inclusive: false,
424
+ excludes: "",
425
+ addAttributes: () => ({ id: { default: null, renderHTML: (attrs2) => ({ "data-comment": attrs2.id }) } }),
426
+ renderHTML: ({ HTMLAttributes }) => ["span", HTMLAttributes, 0]
427
+ });
428
+ var locks = new PluginKey2("w100n-locks");
429
+ var locked = (node) => node.type.name === "paragraph" && String(node.attrs.ref ?? "").startsWith("lock:");
430
+ var scan = (doc) => {
431
+ const spans = [];
432
+ doc.descendants((node, pos) => {
433
+ if (!locked(node)) return true;
434
+ spans.push({ from: pos, to: pos + node.nodeSize });
435
+ return false;
436
+ });
437
+ return spans;
438
+ };
439
+ var Locks = Extension2.create({
440
+ name: "locks",
441
+ addOptions: () => ({ label: "" }),
442
+ addProseMirrorPlugins() {
443
+ const shade = (doc, spans) => DecorationSet2.create(doc, spans.map((s) => Decoration2.node(s.from, s.to, { class: "w100n-text-lock", contenteditable: "false", "data-label": this.options.label })));
444
+ return [new Plugin2({
445
+ key: locks,
446
+ state: {
447
+ init: (_config, state) => {
448
+ const spans = scan(state.doc);
449
+ return { spans, set: shade(state.doc, spans) };
450
+ },
451
+ apply(tr, value2) {
452
+ if (!tr.docChanged) return value2;
453
+ const fresh2 = tr.steps.some((step) => {
454
+ let found = false;
455
+ step.slice?.content.descendants((node) => {
456
+ found || (found = locked(node));
457
+ return !found;
458
+ });
459
+ return found;
460
+ });
461
+ const spans = fresh2 ? scan(tr.doc) : value2.spans.map((s) => ({ from: tr.mapping.map(s.from, 1), to: tr.mapping.map(s.to, -1) })).filter((s) => s.to > s.from);
462
+ return { spans, set: spans.length ? shade(tr.doc, spans) : DecorationSet2.empty };
463
+ }
464
+ },
465
+ filterTransaction(tr, state) {
466
+ let spans = locks.getState(state).spans;
467
+ if (!spans.length || !tr.docChanged) return true;
468
+ return tr.mapping.maps.every((map) => {
469
+ let ok = true;
470
+ map.forEach((from, to) => {
471
+ for (const s of spans) if ((from < s.to && to > s.from || from > s.from && from < s.to) && !(from <= s.from && to >= s.to)) ok = false;
472
+ });
473
+ spans = spans.map((s) => ({ from: map.map(s.from, 1), to: map.map(s.to, -1) }));
474
+ return ok;
475
+ });
476
+ },
477
+ props: {
478
+ decorations: (state) => locks.getState(state).set,
479
+ handleKeyDown(view, event) {
480
+ const back = event.key === "Backspace";
481
+ const { $from, empty } = view.state.selection;
482
+ if (!back && event.key !== "Delete" || !empty || $from.depth < 1) return false;
483
+ if (back ? $from.parentOffset !== 0 : $from.parentOffset !== $from.parent.content.size) return false;
484
+ const at = back ? $from.before() : $from.after();
485
+ const node = back ? view.state.doc.resolve(at).nodeBefore : view.state.doc.resolve(at).nodeAfter;
486
+ if (!node || !locked(node)) return false;
487
+ view.dispatch(view.state.tr.delete(back ? at - node.nodeSize : at, back ? at : at + node.nodeSize));
488
+ return true;
489
+ }
490
+ }
491
+ })];
492
+ }
493
+ });
494
+ var paint = (doc, spots, active, pending2) => DecorationSet2.create(doc, [
495
+ ...spots.filter((s) => s.to > s.from).map((s) => Decoration2.inline(s.from, s.to, { class: s.id === active ? "w100n-text-note is-active" : "w100n-text-note", "data-note": s.id })),
496
+ ...pending2 && pending2.to > pending2.from ? [Decoration2.inline(pending2.from, pending2.to, { class: "w100n-text-note is-active" })] : []
497
+ ]);
498
+ var remap = (tr) => {
499
+ const start = tr.before.content.findDiffStart(tr.doc.content);
500
+ if (!tr.getMeta(ySyncPluginKey) || start === null) return tr.mapping;
501
+ let { a, b } = tr.before.content.findDiffEnd(tr.doc.content);
502
+ if (a < start) [a, b] = [start, b + start - a];
503
+ if (b < start) [a, b] = [a + start - b, start];
504
+ return new StepMap([start, a - start, b - start]);
505
+ };
506
+ var Notes = Extension2.create({
507
+ name: "notes",
508
+ addProseMirrorPlugins: () => [new Plugin2({
509
+ key: notes,
510
+ state: {
511
+ init: (_config, state) => ({ spots: [], active: null, pending: null, set: DecorationSet2.create(state.doc, []) }),
512
+ apply(tr, value2) {
513
+ const next = tr.getMeta(notes);
514
+ if (!next && (!tr.docChanged || !value2.spots.length && !value2.pending)) return value2;
515
+ const by = remap(tr);
516
+ const map = (r) => ({ ...r, from: by.map(r.from, 1), to: by.map(r.to, -1) });
517
+ const merged = { ...value2, spots: value2.spots.map(map), pending: value2.pending && map(value2.pending), ...next };
518
+ return { ...merged, set: paint(tr.doc, merged.spots, merged.active, merged.pending) };
519
+ }
520
+ },
521
+ props: { decorations: (state) => notes.getState(state).set }
522
+ })]
523
+ });
524
+ function kit(kind, t, live) {
525
+ return [
526
+ StarterKit.configure({ trailingNode: false, link: { openOnClick: false, autolink: true, defaultProtocol: "https" }, dropcursor: { color: "#8b5cf6", width: 2 }, ...live ? { undoRedo: false } : {} }),
527
+ TaskList,
528
+ TaskItem.configure({ nested: true, a11y: { checkboxLabel: (node) => node.textContent || t.tasks } }),
529
+ TableKit.configure({ table: { resizable: false } }),
530
+ Image.configure({ inline: true, allowBase64: true }),
531
+ Highlight.configure({ multicolor: true }),
532
+ TextStyle,
533
+ Color,
534
+ FontSize,
535
+ FontFamily,
536
+ Blocks,
537
+ PageBreak.configure({ label: t.pageBreak }),
538
+ Toc.configure({ relative: kind === "markdown", label: t.toc, empty: t.tocEmpty }),
539
+ Note,
540
+ Notes,
541
+ ...kind === "docx" ? [Pager, Locks.configure({ label: t.locked }), revision("insertion", "ins"), revision("deletion", "del"), Suggest] : [],
542
+ ...live ? [Collaboration.configure({ document: live.doc }), CollaborationCaret.configure({ provider: live.link, user: live.user })] : []
543
+ ];
544
+ }
545
+ var textblocks = (editor, change) => editor.chain().focus().command(({ tr, state }) => {
546
+ state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos) => {
547
+ if (!node.isTextblock) return true;
548
+ for (const [key2, value2] of Object.entries(change(node.attrs))) if (node.attrs[key2] !== value2) tr.setNodeAttribute(pos, key2, value2);
549
+ return false;
550
+ });
551
+ return true;
552
+ }).run();
553
+ var align = (editor, value2) => textblocks(editor, () => ({ align: value2 === "left" ? null : value2 }));
554
+ var indent = (editor, step) => {
555
+ const type = editor.isActive("taskItem") ? "taskItem" : editor.isActive("listItem") ? "listItem" : null;
556
+ if (type) return step > 0 ? editor.chain().focus().sinkListItem(type).run() : editor.chain().focus().liftListItem(type).run();
557
+ return textblocks(editor, (attrs2) => ({ indent: Math.min(8, Math.max(0, Number(attrs2.indent) + step)) }));
558
+ };
559
+ var clear = (editor) => {
560
+ const chain = editor.chain().focus();
561
+ for (const mark of ["bold", "italic", "underline", "strike", "code", "highlight", "textStyle"]) chain.unsetMark(mark);
562
+ chain.run();
563
+ return textblocks(editor, () => ({ align: null, indent: 0 }));
564
+ };
565
+ function locate(doc, list) {
566
+ if (!list.length) return [];
567
+ const marked2 = /* @__PURE__ */ new Map();
568
+ doc.descendants((node, pos) => {
569
+ if (!node.isText) return;
570
+ for (const mark of node.marks) {
571
+ if (mark.type.name !== "comment") continue;
572
+ const found = marked2.get(mark.attrs.id);
573
+ if (found) Object.assign(found, { to: pos + node.nodeSize, text: found.text + node.text });
574
+ else marked2.set(mark.attrs.id, { from: pos, to: pos + node.nodeSize, text: node.text });
575
+ }
576
+ });
577
+ const claimed = /* @__PURE__ */ new Set();
578
+ const search = (quote) => {
579
+ const line = quote.split("\n").find((part) => part.trim())?.trim();
580
+ let hit = null;
581
+ if (line) doc.descendants((node, pos) => {
582
+ if (hit) return false;
583
+ if (!node.isTextblock) return true;
584
+ const at = node.textBetween(0, node.content.size, void 0, "\uFFFC").indexOf(line);
585
+ if (at >= 0) hit = { from: pos + 1 + at, to: pos + 1 + at + line.length };
586
+ return false;
587
+ });
588
+ return hit;
589
+ };
590
+ return list.flatMap((c) => {
591
+ const own = [c.anchor, c.id].find((id) => id && marked2.has(id));
592
+ let range = own ? marked2.get(own) : void 0;
593
+ if (!range) {
594
+ const twin = [...marked2].find(([id, m]) => !claimed.has(id) && m.text === c.quote);
595
+ if (twin) {
596
+ claimed.add(twin[0]);
597
+ range = twin[1];
598
+ }
599
+ }
600
+ range ?? (range = search(c.quote));
601
+ return range ? [{ id: c.id, from: range.from, to: range.to }] : [];
602
+ });
603
+ }
604
+
605
+ // src/editor/markdown.ts
606
+ import { marked } from "marked";
607
+ import { MarkdownSerializer } from "prosemirror-markdown";
608
+ var tags = { u: "underline", ins: "underline", mark: "highlight", s: "strike", del: "strike", b: "bold", strong: "bold", i: "italic", em: "italic" };
609
+ var decode = (text) => text.includes("&") ? new DOMParser().parseFromString(`<p>${text.replace(/</g, "&lt;")}</p>`, "text/html").body.textContent ?? text : text;
610
+ var unique = (marks) => [...new Map(marks.map((m) => [m.type, m])).values()];
611
+ function inline(tokens = [], outer = []) {
612
+ const out = [];
613
+ let open = [];
614
+ const marks = () => unique([...outer, ...open]);
615
+ const text = (value2, extra = []) => {
616
+ const set = unique([...marks(), ...extra]);
617
+ const clean = out[out.length - 1]?.type === "hardBreak" ? value2.replace(/^\n/, "") : value2;
618
+ if (clean) out.push({ type: "text", text: clean, ...set.length ? { marks: set } : {} });
619
+ };
620
+ const wrap = (children, mark) => out.push(...inline(children, [...marks(), mark]));
621
+ for (const token of tokens) {
622
+ if (token.type === "text") {
623
+ if (token.tokens) out.push(...inline(token.tokens, marks()));
624
+ else text(decode(token.text));
625
+ } else if (token.type === "escape") text(decode(token.text));
626
+ else if (token.type === "strong") wrap(token.tokens, { type: "bold" });
627
+ else if (token.type === "em") wrap(token.tokens, { type: "italic" });
628
+ else if (token.type === "del") wrap(token.tokens, { type: "strike" });
629
+ else if (token.type === "codespan") text(token.text, [{ type: "code" }]);
630
+ else if (token.type === "br") out.push({ type: "hardBreak" });
631
+ else if (token.type === "link") wrap(token.tokens, { type: "link", attrs: { href: token.href } });
632
+ else if (token.type === "image") out.push({ type: "image", attrs: { src: token.href, alt: token.text || null, title: token.title || null }, ...marks().length ? { marks: marks() } : {} });
633
+ else if (token.type === "html") {
634
+ const tag = /^<(\/?)([a-z]+)\s*\/?>$/i.exec(token.raw.trim());
635
+ const name = tag?.[2].toLowerCase() ?? "";
636
+ if (name === "br") out.push({ type: "hardBreak" });
637
+ else if (!tags[name]) text(token.raw);
638
+ else open = tag[1] ? open.filter((m) => m.type !== tags[name]) : [...open, { type: tags[name] }];
639
+ } else if (token.type !== "checkbox") text(token.raw);
640
+ }
641
+ return out;
642
+ }
643
+ var fill = (content) => content.length ? content : [{ type: "paragraph" }];
644
+ function block(token, hints) {
645
+ const ref = (hint) => {
646
+ const id = `md${Object.keys(hints).length + 1}`;
647
+ hints[id] = hint;
648
+ return id;
649
+ };
650
+ switch (token.type) {
651
+ case "space":
652
+ case "def":
653
+ case "checkbox":
654
+ return [];
655
+ case "heading":
656
+ return [{ type: "heading", attrs: { level: token.depth }, content: inline(token.tokens) }];
657
+ case "paragraph":
658
+ case "text":
659
+ return [{ type: "paragraph", content: token.tokens ? inline(token.tokens) : inline([{ type: "text", raw: token.text, text: token.text }]) }];
660
+ case "blockquote":
661
+ return [{ type: "blockquote", content: fill(token.tokens.flatMap((t) => block(t, hints))) }];
662
+ case "code": {
663
+ const fence = /^ {0,3}(`{3,}|~{3,})/.exec(token.raw)?.[1][0];
664
+ return [{ type: "codeBlock", attrs: { language: token.lang || null, ref: fence ? ref({ fence: fence.repeat(3) }) : null }, content: token.text ? [{ type: "text", text: token.text }] : [] }];
665
+ }
666
+ case "html":
667
+ return [{ type: "codeBlock", attrs: { language: "html" }, content: [{ type: "text", text: token.raw.replace(/\n+$/, "") }] }];
668
+ case "hr":
669
+ return [{ type: "horizontalRule" }];
670
+ case "list": {
671
+ const list = token;
672
+ const tasks = list.items.every((entry2) => entry2.task);
673
+ const marker = /^\s*(?:([-*+])|\d+([.)]))/.exec(list.raw);
674
+ const id = ref({ bullet: marker?.[1], delim: marker?.[2], loose: list.loose });
675
+ return [{
676
+ type: tasks ? "taskList" : list.ordered ? "orderedList" : "bulletList",
677
+ attrs: list.ordered && !tasks ? { start: list.start === "" ? 1 : Number(list.start), ref: id } : { ref: id },
678
+ content: list.items.map((entry2) => {
679
+ const content = fill(entry2.tokens.flatMap((t) => block(t, hints)));
680
+ if (!tasks && entry2.task) content[0].content = [{ type: "text", text: entry2.checked ? "[x] " : "[ ] " }, ...content[0].content ?? []];
681
+ return tasks ? { type: "taskItem", attrs: { checked: !!entry2.checked }, content } : { type: "listItem", content };
682
+ })
683
+ }];
684
+ }
685
+ case "table": {
686
+ const table = token;
687
+ const cell2 = (type) => (c, i) => ({ type, attrs: { align: table.align[i] }, content: [{ type: "paragraph", content: inline(c.tokens) }] });
688
+ return [{ type: "table", content: [
689
+ { type: "tableRow", content: table.header.map(cell2("tableHeader")) },
690
+ ...table.rows.map((row2) => ({ type: "tableRow", content: row2.map(cell2("tableCell")) }))
691
+ ] }];
692
+ }
693
+ default:
694
+ return [{ type: "paragraph", content: inline([{ type: "text", raw: token.raw, text: token.raw }]) }];
695
+ }
696
+ }
697
+ var opens = /^\s*<!--\s*toc\s*-->\s*$/i;
698
+ var shuts = /^\s*<!--\s*\/toc\s*-->\s*$/i;
699
+ var row = /^(\s*)[-*+]\s+\[((?:\\.|[^\]\\])*)\]\(#[^)\s]*\)\s*$/;
700
+ function contents(tokens, i) {
701
+ if (tokens[i].type !== "html" || !opens.test(tokens[i].raw)) return null;
702
+ let j = i + 1;
703
+ const skip2 = () => {
704
+ while (tokens[j]?.type === "space") j++;
705
+ };
706
+ skip2();
707
+ const list = tokens[j]?.type === "list" ? tokens[j++] : null;
708
+ skip2();
709
+ if (tokens[j]?.type !== "html" || !shuts.test(tokens[j].raw)) return null;
710
+ const rows = list ? list.raw.split("\n").filter((line) => line.trim()).map((line) => row.exec(line)) : [];
711
+ if (rows.some((r) => !r)) return null;
712
+ const steps = [...new Set(rows.map((r) => r[1].length))].sort((a, b) => a - b);
713
+ return { end: j, entries: rows.map((r) => [steps.indexOf(r[1].length) + 1, r[2].replace(/\\(.)/g, "$1")]) };
714
+ }
715
+ var slug = (text, seen2) => {
716
+ const base = text.toLowerCase().replace(/[^\p{L}\p{N}\s_-]/gu, "").trim().replace(/\s/g, "-");
717
+ const n = seen2.get(base) ?? 0;
718
+ seen2.set(base, n + 1);
719
+ return n ? `${base}-${n}` : base;
720
+ };
721
+ function sniff(tokens) {
722
+ const style = { bullet: "-", delim: ".", em: "*", strong: "**", fence: "```", br: "\\\n", loose: false };
723
+ const seen2 = /* @__PURE__ */ new Set();
724
+ const note = (key2, value2) => {
725
+ if (seen2.has(key2)) return;
726
+ seen2.add(key2);
727
+ style[key2] = value2;
728
+ };
729
+ let loose = 0;
730
+ marked.walkTokens(tokens, (token) => {
731
+ if (token.type === "list") {
732
+ const marker = /^\s*(?:([-*+])|\d+([.)]))/.exec(token.raw);
733
+ if (token.ordered) note("delim", marker?.[2] ?? ".");
734
+ else note("bullet", marker?.[1] ?? "-");
735
+ loose += token.loose ? 1 : -1;
736
+ } else if (token.type === "em") note("em", token.raw[0]);
737
+ else if (token.type === "strong") note("strong", token.raw.slice(0, 2));
738
+ else if (token.type === "code" && /^ {0,3}(```|~~~)/.test(token.raw)) note("fence", token.raw.trimStart().slice(0, 3));
739
+ else if (token.type === "br" && token.raw !== "<br>") note("br", token.raw.startsWith("\\") ? "\\\n" : " \n");
740
+ });
741
+ style.loose = loose > 0;
742
+ return style;
743
+ }
744
+ function fromMarkdown(source) {
745
+ const bom = source.startsWith("\uFEFF");
746
+ const crlf = source.includes("\r\n");
747
+ const tokens = marked.lexer(source.slice(bom ? 1 : 0).replace(/\r\n?/g, "\n"));
748
+ const hints = {};
749
+ const content = [];
750
+ const raws = [];
751
+ let head = "";
752
+ let gap = "";
753
+ for (let i = 0; i < tokens.length; i++) {
754
+ const token = tokens[i];
755
+ const toc = contents(tokens, i);
756
+ const made2 = toc ? [{ type: "toc", attrs: { entries: JSON.stringify(toc.entries) } }] : block(token, hints);
757
+ if (!made2.length) {
758
+ gap += token.raw;
759
+ continue;
760
+ }
761
+ if (raws.length) raws[raws.length - 1] += gap;
762
+ else head = gap;
763
+ gap = "";
764
+ content.push(...made2);
765
+ raws.push(toc ? tokens.slice(i, toc.end + 1).map((t) => t.raw).join("") : token.raw);
766
+ if (toc) i = toc.end;
767
+ }
768
+ if (!content.length) {
769
+ content.push({ type: "paragraph" });
770
+ raws.push("");
771
+ head = "";
772
+ }
773
+ return { doc: { type: "doc", content }, raws, head, tail: gap, style: sniff(tokens), hints, crlf, bom };
774
+ }
775
+ var track = ({ doc: _json, ...parsed }, doc) => {
776
+ const nodes = [];
777
+ doc.forEach((node) => nodes.push(node));
778
+ return nodes.length === parsed.raws.length ? { ...parsed, nodes } : { ...parsed, nodes: [], raws: [], head: "", tail: "\n" };
779
+ };
780
+ var ticks = (node, side) => {
781
+ const len = Math.max(0, ...(node.isText ? node.text.match(/`+/g) ?? [] : []).map((run) => run.length));
782
+ return len ? side > 0 ? ` ${"`".repeat(len + 1)}` : `${"`".repeat(len + 1)} ` : "`";
783
+ };
784
+ var plain2 = (mark, parent, index) => {
785
+ const node = parent.child(index);
786
+ const href = mark.attrs.href;
787
+ if (!node.isText || node.marks.length !== 1 || index + 1 < parent.childCount && mark.isInSet(parent.child(index + 1).marks)) return null;
788
+ const text = node.text;
789
+ if (text !== href && `mailto:${text}` !== href && !(text.startsWith("www.") && `http://${text}` === href)) return null;
790
+ const before = index ? parent.child(index - 1) : null;
791
+ const after = index + 1 < parent.childCount ? parent.child(index + 1) : null;
792
+ const left = before ? before.isText ? before.text.slice(-1) : "x" : "";
793
+ const right = after ? after.isText ? after.text : "x" : "";
794
+ return /^[\s(*_~]?$/.test(left) && /^([\s)]|[.,:;!?]+(\s|$)|$)/.test(right) ? "bare" : text === href || href.startsWith("mailto:") ? "angle" : null;
795
+ };
796
+ function serializer(style, hints, before, cell2 = false) {
797
+ let form = null;
798
+ const hint = (node) => hints[node.attrs.ref] ?? {};
799
+ const run = (parent, index, types) => {
800
+ let n = 0;
801
+ for (let i = index - 1; i >= 0 && types.includes(parent.child(i).type.name); i--) n++;
802
+ if (!index && before && types.includes(before.type.name)) n++;
803
+ return n % 2;
804
+ };
805
+ const tight = (state, node, render) => {
806
+ const deep = node.content.content.some((entry2) => entry2.content.content.filter((child) => !child.type.name.endsWith("List")).length > 1);
807
+ const was = state.options.tightLists;
808
+ state.options.tightLists = !deep && !(hint(node).loose ?? style.loose);
809
+ render();
810
+ state.options.tightLists = was;
811
+ };
812
+ const list = (state, node, parent, index) => {
813
+ const bullet = hint(node).bullet ?? (run(parent, index, ["bulletList", "taskList"]) ? style.bullet === "-" ? "*" : "-" : style.bullet);
814
+ tight(state, node, () => state.renderList(node, " ", () => `${bullet} `));
815
+ };
816
+ const blank2 = { open: "", close: "", mixable: true };
817
+ const wrap = (open, close = open) => ({ open, close, mixable: true, expelEnclosingWhitespace: true });
818
+ return new MarkdownSerializer({
819
+ paragraph(state, node) {
820
+ state.renderInline(node);
821
+ state.closeBlock(node);
822
+ },
823
+ heading(state, node) {
824
+ state.write(`${"#".repeat(node.attrs.level)} `);
825
+ state.renderInline(node, false);
826
+ state.closeBlock(node);
827
+ },
828
+ blockquote(state, node) {
829
+ state.wrapBlock("> ", null, node, () => state.renderContent(node));
830
+ },
831
+ codeBlock(state, node) {
832
+ const mark = (hint(node).fence ?? style.fence)[0];
833
+ const longest = Math.max(2, ...(node.textContent.match(new RegExp(`${mark}{3,}`, "g")) ?? []).map((r) => r.length));
834
+ const fence = mark.repeat(longest + 1);
835
+ state.write(`${fence}${node.attrs.language ?? ""}
836
+ `);
837
+ state.text(node.textContent, false);
838
+ state.ensureNewLine();
839
+ state.write(fence);
840
+ state.closeBlock(node);
841
+ },
842
+ horizontalRule(state, node) {
843
+ state.write("---");
844
+ state.closeBlock(node);
845
+ },
846
+ pageBreak(state, node) {
847
+ state.closeBlock(node);
848
+ },
849
+ toc(state, node) {
850
+ const seen2 = /* @__PURE__ */ new Map();
851
+ const lines2 = JSON.parse(node.attrs.entries).map(([level, text]) => `${" ".repeat(level - 1)}${style.bullet} [${text.replace(/[[\]\\]/g, "\\$&")}](#${slug(text, seen2)})
852
+ `);
853
+ state.write(`<!-- toc -->
854
+ ${lines2.join("")}<!-- /toc -->`);
855
+ state.closeBlock(node);
856
+ },
857
+ bulletList: list,
858
+ taskList: list,
859
+ orderedList(state, node, parent, index) {
860
+ const start = node.attrs.start ?? 1;
861
+ const delim = hint(node).delim ?? (run(parent, index, ["orderedList"]) ? style.delim === "." ? ")" : "." : style.delim);
862
+ const width = String(start + node.childCount - 1).length;
863
+ tight(state, node, () => state.renderList(node, " ".repeat(width + 2), (i) => `${start + i}${delim} `));
864
+ },
865
+ listItem(state, node) {
866
+ state.renderContent(node);
867
+ },
868
+ taskItem(state, node) {
869
+ state.write(node.attrs.checked ? "[x] " : "[ ] ");
870
+ state.renderContent(node);
871
+ },
872
+ table(state, node) {
873
+ const rows = [];
874
+ const aligns = [];
875
+ node.forEach((row2, _, r) => {
876
+ const cells = [];
877
+ row2.forEach((c) => {
878
+ const span2 = c.attrs.colspan || 1;
879
+ const text = [];
880
+ c.forEach((child) => text.push(serializer(style, hints, null, true).serialize(c.type.schema.topNodeType.create(null, child)).replace(/\n+/g, " ")));
881
+ if (!r) aligns.push(c.attrs.align, ...Array(span2 - 1).fill(null));
882
+ cells.push(text.join("<br>").replace(/\|/g, "\\|"), ...Array(span2 - 1).fill(""));
883
+ });
884
+ rows.push(cells);
885
+ });
886
+ const width = Math.max(...rows.map((r) => r.length));
887
+ const line = (cells) => `| ${[...cells, ...Array(width - cells.length).fill("")].join(" | ")} |`;
888
+ const rule = Array.from({ length: width }, (_, i) => ({ left: ":---", center: ":---:", right: "---:" })[aligns[i] ?? ""] ?? "---");
889
+ [line(rows[0]), `| ${rule.join(" | ")} |`, ...rows.slice(1).map(line)].forEach((text, i) => {
890
+ if (i) state.ensureNewLine();
891
+ state.write(text);
892
+ });
893
+ state.closeBlock(node);
894
+ },
895
+ image(state, node) {
896
+ const src = String(node.attrs.src ?? "");
897
+ const title = node.attrs.title ? ` "${String(node.attrs.title).replace(/"/g, '\\"')}"` : "";
898
+ state.write(`![${state.esc(String(node.attrs.alt ?? ""))}](${/\s/.test(src) ? `<${src}>` : src.replace(/[()]/g, "\\$&")}${title})`);
899
+ },
900
+ hardBreak(state, node, parent, index) {
901
+ for (let i = index + 1; i < parent.childCount; i++) {
902
+ if (parent.child(i).type === node.type) continue;
903
+ state.write(cell2 ? "<br>" : style.br);
904
+ return;
905
+ }
906
+ },
907
+ text(state, node) {
908
+ state.text(node.text, !state.inAutolink);
909
+ }
910
+ }, {
911
+ italic: wrap(style.em),
912
+ bold: wrap(style.strong),
913
+ strike: wrap("~~"),
914
+ underline: wrap("<u>", "</u>"),
915
+ highlight: wrap("<mark>", "</mark>"),
916
+ textStyle: blank2,
917
+ comment: blank2,
918
+ link: {
919
+ open(state, mark, parent, index) {
920
+ form = plain2(mark, parent, index);
921
+ state.inAutolink = !!form;
922
+ return form === "bare" ? "" : form === "angle" ? "<" : "[";
923
+ },
924
+ close(state, mark) {
925
+ state.inAutolink = void 0;
926
+ const was = form;
927
+ form = null;
928
+ return was === "bare" ? "" : was === "angle" ? ">" : `](${String(mark.attrs.href).replace(/[()"]/g, "\\$&")})`;
929
+ },
930
+ mixable: true
931
+ },
932
+ code: { open: (_s, _m, parent, index) => ticks(parent.child(index), -1), close: (_s, _m, parent, index) => ticks(parent.child(index - 1), 1), escape: false }
933
+ }, { hardBreakNodeName: "hardBreak", strict: false, escapeExtraCharacters: /<(?=[A-Za-z/!?])/g });
934
+ }
935
+ var one = (node, before, base) => serializer(base.style, base.hints, before).serialize(node.type.schema.topNodeType.create(null, node)).replace(/\n+$/, "");
936
+ function toMarkdown(doc, base) {
937
+ const nodes = [];
938
+ const found = [];
939
+ let j = 0;
940
+ doc.forEach((node) => {
941
+ let k = -1;
942
+ for (let m = j; m < Math.min(base.nodes.length, j + 64) && k < 0; m++) if (base.nodes[m] === node || base.nodes[m].eq(node)) k = m;
943
+ if (k >= 0) j = k + 1;
944
+ nodes.push(node);
945
+ found.push(k);
946
+ });
947
+ let out = base.head;
948
+ const starts = [];
949
+ nodes.forEach((node, i) => {
950
+ const k = found[i];
951
+ if (i && !(k >= 0 && found[i - 1] === k - 1)) out = out.replace(/\n*$/, "\n\n");
952
+ starts.push(out.length);
953
+ out += k >= 0 ? base.raws[k] : one(node, i ? nodes[i - 1] : null, base);
954
+ });
955
+ const last = found[found.length - 1];
956
+ const end = last >= 0 && last === base.nodes.length - 1;
957
+ if (!end) out = out.replace(/\n*$/, "\n");
958
+ const cut = out.length;
959
+ out += end ? base.tail : base.tail.trim() ? `
960
+ ${base.tail.replace(/^\n+/, "")}` : "";
961
+ const at = starts.map((s) => Math.min(s, cut));
962
+ const raws = at.map((s, i) => out.slice(s, i + 1 < at.length ? at[i + 1] : cut));
963
+ const text = base.crlf ? out.replace(/\n/g, "\r\n") : out;
964
+ return { text: base.bom ? `\uFEFF${text}` : text, base: { ...base, nodes, raws, tail: out.slice(cut) } };
965
+ }
966
+
967
+ // src/sheets/model.ts
968
+ var SheetRefusal = class extends Error {
969
+ constructor(code, sheet = "") {
970
+ super(code);
971
+ this.code = code;
972
+ this.sheet = sheet;
973
+ }
974
+ };
975
+ var counter = 0;
976
+ var fresh = (prefix) => `${prefix}${Date.now().toString(36)}${(counter++).toString(36)}${Math.random().toString(36).slice(2, 6)}`;
977
+ var numbered = (prefix, count) => Array.from({ length: count }, (_, i) => `${prefix}${i}`);
978
+ function insert(list, at, count, prefix) {
979
+ list.splice(at, 0, ...Array.from({ length: count }, () => fresh(prefix)));
980
+ }
981
+ function move(list, from, count, to) {
982
+ const taken = list.splice(from, count);
983
+ list.splice(to > from ? to - count : to, 0, ...taken);
984
+ }
985
+ function resize(list, count, prefix) {
986
+ if (list.length > count) list.length = count;
987
+ else insert(list, list.length, count - list.length, prefix);
988
+ }
989
+ function rebase(model, lines2, sheets) {
990
+ model.origin = { sheets, lines: Object.fromEntries(Object.entries(lines2).map(([id, l]) => [id, { rows: [...l.rows], cols: [...l.cols] }])) };
991
+ }
992
+
993
+ // src/sheets/csv.ts
994
+ function decode2(bytes) {
995
+ if (bytes[0] === 239 && bytes[1] === 187 && bytes[2] === 191) return { text: new TextDecoder("utf-8").decode(bytes.subarray(3)), encoding: "utf-8", bom: true };
996
+ if (bytes[0] === 255 && bytes[1] === 254) return { text: new TextDecoder("utf-16le").decode(bytes.subarray(2)), encoding: "utf-16le", bom: true };
997
+ if (bytes[0] === 254 && bytes[1] === 255) return { text: new TextDecoder("utf-16be").decode(bytes.subarray(2)), encoding: "utf-16be", bom: true };
998
+ try {
999
+ return { text: new TextDecoder("utf-8", { fatal: true }).decode(bytes), encoding: "utf-8", bom: false };
1000
+ } catch {
1001
+ const scored = ["windows-1252", "windows-1250", "windows-1251"].map((encoding) => {
1002
+ const text = new TextDecoder(encoding).decode(bytes);
1003
+ let score = 0;
1004
+ for (const [word] of text.matchAll(/\p{L}+/gu)) {
1005
+ const cyrillic = (word.match(/\p{Script=Cyrillic}/gu) ?? []).length;
1006
+ const accented = (word.match(/[^\x00-\x7f\p{Script=Cyrillic}]/gu) ?? []).length;
1007
+ if (cyrillic === word.length || !cyrillic && accented * 2 <= word.length) score += 1;
1008
+ else score -= 1;
1009
+ }
1010
+ score -= 3 * (text.match(/\p{L}[^\p{L}\x00-\x7f]|[^\p{L}\x00-\x7f]\p{L}/gu) ?? []).length;
1011
+ return { text, encoding, score };
1012
+ });
1013
+ const best = scored.reduce((a, b) => b.score > a.score ? b : a);
1014
+ return { text: best.text, encoding: best.encoding, bom: false };
1015
+ }
1016
+ }
1017
+ function encode(text, encoding, bom) {
1018
+ if (encoding === "utf-8") {
1019
+ const body = new TextEncoder().encode(text);
1020
+ if (!bom) return body;
1021
+ const out2 = new Uint8Array(body.length + 3);
1022
+ out2.set([239, 187, 191]);
1023
+ out2.set(body, 3);
1024
+ return out2;
1025
+ }
1026
+ if (encoding === "utf-16le" || encoding === "utf-16be") {
1027
+ const out2 = new Uint8Array(text.length * 2 + (bom ? 2 : 0));
1028
+ const view = new DataView(out2.buffer);
1029
+ let at = 0;
1030
+ if (bom) {
1031
+ view.setUint16(0, 65279, encoding === "utf-16le");
1032
+ at = 2;
1033
+ }
1034
+ for (let i = 0; i < text.length; i++) view.setUint16(at + i * 2, text.charCodeAt(i), encoding === "utf-16le");
1035
+ return out2;
1036
+ }
1037
+ const table = /* @__PURE__ */ new Map();
1038
+ const decoder2 = new TextDecoder(encoding);
1039
+ for (let b = 255; b >= 0; b--) table.set(decoder2.decode(new Uint8Array([b])), b);
1040
+ const out = new Uint8Array(text.length);
1041
+ for (let i = 0; i < text.length; i++) out[i] = table.get(text[i]) ?? 63;
1042
+ return out;
1043
+ }
1044
+ function split(text, delimiter, limit = Infinity) {
1045
+ const rows = [];
1046
+ let row2 = [];
1047
+ let i = 0;
1048
+ const n = text.length;
1049
+ while (i <= n && rows.length < limit) {
1050
+ const start = i;
1051
+ let value2 = "";
1052
+ if (text[i] === '"') {
1053
+ i++;
1054
+ while (i < n) {
1055
+ if (text[i] === '"') {
1056
+ if (text[i + 1] === '"') {
1057
+ value2 += '"';
1058
+ i += 2;
1059
+ continue;
1060
+ }
1061
+ i++;
1062
+ break;
1063
+ }
1064
+ value2 += text[i++];
1065
+ }
1066
+ while (i < n && text[i] !== delimiter && text[i] !== "\n" && text[i] !== "\r") value2 += text[i++];
1067
+ } else {
1068
+ while (i < n && text[i] !== delimiter && text[i] !== "\n" && text[i] !== "\r") i++;
1069
+ value2 = text.slice(start, i);
1070
+ }
1071
+ row2.push({ text: value2, raw: text.slice(start, i) });
1072
+ if (i >= n) {
1073
+ rows.push(row2);
1074
+ break;
1075
+ }
1076
+ if (text[i] === delimiter) {
1077
+ i++;
1078
+ continue;
1079
+ }
1080
+ i += text[i] === "\r" && text[i + 1] === "\n" ? 2 : 1;
1081
+ rows.push(row2);
1082
+ row2 = [];
1083
+ if (i >= n) break;
1084
+ }
1085
+ return rows;
1086
+ }
1087
+ function sniff2(text) {
1088
+ let best = ",", score = -1;
1089
+ for (const d of [",", ";", " ", "|"]) {
1090
+ const rows = split(text, d, 30).filter((r) => r.length > 1 || r[0]?.text);
1091
+ if (!rows.length) continue;
1092
+ const counts = /* @__PURE__ */ new Map();
1093
+ for (const r of rows) counts.set(r.length, (counts.get(r.length) ?? 0) + 1);
1094
+ const [width, often] = [...counts].sort((a, b) => b[1] - a[1] || b[0] - a[0])[0];
1095
+ const s = width > 1 ? often * 100 + width : 0;
1096
+ if (s > score) {
1097
+ score = s;
1098
+ best = d;
1099
+ }
1100
+ }
1101
+ return best;
1102
+ }
1103
+ var numeric = (s, decimal) => decimal === "," ? /^-?(0|[1-9]\d*)(,\d+)?$/.test(s) : /^-?(0|[1-9]\d*)(\.\d+)?([eE][-+]?\d+)?$/.test(s);
1104
+ function readCsv(bytes) {
1105
+ const { text, encoding, bom } = decode2(new Uint8Array(bytes));
1106
+ const delimiter = sniff2(text);
1107
+ const eol = /\r\n/.test(text) ? "\r\n" : /\r(?!\n)/.test(text) && !text.includes("\n") ? "\r" : "\n";
1108
+ const rows = split(text, delimiter);
1109
+ const end = /[\r\n]$/.test(text);
1110
+ if (end && rows.length && rows[rows.length - 1].length === 1 && rows[rows.length - 1][0].raw === "") rows.pop();
1111
+ let commas = 0, dots = 0;
1112
+ if (delimiter !== ",") for (const r of rows) for (const f of r) {
1113
+ if (/^-?\d+,\d+$/.test(f.text)) commas++;
1114
+ else if (/^-?\d+\.\d+$/.test(f.text)) dots++;
1115
+ }
1116
+ const decimal = commas > dots ? "," : ".";
1117
+ const cellData = {};
1118
+ let width = 0;
1119
+ rows.forEach((r, i) => {
1120
+ width = Math.max(width, r.length);
1121
+ r.forEach((f, c) => {
1122
+ if (f.text === "") return;
1123
+ (cellData[i] ?? (cellData[i] = {}))[c] = numeric(f.text, decimal) ? { v: Number(decimal === "," ? f.text.replace(",", ".") : f.text), t: 2 } : { v: f.text, t: 1 };
1124
+ });
1125
+ });
1126
+ const height = Math.max(rows.length + 100, 1e3);
1127
+ const cols = Math.max(width + 4, 26);
1128
+ const format = { delimiter, encoding, bom, eol, decimal, end };
1129
+ const book = {
1130
+ id: "book",
1131
+ name: "",
1132
+ appVersion: "",
1133
+ locale: "enUS",
1134
+ styles: {},
1135
+ sheetOrder: ["s1"],
1136
+ sheets: { s1: { id: "s1", name: "Sheet1", rowCount: height, columnCount: cols, cellData, defaultColumnWidth: 88, defaultRowHeight: 24 } }
1137
+ };
1138
+ return { book, csv: format, lines: { s1: { rows: numbered("r", height), cols: numbered("c", cols) } }, origin: { sheets: { s1: 1 }, lines: { s1: { rows: numbered("r", height), cols: numbered("c", cols) } } } };
1139
+ }
1140
+ function value(x) {
1141
+ if (!x) return null;
1142
+ const stream = x.p?.body?.dataStream;
1143
+ if (stream !== void 0 && (x.v === void 0 || x.v === null || x.v === "")) return stream.replace(/\r?\n$/, "").replace(/\r\n?/g, "\n");
1144
+ if (x.t === 3 && typeof x.v === "number") return x.v === 1;
1145
+ return x.v ?? null;
1146
+ }
1147
+ function writeCsv(original, model) {
1148
+ const { text } = decode2(new Uint8Array(original));
1149
+ const format = model.csv ?? readCsv(original).csv;
1150
+ const old = split(text, format.delimiter);
1151
+ if (format.end && old.length && old[old.length - 1].length === 1 && old[old.length - 1][0].raw === "") old.pop();
1152
+ const sid = model.book.sheetOrder[0];
1153
+ const sheet = model.book.sheets[sid];
1154
+ const cells = sheet.cellData ?? {};
1155
+ const lines2 = model.lines[sid], origin = model.origin.lines[sid] ?? lines2;
1156
+ const rowFrom = new Map(origin.rows.map((id, i) => [id, i])), colFrom = new Map(origin.cols.map((id, i) => [id, i]));
1157
+ const quote = (s) => s.includes(format.delimiter) || s.includes('"') || s.includes("\n") || s.includes("\r") ? `"${s.replace(/"/g, '""')}"` : s;
1158
+ const show = (v) => {
1159
+ if (v === null || v === void 0) return "";
1160
+ if (typeof v === "boolean") return v ? "TRUE" : "FALSE";
1161
+ if (typeof v === "number") return format.decimal === "," ? String(v).replace(".", ",") : String(v);
1162
+ return String(v);
1163
+ };
1164
+ const last = Math.max(-1, ...Object.keys(cells).map(Number).filter((r) => Object.values(cells[r] ?? {}).some((x) => show(value(x)) !== "")));
1165
+ const out = [];
1166
+ for (let r = 0; r <= last; r++) {
1167
+ const r0 = rowFrom.get(lines2.rows[r]) ?? -1;
1168
+ const was = r0 >= 0 ? old[r0] : void 0;
1169
+ const line = cells[r] ?? {};
1170
+ const filled2 = Object.keys(line).map(Number).filter((c) => show(value(line[c])) !== "");
1171
+ let count = filled2.length ? Math.max(...filled2) + 1 : 0;
1172
+ if (was) for (let c0 = 0; c0 < was.length; c0++) count = Math.max(count, lines2.cols.indexOf(origin.cols[c0]) + 1);
1173
+ const fields = [];
1174
+ for (let c = 0; c < count; c++) {
1175
+ const c0 = colFrom.get(lines2.cols[c]) ?? -1;
1176
+ const before = was && c0 >= 0 ? was[c0] : void 0;
1177
+ const now = show(value(line[c]));
1178
+ if (before && now === before.text) fields.push(before.raw);
1179
+ else if (before && before.text !== "" && now !== "" && numeric(before.text, format.decimal) && Number(before.text.replace(",", ".")) === Number(now.replace(",", "."))) fields.push(before.raw);
1180
+ else fields.push(quote(now));
1181
+ }
1182
+ out.push(fields.join(format.delimiter));
1183
+ }
1184
+ const body = out.join(format.eol) + (format.end && out.length ? format.eol : "");
1185
+ const bytes = encode(body, format.encoding, format.bom);
1186
+ return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
1187
+ }
1188
+
1189
+ // src/sheets/pack.ts
1190
+ var decoder = new TextDecoder();
1191
+ var Pack = class {
1192
+ constructor(bytes) {
1193
+ this.names = /* @__PURE__ */ new Map();
1194
+ this.changed = /* @__PURE__ */ new Map();
1195
+ this.entries = unzip(new Uint8Array(bytes));
1196
+ this.entries.forEach((e, i) => this.names.set(e.name.replace(/^\//, ""), i));
1197
+ }
1198
+ bytes(name) {
1199
+ const next = this.changed.get(name);
1200
+ if (next !== void 0) return typeof next === "string" ? new TextEncoder().encode(next) : next;
1201
+ const i = this.names.get(name);
1202
+ return i === void 0 ? null : inflate(this.entries[i]);
1203
+ }
1204
+ text(name) {
1205
+ const next = this.changed.get(name);
1206
+ if (typeof next === "string") return next;
1207
+ const bytes = this.bytes(name);
1208
+ return bytes && decoder.decode(bytes);
1209
+ }
1210
+ put(name, value2) {
1211
+ this.changed.set(name, value2);
1212
+ }
1213
+ rels(part) {
1214
+ const xml = this.text(relsOf(part));
1215
+ if (!xml) return [];
1216
+ const base = part.includes("/") ? part.slice(0, part.lastIndexOf("/") + 1) : "";
1217
+ return [...xml.matchAll(/<(?:\w+:)?Relationship\b[^>]*>/g)].map((m) => {
1218
+ const a = Object.fromEntries(attrs(m[0]));
1219
+ const external = a.TargetMode === "External";
1220
+ return { id: a.Id, type: a.Type.slice(a.Type.lastIndexOf("/") + 1), target: external ? a.Target : resolve(base, a.Target), external };
1221
+ });
1222
+ }
1223
+ build() {
1224
+ const out = [];
1225
+ const seen2 = /* @__PURE__ */ new Set();
1226
+ for (const e of this.entries) {
1227
+ const name = e.name.replace(/^\//, "");
1228
+ seen2.add(name);
1229
+ const next = this.changed.get(name);
1230
+ if (next === null) continue;
1231
+ out.push(next === void 0 ? e : entry(e.name, typeof next === "string" ? new TextEncoder().encode(next) : next, e));
1232
+ }
1233
+ const like = this.entries[0];
1234
+ for (const [name, next] of this.changed) if (!seen2.has(name) && next !== null) out.push(entry(name, typeof next === "string" ? new TextEncoder().encode(next) : next, like));
1235
+ return zip(out);
1236
+ }
1237
+ };
1238
+ var relsOf = (part) => {
1239
+ const i = part.lastIndexOf("/");
1240
+ return `${part.slice(0, i + 1)}_rels/${part.slice(i + 1)}.rels`;
1241
+ };
1242
+ function resolve(base, target) {
1243
+ if (target.startsWith("/")) return target.slice(1);
1244
+ const parts2 = (base + target).split("/");
1245
+ const out = [];
1246
+ for (const p of parts2) {
1247
+ if (p === "..") out.pop();
1248
+ else if (p !== "." && p !== "") out.push(p);
1249
+ }
1250
+ return out.join("/");
1251
+ }
1252
+ function relative(from, to) {
1253
+ const a = from.split("/").slice(0, -1), b = to.split("/");
1254
+ let i = 0;
1255
+ while (i < a.length && a[i] === b[i]) i++;
1256
+ return [...a.slice(i).map(() => ".."), ...b.slice(i)].join("/");
1257
+ }
1258
+
1259
+ // src/sheets/styles.ts
1260
+ var builtin = {
1261
+ 1: "0",
1262
+ 2: "0.00",
1263
+ 3: "#,##0",
1264
+ 4: "#,##0.00",
1265
+ 5: '"$"#,##0_);("$"#,##0)',
1266
+ 6: '"$"#,##0_);[Red]("$"#,##0)',
1267
+ 7: '"$"#,##0.00_);("$"#,##0.00)',
1268
+ 8: '"$"#,##0.00_);[Red]("$"#,##0.00)',
1269
+ 9: "0%",
1270
+ 10: "0.00%",
1271
+ 11: "0.00E+00",
1272
+ 12: "# ?/?",
1273
+ 13: "# ??/??",
1274
+ 14: "yyyy-mm-dd",
1275
+ 15: "d-mmm-yy",
1276
+ 16: "d-mmm",
1277
+ 17: "mmm-yy",
1278
+ 18: "h:mm AM/PM",
1279
+ 19: "h:mm:ss AM/PM",
1280
+ 20: "h:mm",
1281
+ 21: "h:mm:ss",
1282
+ 22: "yyyy-mm-dd h:mm",
1283
+ 37: "#,##0 ;(#,##0)",
1284
+ 38: "#,##0 ;[Red](#,##0)",
1285
+ 39: "#,##0.00;(#,##0.00)",
1286
+ 40: "#,##0.00;[Red](#,##0.00)",
1287
+ 45: "mm:ss",
1288
+ 46: "[h]:mm:ss",
1289
+ 47: "mmss.0",
1290
+ 48: "##0.0E+0",
1291
+ 49: "@"
1292
+ };
1293
+ var indexed = [
1294
+ "000000",
1295
+ "FFFFFF",
1296
+ "FF0000",
1297
+ "00FF00",
1298
+ "0000FF",
1299
+ "FFFF00",
1300
+ "FF00FF",
1301
+ "00FFFF",
1302
+ "000000",
1303
+ "FFFFFF",
1304
+ "FF0000",
1305
+ "00FF00",
1306
+ "0000FF",
1307
+ "FFFF00",
1308
+ "FF00FF",
1309
+ "00FFFF",
1310
+ "800000",
1311
+ "008000",
1312
+ "000080",
1313
+ "808000",
1314
+ "800080",
1315
+ "008080",
1316
+ "C0C0C0",
1317
+ "808080",
1318
+ "9999FF",
1319
+ "993366",
1320
+ "FFFFCC",
1321
+ "CCFFFF",
1322
+ "660066",
1323
+ "FF8080",
1324
+ "0066CC",
1325
+ "CCCCFF",
1326
+ "000080",
1327
+ "FF00FF",
1328
+ "FFFF00",
1329
+ "00FFFF",
1330
+ "800080",
1331
+ "800000",
1332
+ "008080",
1333
+ "0000FF",
1334
+ "00CCFF",
1335
+ "CCFFFF",
1336
+ "CCFFCC",
1337
+ "FFFF99",
1338
+ "99CCFF",
1339
+ "FF99CC",
1340
+ "CC99FF",
1341
+ "FFCC99",
1342
+ "3366FF",
1343
+ "33CCCC",
1344
+ "99CC00",
1345
+ "FFCC00",
1346
+ "FF9900",
1347
+ "FF6600",
1348
+ "666699",
1349
+ "969696",
1350
+ "003366",
1351
+ "339966",
1352
+ "003300",
1353
+ "333300",
1354
+ "993300",
1355
+ "993366",
1356
+ "333399",
1357
+ "333333",
1358
+ "000000",
1359
+ "FFFFFF"
1360
+ ];
1361
+ var lines = ["", "thin", "hair", "dotted", "dashed", "dashDot", "dashDotDot", "double", "medium", "mediumDashed", "mediumDashDot", "mediumDashDotDot", "slantDashDot", "thick"];
1362
+ var across = ["", "left", "center", "right", "justify", "justify", "distributed"];
1363
+ var down = ["", "top", "center", "bottom"];
1364
+ var sides = [["l", "left"], ["r", "right"], ["t", "top"], ["b", "bottom"]];
1365
+ var fontOrder = ["b", "i", "strike", "condense", "extend", "outline", "shadow", "u", "vertAlign", "sz", "color", "name", "family", "charset", "scheme"];
1366
+ function tinted(hex2, tint) {
1367
+ if (!tint) return hex2;
1368
+ const [r, g, b] = [0, 2, 4].map((i) => parseInt(hex2.slice(i, i + 2), 16) / 255);
1369
+ const max = Math.max(r, g, b), min = Math.min(r, g, b);
1370
+ let h = 0, s = 0, l = (max + min) / 2;
1371
+ if (max !== min) {
1372
+ const d = max - min;
1373
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
1374
+ h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4;
1375
+ h /= 6;
1376
+ }
1377
+ l = tint < 0 ? l * (1 + tint) : l * (1 - tint) + tint;
1378
+ const hue = (p2, q2, t) => {
1379
+ if (t < 0) t += 1;
1380
+ if (t > 1) t -= 1;
1381
+ return t < 1 / 6 ? p2 + (q2 - p2) * 6 * t : t < 1 / 2 ? q2 : t < 2 / 3 ? p2 + (q2 - p2) * (2 / 3 - t) * 6 : p2;
1382
+ };
1383
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s, p = 2 * l - q;
1384
+ const out = s === 0 ? [l, l, l] : [hue(p, q, h + 1 / 3), hue(p, q, h), hue(p, q, h - 1 / 3)];
1385
+ return out.map((v) => Math.round(v * 255).toString(16).padStart(2, "0")).join("").toUpperCase();
1386
+ }
1387
+ function palette(theme) {
1388
+ if (!theme) return ["FFFFFF", "000000", "E7E6E6", "44546A", "4472C4", "ED7D31", "A5A5A5", "FFC000", "5B9BD5", "70AD47", "0563C1", "954F72"];
1389
+ const scheme = /<(?:\w+:)?clrScheme\b[^>]*>([\s\S]*?)<\/(?:\w+:)?clrScheme>/.exec(theme)?.[1] ?? "";
1390
+ const pick = (name) => {
1391
+ const m = new RegExp(`<(?:\\w+:)?${name}>([\\s\\S]*?)</(?:\\w+:)?${name}>`).exec(scheme)?.[1] ?? "";
1392
+ return /(?:val|lastClr)="([0-9A-Fa-f]{6})"/.exec(m.includes("lastClr") ? m.replace(/val="\w+"/, "") : m)?.[1]?.toUpperCase() ?? "000000";
1393
+ };
1394
+ const [dk1, lt1, dk2, lt2] = ["dk1", "lt1", "dk2", "lt2"].map(pick);
1395
+ return [lt1, dk1, lt2, dk2, ...["accent1", "accent2", "accent3", "accent4", "accent5", "accent6", "hlink", "folHlink"].map(pick)];
1396
+ }
1397
+ var hex = (c) => {
1398
+ const s = String(c ?? "").trim();
1399
+ let m = /^#?([0-9a-f]{6})$/i.exec(s);
1400
+ if (m) return "#" + m[1].toUpperCase();
1401
+ m = /^#?([0-9a-f]{3})$/i.exec(s);
1402
+ if (m) return "#" + m[1].split("").map((x) => x + x).join("").toUpperCase();
1403
+ m = /^rgba?\((\d+),\s*(\d+),\s*(\d+)/i.exec(s);
1404
+ return m ? "#" + [m[1], m[2], m[3]].map((v) => Number(v).toString(16).padStart(2, "0")).join("").toUpperCase() : null;
1405
+ };
1406
+ function norm(l) {
1407
+ const out = {};
1408
+ if (l.bl) out.bl = 1;
1409
+ if (l.it) out.it = 1;
1410
+ if (l.ul?.s) out.ul = { s: 1 };
1411
+ if (l.st?.s) out.st = { s: 1 };
1412
+ if (l.va === 2 || l.va === 3) out.va = l.va;
1413
+ if (l.fs) out.fs = Number(l.fs);
1414
+ if (l.ff) out.ff = l.ff;
1415
+ const cl = hex(l.cl?.rgb);
1416
+ if (cl) out.cl = { rgb: cl };
1417
+ const bg = hex(l.bg?.rgb);
1418
+ if (bg) out.bg = { rgb: bg };
1419
+ if (l.bd) {
1420
+ const bd = {};
1421
+ for (const k of ["t", "b", "l", "r", "tl_br", "bl_tr"]) {
1422
+ const b = l.bd[k];
1423
+ if (b && b.s) bd[k] = { s: b.s, cl: { rgb: hex(b.cl?.rgb) ?? "#000000" } };
1424
+ }
1425
+ if (Object.keys(bd).length) out.bd = bd;
1426
+ }
1427
+ if (l.ht) out.ht = l.ht;
1428
+ if (l.vt) out.vt = l.vt;
1429
+ if (l.tb === 3) out.tb = 3;
1430
+ if (l.tr && (l.tr.a || l.tr.v)) out.tr = { a: l.tr.a ?? 0, v: l.tr.v ? 1 : 0 };
1431
+ if (l.n?.pattern && l.n.pattern !== "General") out.n = { pattern: l.n.pattern };
1432
+ return out;
1433
+ }
1434
+ var Styles = class {
1435
+ constructor(xml, theme) {
1436
+ this.formats = /* @__PURE__ */ new Map();
1437
+ this.fonts = [];
1438
+ this.fills = [];
1439
+ this.borders = [];
1440
+ this.xfs = [];
1441
+ this.looks = [];
1442
+ this.index = /* @__PURE__ */ new Map();
1443
+ this.added = false;
1444
+ this.custom = null;
1445
+ this.prefix = () => this.root?.name.includes(":") ? this.root.name.slice(0, this.root.name.indexOf(":") + 1) : "";
1446
+ this.bare = (name) => name.slice(name.indexOf(":") + 1);
1447
+ this.child = (el, name) => el.kids.find((k) => this.bare(k.name) === name);
1448
+ this.xml = xml;
1449
+ this.theme = palette(theme);
1450
+ this.root = xml ? parse(xml).kids.find((k) => !k.name.startsWith("?")) ?? null : null;
1451
+ const s = xml ?? "";
1452
+ const list = (name, tag) => {
1453
+ const el = this.root && this.child(this.root, name);
1454
+ return el ? el.kids.filter((k) => this.bare(k.name) === tag).map((k) => s.slice(k.start, k.end)) : [];
1455
+ };
1456
+ for (const f of list("numFmts", "numFmt")) {
1457
+ const a = Object.fromEntries(attrs(f));
1458
+ this.formats.set(Number(a.numFmtId), a.formatCode);
1459
+ }
1460
+ const colours = this.root && this.child(this.root, "colors");
1461
+ const custom = colours && this.child(colours, "indexedColors");
1462
+ if (custom) this.custom = custom.kids.map((k) => (attr(s, k, "rgb") ?? "FF000000").slice(-6).toUpperCase());
1463
+ this.fonts = list("fonts", "font");
1464
+ this.fills = list("fills", "fill");
1465
+ this.borders = list("borders", "border");
1466
+ this.xfs = list("cellXfs", "xf");
1467
+ if (!this.fonts.length) this.fonts = ['<font><sz val="11"/><name val="Calibri"/></font>'];
1468
+ if (!this.fills.length) this.fills = ['<fill><patternFill patternType="none"/></fill>', '<fill><patternFill patternType="gray125"/></fill>'];
1469
+ if (!this.borders.length) this.borders = ["<border><left/><right/><top/><bottom/><diagonal/></border>"];
1470
+ if (!this.xfs.length) this.xfs = ['<xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/>'];
1471
+ const raw = this.xfs.map((x) => this.look(x));
1472
+ this.looks = raw.map((l) => norm({ ...raw[0], ...l }));
1473
+ this.looks.forEach((l, i) => {
1474
+ const k = JSON.stringify(l);
1475
+ if (!this.index.has(k)) this.index.set(k, i);
1476
+ });
1477
+ }
1478
+ color(tag) {
1479
+ if (!tag) return void 0;
1480
+ const a = Object.fromEntries(attrs(tag));
1481
+ if (a.auto === "1" || a.auto === "true") return void 0;
1482
+ let hex2;
1483
+ if (a.rgb) hex2 = a.rgb.slice(-6).toUpperCase();
1484
+ else if (a.theme !== void 0) hex2 = this.theme[Number(a.theme)];
1485
+ else if (a.indexed !== void 0) hex2 = (this.custom ?? indexed)[Number(a.indexed)] ?? (Number(a.indexed) === 64 ? "000000" : void 0);
1486
+ return hex2 && "#" + tinted(hex2, Number(a.tint ?? 0));
1487
+ }
1488
+ parts(xml) {
1489
+ const root = parse(xml).kids[0];
1490
+ const out = /* @__PURE__ */ new Map();
1491
+ if (root) for (const k of root.kids) out.set(this.bare(k.name), xml.slice(k.start, k.end));
1492
+ return { root, out, open: root ? xml.slice(root.start, root.open) : "" };
1493
+ }
1494
+ pattern(id) {
1495
+ return this.formats.get(id) ?? builtin[id] ?? (id === 0 ? "General" : "General");
1496
+ }
1497
+ look(xf) {
1498
+ const a = Object.fromEntries(attrs(xf.slice(0, xf.indexOf(">") + 1)));
1499
+ const s = {};
1500
+ const font = this.parts(this.fonts[Number(a.fontId ?? 0)] ?? this.fonts[0]).out;
1501
+ const val = (tag) => tag && Object.fromEntries(attrs(tag)).val;
1502
+ const on = (tag) => tag !== void 0 && !/^(0|false)$/.test(val(tag) ?? "1");
1503
+ if (on(font.get("b"))) s.bl = 1;
1504
+ if (on(font.get("i"))) s.it = 1;
1505
+ if (on(font.get("strike"))) s.st = { s: 1 };
1506
+ if (font.has("u") && val(font.get("u")) !== "none") s.ul = { s: 1 };
1507
+ const va = val(font.get("vertAlign"));
1508
+ if (va === "superscript") s.va = 3;
1509
+ if (va === "subscript") s.va = 2;
1510
+ if (font.has("sz")) s.fs = Number(val(font.get("sz")));
1511
+ if (font.has("name")) s.ff = val(font.get("name"));
1512
+ const cl = this.color(font.get("color"));
1513
+ if (cl) s.cl = { rgb: cl };
1514
+ const fill3 = this.fills[Number(a.fillId ?? 0)];
1515
+ const pattern = fill3 && /patternType="(\w+)"/.exec(fill3)?.[1];
1516
+ if (fill3 && pattern && pattern !== "none" && pattern !== "gray125") {
1517
+ const fg = this.color(/<(?:\w+:)?fgColor\b[^>]*>/.exec(fill3)?.[0]);
1518
+ if (fg) s.bg = { rgb: fg };
1519
+ }
1520
+ const border = this.parts(this.borders[Number(a.borderId ?? 0)] ?? "<border/>");
1521
+ const bd = {};
1522
+ for (const [key2, name] of sides) {
1523
+ const el = border.out.get(name) ?? border.out.get(name === "left" ? "start" : name === "right" ? "end" : name);
1524
+ const style = el && /style="(\w+)"/.exec(el)?.[1];
1525
+ if (!style || style === "none") continue;
1526
+ bd[key2] = { s: Math.max(1, lines.indexOf(style)), cl: { rgb: this.color(/<(?:\w+:)?color\b[^>]*>/.exec(el)?.[0]) ?? "#000000" } };
1527
+ }
1528
+ const diagonal = border.out.get("diagonal");
1529
+ const dstyle = diagonal && /style="(\w+)"/.exec(diagonal)?.[1];
1530
+ if (dstyle && dstyle !== "none") {
1531
+ const line = { s: Math.max(1, lines.indexOf(dstyle)), cl: { rgb: this.color(/<(?:\w+:)?color\b[^>]*>/.exec(diagonal)?.[0]) ?? "#000000" } };
1532
+ const flags = Object.fromEntries(attrs(border.open));
1533
+ if (flags.diagonalDown === "1" || flags.diagonalDown === "true") bd.tl_br = line;
1534
+ if (flags.diagonalUp === "1" || flags.diagonalUp === "true") bd.bl_tr = line;
1535
+ }
1536
+ if (Object.keys(bd).length) s.bd = bd;
1537
+ const align2 = /<(?:\w+:)?alignment\b[^>]*>/.exec(xf)?.[0];
1538
+ if (align2) {
1539
+ const al = Object.fromEntries(attrs(align2));
1540
+ const ht = across.indexOf(al.horizontal === "centerContinuous" ? "center" : al.horizontal);
1541
+ if (ht > 0) s.ht = ht;
1542
+ const vt = down.indexOf(al.vertical);
1543
+ if (vt > 0) s.vt = vt;
1544
+ if (al.wrapText === "1" || al.wrapText === "true") s.tb = 3;
1545
+ const turn = Number(al.textRotation ?? 0);
1546
+ if (turn === 255) s.tr = { a: 0, v: 1 };
1547
+ else if (turn) s.tr = { a: turn <= 90 ? turn : 90 - turn, v: 0 };
1548
+ }
1549
+ const id = Number(a.numFmtId ?? 0);
1550
+ if (id) s.n = { pattern: this.pattern(id) };
1551
+ return s;
1552
+ }
1553
+ find(look) {
1554
+ return this.index.get(JSON.stringify(norm(look)));
1555
+ }
1556
+ derive(base, look) {
1557
+ look = norm(look);
1558
+ const key2 = JSON.stringify(look);
1559
+ const known = this.index.get(key2);
1560
+ if (known !== void 0) return known;
1561
+ const was = this.looks[base] ?? {};
1562
+ const xf = this.xfs[base] ?? this.xfs[0];
1563
+ const head = xf.slice(0, xf.indexOf(">") + 1);
1564
+ const a = new Map(attrs(head));
1565
+ const same3 = (keys) => keys.every((k) => JSON.stringify(was[k]) === JSON.stringify(look[k]));
1566
+ const p = this.prefix();
1567
+ if (!same3(["bl", "it", "st", "ul", "va", "fs", "ff", "cl"])) {
1568
+ a.set("fontId", String(this.add("fonts", this.font(Number(a.get("fontId") ?? 0), was, look))));
1569
+ a.set("applyFont", "1");
1570
+ }
1571
+ if (!same3(["bg"])) {
1572
+ a.set("fillId", String(look.bg?.rgb ? this.add("fills", `<${p}fill><${p}patternFill patternType="solid"><${p}fgColor rgb="${argb(look.bg.rgb)}"/><${p}bgColor indexed="64"/></${p}patternFill></${p}fill>`) : 0));
1573
+ a.set("applyFill", "1");
1574
+ }
1575
+ if (!same3(["bd"])) {
1576
+ a.set("borderId", String(this.add("borders", this.border(Number(a.get("borderId") ?? 0), was, look))));
1577
+ a.set("applyBorder", "1");
1578
+ }
1579
+ if (!same3(["n"])) {
1580
+ a.set("numFmtId", String(this.format(look.n?.pattern ?? "General")));
1581
+ a.set("applyNumberFormat", "1");
1582
+ }
1583
+ let inner = xf.endsWith("/>") && xf.indexOf(">") === xf.length - 1 ? "" : xf.slice(head.length, xf.lastIndexOf("<"));
1584
+ if (!same3(["ht", "vt", "tb", "tr"])) {
1585
+ const old = /<(?:\w+:)?alignment\b[^>]*>/.exec(inner)?.[0];
1586
+ const al = new Map(old ? attrs(old) : []);
1587
+ const put = (name2, value2) => value2 === null ? al.delete(name2) : al.set(name2, value2);
1588
+ put("horizontal", look.ht ? across[look.ht] : null);
1589
+ put("vertical", look.vt ? down[look.vt] : null);
1590
+ put("wrapText", look.tb === 3 ? "1" : null);
1591
+ put("textRotation", look.tr?.v ? "255" : look.tr?.a ? String(look.tr.a > 0 ? look.tr.a : 90 - look.tr.a) : null);
1592
+ const tag = al.size ? `<${p}alignment ${[...al].map(([k, v]) => `${k}="${escape(v)}"`).join(" ")}/>` : "";
1593
+ inner = old ? inner.replace(old, tag) : tag + inner;
1594
+ a.set("applyAlignment", "1");
1595
+ }
1596
+ const name = head.slice(1, head.search(/[\s/>]/));
1597
+ const open = `<${name} ${[...a].map(([k, v]) => `${k}="${escape(v)}"`).join(" ")}`;
1598
+ const next = inner ? `${open}>${inner}</${name}>` : `${open}/>`;
1599
+ this.xfs.push(next);
1600
+ this.added = true;
1601
+ const index = this.xfs.length - 1;
1602
+ this.looks.push(norm({ ...this.looks[0], ...this.look(next) }));
1603
+ this.index.set(key2, index);
1604
+ return index;
1605
+ }
1606
+ add(list, xml) {
1607
+ const at = this[list].indexOf(xml);
1608
+ if (at >= 0) return at;
1609
+ this[list].push(xml);
1610
+ this.added = true;
1611
+ return this[list].length - 1;
1612
+ }
1613
+ font(id, was, look) {
1614
+ const p = this.prefix();
1615
+ const { out } = this.parts(this.fonts[id] ?? this.fonts[0]);
1616
+ const set = (name, xml) => xml === null ? out.delete(name) : out.set(name, xml);
1617
+ const diff = (k) => JSON.stringify(was[k]) !== JSON.stringify(look[k]);
1618
+ if (diff("bl")) set("b", look.bl ? `<${p}b/>` : null);
1619
+ if (diff("it")) set("i", look.it ? `<${p}i/>` : null);
1620
+ if (diff("st")) set("strike", look.st?.s ? `<${p}strike/>` : null);
1621
+ if (diff("ul")) set("u", look.ul?.s ? `<${p}u/>` : null);
1622
+ if (diff("va")) set("vertAlign", look.va === 3 ? `<${p}vertAlign val="superscript"/>` : look.va === 2 ? `<${p}vertAlign val="subscript"/>` : null);
1623
+ if (diff("fs")) set("sz", `<${p}sz val="${look.fs ?? 11}"/>`);
1624
+ if (diff("cl")) set("color", look.cl?.rgb ? `<${p}color rgb="${argb(look.cl.rgb)}"/>` : null);
1625
+ if (diff("ff")) {
1626
+ set("name", `<${p}name val="${escape(look.ff ?? "Calibri")}"/>`);
1627
+ set("scheme", null);
1628
+ }
1629
+ return `<${p}font>${fontOrder.filter((k) => out.has(k)).map((k) => out.get(k)).join("")}</${p}font>`;
1630
+ }
1631
+ border(id, was, look) {
1632
+ const p = this.prefix();
1633
+ const { out, open } = this.parts(this.borders[id] ?? this.borders[0]);
1634
+ const flags = new Map(open ? attrs(open) : []);
1635
+ const line = (name, b) => b ? `<${p}${name} style="${lines[b.s] || "thin"}"><${p}color rgb="${argb(b.cl?.rgb ?? "#000000")}"/></${p}${name}>` : `<${p}${name}/>`;
1636
+ const before = was.bd ?? {}, after = look.bd ?? {};
1637
+ const parts2 = [];
1638
+ for (const [key2, name] of sides) {
1639
+ const old = out.get(name) ?? out.get(name === "left" ? "start" : name === "right" ? "end" : name);
1640
+ parts2.push(JSON.stringify(before[key2]) === JSON.stringify(after[key2]) && old ? old : line(name, after[key2]));
1641
+ }
1642
+ const diagonal = after.tl_br ?? after.bl_tr;
1643
+ if (JSON.stringify(before.tl_br) === JSON.stringify(after.tl_br) && JSON.stringify(before.bl_tr) === JSON.stringify(after.bl_tr)) parts2.push(out.get("diagonal") ?? `<${p}diagonal/>`);
1644
+ else {
1645
+ parts2.push(line("diagonal", diagonal));
1646
+ if (after.tl_br) flags.set("diagonalDown", "1");
1647
+ else flags.delete("diagonalDown");
1648
+ if (after.bl_tr) flags.set("diagonalUp", "1");
1649
+ else flags.delete("diagonalUp");
1650
+ }
1651
+ for (const extra of ["vertical", "horizontal"]) if (out.has(extra)) parts2.push(out.get(extra));
1652
+ const attributes = [...flags].map(([k, v]) => ` ${k}="${escape(v)}"`).join("");
1653
+ return `<${p}border${attributes}>${parts2.join("")}</${p}border>`;
1654
+ }
1655
+ format(pattern) {
1656
+ if (pattern === "General") return 0;
1657
+ for (const [id2, code] of this.formats) if (code === pattern) return id2;
1658
+ for (const [id2, code] of Object.entries(builtin)) if (code === pattern) return Number(id2);
1659
+ const id = Math.max(163, ...this.formats.keys()) + 1;
1660
+ this.formats.set(id, pattern);
1661
+ this.added = true;
1662
+ return id;
1663
+ }
1664
+ build() {
1665
+ if (!this.added) return null;
1666
+ const p = this.prefix();
1667
+ const s = this.xml ?? `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
1668
+ <styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"></styleSheet>`;
1669
+ const root = parse(s).kids.find((k) => !k.name.startsWith("?"));
1670
+ const order2 = ["numFmts", "fonts", "fills", "borders", "cellStyleXfs", "cellXfs", "cellStyles", "dxfs", "tableStyles", "colors", "extLst"];
1671
+ const lists = {
1672
+ numFmts: [...this.formats].map(([id, code]) => `<${p}numFmt numFmtId="${id}" formatCode="${escape(code)}"/>`),
1673
+ fonts: this.fonts,
1674
+ fills: this.fills,
1675
+ borders: this.borders,
1676
+ cellXfs: this.xfs
1677
+ };
1678
+ const edits2 = [];
1679
+ for (const name of Object.keys(lists)) {
1680
+ if (!lists[name].length) continue;
1681
+ const el = root.kids.find((k) => this.bare(k.name) === name);
1682
+ if (el) {
1683
+ const open = s.slice(el.start, el.open).replace(/\s*\/?>$/, "").replace(/\scount="\d*"/, "");
1684
+ edits2.push([el.start, el.end, `${open} count="${lists[name].length}">${lists[name].join("")}</${el.name}>`]);
1685
+ } else {
1686
+ const after = root.kids.find((k) => order2.indexOf(this.bare(k.name)) > order2.indexOf(name));
1687
+ const at = after ? after.start : root.close;
1688
+ edits2.push([at, at, `<${p}${name} count="${lists[name].length}">${lists[name].join("")}</${p}${name}>`]);
1689
+ }
1690
+ }
1691
+ edits2.sort((x, y) => y[0] - x[0]);
1692
+ let out = s;
1693
+ for (const [from, to, xml] of edits2) out = out.slice(0, from) + xml + out.slice(to);
1694
+ return out;
1695
+ }
1696
+ };
1697
+ var argb = (hex2) => "FF" + hex2.replace("#", "").toUpperCase().padStart(6, "0").slice(-6);
1698
+
1699
+ // src/sheets/xlsx.ts
1700
+ var key = (r, c) => r * 16384 + c;
1701
+ var px = { row: (pt2) => Math.round(pt2 * 4 / 3 * 100) / 100, col: (w) => Math.round(w * 7 + 5) };
1702
+ var pt = { row: (h) => Math.round(h * 3 / 4 * 100) / 100, col: (w) => Math.max(0, Math.round((w - 5) / 7 * 100) / 100) };
1703
+ var decodeX = (s) => s.includes("_x") ? s.replace(/_x([0-9A-Fa-f]{4})_/g, (_, h) => String.fromCharCode(parseInt(h, 16))) : s;
1704
+ function runs(xml) {
1705
+ const clean = xml.includes("rPh") ? xml.replace(/<(\w+:)?rPh\b[\s\S]*?<\/(\w+:)?rPh>/g, "") : xml;
1706
+ let out = "";
1707
+ for (const m of clean.matchAll(/<(?:\w+:)?t(?:\s[^>]*)?(?:\/>|>([\s\S]*?)<\/(?:\w+:)?t>)/g)) out += m[1] ?? "";
1708
+ return decodeX(unescape(out));
1709
+ }
1710
+ var patterns = /* @__PURE__ */ new Map();
1711
+ var attr2 = (tag, name) => {
1712
+ let re = patterns.get(name);
1713
+ if (!re) patterns.set(name, re = new RegExp(`\\s${name}="([^"]*)"`));
1714
+ const m = re.exec(tag);
1715
+ return m ? unescape(m[1]) : null;
1716
+ };
1717
+ var element = (xml, name) => {
1718
+ const m = new RegExp(`<((?:\\w+:)?${name})\\b[^>]*?(\\/?)>`).exec(xml);
1719
+ if (!m) return null;
1720
+ if (m[2]) return { start: m.index, open: m.index + m[0].length, close: m.index + m[0].length, end: m.index + m[0].length, tag: m[0] };
1721
+ const close = xml.indexOf(`</${m[1]}>`, m.index);
1722
+ return { start: m.index, open: m.index + m[0].length, close, end: close + m[1].length + 3, tag: m[0] };
1723
+ };
1724
+ function worksheets(bytes) {
1725
+ const pack = new Pack(bytes);
1726
+ const part = pack.rels("").find((r) => r.type === "officeDocument")?.target ?? "xl/workbook.xml";
1727
+ const rels = pack.rels(part);
1728
+ return [...(pack.text(part) ?? "").matchAll(/<(?:\w+:)?sheet\b[^>]*\/?>/g)].filter((m) => rels.find((r) => r.id === /\s[\w]+:id="([^"]*)"/.exec(m[0])?.[1])?.type === "worksheet").map((m) => Number(attr2(m[0], "sheetId")));
1729
+ }
1730
+ function load(bytes) {
1731
+ var _a, _b;
1732
+ const pack = new Pack(bytes);
1733
+ const office = pack.rels("").find((r) => r.type === "officeDocument");
1734
+ const part = office?.target ?? "xl/workbook.xml";
1735
+ const xml = pack.text(part);
1736
+ if (!xml) throw new Error("No workbook");
1737
+ const rels = pack.rels(part);
1738
+ const target = (type) => rels.find((r) => r.type === type)?.target;
1739
+ const themePart = target("theme");
1740
+ const stylesPart = target("styles");
1741
+ const styles = new Styles(stylesPart ? pack.text(stylesPart) : null, themePart ? pack.text(themePart) : null);
1742
+ const stringsPart = target("sharedStrings");
1743
+ const strings = [];
1744
+ const sst = stringsPart ? pack.text(stringsPart) : null;
1745
+ if (sst) for (const m of sst.matchAll(/<(?:\w+:)?si\b[^>]*?(?:\/>|>([\s\S]*?)<\/(?:\w+:)?si>)/g)) strings.push(m[1] ? runs(m[1]) : "");
1746
+ const date1904 = /<(?:\w+:)?workbookPr\b[^>]*\bdate1904="(1|true)"/.test(xml);
1747
+ const entries2 = [];
1748
+ for (const m of xml.matchAll(/<(?:\w+:)?sheet\b[^>]*\/?>/g)) {
1749
+ const tag = m[0];
1750
+ const rid = /\s[\w]+:id="([^"]*)"/.exec(tag)?.[1] ?? "";
1751
+ const rel = rels.find((r) => r.id === rid);
1752
+ entries2.push({ name: attr2(tag, "name") ?? "", sheetId: Number(attr2(tag, "sheetId")), rid, xml: tag, sheet: rel?.type === "worksheet" });
1753
+ }
1754
+ const book = {
1755
+ id: "book",
1756
+ name: "",
1757
+ appVersion: "",
1758
+ locale: "enUS",
1759
+ styles: {},
1760
+ sheetOrder: [],
1761
+ sheets: {},
1762
+ resources: [],
1763
+ defaultStyle: styles.looks[0]
1764
+ };
1765
+ if (date1904) book.dateSystem = "date1904";
1766
+ const notes2 = {};
1767
+ const validations = {};
1768
+ const filters = {};
1769
+ const model = { book, lines: {}, origin: { sheets: {}, lines: {} } };
1770
+ const sheets = [];
1771
+ const active = Number(/<(?:\w+:)?workbookView\b[^>]*\bactiveTab="(\d+)"/.exec(xml)?.[1] ?? 0);
1772
+ const useStyle = (xf) => {
1773
+ const id = `x${xf}`;
1774
+ if (!(id in book.styles)) book.styles[id] = styles.looks[xf] ?? {};
1775
+ return id;
1776
+ };
1777
+ for (const entry2 of entries2) {
1778
+ if (!entry2.sheet) continue;
1779
+ const rel = rels.find((r) => r.id === entry2.rid);
1780
+ const sxml = pack.text(rel.target);
1781
+ if (sxml === null) continue;
1782
+ const sid = `s${entry2.sheetId}`;
1783
+ const p = /<(\w+:)?worksheet\b/.exec(sxml)?.[1] ?? "";
1784
+ const srels = pack.rels(rel.target);
1785
+ const sheet = { id: sid, name: entry2.name, cellData: {}, rowData: {}, columnData: {}, mergeData: [] };
1786
+ const state = attr2(entry2.xml, "state");
1787
+ if (state === "hidden") sheet.hidden = 1;
1788
+ if (state === "veryHidden") sheet.hidden = 2;
1789
+ const open = element(sxml, `${p}sheetData`);
1790
+ const bounds = open ? [open.start, open.open, open.close, open.end] : [sxml.length, sxml.length, sxml.length, sxml.length];
1791
+ const head = open ? sxml.slice(0, open.start) : sxml;
1792
+ const tail = open ? sxml.slice(open.end) : "";
1793
+ const format = /<(?:\w+:)?sheetFormatPr\b[^>]*>/.exec(head)?.[0];
1794
+ const defaultRow = format && attr2(format, "defaultRowHeight") ? px.row(Number(attr2(format, "defaultRowHeight"))) : 20;
1795
+ const defaultCol = format && attr2(format, "defaultColWidth") ? px.col(Number(attr2(format, "defaultColWidth"))) : format && attr2(format, "baseColWidth") ? px.col(Number(attr2(format, "baseColWidth")) + 0.71) : 64;
1796
+ sheet.defaultRowHeight = defaultRow;
1797
+ sheet.defaultColumnWidth = defaultCol;
1798
+ const view = /<(?:\w+:)?sheetView\b[^>]*>/.exec(head)?.[0];
1799
+ if (view && attr2(view, "showGridLines") === "0") sheet.showGridlines = 0;
1800
+ if (view && attr2(view, "rightToLeft") === "1") sheet.rightToLeft = 1;
1801
+ if (view && attr2(view, "zoomScale")) sheet.zoomRatio = Number(attr2(view, "zoomScale")) / 100;
1802
+ const pane = /<(?:\w+:)?pane\b[^>]*>/.exec(head)?.[0];
1803
+ if (pane && /^frozen/.test(attr2(pane, "state") ?? "")) {
1804
+ const x = Number(attr2(pane, "xSplit") ?? 0), y = Number(attr2(pane, "ySplit") ?? 0);
1805
+ sheet.freeze = { xSplit: x, ySplit: y, startRow: y, startColumn: x };
1806
+ }
1807
+ const tab = /<(?:\w+:)?tabColor\b[^>]*>/.exec(head)?.[0];
1808
+ if (tab) {
1809
+ const c = styles.color(tab);
1810
+ if (c) sheet.tabColor = c;
1811
+ }
1812
+ const cols = [];
1813
+ for (const m of head.matchAll(/<(?:\w+:)?col\b[^>]*\/?>/g)) {
1814
+ const t = m[0];
1815
+ const spec = { min: Number(attr2(t, "min")), max: Number(attr2(t, "max")), xml: t, hidden: /^(1|true)$/.test(attr2(t, "hidden") ?? "") };
1816
+ if (attr2(t, "width") !== null && /^(1|true)$/.test(attr2(t, "customWidth") ?? "1")) spec.width = px.col(Number(attr2(t, "width")));
1817
+ if (attr2(t, "style") !== null && attr2(t, "style") !== "0") spec.style = Number(attr2(t, "style"));
1818
+ cols.push(spec);
1819
+ }
1820
+ const cellData = {};
1821
+ const rowData = {};
1822
+ const rows = /* @__PURE__ */ new Map();
1823
+ const cells = /* @__PURE__ */ new Map();
1824
+ const masters = /* @__PURE__ */ new Map();
1825
+ const children = [];
1826
+ const rowStyles = /* @__PURE__ */ new Map();
1827
+ let maxRow = -1, maxCol = -1;
1828
+ if (open && open.close > open.open) {
1829
+ const end = open.close;
1830
+ let at = open.open, row2 = -1, col = -1;
1831
+ while (at < end) {
1832
+ const lt = sxml.indexOf("<", at);
1833
+ if (lt < 0 || lt >= end) break;
1834
+ const gt = sxml.indexOf(">", lt);
1835
+ if (sxml.charCodeAt(lt + 1) === 47) {
1836
+ at = gt + 1;
1837
+ continue;
1838
+ }
1839
+ let j = lt + 1;
1840
+ while (j < gt) {
1841
+ const ch = sxml.charCodeAt(j);
1842
+ if (ch === 32 || ch === 47 || ch === 9 || ch === 10 || ch === 13) break;
1843
+ j++;
1844
+ }
1845
+ const name = sxml.slice(lt + 1 + p.length, j);
1846
+ const tag = sxml.slice(lt, gt + 1);
1847
+ if (name === "row") {
1848
+ const r = attr2(tag, "r");
1849
+ row2 = r ? Number(r) - 1 : row2 + 1;
1850
+ col = -1;
1851
+ rows.set(row2, { open: tag });
1852
+ const rd = {};
1853
+ const ht = attr2(tag, "ht");
1854
+ if (ht !== null) rd.h = px.row(Number(ht));
1855
+ if (ht !== null && /^(1|true)$/.test(attr2(tag, "customHeight") ?? "")) rd.ia = 0;
1856
+ if (/^(1|true)$/.test(attr2(tag, "hidden") ?? "")) rd.hd = 1;
1857
+ const rs = attr2(tag, "s");
1858
+ if (rs !== null && /^(1|true)$/.test(attr2(tag, "customFormat") ?? "")) {
1859
+ rowStyles.set(row2, Number(rs));
1860
+ rd.s = useStyle(Number(rs));
1861
+ }
1862
+ if (Object.keys(rd).length) rowData[row2] = rd;
1863
+ if (rd.h !== void 0 || rd.hd || rd.s) maxRow = Math.max(maxRow, row2);
1864
+ at = gt + 1;
1865
+ continue;
1866
+ }
1867
+ if (name !== "c") {
1868
+ at = gt + 1;
1869
+ continue;
1870
+ }
1871
+ const ref = attr2(tag, "r");
1872
+ if (ref) [, col] = cell(ref);
1873
+ else col += 1;
1874
+ const self = sxml.charCodeAt(gt - 1) === 47;
1875
+ const close = self ? gt + 1 : sxml.indexOf(`</${p}c>`, gt);
1876
+ const stop = self ? gt + 1 : close + p.length + 4;
1877
+ const inner = self ? "" : sxml.slice(gt + 1, close);
1878
+ const t = attr2(tag, "t");
1879
+ const s = Number(attr2(tag, "s") ?? 0);
1880
+ const out = {};
1881
+ let shared = false;
1882
+ if (inner) {
1883
+ const f = /<(?:\w+:)?f\b([^>]*?)(?:\/>|>([\s\S]*?)<\/(?:\w+:)?f>)/.exec(inner);
1884
+ if (f) {
1885
+ const kind = attr2(f[0], "t");
1886
+ const formula = f[2] === void 0 ? "" : unescape(f[2]);
1887
+ if (kind === "shared") {
1888
+ shared = true;
1889
+ const si = attr2(f[0], "si") ?? "";
1890
+ if (formula) masters.set(si, { f: formula, r: row2, c: col });
1891
+ else children.push([row2, col, si]);
1892
+ if (formula) out.f = "=" + plain(formula);
1893
+ } else if (kind !== "dataTable" && formula) out.f = "=" + plain(formula);
1894
+ }
1895
+ const v = /<(?:\w+:)?v>([\s\S]*?)<\/(?:\w+:)?v>/.exec(inner)?.[1];
1896
+ if (t === "inlineStr") {
1897
+ const is = /<(?:\w+:)?is>([\s\S]*?)<\/(?:\w+:)?is>/.exec(inner)?.[1];
1898
+ if (is !== void 0) {
1899
+ out.v = runs(is);
1900
+ out.t = 1;
1901
+ }
1902
+ } else if (v !== void 0) {
1903
+ if (t === "s") {
1904
+ out.v = strings[Number(v)] ?? "";
1905
+ out.t = 1;
1906
+ } else if (t === "str" || t === "e") {
1907
+ out.v = decodeX(unescape(v));
1908
+ out.t = 1;
1909
+ } else if (t === "b") {
1910
+ out.v = v === "1" || v === "true";
1911
+ out.t = 3;
1912
+ } else if (t === "d") {
1913
+ const d = Date.parse(v);
1914
+ out.v = Number.isNaN(d) ? v : (d - Date.UTC(1899, 11, 30)) / 864e5;
1915
+ out.t = Number.isNaN(d) ? 1 : 2;
1916
+ } else {
1917
+ out.v = Number(v);
1918
+ out.t = 2;
1919
+ }
1920
+ }
1921
+ }
1922
+ const styled = s || rowStyles.has(row2) || cols.some((spec) => spec.style !== void 0 && col + 1 >= spec.min && col + 1 <= spec.max);
1923
+ if (styled) out.s = useStyle(s);
1924
+ if (out.v !== void 0 || out.f || out.s || shared) {
1925
+ (cellData[row2] ?? (cellData[row2] = {}))[col] = out;
1926
+ if (out.v !== void 0 || out.f || s) {
1927
+ maxRow = Math.max(maxRow, row2);
1928
+ maxCol = Math.max(maxCol, col);
1929
+ }
1930
+ }
1931
+ cells.set(key(row2, col), { start: lt, end: stop, shared });
1932
+ at = stop;
1933
+ }
1934
+ }
1935
+ for (const [r, c, si] of children) {
1936
+ const m = masters.get(si);
1937
+ const target2 = (_a = cellData[r] ?? (cellData[r] = {}))[c] ?? (_a[c] = {});
1938
+ if (m) target2.f = "=" + plain(shifted(m.f, r - m.r, c - m.c));
1939
+ }
1940
+ for (const spec of cols) if (spec.max <= 1024) maxCol = Math.max(maxCol, spec.max - 1);
1941
+ const merges = [];
1942
+ for (const m of tail.matchAll(/<(?:\w+:)?mergeCell\b[^>]*\/?>/g)) {
1943
+ const ref = attr2(m[0], "ref");
1944
+ if (!ref) continue;
1945
+ merges.push(ref);
1946
+ for (const b of boxes(ref)) {
1947
+ sheet.mergeData.push({ startRow: b.startRow, startColumn: b.startColumn, endRow: b.endRow, endColumn: b.endColumn });
1948
+ maxRow = Math.max(maxRow, b.endRow);
1949
+ maxCol = Math.max(maxCol, b.endColumn);
1950
+ }
1951
+ }
1952
+ const rules = [];
1953
+ const dvs = [];
1954
+ const dvBlock = element(tail, `${p}dataValidations`);
1955
+ if (dvBlock) for (const m of tail.slice(dvBlock.open, dvBlock.close).matchAll(/<(?:\w+:)?dataValidation\b[^>]*?(?:\/>|>[\s\S]*?<\/(?:\w+:)?dataValidation>)/g)) {
1956
+ const rule = validation(m[0], `dv${dvs.length}`);
1957
+ dvs.push(m[0]);
1958
+ if (rule) rules.push(rule);
1959
+ }
1960
+ if (rules.length) validations[sid] = rules;
1961
+ const af = /<(?:\w+:)?autoFilter\b[^>]*?(?:\/>|>[\s\S]*?<\/(?:\w+:)?autoFilter>)/.exec(tail)?.[0] ?? null;
1962
+ if (af) {
1963
+ const [b] = boxes(attr2(af, "ref") ?? "");
1964
+ if (b) filters[sid] = { ref: { ...b, rangeType: 0 }, filterColumns: criteria(af), cachedFilteredOut: [] };
1965
+ }
1966
+ const sheetNotes = [];
1967
+ const commentsRel = srels.find((r) => r.type === "comments");
1968
+ const vmlRel = srels.find((r) => r.type === "vmlDrawing");
1969
+ const authors = [];
1970
+ if (commentsRel) {
1971
+ const cx = pack.text(commentsRel.target) ?? "";
1972
+ for (const m of cx.matchAll(/<(?:\w+:)?author>([\s\S]*?)<\/(?:\w+:)?author>|<(?:\w+:)?author\/>/g)) authors.push(unescape(m[1] ?? ""));
1973
+ for (const m of cx.matchAll(/<(?:\w+:)?comment\b[^>]*>[\s\S]*?<\/(?:\w+:)?comment>/g)) {
1974
+ const ref = attr2(m[0], "ref") ?? "";
1975
+ const textXml = /<(?:\w+:)?text>([\s\S]*?)<\/(?:\w+:)?text>/.exec(m[0])?.[1] ?? "";
1976
+ const note = { ref, xml: m[0], text: runs(textXml) };
1977
+ sheetNotes.push(note);
1978
+ const [r, c] = cell(ref);
1979
+ if (r < 0) continue;
1980
+ ((_b = notes2[sid] ?? (notes2[sid] = {}))[r] ?? (_b[r] = {}))[c] = { note: note.text, width: 160, height: 72, show: false, id: `n${sheetNotes.length - 1}`, row: r, col: c };
1981
+ maxRow = Math.max(maxRow, r);
1982
+ maxCol = Math.max(maxCol, c);
1983
+ }
1984
+ }
1985
+ const height = Math.max(maxRow + 1 + 100, 1e3);
1986
+ const width = Math.max(maxCol + 1 + 4, 26);
1987
+ for (const spec of cols) {
1988
+ for (let c = spec.min - 1; c < Math.min(spec.max, width); c++) {
1989
+ const cd = {};
1990
+ if (spec.width !== void 0) cd.w = spec.width;
1991
+ if (spec.hidden) cd.hd = 1;
1992
+ if (spec.style !== void 0) cd.s = useStyle(spec.style);
1993
+ if (Object.keys(cd).length) sheet.columnData[c] = cd;
1994
+ }
1995
+ }
1996
+ sheet.rowCount = height;
1997
+ sheet.columnCount = width;
1998
+ sheet.cellData = cellData;
1999
+ sheet.rowData = rowData;
2000
+ book.sheets[sid] = sheet;
2001
+ book.sheetOrder.push(sid);
2002
+ model.lines[sid] = { rows: numbered("r", height), cols: numbered("c", width) };
2003
+ model.origin.lines[sid] = { rows: numbered("r", height), cols: numbered("c", width) };
2004
+ model.origin.sheets[sid] = entry2.sheetId;
2005
+ sheets.push({
2006
+ sid,
2007
+ name: entry2.name,
2008
+ sheetId: entry2.sheetId,
2009
+ part: rel.target,
2010
+ xml: sxml,
2011
+ p,
2012
+ rels: srels,
2013
+ bounds,
2014
+ rows,
2015
+ cells,
2016
+ cols,
2017
+ merges,
2018
+ validations: dvs,
2019
+ notes: sheetNotes,
2020
+ comments: commentsRel?.target ?? null,
2021
+ vml: vmlRel?.target ?? null,
2022
+ authors,
2023
+ width
2024
+ });
2025
+ }
2026
+ const names = {};
2027
+ for (const m of xml.matchAll(/<(?:\w+:)?definedName\b([^>]*)>([\s\S]*?)<\/(?:\w+:)?definedName>/g)) {
2028
+ const name = attr2(m[0], "name") ?? "";
2029
+ if (name.startsWith("_xlnm.") || /^(1|true)$/.test(attr2(m[0], "hidden") ?? "")) continue;
2030
+ const local = attr2(m[0], "localSheetId");
2031
+ const scoped = local === null ? null : entries2[Number(local)];
2032
+ const id = `d${Object.keys(names).length}`;
2033
+ names[id] = { id, name, formulaOrRefString: plain(unescape(m[2])), localSheetId: scoped ? `s${scoped.sheetId}` : "AllDefaultWorkbook" };
2034
+ }
2035
+ const resources = book.resources;
2036
+ if (Object.keys(names).length) resources.push({ name: "SHEET_DEFINED_NAME_PLUGIN", data: JSON.stringify(names) });
2037
+ if (Object.keys(notes2).length) resources.push({ name: "SHEET_NOTE_PLUGIN", data: JSON.stringify(notes2) });
2038
+ if (Object.keys(validations).length) resources.push({ name: "SHEET_DATA_VALIDATION_PLUGIN", data: JSON.stringify(validations) });
2039
+ if (Object.keys(filters).length) resources.push({ name: "SHEET_FILTER_PLUGIN", data: JSON.stringify(filters) });
2040
+ const shown = entries2[active];
2041
+ if (shown?.sheet && book.sheetOrder.includes(`s${shown.sheetId}`)) model.active = `s${shown.sheetId}`;
2042
+ return { model, book: { pack, part, xml, rels, styles, stylesPart: stylesPart ?? null, sheets, entries: entries2 } };
2043
+ }
2044
+ var kinds = { whole: "whole", decimal: "decimal", list: "list", textLength: "textLength", custom: "custom" };
2045
+ var stops = { information: 0, stop: 1, warning: 2 };
2046
+ function validation(xml, uid) {
2047
+ const type = attr2(xml, "type") ?? "none";
2048
+ const kind = kinds[type];
2049
+ const ranges = boxes(attr2(xml, "sqref") ?? "");
2050
+ if (!kind || !ranges.length) return null;
2051
+ const f = (n) => {
2052
+ const m = new RegExp(`<(?:\\w+:)?formula${n}>([\\s\\S]*?)</(?:\\w+:)?formula${n}>`).exec(xml)?.[1];
2053
+ return m === void 0 ? void 0 : plain(unescape(m));
2054
+ };
2055
+ let formula1 = f(1), formula2 = f(2);
2056
+ if (kind === "list" && formula1 !== void 0) formula1 = /^".*"$/.test(formula1) ? formula1.slice(1, -1).replace(/""/g, '"') : "=" + formula1;
2057
+ else if (kind === "custom" && formula1 !== void 0) formula1 = "=" + formula1;
2058
+ else if (formula1 !== void 0 && !/^-?[\d.]+$/.test(formula1)) formula1 = "=" + formula1;
2059
+ if (formula2 !== void 0 && !/^-?[\d.]+$/.test(formula2)) formula2 = "=" + formula2;
2060
+ const flag = (name) => /^(1|true)$/.test(attr2(xml, name) ?? "");
2061
+ const rule = { uid, type: kind, ranges: ranges.map((b) => ({ ...b, rangeType: 0 })) };
2062
+ const operator = attr2(xml, "operator");
2063
+ if (kind !== "list" && kind !== "custom") rule.operator = operator ?? "between";
2064
+ if (formula1 !== void 0) rule.formula1 = formula1;
2065
+ if (formula2 !== void 0) rule.formula2 = formula2;
2066
+ if (flag("allowBlank")) rule.allowBlank = true;
2067
+ if (kind === "list") rule.showDropDown = !flag("showDropDown");
2068
+ if (flag("showErrorMessage")) rule.showErrorMessage = true;
2069
+ if (flag("showInputMessage")) rule.showInputMessage = true;
2070
+ const style = attr2(xml, "errorStyle");
2071
+ if (style && style in stops) rule.errorStyle = stops[style];
2072
+ for (const name of ["error", "errorTitle", "prompt", "promptTitle"]) if (attr2(xml, name) !== null) rule[name] = attr2(xml, name);
2073
+ return rule;
2074
+ }
2075
+ function criteria(xml) {
2076
+ const out = [];
2077
+ for (const m of xml.matchAll(/<(?:\w+:)?filterColumn\b[^>]*>([\s\S]*?)<\/(?:\w+:)?filterColumn>/g)) {
2078
+ const colId = Number(attr2(m[0], "colId") ?? 0);
2079
+ const inner = m[1];
2080
+ if (/<(?:\w+:)?filters\b/.test(inner)) {
2081
+ const values = [...inner.matchAll(/<(?:\w+:)?filter\b[^>]*\/?>/g)].map((f) => attr2(f[0], "val") ?? "");
2082
+ const blank2 = /<(?:\w+:)?filters\b[^>]*\bblank="(1|true)"/.test(inner);
2083
+ out.push({ colId, filters: { ...values.length && { filters: values }, ...blank2 && { blank: true } } });
2084
+ } else if (/<(?:\w+:)?customFilters\b/.test(inner)) {
2085
+ const and = /<(?:\w+:)?customFilters\b[^>]*\band="(1|true)"/.test(inner);
2086
+ const list = [...inner.matchAll(/<(?:\w+:)?customFilter\b[^>]*\/?>/g)].map((f) => ({ ...attr2(f[0], "operator") && { operator: attr2(f[0], "operator") }, val: attr2(f[0], "val") ?? "" }));
2087
+ out.push({ colId, customFilters: { ...and && { and: 1 }, customFilters: list } });
2088
+ }
2089
+ }
2090
+ return out;
2091
+ }
2092
+
2093
+ // src/sheets/write.ts
2094
+ var order = [
2095
+ "sheetPr",
2096
+ "dimension",
2097
+ "sheetViews",
2098
+ "sheetFormatPr",
2099
+ "cols",
2100
+ "sheetData",
2101
+ "sheetCalcPr",
2102
+ "sheetProtection",
2103
+ "protectedRanges",
2104
+ "scenarios",
2105
+ "autoFilter",
2106
+ "sortState",
2107
+ "dataConsolidate",
2108
+ "customSheetViews",
2109
+ "mergeCells",
2110
+ "phoneticPr",
2111
+ "conditionalFormatting",
2112
+ "dataValidations",
2113
+ "hyperlinks",
2114
+ "printOptions",
2115
+ "pageMargins",
2116
+ "pageSetup",
2117
+ "headerFooter",
2118
+ "rowBreaks",
2119
+ "colBreaks",
2120
+ "customProperties",
2121
+ "cellWatches",
2122
+ "ignoredErrors",
2123
+ "smartTags",
2124
+ "drawing",
2125
+ "legacyDrawing",
2126
+ "legacyDrawingHF",
2127
+ "drawingHF",
2128
+ "picture",
2129
+ "oleObjects",
2130
+ "controls",
2131
+ "webPublishItems",
2132
+ "tableParts",
2133
+ "extLst"
2134
+ ];
2135
+ var errors = /^#(NULL!|DIV\/0!|VALUE!|REF!|NAME\?|NUM!|N\/A|GETTING_DATA|SPILL!|CALC!)$/;
2136
+ var REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
2137
+ var blankSheet = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><dimension ref="A1"/><sheetViews><sheetView workbookViewId="0"/></sheetViews><sheetFormatPr defaultRowHeight="15"/><sheetData/><pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/></worksheet>';
2138
+ var same = (a, b) => JSON.stringify(a ?? null) === JSON.stringify(b ?? null);
2139
+ var blank = (v) => v === void 0 || v === null || v === "";
2140
+ var patterns2 = /* @__PURE__ */ new Map();
2141
+ var setAttr = (tag, name, value2) => {
2142
+ let re = patterns2.get(name);
2143
+ if (!re) patterns2.set(name, re = new RegExp(`\\s${name}="[^"]*"`));
2144
+ if (value2 === null) return tag.replace(re, "");
2145
+ if (re.test(tag)) return tag.replace(re, () => ` ${name}="${escape(value2)}"`);
2146
+ return tag.replace(/\s*(\/?>)$/, (end) => ` ${name}="${escape(value2)}"${end.trim()}`);
2147
+ };
2148
+ var literal = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2149
+ function resource(book, name) {
2150
+ const found = book.resources?.find((r) => r.name === name);
2151
+ return found ? JSON.parse(found.data || "{}") : null;
2152
+ }
2153
+ function textOf(c) {
2154
+ if (!c) return null;
2155
+ const stream = c.p?.body?.dataStream;
2156
+ if (stream !== void 0 && blank(c.v)) return stream.replace(/\r?\n$/, "").replace(/\r\n?/g, "\n");
2157
+ if (c.t === 3 && typeof c.v === "number") return c.v === 1;
2158
+ return c.v ?? null;
2159
+ }
2160
+ function formulas(cells) {
2161
+ const masters = /* @__PURE__ */ new Map();
2162
+ for (const [r, line] of Object.entries(cells)) for (const [c, x] of Object.entries(line ?? {})) if (x?.si && x.f) masters.set(x.si, { f: x.f, r: +r, c: +c });
2163
+ return (r, c, x) => {
2164
+ if (x.f) return x.f;
2165
+ if (!x.si) return null;
2166
+ const m = masters.get(x.si);
2167
+ return m ? "=" + shifted(m.f.replace(/^=/, ""), r - m.r, c - m.c) : null;
2168
+ };
2169
+ }
2170
+ function equalValue(a, b) {
2171
+ if (blank(a) && blank(b)) return true;
2172
+ if (typeof a === "number" && typeof b === "number") return a === b || Math.abs(a - b) <= 1e-9 * Math.max(1, Math.abs(a), Math.abs(b));
2173
+ return a === b;
2174
+ }
2175
+ function lookup(book, s) {
2176
+ if (!s) return {};
2177
+ return (typeof s === "string" ? book.styles[s] : s) ?? {};
2178
+ }
2179
+ var Axis = class {
2180
+ constructor(old, now) {
2181
+ this.old = old;
2182
+ this.now = now;
2183
+ this.map = (i) => i < this.old.length ? this.at.get(this.old[i]) ?? -1 : i + this.shift;
2184
+ this.from = (i) => i < this.now.length ? this.back.get(this.now[i]) ?? -1 : i - this.shift;
2185
+ this.near = (i) => {
2186
+ for (let j = i; j < this.old.length; j++) if (this.map(j) >= 0) return this.map(j);
2187
+ for (let j = i; j >= 0; j--) if (this.map(j) >= 0) return this.map(j);
2188
+ return 0;
2189
+ };
2190
+ this.at = new Map(now.map((id, i) => [id, i]));
2191
+ this.back = new Map(old.map((id, i) => [id, i]));
2192
+ this.moved = old.some((id, i) => this.at.get(id) !== i);
2193
+ const last = old.length ? this.at.get(old[old.length - 1]) : void 0;
2194
+ this.shift = last === void 0 ? now.length - old.length : last - (old.length - 1);
2195
+ }
2196
+ };
2197
+ function find(xml, name) {
2198
+ const m = new RegExp(`<((?:\\w+:)?${name})\\b[^>]*?(\\/?)>`).exec(xml);
2199
+ if (!m) return null;
2200
+ if (m[2]) return { start: m.index, end: m.index + m[0].length, tag: m[0] };
2201
+ const close = xml.indexOf(`</${m[1]}>`, m.index);
2202
+ return { start: m.index, end: close + m[1].length + 3, tag: m[0] };
2203
+ }
2204
+ function place(xml, name, value2) {
2205
+ const found = find(xml, name);
2206
+ if (found) return xml.slice(0, found.start) + (value2 ?? "") + xml.slice(found.end);
2207
+ if (value2 === null) return xml;
2208
+ const rank = order.indexOf(name);
2209
+ let at = -1;
2210
+ for (const later of order.slice(rank + 1)) {
2211
+ const f = find(xml, later);
2212
+ if (f && (at < 0 || f.start < at)) at = f.start;
2213
+ }
2214
+ if (at < 0) at = xml.search(/<\/(?:\w+:)?worksheet>\s*$/);
2215
+ if (at < 0) at = xml.length;
2216
+ return xml.slice(0, at) + value2 + xml.slice(at);
2217
+ }
2218
+ function remapZone(xml, mine, rows, cols) {
2219
+ const ranges = (sqref) => boxes(sqref).map((b) => squeeze(b, rows.map, cols.map)).filter((b) => b !== null).map(span).join(" ");
2220
+ const formula = (f) => remapped(f, mine, rows.map, cols.map);
2221
+ let out = xml.replace(/<((?:\w+:)?)(conditionalFormatting|dataValidation|hyperlink|ignoredError|protectedRange)\b[^>]*?(?:\/>|>[\s\S]*?<\/\1\2>)/g, (all) => {
2222
+ const sq = attr2(all, "sqref");
2223
+ const ref = attr2(all, "ref");
2224
+ let next = all;
2225
+ if (sq !== null) {
2226
+ const s = ranges(sq);
2227
+ if (!s) return "";
2228
+ next = setAttr(next.slice(0, next.indexOf(">") + 1), "sqref", s) + next.slice(next.indexOf(">") + 1);
2229
+ }
2230
+ if (ref !== null) {
2231
+ const s = ranges(ref);
2232
+ if (!s) return "";
2233
+ next = setAttr(next.slice(0, next.indexOf(">") + 1), "ref", s) + next.slice(next.indexOf(">") + 1);
2234
+ }
2235
+ return next.replace(/<((?:\w+:)?)(formula|formula1|formula2)>([\s\S]*?)<\/\1\2>/g, (_, p, n, f) => `<${p}${n}>${escape(formula(unescape(f)))}</${p}${n}>`);
2236
+ });
2237
+ out = out.replace(/<((?:\w+:)?)(autoFilter|sortState|sortCondition)\b[^>]*?>/g, (tag) => {
2238
+ const ref = attr2(tag, "ref");
2239
+ return ref === null ? tag : setAttr(tag, "ref", ranges(ref) || ref);
2240
+ });
2241
+ out = out.replace(/<(xm:sqref)>([\s\S]*?)<\/xm:sqref>/g, (_, n, s) => `<${n}>${ranges(s)}</${n}>`);
2242
+ out = out.replace(/<(xm:f)>([\s\S]*?)<\/xm:f>/g, (_, n, f) => `<${n}>${escape(formula(unescape(f)))}</${n}>`);
2243
+ out = out.replace(/<((?:\w+:)?)(selection|pane)\b[^>]*?>/g, (tag) => {
2244
+ let next = tag;
2245
+ for (const name of ["activeCell", "topLeftCell"]) {
2246
+ const v = attr2(next, name);
2247
+ if (v === null) continue;
2248
+ const [r, c] = cell(v);
2249
+ if (r >= 0) next = setAttr(next, name, a1(rows.near(r), cols.near(c)));
2250
+ }
2251
+ const sq = attr2(next, "sqref");
2252
+ return sq === null ? next : setAttr(next, "sqref", ranges(sq) || "A1");
2253
+ });
2254
+ return out;
2255
+ }
2256
+ function anchors(xml, rows, cols) {
2257
+ return xml.replace(/<((?:\w+:)?)(from|to)>([\s\S]*?)<\/\1\2>/g, (all, p, n, inner) => {
2258
+ const next = inner.replace(/<((?:\w+:)?)col>(\d+)<\/\1col>/, (_, q, v) => `<${q}col>${cols.near(Number(v))}</${q}col>`).replace(/<((?:\w+:)?)row>(\d+)<\/\1row>/, (_, q, v) => `<${q}row>${rows.near(Number(v))}</${q}row>`);
2259
+ return `<${p}${n}>${next}</${p}${n}>`;
2260
+ });
2261
+ }
2262
+ function writeXlsx(original, model) {
2263
+ const { model: base, book } = load(original);
2264
+ const { pack, styles } = book;
2265
+ const cur = model.book;
2266
+ const defaults = norm(styles.looks[0] ?? {});
2267
+ const bySheetId = new Map(book.sheets.map((s) => [s.sheetId, s]));
2268
+ const kept = new Set(cur.sheetOrder.map((sid) => model.origin.sheets[sid]).filter((id) => bySheetId.has(id)));
2269
+ const removed = book.sheets.filter((s) => !kept.has(s.sheetId));
2270
+ const charts = [...pack.names.keys()].filter((n) => /^xl\/charts\/chart[^/]*\.xml$/.test(n));
2271
+ const caches = book.rels.filter((r) => r.type === "pivotCacheDefinition").map((r) => r.target);
2272
+ for (const gone of removed) {
2273
+ const pattern = new RegExp(`(^|[^\\w.])(${literal(gone.name)}|'${literal(gone.name.replace(/'/g, "''"))}')!`);
2274
+ const own = new Set(gone.rels.filter((r) => r.type === "drawing").flatMap((r) => pack.rels(r.target)).filter((r) => r.type === "chart").map((r) => r.target));
2275
+ if (charts.some((c) => !own.has(c) && [...(pack.text(c) ?? "").matchAll(/<(?:\w+:)?f>([\s\S]*?)<\/(?:\w+:)?f>/g)].some((m) => pattern.test(unescape(m[1]))))) throw new SheetRefusal("chartSource", gone.name);
2276
+ if (caches.some((c) => new RegExp(`<(?:\\w+:)?worksheetSource\\b[^>]*\\bsheet="${literal(escape(gone.name))}"`).test(pack.text(c) ?? ""))) throw new SheetRefusal("pivotSheet", gone.name);
2277
+ }
2278
+ const names = /* @__PURE__ */ new Map();
2279
+ const axes = /* @__PURE__ */ new Map();
2280
+ let touched = false;
2281
+ const sheetParts = [];
2282
+ let nextSheetId = Math.max(0, ...book.entries.map((e) => e.sheetId)) + 1;
2283
+ let nextRid = Math.max(0, ...book.rels.map((r) => Number(/\d+$/.exec(r.id)?.[0] ?? 0))) + 1;
2284
+ const used = new Set(pack.names.keys());
2285
+ const fresh2 = (pattern) => {
2286
+ let n = 1;
2287
+ while (used.has(pattern(n)) || pack.changed.has(pattern(n))) n++;
2288
+ used.add(pattern(n));
2289
+ return pattern(n);
2290
+ };
2291
+ const types = [];
2292
+ const defaultsNeeded = /* @__PURE__ */ new Set();
2293
+ for (const sid of cur.sheetOrder) {
2294
+ const id = model.origin.sheets[sid];
2295
+ const rec = id !== void 0 ? bySheetId.get(id) ?? null : null;
2296
+ if (rec && [...axes.values()].every((a) => a.rec !== rec)) {
2297
+ const lines2 = model.lines[sid], old = model.origin.lines[sid] ?? base.lines[rec.sid];
2298
+ axes.set(sid, { rows: new Axis(old.rows, lines2.rows), cols: new Axis(old.cols, lines2.cols), rec });
2299
+ sheetParts.push({ sid, rec, part: rec.part, rid: book.entries.find((e) => e.sheetId === rec.sheetId).rid, sheetId: rec.sheetId });
2300
+ if (cur.sheets[sid].name !== rec.name) names.set(rec.name, cur.sheets[sid].name);
2301
+ } else {
2302
+ const part = fresh2((n) => `xl/worksheets/sheet${n}.xml`);
2303
+ sheetParts.push({ sid, rec: null, part, rid: `rId${nextRid++}`, sheetId: nextSheetId++ });
2304
+ types.push([`/${part}`, "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"]);
2305
+ }
2306
+ }
2307
+ const curNotes = resource(cur, "SHEET_NOTE_PLUGIN");
2308
+ const curRules = resource(cur, "SHEET_DATA_VALIDATION_PLUGIN");
2309
+ const curFilters = resource(cur, "SHEET_FILTER_PLUGIN");
2310
+ const baseRules = resource(base.book, "SHEET_DATA_VALIDATION_PLUGIN") ?? {};
2311
+ const baseFilters = resource(base.book, "SHEET_FILTER_PLUGIN") ?? {};
2312
+ const filterNames = /* @__PURE__ */ new Map();
2313
+ for (const entry2 of sheetParts) {
2314
+ const { sid, rec } = entry2;
2315
+ const sheet = cur.sheets[sid];
2316
+ const ax = axes.get(sid);
2317
+ const rows = ax?.rows ?? new Axis([], model.lines[sid]?.rows ?? []);
2318
+ const cols = ax?.cols ?? new Axis([], model.lines[sid]?.cols ?? []);
2319
+ const old = rec ? base.book.sheets[rec.sid] : {};
2320
+ const xml = rec?.xml ?? blankSheet;
2321
+ const p = rec?.p ?? "";
2322
+ const cells = sheet.cellData ?? {};
2323
+ const oldCells = old.cellData ?? {};
2324
+ const fOf = formulas(cells);
2325
+ const rowStyle = (sh, r) => sh.rowData?.[r]?.s;
2326
+ const colStyle = (sh, c) => sh.columnData?.[c]?.s;
2327
+ const seen2 = /* @__PURE__ */ new Map();
2328
+ const looks = (bk, sh, r, c, x) => {
2329
+ const s = x?.s ?? colStyle(sh, c) ?? rowStyle(sh, r);
2330
+ const id = typeof s === "string" ? (bk === cur ? "c" : "b") + s : "";
2331
+ const known = id && seen2.get(id);
2332
+ if (known) return known;
2333
+ const look = norm({ ...defaults, ...lookup(bk, s) });
2334
+ const made2 = { look, json: JSON.stringify(look) };
2335
+ if (id) seen2.set(id, made2);
2336
+ return made2;
2337
+ };
2338
+ const xfOf = (s) => typeof s === "string" && /^x\d+$/.test(s) ? Number(s.slice(1)) : 0;
2339
+ const xfFor = (look, was) => {
2340
+ if (same(norm(styles.looks[was] ?? {}), look) || was === 0 && same(defaults, look)) return was;
2341
+ return styles.find(look) ?? styles.derive(was, look);
2342
+ };
2343
+ let changed2 = !rec || rows.moved || cols.moved;
2344
+ let reused = 0, total = 0;
2345
+ for (const [r, line] of Object.entries(oldCells)) for (const c of Object.keys(line ?? {})) if (rows.map(+r) >= 0 && cols.map(+c) >= 0) total++;
2346
+ const body = [];
2347
+ const filtered = new Set(curFilters?.[sid]?.cachedFilteredOut ?? []);
2348
+ const indices = /* @__PURE__ */ new Set();
2349
+ for (const [r, line] of Object.entries(cells)) if (line && Object.keys(line).length) indices.add(+r);
2350
+ for (const [r, rd] of Object.entries(sheet.rowData ?? {})) if (rd && (rd.h !== void 0 || rd.hd || rd.s)) indices.add(+r);
2351
+ if (rec) for (const r0 of rec.rows.keys()) {
2352
+ const r = rows.map(r0);
2353
+ if (r >= 0) indices.add(r);
2354
+ }
2355
+ for (const r of filtered) indices.add(r);
2356
+ let minR = Infinity, minC = Infinity, maxR = -1, maxC = -1;
2357
+ for (const r of [...indices].sort((a, b) => a - b)) {
2358
+ const r0 = rows.from(r);
2359
+ const orow = r0 >= 0 ? rec?.rows.get(r0) : void 0;
2360
+ const rd = sheet.rowData?.[r] ?? {};
2361
+ const od = r0 >= 0 ? old.rowData?.[r0] ?? {} : {};
2362
+ let tag = orow ? orow.open.replace(/\s*\/>$/, ">") : `<${p}row>`;
2363
+ tag = setAttr(tag, "r", String(r + 1));
2364
+ if (orow && (rows.moved || cols.moved)) tag = setAttr(tag, "spans", null);
2365
+ if (Math.abs((rd.h ?? -1) - (od.h ?? -1)) > 0.5) {
2366
+ changed2 = true;
2367
+ tag = setAttr(setAttr(tag, "ht", rd.h === void 0 ? null : String(pt.row(rd.h))), "customHeight", rd.h === void 0 ? null : "1");
2368
+ }
2369
+ const hidden = !!rd.hd || filtered.has(r);
2370
+ if (hidden !== !!od.hd) {
2371
+ changed2 = true;
2372
+ tag = setAttr(tag, "hidden", hidden ? "1" : null);
2373
+ }
2374
+ const look = rd.s ? norm({ ...defaults, ...lookup(cur, rd.s) }) : null;
2375
+ const was = od.s ? norm({ ...defaults, ...lookup(base.book, od.s) }) : null;
2376
+ if (!same(look, was)) {
2377
+ changed2 = true;
2378
+ tag = setAttr(setAttr(tag, "s", look ? String(xfFor(look, xfOf(od.s))) : null), "customFormat", look ? "1" : null);
2379
+ }
2380
+ const line = cells[r] ?? {};
2381
+ const parts2 = [];
2382
+ for (const c of Object.keys(line).map(Number).sort((a, b) => a - b)) {
2383
+ const x = line[c];
2384
+ if (!x) continue;
2385
+ const c0 = cols.from(c);
2386
+ const ox = r0 >= 0 && c0 >= 0 ? oldCells[r0]?.[c0] : void 0;
2387
+ const f = fOf(r, c, x);
2388
+ const v = textOf(x);
2389
+ const look2 = looks(cur, sheet, r, c, x);
2390
+ const orec = r0 >= 0 && c0 >= 0 ? rec?.cells.get(key(r0, c0)) : void 0;
2391
+ const unchanged = !!ox && (ox.f ?? null) === f && equalValue(textOf(ox), v) && looks(base.book, old, r0, c0, ox).json === look2.json;
2392
+ if (unchanged) reused++;
2393
+ if (blank(v) && !f && !x.s) continue;
2394
+ if (unchanged && orec && !orec.shared) {
2395
+ const raw = xml.slice(orec.start, orec.end);
2396
+ parts2.push(rows.moved || cols.moved ? raw.replace(/^<[^>]*>/, (t) => setAttr(t, "r", a1(r, c))) : raw);
2397
+ } else {
2398
+ if (!unchanged) changed2 = true;
2399
+ const xf = xfFor(look2.look, xfOf(ox?.s ?? colStyle(sheet, c) ?? rowStyle(sheet, r)));
2400
+ const out = cellXml(p, a1(r, c), xf, x, f, v);
2401
+ if (!out) continue;
2402
+ parts2.push(out);
2403
+ }
2404
+ minR = Math.min(minR, r);
2405
+ maxR = Math.max(maxR, r);
2406
+ minC = Math.min(minC, c);
2407
+ maxC = Math.max(maxC, c);
2408
+ }
2409
+ if (!parts2.length && !orow && !rd.h && !hidden && !look) continue;
2410
+ body.push(parts2.length ? `${tag}${parts2.join("")}</${p}row>` : tag.replace(/>$/, "/>"));
2411
+ }
2412
+ if (rec && reused !== total) changed2 = true;
2413
+ let head = xml.slice(0, rec ? rec.bounds[0] : xml.indexOf("<sheetData"));
2414
+ let tail = xml.slice(rec ? rec.bounds[3] : xml.indexOf("<sheetData/>") + 12);
2415
+ const mine = (s) => s === null || s === rec?.name;
2416
+ if (rec && (rows.moved || cols.moved)) {
2417
+ head = remapZone(head, mine, rows, cols);
2418
+ tail = remapZone(tail, mine, rows, cols);
2419
+ }
2420
+ const colXml = columns(p, rec, sheet, old, cols, defaults, cur, base.book, xfFor, xfOf);
2421
+ if (colXml !== void 0) {
2422
+ changed2 = true;
2423
+ head = place(head, "cols", colXml);
2424
+ }
2425
+ const merges = (sheet.mergeData ?? []).map((m) => span(m)).sort();
2426
+ const oldMerges = [...rec?.merges ?? []].map((m) => span(box(m))).sort();
2427
+ if (!same(merges, oldMerges)) {
2428
+ changed2 = true;
2429
+ tail = place(tail, "mergeCells", merges.length ? `<${p}mergeCells count="${merges.length}">${merges.map((m) => `<${p}mergeCell ref="${m}"/>`).join("")}</${p}mergeCells>` : null);
2430
+ }
2431
+ const freeze = sheet.freeze && (sheet.freeze.xSplit > 0 || sheet.freeze.ySplit > 0) ? [sheet.freeze.xSplit, sheet.freeze.ySplit] : [0, 0];
2432
+ const oldFreeze = old.freeze ? [old.freeze.xSplit, old.freeze.ySplit] : [0, 0];
2433
+ if (!same(freeze, oldFreeze)) {
2434
+ changed2 = true;
2435
+ head = frozen(head, p, freeze[0], freeze[1]);
2436
+ }
2437
+ if ((sheet.showGridlines ?? 1) !== (old.showGridlines ?? 1)) {
2438
+ changed2 = true;
2439
+ head = head.replace(/<(?:\w+:)?sheetView\b[^>]*?>/, (t) => setAttr(t, "showGridLines", sheet.showGridlines === 0 ? "0" : null));
2440
+ }
2441
+ if ((sheet.tabColor ?? "") !== (old.tabColor ?? "")) {
2442
+ changed2 = true;
2443
+ head = tabColour(head, p, sheet.tabColor ?? "");
2444
+ }
2445
+ const rules = (curRules ? curRules[sid] ?? [] : rec ? baseRules[rec.sid] ?? [] : []).map((r) => ({ ...r, ranges: r.ranges.map((b) => ({ startRow: b.startRow, startColumn: b.startColumn, endRow: b.endRow, endColumn: b.endColumn })) }));
2446
+ const oldRules = (rec ? baseRules[rec.sid] ?? [] : []).map((r) => ({ ...r, ranges: r.ranges.map((b) => squeeze(b, rows.map, cols.map)).filter(Boolean) }));
2447
+ if (curRules && !same(rules.map(canonRule), oldRules.map(canonRule))) {
2448
+ changed2 = true;
2449
+ const known = new Map((rec?.validations ?? []).map((v, i) => [`dv${i}`, v]));
2450
+ const shown = new Set(rules.map((r) => r.uid));
2451
+ const hiddenRules = [...known].filter(([uid, v]) => !shown.has(uid) && !(rec && baseRules[rec.sid]?.some((r) => r.uid === uid)) && v).map(([, v]) => rows.moved || cols.moved ? remapZone(v, mine, rows, cols) : v);
2452
+ const list = [...hiddenRules, ...rules.map((r) => validationXml(p, r, known.get(r.uid)))].filter(Boolean);
2453
+ tail = place(tail, "dataValidations", list.length ? `<${p}dataValidations count="${list.length}">${list.join("")}</${p}dataValidations>` : null);
2454
+ }
2455
+ const oldFilter = rec ? baseFilters[rec.sid] ?? null : null;
2456
+ const filter = curFilters ? curFilters[sid] ?? null : oldFilter;
2457
+ const fref = filter?.ref ? span(filter.ref) : null;
2458
+ const oref = oldFilter?.ref ? (() => {
2459
+ const b = squeeze(oldFilter.ref, rows.map, cols.map);
2460
+ return b && span(b);
2461
+ })() : null;
2462
+ if (curFilters && (fref !== oref || !same(filter?.filterColumns ?? [], oldFilter?.filterColumns ?? []))) {
2463
+ changed2 = true;
2464
+ tail = place(tail, "autoFilter", filter?.ref ? filterXml(p, filter.ref, filter.filterColumns ?? []) : null);
2465
+ filterNames.set(entry2.sheetId, filter?.ref ? `${quoted(sheet.name)}!${span(filter.ref).split(":").map((s) => s.replace(/([A-Z]+)(\d+)/, "$$$1$$$2")).join(":")}` : null);
2466
+ }
2467
+ const notes2 = Object.values(curNotes?.[sid] ?? {}).flatMap((line) => Object.values(line ?? {})).filter((n) => n && !blank(n.note));
2468
+ const oldNotes = (rec?.notes ?? []).map((n) => ({ ref: n.ref, text: n.text }));
2469
+ const nowNotes = notes2.map((n) => ({ ref: a1(n.row, n.col), text: n.note })).sort((a, b) => a.ref.localeCompare(b.ref));
2470
+ if (curNotes && !same(nowNotes, [...oldNotes].sort((a, b) => a.ref.localeCompare(b.ref)))) {
2471
+ changed2 = true;
2472
+ tail = writeNotes(book, entry2, tail, p, notes2, rows, cols, types, defaultsNeeded, fresh2);
2473
+ }
2474
+ const rename = (s) => names.size ? s.replace(/<(xm:f|(?:\w+:)?formula\d?)>([\s\S]*?)<\/\1>/g, (_, n, f) => `<${n}>${escape([...names].reduce((g, [from, to]) => renamed(g, from, to), unescape(f)))}</${n}>`) : s;
2475
+ if (!changed2) {
2476
+ if (rec && rename(xml) !== xml) pack.put(entry2.part, rename(xml));
2477
+ continue;
2478
+ }
2479
+ touched = true;
2480
+ head = rename(head);
2481
+ tail = rename(tail);
2482
+ if (/\sr:id="/.test(tail) && !/xmlns:r=/.test(head)) head = head.replace(/<((?:\w+:)?worksheet)\b/, `<$1 xmlns:r="${REL}"`);
2483
+ const dim = maxR < 0 ? "A1" : span({ startRow: minR, startColumn: minC, endRow: maxR, endColumn: maxC });
2484
+ head = /<(?:\w+:)?dimension\b/.test(head) ? head.replace(/<((?:\w+:)?)dimension\b[^>]*\/?>/, `<$1dimension ref="${dim}"/>`) : place(head, "dimension", `<${p}dimension ref="${dim}"/>`);
2485
+ pack.put(entry2.part, head + (body.length ? `<${p}sheetData>${body.join("")}</${p}sheetData>` : `<${p}sheetData/>`) + tail);
2486
+ if (rec && (rows.moved || cols.moved)) {
2487
+ for (const rel of rec.rels) {
2488
+ if (rel.external) continue;
2489
+ if (rel.type === "drawing") {
2490
+ const d = pack.text(rel.target);
2491
+ if (d) pack.put(rel.target, anchors(d, rows, cols));
2492
+ }
2493
+ if (rel.type === "table") {
2494
+ const t = pack.text(rel.target);
2495
+ if (!t) continue;
2496
+ const ref = attr2(/<(?:\w+:)?table\b[^>]*>/.exec(t)?.[0] ?? "", "ref");
2497
+ const b = ref && box(ref);
2498
+ const moved = b && squeeze(b, rows.map, cols.map);
2499
+ if (b && moved && moved.endColumn - moved.startColumn !== b.endColumn - b.startColumn) throw new SheetRefusal("tableColumns", rec.name);
2500
+ if (moved) pack.put(rel.target, t.replace(/(<(?:\w+:)?(?:table|autoFilter)\b[^>]*?\sref=")([^"]*)"/g, (_, a, r) => `${a}${span(squeeze(box(r), rows.map, cols.map) ?? box(r))}"`));
2501
+ }
2502
+ }
2503
+ }
2504
+ }
2505
+ const sheetStyles = styles.build();
2506
+ if (sheetStyles) {
2507
+ const target = book.stylesPart ?? "xl/styles.xml";
2508
+ pack.put(target, sheetStyles);
2509
+ if (!book.stylesPart) {
2510
+ types.push([`/${target}`, "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"]);
2511
+ pack.put(relsOf(book.part), (pack.text(relsOf(book.part)) ?? "").replace(/<\/(?:\w+:)?Relationships>/, (end) => `<Relationship Id="rId${nextRid++}" Type="${REL}/styles" Target="${relative(book.part, target)}"/>${end}`));
2512
+ }
2513
+ touched = true;
2514
+ }
2515
+ for (const [sid, ax] of axes) {
2516
+ if (!ax.rows.moved && !ax.cols.moved) continue;
2517
+ const name = ax.rec.name;
2518
+ const mine = (s) => s === name;
2519
+ for (const c of charts) {
2520
+ const t = pack.text(c);
2521
+ if (t && t.includes(name)) pack.put(c, t.replace(/<((?:\w+:)?)f>([\s\S]*?)<\/\1f>/g, (_, p, f) => `<${p}f>${escape(remapped(unescape(f), mine, ax.rows.map, ax.cols.map))}</${p}f>`));
2522
+ }
2523
+ for (const c of caches) {
2524
+ const t = pack.text(c);
2525
+ if (t) pack.put(c, t.replace(/<(?:\w+:)?worksheetSource\b[^>]*>/g, (tag) => attr2(tag, "sheet") === name && attr2(tag, "ref") ? setAttr(tag, "ref", span(squeeze(box(attr2(tag, "ref")), ax.rows.map, ax.cols.map) ?? box(attr2(tag, "ref")))) : tag));
2526
+ }
2527
+ for (const other of sheetParts) {
2528
+ if (other.sid === sid || !other.rec) continue;
2529
+ const t = pack.text(other.part);
2530
+ if (t && t.includes(name)) pack.put(other.part, t.replace(/<(xm:f|(?:\w+:)?formula\d?)>([\s\S]*?)<\/\1>/g, (_, n, f) => `<${n}>${escape(remapped(unescape(f), mine, ax.rows.map, ax.cols.map))}</${n}>`));
2531
+ }
2532
+ }
2533
+ for (const [from, to] of names) {
2534
+ for (const c of charts) {
2535
+ const t = pack.text(c);
2536
+ if (t && t.includes(from)) pack.put(c, t.replace(/<((?:\w+:)?)f>([\s\S]*?)<\/\1f>/g, (_, p, f) => `<${p}f>${escape(renamed(unescape(f), from, to))}</${p}f>`));
2537
+ }
2538
+ for (const c of caches) {
2539
+ const t = pack.text(c);
2540
+ if (t) pack.put(c, t.replace(/(<(?:\w+:)?worksheetSource\b[^>]*\ssheet=")([^"]*)"/g, (all, a, s) => unescape(s) === from ? `${a}${escape(to)}"` : all));
2541
+ }
2542
+ }
2543
+ const sheetsChanged = removed.length > 0 || names.size > 0 || sheetParts.some((s) => !s.rec) || sheetParts.map((s) => s.sheetId).join() !== book.entries.filter((e) => e.sheet && kept.has(e.sheetId)).map((e) => e.sheetId).join() || cur.sheetOrder.some((sid) => {
2544
+ const rec = axes.get(sid)?.rec;
2545
+ return !!rec && (cur.sheets[sid].hidden ?? 0) !== (base.book.sheets[rec.sid].hidden ?? 0);
2546
+ });
2547
+ if (!touched && !sheetsChanged && !filterNames.size) return original;
2548
+ let wb = book.xml;
2549
+ const listed = [];
2550
+ const nonSheets = book.entries.map((e, i) => ({ e, i })).filter((x) => !x.e.sheet);
2551
+ const indexOf = new Map(book.entries.map((e, i) => [e.sheetId, i]));
2552
+ const wp = /<(\w+:)?workbook\b/.exec(wb)?.[1] ?? "";
2553
+ const relPrefix = /xmlns:(\w+)="http:\/\/schemas\.openxmlformats\.org\/officeDocument\/2006\/relationships"/.exec(wb)?.[1] ?? "r";
2554
+ for (const s of sheetParts) {
2555
+ const sheet = cur.sheets[s.sid];
2556
+ const state = sheet.hidden === 2 ? "veryHidden" : sheet.hidden ? "hidden" : null;
2557
+ let tag = s.rec ? book.entries.find((e) => e.sheetId === s.sheetId).xml : `<${wp}sheet name="" sheetId="${s.sheetId}" ${relPrefix}:id="${s.rid}"/>`;
2558
+ tag = setAttr(setAttr(tag, "name", sheet.name ?? `Sheet${s.sheetId}`), "state", state);
2559
+ listed.push({ xml: tag, sheetId: s.sheetId, oldIndex: s.rec ? indexOf.get(s.sheetId) : -1 });
2560
+ }
2561
+ for (const { e, i } of nonSheets) {
2562
+ let at = listed.findIndex((x) => x.oldIndex > i);
2563
+ if (at < 0) at = listed.length;
2564
+ listed.splice(at, 0, { xml: e.xml, sheetId: e.sheetId, oldIndex: i });
2565
+ }
2566
+ wb = wb.replace(/(<(?:\w+:)?sheets\b[^>]*>)[\s\S]*?(<\/(?:\w+:)?sheets>)/, (_, a, b) => a + listed.map((x) => x.xml).join("") + b);
2567
+ const newIndex = new Map(listed.map((x, i) => [x.oldIndex, i]));
2568
+ const sheetIndex = new Map(listed.map((x, i) => [x.sheetId, i]));
2569
+ const removedNames = new Set(removed.map((r) => r.name));
2570
+ wb = wb.replace(/<((?:\w+:)?)definedName\b([^>]*)>([\s\S]*?)<\/\1definedName>/g, (all, p, attrs0, body) => {
2571
+ let tag = `<${p}definedName${attrs0}>`;
2572
+ const local = attr2(tag, "localSheetId");
2573
+ if (local !== null) {
2574
+ const next = newIndex.get(Number(local));
2575
+ if (next === void 0) return "";
2576
+ tag = setAttr(tag, "localSheetId", String(next));
2577
+ const owner = listed[next];
2578
+ if (attr2(tag, "name") === "_xlnm._FilterDatabase" && filterNames.has(owner.sheetId)) {
2579
+ const f2 = filterNames.get(owner.sheetId);
2580
+ filterNames.delete(owner.sheetId);
2581
+ return f2 ? `${tag}${escape(f2)}</${p}definedName>` : "";
2582
+ }
2583
+ }
2584
+ let f = unescape(body);
2585
+ for (const gone of removedNames) f = f.replace(new RegExp(`(?:'${literal(gone.replace(/'/g, "''"))}'|${literal(gone)})![$A-Z0-9:]+`, "g"), "#REF!");
2586
+ for (const [, ax] of axes) if (ax.rows.moved || ax.cols.moved) f = remapped(f, (s) => s === ax.rec.name, ax.rows.map, ax.cols.map);
2587
+ for (const [from, to] of names) f = renamed(f, from, to);
2588
+ return `${tag}${escape(f)}</${p}definedName>`;
2589
+ });
2590
+ for (const [sheetId, f] of filterNames) {
2591
+ if (!f) continue;
2592
+ const def = `<${wp}definedName name="_xlnm._FilterDatabase" localSheetId="${sheetIndex.get(sheetId)}" hidden="1">${escape(f)}</${wp}definedName>`;
2593
+ wb = /<(?:\w+:)?definedNames\b/.test(wb) ? wb.replace(/<\/(?:\w+:)?definedNames>/, (end) => def + end) : wb.replace(/<\/(?:\w+:)?sheets>/, (end) => `${end}<${wp}definedNames>${def}</${wp}definedNames>`);
2594
+ }
2595
+ wb = wb.replace(/<((?:\w+:)?)definedNames>\s*<\/\1definedNames>/, "");
2596
+ wb = wb.replace(/<(?:\w+:)?workbookView\b[^>]*>/g, (tag) => {
2597
+ const total = listed.length;
2598
+ let next = tag;
2599
+ const tab = attr2(next, "activeTab");
2600
+ if (tab !== null) next = setAttr(next, "activeTab", String(Math.min(newIndex.get(Number(tab)) ?? 0, total - 1)));
2601
+ const first = attr2(next, "firstSheet");
2602
+ if (first !== null) next = setAttr(next, "firstSheet", String(Math.min(newIndex.get(Number(first)) ?? 0, total - 1)));
2603
+ return next;
2604
+ });
2605
+ if (touched) {
2606
+ wb = /<(?:\w+:)?calcPr\b/.test(wb) ? wb.replace(/<(?:\w+:)?calcPr\b[^>]*?\/?>/, (tag) => setAttr(tag, "fullCalcOnLoad", "1")) : wb.replace(/(<\/(?:\w+:)?sheets>(?:\s*<(?:\w+:)?(?:functionGroups|externalReferences|definedNames)\b[\s\S]*?<\/(?:\w+:)?(?:functionGroups|externalReferences|definedNames)>)*)/, `$1<${wp}calcPr fullCalcOnLoad="1"/>`);
2607
+ }
2608
+ pack.put(book.part, wb);
2609
+ let rels = pack.text(relsOf(book.part)) ?? "";
2610
+ for (const gone of removed) {
2611
+ const entry2 = book.entries.find((e) => e.sheetId === gone.sheetId);
2612
+ rels = rels.replace(new RegExp(`<(?:\\w+:)?Relationship\\b[^>]*\\bId="${entry2.rid}"[^>]*\\/>`), "");
2613
+ pack.put(gone.part, null);
2614
+ pack.put(relsOf(gone.part), null);
2615
+ types.push([`/${gone.part}`, null]);
2616
+ }
2617
+ const calc = book.rels.find((r) => r.type === "calcChain");
2618
+ if (calc && touched) {
2619
+ rels = rels.replace(new RegExp(`<(?:\\w+:)?Relationship\\b[^>]*\\bId="${calc.id}"[^>]*\\/>`), "");
2620
+ pack.put(calc.target, null);
2621
+ types.push([`/${calc.target}`, null]);
2622
+ }
2623
+ for (const s of sheetParts) if (!s.rec) rels = rels.replace(/<\/(?:\w+:)?Relationships>/, (end) => `<Relationship Id="${s.rid}" Type="${REL}/worksheet" Target="${relative(book.part, s.part)}"/>${end}`);
2624
+ pack.put(relsOf(book.part), rels);
2625
+ contentTypes(pack, types, defaultsNeeded);
2626
+ return copy(pack.build());
2627
+ }
2628
+ var copy = (u) => u.buffer.slice(u.byteOffset, u.byteOffset + u.byteLength);
2629
+ function contentTypes(pack, types, defaults) {
2630
+ if (!types.length && !defaults.size) return;
2631
+ let ct = pack.text("[Content_Types].xml") ?? "";
2632
+ for (const [name, type] of types) {
2633
+ ct = ct.replace(new RegExp(`<Override\\b[^>]*PartName="${literal(name)}"[^>]*\\/>`), "");
2634
+ if (type) ct = ct.replace("</Types>", () => `<Override PartName="${name}" ContentType="${type}"/></Types>`);
2635
+ }
2636
+ for (const ext of defaults) if (!new RegExp(`Extension="${ext}"`, "i").test(ct)) ct = ct.replace(/(<Types\b[^>]*>)/, `$1<Default Extension="${ext}" ContentType="application/vnd.openxmlformats-officedocument.vmlDrawing"/>`);
2637
+ pack.put("[Content_Types].xml", ct);
2638
+ }
2639
+ function cellXml(p, ref, xf, x, f, v) {
2640
+ const s = xf ? ` s="${xf}"` : "";
2641
+ if (f) {
2642
+ const body = escape(stored(f.replace(/^=/, "")));
2643
+ let t = "", val = "";
2644
+ if (typeof v === "number" && Number.isFinite(v)) val = `<${p}v>${v}</${p}v>`;
2645
+ else if (typeof v === "boolean" || x.t === 3) {
2646
+ t = ' t="b"';
2647
+ val = `<${p}v>${v === true || v === 1 ? 1 : 0}</${p}v>`;
2648
+ } else if (typeof v === "string" && v !== "") {
2649
+ t = errors.test(v) ? ' t="e"' : ' t="str"';
2650
+ val = `<${p}v>${escape(v)}</${p}v>`;
2651
+ }
2652
+ return `<${p}c r="${ref}"${s}${t}><${p}f>${body}</${p}f>${val}</${p}c>`;
2653
+ }
2654
+ if (blank(v)) return xf ? `<${p}c r="${ref}"${s}/>` : "";
2655
+ if (typeof v === "boolean") return `<${p}c r="${ref}"${s} t="b"><${p}v>${v ? 1 : 0}</${p}v></${p}c>`;
2656
+ if (typeof v === "number") return Number.isFinite(v) ? `<${p}c r="${ref}"${s}><${p}v>${v}</${p}v></${p}c>` : `<${p}c r="${ref}"${s} t="e"><${p}v>#NUM!</${p}v></${p}c>`;
2657
+ const str = String(v);
2658
+ if (x.t === 2 && str.trim() !== "" && Number.isFinite(Number(str))) return `<${p}c r="${ref}"${s}><${p}v>${Number(str)}</${p}v></${p}c>`;
2659
+ if (x.t !== 4 && errors.test(str)) return `<${p}c r="${ref}"${s} t="e"><${p}v>${escape(str)}</${p}v></${p}c>`;
2660
+ const space = /^\s|\s$|\n/.test(str) ? ' xml:space="preserve"' : "";
2661
+ return `<${p}c r="${ref}"${s} t="inlineStr"><${p}is><${p}t${space}>${escape(str)}</${p}t></${p}is></${p}c>`;
2662
+ }
2663
+ function columns(p, rec, sheet, old, cols, defaults, cur, baseBook, xfFor, xfOf) {
2664
+ const now = sheet.columnData ?? {}, was = old.columnData ?? {};
2665
+ const count = sheet.columnCount ?? 26;
2666
+ const look = (bk, s) => s ? norm({ ...defaults, ...lookup(bk, s) }) : null;
2667
+ let differs = cols.moved;
2668
+ for (let c = 0; c < count && !differs; c++) {
2669
+ const c0 = cols.from(c);
2670
+ const a = now[c] ?? {}, b = c0 >= 0 ? was[c0] ?? {} : {};
2671
+ if (Math.abs((a.w ?? -1) - (b.w ?? -1)) > 0.5 || !!a.hd !== !!b.hd || !same(look(cur, a.s), look(baseBook, b.s))) differs = true;
2672
+ }
2673
+ if (!differs) return void 0;
2674
+ const specs = rec?.cols ?? [];
2675
+ const specAt = (c0) => specs.find((s) => c0 + 1 >= s.min && c0 + 1 <= s.max);
2676
+ const out = [];
2677
+ for (let c = 0; c < count; c++) {
2678
+ const c0 = cols.from(c);
2679
+ const spec = c0 >= 0 ? specAt(c0) : void 0;
2680
+ const a = new Map(spec ? [...spec.xml.matchAll(/([\w:]+)="([^"]*)"/g)].map((m) => [m[1], m[2]]) : []);
2681
+ a.delete("min");
2682
+ a.delete("max");
2683
+ const n = now[c] ?? {}, o = c0 >= 0 ? was[c0] ?? {} : {};
2684
+ if (Math.abs((n.w ?? -1) - (o.w ?? -1)) > 0.5) {
2685
+ if (n.w === void 0) {
2686
+ a.delete("width");
2687
+ a.delete("customWidth");
2688
+ } else {
2689
+ a.set("width", String(pt.col(n.w)));
2690
+ a.set("customWidth", "1");
2691
+ }
2692
+ }
2693
+ if (!!n.hd !== !!o.hd) n.hd ? a.set("hidden", "1") : a.delete("hidden");
2694
+ const ln = look(cur, n.s), lo = look(baseBook, o.s);
2695
+ if (!same(ln, lo)) ln ? a.set("style", String(xfFor(ln, xfOf(o.s)))) : a.delete("style");
2696
+ if (!a.size) continue;
2697
+ if (!a.has("width")) a.set("width", String(pt.col(sheet.defaultColumnWidth ?? 64)));
2698
+ out.push({ c, attrs: a });
2699
+ }
2700
+ const runs2 = [];
2701
+ for (let i = 0; i < out.length; i++) {
2702
+ let j = i;
2703
+ const k = JSON.stringify([...out[i].attrs]);
2704
+ while (j + 1 < out.length && out[j + 1].c === out[j].c + 1 && JSON.stringify([...out[j + 1].attrs]) === k) j++;
2705
+ runs2.push(`<${p}col min="${out[i].c + 1}" max="${out[j].c + 1}"${[...out[i].attrs].map(([n, v]) => ` ${n}="${v}"`).join("")}/>`);
2706
+ i = j;
2707
+ }
2708
+ const shift = count - (rec?.width ?? count);
2709
+ for (const spec of specs) {
2710
+ if (spec.max <= (rec?.width ?? 0)) continue;
2711
+ const min = Math.max(count + 1, spec.min + shift), max = Math.min(16384, spec.max + shift);
2712
+ if (min <= max) runs2.push(spec.xml.replace(/\smin="\d+"/, ` min="${min}"`).replace(/\smax="\d+"/, ` max="${max}"`));
2713
+ }
2714
+ return runs2.length ? `<${p}cols>${runs2.join("")}</${p}cols>` : null;
2715
+ }
2716
+ function frozen(head, p, x, y) {
2717
+ const pane = x || y ? `<${p}pane${x ? ` xSplit="${x}"` : ""}${y ? ` ySplit="${y}"` : ""} topLeftCell="${a1(y, x)}" activePane="${x && y ? "bottomRight" : y ? "bottomLeft" : "topRight"}" state="frozen"/>` : "";
2718
+ const selection = x || y ? `<${p}selection pane="${x && y ? "bottomRight" : y ? "bottomLeft" : "topRight"}" activeCell="${a1(y, x)}" sqref="${a1(y, x)}"/>` : `<${p}selection activeCell="A1" sqref="A1"/>`;
2719
+ const view = /<((?:\w+:)?)sheetView\b[^>]*?(\/?)>/.exec(head);
2720
+ if (!view) return place(head, "sheetViews", `<${p}sheetViews><${p}sheetView workbookViewId="0">${pane}${selection}</${p}sheetView></${p}sheetViews>`);
2721
+ if (view[2]) return head.slice(0, view.index) + view[0].replace(/\s*\/>$/, ">") + pane + selection + `</${view[1]}sheetView>` + head.slice(view.index + view[0].length);
2722
+ const close = head.indexOf(`</${view[1]}sheetView>`, view.index);
2723
+ const inner = head.slice(view.index + view[0].length, close).replace(/<(?:\w+:)?pane\b[^>]*\/>/g, "").replace(/<(?:\w+:)?selection\b[^>]*\/>/g, "");
2724
+ return head.slice(0, view.index) + view[0] + pane + selection + inner + head.slice(close);
2725
+ }
2726
+ function tabColour(head, p, colour) {
2727
+ const tag = colour ? `<${p}tabColor rgb="FF${colour.replace("#", "").toUpperCase()}"/>` : "";
2728
+ if (/<(?:\w+:)?tabColor\b/.test(head)) return head.replace(/<(?:\w+:)?tabColor\b[^>]*\/>/, tag);
2729
+ if (!colour) return head;
2730
+ const pr = /<((?:\w+:)?)sheetPr\b[^>]*?(\/?)>/.exec(head);
2731
+ if (!pr) return place(head, "sheetPr", `<${p}sheetPr>${tag}</${p}sheetPr>`);
2732
+ if (pr[2]) return head.slice(0, pr.index) + pr[0].replace(/\s*\/>$/, ">") + tag + `</${pr[1]}sheetPr>` + head.slice(pr.index + pr[0].length);
2733
+ return head.slice(0, pr.index + pr[0].length) + tag + head.slice(pr.index + pr[0].length);
2734
+ }
2735
+ function canonRule(r) {
2736
+ const out = {};
2737
+ for (const k of ["uid", "type", "operator", "formula1", "formula2", "allowBlank", "showDropDown", "showErrorMessage", "showInputMessage", "errorStyle", "error", "errorTitle", "prompt", "promptTitle"]) {
2738
+ const v = r[k];
2739
+ if (v !== void 0 && v !== null && v !== false && v !== "") out[k] = v;
2740
+ }
2741
+ if (out.type === "list" && out.showDropDown === void 0) out.showDropDown = true;
2742
+ out.ranges = r.ranges.map((b) => span(b)).sort();
2743
+ return out;
2744
+ }
2745
+ function validationXml(p, r, was) {
2746
+ if (!["whole", "decimal", "list", "textLength", "custom", "date"].includes(String(r.type))) return "";
2747
+ let tag = was ? was.slice(0, was.indexOf(">") + 1).replace(/\s*\/>$/, ">") : `<${p}dataValidation>`;
2748
+ const bool = (name, on) => {
2749
+ tag = setAttr(tag, name, on ? "1" : null);
2750
+ };
2751
+ tag = setAttr(tag, "type", String(r.type));
2752
+ tag = setAttr(tag, "operator", r.type === "list" || r.type === "custom" || !r.operator || r.operator === "between" ? null : String(r.operator));
2753
+ bool("allowBlank", r.allowBlank);
2754
+ bool("showDropDown", r.type === "list" && r.showDropDown === false);
2755
+ bool("showInputMessage", r.showInputMessage);
2756
+ bool("showErrorMessage", r.showErrorMessage);
2757
+ const style = Object.entries(stops).find(([, v]) => v === r.errorStyle)?.[0];
2758
+ tag = setAttr(tag, "errorStyle", style && style !== "stop" ? style : null);
2759
+ for (const name of ["errorTitle", "error", "promptTitle", "prompt"]) tag = setAttr(tag, name, blank(r[name]) ? null : String(r[name]));
2760
+ tag = setAttr(tag, "sqref", r.ranges.map(span).join(" "));
2761
+ const f1 = r.formula1 === void 0 ? "" : r.type === "list" && !String(r.formula1).startsWith("=") ? `"${listText(String(r.formula1)).replace(/"/g, '""')}"` : stored(String(r.formula1).replace(/^=/, ""));
2762
+ const f2 = r.formula2 === void 0 ? "" : stored(String(r.formula2).replace(/^=/, ""));
2763
+ return `${tag}${f1 ? `<${p}formula1>${escape(f1)}</${p}formula1>` : ""}${f2 ? `<${p}formula2>${escape(f2)}</${p}formula2>` : ""}</${p}dataValidation>`;
2764
+ }
2765
+ function listText(f) {
2766
+ try {
2767
+ const list = JSON.parse(f);
2768
+ if (Array.isArray(list)) return list.join(",");
2769
+ } catch {
2770
+ return f;
2771
+ }
2772
+ return f;
2773
+ }
2774
+ function filterXml(p, ref, columns2) {
2775
+ const body = columns2.map((c) => {
2776
+ if (c.filters) return `<${p}filterColumn colId="${c.colId}"><${p}filters${c.filters.blank ? ' blank="1"' : ""}>${(c.filters.filters ?? []).map((v) => `<${p}filter val="${escape(String(v))}"/>`).join("")}</${p}filters></${p}filterColumn>`;
2777
+ if (c.customFilters) return `<${p}filterColumn colId="${c.colId}"><${p}customFilters${c.customFilters.and ? ' and="1"' : ""}>${c.customFilters.customFilters.map((f) => `<${p}customFilter${f.operator ? ` operator="${f.operator}"` : ""} val="${escape(String(f.val))}"/>`).join("")}</${p}customFilters></${p}filterColumn>`;
2778
+ return "";
2779
+ }).join("");
2780
+ return body ? `<${p}autoFilter ref="${span(ref)}">${body}</${p}autoFilter>` : `<${p}autoFilter ref="${span(ref)}"/>`;
2781
+ }
2782
+ function writeNotes(book, entry2, tail, p, notes2, rows, cols, types, defaults, fresh2) {
2783
+ const { pack } = book;
2784
+ const rec = entry2.rec;
2785
+ const relsPart = relsOf(entry2.part);
2786
+ let rels = pack.text(relsPart) ?? '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"></Relationships>';
2787
+ let nextRid = Math.max(0, ...[...rels.matchAll(/\bId="rId(\d+)"/g)].map((m) => Number(m[1]))) + 1;
2788
+ let commentsPart = rec?.comments ?? null;
2789
+ let vmlPart = rec?.vml ?? null;
2790
+ if (!commentsPart) {
2791
+ commentsPart = fresh2((n) => `xl/comments${n}.xml`);
2792
+ rels = rels.replace("</Relationships>", () => `<Relationship Id="rId${nextRid++}" Type="${REL}/comments" Target="${relative(entry2.part, commentsPart)}"/></Relationships>`);
2793
+ types.push([`/${commentsPart}`, "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml"]);
2794
+ }
2795
+ if (!vmlPart) {
2796
+ vmlPart = fresh2((n) => `xl/drawings/vmlDrawing${n}.vml`);
2797
+ const rid = `rId${nextRid++}`;
2798
+ rels = rels.replace("</Relationships>", () => `<Relationship Id="${rid}" Type="${REL}/vmlDrawing" Target="${relative(entry2.part, vmlPart)}"/></Relationships>`);
2799
+ defaults.add("vml");
2800
+ const relNs = /xmlns:(\w+)="http:\/\/schemas\.openxmlformats\.org\/officeDocument\/2006\/relationships"/.exec(rec?.xml ?? "")?.[1];
2801
+ tail = place(tail, "legacyDrawing", `<${p}legacyDrawing ${relNs ?? "r"}:id="${rid}"/>`);
2802
+ }
2803
+ pack.put(relsPart, rels);
2804
+ const authors = rec?.authors.length ? [...rec.authors] : ["Author"];
2805
+ const byOld = new Map((rec?.notes ?? []).map((n) => {
2806
+ const [r, c] = cell(n.ref);
2807
+ return [a1(rows.map(r), cols.map(c)), n];
2808
+ }));
2809
+ const list = [...notes2].sort((a, b) => a.row - b.row || a.col - b.col).map((n) => {
2810
+ const ref = a1(n.row, n.col);
2811
+ const was = byOld.get(ref);
2812
+ if (was && was.text === n.note) return setAttr(was.xml.slice(0, was.xml.indexOf(">") + 1), "ref", ref) + was.xml.slice(was.xml.indexOf(">") + 1);
2813
+ const authorId = was ? attr2(was.xml, "authorId") ?? "0" : "0";
2814
+ return `<${p}comment ref="${ref}" authorId="${authorId}"><${p}text><${p}r><${p}t xml:space="preserve">${escape(n.note)}</${p}t></${p}r></${p}text></${p}comment>`;
2815
+ });
2816
+ const existing = pack.text(commentsPart);
2817
+ const authorsXml = `<${p}authors>${authors.map((a) => `<${p}author>${escape(a)}</${p}author>`).join("")}</${p}authors>`;
2818
+ const commentsXml = existing ? existing.replace(/<((?:\w+:)?)commentList\b[^>]*?(?:\/>|>[\s\S]*?<\/\1commentList>)/, () => `<${p}commentList>${list.join("")}</${p}commentList>`) : `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2819
+ <comments xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">${authorsXml}<commentList>${list.join("")}</commentList></comments>`;
2820
+ pack.put(commentsPart, commentsXml);
2821
+ const vml = pack.text(vmlPart) ?? '<xml xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel"><o:shapelayout v:ext="edit"><o:idmap v:ext="edit" data="1"/></o:shapelayout><v:shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202" path="m,l,21600r21600,l21600,xe"><v:stroke joinstyle="miter"/><v:path gradientshapeok="t" o:connecttype="rect"/></v:shapetype></xml>';
2822
+ const shapes = /* @__PURE__ */ new Map();
2823
+ let rest = vml.replace(/<v:shape\b[^>]*>[\s\S]*?<\/v:shape>/g, (shape) => {
2824
+ if (!/ObjectType="Note"/.test(shape)) return shape;
2825
+ const r = Number(/<x:Row>(\d+)<\/x:Row>/.exec(shape)?.[1] ?? -1), c = Number(/<x:Column>(\d+)<\/x:Column>/.exec(shape)?.[1] ?? -1);
2826
+ if (r >= 0 && c >= 0) shapes.set(a1(rows.map(r), cols.map(c)), shape);
2827
+ return "";
2828
+ });
2829
+ let id = Math.max(1024, ...[...vml.matchAll(/_x0000_s(\d+)/g)].map((m) => Number(m[1])));
2830
+ const out = notes2.map((n) => {
2831
+ const ref = a1(n.row, n.col);
2832
+ const was = shapes.get(ref);
2833
+ if (was) return was.replace(/<x:Row>\d+<\/x:Row>/, `<x:Row>${n.row}</x:Row>`).replace(/<x:Column>\d+<\/x:Column>/, `<x:Column>${n.col}</x:Column>`).replace(/<x:Anchor>([^<]*)<\/x:Anchor>/, `<x:Anchor>${n.col + 1}, 15, ${n.row}, 2, ${n.col + 3}, 15, ${n.row + 4}, 16</x:Anchor>`);
2834
+ return `<v:shape id="_x0000_s${++id}" type="#_x0000_t202" style="position:absolute;margin-left:59.25pt;margin-top:1.5pt;width:108pt;height:59.25pt;z-index:1;visibility:hidden" fillcolor="#ffffe1" o:insetmode="auto"><v:fill color2="#ffffe1"/><v:shadow on="t" color="black" obscured="t"/><v:path o:connecttype="none"/><v:textbox style="mso-direction-alt:auto"><div style="text-align:left"></div></v:textbox><x:ClientData ObjectType="Note"><x:MoveWithCells/><x:SizeWithCells/><x:Anchor>${n.col + 1}, 15, ${n.row}, 2, ${n.col + 3}, 15, ${n.row + 4}, 16</x:Anchor><x:AutoFill>False</x:AutoFill><x:Row>${n.row}</x:Row><x:Column>${n.col}</x:Column></x:ClientData></v:shape>`;
2835
+ }).join("");
2836
+ rest = rest.replace(/<\/xml>\s*$/, () => `${out}</xml>`);
2837
+ pack.put(vmlPart, rest);
2838
+ return tail;
2839
+ }
2840
+
2841
+ // src/sheets/book.ts
2842
+ function readSheet(bytes, kind) {
2843
+ return kind === "csv" ? readCsv(bytes) : load(bytes).model;
2844
+ }
2845
+ function writeSheet(original, model, kind) {
2846
+ return kind === "csv" ? writeCsv(original, model) : writeXlsx(original, model);
2847
+ }
2848
+
2849
+ // src/sheets/shared.ts
2850
+ import * as Y from "yjs";
2851
+ var props = ["name", "hidden", "tabColor", "freeze", "showGridlines", "rightToLeft"];
2852
+ var spot = (row2, col) => `${row2}:${col}`;
2853
+ var canon = (x) => x === null || typeof x !== "object" ? JSON.stringify(x ?? null) : Array.isArray(x) ? `[${x.map(canon).join(",")}]` : `{${Object.keys(x).filter((k) => x[k] !== void 0).sort().map((k) => `${JSON.stringify(k)}:${canon(x[k])}`).join(",")}}`;
2854
+ var strip = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0 && v !== null));
2855
+ var fnv = (bytes, h = 2166136261) => {
2856
+ for (const b of bytes) h = Math.imul(h ^ b, 16777619) >>> 0;
2857
+ return h;
2858
+ };
2859
+ function parts(doc) {
2860
+ const book = doc.getMap("book");
2861
+ return {
2862
+ book,
2863
+ values: doc.getMap("values"),
2864
+ origin: doc.getMap("origin"),
2865
+ order: book.get("order"),
2866
+ sheets: book.get("sheets"),
2867
+ styles: book.get("styles")
2868
+ };
2869
+ }
2870
+ var pieces = (m) => ({
2871
+ rows: m.get("rows"),
2872
+ cols: m.get("cols"),
2873
+ cells: m.get("cells"),
2874
+ rowData: m.get("rowData"),
2875
+ colData: m.get("colData"),
2876
+ merges: m.get("merges"),
2877
+ notes: m.get("notes")
2878
+ });
2879
+ function made(config, lines2) {
2880
+ const m = new Y.Map();
2881
+ for (const name of props) if (config[name] !== void 0) m.set(name, config[name]);
2882
+ m.set("look", strip({ defaultRowHeight: config.defaultRowHeight, defaultColumnWidth: config.defaultColumnWidth, zoomRatio: config.zoomRatio }));
2883
+ m.set("rows", Y.Array.from(lines2.rows));
2884
+ m.set("cols", Y.Array.from(lines2.cols));
2885
+ for (const name of ["cells", "rowData", "colData", "merges", "notes"]) m.set(name, new Y.Map());
2886
+ return m;
2887
+ }
2888
+ function fill2(doc, model) {
2889
+ const { book: wb, lines: lines2 } = model;
2890
+ const book = doc.getMap("book");
2891
+ const notes2 = JSON.parse(wb.resources?.find((r) => r.name === "SHEET_NOTE_PLUGIN")?.data ?? "{}");
2892
+ doc.transact(() => {
2893
+ book.set("head", strip({ id: wb.id, name: wb.name, appVersion: wb.appVersion, locale: wb.locale, defaultStyle: wb.defaultStyle, dateSystem: wb.dateSystem }));
2894
+ book.set("extras", (wb.resources ?? []).filter((r) => r.name !== "SHEET_NOTE_PLUGIN"));
2895
+ book.set("active", model.active ?? null);
2896
+ book.set("styles", new Y.Map());
2897
+ book.set("order", Y.Array.from(wb.sheetOrder));
2898
+ book.set("sheets", new Y.Map());
2899
+ const { sheets, styles, values, origin } = parts(doc);
2900
+ for (const [id, look] of Object.entries(wb.styles)) if (look) styles.set(id, look);
2901
+ for (const sid of wb.sheetOrder) {
2902
+ const sheet = wb.sheets[sid];
2903
+ const l = lines2[sid];
2904
+ sheets.set(sid, made(sheet, l));
2905
+ origin.set(sid, { id: model.origin.sheets[sid], name: sheet.name ?? "", rows: l.rows.length, cols: l.cols.length });
2906
+ const { cells, rowData, colData, merges, notes: kept } = pieces(sheets.get(sid));
2907
+ for (const [r, line] of Object.entries(sheet.cellData ?? {})) for (const [c, x] of Object.entries(line ?? {})) {
2908
+ if (!x) continue;
2909
+ const at = spot(l.rows[+r], l.cols[+c]);
2910
+ const out = {};
2911
+ if (x.f) {
2912
+ out.f = x.f;
2913
+ values.set(`${sid}:${at}`, { v: x.v ?? null, t: x.t ?? null });
2914
+ } else {
2915
+ if (x.v !== void 0 && x.v !== null) out.v = x.v;
2916
+ if (x.t) out.t = x.t;
2917
+ }
2918
+ if (x.p) out.p = x.p;
2919
+ if (typeof x.s === "string") out.s = x.s;
2920
+ cells.set(at, out);
2921
+ }
2922
+ for (const [r, rd] of Object.entries(sheet.rowData ?? {})) if (rd) rowData.set(l.rows[+r], strip({ h: rd.h, hd: rd.hd, ia: rd.ia, s: typeof rd.s === "string" ? rd.s : void 0 }));
2923
+ for (const [c, cd] of Object.entries(sheet.columnData ?? {})) if (cd) colData.set(l.cols[+c], strip({ w: cd.w, hd: cd.hd, s: typeof cd.s === "string" ? cd.s : void 0 }));
2924
+ for (const b of sheet.mergeData ?? []) merges.set([l.rows[b.startRow], l.cols[b.startColumn], l.rows[b.endRow], l.cols[b.endColumn]].join(":"), 1);
2925
+ for (const [r, line] of Object.entries(notes2[sid] ?? {})) for (const [c, n] of Object.entries(line)) kept.set(spot(l.rows[+r], l.cols[+c]), { note: n.note, width: n.width, height: n.height });
2926
+ }
2927
+ });
2928
+ }
2929
+ function sheetOf(doc, sid, l) {
2930
+ const { sheets, values } = parts(doc);
2931
+ const m = sheets.get(sid);
2932
+ const { cells, rowData, colData, merges } = pieces(m);
2933
+ const rows = new Map(l.rows.map((id, i) => [id, i])), cols = new Map(l.cols.map((id, i) => [id, i]));
2934
+ const cellData = {};
2935
+ for (const [at, x] of cells) {
2936
+ const [row2, col] = at.split(":");
2937
+ const r = rows.get(row2), c = cols.get(col);
2938
+ if (r === void 0 || c === void 0) continue;
2939
+ const kept = x.f ? values.get(`${sid}:${at}`) : void 0;
2940
+ (cellData[r] ?? (cellData[r] = {}))[c] = kept ? { ...x, v: kept.v, t: kept.t } : { ...x };
2941
+ }
2942
+ const rowsOut = {}, colsOut = {};
2943
+ for (const [id, x] of rowData) if (rows.has(id)) rowsOut[rows.get(id)] = { ...x };
2944
+ for (const [id, x] of colData) if (cols.has(id)) colsOut[cols.get(id)] = { ...x };
2945
+ const mergeData = [...merges.keys()].map((k) => k.split(":")).map(([r0, c0, r1, c1]) => ({ startRow: rows.get(r0), startColumn: cols.get(c0), endRow: rows.get(r1), endColumn: cols.get(c1) })).filter((b) => [b.startRow, b.startColumn, b.endRow, b.endColumn].every((n) => n !== void 0));
2946
+ const out = { ...m.get("look"), id: sid, rowCount: l.rows.length, columnCount: l.cols.length, cellData, rowData: rowsOut, columnData: colsOut, mergeData };
2947
+ for (const name of props) if (m.has(name)) Object.assign(out, { [name]: m.get(name) });
2948
+ return out;
2949
+ }
2950
+ var notesOf = (m, l) => {
2951
+ const rows = new Map(l.rows.map((id, i) => [id, i])), cols = new Map(l.cols.map((id, i) => [id, i]));
2952
+ return [...pieces(m).notes].map(([at, n]) => ({ ...n, row: rows.get(at.split(":")[0]), col: cols.get(at.split(":")[1]) })).filter((n) => n.row !== void 0 && n.col !== void 0);
2953
+ };
2954
+ function build(doc) {
2955
+ const { book, order: order2, sheets, styles, origin } = parts(doc);
2956
+ const sheetOrder = [...new Set(order2.toArray())].filter((sid) => sheets.has(sid));
2957
+ const wb = { ...book.get("head"), styles: styles.toJSON(), sheetOrder, sheets: {}, resources: [] };
2958
+ const model = { book: wb, lines: {}, origin: { sheets: {}, lines: {} } };
2959
+ const notes2 = {};
2960
+ for (const sid of sheetOrder) {
2961
+ const { rows, cols } = pieces(sheets.get(sid));
2962
+ const l = { rows: rows.toArray(), cols: cols.toArray() };
2963
+ model.lines[sid] = l;
2964
+ wb.sheets[sid] = sheetOf(doc, sid, l);
2965
+ notesOf(sheets.get(sid), l).forEach((n, i) => {
2966
+ var _a, _b;
2967
+ ((_a = notes2[sid] ?? (notes2[sid] = {}))[_b = n.row] ?? (_a[_b] = {}))[n.col] = { ...n, show: false, id: `n${i}` };
2968
+ });
2969
+ const o = origin.get(sid);
2970
+ if (!o) continue;
2971
+ model.origin.sheets[sid] = o.id;
2972
+ model.origin.lines[sid] = { rows: typeof o.rows === "number" ? numbered("r", o.rows) : o.rows, cols: typeof o.cols === "number" ? numbered("c", o.cols) : o.cols };
2973
+ }
2974
+ wb.resources.push({ name: "SHEET_NOTE_PLUGIN", data: JSON.stringify(notes2) });
2975
+ const active = book.get("active");
2976
+ if (active && sheetOrder.includes(active)) model.active = active;
2977
+ return model;
2978
+ }
2979
+ function extras(doc, model) {
2980
+ const { book, origin } = parts(doc);
2981
+ const own = new Map([...origin.entries()].filter(([sid]) => model.lines[sid]).map(([sid, o]) => {
2982
+ const old = model.origin.lines[sid], now = model.lines[sid];
2983
+ return [`s${o.id}`, { sid, name: o.name, rows: new Axis(old.rows, now.rows), cols: new Axis(old.cols, now.cols) }];
2984
+ }));
2985
+ const fix = (b, sid) => {
2986
+ const a = own.get(sid);
2987
+ return squeeze(b, a.rows.map, a.cols.map);
2988
+ };
2989
+ for (const r of book.get("extras")) {
2990
+ const parsed = JSON.parse(r.data);
2991
+ let out = {};
2992
+ if (r.name === "SHEET_DEFINED_NAME_PLUGIN") out = Object.fromEntries(Object.entries(parsed).map(([id, n]) => {
2993
+ let f = n.formulaOrRefString;
2994
+ for (const a of own.values()) {
2995
+ f = remapped(f, (s) => s === a.name, a.rows.map, a.cols.map);
2996
+ if (a.name !== model.book.sheets[a.sid].name) f = renamed(f, a.name, model.book.sheets[a.sid].name);
2997
+ }
2998
+ return [id, { ...n, formulaOrRefString: f, localSheetId: own.get(n.localSheetId)?.sid ?? n.localSheetId }];
2999
+ }));
3000
+ else for (const [base, x] of Object.entries(parsed)) {
3001
+ const a = own.get(base);
3002
+ if (!a) continue;
3003
+ if (r.name === "SHEET_DATA_VALIDATION_PLUGIN") out[a.sid] = x.map((rule) => ({ ...rule, ranges: rule.ranges.map((b) => fix(b, base)).filter(Boolean) })).filter((rule) => rule.ranges.length);
3004
+ else if (r.name === "SHEET_FILTER_PLUGIN") {
3005
+ const f = x;
3006
+ const ref = fix(f.ref, base);
3007
+ if (ref) out[a.sid] = { ...f, ref: { ...f.ref, ...ref }, cachedFilteredOut: (f.cachedFilteredOut ?? []).map(a.rows.map).filter((n) => n >= 0) };
3008
+ } else out[a.sid] = x;
3009
+ }
3010
+ model.book.resources.push({ name: r.name, data: JSON.stringify(out) });
3011
+ }
3012
+ return model;
3013
+ }
3014
+ function settle(doc, model, bytes, kind) {
3015
+ const { book, origin } = parts(doc);
3016
+ const ids = kind === "csv" ? [] : worksheets(bytes);
3017
+ const saved = readSheet(bytes, kind);
3018
+ const back = /* @__PURE__ */ new Map();
3019
+ model.book.sheetOrder.forEach((sid, i) => {
3020
+ const id = ids[i] ?? i + 1;
3021
+ back.set(`s${id}`, sid);
3022
+ origin.set(sid, { id, name: model.book.sheets[sid].name ?? "", rows: model.lines[sid].rows, cols: model.lines[sid].cols });
3023
+ });
3024
+ for (const sid of [...origin.keys()]) if (!model.lines[sid]) origin.delete(sid);
3025
+ book.set("extras", (saved.book.resources ?? []).filter((r) => r.name !== "SHEET_NOTE_PLUGIN"));
3026
+ }
3027
+ function applyCells(doc, list, origin) {
3028
+ const { order: order2, sheets, values } = parts(doc);
3029
+ let done = 0;
3030
+ doc.transact(() => {
3031
+ for (const x of list) {
3032
+ const sid = order2.toArray().find((id) => sheets.get(id)?.get("name") === x.sheet);
3033
+ const [r, c] = cell(x.ref);
3034
+ if (!sid || r < 0) continue;
3035
+ const { rows, cols, cells } = pieces(sheets.get(sid));
3036
+ if (r >= rows.length || c >= cols.length) continue;
3037
+ const at = spot(rows.get(r), cols.get(c));
3038
+ const next = {};
3039
+ if (x.formula !== void 0) next.f = x.formula.startsWith("=") ? x.formula : `=${x.formula}`;
3040
+ else if (typeof x.value === "boolean") Object.assign(next, { v: x.value ? 1 : 0, t: 3 });
3041
+ else if (x.value !== void 0 && x.value !== null && x.value !== "") Object.assign(next, { v: x.value, t: typeof x.value === "number" ? 2 : 1 });
3042
+ const s = cells.get(at)?.s;
3043
+ if (s) next.s = s;
3044
+ values.delete(`${sid}:${at}`);
3045
+ if (Object.keys(next).length) cells.set(at, next);
3046
+ else cells.delete(at);
3047
+ done++;
3048
+ }
3049
+ }, origin);
3050
+ return done;
3051
+ }
3052
+
3053
+ // src/sheets/text.ts
3054
+ var en = {
3055
+ tools: "Sheet tools",
3056
+ loading: "Opening the sheet",
3057
+ failed: "This sheet could not be opened",
3058
+ retry: "Try again",
3059
+ undo: "Undo",
3060
+ redo: "Redo",
3061
+ bold: "Bold",
3062
+ italic: "Italic",
3063
+ underline: "Underline",
3064
+ strike: "Strike out",
3065
+ textColour: "Text colour",
3066
+ fill: "Fill colour",
3067
+ automatic: "Automatic",
3068
+ noFill: "No fill",
3069
+ borders: "Borders",
3070
+ borderAll: "All borders",
3071
+ borderOuter: "Outer border",
3072
+ borderBottom: "Bottom border",
3073
+ borderNone: "No borders",
3074
+ alignLeft: "Align left",
3075
+ alignCenter: "Centre",
3076
+ alignRight: "Align right",
3077
+ wrap: "Wrap text",
3078
+ merge: "Merge cells",
3079
+ unmerge: "Split cells",
3080
+ format: "Number format",
3081
+ general: "General",
3082
+ number: "Number",
3083
+ percent: "Percent",
3084
+ currency: "Currency",
3085
+ date: "Date",
3086
+ time: "Time",
3087
+ text: "Text",
3088
+ rowAbove: "Row above",
3089
+ rowBelow: "Row below",
3090
+ columnLeft: "Column on the left",
3091
+ columnRight: "Column on the right",
3092
+ deleteRows: "Delete rows",
3093
+ deleteColumns: "Delete columns",
3094
+ freeze: "Freeze",
3095
+ freezeNone: "Unfreeze",
3096
+ freezeRow: "First row",
3097
+ freezeColumn: "First column",
3098
+ freezeHere: "Up to the selected cell",
3099
+ sortUp: "Sort A to Z",
3100
+ sortDown: "Sort Z to A",
3101
+ filter: "Filter",
3102
+ find: "Find and replace",
3103
+ note: "Note",
3104
+ save: "Save",
3105
+ saving: "Saving",
3106
+ saved: "Saved",
3107
+ saveFailed: "Could not save",
3108
+ editedNote: "Sheet edited",
3109
+ viewOnly: "View only",
3110
+ notesOnly: "You can add notes",
3111
+ offline: "Offline",
3112
+ offlineHint: "Your changes stay here and sync when the connection is back",
3113
+ liveOff: "Live editing is unavailable",
3114
+ people: "People in this sheet",
3115
+ you: "you",
3116
+ refused: {
3117
+ chartSource: "A chart on another sheet uses data from \u201C{sheet}\u201D. Bring that sheet back to save.",
3118
+ pivotSheet: "A pivot table reads its data from \u201C{sheet}\u201D. Bring that sheet back to save.",
3119
+ tableColumns: "Columns changed inside a table on \u201C{sheet}\u201D. Undo that change to save."
3120
+ }
3121
+ };
3122
+ var pl = {
3123
+ tools: "Narz\u0119dzia arkusza",
3124
+ loading: "Otwieranie arkusza",
3125
+ failed: "Nie uda\u0142o si\u0119 otworzy\u0107 tego arkusza",
3126
+ retry: "Spr\xF3buj ponownie",
3127
+ undo: "Cofnij",
3128
+ redo: "Pon\xF3w",
3129
+ bold: "Pogrubienie",
3130
+ italic: "Kursywa",
3131
+ underline: "Podkre\u015Blenie",
3132
+ strike: "Przekre\u015Blenie",
3133
+ textColour: "Kolor tekstu",
3134
+ fill: "Kolor wype\u0142nienia",
3135
+ automatic: "Automatyczny",
3136
+ noFill: "Bez wype\u0142nienia",
3137
+ borders: "Obramowanie",
3138
+ borderAll: "Wszystkie kraw\u0119dzie",
3139
+ borderOuter: "Kraw\u0119dzie zewn\u0119trzne",
3140
+ borderBottom: "Dolna kraw\u0119d\u017A",
3141
+ borderNone: "Bez kraw\u0119dzi",
3142
+ alignLeft: "Do lewej",
3143
+ alignCenter: "Wy\u015Brodkuj",
3144
+ alignRight: "Do prawej",
3145
+ wrap: "Zawijaj tekst",
3146
+ merge: "Scal kom\xF3rki",
3147
+ unmerge: "Rozdziel kom\xF3rki",
3148
+ format: "Format liczb",
3149
+ general: "Og\xF3lny",
3150
+ number: "Liczba",
3151
+ percent: "Procent",
3152
+ currency: "Waluta",
3153
+ date: "Data",
3154
+ time: "Godzina",
3155
+ text: "Tekst",
3156
+ rowAbove: "Wiersz powy\u017Cej",
3157
+ rowBelow: "Wiersz poni\u017Cej",
3158
+ columnLeft: "Kolumna po lewej",
3159
+ columnRight: "Kolumna po prawej",
3160
+ deleteRows: "Usu\u0144 wiersze",
3161
+ deleteColumns: "Usu\u0144 kolumny",
3162
+ freeze: "Zablokuj",
3163
+ freezeNone: "Odblokuj",
3164
+ freezeRow: "Pierwszy wiersz",
3165
+ freezeColumn: "Pierwsza kolumna",
3166
+ freezeHere: "Do zaznaczonej kom\xF3rki",
3167
+ sortUp: "Sortuj od A do Z",
3168
+ sortDown: "Sortuj od Z do A",
3169
+ filter: "Filtr",
3170
+ find: "Znajd\u017A i zamie\u0144",
3171
+ note: "Notatka",
3172
+ save: "Zapisz",
3173
+ saving: "Zapisywanie",
3174
+ saved: "Zapisano",
3175
+ saveFailed: "Nie uda\u0142o si\u0119 zapisa\u0107",
3176
+ editedNote: "Edycja arkusza",
3177
+ viewOnly: "Tylko podgl\u0105d",
3178
+ notesOnly: "Mo\u017Cesz dodawa\u0107 notatki",
3179
+ offline: "Offline",
3180
+ offlineHint: "Zmiany zostaj\u0105 tutaj i zsynchronizuj\u0105 si\u0119 po powrocie po\u0142\u0105czenia",
3181
+ liveOff: "Wsp\xF3lna edycja jest niedost\u0119pna",
3182
+ people: "Osoby w tym arkuszu",
3183
+ you: "ty",
3184
+ refused: {
3185
+ chartSource: "Wykres na innym arkuszu korzysta z danych arkusza \u201E{sheet}\u201D. Przywr\xF3\u0107 ten arkusz, aby zapisa\u0107.",
3186
+ pivotSheet: "Tabela przestawna pobiera dane z arkusza \u201E{sheet}\u201D. Przywr\xF3\u0107 ten arkusz, aby zapisa\u0107.",
3187
+ tableColumns: "Kolumny zmieni\u0142y si\u0119 wewn\u0105trz tabeli na arkuszu \u201E{sheet}\u201D. Cofnij t\u0119 zmian\u0119, aby zapisa\u0107."
3188
+ }
3189
+ };
3190
+ var uk = {
3191
+ tools: "\u0406\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u0438 \u0442\u0430\u0431\u043B\u0438\u0446\u0456",
3192
+ loading: "\u0412\u0456\u0434\u043A\u0440\u0438\u0432\u0430\u0454\u043C\u043E \u0442\u0430\u0431\u043B\u0438\u0446\u044E",
3193
+ failed: "\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0432\u0456\u0434\u043A\u0440\u0438\u0442\u0438 \u0446\u044E \u0442\u0430\u0431\u043B\u0438\u0446\u044E",
3194
+ retry: "\u0421\u043F\u0440\u043E\u0431\u0443\u0432\u0430\u0442\u0438 \u0449\u0435",
3195
+ undo: "\u0412\u0456\u0434\u043C\u0456\u043D\u0438\u0442\u0438",
3196
+ redo: "\u041F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0438",
3197
+ bold: "\u0416\u0438\u0440\u043D\u0438\u0439",
3198
+ italic: "\u041A\u0443\u0440\u0441\u0438\u0432",
3199
+ underline: "\u041F\u0456\u0434\u043A\u0440\u0435\u0441\u043B\u0435\u043D\u0438\u0439",
3200
+ strike: "\u0417\u0430\u043A\u0440\u0435\u0441\u043B\u0435\u043D\u0438\u0439",
3201
+ textColour: "\u041A\u043E\u043B\u0456\u0440 \u0442\u0435\u043A\u0441\u0442\u0443",
3202
+ fill: "\u041A\u043E\u043B\u0456\u0440 \u0437\u0430\u043B\u0438\u0432\u043A\u0438",
3203
+ automatic: "\u0410\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u043D\u0438\u0439",
3204
+ noFill: "\u0411\u0435\u0437 \u0437\u0430\u043B\u0438\u0432\u043A\u0438",
3205
+ borders: "\u041C\u0435\u0436\u0456",
3206
+ borderAll: "\u0423\u0441\u0456 \u043C\u0435\u0436\u0456",
3207
+ borderOuter: "\u0417\u043E\u0432\u043D\u0456\u0448\u043D\u0456 \u043C\u0435\u0436\u0456",
3208
+ borderBottom: "\u041D\u0438\u0436\u043D\u044F \u043C\u0435\u0436\u0430",
3209
+ borderNone: "\u0411\u0435\u0437 \u043C\u0435\u0436",
3210
+ alignLeft: "\u041B\u0456\u0432\u043E\u0440\u0443\u0447",
3211
+ alignCenter: "\u041F\u043E \u0446\u0435\u043D\u0442\u0440\u0443",
3212
+ alignRight: "\u041F\u0440\u0430\u0432\u043E\u0440\u0443\u0447",
3213
+ wrap: "\u041F\u0435\u0440\u0435\u043D\u043E\u0441\u0438\u0442\u0438 \u0442\u0435\u043A\u0441\u0442",
3214
+ merge: "\u041E\u0431\u2019\u0454\u0434\u043D\u0430\u0442\u0438 \u043A\u043B\u0456\u0442\u0438\u043D\u043A\u0438",
3215
+ unmerge: "\u0420\u043E\u0437\u2019\u0454\u0434\u043D\u0430\u0442\u0438 \u043A\u043B\u0456\u0442\u0438\u043D\u043A\u0438",
3216
+ format: "\u0424\u043E\u0440\u043C\u0430\u0442 \u0447\u0438\u0441\u0435\u043B",
3217
+ general: "\u0417\u0430\u0433\u0430\u043B\u044C\u043D\u0438\u0439",
3218
+ number: "\u0427\u0438\u0441\u043B\u043E",
3219
+ percent: "\u0412\u0456\u0434\u0441\u043E\u0442\u043E\u043A",
3220
+ currency: "\u0412\u0430\u043B\u044E\u0442\u0430",
3221
+ date: "\u0414\u0430\u0442\u0430",
3222
+ time: "\u0427\u0430\u0441",
3223
+ text: "\u0422\u0435\u043A\u0441\u0442",
3224
+ rowAbove: "\u0420\u044F\u0434\u043E\u043A \u0432\u0438\u0449\u0435",
3225
+ rowBelow: "\u0420\u044F\u0434\u043E\u043A \u043D\u0438\u0436\u0447\u0435",
3226
+ columnLeft: "\u0421\u0442\u043E\u0432\u043F\u0435\u0446\u044C \u043B\u0456\u0432\u043E\u0440\u0443\u0447",
3227
+ columnRight: "\u0421\u0442\u043E\u0432\u043F\u0435\u0446\u044C \u043F\u0440\u0430\u0432\u043E\u0440\u0443\u0447",
3228
+ deleteRows: "\u0412\u0438\u0434\u0430\u043B\u0438\u0442\u0438 \u0440\u044F\u0434\u043A\u0438",
3229
+ deleteColumns: "\u0412\u0438\u0434\u0430\u043B\u0438\u0442\u0438 \u0441\u0442\u043E\u0432\u043F\u0446\u0456",
3230
+ freeze: "\u0417\u0430\u043A\u0440\u0456\u043F\u0438\u0442\u0438",
3231
+ freezeNone: "\u0412\u0456\u0434\u043A\u0440\u0456\u043F\u0438\u0442\u0438",
3232
+ freezeRow: "\u041F\u0435\u0440\u0448\u0438\u0439 \u0440\u044F\u0434\u043E\u043A",
3233
+ freezeColumn: "\u041F\u0435\u0440\u0448\u0438\u0439 \u0441\u0442\u043E\u0432\u043F\u0435\u0446\u044C",
3234
+ freezeHere: "\u0414\u043E \u0432\u0438\u0434\u0456\u043B\u0435\u043D\u043E\u0457 \u043A\u043B\u0456\u0442\u0438\u043D\u043A\u0438",
3235
+ sortUp: "\u0421\u043E\u0440\u0442\u0443\u0432\u0430\u0442\u0438 \u0432\u0456\u0434 \u0410 \u0434\u043E \u042F",
3236
+ sortDown: "\u0421\u043E\u0440\u0442\u0443\u0432\u0430\u0442\u0438 \u0432\u0456\u0434 \u042F \u0434\u043E \u0410",
3237
+ filter: "\u0424\u0456\u043B\u044C\u0442\u0440",
3238
+ find: "\u0417\u043D\u0430\u0439\u0442\u0438 \u0439 \u0437\u0430\u043C\u0456\u043D\u0438\u0442\u0438",
3239
+ note: "\u041F\u0440\u0438\u043C\u0456\u0442\u043A\u0430",
3240
+ save: "\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438",
3241
+ saving: "\u0417\u0431\u0435\u0440\u0435\u0436\u0435\u043D\u043D\u044F",
3242
+ saved: "\u0417\u0431\u0435\u0440\u0435\u0436\u0435\u043D\u043E",
3243
+ saveFailed: "\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0437\u0431\u0435\u0440\u0435\u0433\u0442\u0438",
3244
+ editedNote: "\u041F\u0440\u0430\u0432\u043A\u0430 \u0442\u0430\u0431\u043B\u0438\u0446\u0456",
3245
+ viewOnly: "\u041B\u0438\u0448\u0435 \u043F\u0435\u0440\u0435\u0433\u043B\u044F\u0434",
3246
+ notesOnly: "\u041C\u043E\u0436\u043D\u0430 \u0434\u043E\u0434\u0430\u0432\u0430\u0442\u0438 \u043F\u0440\u0438\u043C\u0456\u0442\u043A\u0438",
3247
+ offline: "\u041E\u0444\u043B\u0430\u0439\u043D",
3248
+ offlineHint: "\u0417\u043C\u0456\u043D\u0438 \u043B\u0438\u0448\u0430\u044E\u0442\u044C\u0441\u044F \u0442\u0443\u0442 \u0456 \u0441\u0438\u043D\u0445\u0440\u043E\u043D\u0456\u0437\u0443\u044E\u0442\u044C\u0441\u044F, \u043A\u043E\u043B\u0438 \u0437\u2019\u044F\u0432\u0438\u0442\u044C\u0441\u044F \u0437\u0432\u2019\u044F\u0437\u043E\u043A",
3249
+ liveOff: "\u0421\u043F\u0456\u043B\u044C\u043D\u0435 \u0440\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u043D\u043D\u044F \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0435",
3250
+ people: "\u041B\u044E\u0434\u0438 \u0432 \u0446\u0456\u0439 \u0442\u0430\u0431\u043B\u0438\u0446\u0456",
3251
+ you: "\u0432\u0438",
3252
+ refused: {
3253
+ chartSource: "\u0414\u0456\u0430\u0433\u0440\u0430\u043C\u0430 \u043D\u0430 \u0456\u043D\u0448\u043E\u043C\u0443 \u0430\u0440\u043A\u0443\u0448\u0456 \u0431\u0435\u0440\u0435 \u0434\u0430\u043D\u0456 \u0437 \u0430\u0440\u043A\u0443\u0448\u0430 \xAB{sheet}\xBB. \u041F\u043E\u0432\u0435\u0440\u043D\u0456\u0442\u044C \u0446\u0435\u0439 \u0430\u0440\u043A\u0443\u0448, \u0449\u043E\u0431 \u0437\u0431\u0435\u0440\u0435\u0433\u0442\u0438.",
3254
+ pivotSheet: "\u0417\u0432\u0435\u0434\u0435\u043D\u0430 \u0442\u0430\u0431\u043B\u0438\u0446\u044F \u0431\u0435\u0440\u0435 \u0434\u0430\u043D\u0456 \u0437 \u0430\u0440\u043A\u0443\u0448\u0430 \xAB{sheet}\xBB. \u041F\u043E\u0432\u0435\u0440\u043D\u0456\u0442\u044C \u0446\u0435\u0439 \u0430\u0440\u043A\u0443\u0448, \u0449\u043E\u0431 \u0437\u0431\u0435\u0440\u0435\u0433\u0442\u0438.",
3255
+ tableColumns: "\u0421\u0442\u043E\u0432\u043F\u0446\u0456 \u0437\u043C\u0456\u043D\u0438\u043B\u0438\u0441\u044F \u0432\u0441\u0435\u0440\u0435\u0434\u0438\u043D\u0456 \u0442\u0430\u0431\u043B\u0438\u0446\u0456 \u043D\u0430 \u0430\u0440\u043A\u0443\u0448\u0456 \xAB{sheet}\xBB. \u0412\u0456\u0434\u043C\u0456\u043D\u0456\u0442\u044C \u0446\u044E \u0437\u043C\u0456\u043D\u0443, \u0449\u043E\u0431 \u0437\u0431\u0435\u0440\u0435\u0433\u0442\u0438."
3256
+ }
3257
+ };
3258
+ var sheetTexts = { en, pl, uk };
3259
+
3260
+ // src/collab.ts
3261
+ var ours = "w100n-collab";
3262
+ var schemas = /* @__PURE__ */ new Map();
3263
+ var schemaOf = (kind) => schemas.get(kind) ?? schemas.set(kind, getSchema(kit(kind, texts.en))).get(kind);
3264
+ var parse2 = async (kind, bytes) => kind === "docx" ? (await readDocx(bytes)).doc : fromMarkdown(new TextDecoder().decode(bytes)).doc;
3265
+ var edits = (tr) => tr.changedParentTypes.has(tr.doc.get("default")) || tr.changedParentTypes.has(tr.doc.get("book"));
3266
+ var filled = (doc) => doc.getXmlFragment("default").length > 0 || doc.getMap("book").size > 0;
3267
+ function seed(doc, kind, bytes, json) {
3268
+ if (filled(doc)) return false;
3269
+ const fixed = new Y2.Doc();
3270
+ fixed.clientID = fnv(new Uint8Array(bytes), fnv(new TextEncoder().encode(`${version}:${kind}`)));
3271
+ if (kind === "xlsx" || kind === "csv") fill2(fixed, readSheet(bytes, kind));
3272
+ else prosemirrorJSONToYXmlFragment(schemaOf(kind), json, fixed.getXmlFragment("default"));
3273
+ Y2.applyUpdate(doc, Y2.encodeStateAsUpdate(fixed), ours);
3274
+ return true;
3275
+ }
3276
+ function follow(doc, author) {
3277
+ const editors = doc.getMap("editors");
3278
+ const before = (tr) => tr.meta.set("fresh", !filled(doc));
3279
+ const after = (tr) => {
3280
+ const who = !tr.meta.get("fresh") && edits(tr) ? author(tr.origin) : null;
3281
+ if (who && !editors.has(who.id)) doc.transact(() => editors.set(who.id, who), ours);
3282
+ };
3283
+ doc.on("beforeTransaction", before);
3284
+ doc.on("afterTransaction", after);
3285
+ return () => {
3286
+ doc.off("beforeTransaction", before);
3287
+ doc.off("afterTransaction", after);
3288
+ };
3289
+ }
3290
+ var pending = (doc) => doc.getMap("editors").size > 0;
3291
+ var Refusal = class extends Error {
3292
+ };
3293
+ function applyText(doc, kind, changes2, origin) {
3294
+ const schema = schemaOf(kind);
3295
+ const fragment = doc.getXmlFragment("default");
3296
+ const step = new Transform(yXmlFragmentToProseMirrorRootNode(fragment, schema));
3297
+ for (const c of changes2) {
3298
+ const hits = [];
3299
+ step.doc.descendants((node, pos) => {
3300
+ if (!node.isTextblock) return true;
3301
+ const text = node.textBetween(0, node.content.size, void 0, "\uFFFC");
3302
+ for (let i = text.indexOf(c.find); c.find && i >= 0; i = text.indexOf(c.find, i + 1)) hits.push(pos + 1 + i);
3303
+ return false;
3304
+ });
3305
+ if (hits.length !== 1) throw new Refusal(`${hits.length ? "more than once" : "not"} in the document: ${c.find.slice(0, 80)}`);
3306
+ const [at] = hits;
3307
+ if (c.replace) step.replaceWith(at, at + c.find.length, schema.text(c.replace, step.doc.resolve(at + 1).marks()));
3308
+ else step.delete(at, at + c.find.length);
3309
+ }
3310
+ updateYFragment({ transact: (run) => doc.transact(run, origin) }, fragment, step.doc, { mapping: /* @__PURE__ */ new Map(), isOMark: /* @__PURE__ */ new Map() });
3311
+ return changes2.length;
3312
+ }
3313
+ async function write(kind, base, node, load2) {
3314
+ if (kind === "docx") return writeDocx(base, node.toJSON(), load2);
3315
+ const parsed = fromMarkdown(new TextDecoder().decode(base));
3316
+ return new TextEncoder().encode(toMarkdown(node, track(parsed, node.type.schema.nodeFromJSON(parsed.doc))).text).buffer;
3317
+ }
3318
+ var blocks2 = (fragment, schema) => {
3319
+ const out = [];
3320
+ const walk = (parent) => parent.toArray().forEach((child) => {
3321
+ if (!(child instanceof Y2.XmlElement) || !schema.nodes[child.nodeName]?.isBlock) return;
3322
+ out.push(child);
3323
+ walk(child);
3324
+ });
3325
+ walk(fragment);
3326
+ return out;
3327
+ };
3328
+ var same2 = (a, b) => {
3329
+ const [x, y] = [new Uint8Array(a), new Uint8Array(b)];
3330
+ return x.length === y.length && x.every((v, i) => v === y[i]);
3331
+ };
3332
+ var named = (label, who) => {
3333
+ const names = who.map((w) => w.name).join(", ");
3334
+ return `${label}: ${names.length > 180 ? `${names.slice(0, 177)}...` : names}`;
3335
+ };
3336
+ async function save(doc, kind, base, put, load2, note) {
3337
+ const editors = doc.getMap("editors");
3338
+ const who = [...editors.values()];
3339
+ if (!who.length) return null;
3340
+ if (kind === "xlsx" || kind === "csv") return workbook(doc, kind, base, put, who, note);
3341
+ const schema = schemaOf(kind);
3342
+ const fragment = doc.getXmlFragment("default");
3343
+ const list = blocks2(fragment, schema);
3344
+ const node = yXmlFragmentToProseMirrorRootNode(fragment, schema);
3345
+ let touched = false;
3346
+ const watch = (tr) => {
3347
+ touched || (touched = tr.origin !== ours && edits(tr));
3348
+ };
3349
+ doc.on("afterTransaction", watch);
3350
+ try {
3351
+ const bytes = await write(kind, base, node, load2);
3352
+ const changed2 = !same2(bytes, base);
3353
+ const id = changed2 ? await put(bytes, note ?? named((texts[who[0].language] ?? texts.en).editedNote, who)) : null;
3354
+ const refs = [];
3355
+ if (changed2) schema.nodeFromJSON(await parse2(kind, bytes)).descendants((n) => {
3356
+ if (n.isBlock) refs.push([n.type.name, n.attrs.ref ?? null]);
3357
+ });
3358
+ doc.transact(() => {
3359
+ if (refs.length === list.length && list.every((el, i) => el.nodeName === refs[i][0])) list.forEach((el, i) => {
3360
+ const ref = refs[i][1];
3361
+ if ((el.getAttribute("ref") ?? null) === ref) return;
3362
+ if (ref === null) el.removeAttribute("ref");
3363
+ else el.setAttribute("ref", ref);
3364
+ });
3365
+ if (id) doc.getMap("meta").set("version", id);
3366
+ if (!touched) who.forEach((w) => editors.delete(w.id));
3367
+ }, ours);
3368
+ return { bytes: changed2 ? bytes : base, version: id };
3369
+ } finally {
3370
+ doc.off("afterTransaction", watch);
3371
+ }
3372
+ }
3373
+ async function workbook(doc, kind, base, put, who, note) {
3374
+ const editors = doc.getMap("editors");
3375
+ const model = build(doc);
3376
+ let touched = false;
3377
+ const watch = (tr) => {
3378
+ touched || (touched = tr.origin !== ours && edits(tr));
3379
+ };
3380
+ doc.on("afterTransaction", watch);
3381
+ try {
3382
+ const bytes = writeSheet(base, model, kind);
3383
+ const changed2 = !same2(bytes, base);
3384
+ const id = changed2 ? await put(bytes, note ?? named((sheetTexts[who[0].language] ?? sheetTexts.en).editedNote, who)) : null;
3385
+ doc.transact(() => {
3386
+ if (changed2) settle(doc, model, bytes, kind);
3387
+ if (id) doc.getMap("meta").set("version", id);
3388
+ if (!touched) who.forEach((w) => editors.delete(w.id));
3389
+ }, ours);
3390
+ return { bytes: changed2 ? bytes : base, version: id };
3391
+ } finally {
3392
+ doc.off("afterTransaction", watch);
3393
+ }
3394
+ }
3395
+
3396
+ export {
3397
+ a4,
3398
+ letter,
3399
+ paging,
3400
+ notes,
3401
+ entries,
3402
+ changes,
3403
+ decide,
3404
+ suggesting,
3405
+ kit,
3406
+ align,
3407
+ indent,
3408
+ clear,
3409
+ locate,
3410
+ fromMarkdown,
3411
+ track,
3412
+ toMarkdown,
3413
+ SheetRefusal,
3414
+ fresh,
3415
+ insert,
3416
+ move,
3417
+ resize,
3418
+ rebase,
3419
+ worksheets,
3420
+ readSheet,
3421
+ writeSheet,
3422
+ props,
3423
+ spot,
3424
+ canon,
3425
+ strip,
3426
+ fnv,
3427
+ parts,
3428
+ pieces,
3429
+ made,
3430
+ sheetOf,
3431
+ notesOf,
3432
+ build,
3433
+ extras,
3434
+ applyCells,
3435
+ sheetTexts,
3436
+ ours,
3437
+ parse2 as parse,
3438
+ edits,
3439
+ filled,
3440
+ seed,
3441
+ follow,
3442
+ pending,
3443
+ Refusal,
3444
+ applyText,
3445
+ save
3446
+ };
3447
+ //# sourceMappingURL=chunk-CE3AADY6.js.map