@w100n/documents 0.13.0 → 0.14.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 (52) hide show
  1. package/dist/{SheetView-3XTEV2VT.css → SheetView-43MPR64N.css} +5 -4
  2. package/dist/{SheetView-3XTEV2VT.css.map → SheetView-43MPR64N.css.map} +1 -1
  3. package/dist/{SheetView-3UAFXGZS.js → SheetView-4TPL7DES.js} +51 -10
  4. package/dist/SheetView-4TPL7DES.js.map +1 -0
  5. package/dist/{TextEditor-OLBLWC6F.js → TextEditor-VBHWUOZR.js} +636 -225
  6. package/dist/TextEditor-VBHWUOZR.js.map +1 -0
  7. package/dist/{chunk-L765DZPO.js → chunk-2CA3HQTI.js} +3 -3
  8. package/dist/{chunk-L765DZPO.js.map → chunk-2CA3HQTI.js.map} +1 -1
  9. package/dist/{chunk-MRP3EURG.js → chunk-5MH4WDW4.js} +133 -20
  10. package/dist/chunk-5MH4WDW4.js.map +1 -0
  11. package/dist/{chunk-WR3MT7KP.js → chunk-DR3TTJWZ.js} +374 -29
  12. package/dist/chunk-DR3TTJWZ.js.map +1 -0
  13. package/dist/{chunk-T7XCGDE5.js → chunk-RCQODE2Z.js} +2 -2
  14. package/dist/collab.cjs +487 -46
  15. package/dist/collab.cjs.map +1 -1
  16. package/dist/collab.d.cts +2 -2
  17. package/dist/collab.d.ts +2 -2
  18. package/dist/collab.js +2 -2
  19. package/dist/{grid-EI5JNZAA.js → grid-Q4XBPQFY.js} +3 -3
  20. package/dist/grid-Q4XBPQFY.js.map +1 -0
  21. package/dist/index.cjs +1449 -314
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.css +888 -171
  24. package/dist/index.css.map +1 -1
  25. package/dist/index.d.cts +9 -4
  26. package/dist/index.d.ts +9 -4
  27. package/dist/index.js +282 -32
  28. package/dist/index.js.map +1 -1
  29. package/dist/kinds.cjs +2 -2
  30. package/dist/kinds.cjs.map +1 -1
  31. package/dist/kinds.d.cts +2 -2
  32. package/dist/kinds.d.ts +2 -2
  33. package/dist/kinds.js +1 -1
  34. package/dist/memory.cjs +3 -0
  35. package/dist/memory.cjs.map +1 -1
  36. package/dist/memory.d.cts +1 -1
  37. package/dist/memory.d.ts +1 -1
  38. package/dist/memory.js +4 -1
  39. package/dist/memory.js.map +1 -1
  40. package/dist/{types-Er60M5kL.d.ts → types-BTsVooZw.d.cts} +2 -1
  41. package/dist/{types-Er60M5kL.d.cts → types-BTsVooZw.d.ts} +2 -1
  42. package/dist/write-BCI8yool.d.cts +16 -0
  43. package/dist/write-BCI8yool.d.ts +16 -0
  44. package/package.json +1 -1
  45. package/dist/SheetView-3UAFXGZS.js.map +0 -1
  46. package/dist/TextEditor-OLBLWC6F.js.map +0 -1
  47. package/dist/chunk-MRP3EURG.js.map +0 -1
  48. package/dist/chunk-WR3MT7KP.js.map +0 -1
  49. package/dist/grid-EI5JNZAA.js.map +0 -1
  50. package/dist/write-DaVtTJCS.d.cts +0 -6
  51. package/dist/write-DaVtTJCS.d.ts +0 -6
  52. /package/dist/{chunk-T7XCGDE5.js.map → chunk-RCQODE2Z.js.map} +0 -0
package/dist/index.cjs CHANGED
@@ -81,6 +81,10 @@ var init_text = __esm({
81
81
  versions: "Versions",
82
82
  details: "Details",
83
83
  noOutline: "This document has no headings",
84
+ findHeading: "Find a heading",
85
+ read: "read",
86
+ showSections: "Show sections",
87
+ hideSections: "Hide sections",
84
88
  current: "Current",
85
89
  size: "Size",
86
90
  updated: "Updated",
@@ -128,6 +132,12 @@ var init_text = __esm({
128
132
  save: "Save",
129
133
  saving: "Saving",
130
134
  saved: "Saved",
135
+ align: "Align",
136
+ moreTools: "More tools",
137
+ fewerTools: "Fewer tools",
138
+ typeFilter: "Type",
139
+ selectAll: "Select all",
140
+ clearPick: "Clear",
131
141
  saveFailed: "Could not save",
132
142
  remove: "Remove",
133
143
  notePlaceholder: "Write a note",
@@ -237,6 +247,11 @@ var init_text = __esm({
237
247
  someone: "Someone",
238
248
  copyAs: "Make an XLSX copy",
239
249
  copyFailed: "Could not make the copy",
250
+ downloadAs: "Download as",
251
+ makeCopy: "Make a copy",
252
+ copyOf: "Copy of",
253
+ rename: "Rename",
254
+ renameFailed: "Could not rename",
240
255
  editComment: "Edit",
241
256
  delete: "Delete",
242
257
  deleteAsk: "Delete this comment?",
@@ -322,7 +337,52 @@ var init_text = __esm({
322
337
  untitled: "Untitled",
323
338
  kindHints: { docx: "Word, DOCX", markdown: "MD, same editor", sheet: "Excel, XLSX", slides: "HTML slides" },
324
339
  newKinds: { docx: "Document", markdown: "Markdown", sheet: "Spreadsheet", slides: "Presentation" },
325
- templates: { blank: "Blank", letter: "Letter", contract: "Contract", notes: "Meeting notes", invoice: "Invoice", report: "Report" }
340
+ templates: { blank: "Blank", letter: "Letter", contract: "Contract", notes: "Meeting notes", invoice: "Invoice", report: "Report" },
341
+ menuFile: "File",
342
+ menuEdit: "Edit",
343
+ menuFormat: "Format",
344
+ menuTools: "Tools",
345
+ zoom: "Zoom",
346
+ font: "Font",
347
+ fontSize: "Font size",
348
+ defaultFont: "Default",
349
+ lineSpacing: "Line and paragraph spacing",
350
+ single: "Single",
351
+ double: "Double",
352
+ spaceAfter: "Add space after paragraph",
353
+ noSpaceAfter: "Remove space after paragraph",
354
+ superscript: "Superscript",
355
+ subscript: "Subscript",
356
+ painter: "Paint format",
357
+ painterHint: "Select text to paint, double click keeps it on, Esc stops",
358
+ pageSetup: "Page setup",
359
+ orientation: "Orientation",
360
+ portrait: "Portrait",
361
+ landscape: "Landscape",
362
+ marginsCm: "Margins, cm",
363
+ mTop: "Top",
364
+ mRight: "Right",
365
+ mBottom: "Bottom",
366
+ mLeft: "Left",
367
+ headerText: "Header",
368
+ footerText: "Footer",
369
+ pageNumbers: "Page numbers in the footer",
370
+ wrapInline: "In line with text",
371
+ wrapLeft: "Text wraps on the right",
372
+ wrapRight: "Text wraps on the left",
373
+ cellFill: "Cell fill",
374
+ tableBorders: "Table borders",
375
+ findReplace: "Find and replace",
376
+ replaceWith: "Replace with",
377
+ replaceOne: "Replace",
378
+ replaceAll: "Replace all",
379
+ matchCase: "Match case",
380
+ words: "Words",
381
+ print: "Print",
382
+ autosavedNote: "Autosaved",
383
+ uploadFile: "Upload a file",
384
+ uploading: "Uploading",
385
+ uploadFailed: "Could not upload the file"
326
386
  };
327
387
  pl2 = {
328
388
  documents: "Dokumenty",
@@ -339,6 +399,10 @@ var init_text = __esm({
339
399
  versions: "Wersje",
340
400
  details: "Szczeg\xF3\u0142y",
341
401
  noOutline: "Ten dokument nie ma nag\u0142\xF3wk\xF3w",
402
+ findHeading: "Znajd\u017A nag\u0142\xF3wek",
403
+ read: "przeczytano",
404
+ showSections: "Poka\u017C sekcje",
405
+ hideSections: "Ukryj sekcje",
342
406
  current: "Bie\u017C\u0105ca",
343
407
  size: "Rozmiar",
344
408
  updated: "Zmieniono",
@@ -386,6 +450,12 @@ var init_text = __esm({
386
450
  save: "Zapisz",
387
451
  saving: "Zapisywanie",
388
452
  saved: "Zapisano",
453
+ align: "Wyr\xF3wnanie",
454
+ moreTools: "Wi\u0119cej narz\u0119dzi",
455
+ fewerTools: "Mniej narz\u0119dzi",
456
+ typeFilter: "Typ",
457
+ selectAll: "Zaznacz wszystkie",
458
+ clearPick: "Wyczy\u015B\u0107",
389
459
  saveFailed: "Nie uda\u0142o si\u0119 zapisa\u0107",
390
460
  remove: "Usu\u0144",
391
461
  notePlaceholder: "Napisz notatk\u0119",
@@ -494,6 +564,11 @@ var init_text = __esm({
494
564
  removed: "Usuni\u0119to",
495
565
  someone: "Kto\u015B",
496
566
  copyAs: "Zr\xF3b kopi\u0119 XLSX",
567
+ downloadAs: "Pobierz jako",
568
+ makeCopy: "Utw\xF3rz kopi\u0119",
569
+ copyOf: "Kopia",
570
+ rename: "Zmie\u0144 nazw\u0119",
571
+ renameFailed: "Nie uda\u0142o si\u0119 zmieni\u0107 nazwy",
497
572
  copyFailed: "Nie uda\u0142o si\u0119 zrobi\u0107 kopii",
498
573
  editComment: "Edytuj",
499
574
  delete: "Usu\u0144",
@@ -580,7 +655,52 @@ var init_text = __esm({
580
655
  untitled: "Bez tytu\u0142u",
581
656
  kindHints: { docx: "Word, DOCX", markdown: "MD, ten sam edytor", sheet: "Excel, XLSX", slides: "Slajdy HTML" },
582
657
  newKinds: { docx: "Dokument", markdown: "Markdown", sheet: "Arkusz", slides: "Prezentacja" },
583
- templates: { blank: "Pusty", letter: "List", contract: "Umowa", notes: "Notatki ze spotkania", invoice: "Faktura", report: "Raport" }
658
+ templates: { blank: "Pusty", letter: "List", contract: "Umowa", notes: "Notatki ze spotkania", invoice: "Faktura", report: "Raport" },
659
+ menuFile: "Plik",
660
+ menuEdit: "Edycja",
661
+ menuFormat: "Format",
662
+ menuTools: "Narz\u0119dzia",
663
+ zoom: "Powi\u0119kszenie",
664
+ font: "Czcionka",
665
+ fontSize: "Rozmiar czcionki",
666
+ defaultFont: "Domy\u015Blna",
667
+ lineSpacing: "Interlinia i odst\u0119py",
668
+ single: "Pojedyncza",
669
+ double: "Podw\xF3jna",
670
+ spaceAfter: "Dodaj odst\u0119p po akapicie",
671
+ noSpaceAfter: "Usu\u0144 odst\u0119p po akapicie",
672
+ superscript: "Indeks g\xF3rny",
673
+ subscript: "Indeks dolny",
674
+ painter: "Malarz format\xF3w",
675
+ painterHint: "Zaznacz tekst, dwuklik zostawia w\u0142\u0105czone, Esc ko\u0144czy",
676
+ pageSetup: "Ustawienia strony",
677
+ orientation: "Orientacja",
678
+ portrait: "Pionowa",
679
+ landscape: "Pozioma",
680
+ marginsCm: "Marginesy, cm",
681
+ mTop: "G\xF3rny",
682
+ mRight: "Prawy",
683
+ mBottom: "Dolny",
684
+ mLeft: "Lewy",
685
+ headerText: "Nag\u0142\xF3wek",
686
+ footerText: "Stopka",
687
+ pageNumbers: "Numery stron w stopce",
688
+ wrapInline: "W linii z tekstem",
689
+ wrapLeft: "Tekst op\u0142ywa z prawej",
690
+ wrapRight: "Tekst op\u0142ywa z lewej",
691
+ cellFill: "Wype\u0142nienie kom\xF3rki",
692
+ tableBorders: "Obramowanie tabeli",
693
+ findReplace: "Znajd\u017A i zamie\u0144",
694
+ replaceWith: "Zamie\u0144 na",
695
+ replaceOne: "Zamie\u0144",
696
+ replaceAll: "Zamie\u0144 wszystko",
697
+ matchCase: "Uwzgl\u0119dnij wielko\u015B\u0107 liter",
698
+ words: "S\u0142owa",
699
+ print: "Drukuj",
700
+ autosavedNote: "Zapisano automatycznie",
701
+ uploadFile: "Wgraj plik",
702
+ uploading: "Wysy\u0142anie",
703
+ uploadFailed: "Nie uda\u0142o si\u0119 wgra\u0107 pliku"
584
704
  };
585
705
  uk2 = {
586
706
  documents: "\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0438",
@@ -597,6 +717,10 @@ var init_text = __esm({
597
717
  versions: "\u0412\u0435\u0440\u0441\u0456\u0457",
598
718
  details: "\u0414\u0435\u0442\u0430\u043B\u0456",
599
719
  noOutline: "\u0423 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0456 \u043D\u0435\u043C\u0430\u0454 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0456\u0432",
720
+ findHeading: "\u0417\u043D\u0430\u0439\u0442\u0438 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A",
721
+ read: "\u043F\u0440\u043E\u0447\u0438\u0442\u0430\u043D\u043E",
722
+ showSections: "\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u0438 \u0440\u043E\u0437\u0434\u0456\u043B\u0438",
723
+ hideSections: "\u0421\u0445\u043E\u0432\u0430\u0442\u0438 \u0440\u043E\u0437\u0434\u0456\u043B\u0438",
600
724
  current: "\u041F\u043E\u0442\u043E\u0447\u043D\u0430",
601
725
  size: "\u0420\u043E\u0437\u043C\u0456\u0440",
602
726
  updated: "\u0417\u043C\u0456\u043D\u0435\u043D\u043E",
@@ -644,6 +768,12 @@ var init_text = __esm({
644
768
  save: "\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438",
645
769
  saving: "\u0417\u0431\u0435\u0440\u0435\u0436\u0435\u043D\u043D\u044F",
646
770
  saved: "\u0417\u0431\u0435\u0440\u0435\u0436\u0435\u043D\u043E",
771
+ align: "\u0412\u0438\u0440\u0456\u0432\u043D\u044E\u0432\u0430\u043D\u043D\u044F",
772
+ moreTools: "\u0411\u0456\u043B\u044C\u0448\u0435 \u0456\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u0456\u0432",
773
+ fewerTools: "\u041C\u0435\u043D\u0448\u0435 \u0456\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u0456\u0432",
774
+ typeFilter: "\u0422\u0438\u043F",
775
+ selectAll: "\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0432\u0441\u0456",
776
+ clearPick: "\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u0438",
647
777
  saveFailed: "\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0437\u0431\u0435\u0440\u0435\u0433\u0442\u0438",
648
778
  remove: "\u0412\u0438\u0434\u0430\u043B\u0438\u0442\u0438",
649
779
  notePlaceholder: "\u041D\u0430\u043F\u0438\u0448\u0456\u0442\u044C \u043D\u043E\u0442\u0430\u0442\u043A\u0443",
@@ -752,6 +882,11 @@ var init_text = __esm({
752
882
  removed: "\u0412\u0438\u0434\u0430\u043B\u0435\u043D\u043E",
753
883
  someone: "\u0425\u0442\u043E\u0441\u044C",
754
884
  copyAs: "\u0417\u0440\u043E\u0431\u0438\u0442\u0438 \u043A\u043E\u043F\u0456\u044E XLSX",
885
+ downloadAs: "\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u044F\u043A",
886
+ makeCopy: "\u0417\u0440\u043E\u0431\u0438\u0442\u0438 \u043A\u043E\u043F\u0456\u044E",
887
+ copyOf: "\u041A\u043E\u043F\u0456\u044F",
888
+ rename: "\u041F\u0435\u0440\u0435\u0439\u043C\u0435\u043D\u0443\u0432\u0430\u0442\u0438",
889
+ renameFailed: "\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u043F\u0435\u0440\u0435\u0439\u043C\u0435\u043D\u0443\u0432\u0430\u0442\u0438",
755
890
  copyFailed: "\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0437\u0440\u043E\u0431\u0438\u0442\u0438 \u043A\u043E\u043F\u0456\u044E",
756
891
  editComment: "\u0417\u043C\u0456\u043D\u0438\u0442\u0438",
757
892
  delete: "\u0412\u0438\u0434\u0430\u043B\u0438\u0442\u0438",
@@ -838,7 +973,52 @@ var init_text = __esm({
838
973
  untitled: "\u0411\u0435\u0437 \u043D\u0430\u0437\u0432\u0438",
839
974
  kindHints: { docx: "Word, DOCX", markdown: "MD, \u0442\u043E\u0439 \u0441\u0430\u043C\u0438\u0439 \u0440\u0435\u0434\u0430\u043A\u0442\u043E\u0440", sheet: "Excel, XLSX", slides: "HTML-\u0441\u043B\u0430\u0439\u0434\u0438" },
840
975
  newKinds: { docx: "\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442", markdown: "Markdown", sheet: "\u0422\u0430\u0431\u043B\u0438\u0446\u044F", slides: "\u041F\u0440\u0435\u0437\u0435\u043D\u0442\u0430\u0446\u0456\u044F" },
841
- templates: { blank: "\u041F\u043E\u0440\u043E\u0436\u043D\u0456\u0439", letter: "\u041B\u0438\u0441\u0442", contract: "\u0414\u043E\u0433\u043E\u0432\u0456\u0440", notes: "\u041D\u043E\u0442\u0430\u0442\u043A\u0438 \u0437\u0443\u0441\u0442\u0440\u0456\u0447\u0456", invoice: "\u0420\u0430\u0445\u0443\u043D\u043E\u043A", report: "\u0417\u0432\u0456\u0442" }
976
+ templates: { blank: "\u041F\u043E\u0440\u043E\u0436\u043D\u0456\u0439", letter: "\u041B\u0438\u0441\u0442", contract: "\u0414\u043E\u0433\u043E\u0432\u0456\u0440", notes: "\u041D\u043E\u0442\u0430\u0442\u043A\u0438 \u0437\u0443\u0441\u0442\u0440\u0456\u0447\u0456", invoice: "\u0420\u0430\u0445\u0443\u043D\u043E\u043A", report: "\u0417\u0432\u0456\u0442" },
977
+ menuFile: "\u0424\u0430\u0439\u043B",
978
+ menuEdit: "\u041F\u0440\u0430\u0432\u043A\u0430",
979
+ menuFormat: "\u0424\u043E\u0440\u043C\u0430\u0442",
980
+ menuTools: "\u0406\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u0438",
981
+ zoom: "\u041C\u0430\u0441\u0448\u0442\u0430\u0431",
982
+ font: "\u0428\u0440\u0438\u0444\u0442",
983
+ fontSize: "\u0420\u043E\u0437\u043C\u0456\u0440 \u0448\u0440\u0438\u0444\u0442\u0443",
984
+ defaultFont: "\u0422\u0438\u043F\u043E\u0432\u0438\u0439",
985
+ lineSpacing: "\u041C\u0456\u0436\u0440\u044F\u0434\u043A\u043E\u0432\u0438\u0439 \u0456\u043D\u0442\u0435\u0440\u0432\u0430\u043B \u0456 \u0432\u0456\u0434\u0441\u0442\u0443\u043F\u0438",
986
+ single: "\u041E\u0434\u0438\u043D\u0430\u0440\u043D\u0438\u0439",
987
+ double: "\u041F\u043E\u0434\u0432\u0456\u0439\u043D\u0438\u0439",
988
+ spaceAfter: "\u0414\u043E\u0434\u0430\u0442\u0438 \u0432\u0456\u0434\u0441\u0442\u0443\u043F \u043F\u0456\u0441\u043B\u044F \u0430\u0431\u0437\u0430\u0446\u0443",
989
+ noSpaceAfter: "\u041F\u0440\u0438\u0431\u0440\u0430\u0442\u0438 \u0432\u0456\u0434\u0441\u0442\u0443\u043F \u043F\u0456\u0441\u043B\u044F \u0430\u0431\u0437\u0430\u0446\u0443",
990
+ superscript: "\u0412\u0435\u0440\u0445\u043D\u0456\u0439 \u0456\u043D\u0434\u0435\u043A\u0441",
991
+ subscript: "\u041D\u0438\u0436\u043D\u0456\u0439 \u0456\u043D\u0434\u0435\u043A\u0441",
992
+ painter: "\u041A\u043E\u043F\u0456\u044E\u0432\u0430\u0442\u0438 \u0444\u043E\u0440\u043C\u0430\u0442",
993
+ painterHint: "\u0412\u0438\u0434\u0456\u043B\u0456\u0442\u044C \u0442\u0435\u043A\u0441\u0442, \u043F\u043E\u0434\u0432\u0456\u0439\u043D\u0438\u0439 \u043A\u043B\u0456\u043A \u043B\u0438\u0448\u0430\u0454 \u0443\u0432\u0456\u043C\u043A\u043D\u0435\u043D\u0438\u043C, Esc \u0432\u0438\u043C\u0438\u043A\u0430\u0454",
994
+ pageSetup: "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0438 \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0438",
995
+ orientation: "\u041E\u0440\u0456\u0454\u043D\u0442\u0430\u0446\u0456\u044F",
996
+ portrait: "\u041A\u043D\u0438\u0436\u043A\u043E\u0432\u0430",
997
+ landscape: "\u0410\u043B\u044C\u0431\u043E\u043C\u043D\u0430",
998
+ marginsCm: "\u041F\u043E\u043B\u044F, \u0441\u043C",
999
+ mTop: "\u0412\u0435\u0440\u0445\u043D\u0454",
1000
+ mRight: "\u041F\u0440\u0430\u0432\u0435",
1001
+ mBottom: "\u041D\u0438\u0436\u043D\u0454",
1002
+ mLeft: "\u041B\u0456\u0432\u0435",
1003
+ headerText: "\u0412\u0435\u0440\u0445\u043D\u0456\u0439 \u043A\u043E\u043B\u043E\u043D\u0442\u0438\u0442\u0443\u043B",
1004
+ footerText: "\u041D\u0438\u0436\u043D\u0456\u0439 \u043A\u043E\u043B\u043E\u043D\u0442\u0438\u0442\u0443\u043B",
1005
+ pageNumbers: "\u041D\u043E\u043C\u0435\u0440\u0438 \u0441\u0442\u043E\u0440\u0456\u043D\u043E\u043A \u0443\u043D\u0438\u0437\u0443",
1006
+ wrapInline: "\u0423 \u0440\u044F\u0434\u043A\u0443 \u0437 \u0442\u0435\u043A\u0441\u0442\u043E\u043C",
1007
+ wrapLeft: "\u0422\u0435\u043A\u0441\u0442 \u043E\u0431\u0442\u0456\u043A\u0430\u0454 \u043F\u0440\u0430\u0432\u043E\u0440\u0443\u0447",
1008
+ wrapRight: "\u0422\u0435\u043A\u0441\u0442 \u043E\u0431\u0442\u0456\u043A\u0430\u0454 \u043B\u0456\u0432\u043E\u0440\u0443\u0447",
1009
+ cellFill: "\u0417\u0430\u043B\u0438\u0432\u043A\u0430 \u043A\u043B\u0456\u0442\u0438\u043D\u043A\u0438",
1010
+ tableBorders: "\u041C\u0435\u0436\u0456 \u0442\u0430\u0431\u043B\u0438\u0446\u0456",
1011
+ findReplace: "\u0417\u043D\u0430\u0439\u0442\u0438 \u0439 \u0437\u0430\u043C\u0456\u043D\u0438\u0442\u0438",
1012
+ replaceWith: "\u0417\u0430\u043C\u0456\u043D\u0438\u0442\u0438 \u043D\u0430",
1013
+ replaceOne: "\u0417\u0430\u043C\u0456\u043D\u0438\u0442\u0438",
1014
+ replaceAll: "\u0417\u0430\u043C\u0456\u043D\u0438\u0442\u0438 \u0432\u0441\u0456",
1015
+ matchCase: "\u0417 \u0443\u0440\u0430\u0445\u0443\u0432\u0430\u043D\u043D\u044F\u043C \u0440\u0435\u0433\u0456\u0441\u0442\u0440\u0443",
1016
+ words: "\u0421\u043B\u043E\u0432\u0430",
1017
+ print: "\u0414\u0440\u0443\u043A",
1018
+ autosavedNote: "\u0417\u0431\u0435\u0440\u0435\u0436\u0435\u043D\u043E \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u043D\u043E",
1019
+ uploadFile: "\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0444\u0430\u0439\u043B",
1020
+ uploading: "\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0435\u043D\u043D\u044F",
1021
+ uploadFailed: "\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0444\u0430\u0439\u043B"
842
1022
  };
843
1023
  texts = { en: en2, pl: pl2, uk: uk2 };
844
1024
  }
@@ -1237,6 +1417,8 @@ function fmtOf(marks2) {
1237
1417
  else if (m.type === "underline") f.u = true;
1238
1418
  else if (m.type === "strike") f.s = true;
1239
1419
  else if (m.type === "code") f.code = true;
1420
+ else if (m.type === "superscript") f.va = "sup";
1421
+ else if (m.type === "subscript") f.va = "sub";
1240
1422
  else if (m.type === "link" && typeof a.href === "string" && a.href) f.link = a.href;
1241
1423
  else if (m.type === "highlight") f.hl = color(a.color) ?? "#ffff00";
1242
1424
  else if (m.type === "textStyle") {
@@ -1255,6 +1437,7 @@ function marksOf(f) {
1255
1437
  if (f.u) out.push({ type: "underline" });
1256
1438
  if (f.s) out.push({ type: "strike" });
1257
1439
  if (f.code) out.push({ type: "code" });
1440
+ if (f.va) out.push({ type: f.va === "sup" ? "superscript" : "subscript" });
1258
1441
  if (f.link) out.push({ type: "link", attrs: { href: f.link } });
1259
1442
  if (f.hl) out.push({ type: "highlight", attrs: { color: f.hl } });
1260
1443
  if (f.color || f.size || f.font) out.push({ type: "textStyle", attrs: { color: f.color, fontSize: f.size, fontFamily: f.font } });
@@ -1265,7 +1448,7 @@ function marksOf(f) {
1265
1448
  return out.length ? out : void 0;
1266
1449
  }
1267
1450
  function keyOf(f) {
1268
- return `${+f.b}${+f.i}${+f.u}${+f.s}${+f.code}|${f.link ?? ""}|${f.hl ?? ""}|${f.color ?? ""}|${f.size ?? ""}|${f.font ?? ""}|${f.rev ?? ""}`;
1451
+ return `${+f.b}${+f.i}${+f.u}${+f.s}${+f.code}|${f.link ?? ""}|${f.hl ?? ""}|${f.color ?? ""}|${f.size ?? ""}|${f.font ?? ""}|${f.rev ?? ""}|${f.va ?? ""}`;
1269
1452
  }
1270
1453
  function outline(v) {
1271
1454
  const n = Number(v);
@@ -1303,6 +1486,11 @@ function props(s, rPr, fonts) {
1303
1486
  case "w:sz":
1304
1487
  out.size = size(+(attr(s, k, "w:val") ?? 0) / 2);
1305
1488
  break;
1489
+ case "w:vertAlign": {
1490
+ const v = attr(s, k, "w:val");
1491
+ out.va = v === "superscript" ? "sup" : v === "subscript" ? "sub" : null;
1492
+ break;
1493
+ }
1306
1494
  case "w:highlight": {
1307
1495
  const v = attr(s, k, "w:val") ?? "none";
1308
1496
  out.hl = highlights[v] ? "#" + highlights[v] : null;
@@ -1338,7 +1526,7 @@ var init_pkg = __esm({
1338
1526
  "use strict";
1339
1527
  init_xml();
1340
1528
  init_zip();
1341
- plain = { b: false, i: false, u: false, s: false, code: false, link: null, hl: null, color: null, size: null, font: null, rev: null };
1529
+ plain = { b: false, i: false, u: false, s: false, code: false, link: null, hl: null, color: null, size: null, font: null, rev: null, va: null };
1342
1530
  highlights = {
1343
1531
  yellow: "ffff00",
1344
1532
  green: "00ff00",
@@ -1738,7 +1926,7 @@ var init_read = __esm({
1738
1926
  "use strict";
1739
1927
  init_pkg();
1740
1928
  init_xml();
1741
- blank2 = () => ({ align: null, indent: 0, ref: null });
1929
+ blank2 = () => ({ align: null, indent: 0, line: null, after: null, ref: null });
1742
1930
  mimes = { png: "image/png", jpg: "image/jpeg", jpeg: "image/jpeg", gif: "image/gif", bmp: "image/bmp", webp: "image/webp", svg: "image/svg+xml" };
1743
1931
  Reader = class {
1744
1932
  constructor(pkg) {
@@ -1845,7 +2033,14 @@ var init_read = __esm({
1845
2033
  const src = p.pic && this.src(p.pic.embed);
1846
2034
  if (!src) continue;
1847
2035
  const meta2 = Object.fromEntries(attrs(/<wp:docPr\b[^>]*>/.exec(p.raw)?.[0] ?? "<x>"));
1848
- p.img = { src, alt: meta2.descr ?? null, title: meta2.title ?? null, width: Math.round(p.pic.cx / 9525), height: Math.round(p.pic.cy / 9525) };
2036
+ p.img = {
2037
+ src,
2038
+ alt: meta2.descr ?? null,
2039
+ title: meta2.title ?? null,
2040
+ width: Math.round(p.pic.cx / 9525),
2041
+ height: Math.round(p.pic.cy / 9525),
2042
+ wrap: /<wp:anchor\b/.test(p.raw) ? /<wp:positionH\b[^>]*>\s*<wp:align>right</.test(p.raw) ? "right" : "left" : null
2043
+ };
1849
2044
  }
1850
2045
  const pPr = kid(el, "w:pPr");
1851
2046
  const styles2 = this.pkg.styles;
@@ -1873,7 +2068,11 @@ var init_read = __esm({
1873
2068
  const ind = pPr && kid(pPr, "w:ind");
1874
2069
  const left = ind && (attr(s, ind, "w:left") ?? attr(s, ind, "w:start"));
1875
2070
  const indent2 = isList ? 0 : Math.max(0, Math.round((left !== null && left !== void 0 ? +left : styles2.left(style)) / 720));
1876
- const base = { align: align(jc ? attr(s, jc, "w:val") : styles2.jc(style)), indent: indent2, ref };
2071
+ const sp = pPr && kid(pPr, "w:spacing");
2072
+ const lineAt = sp && attr(s, sp, "w:line");
2073
+ const afterAt = sp && attr(s, sp, "w:after");
2074
+ const auto = !sp || !attr(s, sp, "w:lineRule") || attr(s, sp, "w:lineRule") === "auto";
2075
+ const base = { align: align(jc ? attr(s, jc, "w:val") : styles2.jc(style)), indent: indent2, line: lineAt && auto ? Math.round(+lineAt / 2.4) / 100 : null, after: afterAt ? +afterAt / 20 : null, ref };
1877
2076
  const node = level ? { type: "heading", attrs: { level, ...base } } : { type: "paragraph", attrs: base };
1878
2077
  const content = inline2(final);
1879
2078
  if (content.length) node.content = content;
@@ -2081,10 +2280,13 @@ var init_read = __esm({
2081
2280
  const ref = this.ref();
2082
2281
  const pr = kid(el, "w:tblPr");
2083
2282
  const jc = pr && kid(pr, "w:jc");
2084
- const node = { type: "table", attrs: { align: align(jc ? attr(s, jc, "w:val") : null), indent: 0, ref }, content: [] };
2283
+ const bd = pr && kid(pr, "w:tblBorders");
2284
+ const bare2 = !!bd && bd.kids.length > 0 && bd.kids.every((k) => /^(none|nil)$/.test(attr(s, k, "w:val") ?? ""));
2285
+ const node = { type: "table", attrs: { align: align(jc ? attr(s, jc, "w:val") : null), indent: 0, borders: bare2 ? "none" : null, ref }, content: [] };
2085
2286
  const b = this.block("tbl", el, node, ref);
2086
2287
  const grid3 = kid(el, "w:tblGrid");
2087
2288
  b.cols = grid3 ? grid3.kids.filter((k) => k.name === "w:gridCol").length : 0;
2289
+ const widths = grid3 ? grid3.kids.filter((k) => k.name === "w:gridCol").map((k) => Math.floor(+(attr(s, k, "w:w") ?? 0) / 15)) : [];
2088
2290
  const open = [];
2089
2291
  let prev = grid3 ? grid3.end : pr ? pr.end : el.open;
2090
2292
  for (const tr of el.kids) {
@@ -2120,7 +2322,10 @@ var init_read = __esm({
2120
2322
  if (vm === "continue") open[col].attrs.rowspan++;
2121
2323
  else {
2122
2324
  const content = assemble(inside.list);
2123
- cell2.node = { type: header ? "tableHeader" : "tableCell", attrs: { colspan: span2, rowspan: 1, align: null, indent: 0, ref: cref }, content: content.length ? content : [{ type: "paragraph", attrs: blank2() }] };
2325
+ const own = widths.slice(col, col + span2);
2326
+ const shd = tcPr && kid(tcPr, "w:shd");
2327
+ const fill3 = shd ? attr(s, shd, "w:fill") : null;
2328
+ cell2.node = { type: header ? "tableHeader" : "tableCell", attrs: { colspan: span2, rowspan: 1, colwidth: own.length === span2 && own.every((w) => w > 0) ? own : null, background: fill3 && /^[0-9a-f]{6}$/i.test(fill3) ? `#${fill3.toLowerCase()}` : null, align: null, indent: 0, ref: cref }, content: content.length ? content : [{ type: "paragraph", attrs: blank2() }] };
2124
2329
  row2.node.content.push(cell2.node);
2125
2330
  for (let c = col; c < col + span2; c++) open[c] = null;
2126
2331
  if (vm === "restart") open[col] = cell2.node;
@@ -2195,6 +2400,8 @@ function value(key2, v) {
2195
2400
  if (v === void 0 || v === "" || v === null) return null;
2196
2401
  if (key2 === "align") return v === "left" ? null : v;
2197
2402
  if (key2 === "width" || key2 === "height") return Math.round(Number(v)) || null;
2403
+ if (key2 === "line" || key2 === "after") return Number.isFinite(Number(v)) ? Number(v) : null;
2404
+ if (key2 === "colwidth") return Array.isArray(v) && v.length && v.every((w) => Number(w) > 0) ? v.map((w) => Math.round(Number(w))) : null;
2198
2405
  if (key2 === "indent" || key2 === "level" || key2 === "colspan" || key2 === "rowspan" || key2 === "start") return Number(v) || 0;
2199
2406
  if (key2 === "checked") return !!v;
2200
2407
  return v;
@@ -2228,7 +2435,7 @@ function inlineSig(kids) {
2228
2435
  return out;
2229
2436
  }
2230
2437
  function picture2(a) {
2231
- return JSON.stringify([a.src ?? null, a.alt || null, a.title || null, Math.round(Number(a.width)) || null, Math.round(Number(a.height)) || null]);
2438
+ return JSON.stringify([a.src ?? null, a.alt || null, a.title || null, Math.round(Number(a.width)) || null, Math.round(Number(a.height)) || null, a.wrap || null]);
2232
2439
  }
2233
2440
  function flatten(content, out = [], quote2 = false) {
2234
2441
  for (const node of content) {
@@ -2360,15 +2567,16 @@ var init_write = __esm({
2360
2567
  REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
2361
2568
  special = { " ": "<w:tab/>", "\n": "<w:br/>", "\u2011": "<w:noBreakHyphen/>", "\xAD": "<w:softHyphen/>" };
2362
2569
  keys = {
2363
- paragraph: [["align", null], ["indent", 0]],
2364
- heading: [["level", 1], ["align", null], ["indent", 0]],
2365
- table: [["align", null]],
2366
- tableCell: [["colspan", 1], ["rowspan", 1]],
2367
- tableHeader: [["colspan", 1], ["rowspan", 1]],
2570
+ paragraph: [["align", null], ["indent", 0], ["line", null], ["after", null]],
2571
+ heading: [["level", 1], ["align", null], ["indent", 0], ["line", null], ["after", null]],
2572
+ table: [["align", null], ["borders", null]],
2573
+ tableCell: [["colspan", 1], ["rowspan", 1], ["colwidth", null], ["background", null]],
2574
+ tableHeader: [["colspan", 1], ["rowspan", 1], ["colwidth", null], ["background", null]],
2368
2575
  orderedList: [["start", 1]],
2369
2576
  taskItem: [["checked", false]],
2370
2577
  codeBlock: [["language", null]],
2371
- toc: [["entries", "[]"], ["title", null]]
2578
+ toc: [["entries", "[]"], ["title", null]],
2579
+ image: [["src", null], ["alt", null], ["title", null], ["width", null], ["height", null], ["wrap", null]]
2372
2580
  };
2373
2581
  groups = 0;
2374
2582
  Writer = class {
@@ -2404,7 +2612,7 @@ var init_write = __esm({
2404
2612
  this.docPr = max + 1;
2405
2613
  this.nextRev = Math.max(0, ...[...this.s.matchAll(/\bw:id="(\d+)"/g)].map((m) => +m[1])) + 1;
2406
2614
  }
2407
- run(doc) {
2615
+ run(doc, setup) {
2408
2616
  const s = this.s;
2409
2617
  this.body = this.r.body();
2410
2618
  const { list, tail, body } = this.body;
@@ -2414,8 +2622,8 @@ var init_write = __esm({
2414
2622
  this.carryOver(list, (x) => rest = x);
2415
2623
  let xml = this.container(flatten(doc.content ?? []), list, null);
2416
2624
  if (this.last === "tbl" && list[list.length - 1]?.kind !== "tbl") xml += "<w:p/>";
2417
- const text = s.slice(0, body.open) + xml + rest + s.slice(tail);
2418
2625
  const changed2 = /* @__PURE__ */ new Map();
2626
+ const text = this.marginal(s.slice(0, body.open) + xml + rest + s.slice(tail), setup, changed2);
2419
2627
  if (text !== s) changed2.set(this.pkg.main, text);
2420
2628
  if (this.rels.length) {
2421
2629
  const path = this.pkg.relsPath(this.pkg.main);
@@ -2541,6 +2749,79 @@ var init_write = __esm({
2541
2749
  if (o.kind === "toc") return b && sig(o.node) === sig(b.node) ? s.slice(b.start, b.end) : this.toc(o.node);
2542
2750
  return this.code(o);
2543
2751
  }
2752
+ marginal(text, setup, changed2) {
2753
+ if (!setup || !setup.page && setup.header === void 0 && setup.footer === void 0 && setup.numbers === void 0) return text;
2754
+ const end = text.lastIndexOf("</w:body>");
2755
+ const opens2 = (i) => /^<w:sectPr[\s>/]/.test(text.slice(i, i + 11));
2756
+ let start = -1;
2757
+ let close = text.lastIndexOf("</w:sectPr>", end);
2758
+ if (close >= 0 && !text.slice(close + 11, end).trim()) {
2759
+ let depth = 1;
2760
+ let i = close;
2761
+ while (depth > 0 && i > 0) {
2762
+ let o = text.lastIndexOf("<w:sectPr", i - 1);
2763
+ while (o >= 0 && !opens2(o)) o = text.lastIndexOf("<w:sectPr", o - 1);
2764
+ const c = text.lastIndexOf("</w:sectPr>", i - 1);
2765
+ if (c > o) {
2766
+ depth++;
2767
+ i = c;
2768
+ } else if (o < 0) break;
2769
+ else {
2770
+ if (text[text.indexOf(">", o) - 1] !== "/") depth--;
2771
+ i = o;
2772
+ }
2773
+ }
2774
+ start = i;
2775
+ close += 11;
2776
+ } else {
2777
+ start = close = end;
2778
+ }
2779
+ let sec = start === end ? "<w:sectPr></w:sectPr>" : text.slice(start, close);
2780
+ if (sec.endsWith("/>") && !sec.includes("</w:sectPr>")) sec = sec.slice(0, -2) + "></w:sectPr>";
2781
+ const after = ["w:pgMar", "w:paperSrc", "w:pgBorders", "w:lnNumType", "w:pgNumType", "w:cols", "w:formProt", "w:vAlign", "w:noEndnote", "w:titlePg", "w:textDirection", "w:bidi", "w:rtlGutter", "w:docGrid", "w:printerSettings", "w:sectPrChange"];
2782
+ const put = (name, xml, before) => {
2783
+ const re = new RegExp(`<${name}\\b[^>]*?(?:/>|>[\\s\\S]*?</${name}>)`);
2784
+ if (re.test(sec)) {
2785
+ sec = sec.replace(re, xml);
2786
+ return;
2787
+ }
2788
+ const at = before.map((b) => sec.search(new RegExp(`<${b}[\\s>/]`))).filter((i2) => i2 >= 0);
2789
+ const i = at.length ? Math.min(...at) : sec.lastIndexOf("</w:sectPr>");
2790
+ sec = sec.slice(0, i) + xml + sec.slice(i);
2791
+ };
2792
+ const tw = (px2) => Math.round(px2 * 15);
2793
+ if (setup.page) {
2794
+ const { width, height, margins: [top, right, bottom, left] } = setup.page;
2795
+ put("w:pgSz", `<w:pgSz w:w="${tw(width)}" w:h="${tw(height)}"${width > height ? ' w:orient="landscape"' : ""}/>`, after);
2796
+ const was = /<w:pgMar\b[^>]*\/>/.exec(sec)?.[0] ?? "";
2797
+ const keep = attrs(was.replace(/^<w:pgMar|\/>$/g, "")).filter(([k]) => !["w:top", "w:right", "w:bottom", "w:left"].includes(k));
2798
+ if (!keep.some(([k]) => k === "w:header")) keep.push(["w:header", "708"], ["w:footer", "708"], ["w:gutter", "0"]);
2799
+ put("w:pgMar", `<w:pgMar w:top="${tw(top)}" w:right="${tw(right)}" w:bottom="${tw(bottom)}" w:left="${tw(left)}" ${keep.map(([k, v]) => `${k}="${escape2(v)}"`).join(" ")}/>`, after.slice(1));
2800
+ }
2801
+ const part = (kind, body) => {
2802
+ sec = sec.replace(new RegExp(`<w:${kind}Reference\\b[^>]*\\bw:type="default"[^>]*/>`), "");
2803
+ if (!body) return;
2804
+ let n = 1;
2805
+ while (this.pkg.files.has(`word/${kind}${n}.xml`) || changed2.has(`word/${kind}${n}.xml`)) n++;
2806
+ const id = this.relId();
2807
+ const tag = kind === "header" ? "w:hdr" : "w:ftr";
2808
+ changed2.set(`word/${kind}${n}.xml`, `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2809
+ <${tag} xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="${REL}">${body}</${tag}>`);
2810
+ this.rels.push(`<Relationship Id="${id}" Type="${REL}/${kind}" Target="${kind}${n}.xml"/>`);
2811
+ this.types.add(`<Override PartName="/word/${kind}${n}.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.${kind}+xml"/>`);
2812
+ const open = sec.indexOf(">") + 1;
2813
+ sec = sec.slice(0, open) + `<w:${kind}Reference w:type="default" r:id="${id}"/>` + sec.slice(open);
2814
+ };
2815
+ const line = (words, page) => {
2816
+ const field = '<w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText xml:space="preserve"> PAGE </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>1</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r>';
2817
+ const run2 = words ? `<w:r><w:t xml:space="preserve">${escape2(words)}</w:t></w:r>` : "";
2818
+ if (!words && !page) return "";
2819
+ return `<w:p><w:pPr>${page && words ? `<w:tabs><w:tab w:val="right" w:pos="${this.textWidth()}"/></w:tabs>` : page ? '<w:jc w:val="right"/>' : ""}</w:pPr>${run2}${page && words ? "<w:r><w:tab/></w:r>" : ""}${page ? field : ""}</w:p>`;
2820
+ };
2821
+ if (setup.header !== void 0) part("header", line(setup.header, false));
2822
+ if (setup.footer !== void 0 || setup.numbers !== void 0) part("footer", line(setup.footer ?? "", !!setup.numbers));
2823
+ return text.slice(0, start) + sec + text.slice(close);
2824
+ }
2544
2825
  toc(node) {
2545
2826
  this.tocs = true;
2546
2827
  const styles2 = this.pkg.styles;
@@ -2658,6 +2939,20 @@ var init_write = __esm({
2658
2939
  if (align(direct ?? styles2.jc(style)) !== want) {
2659
2940
  set["w:jc"] = align(styles2.jc(style)) === want ? null : `<w:jc w:val="${{ center: "center", right: "right", justify: "both" }[want ?? ""] ?? "left"}"/>`;
2660
2941
  }
2942
+ const spEl = get("w:spacing");
2943
+ const spacing2 = spEl ? attrs(xml.slice(spEl.start, spEl.open)) : [];
2944
+ const had = (name) => spacing2.find(([k]) => k === name)?.[1] ?? null;
2945
+ const line = value("line", o.node.attrs?.line);
2946
+ const after = value("after", o.node.attrs?.after);
2947
+ const auto = !had("w:lineRule") || had("w:lineRule") === "auto";
2948
+ const drift = (had("w:line") && auto ? Math.round(+had("w:line") / 2.4) / 100 : null) !== line || (had("w:after") ? +had("w:after") / 20 : null) !== after;
2949
+ if ((b || line !== null || after !== null) && drift) {
2950
+ const kept = spacing2.filter(([k]) => k !== "w:line" && k !== "w:lineRule" && k !== "w:after" && !(k === "w:afterAutospacing" && after !== null));
2951
+ if (line !== null) kept.push(["w:line", String(Math.round(line * 240))], ["w:lineRule", "auto"]);
2952
+ else if (had("w:line") && !auto) kept.push(["w:line", had("w:line")], ["w:lineRule", had("w:lineRule")]);
2953
+ if (after !== null) kept.push(["w:after", String(Math.round(after * 20))]);
2954
+ set["w:spacing"] = kept.length ? `<w:spacing ${kept.map(([k, v]) => `${k}="${escape2(v)}"`).join(" ")}/>` : null;
2955
+ }
2661
2956
  if (!pr) {
2662
2957
  const indEl = "w:ind" in set ? void 0 : get("w:ind");
2663
2958
  const list = indEl ? attrs(xml.slice(indEl.start, indEl.open)).filter(([k]) => k !== "w:left" && k !== "w:start") : [];
@@ -2912,6 +3207,7 @@ var init_write = __esm({
2912
3207
  set["w:strike"] = to.s ? "<w:strike/>" : sf.s ? '<w:strike w:val="0"/>' : null;
2913
3208
  if (!to.s) set["w:dstrike"] = null;
2914
3209
  }
3210
+ if (to.va !== from.va) set["w:vertAlign"] = to.va ? `<w:vertAlign w:val="${to.va === "sup" ? "superscript" : "subscript"}"/>` : sf.va ? '<w:vertAlign w:val="baseline"/>' : null;
2915
3211
  if (to.color !== from.color) set["w:color"] = to.color ? `<w:color w:val="${to.color.slice(1).toUpperCase()}"/>` : sf.color ? '<w:color w:val="auto"/>' : null;
2916
3212
  if (to.size !== from.size) {
2917
3213
  const hp = to.size ? Math.round(parseFloat(to.size) * 2) : 0;
@@ -2970,6 +3266,17 @@ var init_write = __esm({
2970
3266
  this.srcs.set(src, added.id);
2971
3267
  return added;
2972
3268
  }
3269
+ wrapped(raw, side2) {
3270
+ const anchor = /<wp:anchor\b/.test(raw);
3271
+ if (!side2 && !anchor) return raw;
3272
+ const ns = (tag) => attrs(/<wp:(?:inline|anchor)\b([^>]*)>/.exec(tag)?.[1] ?? "").filter(([k]) => k.startsWith("xmlns")).map(([k, v]) => ` ${k}="${v}"`).join("");
3273
+ const part = (name) => new RegExp(`<${name}\\b[^>]*?(?:/>|>[\\s\\S]*?</${name}>)`).exec(raw)?.[0] ?? "";
3274
+ const body = part("wp:extent") + part("wp:effectExtent");
3275
+ const rest = part("wp:docPr") + part("wp:cNvGraphicFramePr") + part("a:graphic");
3276
+ if (!side2) return raw.replace(/<wp:anchor\b[\s\S]*<\/wp:anchor>/, `<wp:inline distT="0" distB="0" distL="0" distR="0"${ns(raw)}>${body}${rest}</wp:inline>`);
3277
+ const head2 = `<wp:anchor distT="0" distB="0" distL="114300" distR="114300" simplePos="0" relativeHeight="251658240" behindDoc="0" locked="0" layoutInCell="1" allowOverlap="1"${ns(raw)}><wp:simplePos x="0" y="0"/><wp:positionH relativeFrom="column"><wp:align>${side2 === "right" ? "right" : "left"}</wp:align></wp:positionH><wp:positionV relativeFrom="paragraph"><wp:posOffset>0</wp:posOffset></wp:positionV>`;
3278
+ return raw.replace(anchor ? /<wp:anchor\b[\s\S]*<\/wp:anchor>/ : /<wp:inline\b[\s\S]*<\/wp:inline>/, `${head2}${body}<wp:wrapSquare wrapText="bothSides"/>${rest}</wp:anchor>`);
3279
+ }
2973
3280
  drawing(img) {
2974
3281
  const media = this.embed(String(img.src ?? ""));
2975
3282
  const max = Math.round(this.textWidth() / 15);
@@ -2981,7 +3288,8 @@ var init_write = __esm({
2981
3288
  else if (!w) w = Math.round(h * nw / nh);
2982
3289
  const id = this.docPr++;
2983
3290
  const ext = `cx="${Math.round(w * 9525)}" cy="${Math.round(h * 9525)}"`;
2984
- return `<w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"><wp:extent ${ext}/><wp:effectExtent l="0" t="0" r="0" b="0"/>${meta(`<wp:docPr id="${id}" name="Picture ${id}"/>`, img)}<wp:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/></wp:cNvGraphicFramePr><a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:nvPicPr><pic:cNvPr id="${id}" name="Picture ${id}"/><pic:cNvPicPr/></pic:nvPicPr><pic:blipFill><a:blip r:embed="${media.id}"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext ${ext}/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing>`;
3291
+ const xml = `<w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"><wp:extent ${ext}/><wp:effectExtent l="0" t="0" r="0" b="0"/>${meta(`<wp:docPr id="${id}" name="Picture ${id}"/>`, img)}<wp:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/></wp:cNvGraphicFramePr><a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:nvPicPr><pic:cNvPr id="${id}" name="Picture ${id}"/><pic:cNvPicPr/></pic:nvPicPr><pic:blipFill><a:blip r:embed="${media.id}"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext ${ext}/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing>`;
3292
+ return img.wrap ? this.wrapped(xml, img.wrap) : xml;
2985
3293
  }
2986
3294
  patch(raw, old, img) {
2987
3295
  let xml = raw;
@@ -2993,6 +3301,7 @@ var init_write = __esm({
2993
3301
  }
2994
3302
  if ((img.alt || null) !== (old.alt || null) || (img.title || null) !== (old.title || null)) xml = xml.replace(/<wp:docPr\b[^>]*>/, (tag) => meta(tag, img));
2995
3303
  if (img.src !== old.src) xml = xml.replace(/(<a:blip\b[^>]*\br:embed=")[^"]*"/, `$1${this.embed(String(img.src ?? "")).id}"`);
3304
+ if ((img.wrap || null) !== (old.wrap || null)) xml = this.wrapped(xml, img.wrap);
2996
3305
  return xml;
2997
3306
  }
2998
3307
  textWidth() {
@@ -3058,6 +3367,27 @@ var init_write = __esm({
3058
3367
  head2 = `<w:tbl>${tblPr}<w:tblGrid>${`<w:gridCol w:w="${Math.floor(this.textWidth() / cols)}"/>`.repeat(cols)}</w:tblGrid>`;
3059
3368
  }
3060
3369
  const width = Math.floor(this.textWidth() / cols);
3370
+ const sized = [];
3371
+ for (const r of layout2) for (const sl of r) {
3372
+ const own2 = sl.cell && value("colwidth", sl.cell.attrs?.colwidth);
3373
+ if (own2 && own2.length === sl.span) own2.forEach((w, k) => {
3374
+ var _a;
3375
+ return sized[_a = sl.col + k] ?? (sized[_a] = w);
3376
+ });
3377
+ }
3378
+ const known = sized.length === cols && sized.every(Boolean);
3379
+ const had = [...head2.matchAll(/<w:gridCol\b[^>]*\bw:w="(\d+)"/g)].map((m) => Math.floor(+m[1] / 15));
3380
+ if (known && had.join() !== sized.join()) {
3381
+ const list = sized.map((w) => `<w:gridCol w:w="${Math.round(w * 15)}"/>`).join("");
3382
+ head2 = head2.replace(/(<w:tblGrid\b[^>]*>)[\s\S]*?(<\/w:tblGrid>)/, `$1${list}$2`);
3383
+ }
3384
+ const own = (col, span2) => known ? sized.slice(col, col + span2) : null;
3385
+ const borders = value("borders", o.node.attrs?.borders);
3386
+ if (borders !== value("borders", b?.node.attrs?.borders)) {
3387
+ const line = (side2) => `<w:${side2} w:val="${borders === "none" ? "none" : "single"}" w:sz="4" w:space="0" w:color="${borders === "none" ? "auto" : "94A3B8"}"/>`;
3388
+ const all = `<w:tblBorders>${["top", "left", "bottom", "right", "insideH", "insideV"].map(line).join("")}</w:tblBorders>`;
3389
+ head2 = /<w:tblBorders\b/.test(head2) ? head2.replace(/<w:tblBorders\b[\s\S]*?<\/w:tblBorders>|<w:tblBorders\/>/, all) : head2.replace(/(<w:tblPr\b[^>]*>(?:(?!<\/w:tblPr>)[\s\S])*?)(<w:shd\b|<w:tblLayout\b|<w:tblCellMar\b|<w:tblLook\b|<w:tblCaption\b|<w:tblDescription\b|<w:tblPrChange\b|<\/w:tblPr>)/, `$1${all}$2`);
3390
+ }
3061
3391
  let xml = head2;
3062
3392
  let above = [];
3063
3393
  let aboveRow = null;
@@ -3088,7 +3418,7 @@ var init_write = __esm({
3088
3418
  if (!sl.cell) {
3089
3419
  const cont = R2?.cells.find((c) => c.vm === "continue" && c.col === sl.col);
3090
3420
  if (cont) xml += cont.lead + s.slice(cont.el.start, cont.el.end);
3091
- else xml += `<w:tc>${this.tcPr(cover.get(sl.from) ?? above[sl.col] ?? null, sl.span, "continue", width)}<w:p/></w:tc>`;
3421
+ else xml += `<w:tc>${this.tcPr(cover.get(sl.from) ?? above[sl.col] ?? null, sl.span, "continue", width, true, own(sl.col, sl.span))}<w:p/></w:tc>`;
3092
3422
  now[sl.col] = cover.get(sl.from) ?? null;
3093
3423
  continue;
3094
3424
  }
@@ -3104,7 +3434,7 @@ var init_write = __esm({
3104
3434
  const fallback = srcCell?.blocks.find((x) => x.kind === "p") ?? null;
3105
3435
  let inside = this.container(flatten(sl.cell.content ?? []), C ? C.blocks : [], fallback) + (C ? this.left.get(C) ?? "" : "");
3106
3436
  if (!this.last || this.last === "tbl") inside += "<w:p/>";
3107
- xml += (C ? C.lead + opened(s, C.el) : "<w:tc>") + this.tcPr(srcCell, sl.span, vm, width, !C) + inside + (C ? C.tail : "") + "</w:tc>";
3437
+ xml += (C ? C.lead + opened(s, C.el) : "<w:tc>") + this.tcPr(srcCell, sl.span, vm, width, !C, own(sl.col, sl.span), value("background", sl.cell.attrs?.background)) + inside + (C ? C.tail : "") + "</w:tc>";
3108
3438
  }
3109
3439
  const lastCell = R2?.cells[R2.cells.length - 1];
3110
3440
  xml += (R2 && lastCell ? s.slice(lastCell.el.end, R2.el.close) : "") + "</w:tr>";
@@ -3113,15 +3443,21 @@ var init_write = __esm({
3113
3443
  });
3114
3444
  return xml + tail + "</w:tbl>";
3115
3445
  }
3116
- tcPr(src, span2, vm, width, clone = true) {
3446
+ tcPr(src, span2, vm, width, clone = true, own = null, fill3) {
3117
3447
  const s = this.s;
3118
3448
  const el = src && kid(src.el, "w:tcPr");
3119
3449
  const xml = el ? s.slice(el.start, el.end) : "";
3120
- if (!clone && src && src.span === span2 && src.vm === vm) return xml;
3450
+ const tcW = el && kid(el, "w:tcW");
3451
+ const sized = own ? Math.round(own.reduce((a, w) => a + w, 0) * 15) : null;
3452
+ const resized = sized !== null && !(tcW && attr(s, tcW, "w:type") === "dxa" && Math.abs(+(attr(s, tcW, "w:w") ?? 0) - sized) < 15);
3453
+ const was = src?.node ? value("background", src.node.attrs?.background) : null;
3454
+ const painted = fill3 !== void 0 && fill3 !== was;
3455
+ if (!clone && src && src.span === span2 && src.vm === vm && !resized && !painted) return xml;
3121
3456
  const set = { "w:gridSpan": span2 > 1 ? `<w:gridSpan w:val="${span2}"/>` : null, "w:vMerge": vm === "restart" ? '<w:vMerge w:val="restart"/>' : vm ? "<w:vMerge/>" : null, "w:hMerge": null };
3122
3457
  if (clone) Object.assign(set, { "w:cellIns": null, "w:cellDel": null, "w:cellMerge": null, "w:tcPrChange": null });
3123
- const tcW = el && kid(el, "w:tcW");
3124
- if (!tcW && !src) set["w:tcW"] = `<w:tcW w:w="${width * span2}" w:type="dxa"/>`;
3458
+ if (painted) set["w:shd"] = fill3 ? `<w:shd w:val="clear" w:color="auto" w:fill="${fill3.slice(1).toUpperCase()}"/>` : null;
3459
+ if (resized) set["w:tcW"] = `<w:tcW w:w="${sized}" w:type="dxa"/>`;
3460
+ else if (!tcW && !src) set["w:tcW"] = `<w:tcW w:w="${width * span2}" w:type="dxa"/>`;
3125
3461
  else if (tcW && src && src.span !== span2 && attr(xml, tcW, "w:type") === "dxa") set["w:tcW"] = `<w:tcW w:w="${Math.round(+(attr(xml, tcW, "w:w") ?? 0) * span2 / src.span)}" w:type="dxa"/>`;
3126
3462
  return rebuild(xml, "w:tcPr", TC, set);
3127
3463
  }
@@ -3138,15 +3474,24 @@ async function readDocx(bytes) {
3138
3474
  const size2 = sect && kid(sect, "w:pgSz");
3139
3475
  const mar = sect && kid(sect, "w:pgMar");
3140
3476
  const px2 = (el, name, fallback) => Math.round(Math.abs(+((el && attr(s, el, name)) ?? fallback)) / 15 * 100) / 100;
3477
+ const words = (kind) => {
3478
+ const ref = sect?.kids.find((k) => k.name === `w:${kind}Reference` && attr(s, k, "w:type") === "default");
3479
+ const part = ref && pkg.rels.get(attr(s, ref, "r:id") ?? "");
3480
+ const xml = part ? pkg.text(part.target) ?? "" : "";
3481
+ return { text: [...xml.matchAll(/<w:t(?:\s[^>]*)?>([^<]*)<\/w:t>/g)].map((m) => m[1]).join("").replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").trim(), page: /\bPAGE\b/.test(xml) };
3482
+ };
3483
+ const head2 = words("header");
3484
+ const foot = words("footer");
3141
3485
  return {
3486
+ marginal: { header: head2.text, footer: foot.page ? foot.text.replace(/\s*\d+$/, "") : foot.text, numbers: foot.page },
3142
3487
  doc: { type: "doc", content: content.length ? content : [{ type: "paragraph", attrs: { align: null, indent: 0, ref: null } }] },
3143
3488
  styles: pkg.styles.list(),
3144
3489
  page: { width: px2(size2, "w:w", 12240), height: px2(size2, "w:h", 15840), margins: [px2(mar, "w:top", 1440), px2(mar, "w:right", 1440), px2(mar, "w:bottom", 1440), px2(mar, "w:left", 1440)] }
3145
3490
  };
3146
3491
  }
3147
- async function writeDocx(original, doc, load3 = fetched) {
3492
+ async function writeDocx(original, doc, load3 = fetched, setup) {
3148
3493
  const pkg = new Pkg(new Uint8Array(original));
3149
- const out = new Writer(pkg, await images(doc, load3)).run(doc);
3494
+ const out = new Writer(pkg, await images(doc, load3)).run(doc, setup);
3150
3495
  return out ? out.slice().buffer : original.slice(0);
3151
3496
  }
3152
3497
  var init_docx = __esm({
@@ -3269,10 +3614,10 @@ var init_pager = __esm({
3269
3614
  addProseMirrorPlugins: () => [new import_state.Plugin({
3270
3615
  key: paging,
3271
3616
  state: {
3272
- init: () => ({ set: import_view.DecorationSet.empty, page: a4 }),
3617
+ init: () => ({ set: import_view.DecorationSet.empty, page: a4, marks: { header: "", footer: "" } }),
3273
3618
  apply(tr, value3) {
3274
3619
  const next = tr.getMeta(paging);
3275
- return { set: next?.set ?? value3.set.map(tr.mapping, tr.doc), page: next?.page ?? value3.page };
3620
+ return { set: next?.set ?? value3.set.map(tr.mapping, tr.doc), page: next?.page ?? value3.page, marks: next?.marks ?? value3.marks };
3276
3621
  }
3277
3622
  },
3278
3623
  props: { decorations: (state) => paging.getState(state).set },
@@ -3282,17 +3627,34 @@ var init_pager = __esm({
3282
3627
  const run2 = () => {
3283
3628
  if (!view.dom.isConnected) return;
3284
3629
  const gaps = measure(view);
3285
- const next = gaps.map((g) => `${g.pos}:${g.height}`).join();
3630
+ const { marks: marks2 } = paging.getState(view.state);
3631
+ const next = gaps.map((g) => `${g.pos}:${g.height}`).join() + `|${marks2.header}|${marks2.footer}`;
3286
3632
  if (next === sig2) return;
3287
3633
  sig2 = next;
3288
- const set = import_view.DecorationSet.create(view.state.doc, gaps.map((g) => import_view.Decoration.widget(g.pos, () => {
3634
+ const line = (parent, cls, text) => {
3635
+ if (!text) return;
3636
+ const span2 = document.createElement("span");
3637
+ span2.className = cls;
3638
+ span2.textContent = text;
3639
+ parent.append(span2);
3640
+ };
3641
+ const first = import_view.Decoration.widget(0, () => {
3642
+ const el = document.createElement("div");
3643
+ el.className = "w100n-text-first";
3644
+ el.contentEditable = "false";
3645
+ line(el, "w100n-text-head", marks2.header);
3646
+ return el;
3647
+ }, { key: `first:${marks2.header}`, side: -1, ignoreSelection: true });
3648
+ const set = import_view.DecorationSet.create(view.state.doc, [first, ...gaps.map((g) => import_view.Decoration.widget(g.pos, () => {
3289
3649
  const el = document.createElement("div");
3290
3650
  el.className = g.end ? "w100n-text-gap is-end" : "w100n-text-gap";
3291
3651
  el.style.height = `${g.height}px`;
3292
3652
  el.dataset.page = String(g.page);
3293
3653
  el.contentEditable = "false";
3654
+ line(el, "w100n-text-foot", marks2.footer);
3655
+ if (!g.end) line(el, "w100n-text-head", marks2.header);
3294
3656
  return el;
3295
- }, { key: `${g.pos}:${g.height}:${g.page}`, side: -1, ignoreSelection: true })));
3657
+ }, { key: `${g.pos}:${g.height}:${g.page}:${marks2.header}:${marks2.footer}`, side: -1, ignoreSelection: true }))]);
3296
3658
  view.dispatch(view.state.tr.setMeta(paging, { set }).setMeta("addToHistory", false));
3297
3659
  };
3298
3660
  const later = (ms) => {
@@ -3304,7 +3666,7 @@ var init_pager = __esm({
3304
3666
  later(0);
3305
3667
  return {
3306
3668
  update: (next, prev) => {
3307
- if (paging.getState(next.state).page !== paging.getState(prev).page) later(0);
3669
+ if (paging.getState(next.state).page !== paging.getState(prev).page || paging.getState(next.state).marks !== paging.getState(prev).marks) later(0);
3308
3670
  else if (next.state.doc !== prev.doc) later(400);
3309
3671
  },
3310
3672
  destroy: () => {
@@ -3353,13 +3715,21 @@ function kit(kind, t, live) {
3353
3715
  import_starter_kit.default.configure({ trailingNode: false, link: { openOnClick: false, autolink: true, defaultProtocol: "https" }, dropcursor: { color: "#8b5cf6", width: 2 }, ...live ? { undoRedo: false } : {} }),
3354
3716
  import_extension_list.TaskList,
3355
3717
  import_extension_list.TaskItem.configure({ nested: true, a11y: { checkboxLabel: (node) => node.textContent || t.tasks } }),
3356
- import_extension_table.TableKit.configure({ table: { resizable: false } }),
3357
- import_extension_image.default.configure({ inline: true, allowBase64: true }),
3718
+ import_extension_table.TableKit.configure({ table: { resizable: true, cellMinWidth: 32 } }),
3719
+ Cells,
3720
+ Search2,
3721
+ import_extension_image.default.extend({
3722
+ addAttributes() {
3723
+ return { ...this.parent?.(), wrap: { default: null, parseHTML: (el) => el.dataset.wrap ?? null, renderHTML: (attrs2) => attrs2.wrap ? { "data-wrap": attrs2.wrap } : {} } };
3724
+ }
3725
+ }).configure({ inline: true, allowBase64: true, resize: { enabled: true, directions: ["top-left", "top-right", "bottom-left", "bottom-right"], minWidth: 24, minHeight: 24, alwaysPreserveAspectRatio: true } }),
3358
3726
  import_extension_highlight.default.configure({ multicolor: true }),
3359
3727
  import_extension_text_style.TextStyle,
3360
3728
  import_extension_text_style.Color,
3361
3729
  import_extension_text_style.FontSize,
3362
3730
  import_extension_text_style.FontFamily,
3731
+ script("superscript", "sup", "subscript"),
3732
+ script("subscript", "sub", "superscript"),
3363
3733
  Blocks,
3364
3734
  PageBreak.configure({ label: t.pageBreak }),
3365
3735
  Toc.configure({ relative: kind === "markdown", label: t.toc, empty: t.tocEmpty }),
@@ -3408,7 +3778,7 @@ function locate(doc, list) {
3408
3778
  return range ? [{ id: c.id, from: range.from, to: range.to }] : [];
3409
3779
  });
3410
3780
  }
3411
- var import_core2, import_extension_collaboration, import_extension_collaboration_caret, import_extension_highlight, import_extension_image, import_extension_list, import_extension_table, import_extension_text_style, import_state2, import_transform, import_view2, import_starter_kit, import_y_tiptap, notes, blocks, changed, Blocks, PageBreak, headings, Toc, revision, seen, suggesting, Suggest, Note, locks, locked, scan, Locks, paint, remap, Notes, textblocks, align2, indent, clear;
3781
+ var import_core2, import_extension_collaboration, import_extension_collaboration_caret, import_extension_highlight, import_extension_image, import_extension_list, import_extension_table, import_extension_text_style, import_state2, import_transform, import_view2, import_starter_kit, import_y_tiptap, notes, blocks, changed, Cells, searching, lookup, Search2, replace, cleanPaste, Blocks, PageBreak, headings, Toc, revision, seen, suggesting, Suggest, Note, locks, locked, scan, Locks, paint, remap, Notes, script, textblocks, align2, spacing, indent, clear;
3412
3782
  var init_extensions = __esm({
3413
3783
  "src/editor/extensions.ts"() {
3414
3784
  "use strict";
@@ -3456,6 +3826,63 @@ var init_extensions = __esm({
3456
3826
  }));
3457
3827
  return ranges;
3458
3828
  };
3829
+ Cells = import_core2.Extension.create({
3830
+ name: "cells",
3831
+ addGlobalAttributes: () => [
3832
+ { types: ["tableCell", "tableHeader"], attributes: { background: { default: null, parseHTML: (el) => el.dataset.fill ?? null, renderHTML: (attrs2) => attrs2.background ? { "data-fill": attrs2.background, style: `background-color: ${attrs2.background}` } : {} } } },
3833
+ { types: ["table"], attributes: { borders: { default: null, parseHTML: (el) => el.dataset.borders ?? null, renderHTML: (attrs2) => attrs2.borders ? { "data-borders": attrs2.borders } : {} } } }
3834
+ ]
3835
+ });
3836
+ searching = new import_state2.PluginKey("w100n-search");
3837
+ lookup = (doc, query, matchCase) => {
3838
+ const hits = [];
3839
+ if (!query) return hits;
3840
+ const needle = matchCase ? query : query.toLowerCase();
3841
+ doc.descendants((node, pos) => {
3842
+ if (!node.isTextblock) return true;
3843
+ let text = "";
3844
+ const at = [];
3845
+ node.forEach((child, offset) => {
3846
+ const part = child.isText ? child.text : "\uFFFC";
3847
+ for (let i = 0; i < part.length; i++) at.push(pos + 1 + offset + i);
3848
+ text += part;
3849
+ });
3850
+ const hay = matchCase ? text : text.toLowerCase();
3851
+ for (let i = hay.indexOf(needle); i >= 0; i = hay.indexOf(needle, i + needle.length)) hits.push({ from: at[i], to: at[i + needle.length - 1] + 1 });
3852
+ return false;
3853
+ });
3854
+ return hits;
3855
+ };
3856
+ Search2 = import_core2.Extension.create({
3857
+ name: "search",
3858
+ addProseMirrorPlugins: () => [new import_state2.Plugin({
3859
+ key: searching,
3860
+ state: {
3861
+ init: () => ({ query: "", matchCase: false, hits: [], at: 0, set: import_view2.DecorationSet.empty }),
3862
+ apply(tr, value3) {
3863
+ const meta2 = tr.getMeta(searching);
3864
+ if (!meta2 && !tr.docChanged) return value3;
3865
+ const next = { ...value3, ...meta2 };
3866
+ const hits = lookup(tr.doc, next.query, next.matchCase);
3867
+ const at = hits.length ? (next.at % hits.length + hits.length) % hits.length : 0;
3868
+ return { ...next, hits, at, set: import_view2.DecorationSet.create(tr.doc, hits.map((h, i) => import_view2.Decoration.inline(h.from, h.to, { class: i === at ? "w100n-found is-current" : "w100n-found" }))) };
3869
+ }
3870
+ },
3871
+ props: { decorations: (state) => searching.getState(state).set }
3872
+ })]
3873
+ });
3874
+ replace = (editor, text, all) => {
3875
+ const { hits, at } = searching.getState(editor.state);
3876
+ if (!hits.length) return 0;
3877
+ const tr = editor.state.tr;
3878
+ for (const hit of all ? [...hits].reverse() : [hits[at]]) tr.insertText(text, hit.from, hit.to);
3879
+ editor.view.dispatch(tr);
3880
+ return all ? hits.length : 1;
3881
+ };
3882
+ cleanPaste = (html) => html.replace(/<!--\[if[\s\S]*?<!\[endif\]-->/g, "").replace(/<o:p>[\s\S]*?<\/o:p>/g, "").replace(/\sclass=("|')?Mso[^"'\s>]*\1?/g, "").replace(/<img\b[^>]*\ssrc=("|')file:[^"']*\1[^>]*>/gi, "").replace(/\sstyle=("|')([^"']*)\1/g, (_, q, css2) => {
3883
+ const kept = css2.split(";").map((x) => x.trim()).filter((x) => x && !/^mso-|^tab-stops|^font-family:\s*["']?(Symbol|Wingdings)/i.test(x)).join("; ");
3884
+ return kept ? ` style=${q}${kept}${q}` : "";
3885
+ });
3459
3886
  Blocks = import_core2.Extension.create({
3460
3887
  name: "blocks",
3461
3888
  addGlobalAttributes: () => [{
@@ -3463,6 +3890,8 @@ var init_extensions = __esm({
3463
3890
  attributes: {
3464
3891
  align: { default: null, parseHTML: (el) => el.style.textAlign || null, renderHTML: (attrs2) => attrs2.align ? { style: `text-align: ${attrs2.align}` } : {} },
3465
3892
  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` } : {} },
3893
+ line: { default: null, parseHTML: (el) => Number(el.dataset.line) || null, renderHTML: (attrs2) => attrs2.line ? { "data-line": attrs2.line, style: `line-height: ${attrs2.line * 1.15}` } : {} },
3894
+ after: { default: null, parseHTML: (el) => el.dataset.after ? Number(el.dataset.after) : null, renderHTML: (attrs2) => attrs2.after === null || attrs2.after === void 0 ? {} : { "data-after": attrs2.after, style: `margin-bottom: ${attrs2.after}pt` } },
3466
3895
  ref: { default: null, rendered: false, keepOnSplit: false }
3467
3896
  }
3468
3897
  }],
@@ -3773,6 +4202,15 @@ var init_extensions = __esm({
3773
4202
  props: { decorations: (state) => notes.getState(state).set }
3774
4203
  })]
3775
4204
  });
4205
+ script = (name, tag, other) => import_core2.Mark.create({
4206
+ name,
4207
+ excludes: other,
4208
+ parseHTML: () => [{ tag }, { style: `vertical-align=${name === "superscript" ? "super" : "sub"}` }],
4209
+ renderHTML: () => [tag, 0],
4210
+ addKeyboardShortcuts() {
4211
+ return { [name === "superscript" ? "Mod-." : "Mod-,"]: () => this.editor.commands.toggleMark(name) };
4212
+ }
4213
+ });
3776
4214
  textblocks = (editor, change) => editor.chain().focus().command(({ tr, state }) => {
3777
4215
  state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos) => {
3778
4216
  if (!node.isTextblock) return true;
@@ -3782,6 +4220,7 @@ var init_extensions = __esm({
3782
4220
  return true;
3783
4221
  }).run();
3784
4222
  align2 = (editor, value3) => textblocks(editor, () => ({ align: value3 === "left" ? null : value3 }));
4223
+ spacing = (editor, change) => textblocks(editor, () => change);
3785
4224
  indent = (editor, step) => {
3786
4225
  const type = editor.isActive("taskItem") ? "taskItem" : editor.isActive("listItem") ? "listItem" : null;
3787
4226
  if (type) return step > 0 ? editor.chain().focus().sinkListItem(type).run() : editor.chain().focus().liftListItem(type).run();
@@ -3800,7 +4239,7 @@ var init_extensions = __esm({
3800
4239
  var version;
3801
4240
  var init_package = __esm({
3802
4241
  "package.json"() {
3803
- version = "0.13.0";
4242
+ version = "0.14.0";
3804
4243
  }
3805
4244
  });
3806
4245
 
@@ -5503,7 +5942,7 @@ function equalValue(a, b) {
5503
5942
  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));
5504
5943
  return a === b;
5505
5944
  }
5506
- function lookup(book, s) {
5945
+ function lookup2(book, s) {
5507
5946
  if (!s) return {};
5508
5947
  return (typeof s === "string" ? book.styles[s] : s) ?? {};
5509
5948
  }
@@ -5643,7 +6082,7 @@ function writeXlsx(original, model) {
5643
6082
  const id = typeof s === "string" ? (bk === cur ? "c" : "b") + s : "";
5644
6083
  const known = id && seen2.get(id);
5645
6084
  if (known) return known;
5646
- const look = norm({ ...defaults, ...lookup(bk, s) });
6085
+ const look = norm({ ...defaults, ...lookup2(bk, s) });
5647
6086
  const made2 = { look, json: JSON.stringify(look) };
5648
6087
  if (id) seen2.set(id, made2);
5649
6088
  return made2;
@@ -5684,8 +6123,8 @@ function writeXlsx(original, model) {
5684
6123
  changed2 = true;
5685
6124
  tag = setAttr(tag, "hidden", hidden ? "1" : null);
5686
6125
  }
5687
- const look = rd.s ? norm({ ...defaults, ...lookup(cur, rd.s) }) : null;
5688
- const was = od.s ? norm({ ...defaults, ...lookup(base.book, od.s) }) : null;
6126
+ const look = rd.s ? norm({ ...defaults, ...lookup2(cur, rd.s) }) : null;
6127
+ const was = od.s ? norm({ ...defaults, ...lookup2(base.book, od.s) }) : null;
5689
6128
  if (!same2(look, was)) {
5690
6129
  changed2 = true;
5691
6130
  tag = setAttr(setAttr(tag, "s", look ? String(xfFor(look, xfOf(od.s))) : null), "customFormat", look ? "1" : null);
@@ -5975,7 +6414,7 @@ function cellXml(p, ref, xf, x, f, v) {
5975
6414
  function columns(p, rec, sheet2, old, cols, defaults, cur, baseBook, xfFor, xfOf) {
5976
6415
  const now = sheet2.columnData ?? {}, was = old.columnData ?? {};
5977
6416
  const count = sheet2.columnCount ?? 26;
5978
- const look = (bk, s) => s ? norm({ ...defaults, ...lookup(bk, s) }) : null;
6417
+ const look = (bk, s) => s ? norm({ ...defaults, ...lookup2(bk, s) }) : null;
5979
6418
  let differs2 = cols.moved;
5980
6419
  for (let c = 0; c < count && !differs2; c++) {
5981
6420
  const c0 = cols.from(c);
@@ -6448,6 +6887,11 @@ var init_text2 = __esm({
6448
6887
  "src/sheets/text.ts"() {
6449
6888
  "use strict";
6450
6889
  en3 = {
6890
+ asCurrency: "Format as euro",
6891
+ asPercent: "Format as percent",
6892
+ fewerDecimals: "Fewer decimal places",
6893
+ moreDecimals: "More decimal places",
6894
+ sum: "Sum",
6451
6895
  tools: "Sheet tools",
6452
6896
  loading: "Opening the sheet",
6453
6897
  failed: "This sheet could not be opened",
@@ -6516,6 +6960,11 @@ var init_text2 = __esm({
6516
6960
  }
6517
6961
  };
6518
6962
  pl3 = {
6963
+ asCurrency: "Formatuj jako euro",
6964
+ asPercent: "Formatuj jako procent",
6965
+ fewerDecimals: "Mniej miejsc po przecinku",
6966
+ moreDecimals: "Wi\u0119cej miejsc po przecinku",
6967
+ sum: "Suma",
6519
6968
  tools: "Narz\u0119dzia arkusza",
6520
6969
  loading: "Otwieranie arkusza",
6521
6970
  failed: "Nie uda\u0142o si\u0119 otworzy\u0107 tego arkusza",
@@ -6584,6 +7033,11 @@ var init_text2 = __esm({
6584
7033
  }
6585
7034
  };
6586
7035
  uk3 = {
7036
+ asCurrency: "\u0424\u043E\u0440\u043C\u0430\u0442 \u0454\u0432\u0440\u043E",
7037
+ asPercent: "\u0424\u043E\u0440\u043C\u0430\u0442 \u0432\u0456\u0434\u0441\u043E\u0442\u043A\u0456\u0432",
7038
+ fewerDecimals: "\u041C\u0435\u043D\u0448\u0435 \u0437\u043D\u0430\u043A\u0456\u0432 \u043F\u0456\u0441\u043B\u044F \u043A\u043E\u043C\u0438",
7039
+ moreDecimals: "\u0411\u0456\u043B\u044C\u0448\u0435 \u0437\u043D\u0430\u043A\u0456\u0432 \u043F\u0456\u0441\u043B\u044F \u043A\u043E\u043C\u0438",
7040
+ sum: "\u0421\u0443\u043C\u0430",
6587
7041
  tools: "\u0406\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u0438 \u0442\u0430\u0431\u043B\u0438\u0446\u0456",
6588
7042
  loading: "\u0412\u0456\u0434\u043A\u0440\u0438\u0432\u0430\u0454\u043C\u043E \u0442\u0430\u0431\u043B\u0438\u0446\u044E",
6589
7043
  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",
@@ -6679,8 +7133,8 @@ function follow(doc, author) {
6679
7133
  doc.off("afterTransaction", after);
6680
7134
  };
6681
7135
  }
6682
- async function write3(kind, base, node, load3) {
6683
- if (kind === "docx") return writeDocx(base, node.toJSON(), load3);
7136
+ async function write3(kind, base, node, load3, setup) {
7137
+ if (kind === "docx") return writeDocx(base, node.toJSON(), load3, setup);
6684
7138
  const parsed = fromMarkdown(new TextDecoder().decode(base));
6685
7139
  return new TextEncoder().encode(toMarkdown(node, track(parsed, node.type.schema.nodeFromJSON(parsed.doc))).text).buffer;
6686
7140
  }
@@ -6699,7 +7153,7 @@ async function save(doc, kind, base, put, load3, note) {
6699
7153
  };
6700
7154
  doc.on("afterTransaction", watch);
6701
7155
  try {
6702
- const bytes = await write3(kind, base, node, load3);
7156
+ const bytes = await write3(kind, base, node, load3, doc.getMap("setup").size ? doc.getMap("setup").toJSON() : void 0);
6703
7157
  const changed2 = !same3(bytes, base);
6704
7158
  const id = changed2 ? await put(bytes, note ?? named2((texts[who[0].language] ?? texts.en).editedNote, who)) : null;
6705
7159
  const refs2 = [];
@@ -6763,7 +7217,7 @@ var init_collab = __esm({
6763
7217
  schemas = /* @__PURE__ */ new Map();
6764
7218
  schemaOf = (kind) => schemas.get(kind) ?? schemas.set(kind, (0, import_core3.getSchema)(kit(kind, texts.en))).get(kind);
6765
7219
  parse3 = async (kind, bytes) => kind === "docx" ? (await readDocx(bytes)).doc : fromMarkdown(new TextDecoder().decode(bytes)).doc;
6766
- edits = (tr) => tr.changedParentTypes.has(tr.doc.get("default")) || tr.changedParentTypes.has(tr.doc.get("book"));
7220
+ edits = (tr) => tr.changedParentTypes.has(tr.doc.get("default")) || tr.changedParentTypes.has(tr.doc.get("book")) || tr.changedParentTypes.has(tr.doc.get("setup"));
6767
7221
  filled = (doc) => doc.getXmlFragment("default").length > 0 || doc.getMap("book").size > 0;
6768
7222
  pending = (doc) => doc.getMap("editors").size > 0;
6769
7223
  blocks2 = (fragment, schema) => {
@@ -6988,7 +7442,7 @@ var TextEditor_exports = {};
6988
7442
  __export(TextEditor_exports, {
6989
7443
  default: () => TextEditor
6990
7444
  });
6991
- function TextEditor({ kind, bytes, t, language, rights, host, together, documentId, onSaved, onOutline, onPanel, slot, guard }) {
7445
+ function TextEditor({ kind, bytes, t, language, rights, host, together, documentId, onSaved, onOutline, onReading, onPanel, slot, head: head2, file, guard }) {
6992
7446
  const docx2 = kind === "docx";
6993
7447
  const can = { edit: !!host?.save && !!rights?.edit, comment: !!host?.comment && !!rights && (rights.comment || rights.edit) };
6994
7448
  const source = useLoad(async () => {
@@ -7002,8 +7456,9 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7002
7456
  const baseline = (0, import_react10.useRef)(null);
7003
7457
  const anchors2 = (0, import_react10.useRef)(/* @__PURE__ */ new Map());
7004
7458
  const scroller = (0, import_react10.useRef)(null);
7005
- const [tab, setTab] = (0, import_react10.useState)(can.edit ? "home" : can.comment ? "review" : "view");
7459
+ const root = (0, import_react10.useRef)(null);
7006
7460
  const [pop, setPop] = (0, import_react10.useState)(null);
7461
+ const [more, setMore] = (0, import_react10.useState)(() => typeof localStorage !== "undefined" && localStorage.getItem("w100n-docs-more") === "1");
7007
7462
  const [zoom, setZoom] = (0, import_react10.useState)(null);
7008
7463
  const [layout2, setLayout] = (0, import_react10.useState)(null);
7009
7464
  const [room, setRoom] = (0, import_react10.useState)(0);
@@ -7020,6 +7475,14 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7020
7475
  const [editing, setEditing] = (0, import_react10.useState)(null);
7021
7476
  const [dropping, setDropping] = (0, import_react10.useState)(null);
7022
7477
  const [failed, setFailed] = (0, import_react10.useState)(false);
7478
+ const [paint2, setPaint] = (0, import_react10.useState)(null);
7479
+ const [query, setQuery] = (0, import_react10.useState)("");
7480
+ const [swap, setSwap] = (0, import_react10.useState)("");
7481
+ const [matchCase, setMatchCase] = (0, import_react10.useState)(false);
7482
+ const [count, setCount] = (0, import_react10.useState)({ words: 0, pages: 0 });
7483
+ const [marg, setMarg] = (0, import_react10.useState)(null);
7484
+ const [unsetup, setUnsetup] = (0, import_react10.useState)(false);
7485
+ const [draft2, setDraft2] = (0, import_react10.useState)(null);
7023
7486
  useRestore(pop !== null);
7024
7487
  useRestore(editing !== null);
7025
7488
  useRestore(dropping !== null);
@@ -7029,7 +7492,7 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7029
7492
  editable: can.edit && (!live || !!shared),
7030
7493
  immediatelyRender: true,
7031
7494
  shouldRerenderOnTransaction: false,
7032
- editorProps: { attributes: { class: "w100n-docs-prose w100n-text-body", "aria-label": t.documentText } },
7495
+ editorProps: { attributes: { class: "w100n-docs-prose w100n-text-body", "aria-label": t.documentText }, transformPastedHTML: cleanPaste },
7033
7496
  onCreate: ({ editor: made2 }) => {
7034
7497
  if (source.data && !live) baseline.current = { bytes, doc: made2.state.doc, base: source.data.md && track(source.data.md, made2.state.doc) };
7035
7498
  }
@@ -7055,6 +7518,15 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7055
7518
  link: e.isActive("link"),
7056
7519
  color: e.getAttributes("textStyle").color ?? null,
7057
7520
  glow: e.isActive("highlight"),
7521
+ font: e.getAttributes("textStyle").fontFamily ?? null,
7522
+ size: e.getAttributes("textStyle").fontSize ?? null,
7523
+ fill: e.getAttributes("tableCell").background ?? e.getAttributes("tableHeader").background ?? null,
7524
+ bare: e.getAttributes("table").borders === "none",
7525
+ sup: e.isActive("superscript"),
7526
+ sub: e.isActive("subscript"),
7527
+ img: e.isActive("image") ? e.getAttributes("image").wrap ?? "inline" : null,
7528
+ line: block2.attrs.line ?? null,
7529
+ after: block2.attrs.after ?? null,
7058
7530
  undo: e.can().undo(),
7059
7531
  redo: e.can().redo(),
7060
7532
  empty,
@@ -7065,6 +7537,7 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7065
7537
  });
7066
7538
  return at;
7067
7539
  })(),
7540
+ find: (({ at, hits }) => `${at}/${hits.length}`)(searching.getState(e.state)),
7068
7541
  suggest: !!suggesting.getState(e.state)?.on,
7069
7542
  revs: docx2 ? changes(e.state.doc) : [],
7070
7543
  dirty: !!baseline.current && !e.state.doc.eq(baseline.current.doc)
@@ -7072,9 +7545,43 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7072
7545
  }
7073
7546
  });
7074
7547
  const page = layout2 ?? source.data?.page ?? a4;
7548
+ const print = () => {
7549
+ if (!editor) return;
7550
+ const frame = document.createElement("iframe");
7551
+ frame.style.cssText = "position:fixed;width:0;height:0;border:0;opacity:0";
7552
+ document.body.append(frame);
7553
+ const [mt, mr, mb, ml] = page.margins;
7554
+ const size2 = docx2 ? `${page.width}px ${page.height}px` : "A4";
7555
+ frame.contentDocument.open();
7556
+ frame.contentDocument.write(`<!DOCTYPE html><html><head><meta charset="utf-8"><title>${editor.state.doc.firstChild?.textContent.slice(0, 80).replace(/[<&]/g, "") ?? ""}</title><style>
7557
+ @page { size: ${size2}; margin: ${docx2 ? `${mt}px ${mr}px ${mb}px ${ml}px` : "20mm"}; }
7558
+ body { margin: 0; font: 11pt/1.5 Arial, sans-serif; color: #111; }
7559
+ h1 { font-size: 20pt; } h2 { font-size: 15pt; } h3 { font-size: 13pt; }
7560
+ table { border-collapse: collapse; width: 100%; } td, th { border: 1px solid #94a3b8; padding: 4px 6px; vertical-align: top; } table[data-borders='none'] td, table[data-borders='none'] th { border-color: transparent; }
7561
+ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt 0; } img[data-wrap='right'] { float: right; margin: 0 0 6pt 12pt; }
7562
+ [data-type='page-break'], .page-break { break-after: page; height: 0; overflow: hidden; }
7563
+ </style></head><body>${editor.getHTML()}</body></html>`);
7564
+ frame.contentDocument.close();
7565
+ frame.contentWindow.focus();
7566
+ frame.contentWindow.print();
7567
+ setTimeout(() => frame.remove(), 1e3);
7568
+ };
7569
+ const marginal = marg ?? (source.data && "marginal" in source.data ? source.data.marginal : null) ?? { header: "", footer: "", numbers: false };
7570
+ (0, import_react10.useEffect)(() => {
7571
+ if (editor && docx2 && source.data) editor.view.dispatch(editor.state.tr.setMeta(paging, { page, marks: { header: marginal.header, footer: marginal.footer } }));
7572
+ }, [editor, source.data, page, marginal.header, marginal.footer]);
7075
7573
  (0, import_react10.useEffect)(() => {
7076
- if (editor && docx2 && source.data) editor.view.dispatch(editor.state.tr.setMeta(paging, { page }));
7077
- }, [editor, source.data, page]);
7574
+ if (!shared || !docx2) return;
7575
+ const map = shared.doc.getMap("setup");
7576
+ const sync = () => {
7577
+ const v = map.toJSON();
7578
+ if (v.page) setLayout(v.page);
7579
+ if (v.header !== void 0 || v.footer !== void 0 || v.numbers !== void 0) setMarg({ header: v.header ?? "", footer: v.footer ?? "", numbers: !!v.numbers });
7580
+ };
7581
+ sync();
7582
+ map.observe(sync);
7583
+ return () => map.unobserve(sync);
7584
+ }, [shared, docx2]);
7078
7585
  const loaded = useLoad((signal) => host?.comments ? host.comments(documentId, { signal }) : Promise.resolve([]), [host, documentId]);
7079
7586
  const all = [...loaded.data ?? [], ...added].flatMap((c) => c.id in changed2 ? changed2[c.id] ?? [] : [c]).filter((c) => !c.replyTo || changed2[c.replyTo] !== null);
7080
7587
  const open = all.filter((c) => !c.replyTo && !c.resolved);
@@ -7084,8 +7591,8 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7084
7591
  if (!editor || !source.data) return;
7085
7592
  const have = new Map(notes.getState(editor.state).spots.map((s) => [s.id, s]));
7086
7593
  const fresh2 = open.filter((c) => !have.has(c.id));
7087
- const found = locate(editor.state.doc, fresh2.map((c) => ({ id: c.id, quote: c.quote, anchor: anchors2.current.get(c.id) })));
7088
- editor.view.dispatch(editor.state.tr.setMeta(notes, { spots: [...open.flatMap((c) => have.get(c.id) ?? []), ...found] }));
7594
+ const found2 = locate(editor.state.doc, fresh2.map((c) => ({ id: c.id, quote: c.quote, anchor: anchors2.current.get(c.id) })));
7595
+ editor.view.dispatch(editor.state.tr.setMeta(notes, { spots: [...open.flatMap((c) => have.get(c.id) ?? []), ...found2] }));
7089
7596
  }, [editor, source.data, openIds]);
7090
7597
  (0, import_react10.useEffect)(() => {
7091
7598
  if (editor && source.data) editor.view.dispatch(editor.state.tr.setMeta(notes, { active }));
@@ -7103,6 +7610,8 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7103
7610
  editor.commands.setTextSelection(offset + 1);
7104
7611
  } });
7105
7612
  });
7613
+ const text = editor.state.doc.textBetween(0, editor.state.doc.content.size, " ", " ");
7614
+ setCount({ words: (text.match(/[\p{L}\p{N}]+(?:['’-][\p{L}\p{N}]+)*/gu) ?? []).length, pages: scroller.current?.querySelectorAll(".w100n-text-gap").length ?? 0 });
7106
7615
  const key2 = JSON.stringify(list.map((h) => [h.id, h.level, h.text]));
7107
7616
  if (key2 === last2) return;
7108
7617
  last2 = key2;
@@ -7119,7 +7628,35 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7119
7628
  editor.off("update", later);
7120
7629
  };
7121
7630
  }, [editor, source.data, onOutline]);
7122
- const dirty = live ? live.pending : !!state?.dirty;
7631
+ (0, import_react10.useEffect)(() => {
7632
+ const el = scroller.current;
7633
+ if (!el || !editor || !onReading) return;
7634
+ let frame = 0;
7635
+ let last2 = "";
7636
+ const look = () => {
7637
+ cancelAnimationFrame(frame);
7638
+ frame = requestAnimationFrame(() => {
7639
+ const line = el.getBoundingClientRect().top + el.clientHeight / 3;
7640
+ let id = null;
7641
+ editor.state.doc.forEach((node, offset) => {
7642
+ const dom = node.type.name === "heading" && node.textContent.trim() ? editor.view.nodeDOM(offset) : null;
7643
+ if (dom && dom.getBoundingClientRect().top <= line) id = `h${offset}`;
7644
+ });
7645
+ const room2 = el.scrollHeight - el.clientHeight;
7646
+ const progress = room2 > 0 ? Math.round(el.scrollTop / room2 * 100) / 100 : 1;
7647
+ if (`${id}:${progress}` === last2) return;
7648
+ last2 = `${id}:${progress}`;
7649
+ onReading({ documentId, id, progress });
7650
+ });
7651
+ };
7652
+ look();
7653
+ el.addEventListener("scroll", look, { passive: true });
7654
+ return () => {
7655
+ cancelAnimationFrame(frame);
7656
+ el.removeEventListener("scroll", look);
7657
+ };
7658
+ }, [editor, source.data, onReading, documentId]);
7659
+ const dirty = live ? live.pending : !!state?.dirty || unsetup;
7123
7660
  const unsent = live ? live.unsynced && can.edit : dirty;
7124
7661
  (0, import_react10.useEffect)(() => {
7125
7662
  if (!guard || live || !dirty || !source.data || !editor) return;
@@ -7128,6 +7665,11 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7128
7665
  guard.current = null;
7129
7666
  };
7130
7667
  });
7668
+ (0, import_react10.useEffect)(() => {
7669
+ if (live || !dirty || !can.edit || saving === "busy" || !editor) return;
7670
+ const timer = window.setTimeout(() => void save2(true), 3e3);
7671
+ return () => clearTimeout(timer);
7672
+ });
7131
7673
  (0, import_react10.useEffect)(() => {
7132
7674
  if (!unsent) return;
7133
7675
  const stop = (e) => e.preventDefault();
@@ -7141,6 +7683,30 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7141
7683
  watch.observe(el);
7142
7684
  return () => watch.disconnect();
7143
7685
  }, [editor, source.data]);
7686
+ (0, import_react10.useEffect)(() => {
7687
+ const el = root.current;
7688
+ if (!el) return;
7689
+ const open2 = () => {
7690
+ setPop("find");
7691
+ el.querySelector(".w100n-text-find input")?.focus();
7692
+ };
7693
+ el.addEventListener("docs-find", open2);
7694
+ return () => el.removeEventListener("docs-find", open2);
7695
+ }, [editor, source.data]);
7696
+ (0, import_react10.useEffect)(() => {
7697
+ const shown = pop === "find" ? query : "";
7698
+ if (editor && searching.getState(editor.state).query !== shown) editor.view.dispatch(editor.state.tr.setMeta(searching, { query: shown }));
7699
+ }, [editor, pop, query]);
7700
+ (0, import_react10.useEffect)(() => {
7701
+ const press = (e) => {
7702
+ if (!(e.metaKey || e.ctrlKey) || e.altKey || e.shiftKey || e.key.toLowerCase() !== "p") return;
7703
+ e.preventDefault();
7704
+ e.stopPropagation();
7705
+ print();
7706
+ };
7707
+ window.addEventListener("keydown", press, true);
7708
+ return () => window.removeEventListener("keydown", press, true);
7709
+ });
7144
7710
  (0, import_react10.useEffect)(() => {
7145
7711
  if (!pop) return;
7146
7712
  const close = (e) => {
@@ -7151,7 +7717,7 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7151
7717
  }, [pop]);
7152
7718
  if (source.error) return docx2 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-docs-scroll", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DocxView, { bytes, onOutline, failed: t.failed }) }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-docs-empty", children: t.failed });
7153
7719
  if (!source.data || !editor || !state || live && !live.ready && !live.late && !live.denied) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-docs-empty", children: t.loading });
7154
- const save2 = async () => {
7720
+ const save2 = async (auto = false) => {
7155
7721
  if (live) {
7156
7722
  if (!can.edit || !live.ready || !live.online || !live.pending || saving === "busy") return false;
7157
7723
  setSaving("busy");
@@ -7161,17 +7727,18 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7161
7727
  }
7162
7728
  const was = baseline.current;
7163
7729
  const doc = editor.state.doc;
7164
- if (!can.edit || !was || saving === "busy" || doc.eq(was.doc)) return false;
7730
+ if (!can.edit || !was || saving === "busy" || doc.eq(was.doc) && !unsetup) return false;
7165
7731
  setSaving("busy");
7166
7732
  try {
7167
7733
  const md = was.base && toMarkdown(doc, was.base);
7168
- const out = md ? new TextEncoder().encode(md.text).buffer : await writeDocx(was.bytes, editor.getJSON());
7169
- await host.save(documentId, out, t.editedNote);
7734
+ const out = md ? new TextEncoder().encode(md.text).buffer : await writeDocx(was.bytes, editor.getJSON(), void 0, unsetup ? { page, ...marginal } : void 0);
7735
+ await host.save(documentId, out, auto ? t.autosavedNote : t.editedNote, auto);
7170
7736
  baseline.current = { bytes: md ? out : was.bytes, doc, base: md ? md.base : null };
7171
7737
  if (!md && editor.state.doc === doc) {
7172
7738
  const fresh2 = (await readDocx(out)).doc;
7173
7739
  if (editor.state.doc === doc && renew(fresh2)) baseline.current = { bytes: out, doc: editor.state.doc, base: null };
7174
7740
  }
7741
+ setUnsetup(false);
7175
7742
  setSaving("done");
7176
7743
  onSaved?.();
7177
7744
  return true;
@@ -7199,7 +7766,6 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7199
7766
  };
7200
7767
  const linkUp = () => {
7201
7768
  setHref(editor.getAttributes("link").href ?? "");
7202
- setTab("insert");
7203
7769
  setPop("link");
7204
7770
  };
7205
7771
  const putLink = () => {
@@ -7300,20 +7866,22 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7300
7866
  const keys2 = (e) => {
7301
7867
  if (e.defaultPrevented) return;
7302
7868
  const key2 = e.key.toLowerCase();
7303
- const mod = e.metaKey || e.ctrlKey;
7304
- if (key2 === "escape" && (pop || draft)) {
7869
+ const mod2 = e.metaKey || e.ctrlKey;
7870
+ if (key2 === "escape" && (pop || draft || paint2)) {
7305
7871
  e.stopPropagation();
7306
- if (pop) setPop(null);
7872
+ if (paint2) setPaint(null);
7873
+ else if (pop) setPop(null);
7307
7874
  else drop2();
7308
7875
  return;
7309
7876
  }
7310
- if (!mod) return;
7877
+ if (!mod2) return;
7311
7878
  const act = (run2) => {
7312
7879
  e.preventDefault();
7313
7880
  run2();
7314
7881
  };
7315
7882
  if (key2 === "s" && can.edit) act(() => void save2());
7316
7883
  else if (key2 === "k" && can.edit) act(linkUp);
7884
+ else if (key2 === "f" && !e.altKey) act(() => setPop("find"));
7317
7885
  else if (key2 === "m" && e.altKey && can.comment) act(begin);
7318
7886
  else if (!can.edit || e.altKey) return;
7319
7887
  else if (key2 === "]" || key2 === "[") act(() => indent(editor, key2 === "]" ? 1 : -1));
@@ -7344,14 +7912,6 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7344
7912
  ["quote", named3((s) => /quote/i.test(s.name)) || t.quote, () => editor.chain().focus().clearNodes().setParagraph().setBlockquote().run()],
7345
7913
  ["code", t.code, () => editor.chain().focus().setCodeBlock().run()]
7346
7914
  ];
7347
- const tabs = [
7348
- ...can.edit ? [["home", t.home], ["insert", t.insert]] : [],
7349
- ...can.edit && docx2 ? [["layout", t.layout]] : [],
7350
- ...can.edit ? [["refs", t.references]] : [],
7351
- ...host?.comments && (can.comment || open.length > 0) ? [["review", t.review]] : [],
7352
- ["view", t.viewTab]
7353
- ];
7354
- const shown = tabs.some(([key2]) => key2 === tab) ? tab : "view";
7355
7915
  const margins = [[t.marginsNormal, [96, 96, 96, 96]], [t.marginsNarrow, [48, 48, 48, 48]], [t.marginsWide, [96, 192, 96, 192]]];
7356
7916
  const when = (iso) => new Intl.DateTimeFormat(language, { day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" }).format(new Date(iso));
7357
7917
  const person = (c) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("header", { children: [
@@ -7415,10 +7975,273 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7415
7975
  setPop(null);
7416
7976
  }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("i", { style: { background: c } }) }, i))
7417
7977
  ] });
7418
- let tools = null;
7419
- if (shown === "home") tools = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
7978
+ const mod = /Mac|iPhone|iPad/.test(navigator.platform) ? "\u2318" : "Ctrl+";
7979
+ const item = (label, run2, more2 = {}) => ({ label, run: run2, ...more2 });
7980
+ const insertToc = () => {
7981
+ const at = editor.state.selection.$from.before(1);
7982
+ editor.chain().focus().insertContentAt(at, { type: "toc", attrs: { entries: JSON.stringify(entries(editor.state.doc, !docx2, at - 1)) } }).run();
7983
+ };
7984
+ const suggest = () => editor.view.dispatch(editor.state.tr.setMeta(suggesting, { on: !state.suggest, me: host?.me.name ?? "" }));
7985
+ const aligns = [[import_lucide_react5.AlignLeft, t.alignLeft, "left"], [import_lucide_react5.AlignCenter, t.alignCenter, "center"], [import_lucide_react5.AlignRight, t.alignRight, "right"], [import_lucide_react5.AlignJustify, t.justify, "justify"]];
7986
+ const lines2 = [[1, t.single], [1.15, "1.15"], [1.5, "1.5"], [2, t.double]];
7987
+ const menus = [
7988
+ ["file", t.menuFile, [
7989
+ ...can.edit ? [
7990
+ item(t.save, () => void save2(), { keys: `${mod}S`, off: !dirty }),
7991
+ item(t.print, print, { keys: `${mod}P` }),
7992
+ ...docx2 ? ["-", item(t.pageSetup, () => setDraft2({ width: page.width, height: page.height, margins: page.margins.map(cm), ...marginal }))] : []
7993
+ ] : [],
7994
+ ...can.edit && (file?.formats.length || file?.copy || file?.rename) ? ["-"] : [],
7995
+ ...(file?.formats ?? []).map((f) => item(`${t.downloadAs} ${f === "md" ? "Markdown" : f.toUpperCase()}`, () => file.download(f))),
7996
+ !!file?.copy && item(t.makeCopy, file.copy),
7997
+ !!file?.rename && item(t.rename, file.rename)
7998
+ ]],
7999
+ ["edit", t.menuEdit, can.edit ? [
8000
+ item(t.undo, () => editor.chain().focus().undo().run(), { keys: `${mod}Z`, off: !state.undo }),
8001
+ item(t.redo, () => editor.chain().focus().redo().run(), { keys: `${mod}\u21E7Z`, off: !state.redo }),
8002
+ "-",
8003
+ item(t.findReplace, () => setPop("find"), { keys: `${mod}F` }),
8004
+ "-",
8005
+ item(t.clearFormat, () => clear(editor), { keys: `${mod}\\` })
8006
+ ] : []],
8007
+ ["view", t.viewTab, [
8008
+ item(t.zoomIn, () => zoomBy(10)),
8009
+ item(t.zoomOut, () => zoomBy(-10)),
8010
+ docx2 && item(t.fitWidth, () => setZoom(null), { on: zoom === null }),
8011
+ item(t.fit, () => setZoom(100)),
8012
+ "-",
8013
+ item(t.outline, () => onPanel?.("outline")),
8014
+ "-",
8015
+ item([docx2 && count.pages ? `${t.pages}: ${count.pages}` : "", `${t.words}: ${count.words.toLocaleString(language)}`].filter(Boolean).join(" \xB7 "), () => {
8016
+ }, { off: true })
8017
+ ]],
8018
+ ["insert", t.insert, can.edit ? [
8019
+ item(t.table, () => setPop("table")),
8020
+ item(t.image, () => {
8021
+ setHref("");
8022
+ setPop("image");
8023
+ }),
8024
+ item(t.link, linkUp, { keys: `${mod}K` }),
8025
+ docx2 && item(t.pageBreak, () => editor.chain().focus().insertContent({ type: "pageBreak" }).run(), { keys: `${mod}\u21B5` }),
8026
+ item(t.rule, () => editor.chain().focus().setHorizontalRule().run()),
8027
+ "-",
8028
+ state.toc < 0 ? item(t.tocInsert, insertToc) : item(t.tocRemove, () => editor.chain().focus().deleteRange({ from: state.toc, to: state.toc + editor.state.doc.nodeAt(state.toc).nodeSize }).run()),
8029
+ can.comment && item(t.addComment, begin, { off: state.empty, keys: `${mod}\u2325M` })
8030
+ ] : []],
8031
+ ["format", t.menuFormat, can.edit ? [
8032
+ ...styles2.map(([key2, label, run2]) => item(label, run2, { on: state.style === key2 })),
8033
+ "-",
8034
+ item(t.bold, () => editor.chain().focus().toggleBold().run(), { on: state.bold, keys: `${mod}B` }),
8035
+ item(t.italic, () => editor.chain().focus().toggleItalic().run(), { on: state.italic, keys: `${mod}I` }),
8036
+ docx2 && item(t.underline, () => editor.chain().focus().toggleUnderline().run(), { on: state.underline, keys: `${mod}U` }),
8037
+ item(t.strike, () => editor.chain().focus().toggleStrike().run(), { on: state.strike }),
8038
+ docx2 && item(t.superscript, () => editor.chain().focus().toggleMark("superscript").run(), { on: state.sup, keys: `${mod}.` }),
8039
+ docx2 && item(t.subscript, () => editor.chain().focus().toggleMark("subscript").run(), { on: state.sub, keys: `${mod},` }),
8040
+ ...docx2 ? [
8041
+ "-",
8042
+ ...aligns.map(([, label, value3]) => item(label, () => align2(editor, value3), { on: state.align === value3 })),
8043
+ "-",
8044
+ ...lines2.map(([v, label]) => item(`${t.lineSpacing}: ${label}`, () => spacing(editor, { line: v }), { on: state.line === v }))
8045
+ ] : [],
8046
+ "-",
8047
+ item(t.bullets, () => editor.chain().focus().toggleBulletList().run(), { on: state.bullets }),
8048
+ item(t.numbers, () => editor.chain().focus().toggleOrderedList().run(), { on: state.numbers }),
8049
+ item(t.tasks, () => editor.chain().focus().toggleTaskList().run(), { on: state.tasks }),
8050
+ "-",
8051
+ item(t.outdent, () => indent(editor, -1), { keys: `${mod}[` }),
8052
+ item(t.indent, () => indent(editor, 1), { keys: `${mod}]` })
8053
+ ] : []],
8054
+ ["tools", t.menuTools, [
8055
+ docx2 && can.edit && item(t.suggest, suggest, { on: state.suggest }),
8056
+ docx2 && can.edit && state.revs.length > 0 && item(t.acceptAll, () => decide(editor, true)),
8057
+ docx2 && can.edit && state.revs.length > 0 && item(t.rejectAll, () => decide(editor, false)),
8058
+ !!host?.comments && (can.comment || open.length > 0) && item(t.comments, () => onPanel?.("comments"))
8059
+ ]]
8060
+ ];
8061
+ const menu = ([key2, label, list]) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-anchor", children: [
8062
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "w100n-text-menu-button", "data-pop": true, "aria-haspopup": "menu", "aria-expanded": pop === key2, onClick: () => pick(key2), children: label }),
8063
+ pop === key2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-text-pop w100n-text-menu", role: "menu", "aria-label": label, children: list.filter((x) => x !== false).map((x, i) => x === "-" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("hr", {}, i) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", role: x.on === void 0 ? "menuitem" : "menuitemcheckbox", "aria-checked": x.on, disabled: x.off, onClick: () => {
8064
+ setPop(null);
8065
+ x.run();
8066
+ }, children: [
8067
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Check, { "aria-hidden": true }),
8068
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: x.label }),
8069
+ x.keys && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("kbd", { children: x.keys })
8070
+ ] }, i)) })
8071
+ ] }, key2);
8072
+ const seek = (next) => {
8073
+ editor.view.dispatch(editor.state.tr.setMeta(searching, next));
8074
+ const found2 = searching.getState(editor.state);
8075
+ const hit = found2.hits[found2.at];
8076
+ if (hit && next.at !== void 0) {
8077
+ editor.commands.setTextSelection(hit);
8078
+ editor.view.dom.querySelector(".w100n-found.is-current")?.scrollIntoView({ behavior: "smooth", block: "center" });
8079
+ }
8080
+ };
8081
+ const found = searching.getState(editor.state);
8082
+ const finder = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-anchor", children: [
8083
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "data-pop": true, "aria-expanded": pop === "find", "aria-label": t.findReplace, title: t.findReplace, onClick: () => pick("find"), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Search, { "aria-hidden": true }) }),
8084
+ pop === "find" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-pop w100n-text-find", role: "search", "aria-label": t.findReplace, children: [
8085
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-docs-row", children: [
8086
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
8087
+ "input",
8088
+ {
8089
+ autoFocus: true,
8090
+ value: query,
8091
+ placeholder: t.find,
8092
+ "aria-label": t.find,
8093
+ onFocus: (e) => e.currentTarget.select(),
8094
+ onChange: (e) => {
8095
+ setQuery(e.target.value);
8096
+ seek({ query: e.target.value, at: 0 });
8097
+ },
8098
+ onKeyDown: (e) => {
8099
+ if (e.key === "Enter") {
8100
+ e.preventDefault();
8101
+ seek({ at: (found?.at ?? 0) + (e.shiftKey ? -1 : 1) });
8102
+ }
8103
+ }
8104
+ }
8105
+ ),
8106
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("small", { "aria-live": "polite", children: query ? found?.hits.length ? `${(found.at ?? 0) + 1} / ${found.hits.length}` : t.noHits : "" }),
8107
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "aria-label": t.previous, title: t.previous, disabled: !found?.hits.length, onClick: () => seek({ at: found.at - 1 }), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.ChevronUp, { "aria-hidden": true }) }),
8108
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "aria-label": t.next, title: t.next, disabled: !found?.hits.length, onClick: () => seek({ at: found.at + 1 }), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.ChevronDown, { "aria-hidden": true }) })
8109
+ ] }),
8110
+ can.edit && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-docs-row", children: [
8111
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { value: swap, placeholder: t.replaceWith, "aria-label": t.replaceWith, onChange: (e) => setSwap(e.target.value) }),
8112
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "w100n-pdf-link", disabled: !found?.hits.length, onClick: () => {
8113
+ replace(editor, swap, false);
8114
+ seek({});
8115
+ }, children: t.replaceOne }),
8116
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "w100n-docs-action", disabled: !found?.hits.length, onClick: () => {
8117
+ replace(editor, swap, true);
8118
+ seek({});
8119
+ }, children: t.replaceAll })
8120
+ ] }),
8121
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "w100n-setup-check", children: [
8122
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "checkbox", checked: matchCase, onChange: (e) => {
8123
+ setMatchCase(e.target.checked);
8124
+ seek({ matchCase: e.target.checked, at: 0 });
8125
+ } }),
8126
+ t.matchCase
8127
+ ] })
8128
+ ] })
8129
+ ] });
8130
+ const formats = ["bold", "italic", "underline", "strike", "code", "highlight", "textStyle", "superscript", "subscript"];
8131
+ const take = (keep2) => {
8132
+ if (paint2 && !keep2) return setPaint(null);
8133
+ const { $from } = editor.state.selection;
8134
+ const marks2 = (editor.state.storedMarks ?? $from.marks()).filter((m) => formats.includes(m.type.name)).map((m) => ({ type: m.type.name, attrs: m.attrs }));
8135
+ setPaint({ marks: marks2, block: { align: $from.parent.attrs.align, line: $from.parent.attrs.line, after: $from.parent.attrs.after }, keep: keep2 });
8136
+ };
8137
+ const lay = () => {
8138
+ if (!paint2 || editor.state.selection.empty) return;
8139
+ const chain = editor.chain().focus();
8140
+ for (const name of formats) chain.unsetMark(name);
8141
+ for (const m of paint2.marks) chain.setMark(m.type, m.attrs);
8142
+ chain.run();
8143
+ align2(editor, paint2.block.align);
8144
+ spacing(editor, { line: paint2.block.line, after: paint2.block.after });
8145
+ if (!paint2.keep) setPaint(null);
8146
+ };
8147
+ const fontPicker = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-anchor", children: [
8148
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-text-picker", "data-size": "mid", "data-pop": true, "aria-haspopup": "listbox", "aria-expanded": pop === "font", "aria-label": t.font, title: t.font, onClick: () => pick("font"), children: [
8149
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { fontFamily: state.font ?? void 0 }, children: state.font ?? t.defaultFont }),
8150
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.ChevronDown, { "aria-hidden": true })
8151
+ ] }),
8152
+ pop === "font" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-pop w100n-text-styles", role: "listbox", "aria-label": t.font, children: [
8153
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", role: "option", "aria-selected": !state.font, onClick: () => {
8154
+ editor.chain().focus().unsetFontFamily().run();
8155
+ setPop(null);
8156
+ }, children: t.defaultFont }),
8157
+ faces.map((f) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", role: "option", "aria-selected": state.font === f, style: { fontFamily: f }, onClick: () => {
8158
+ editor.chain().focus().setFontFamily(f).run();
8159
+ setPop(null);
8160
+ }, children: f }, f))
8161
+ ] })
8162
+ ] });
8163
+ const sizePicker = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-anchor", children: [
8164
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-text-picker", "data-size": "small", "data-pop": true, "aria-haspopup": "listbox", "aria-expanded": pop === "size", "aria-label": t.fontSize, title: t.fontSize, onClick: () => pick("size"), children: [
8165
+ state.size ? parseFloat(state.size) : t.defaultFont,
8166
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.ChevronDown, { "aria-hidden": true })
8167
+ ] }),
8168
+ pop === "size" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-pop w100n-text-styles", role: "listbox", "aria-label": t.fontSize, children: [
8169
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", role: "option", "aria-selected": !state.size, onClick: () => {
8170
+ editor.chain().focus().unsetFontSize().run();
8171
+ setPop(null);
8172
+ }, children: t.defaultFont }),
8173
+ sizes.map((n) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", role: "option", "aria-selected": state.size !== null && parseFloat(state.size) === n, onClick: () => {
8174
+ editor.chain().focus().setFontSize(`${n}pt`).run();
8175
+ setPop(null);
8176
+ }, children: n }, n))
8177
+ ] })
8178
+ ] });
8179
+ const spacer = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-anchor", children: [
8180
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "data-pop": true, "aria-expanded": pop === "spacing", "aria-label": t.lineSpacing, title: t.lineSpacing, onClick: () => pick("spacing"), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.UnfoldVertical, { "aria-hidden": true }) }),
8181
+ pop === "spacing" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-pop w100n-text-styles", role: "listbox", "aria-label": t.lineSpacing, children: [
8182
+ lines2.map(([v, label]) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", role: "option", "aria-selected": state.line === v, onClick: () => {
8183
+ spacing(editor, { line: v });
8184
+ setPop(null);
8185
+ }, children: label }, v)),
8186
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("hr", {}),
8187
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", role: "option", "aria-selected": false, onClick: () => {
8188
+ spacing(editor, { after: state.after === 0 ? 8 : 0 });
8189
+ setPop(null);
8190
+ }, children: state.after === 0 ? t.spaceAfter : t.noSpaceAfter })
8191
+ ] })
8192
+ ] });
8193
+ const applySetup = () => {
8194
+ const d = draft2;
8195
+ const next = { width: d.width, height: d.height, margins: d.margins.map((v) => Math.round(v / 2.54 * 96 * 100) / 100) };
8196
+ const marks2 = { header: d.header.trim(), footer: d.footer.trim(), numbers: d.numbers };
8197
+ if (shared) shared.doc.transact(() => {
8198
+ const map = shared.doc.getMap("setup");
8199
+ map.set("page", next);
8200
+ for (const [key2, v] of Object.entries(marks2)) map.set(key2, v);
8201
+ });
8202
+ else {
8203
+ setLayout(next);
8204
+ setMarg(marks2);
8205
+ setUnsetup(true);
8206
+ }
8207
+ setDraft2(null);
8208
+ };
8209
+ const zooms = [50, 75, 90, 100, 125, 150, 200];
8210
+ const zoomer = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-anchor", children: [
8211
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-text-picker", "data-size": "small", "data-pop": true, "aria-haspopup": "listbox", "aria-expanded": pop === "zoom", "aria-label": t.zoom, title: t.zoom, onClick: () => pick("zoom"), children: [
8212
+ percent,
8213
+ "%",
8214
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.ChevronDown, { "aria-hidden": true })
8215
+ ] }),
8216
+ pop === "zoom" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-pop w100n-text-styles", role: "listbox", "aria-label": t.zoom, children: [
8217
+ docx2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", role: "option", "aria-selected": zoom === null, onClick: () => {
8218
+ setZoom(null);
8219
+ setPop(null);
8220
+ }, children: t.fitWidth }),
8221
+ zooms.map((z) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", role: "option", "aria-selected": zoom === z, onClick: () => {
8222
+ setZoom(z);
8223
+ setPop(null);
8224
+ }, children: [
8225
+ z,
8226
+ "%"
8227
+ ] }, z))
8228
+ ] })
8229
+ ] });
8230
+ const Aligned = aligns.find(([, , value3]) => value3 === state.align)?.[0] ?? import_lucide_react5.AlignLeft;
8231
+ const aligner = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-anchor", children: [
8232
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "data-pop": true, "aria-expanded": pop === "align", "aria-label": t.align, title: t.align, onClick: () => pick("align"), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Aligned, { "aria-hidden": true }) }),
8233
+ pop === "align" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-text-pop", role: "group", "aria-label": t.align, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-text-tools", children: aligns.map(([icon, label, value3], i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react10.Fragment, { children: tool(icon, label, () => {
8234
+ align2(editor, value3);
8235
+ setPop(null);
8236
+ }, state.align === value3) }, i)) }) })
8237
+ ] });
8238
+ const widen = () => {
8239
+ localStorage.setItem("w100n-docs-more", more ? "" : "1");
8240
+ setMore(!more);
8241
+ };
8242
+ const main = can.edit ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
7420
8243
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-anchor", children: [
7421
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-text-picker", "data-pop": true, "aria-haspopup": "listbox", "aria-expanded": pop === "style", "aria-label": t.paragraphStyle, title: t.paragraphStyle, onClick: () => pick("style"), children: [
8244
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-text-picker", "data-size": "mid", "data-pop": true, "aria-haspopup": "listbox", "aria-expanded": pop === "style", "aria-label": t.paragraphStyle, title: t.paragraphStyle, onClick: () => pick("style"), children: [
7422
8245
  styles2.find(([key2]) => key2 === state.style)?.[1] ?? t.normal,
7423
8246
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.ChevronDown, { "aria-hidden": true })
7424
8247
  ] }),
@@ -7441,8 +8264,7 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7441
8264
  gap,
7442
8265
  tool(import_lucide_react5.Bold, t.bold, () => editor.chain().focus().toggleBold().run(), state.bold),
7443
8266
  tool(import_lucide_react5.Italic, t.italic, () => editor.chain().focus().toggleItalic().run(), state.italic),
7444
- docx2 && tool(import_lucide_react5.Underline, t.underline, () => editor.chain().focus().toggleUnderline().run(), state.underline),
7445
- tool(import_lucide_react5.Strikethrough, t.strike, () => editor.chain().focus().toggleStrike().run(), state.strike),
8267
+ docx2 ? tool(import_lucide_react5.Underline, t.underline, () => editor.chain().focus().toggleUnderline().run(), state.underline) : tool(import_lucide_react5.Strikethrough, t.strike, () => editor.chain().focus().toggleStrike().run(), state.strike),
7446
8268
  !docx2 && tool(import_lucide_react5.Code, t.code, () => editor.chain().focus().toggleCode().run(), state.code),
7447
8269
  docx2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-anchor", children: [
7448
8270
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", "data-pop": true, "aria-expanded": pop === "color", "aria-label": t.textColour, title: t.textColour, onClick: () => pick("color"), children: [
@@ -7451,60 +8273,34 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7451
8273
  ] }),
7452
8274
  pop === "color" && swatches(inks, state.color, (c) => c ? editor.chain().focus().setColor(c).run() : editor.chain().focus().unsetColor().run(), t.automatic)
7453
8275
  ] }),
7454
- docx2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-anchor", children: [
7455
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "data-pop": true, "aria-expanded": pop === "mark", "aria-pressed": state.glow, "aria-label": t.highlight, title: t.highlight, onClick: () => pick("mark"), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Highlighter, { "aria-hidden": true }) }),
7456
- pop === "mark" && swatches(glows, null, (c) => c ? editor.chain().focus().setHighlight({ color: c }).run() : editor.chain().focus().unsetHighlight().run(), t.noColour)
7457
- ] }),
7458
8276
  gap,
8277
+ docx2 && aligner,
7459
8278
  tool(import_lucide_react5.List, t.bullets, () => editor.chain().focus().toggleBulletList().run(), state.bullets),
7460
8279
  tool(import_lucide_react5.ListOrdered, t.numbers, () => editor.chain().focus().toggleOrderedList().run(), state.numbers),
7461
- tool(import_lucide_react5.ListChecks, t.tasks, () => editor.chain().focus().toggleTaskList().run(), state.tasks),
7462
- docx2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
7463
- gap,
7464
- [[import_lucide_react5.AlignLeft, t.alignLeft, "left"], [import_lucide_react5.AlignCenter, t.alignCenter, "center"], [import_lucide_react5.AlignRight, t.alignRight, "right"], [import_lucide_react5.AlignJustify, t.justify, "justify"]].map(([icon, label, value3], i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react10.Fragment, { children: tool(icon, label, () => align2(editor, value3), state.align === value3) }, i))
7465
- ] }),
8280
+ !docx2 && tool(import_lucide_react5.ListChecks, t.tasks, () => editor.chain().focus().toggleTaskList().run(), state.tasks),
7466
8281
  gap,
7467
- tool(import_lucide_react5.ListIndentDecrease, t.outdent, () => indent(editor, -1)),
7468
- tool(import_lucide_react5.ListIndentIncrease, t.indent, () => indent(editor, 1)),
7469
- tool(import_lucide_react5.RemoveFormatting, t.clearFormat, () => clear(editor))
7470
- ] });
7471
- else if (shown === "insert") tools = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
7472
8282
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-anchor", children: [
7473
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "data-pop": true, "aria-expanded": pop === "table", "aria-label": t.table, title: t.table, onClick: () => pick("table"), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Table, { "aria-hidden": true }) }),
7474
- pop === "table" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-pop w100n-text-grid", role: "group", "aria-label": t.table, onPointerLeave: () => setGrid({ rows: 0, cols: 0 }), children: [
7475
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: Array.from({ length: 48 }, (_, i) => {
7476
- const rows = Math.floor(i / 8) + 1;
7477
- const cols = i % 8 + 1;
7478
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
7479
- "button",
7480
- {
7481
- type: "button",
7482
- "aria-label": `${rows} \xD7 ${cols}`,
7483
- "data-on": rows <= grid3.rows && cols <= grid3.cols,
7484
- onPointerEnter: () => setGrid({ rows, cols }),
7485
- onClick: () => {
7486
- editor.chain().focus().insertTable({ rows, cols, withHeaderRow: true }).run();
7487
- setPop(null);
7488
- }
7489
- },
7490
- i
7491
- );
7492
- }) }),
7493
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("small", { children: grid3.rows ? `${grid3.rows} \xD7 ${grid3.cols}` : t.table })
8283
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "data-pop": true, "aria-expanded": pop === "link", "aria-pressed": state.link, "aria-label": t.link, title: t.link, onClick: () => pop === "link" ? setPop(null) : linkUp(), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Link, { "aria-hidden": true }) }),
8284
+ pop === "link" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-pop w100n-text-form", children: [
8285
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { autoFocus: true, value: href, placeholder: t.linkAddress, "aria-label": t.linkAddress, onChange: (e) => setHref(e.target.value), onKeyDown: (e) => {
8286
+ if (e.key === "Enter") putLink();
8287
+ } }),
8288
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-docs-row", children: [
8289
+ state.link && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-pdf-link", onClick: () => {
8290
+ editor.chain().focus().extendMarkRange("link").unsetLink().run();
8291
+ setPop(null);
8292
+ }, children: [
8293
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Link2Off, { "aria-hidden": true }),
8294
+ t.unlink
8295
+ ] }),
8296
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-docs-action", disabled: !href.trim(), onClick: putLink, children: [
8297
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Link, { "aria-hidden": true }),
8298
+ t.apply
8299
+ ] })
8300
+ ] })
7494
8301
  ] })
7495
8302
  ] }),
7496
- state.table && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
7497
- tool(import_lucide_react5.BetweenHorizontalStart, t.rowAbove, () => editor.chain().focus().addRowBefore().run()),
7498
- tool(import_lucide_react5.BetweenHorizontalEnd, t.rowBelow, () => editor.chain().focus().addRowAfter().run()),
7499
- tool(import_lucide_react5.BetweenVerticalStart, t.columnLeft, () => editor.chain().focus().addColumnBefore().run()),
7500
- tool(import_lucide_react5.BetweenVerticalEnd, t.columnRight, () => editor.chain().focus().addColumnAfter().run()),
7501
- tool(import_lucide_react5.PanelTop, t.headerRow, () => editor.chain().focus().toggleHeaderRow().run()),
7502
- docx2 && tool(import_lucide_react5.TableCellsMerge, t.mergeCells, () => editor.chain().focus().mergeOrSplit().run()),
7503
- tool(import_lucide_react5.TableRowsSplit, t.deleteRow, () => editor.chain().focus().deleteRow().run()),
7504
- tool(import_lucide_react5.TableColumnsSplit, t.deleteColumn, () => editor.chain().focus().deleteColumn().run()),
7505
- tool(import_lucide_react5.Trash2, t.deleteTable, () => editor.chain().focus().deleteTable().run())
7506
- ] }),
7507
- gap,
8303
+ can.comment && tool(import_lucide_react5.MessageSquarePlus, t.addComment, begin, void 0, state.empty),
7508
8304
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-anchor", children: [
7509
8305
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "data-pop": true, "aria-expanded": pop === "image", "aria-label": t.image, title: t.image, onClick: () => {
7510
8306
  setHref("");
@@ -7531,14 +8327,14 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7531
8327
  docx2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "w100n-pdf-link", children: [
7532
8328
  t.chooseFile,
7533
8329
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "file", accept: "image/png,image/jpeg,image/gif", hidden: true, onChange: (e) => {
7534
- const file = e.target.files?.[0];
7535
- if (!file) return;
8330
+ const file2 = e.target.files?.[0];
8331
+ if (!file2) return;
7536
8332
  const reader = new FileReader();
7537
8333
  reader.onload = () => {
7538
- editor.chain().focus().setImage({ src: String(reader.result), alt: file.name }).run();
8334
+ editor.chain().focus().setImage({ src: String(reader.result), alt: file2.name }).run();
7539
8335
  setPop(null);
7540
8336
  };
7541
- reader.readAsDataURL(file);
8337
+ reader.readAsDataURL(file2);
7542
8338
  } })
7543
8339
  ] }),
7544
8340
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-docs-action", disabled: !href.trim(), onClick: () => {
@@ -7552,162 +8348,215 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7552
8348
  ] })
7553
8349
  ] }),
7554
8350
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-anchor", children: [
7555
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "data-pop": true, "aria-expanded": pop === "link", "aria-pressed": state.link, "aria-label": t.link, title: t.link, onClick: () => pop === "link" ? setPop(null) : linkUp(), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Link, { "aria-hidden": true }) }),
7556
- pop === "link" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-pop w100n-text-form", children: [
7557
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { autoFocus: true, value: href, placeholder: t.linkAddress, "aria-label": t.linkAddress, onChange: (e) => setHref(e.target.value), onKeyDown: (e) => {
7558
- if (e.key === "Enter") putLink();
7559
- } }),
7560
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-docs-row", children: [
7561
- state.link && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-pdf-link", onClick: () => {
7562
- editor.chain().focus().extendMarkRange("link").unsetLink().run();
7563
- setPop(null);
7564
- }, children: [
7565
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Link2Off, { "aria-hidden": true }),
7566
- t.unlink
7567
- ] }),
7568
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-docs-action", disabled: !href.trim(), onClick: putLink, children: [
7569
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Link, { "aria-hidden": true }),
7570
- t.apply
7571
- ] })
7572
- ] })
8351
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "data-pop": true, "aria-expanded": pop === "table", "aria-label": t.table, title: t.table, onClick: () => pick("table"), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Table, { "aria-hidden": true }) }),
8352
+ pop === "table" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-pop w100n-text-grid", role: "group", "aria-label": t.table, onPointerLeave: () => setGrid({ rows: 0, cols: 0 }), children: [
8353
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: Array.from({ length: 48 }, (_, i) => {
8354
+ const rows = Math.floor(i / 8) + 1;
8355
+ const cols = i % 8 + 1;
8356
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
8357
+ "button",
8358
+ {
8359
+ type: "button",
8360
+ "aria-label": `${rows} \xD7 ${cols}`,
8361
+ "data-on": rows <= grid3.rows && cols <= grid3.cols,
8362
+ onPointerEnter: () => setGrid({ rows, cols }),
8363
+ onClick: () => {
8364
+ editor.chain().focus().insertTable({ rows, cols, withHeaderRow: true }).run();
8365
+ setPop(null);
8366
+ }
8367
+ },
8368
+ i
8369
+ );
8370
+ }) }),
8371
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("small", { children: grid3.rows ? `${grid3.rows} \xD7 ${grid3.cols}` : t.table })
7573
8372
  ] })
7574
8373
  ] }),
7575
- docx2 && tool(import_lucide_react5.SeparatorHorizontal, t.pageBreak, () => editor.chain().focus().insertContent({ type: "pageBreak" }).run()),
7576
- tool(import_lucide_react5.Minus, t.rule, () => editor.chain().focus().setHorizontalRule().run())
7577
- ] });
7578
- else if (shown === "layout") tools = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
7579
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-text-label", children: t.pageSize }),
7580
- [["A4", a4], ["Letter", letter]].map(([label, size2], i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
7581
- "button",
7582
- {
7583
- type: "button",
7584
- className: "w100n-text-word",
7585
- "aria-pressed": Math.abs(page.width - size2.width) < 2 && Math.abs(page.height - size2.height) < 2,
7586
- onClick: () => setLayout({ ...page, width: size2.width, height: size2.height }),
7587
- children: label
7588
- },
7589
- i
7590
- )),
7591
8374
  gap,
7592
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-text-label", children: t.margins }),
7593
- margins.map(([label, values], i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
7594
- "button",
7595
- {
7596
- type: "button",
7597
- className: "w100n-text-word",
7598
- "aria-pressed": values.every((v, n) => Math.abs(page.margins[n] - v) < 2),
7599
- onClick: () => setLayout({ ...page, margins: values }),
7600
- children: label
7601
- },
7602
- i
7603
- ))
7604
- ] });
7605
- else if (shown === "refs") tools = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
7606
- state.toc < 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-docs-action", onClick: () => {
7607
- const at = editor.state.selection.$from.before(1);
7608
- editor.chain().focus().insertContentAt(at, { type: "toc", attrs: { entries: JSON.stringify(entries(editor.state.doc, !docx2, at - 1)) } }).run();
7609
- }, children: [
7610
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.TableOfContents, { "aria-hidden": true }),
7611
- t.tocInsert
7612
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
7613
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-text-word", onClick: () => editor.view.nodeDOM(state.toc)?.scrollIntoView({ behavior: "smooth", block: "start" }), children: [
7614
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.TableOfContents, { "aria-hidden": true }),
7615
- t.tocGo
7616
- ] }),
7617
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-docs-action", "data-tone": "red", onClick: () => editor.chain().focus().deleteRange({ from: state.toc, to: state.toc + editor.state.doc.nodeAt(state.toc).nodeSize }).run(), children: [
7618
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Trash2, { "aria-hidden": true }),
7619
- t.tocRemove
7620
- ] })
7621
- ] }),
7622
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-text-label", children: t.tocHint })
7623
- ] });
7624
- else if (shown === "review") tools = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
7625
- can.comment && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-docs-action", disabled: state.empty, onClick: begin, children: [
7626
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.MessageSquarePlus, { "aria-hidden": true }),
7627
- t.addComment
8375
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "aria-expanded": more, "aria-label": more ? t.fewerTools : t.moreTools, title: more ? t.fewerTools : t.moreTools, onClick: widen, children: more ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.ChevronDown, { "aria-hidden": true }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.ChevronUp, { "aria-hidden": true }) })
8376
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
8377
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-text-word", onClick: () => onPanel?.("outline"), children: [
8378
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.ListTree, { "aria-hidden": true }),
8379
+ t.outline
7628
8380
  ] }),
7629
- docx2 && can.edit && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
7630
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
7631
- "button",
7632
- {
7633
- type: "button",
7634
- className: "w100n-text-word",
7635
- "aria-pressed": state.suggest,
7636
- onClick: () => editor.view.dispatch(editor.state.tr.setMeta(suggesting, { on: !state.suggest, me: host?.me.name ?? "" })),
7637
- children: [
7638
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.FilePenLine, { "aria-hidden": true }),
7639
- t.suggest
7640
- ]
7641
- }
7642
- ),
7643
- state.revs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
7644
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-docs-action", "data-tone": "green", onClick: () => decide(editor, true), children: [
7645
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.CheckCheck, { "aria-hidden": true }),
7646
- t.acceptAll
7647
- ] }),
7648
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-docs-action", "data-tone": "red", onClick: () => decide(editor, false), children: [
7649
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.X, { "aria-hidden": true }),
7650
- t.rejectAll
7651
- ] })
8381
+ can.comment && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
8382
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-text-grow" }),
8383
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-docs-action", disabled: state.empty, onClick: begin, children: [
8384
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.MessageSquarePlus, { "aria-hidden": true }),
8385
+ t.addComment
7652
8386
  ] })
7653
8387
  ] }),
7654
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-text-word", onClick: () => onPanel?.("comments"), children: [
8388
+ !!host?.comments && (can.comment || open.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-text-word", onClick: () => onPanel?.("comments"), children: [
7655
8389
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.MessagesSquare, { "aria-hidden": true }),
7656
8390
  t.comments,
7657
8391
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("b", { children: open.length })
7658
8392
  ] })
7659
8393
  ] });
7660
- else tools = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
7661
- tool(import_lucide_react5.Minus, t.zoomOut, () => zoomBy(-10)),
7662
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-pdf-zoom", children: [
7663
- percent,
7664
- "%"
8394
+ const extra = can.edit && more && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
8395
+ docx2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
8396
+ fontPicker,
8397
+ sizePicker,
8398
+ gap
8399
+ ] }),
8400
+ docx2 && tool(import_lucide_react5.Strikethrough, t.strike, () => editor.chain().focus().toggleStrike().run(), state.strike),
8401
+ docx2 && tool(import_lucide_react5.Superscript, t.superscript, () => editor.chain().focus().toggleMark("superscript").run(), state.sup),
8402
+ docx2 && tool(import_lucide_react5.Subscript, t.subscript, () => editor.chain().focus().toggleMark("subscript").run(), state.sub),
8403
+ docx2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-anchor", children: [
8404
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "data-pop": true, "aria-expanded": pop === "mark", "aria-pressed": state.glow, "aria-label": t.highlight, title: t.highlight, onClick: () => pick("mark"), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Highlighter, { "aria-hidden": true }) }),
8405
+ pop === "mark" && swatches(glows, null, (c) => c ? editor.chain().focus().setHighlight({ color: c }).run() : editor.chain().focus().unsetHighlight().run(), t.noColour)
7665
8406
  ] }),
7666
- tool(import_lucide_react5.Plus, t.zoomIn, () => zoomBy(10)),
7667
- docx2 && tool(import_lucide_react5.MoveHorizontal, t.fitWidth, () => setZoom(null), zoom === null),
7668
- tool(import_lucide_react5.Maximize2, t.fit, () => setZoom(100)),
8407
+ docx2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
8408
+ gap,
8409
+ spacer
8410
+ ] }),
8411
+ tool(import_lucide_react5.ListIndentDecrease, t.outdent, () => indent(editor, -1)),
8412
+ tool(import_lucide_react5.ListIndentIncrease, t.indent, () => indent(editor, 1)),
8413
+ docx2 && tool(import_lucide_react5.ListChecks, t.tasks, () => editor.chain().focus().toggleTaskList().run(), state.tasks),
7669
8414
  gap,
7670
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-text-word", onClick: () => onPanel?.("outline"), children: [
7671
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.ListTree, { "aria-hidden": true }),
7672
- t.outline
8415
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "aria-label": t.painter, title: paint2 ? t.painterHint : t.painter, "aria-pressed": !!paint2, onClick: () => take(false), onDoubleClick: () => take(true), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.PaintRoller, { "aria-hidden": true }) }),
8416
+ tool(import_lucide_react5.RemoveFormatting, t.clearFormat, () => clear(editor)),
8417
+ docx2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
8418
+ gap,
8419
+ tool(import_lucide_react5.FilePenLine, t.suggest, suggest, state.suggest)
7673
8420
  ] })
7674
8421
  ] });
7675
- const sheet2 = docx2 ? { "--page-w": `${page.width}px`, "--page-h": `${page.height}px`, "--mt": `${page.margins[0]}px`, "--mr": `${page.margins[1]}px`, "--mb": `${page.margins[2]}px`, "--ml": `${page.margins[3]}px` } : void 0;
7676
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-text", "data-kind": kind, onKeyDown: keys2, children: [
7677
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-text-ribbon", role: "toolbar", "aria-label": t.textTools, onKeyDown: rove, onPointerDown: (e) => {
7678
- if (e.target.closest("button")) e.preventDefault();
7679
- }, children: [
7680
- (tabs.length > 1 || live) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-text-tabs", children: [
7681
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { role: "tablist", "aria-label": t.textTools, children: tabs.length > 1 && tabs.map(([key2, label]) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", role: "tab", "aria-selected": shown === key2, onClick: () => {
7682
- setTab(key2);
7683
- setPop(null);
7684
- }, children: label }, key2)) }),
7685
- (can.edit || live) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-end", children: [
7686
- live && (live.ready ? !live.online : live.late || live.denied) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-live", title: live.denied ? void 0 : t.offlineHint, children: [
7687
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.WifiOff, { "aria-hidden": true }),
7688
- live.denied ? t.liveOff : t.offline
7689
- ] }),
7690
- live && live.people.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-text-people", role: "group", "aria-label": t.people, children: live.people.map((p) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-text-face", title: p.me ? `${p.name} (${t.you})` : p.name, style: { "--face": p.color }, children: p.avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("img", { src: p.avatarUrl, alt: "" }) : p.name.slice(0, 1).toUpperCase() }, p.id)) }),
7691
- state.suggest && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-docs-badge", children: t.suggesting }),
7692
- can.edit && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
7693
- tool(import_lucide_react5.Undo2, t.undo, () => editor.chain().focus().undo().run(), void 0, !state.undo),
7694
- tool(import_lucide_react5.Redo2, t.redo, () => editor.chain().focus().redo().run(), void 0, !state.redo),
7695
- saving === "failed" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-docs-muted", children: t.saveFailed }),
7696
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-docs-action", disabled: !dirty || saving === "busy" || !!live && !live.online, onClick: () => void save2(), children: [
7697
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Save, { "aria-hidden": true }),
7698
- saving === "busy" ? t.saving : !dirty && saving === "done" ? t.saved : t.save
7699
- ] })
7700
- ] })
7701
- ] })
8422
+ const context = can.edit && (state.table ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
8423
+ tool(import_lucide_react5.BetweenHorizontalStart, t.rowAbove, () => editor.chain().focus().addRowBefore().run()),
8424
+ tool(import_lucide_react5.BetweenHorizontalEnd, t.rowBelow, () => editor.chain().focus().addRowAfter().run()),
8425
+ tool(import_lucide_react5.BetweenVerticalStart, t.columnLeft, () => editor.chain().focus().addColumnBefore().run()),
8426
+ tool(import_lucide_react5.BetweenVerticalEnd, t.columnRight, () => editor.chain().focus().addColumnAfter().run()),
8427
+ tool(import_lucide_react5.PanelTop, t.headerRow, () => editor.chain().focus().toggleHeaderRow().run()),
8428
+ docx2 && tool(import_lucide_react5.TableCellsMerge, t.mergeCells, () => editor.chain().focus().mergeOrSplit().run()),
8429
+ docx2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-anchor", children: [
8430
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", "data-pop": true, "aria-expanded": pop === "fill", "aria-label": t.cellFill, title: t.cellFill, onClick: () => pick("fill"), children: [
8431
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.PaintBucket, { "aria-hidden": true }),
8432
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("i", { className: "w100n-text-bar", style: { background: state.fill ?? "transparent" } })
7702
8433
  ] }),
7703
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-text-tools", role: "group", "aria-label": tabs.find(([key2]) => key2 === shown)?.[1], children: tools })
8434
+ pop === "fill" && swatches(glows, state.fill, (c) => editor.chain().focus().setCellAttribute("background", c).run(), t.noColour)
8435
+ ] }),
8436
+ docx2 && tool(import_lucide_react5.Grid3x3, t.tableBorders, () => editor.chain().focus().updateAttributes("table", { borders: state.bare ? null : "none" }).run(), !state.bare),
8437
+ tool(import_lucide_react5.TableRowsSplit, t.deleteRow, () => editor.chain().focus().deleteRow().run()),
8438
+ tool(import_lucide_react5.TableColumnsSplit, t.deleteColumn, () => editor.chain().focus().deleteColumn().run()),
8439
+ tool(import_lucide_react5.Trash2, t.deleteTable, () => editor.chain().focus().deleteTable().run())
8440
+ ] }) : state.img && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: [[import_lucide_react5.Image, t.wrapInline, "inline"], [import_lucide_react5.PanelLeft, t.wrapLeft, "left"], [import_lucide_react5.PanelRight, t.wrapRight, "right"]].map(([icon, label, value3]) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react10.Fragment, { children: tool(icon, label, () => editor.chain().focus().updateAttributes("image", { wrap: value3 === "inline" ? null : value3 }).run(), state.img === value3) }, value3)) }));
8441
+ const status = (can.edit || live) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-end", children: [
8442
+ live && (live.ready ? !live.online : live.late || live.denied) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-text-live", title: live.denied ? void 0 : t.offlineHint, children: [
8443
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.WifiOff, { "aria-hidden": true }),
8444
+ live.denied ? t.liveOff : t.offline
8445
+ ] }),
8446
+ state.suggest && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-docs-badge", children: t.suggesting }),
8447
+ can.edit && saving === "failed" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-text-saved", title: `${t.save} (${mod}S)`, onClick: () => void save2(), children: [
8448
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.CloudAlert, { "aria-hidden": true }),
8449
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: t.saveFailed })
8450
+ ] }),
8451
+ live && live.people.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-text-people", role: "group", "aria-label": t.people, children: live.people.map((p) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-text-face", title: p.me ? `${p.name} (${t.you})` : p.name, style: { "--face": p.color }, children: p.avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("img", { src: p.avatarUrl, alt: "" }) : p.name.split(/\s+/).map((w) => w[0]).join("").slice(0, 2).toUpperCase() }, p.id)) })
8452
+ ] });
8453
+ const menubar = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-text-menus", role: "menubar", "aria-label": t.textTools, children: menus.filter(([, , list]) => list.some((x) => x && x !== "-")).map(menu) });
8454
+ const keep = (e) => {
8455
+ if (e.target.closest("button")) e.preventDefault();
8456
+ };
8457
+ const sheet2 = docx2 ? { "--page-w": `${page.width}px`, "--page-h": `${page.height}px`, "--mt": `${page.margins[0]}px`, "--mr": `${page.margins[1]}px`, "--mb": `${page.margins[2]}px`, "--ml": `${page.margins[3]}px` } : void 0;
8458
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: root, className: "w100n-text", "data-kind": kind, "data-docs-find": true, onKeyDown: keys2, children: [
8459
+ head2 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
8460
+ head2.menus && (0, import_react_dom2.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-text-ribbon w100n-text-docbar", onKeyDown: rove, onPointerDown: keep, children: menubar }), head2.menus),
8461
+ head2.status && status && (0, import_react_dom2.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-text-ribbon w100n-text-docbar", onPointerDown: keep, children: status }), head2.status)
8462
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-text-ribbon w100n-text-top", onKeyDown: rove, onPointerDown: keep, children: [
8463
+ menubar,
8464
+ status
7704
8465
  ] }),
7705
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: scroller, className: "w100n-text-scroll", onClick: (e) => {
8466
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: scroller, className: "w100n-text-scroll", "data-paint": !!paint2, onMouseUp: lay, onClick: (e) => {
7706
8467
  const id = e.target.closest("[data-note]")?.getAttribute("data-note");
7707
8468
  if (!id) return;
7708
8469
  setActive(id);
7709
8470
  onPanel?.("comments");
7710
8471
  }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-text-zoomed", style: { zoom: percent / 100 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: docx2 ? "w100n-text-sheet" : "w100n-docs-page w100n-text-column", style: sheet2, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react9.EditorContent, { editor }) }) }) }),
8472
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-text-ribbon w100n-text-corner", "data-side": "left", onPointerDown: keep, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-text-tools", role: "group", "aria-label": t.zoom, children: [
8473
+ tool(import_lucide_react5.Minus, t.zoomOut, () => zoomBy(-10)),
8474
+ zoomer,
8475
+ tool(import_lucide_react5.Plus, t.zoomIn, () => zoomBy(10))
8476
+ ] }) }),
8477
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-text-ribbon w100n-text-island", role: "toolbar", "aria-label": t.textTools, onKeyDown: rove, onPointerDown: keep, children: [
8478
+ context && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-text-tools", role: "group", "aria-label": state.table ? t.table : t.image, children: context }),
8479
+ extra && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-text-tools", role: "group", "aria-label": t.moreTools, children: extra }),
8480
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-text-tools", role: "group", "aria-label": t.textTools, children: main })
8481
+ ] }),
8482
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-text-ribbon w100n-text-corner", "data-side": "right", onPointerDown: keep, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-text-tools", role: "group", "aria-label": t.findReplace, children: [
8483
+ can.edit && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
8484
+ tool(import_lucide_react5.Undo2, t.undo, () => editor.chain().focus().undo().run(), void 0, !state.undo),
8485
+ tool(import_lucide_react5.Redo2, t.redo, () => editor.chain().focus().redo().run(), void 0, !state.redo),
8486
+ gap
8487
+ ] }),
8488
+ finder
8489
+ ] }) }),
8490
+ draft2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-pdf-back", onKeyDown: (e) => {
8491
+ if (e.key === "Escape") {
8492
+ e.stopPropagation();
8493
+ setDraft2(null);
8494
+ }
8495
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("form", { className: "w100n-pdf-dialog w100n-setup", role: "dialog", "aria-modal": true, "aria-label": t.pageSetup, onSubmit: (e) => {
8496
+ e.preventDefault();
8497
+ applySetup();
8498
+ }, children: [
8499
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-new-head", children: [
8500
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-new-tile", "data-tone": "blue", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Ruler, { "aria-hidden": true }) }),
8501
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("b", { className: "w100n-pdf-dialog-title", children: t.pageSetup }),
8502
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "w100n-docs-close", onClick: () => setDraft2(null), "aria-label": t.close, title: t.close, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.X, { "aria-hidden": true }) })
8503
+ ] }),
8504
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "w100n-docs-caption", children: t.pageSize }),
8505
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-docs-chips", role: "group", "aria-label": t.pageSize, children: [["A4", a4], ["Letter", letter], ["Legal", legal]].map(([label, size2]) => {
8506
+ const land = draft2.width > draft2.height;
8507
+ const on2 = Math.abs(Math.min(draft2.width, draft2.height) - size2.width) < 2 && Math.abs(Math.max(draft2.width, draft2.height) - size2.height) < 2;
8508
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "aria-pressed": on2, onClick: () => setDraft2({ ...draft2, width: land ? size2.height : size2.width, height: land ? size2.width : size2.height }), children: label }, label);
8509
+ }) }),
8510
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "w100n-docs-caption", children: t.orientation }),
8511
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-docs-chips", role: "group", "aria-label": t.orientation, children: [[false, t.portrait], [true, t.landscape]].map(([land, label]) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
8512
+ "button",
8513
+ {
8514
+ type: "button",
8515
+ "aria-pressed": draft2.width > draft2.height === land,
8516
+ onClick: () => {
8517
+ if (draft2.width > draft2.height !== land) setDraft2({ ...draft2, width: draft2.height, height: draft2.width });
8518
+ },
8519
+ children: label
8520
+ },
8521
+ label
8522
+ )) }),
8523
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "w100n-docs-caption", children: t.marginsCm }),
8524
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-docs-chips", role: "group", "aria-label": t.margins, children: margins.map(([label, values]) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "aria-pressed": values.every((v, n) => Math.abs(cm(v) - draft2.margins[n]) < 0.05), onClick: () => setDraft2({ ...draft2, margins: values.map(cm) }), children: label }, label)) }),
8525
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-setup-grid", children: [t.mTop, t.mRight, t.mBottom, t.mLeft].map((label, n) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { children: [
8526
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: label }),
8527
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
8528
+ "input",
8529
+ {
8530
+ className: "w100n-docs-field",
8531
+ type: "number",
8532
+ min: 0,
8533
+ max: 10,
8534
+ step: 0.1,
8535
+ value: draft2.margins[n],
8536
+ onChange: (e) => setDraft2({ ...draft2, margins: draft2.margins.map((v, i) => i === n ? Math.max(0, Math.min(10, Number(e.target.value) || 0)) : v) })
8537
+ }
8538
+ )
8539
+ ] }, n)) }),
8540
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "w100n-setup-line", children: [
8541
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: t.headerText }),
8542
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { className: "w100n-docs-field", value: draft2.header, onChange: (e) => setDraft2({ ...draft2, header: e.target.value }) })
8543
+ ] }),
8544
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "w100n-setup-line", children: [
8545
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: t.footerText }),
8546
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { className: "w100n-docs-field", value: draft2.footer, onChange: (e) => setDraft2({ ...draft2, footer: e.target.value }) })
8547
+ ] }),
8548
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "w100n-setup-check", children: [
8549
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "checkbox", checked: draft2.numbers, onChange: (e) => setDraft2({ ...draft2, numbers: e.target.checked }) }),
8550
+ t.pageNumbers
8551
+ ] }),
8552
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-pdf-dialog-end", children: [
8553
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "w100n-pdf-link", onClick: () => setDraft2(null), children: t.cancel }),
8554
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "w100n-docs-action", onClick: applySetup, children: [
8555
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Check, { "aria-hidden": true }),
8556
+ t.apply
8557
+ ] })
8558
+ ] })
8559
+ ] }) }),
7711
8560
  slot && (0, import_react_dom2.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-text-notes", children: [
7712
8561
  draft && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-text-card w100n-text-draft", children: [
7713
8562
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("blockquote", { children: draft.quote }),
@@ -7819,7 +8668,7 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7819
8668
  ] }), slot)
7820
8669
  ] });
7821
8670
  }
7822
- var import_react9, import_lucide_react5, import_react10, import_react_dom2, import_jsx_runtime6, inks, glows, uid2;
8671
+ var import_react9, import_lucide_react5, import_react10, import_react_dom2, import_jsx_runtime6, legal, cm, inks, glows, faces, sizes, uid2;
7823
8672
  var init_TextEditor = __esm({
7824
8673
  "src/editor/TextEditor.tsx"() {
7825
8674
  "use strict";
@@ -7836,8 +8685,12 @@ var init_TextEditor = __esm({
7836
8685
  init_markdown();
7837
8686
  init_pager();
7838
8687
  import_jsx_runtime6 = require("react/jsx-runtime");
8688
+ legal = { width: 816, height: 1344 };
8689
+ cm = (px2) => Math.round(px2 / 96 * 254) / 100;
7839
8690
  inks = ["#0f172a", "#475569", "#dc2626", "#ea580c", "#ca8a04", "#16a34a", "#0891b2", "#2563eb", "#7c3aed", "#db2777"];
7840
8691
  glows = ["#fef08a", "#bbf7d0", "#bfdbfe", "#fbcfe8", "#fed7aa", "#ddd6fe"];
8692
+ faces = ["Arial", "Calibri", "Cambria", "Courier New", "Georgia", "Inter", "Roboto", "Times New Roman", "Verdana"];
8693
+ sizes = [8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 48, 72];
7841
8694
  uid2 = () => Math.random().toString(36).slice(2, 10);
7842
8695
  }
7843
8696
  });
@@ -8159,7 +9012,7 @@ function bind(api, injector, doc, model, edit) {
8159
9012
  const linesTo = (sid, ids, row2) => {
8160
9013
  const { rowData, colData } = pieces(sheets.get(sid));
8161
9014
  const map = row2 ? index(sid).rows : index(sid).cols;
8162
- const info = {}, sizes = {};
9015
+ const info = {}, sizes2 = {};
8163
9016
  const ranges = [];
8164
9017
  for (const id of ids) {
8165
9018
  const i = map.get(id);
@@ -8168,16 +9021,16 @@ function bind(api, injector, doc, model, edit) {
8168
9021
  const s = x?.s ? styles2.get(x.s) : void 0;
8169
9022
  info[i] = x ? row2 ? { h: x.h, hd: x.hd, ia: x.ia, s } : { w: x.w, hd: x.hd, s } : null;
8170
9023
  const size2 = row2 ? x?.h : x?.w;
8171
- if (size2 !== void 0) sizes[i] = size2;
9024
+ if (size2 !== void 0) sizes2[i] = size2;
8172
9025
  ranges.push({ startRow: row2 ? i : 0, endRow: row2 ? i : 0, startColumn: row2 ? 0 : i, endColumn: row2 ? 0 : i });
8173
9026
  }
8174
9027
  if (!ranges.length) return;
8175
9028
  if (row2) {
8176
9029
  run2("sheet.mutation.set-row-data", { subUnitId: sid, rowData: info });
8177
- run2("sheet.mutation.set-worksheet-row-height", { subUnitId: sid, ranges, rowHeight: sizes });
9030
+ run2("sheet.mutation.set-worksheet-row-height", { subUnitId: sid, ranges, rowHeight: sizes2 });
8178
9031
  } else {
8179
9032
  run2("sheet.mutation.set-col-data", { subUnitId: sid, columnData: info });
8180
- run2("sheet.mutation.set-worksheet-col-width", { subUnitId: sid, ranges, colWidth: sizes });
9033
+ run2("sheet.mutation.set-worksheet-col-width", { subUnitId: sid, ranges, colWidth: sizes2 });
8181
9034
  }
8182
9035
  };
8183
9036
  const mergesTo = (sid) => {
@@ -8343,7 +9196,7 @@ __export(grid_exports, {
8343
9196
  grid: () => grid2,
8344
9197
  marks: () => marks
8345
9198
  });
8346
- function grid2(container, language, dark, edit) {
9199
+ function grid2(container, language, edit) {
8347
9200
  return (0, import_presets.createUniver)({
8348
9201
  locale: language === "pl" ? import_presets.LocaleType.PL_PL : import_presets.LocaleType.EN_US,
8349
9202
  locales: {
@@ -8351,7 +9204,7 @@ function grid2(container, language, dark, edit) {
8351
9204
  [import_presets.LocaleType.PL_PL]: (0, import_presets.mergeLocales)(import_pl_PL.default, import_pl_PL2.default, import_pl_PL3.default, import_pl_PL4.default, import_pl_PL5.default, import_pl_PL6.default)
8352
9205
  },
8353
9206
  theme: import_presets.purpleTheme,
8354
- darkMode: dark,
9207
+ darkMode: false,
8355
9208
  presets: [
8356
9209
  (0, import_preset_sheets_core.UniverSheetsCorePreset)({
8357
9210
  container,
@@ -8432,10 +9285,26 @@ var init_grid = __esm({
8432
9285
  var SheetView_exports = {};
8433
9286
  __export(SheetView_exports, {
8434
9287
  SheetView: () => SheetView,
9288
+ autoSum: () => autoSum,
9289
+ decimals: () => decimals,
8435
9290
  default: () => SheetView_default,
8436
9291
  readSheet: () => readSheet,
8437
9292
  writeSheet: () => writeSheet
8438
9293
  });
9294
+ function autoSum(r, numeric2) {
9295
+ if (r.startRow !== r.endRow || r.startColumn !== r.endColumn) {
9296
+ return Array.from({ length: r.endColumn - r.startColumn + 1 }, (_, i) => {
9297
+ const col = r.startColumn + i;
9298
+ return { row: r.endRow + 1, col, f: `=SUM(${letters2(col)}${r.startRow + 1}:${letters2(col)}${r.endRow + 1})` };
9299
+ });
9300
+ }
9301
+ let top = r.startRow;
9302
+ while (top > 0 && numeric2(top - 1, r.startColumn)) top--;
9303
+ if (top < r.startRow) return [{ row: r.startRow, col: r.startColumn, f: `=SUM(${letters2(r.startColumn)}${top + 1}:${letters2(r.startColumn)}${r.startRow})` }];
9304
+ let left = r.startColumn;
9305
+ while (left > 0 && numeric2(r.startRow, left - 1)) left--;
9306
+ return left < r.startColumn ? [{ row: r.startRow, col: r.startColumn, f: `=SUM(${letters2(left)}${r.startRow + 1}:${letters2(r.startColumn - 1)}${r.startRow + 1})` }] : [];
9307
+ }
8439
9308
  function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSaveRequest, guard, host, together, documentId = "", onSaved }) {
8440
9309
  const t = sheetTexts[language];
8441
9310
  const box2 = (0, import_react11.useRef)(null);
@@ -8480,7 +9349,7 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
8480
9349
  if (kind === "csv") model.book.sheets.s1.name = name.replace(/\.[^.]+$/, "") || "Sheet1";
8481
9350
  const host2 = box2.current.appendChild(document.createElement("div"));
8482
9351
  host2.className = "w100n-sheet-host";
8483
- const view = grid3(host2, language, theme === "dark", edit);
9352
+ const view = grid3(host2, language, edit);
8484
9353
  const { univer, univerAPI: api2 } = view;
8485
9354
  const wb = api2.createWorkbook(model.book);
8486
9355
  if (model.active) wb.setActiveSheet(model.active);
@@ -8547,9 +9416,6 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
8547
9416
  (0, import_react11.useEffect)(() => {
8548
9417
  live.current?.marks?.show((room?.people ?? []).flatMap((p) => !p.me && p.selection ? [{ ...p.selection, color: p.color }] : []));
8549
9418
  }, [room?.people, phase]);
8550
- (0, import_react11.useEffect)(() => {
8551
- live.current?.api.toggleDarkMode(theme === "dark");
8552
- }, [theme]);
8553
9419
  (0, import_react11.useEffect)(() => {
8554
9420
  live.current?.api.setLocale(language === "pl" ? "plPL" : "enUS");
8555
9421
  }, [language]);
@@ -8644,6 +9510,13 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
8644
9510
  [t.time, "hh:mm"],
8645
9511
  [t.text, "@"]
8646
9512
  ];
9513
+ const places = (step) => range()?.setNumberFormat(decimals(look?.n ?? "General", step));
9514
+ const sum = () => {
9515
+ const r = range()?.getRange();
9516
+ const ws = sheet2();
9517
+ const numeric2 = (row2, c) => ws?.getRange(row2, c).getCellData()?.t === import_core5.CellValueType.NUMBER;
9518
+ if (r && ws) for (const x of autoSum(r, numeric2)) ws.getRange(x.row, x.col).setValue({ f: x.f });
9519
+ };
8647
9520
  const shown = formats.find(([, p]) => p === look?.n)?.[0] ?? (look && look.n !== "General" ? look.n : t.general);
8648
9521
  const border = (type) => {
8649
9522
  range()?.setBorder(type, type === "none" ? 0 : 1, "#000000");
@@ -8704,6 +9577,10 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
8704
9577
  i
8705
9578
  )) })
8706
9579
  ),
9580
+ tool(import_lucide_react6.Euro, t.asCurrency, () => range()?.setNumberFormat('#,##0.00 "\u20AC"'), look?.n === '#,##0.00 "\u20AC"'),
9581
+ tool(import_lucide_react6.Percent, t.asPercent, () => range()?.setNumberFormat("0.00%"), look?.n === "0.00%"),
9582
+ tool(import_lucide_react6.DecimalsArrowLeft, t.fewerDecimals, () => places(-1)),
9583
+ tool(import_lucide_react6.DecimalsArrowRight, t.moreDecimals, () => places(1)),
8707
9584
  gap,
8708
9585
  tool(import_lucide_react6.Bold, t.bold, () => run2("sheet.command.set-range-bold"), look?.bl),
8709
9586
  tool(import_lucide_react6.Italic, t.italic, () => run2("sheet.command.set-range-italic"), look?.it),
@@ -8772,6 +9649,7 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
8772
9649
  ] })
8773
9650
  ),
8774
9651
  gap,
9652
+ tool(import_lucide_react6.Sigma, t.sum, sum),
8775
9653
  tool(import_lucide_react6.ArrowDownAZ, t.sortUp, () => run2("sheet.command.sort-range-asc")),
8776
9654
  tool(import_lucide_react6.ArrowDownZA, t.sortDown, () => run2("sheet.command.sort-range-desc")),
8777
9655
  !room && tool(import_lucide_react6.Funnel, t.filter, () => run2("sheet.command.smart-toggle-filter")),
@@ -8785,7 +9663,7 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
8785
9663
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react6.WifiOff, { "aria-hidden": true }),
8786
9664
  room.denied ? t.liveOff : t.offline
8787
9665
  ] }),
8788
- room && room.people.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "w100n-text-people", role: "group", "aria-label": t.people, children: room.people.map((p) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "w100n-text-face", title: p.me ? `${p.name} (${t.you})` : p.name, style: { "--face": p.color }, children: p.avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { src: p.avatarUrl, alt: "" }) : p.name.slice(0, 1).toUpperCase() }, p.id)) }),
9666
+ room && room.people.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "w100n-text-people", role: "group", "aria-label": t.people, children: room.people.map((p) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "w100n-text-face", title: p.me ? `${p.name} (${t.you})` : p.name, style: { "--face": p.color }, children: p.avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { src: p.avatarUrl, alt: "" }) : p.name.split(/\s+/).map((w) => w[0]).join("").slice(0, 2).toUpperCase() }, p.id)) }),
8789
9667
  !edit && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "w100n-docs-badge", children: notes2 ? t.notesOnly : t.viewOnly }),
8790
9668
  saving === "failed" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "w100n-sheet-muted", role: "alert", children: refusal ? t.refused[refusal.code].replace("{sheet}", refusal.sheet) : t.saveFailed }),
8791
9669
  (edit || notes2) && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { type: "button", className: "w100n-docs-action", disabled: !pending2 || saving === "busy" || phase !== "ready" || !!room && !room.online, onClick: () => void save2(), children: [
@@ -8803,12 +9681,13 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
8803
9681
  ] })
8804
9682
  ] });
8805
9683
  }
8806
- var import_react11, import_lucide_react6, import_jsx_runtime7, SheetView_default;
9684
+ var import_react11, import_lucide_react6, import_core5, import_jsx_runtime7, decimals, letters2, SheetView_default;
8807
9685
  var init_SheetView = __esm({
8808
9686
  "src/sheets/SheetView.tsx"() {
8809
9687
  "use strict";
8810
9688
  import_react11 = require("react");
8811
9689
  import_lucide_react6 = require("lucide-react");
9690
+ import_core5 = require("@univerjs/core");
8812
9691
  init_live();
8813
9692
  init_focus();
8814
9693
  init_bind();
@@ -8821,6 +9700,16 @@ var init_SheetView = __esm({
8821
9700
  init_xlsx();
8822
9701
  init_sheets();
8823
9702
  import_jsx_runtime7 = require("react/jsx-runtime");
9703
+ decimals = (pattern, step) => {
9704
+ const p = pattern === "General" ? "0" : pattern;
9705
+ const next = Math.max(0, (/0(?:\.(0+))?/.exec(p)?.[1]?.length ?? 0) + step);
9706
+ return p.replace(/0(?:\.0+)?/, `0${next ? `.${"0".repeat(next)}` : ""}`);
9707
+ };
9708
+ letters2 = (c) => {
9709
+ let s = "";
9710
+ for (let n = c + 1; n > 0; n = Math.floor((n - 1) / 26)) s = String.fromCharCode(65 + (n - 1) % 26) + s;
9711
+ return s;
9712
+ };
8824
9713
  SheetView_default = SheetView;
8825
9714
  }
8826
9715
  });
@@ -8881,9 +9770,9 @@ function readable(name, mimeType) {
8881
9770
  const kind = kindOf(name, mimeType);
8882
9771
  return kind !== "sheet" || /\.(xlsx|csv)$/i.test(name) || /spreadsheetml|text\/csv/.test(mimeType ?? "") ? kind : null;
8883
9772
  }
8884
- function matches(doc, query, kind) {
9773
+ function matches(doc, query, picked) {
8885
9774
  const words = query.toLocaleLowerCase().split(/\s+/).filter(Boolean);
8886
- return (kind === "all" || doc.kind === kind) && words.every((word) => doc.name.toLocaleLowerCase().includes(word));
9775
+ return (!picked.length || picked.includes(doc.kind)) && words.every((word) => doc.name.toLocaleLowerCase().includes(word));
8887
9776
  }
8888
9777
 
8889
9778
  // src/slides/SlidesView.tsx
@@ -10581,7 +11470,7 @@ function PdfView({ bytes, t, language, worker, rights, host, documentId, onSaved
10581
11470
  const words = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
10582
11471
  const anchor = (0, import_react6.useRef)({ scale: 0, page: 0, frac: 0 });
10583
11472
  const [pdf, setPdf] = (0, import_react6.useState)(null);
10584
- const [sizes, setSizes] = (0, import_react6.useState)([]);
11473
+ const [sizes2, setSizes] = (0, import_react6.useState)([]);
10585
11474
  const [error, setError] = (0, import_react6.useState)(false);
10586
11475
  const [box2, setBox] = (0, import_react6.useState)({ w: 0, h: 0 });
10587
11476
  const [top, setTop] = (0, import_react6.useState)(0);
@@ -10691,23 +11580,23 @@ function PdfView({ bytes, t, language, worker, rights, host, documentId, onSaved
10691
11580
  document.addEventListener("pointerdown", close);
10692
11581
  return () => document.removeEventListener("pointerdown", close);
10693
11582
  }, [more, palette2]);
10694
- const widest = Math.max(1, ...sizes.map((s) => s.w));
10695
- const tallest = Math.max(1, ...sizes.map((s) => s.h));
11583
+ const widest = Math.max(1, ...sizes2.map((s) => s.w));
11584
+ const tallest = Math.max(1, ...sizes2.map((s) => s.h));
10696
11585
  const room = { w: Math.max(120, box2.w - 32), h: Math.max(120, box2.h - 32) };
10697
11586
  const scale = fit === "auto" ? Math.min(room.w / widest, 5 / 3) : fit === "width" ? room.w / widest : fit === "page" ? Math.min(room.w / widest, room.h / tallest) : zoom / 75;
10698
11587
  const percent = Math.round(scale * 75);
10699
11588
  const tops = [];
10700
11589
  let end = 16;
10701
- for (const s of sizes) {
11590
+ for (const s of sizes2) {
10702
11591
  tops.push(end);
10703
11592
  end += s.h * scale + 16;
10704
11593
  }
10705
11594
  let page = 1;
10706
11595
  while (page < tops.length && tops[page] <= top + box2.h / 3) page++;
10707
- const live = (i) => !!pdf && tops[i] < top + box2.h * 2 && tops[i] + sizes[i].h * scale > top - box2.h;
11596
+ const live = (i) => !!pdf && tops[i] < top + box2.h * 2 && tops[i] + sizes2[i].h * scale > top - box2.h;
10708
11597
  const thumbTops = [];
10709
11598
  let thumbEnd = 10;
10710
- for (const s of sizes) {
11599
+ for (const s of sizes2) {
10711
11600
  thumbTops.push(thumbEnd);
10712
11601
  thumbEnd += s.h * 96 / s.w + 34;
10713
11602
  }
@@ -10715,11 +11604,11 @@ function PdfView({ bytes, t, language, worker, rights, host, documentId, onSaved
10715
11604
  const centre = (y) => {
10716
11605
  let i = 0;
10717
11606
  while (i + 1 < tops.length && tops[i + 1] <= y + box2.h / 2) i++;
10718
- return { page: i, frac: sizes[i] ? (y + box2.h / 2 - tops[i]) / (sizes[i].h * scale) : 0 };
11607
+ return { page: i, frac: sizes2[i] ? (y + box2.h / 2 - tops[i]) / (sizes2[i].h * scale) : 0 };
10719
11608
  };
10720
11609
  (0, import_react6.useLayoutEffect)(() => {
10721
11610
  const was = anchor.current;
10722
- if (was.scale && was.scale !== scale && sizes[was.page]) scroller.current.scrollTop = tops[was.page] + was.frac * sizes[was.page].h * scale - box2.h / 2;
11611
+ if (was.scale && was.scale !== scale && sizes2[was.page]) scroller.current.scrollTop = tops[was.page] + was.frac * sizes2[was.page].h * scale - box2.h / 2;
10723
11612
  anchor.current = { ...was, scale };
10724
11613
  }, [scale]);
10725
11614
  (0, import_react6.useEffect)(() => {
@@ -10796,7 +11685,7 @@ function PdfView({ bytes, t, language, worker, rights, host, documentId, onSaved
10796
11685
  const next = (at + d + hits.list.length) % hits.list.length;
10797
11686
  setAt(next);
10798
11687
  const n = hits.list[next].page;
10799
- if (tops[n - 1] + sizes[n - 1].h * scale < top || tops[n - 1] > top + box2.h) go(n);
11688
+ if (tops[n - 1] + sizes2[n - 1].h * scale < top || tops[n - 1] > top + box2.h) go(n);
10800
11689
  };
10801
11690
  const markText = (kind) => {
10802
11691
  const picked = document.getSelection();
@@ -10852,7 +11741,7 @@ function PdfView({ bytes, t, language, worker, rights, host, documentId, onSaved
10852
11741
  }),
10853
11742
  place: (n, p) => {
10854
11743
  if (!pending2) return;
10855
- const size2 = sizes[n - 1];
11744
+ const size2 = sizes2[n - 1];
10856
11745
  const w = Math.min(180, size2.w / 2);
10857
11746
  const h = w / pending2.ratio;
10858
11747
  const mark = {
@@ -11032,7 +11921,7 @@ function PdfView({ bytes, t, language, worker, rights, host, documentId, onSaved
11032
11921
  ),
11033
11922
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
11034
11923
  "/ ",
11035
- sizes.length || ""
11924
+ sizes2.length || ""
11036
11925
  ] })
11037
11926
  ] }) },
11038
11927
  { key: "g1", at: 2, node: gap },
@@ -11148,7 +12037,7 @@ function PdfView({ bytes, t, language, worker, rights, host, documentId, onSaved
11148
12037
  }, children: t.cancel })
11149
12038
  ] }),
11150
12039
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "w100n-pdf-body", children: [
11151
- rail && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("nav", { ref: railBox, className: "w100n-pdf-rail", "aria-label": t.pages, onScroll: (e) => setRailTop(Math.round(e.currentTarget.scrollTop / 80) * 80), children: sizes.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { type: "button", className: "w100n-pdf-thumb", "aria-current": page === i + 1, onClick: () => go(i + 1), "aria-label": `${t.page} ${i + 1}`, children: [
12040
+ rail && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("nav", { ref: railBox, className: "w100n-pdf-rail", "aria-label": t.pages, onScroll: (e) => setRailTop(Math.round(e.currentTarget.scrollTop / 80) * 80), children: sizes2.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { type: "button", className: "w100n-pdf-thumb", "aria-current": page === i + 1, onClick: () => go(i + 1), "aria-label": `${t.page} ${i + 1}`, children: [
11152
12041
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PdfPage, { pdf, n: i + 1, size: s, scale: 96 / s.w, live: !!pdf && thumbLive(i) }),
11153
12042
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: i + 1 })
11154
12043
  ] }, i)) }),
@@ -11175,7 +12064,7 @@ function PdfView({ bytes, t, language, worker, rights, host, documentId, onSaved
11175
12064
  },
11176
12065
  children: [
11177
12066
  error && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "w100n-docs-note", children: t.failed }),
11178
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "w100n-pdf-pages", children: sizes.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PdfPage, { id: `${prefix}-${i + 1}`, pdf, n: i + 1, size: s, scale, live: live(i), layers: {
12067
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "w100n-pdf-pages", children: sizes2.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PdfPage, { id: `${prefix}-${i + 1}`, pdf, n: i + 1, size: s, scale, live: live(i), layers: {
11179
12068
  forms: can.edit,
11180
12069
  tool,
11181
12070
  marks: byPage.get(i + 1) ?? [],
@@ -11935,7 +12824,12 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
11935
12824
  onPlace?.(next);
11936
12825
  };
11937
12826
  const [query, setQuery] = (0, import_react16.useState)("");
11938
- const [kind, setKind] = (0, import_react16.useState)("all");
12827
+ const [picked, setPicked] = (0, import_react16.useState)([]);
12828
+ const [typing, setTyping] = (0, import_react16.useState)(false);
12829
+ const [menusAt, setMenusAt] = (0, import_react16.useState)(null);
12830
+ const [renaming, setRenaming] = (0, import_react16.useState)(null);
12831
+ const [renamed2, setRenamed] = (0, import_react16.useState)("idle");
12832
+ const [statusAt, setStatusAt] = (0, import_react16.useState)(null);
11939
12833
  const [listOpen, setListOpen] = (0, import_react16.useState)(true);
11940
12834
  const [panelOpen, setPanelOpen] = (0, import_react16.useState)(true);
11941
12835
  const [narrow, setNarrow] = (0, import_react16.useState)(false);
@@ -11949,13 +12843,13 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
11949
12843
  const el = body.current;
11950
12844
  let was = false;
11951
12845
  const check = () => {
11952
- const now = getComputedStyle(el).getPropertyValue("--docs-narrow").trim() === "1";
11953
- if (now && !was) {
12846
+ const now2 = getComputedStyle(el).getPropertyValue("--docs-narrow").trim() === "1";
12847
+ if (now2 && !was) {
11954
12848
  setPanelOpen(false);
11955
12849
  if (here.documentId) setListOpen(false);
11956
12850
  }
11957
- was = now;
11958
- setNarrow(now);
12851
+ was = now2;
12852
+ setNarrow(now2);
11959
12853
  };
11960
12854
  check();
11961
12855
  if (typeof ResizeObserver === "undefined") return;
@@ -11964,6 +12858,23 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
11964
12858
  return () => watch.disconnect();
11965
12859
  }, [here.documentId]);
11966
12860
  const [picking, setPicking] = (0, import_react16.useState)(false);
12861
+ const [adding, setAdding] = (0, import_react16.useState)(false);
12862
+ (0, import_react16.useEffect)(() => {
12863
+ if (!adding) return;
12864
+ const close = (e) => {
12865
+ if (!e.target.closest(".w100n-docs-new")) setAdding(false);
12866
+ };
12867
+ document.addEventListener("pointerdown", close);
12868
+ return () => document.removeEventListener("pointerdown", close);
12869
+ }, [adding]);
12870
+ (0, import_react16.useEffect)(() => {
12871
+ if (!typing) return;
12872
+ const close = (e) => {
12873
+ if (!e.target.closest(".w100n-docs-types")) setTyping(false);
12874
+ };
12875
+ document.addEventListener("pointerdown", close);
12876
+ return () => document.removeEventListener("pointerdown", close);
12877
+ }, [typing]);
11967
12878
  (0, import_react16.useEffect)(() => {
11968
12879
  if (!picking) return;
11969
12880
  const close = (e) => {
@@ -11974,6 +12885,9 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
11974
12885
  }, [picking]);
11975
12886
  const [tab, setTab] = (0, import_react16.useState)("outline");
11976
12887
  const [outline2, setOutline] = (0, import_react16.useState)([]);
12888
+ const [reading, setReading] = (0, import_react16.useState)(null);
12889
+ const [hunt, setHunt] = (0, import_react16.useState)("");
12890
+ const [fold, setFold] = (0, import_react16.useState)({});
11977
12891
  const [version2, setVersion] = (0, import_react16.useState)({ documentId: null, id: null });
11978
12892
  const versionId = version2.documentId === here.documentId ? version2.id : null;
11979
12893
  const [restoring, setRestoring] = (0, import_react16.useState)("idle");
@@ -11981,6 +12895,8 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
11981
12895
  const [copying, setCopying] = (0, import_react16.useState)("idle");
11982
12896
  const [box2, setBox] = (0, import_react16.useState)(null);
11983
12897
  const [making, setMaking] = (0, import_react16.useState)(false);
12898
+ const [sending, setSending] = (0, import_react16.useState)("idle");
12899
+ const upload = (0, import_react16.useRef)(null);
11984
12900
  const spaces = useLoad((signal) => host.spaces({ signal }), [host]);
11985
12901
  const single = spaces.data?.length === 1 ? spaces.data[0].id : null;
11986
12902
  const spaceId = here.spaceId ?? single;
@@ -11991,14 +12907,30 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
11991
12907
  const all2 = await host.spaces({ signal });
11992
12908
  return (await Promise.all(all2.map((item) => host.documents(item.id, { signal })))).flat();
11993
12909
  }, [host, spaceId]);
12910
+ (0, import_react16.useEffect)(() => {
12911
+ const sync = () => {
12912
+ if (document.visibilityState !== "visible") return;
12913
+ spaces.retry();
12914
+ list.retry();
12915
+ };
12916
+ const timer = window.setInterval(sync, 3e4);
12917
+ window.addEventListener("focus", sync);
12918
+ document.addEventListener("visibilitychange", sync);
12919
+ return () => {
12920
+ clearInterval(timer);
12921
+ window.removeEventListener("focus", sync);
12922
+ document.removeEventListener("visibilitychange", sync);
12923
+ };
12924
+ }, []);
11994
12925
  const doc = useLoad((signal) => here.documentId ? host.document(here.documentId, { signal }) : Promise.resolve(null), [host, here.documentId]);
11995
12926
  const versions = useLoad((signal) => here.documentId ? host.versions(here.documentId, { signal }) : Promise.resolve([]), [host, here.documentId]);
11996
12927
  const content = useLoad((signal) => here.documentId ? host.content(here.documentId, versionId, { signal }) : Promise.resolve(null), [host, here.documentId, versionId]);
11997
12928
  const pdf = doc.data?.kind === "pdf";
11998
12929
  const text = doc.data?.kind === "markdown" || doc.data?.kind === "docx";
12930
+ const docbar = text && !versionId && !narrow;
11999
12931
  const signatures = useLoad((signal) => here.documentId && pdf && host.signatures ? host.signatures(here.documentId, { signal }) : Promise.resolve([]), [host, here.documentId, pdf]);
12000
12932
  const all = list.data ?? [];
12001
- const shown = all.filter((item) => matches(item, query, kind));
12933
+ const shown = all.filter((item) => matches(item, query, picked));
12002
12934
  const present = kinds.filter((item) => all.some((doc2) => doc2.kind === item));
12003
12935
  const folders = spaceId ? [.../* @__PURE__ */ new Set(["", ...shown.map((item) => item.folder ?? "")])].filter((folder2) => shown.some((item) => (item.folder ?? "") === folder2)) : [""];
12004
12936
  const names2 = new Map((spaces.data ?? []).map((item) => [item.id, item.name]));
@@ -12036,6 +12968,8 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
12036
12968
  }
12037
12969
  ask(() => {
12038
12970
  setOutline([]);
12971
+ setHunt("");
12972
+ setFold({});
12039
12973
  setTab("outline");
12040
12974
  go({ spaceId: here.spaceId, documentId: item.id });
12041
12975
  if (narrow) setListOpen(false);
@@ -12044,7 +12978,7 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
12044
12978
  const pick = (next) => {
12045
12979
  setPicking(false);
12046
12980
  ask(() => {
12047
- setKind("all");
12981
+ setPicked([]);
12048
12982
  go({ spaceId: next, documentId: null });
12049
12983
  });
12050
12984
  };
@@ -12095,6 +13029,44 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
12095
13029
  setCopying("failed");
12096
13030
  }
12097
13031
  };
13032
+ const copy2 = async (file) => {
13033
+ setCopying("busy");
13034
+ try {
13035
+ const made2 = await host.create({ name: `${t.copyOf} ${file.name}`, bytes: await host.content(file.id), mimeType: file.mimeType ?? "application/octet-stream" });
13036
+ setCopying("idle");
13037
+ opened2(made2);
13038
+ } catch {
13039
+ setCopying("failed");
13040
+ }
13041
+ };
13042
+ const rename = async (file, draft) => {
13043
+ setRenaming(null);
13044
+ const ext = /\.[^.]+$/.exec(file.name)?.[0] ?? "";
13045
+ const name = draft.trim() && (/\.[^.\s]+$/.test(draft.trim()) ? draft.trim() : draft.trim() + ext);
13046
+ if (!name || name === file.name) return;
13047
+ try {
13048
+ await host.rename(file.id, name);
13049
+ setRenamed("idle");
13050
+ doc.retry();
13051
+ list.retry();
13052
+ } catch {
13053
+ setRenamed("failed");
13054
+ }
13055
+ };
13056
+ const opened2 = (made2) => {
13057
+ spaces.retry();
13058
+ list.retry();
13059
+ ask(() => go({ spaceId: here.spaceId && made2.spaceId, documentId: made2.id }));
13060
+ };
13061
+ const send = async (file) => {
13062
+ setSending("busy");
13063
+ try {
13064
+ opened2(await host.create({ name: file.name, bytes: await file.arrayBuffer(), mimeType: file.type || "application/octet-stream" }));
13065
+ setSending("idle");
13066
+ } catch {
13067
+ setSending("failed");
13068
+ }
13069
+ };
12098
13070
  let stage = /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "w100n-docs-empty", children: [
12099
13071
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.FileText, { "aria-hidden": true }),
12100
13072
  t.pick
@@ -12117,13 +13089,21 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
12117
13089
  together: doc.data.live,
12118
13090
  documentId: doc.data.id,
12119
13091
  onOutline: setOutline,
13092
+ onReading: setReading,
12120
13093
  onPanel: (next) => {
12121
13094
  setPanelOpen(true);
12122
13095
  setTab(next);
12123
13096
  if (narrow) setListOpen(false);
12124
13097
  },
12125
13098
  slot: tab === "comments" && panelOpen ? box2 : null,
13099
+ head: docbar ? { menus: menusAt, status: statusAt } : void 0,
12126
13100
  guard,
13101
+ file: versionId ? void 0 : {
13102
+ formats: host.exportAs ? doc.data.exports ?? [] : [],
13103
+ download: (f) => void exportAs(doc.data, f),
13104
+ copy: host.create ? () => void copy2(doc.data) : void 0,
13105
+ rename: host.rename && doc.data.rights.edit ? () => setRenaming(doc.data.name.replace(/\.[^.]+$/, "")) : void 0
13106
+ },
12127
13107
  onSaved: () => {
12128
13108
  versions.retry();
12129
13109
  doc.retry();
@@ -12203,6 +13183,17 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
12203
13183
  else stage = /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "w100n-docs-empty", children: t.unsupported });
12204
13184
  }
12205
13185
  const Kind = doc.data ? icons3[doc.data.kind] : import_lucide_react10.FileText;
13186
+ const top = Math.min(...outline2.map((h) => h.level));
13187
+ const chapters = outline2.reduce((all2, h) => {
13188
+ if (h.level === top || !all2.length) all2.push({ head: h, subs: [] });
13189
+ else all2[all2.length - 1].subs.push(h);
13190
+ return all2;
13191
+ }, []);
13192
+ const now = reading?.documentId === here.documentId ? reading : null;
13193
+ const reached = now ? chapters.findIndex((c) => c.head.id === now.id || c.subs.some((s) => s.id === now.id)) : -1;
13194
+ const words = hunt.toLocaleLowerCase().split(/\s+/).filter(Boolean);
13195
+ const hit = (h) => words.every((w) => h.text.toLocaleLowerCase().includes(w));
13196
+ const reach = (h) => h.go ? h.go() : document.getElementById(h.id)?.scrollIntoView({ behavior: "smooth", block: "start" });
12206
13197
  const crumbs = doc.data ? [names2.get(doc.data.spaceId), doc.data.folder].filter(Boolean) : space ? [space.name] : [];
12207
13198
  const panelTabs = [["outline", import_lucide_react10.ListTree, t.outline], ["versions", import_lucide_react10.History, t.versions], ["details", import_lucide_react10.Info, t.details]];
12208
13199
  if (pdf && host.signatures) panelTabs.push(["signatures", import_lucide_react10.Signature, t.signatures]);
@@ -12241,13 +13232,38 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
12241
13232
  narrow && listToggle,
12242
13233
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w100n-docs-tile", "data-kind": doc.data?.kind, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Kind, { "aria-hidden": true }) }),
12243
13234
  /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "w100n-docs-heading", children: [
12244
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("strong", { className: "w100n-docs-title", children: doc.data?.name ?? t.documents }),
12245
- crumbs.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w100n-docs-crumbs", children: crumbs.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
13235
+ renaming !== null && doc.data ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
13236
+ "input",
13237
+ {
13238
+ className: "w100n-docs-title w100n-docs-rename",
13239
+ autoFocus: true,
13240
+ value: renaming,
13241
+ "aria-label": t.rename,
13242
+ onFocus: (e) => e.currentTarget.select(),
13243
+ onChange: (e) => setRenaming(e.target.value),
13244
+ onBlur: () => void rename(doc.data, renaming),
13245
+ onKeyDown: (e) => {
13246
+ if (e.key === "Enter") e.currentTarget.blur();
13247
+ if (e.key === "Escape") {
13248
+ e.stopPropagation();
13249
+ setRenaming(null);
13250
+ }
13251
+ }
13252
+ }
13253
+ ) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
13254
+ "strong",
13255
+ {
13256
+ className: "w100n-docs-title",
13257
+ title: docbar ? crumbs.join(" / ") : void 0,
13258
+ onDoubleClick: host.rename && doc.data?.rights.edit && !versionId ? () => setRenaming(doc.data.name.replace(/\.[^.]+$/, "")) : void 0,
13259
+ children: doc.data?.name ?? t.documents
13260
+ }
13261
+ ),
13262
+ docbar ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { ref: setMenusAt, className: "w100n-docs-menus" }) : crumbs.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w100n-docs-crumbs", children: crumbs.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
12246
13263
  i > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.ChevronRight, { "aria-hidden": true }),
12247
13264
  item
12248
13265
  ] }, i)) }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w100n-docs-hint", children: t.hint })
12249
13266
  ] }),
12250
- doc.data && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w100n-docs-badge", "data-kind": doc.data.kind, children: t.kinds[doc.data.kind] }),
12251
13267
  versionId && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w100n-docs-badge", children: versions.data?.find((v) => v.id === versionId) && date(versions.data.find((v) => v.id === versionId).createdAt) }),
12252
13268
  versionId && here.documentId && host.restore && doc.data?.rights.edit && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "w100n-docs-action", disabled: restoring === "busy", onClick: () => void restore(here.documentId, versionId), children: [
12253
13269
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.RotateCcw, { "aria-hidden": true }),
@@ -12259,6 +13275,8 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
12259
13275
  t.copyAs
12260
13276
  ] }),
12261
13277
  copying === "failed" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w100n-docs-muted", children: t.copyFailed }),
13278
+ renamed2 === "failed" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w100n-docs-muted", children: t.renameFailed }),
13279
+ docbar && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { ref: setStatusAt, className: "w100n-docs-status" }),
12262
13280
  sharing && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "w100n-docs-action", "aria-label": t.share, title: t.share, onClick: () => {
12263
13281
  setTab("sharing");
12264
13282
  side2("panel", true);
@@ -12267,10 +13285,6 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
12267
13285
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: t.share })
12268
13286
  ] }),
12269
13287
  doc.data && !versionId && actions?.(doc.data),
12270
- host.create && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "w100n-docs-action", "aria-label": t.create, title: t.create, onClick: () => setMaking(true), children: [
12271
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.Plus, { "aria-hidden": true }),
12272
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: t.create })
12273
- ] }),
12274
13288
  narrow && panelToggle,
12275
13289
  end && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "w100n-docs-end w100n-docs-slot", children: slot(end) })
12276
13290
  ] }),
@@ -12283,6 +13297,39 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
12283
13297
  t.documents,
12284
13298
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: all.length })
12285
13299
  ] }),
13300
+ host.create && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "w100n-docs-new", onKeyDown: (e) => {
13301
+ if (e.key === "Escape" && adding) {
13302
+ e.stopPropagation();
13303
+ setAdding(false);
13304
+ }
13305
+ }, children: [
13306
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "w100n-docs-action", "aria-haspopup": "menu", "aria-expanded": adding, disabled: sending === "busy", onClick: () => setAdding(!adding), children: [
13307
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.Plus, { "aria-hidden": true }),
13308
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: sending === "busy" ? t.uploading : t.create }),
13309
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.ChevronDown, { "aria-hidden": true })
13310
+ ] }),
13311
+ adding && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { role: "menu", className: "w100n-docs-menu", children: [
13312
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", role: "menuitem", onClick: () => {
13313
+ setAdding(false);
13314
+ setMaking(true);
13315
+ }, children: [
13316
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w100n-docs-all", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.FilePlus, { "aria-hidden": true }) }),
13317
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("b", { children: t.newTitle })
13318
+ ] }),
13319
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", role: "menuitem", onClick: () => {
13320
+ setAdding(false);
13321
+ upload.current.click();
13322
+ }, children: [
13323
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w100n-docs-all", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.Upload, { "aria-hidden": true }) }),
13324
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("b", { children: t.uploadFile })
13325
+ ] })
13326
+ ] }),
13327
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { ref: upload, type: "file", hidden: true, "aria-label": t.uploadFile, accept: ".docx,.md,.markdown,.pdf,.xlsx,.csv,.html,.htm", onChange: (e) => {
13328
+ const file = e.target.files?.[0];
13329
+ e.target.value = "";
13330
+ if (file) void send(file);
13331
+ } })
13332
+ ] }),
12286
13333
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { ref: listClose, type: "button", className: "w100n-docs-close", onClick: () => side2("list", false), "aria-label": t.closeList, title: t.closeList, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.X, { "aria-hidden": true }) })
12287
13334
  ] }),
12288
13335
  (spaces.data?.length ?? 0) > 1 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "w100n-docs-picker", onKeyDown: (e) => {
@@ -12314,16 +13361,48 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
12314
13361
  ] }, group))
12315
13362
  ] })
12316
13363
  ] }),
12317
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "w100n-docs-field w100n-docs-search", children: [
12318
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.Search, { "aria-hidden": true }),
12319
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { value: query, onChange: (event) => setQuery(event.target.value), placeholder: t.search, "aria-label": t.search })
13364
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "w100n-docs-filters", children: [
13365
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "w100n-docs-field w100n-docs-search", children: [
13366
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.Search, { "aria-hidden": true }),
13367
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { value: query, onChange: (event) => setQuery(event.target.value), placeholder: t.search, "aria-label": t.search })
13368
+ ] }),
13369
+ present.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "w100n-docs-types", onKeyDown: (e) => {
13370
+ if (e.key !== "Escape" || !typing) return;
13371
+ e.stopPropagation();
13372
+ setTyping(false);
13373
+ e.currentTarget.querySelector("button").focus();
13374
+ }, children: [
13375
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "w100n-docs-field", "aria-haspopup": "listbox", "aria-expanded": typing, "data-on": picked.length > 0, onClick: () => setTyping(!typing), children: [
13376
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.ListFilter, { "aria-hidden": true }),
13377
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("b", { children: t.typeFilter }),
13378
+ picked.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w100n-docs-badge", children: picked.length }),
13379
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.ChevronDown, { "aria-hidden": true })
13380
+ ] }),
13381
+ typing && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { role: "listbox", "aria-multiselectable": true, "aria-label": t.kind, className: "w100n-docs-menu", children: [
13382
+ present.map((item) => {
13383
+ const Icon = icons3[item];
13384
+ const on2 = picked.includes(item);
13385
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", role: "option", "aria-selected": on2, onClick: () => setPicked(on2 ? picked.filter((k) => k !== item) : [...picked, item]), children: [
13386
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w100n-docs-box", children: on2 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.Check, { "aria-hidden": true }) }),
13387
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w100n-docs-tile", "data-kind": item, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { "aria-hidden": true }) }),
13388
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("b", { children: t.kinds[item] }),
13389
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w100n-docs-count", children: all.filter((doc2) => doc2.kind === item).length })
13390
+ ] }, item);
13391
+ }),
13392
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "w100n-docs-menu-foot", children: [
13393
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", onClick: () => setPicked(present), children: t.selectAll }),
13394
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", onClick: () => setPicked([]), children: t.clearPick })
13395
+ ] })
13396
+ ] })
13397
+ ] })
12320
13398
  ] }),
12321
- present.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "w100n-docs-chips", role: "group", "aria-label": t.kind, children: ["all", ...present].map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", "aria-pressed": kind === item, onClick: () => setKind(item), children: [
12322
- item === "all" ? t.all : t.kinds[item],
12323
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { "aria-hidden": true, children: item === "all" ? all.length : all.filter((doc2) => doc2.kind === item).length })
13399
+ picked.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "w100n-docs-chips", role: "group", "aria-label": t.kind, children: picked.map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", "aria-pressed": true, "aria-label": `${t.clearPick}: ${t.kinds[item]}`, onClick: () => setPicked(picked.filter((k) => k !== item)), children: [
13400
+ t.kinds[item],
13401
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.X, { "aria-hidden": true })
12324
13402
  ] }, item)) })
12325
13403
  ] }),
12326
13404
  /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "w100n-docs-cards", children: [
13405
+ sending === "failed" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "w100n-docs-muted", role: "alert", children: t.uploadFailed }),
12327
13406
  list.error && failed(list.retry),
12328
13407
  list.loading && !list.data && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "w100n-docs-muted", children: t.loading }),
12329
13408
  list.data && !shown.length && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "w100n-docs-muted", children: all.length ? t.nothing : t.empty }),
@@ -12353,7 +13432,65 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
12353
13432
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "w100n-docs-close", onClick: () => side2("panel", false), "aria-label": t.closePanel, title: t.closePanel, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.X, { "aria-hidden": true }) })
12354
13433
  ] }) }),
12355
13434
  /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "w100n-docs-panel-body", role: "tabpanel", "aria-label": panelTabs.find(([key2]) => key2 === tab)?.[2], children: [
12356
- tab === "outline" && (outline2.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("nav", { className: "w100n-docs-outline", children: outline2.map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", "data-level": item.level, onClick: () => item.go ? item.go() : document.getElementById(item.id)?.scrollIntoView({ behavior: "smooth", block: "start" }), children: item.text }, item.id)) }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "w100n-docs-muted", children: t.noOutline })),
13435
+ tab === "outline" && (outline2.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("nav", { className: "w100n-docs-outline", "aria-label": t.outline, children: [
13436
+ now && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "w100n-docs-reading", children: [
13437
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("i", { style: { width: `${Math.round(now.progress * 100)}%` } }) }),
13438
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("small", { children: [
13439
+ Math.round(now.progress * 100),
13440
+ "% ",
13441
+ t.read
13442
+ ] })
13443
+ ] }),
13444
+ outline2.length > 8 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "w100n-docs-field w100n-docs-search", children: [
13445
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.Search, { "aria-hidden": true }),
13446
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { value: hunt, onChange: (e) => setHunt(e.target.value), placeholder: t.findHeading, "aria-label": t.findHeading })
13447
+ ] }),
13448
+ chapters.map((c, i) => {
13449
+ const subs = words.length ? c.subs.filter(hit) : c.subs;
13450
+ if (words.length && !hit(c.head) && !subs.length) return null;
13451
+ const opened3 = words.length > 0 || (fold[c.head.id] ?? i === reached);
13452
+ const named3 = /^(\d+)[.)]?\s+(.+)$/.exec(c.head.text);
13453
+ const mark = c.subs.findIndex((s) => s.id === now?.id);
13454
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "w100n-docs-chapter", "data-state": reached < 0 ? void 0 : i < reached ? "done" : i === reached ? "now" : void 0, children: [
13455
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "w100n-docs-chapter-row", children: [
13456
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "w100n-docs-chapter-go", "aria-label": c.head.text, "aria-current": now?.id === c.head.id ? "location" : void 0, onClick: () => reach(c.head), children: [
13457
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w100n-docs-chapter-num", children: named3 ? named3[1] : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.Bookmark, { "aria-hidden": true }) }),
13458
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("b", { children: named3 ? named3[2] : c.head.text })
13459
+ ] }),
13460
+ c.subs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
13461
+ "button",
13462
+ {
13463
+ type: "button",
13464
+ className: "w100n-docs-chapter-fold",
13465
+ "aria-expanded": opened3,
13466
+ "aria-label": opened3 ? t.hideSections : t.showSections,
13467
+ title: opened3 ? t.hideSections : t.showSections,
13468
+ onClick: () => setFold({ ...fold, [c.head.id]: !opened3 }),
13469
+ children: [
13470
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("small", { children: c.subs.length }),
13471
+ opened3 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.ChevronDown, { "aria-hidden": true }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react10.ChevronRight, { "aria-hidden": true })
13472
+ ]
13473
+ }
13474
+ )
13475
+ ] }),
13476
+ opened3 && subs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "w100n-docs-sections", children: subs.map((s) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
13477
+ "button",
13478
+ {
13479
+ type: "button",
13480
+ "data-level": s.level - top,
13481
+ onClick: () => reach(s),
13482
+ "data-state": i < reached || i === reached && c.subs.indexOf(s) < mark ? "done" : void 0,
13483
+ "aria-current": now?.id === s.id ? "location" : void 0,
13484
+ children: [
13485
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("i", { "aria-hidden": true }),
13486
+ s.text
13487
+ ]
13488
+ },
13489
+ s.id
13490
+ )) })
13491
+ ] }, c.head.id);
13492
+ })
13493
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "w100n-docs-muted", children: t.noOutline })),
12357
13494
  tab === "versions" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "w100n-docs-versions", children: [
12358
13495
  versions.error && failed(versions.retry),
12359
13496
  (versions.data ?? []).map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
@@ -12444,9 +13581,7 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
12444
13581
  ] }),
12445
13582
  making && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(NewDocument, { host, t, onClose: () => setMaking(false), onMade: (made2) => {
12446
13583
  setMaking(false);
12447
- spaces.retry();
12448
- list.retry();
12449
- ask(() => go({ spaceId: here.spaceId && made2.spaceId, documentId: made2.id }));
13584
+ opened2(made2);
12450
13585
  } }),
12451
13586
  dialog
12452
13587
  ] });