@w100n/documents 0.14.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -201,6 +201,14 @@ var init_text = __esm({
201
201
  chooseFile: "Choose a file",
202
202
  put: "Insert",
203
203
  link: "Link",
204
+ footnote: "Footnote",
205
+ footnoteText: "Footnote text",
206
+ formula: "Formula",
207
+ formulaHint: "Saved as a Word equation",
208
+ symbols: "Special characters",
209
+ symbolSearch: "Search, for example arrow",
210
+ update: "Update",
211
+ removeFootnote: "Remove footnote",
204
212
  linkAddress: "Link address",
205
213
  apply: "Apply",
206
214
  unlink: "Remove link",
@@ -519,6 +527,14 @@ var init_text = __esm({
519
527
  chooseFile: "Wybierz plik",
520
528
  put: "Wstaw",
521
529
  link: "Link",
530
+ footnote: "Przypis",
531
+ footnoteText: "Tekst przypisu",
532
+ formula: "Wz\xF3r",
533
+ formulaHint: "Zapisany jako r\xF3wnanie Word",
534
+ symbols: "Znaki specjalne",
535
+ symbolSearch: "Szukaj, na przyk\u0142ad strza\u0142ka",
536
+ update: "Zmie\u0144",
537
+ removeFootnote: "Usu\u0144 przypis",
522
538
  linkAddress: "Adres linku",
523
539
  apply: "Zastosuj",
524
540
  unlink: "Usu\u0144 link",
@@ -836,6 +852,14 @@ var init_text = __esm({
836
852
  imageLink: "\u0410\u0434\u0440\u0435\u0441\u0430 \u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u043D\u044F",
837
853
  chooseFile: "\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0444\u0430\u0439\u043B",
838
854
  put: "\u0412\u0441\u0442\u0430\u0432\u0438\u0442\u0438",
855
+ footnote: "\u0412\u0438\u043D\u043E\u0441\u043A\u0430",
856
+ footnoteText: "\u0422\u0435\u043A\u0441\u0442 \u0432\u0438\u043D\u043E\u0441\u043A\u0438",
857
+ formula: "\u0424\u043E\u0440\u043C\u0443\u043B\u0430",
858
+ formulaHint: "\u0417\u0431\u0435\u0440\u0456\u0433\u0430\u0454\u0442\u044C\u0441\u044F \u044F\u043A \u0440\u0456\u0432\u043D\u044F\u043D\u043D\u044F Word",
859
+ symbols: "\u0421\u043F\u0435\u0446\u0441\u0438\u043C\u0432\u043E\u043B\u0438",
860
+ symbolSearch: "\u041F\u043E\u0448\u0443\u043A, \u043D\u0430\u043F\u0440\u0438\u043A\u043B\u0430\u0434 \u0441\u0442\u0440\u0456\u043B\u043A\u0430",
861
+ update: "\u0417\u043C\u0456\u043D\u0438\u0442\u0438",
862
+ removeFootnote: "\u0412\u0438\u0434\u0430\u043B\u0438\u0442\u0438 \u0432\u0438\u043D\u043E\u0441\u043A\u0443",
839
863
  link: "\u041F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F",
840
864
  linkAddress: "\u0410\u0434\u0440\u0435\u0441\u0430 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F",
841
865
  apply: "\u0417\u0430\u0441\u0442\u043E\u0441\u0443\u0432\u0430\u0442\u0438",
@@ -1772,6 +1796,272 @@ var init_pkg = __esm({
1772
1796
  }
1773
1797
  });
1774
1798
 
1799
+ // src/editor/math.ts
1800
+ function parse3(src) {
1801
+ let i = 0;
1802
+ const group = () => {
1803
+ if (src[i] === "{") {
1804
+ i++;
1805
+ const kids2 = row2("}");
1806
+ i++;
1807
+ return kids2.length === 1 ? kids2[0] : { t: "row", kids: kids2 };
1808
+ }
1809
+ return one2() ?? { t: "row", kids: [] };
1810
+ };
1811
+ const one2 = () => {
1812
+ while (src[i] === " ") i++;
1813
+ if (i >= src.length) return null;
1814
+ const c = src[i];
1815
+ if (c === "{") return group();
1816
+ if (c === "\\") {
1817
+ const m = /^\\([a-zA-Z]+|.)/.exec(src.slice(i));
1818
+ if (!m) {
1819
+ i++;
1820
+ return { t: "tok", v: "\\", kind: "mo" };
1821
+ }
1822
+ i += m[0].length;
1823
+ const name = m[1];
1824
+ if (name === "frac") return { t: "frac", num: group(), den: group() };
1825
+ if (name === "sqrt") {
1826
+ let deg = null;
1827
+ if (src[i] === "[") {
1828
+ const end = src.indexOf("]", i);
1829
+ deg = parse3(src.slice(i + 1, end < 0 ? src.length : end));
1830
+ i = end < 0 ? src.length : end + 1;
1831
+ }
1832
+ return { t: "sqrt", body: group(), deg };
1833
+ }
1834
+ if (name === "text" || name === "mathrm") {
1835
+ const g = src[i] === "{" ? src.indexOf("}", i) : -1;
1836
+ const v = g < 0 ? "" : src.slice(i + 1, g);
1837
+ i = g < 0 ? i : g + 1;
1838
+ return { t: "tok", v, kind: "mtext" };
1839
+ }
1840
+ if (name === "left" || name === "right") return one2();
1841
+ if (words[name]) return { t: "tok", v: words[name], kind: "mi" };
1842
+ if (ops[name]) return { t: "tok", v: ops[name], kind: "mo" };
1843
+ return { t: "tok", v: name.length === 1 ? name : `\\${name}`, kind: name.length === 1 ? "mo" : "mi" };
1844
+ }
1845
+ if (/[0-9.]/.test(c)) {
1846
+ const m = /^[0-9]*\.?[0-9]+|^[0-9]+/.exec(src.slice(i));
1847
+ i += m[0].length;
1848
+ return { t: "tok", v: m[0], kind: "mn" };
1849
+ }
1850
+ i++;
1851
+ if (/[\p{L}]/u.test(c)) return { t: "tok", v: c, kind: big.has(c) ? "mo" : "mi" };
1852
+ return { t: "tok", v: c, kind: "mo" };
1853
+ };
1854
+ const row2 = (stop) => {
1855
+ const kids2 = [];
1856
+ while (i < src.length && src[i] !== stop) {
1857
+ while (src[i] === " ") i++;
1858
+ if (i >= src.length || src[i] === stop) break;
1859
+ if (src[i] === "^" || src[i] === "_") {
1860
+ const base = kids2.pop() ?? { t: "row", kids: [] };
1861
+ const s = base.t === "script" && !base.sub !== !base.sup ? base : { t: "script", base, sub: null, sup: null };
1862
+ const which = src[i++] === "^" ? "sup" : "sub";
1863
+ s[which] = group();
1864
+ kids2.push(s);
1865
+ continue;
1866
+ }
1867
+ if (src[i] === "}") {
1868
+ i++;
1869
+ continue;
1870
+ }
1871
+ const a = one2();
1872
+ if (a) kids2.push(a);
1873
+ }
1874
+ return kids2;
1875
+ };
1876
+ const kids = row2("\0");
1877
+ return kids.length === 1 ? kids[0] : { t: "row", kids };
1878
+ }
1879
+ function ml(a) {
1880
+ switch (a.t) {
1881
+ case "tok":
1882
+ return `<${a.kind}>${esc(a.v)}</${a.kind}>`;
1883
+ case "row":
1884
+ return `<mrow>${a.kids.map(ml).join("")}</mrow>`;
1885
+ case "frac":
1886
+ return `<mfrac>${ml(a.num)}${ml(a.den)}</mfrac>`;
1887
+ case "sqrt":
1888
+ return a.deg ? `<mroot>${ml(a.body)}${ml(a.deg)}</mroot>` : `<msqrt>${ml(a.body)}</msqrt>`;
1889
+ case "script": {
1890
+ const over = a.base.t === "tok" && big.has(a.base.v);
1891
+ if (a.sub && a.sup) return `<${over ? "munderover" : "msubsup"}>${ml(a.base)}${ml(a.sub)}${ml(a.sup)}</${over ? "munderover" : "msubsup"}>`;
1892
+ if (a.sub) return `<${over ? "munder" : "msub"}>${ml(a.base)}${ml(a.sub)}</${over ? "munder" : "msub"}>`;
1893
+ return `<${over ? "mover" : "msup"}>${ml(a.base)}${ml(a.sup)}</${over ? "mover" : "msup"}>`;
1894
+ }
1895
+ }
1896
+ }
1897
+ function om(a) {
1898
+ switch (a.t) {
1899
+ case "tok":
1900
+ return run(a.v, a.kind === "mtext" || a.kind === "mo" && !big.has(a.v));
1901
+ case "row":
1902
+ return a.kids.map(om).join("");
1903
+ case "frac":
1904
+ return `<m:f><m:num>${om(a.num)}</m:num><m:den>${om(a.den)}</m:den></m:f>`;
1905
+ case "sqrt":
1906
+ return a.deg ? `<m:rad><m:deg>${om(a.deg)}</m:deg><m:e>${om(a.body)}</m:e></m:rad>` : `<m:rad><m:radPr><m:degHide m:val="1"/></m:radPr><m:deg/><m:e>${om(a.body)}</m:e></m:rad>`;
1907
+ case "script": {
1908
+ if (a.base.t === "tok" && big.has(a.base.v)) return `<m:nary><m:naryPr><m:chr m:val="${a.base.v}"/>${a.sub ? "" : '<m:subHide m:val="1"/>'}${a.sup ? "" : '<m:supHide m:val="1"/>'}</m:naryPr><m:sub>${a.sub ? om(a.sub) : ""}</m:sub><m:sup>${a.sup ? om(a.sup) : ""}</m:sup><m:e/></m:nary>`;
1909
+ if (a.sub && a.sup) return `<m:sSubSup><m:e>${om(a.base)}</m:e><m:sub>${om(a.sub)}</m:sub><m:sup>${om(a.sup)}</m:sup></m:sSubSup>`;
1910
+ if (a.sub) return `<m:sSub><m:e>${om(a.base)}</m:e><m:sub>${om(a.sub)}</m:sub></m:sSub>`;
1911
+ return `<m:sSup><m:e>${om(a.base)}</m:e><m:sup>${om(a.sup)}</m:sup></m:sSup>`;
1912
+ }
1913
+ }
1914
+ }
1915
+ function tree(xml) {
1916
+ const root = { name: "", kids: [], text: "", attrs: {} };
1917
+ const stack = [root];
1918
+ for (const m of xml.matchAll(/<(\/?)([\w:]+)([^>]*?)(\/?)>|([^<]+)/g)) {
1919
+ const top = stack[stack.length - 1];
1920
+ if (m[5] !== void 0) {
1921
+ top.text += m[5];
1922
+ continue;
1923
+ }
1924
+ if (m[1]) {
1925
+ stack.pop();
1926
+ continue;
1927
+ }
1928
+ const attrs2 = Object.fromEntries([...m[3].matchAll(/([\w:]+)="([^"]*)"/g)].map((a) => [a[1], a[2]]));
1929
+ const node = { name: m[2], kids: [], text: "", attrs: attrs2 };
1930
+ top.kids.push(node);
1931
+ if (!m[4]) stack.push(node);
1932
+ }
1933
+ return root;
1934
+ }
1935
+ function tex(n) {
1936
+ const part = (name) => n.kids.find((k) => k.name === name);
1937
+ const all = (k) => k ? k.kids.map(tex).join("") : "";
1938
+ switch (n.name) {
1939
+ case "m:t":
1940
+ return [...unesc(n.text)].map((ch) => glyph[ch] ? `\\${glyph[ch]} ` : ch).join("");
1941
+ case "m:f":
1942
+ return `\\frac{${all(part("m:num"))}}{${all(part("m:den"))}}`;
1943
+ case "m:sSup":
1944
+ return `${brace(all(part("m:e")))}^${brace(all(part("m:sup")))}`;
1945
+ case "m:sSub":
1946
+ return `${brace(all(part("m:e")))}_${brace(all(part("m:sub")))}`;
1947
+ case "m:sSubSup":
1948
+ return `${brace(all(part("m:e")))}_${brace(all(part("m:sub")))}^${brace(all(part("m:sup")))}`;
1949
+ case "m:rad": {
1950
+ const deg = all(part("m:deg"));
1951
+ return `\\sqrt${deg ? `[${deg}]` : ""}{${all(part("m:e"))}}`;
1952
+ }
1953
+ case "m:nary": {
1954
+ const chr = part("m:naryPr")?.kids.find((k) => k.name === "m:chr")?.attrs["m:val"] ?? "\u222B";
1955
+ const sub = all(part("m:sub")), sup = all(part("m:sup"));
1956
+ return `${glyph[chr] ? `\\${glyph[chr]}` : chr}${sub ? `_${brace(sub)}` : ""}${sup ? `^${brace(sup)}` : ""} ${all(part("m:e"))}`.trim();
1957
+ }
1958
+ case "m:d": {
1959
+ const pr = part("m:dPr")?.kids ?? [];
1960
+ const beg = pr.find((k) => k.name === "m:begChr")?.attrs["m:val"] ?? "(";
1961
+ const end = pr.find((k) => k.name === "m:endChr")?.attrs["m:val"] ?? ")";
1962
+ return `${beg}${n.kids.filter((k) => k.name === "m:e").map(all).join(",")}${end}`;
1963
+ }
1964
+ case "m:rPr":
1965
+ case "m:ctrlPr":
1966
+ case "w:rPr":
1967
+ case "m:naryPr":
1968
+ case "m:dPr":
1969
+ case "m:radPr":
1970
+ case "m:fPr":
1971
+ case "m:sSupPr":
1972
+ case "m:sSubPr":
1973
+ case "m:sSubSupPr":
1974
+ return "";
1975
+ default:
1976
+ return n.kids.map(tex).join("");
1977
+ }
1978
+ }
1979
+ var words, ops, big, glyph, esc, mathml, run, omml, unesc, brace, latexOf;
1980
+ var init_math = __esm({
1981
+ "src/editor/math.ts"() {
1982
+ "use strict";
1983
+ words = {
1984
+ alpha: "\u03B1",
1985
+ beta: "\u03B2",
1986
+ gamma: "\u03B3",
1987
+ delta: "\u03B4",
1988
+ epsilon: "\u03B5",
1989
+ zeta: "\u03B6",
1990
+ eta: "\u03B7",
1991
+ theta: "\u03B8",
1992
+ iota: "\u03B9",
1993
+ kappa: "\u03BA",
1994
+ lambda: "\u03BB",
1995
+ mu: "\u03BC",
1996
+ nu: "\u03BD",
1997
+ xi: "\u03BE",
1998
+ pi: "\u03C0",
1999
+ rho: "\u03C1",
2000
+ sigma: "\u03C3",
2001
+ tau: "\u03C4",
2002
+ upsilon: "\u03C5",
2003
+ phi: "\u03C6",
2004
+ chi: "\u03C7",
2005
+ psi: "\u03C8",
2006
+ omega: "\u03C9",
2007
+ Gamma: "\u0393",
2008
+ Delta: "\u0394",
2009
+ Theta: "\u0398",
2010
+ Lambda: "\u039B",
2011
+ Xi: "\u039E",
2012
+ Pi: "\u03A0",
2013
+ Sigma: "\u03A3",
2014
+ Phi: "\u03A6",
2015
+ Psi: "\u03A8",
2016
+ Omega: "\u03A9",
2017
+ infty: "\u221E",
2018
+ partial: "\u2202",
2019
+ nabla: "\u2207"
2020
+ };
2021
+ ops = {
2022
+ cdot: "\xB7",
2023
+ times: "\xD7",
2024
+ div: "\xF7",
2025
+ pm: "\xB1",
2026
+ mp: "\u2213",
2027
+ le: "\u2264",
2028
+ leq: "\u2264",
2029
+ ge: "\u2265",
2030
+ geq: "\u2265",
2031
+ ne: "\u2260",
2032
+ neq: "\u2260",
2033
+ approx: "\u2248",
2034
+ equiv: "\u2261",
2035
+ to: "\u2192",
2036
+ rightarrow: "\u2192",
2037
+ leftarrow: "\u2190",
2038
+ Rightarrow: "\u21D2",
2039
+ in: "\u2208",
2040
+ notin: "\u2209",
2041
+ subset: "\u2282",
2042
+ cup: "\u222A",
2043
+ cap: "\u2229",
2044
+ forall: "\u2200",
2045
+ exists: "\u2203",
2046
+ sum: "\u2211",
2047
+ prod: "\u220F",
2048
+ int: "\u222B",
2049
+ oint: "\u222E",
2050
+ degree: "\xB0"
2051
+ };
2052
+ big = /* @__PURE__ */ new Set(["\u2211", "\u220F", "\u222B", "\u222E"]);
2053
+ glyph = {};
2054
+ for (const [k, v] of [...Object.entries(words), ...Object.entries(ops)]) glyph[v] ?? (glyph[v] = k);
2055
+ esc = (v) => v.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
2056
+ mathml = (latex) => `<math xmlns="http://www.w3.org/1998/Math/MathML">${ml(parse3(latex))}</math>`;
2057
+ run = (v, plain4 = false) => `<m:r>${plain4 ? '<m:rPr><m:sty m:val="p"/></m:rPr>' : ""}<m:t xml:space="preserve">${esc(v)}</m:t></m:r>`;
2058
+ omml = (latex) => `<m:oMath xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math">${om(parse3(latex))}</m:oMath>`;
2059
+ unesc = (v) => v.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
2060
+ brace = (v) => v.length === 1 ? v : `{${v}}`;
2061
+ latexOf = (xml) => tex(tree(xml)).replace(/\s+/g, " ").trim();
2062
+ }
2063
+ });
2064
+
1775
2065
  // src/docx/read.ts
1776
2066
  function align(v) {
1777
2067
  if (v === "center") return "center";
@@ -1855,6 +2145,11 @@ function inline2(pieces2) {
1855
2145
  const out = [];
1856
2146
  let key2 = "";
1857
2147
  for (const p of pieces2) {
2148
+ if (p.math !== void 0 || p.note) {
2149
+ out.push(p.note ? { type: "footnote", attrs: { id: p.note.id, text: p.note.text } } : { type: "math", attrs: { latex: p.math } });
2150
+ key2 = "";
2151
+ continue;
2152
+ }
1858
2153
  if (p.img) {
1859
2154
  out.push({ type: "image", attrs: { ...p.img } });
1860
2155
  key2 = "";
@@ -1920,12 +2215,13 @@ function nest(list) {
1920
2215
  }
1921
2216
  return root;
1922
2217
  }
1923
- var blank2, mimes, Reader;
2218
+ var blank2, mimes, Reader, noteText;
1924
2219
  var init_read = __esm({
1925
2220
  "src/docx/read.ts"() {
1926
2221
  "use strict";
1927
2222
  init_pkg();
1928
2223
  init_xml();
2224
+ init_math();
1929
2225
  blank2 = () => ({ align: null, indent: 0, line: null, after: null, ref: null });
1930
2226
  mimes = { png: "image/png", jpg: "image/jpeg", jpeg: "image/jpeg", gif: "image/gif", bmp: "image/bmp", webp: "image/webp", svg: "image/svg+xml" };
1931
2227
  Reader = class {
@@ -1933,6 +2229,7 @@ var init_read = __esm({
1933
2229
  this.pkg = pkg;
1934
2230
  this.n = 0;
1935
2231
  this.refs = /* @__PURE__ */ new Map();
2232
+ this.footnotes = null;
1936
2233
  this.counters = /* @__PURE__ */ new Map();
1937
2234
  this.fmts = /* @__PURE__ */ new Map();
1938
2235
  this.media = /* @__PURE__ */ new Map();
@@ -2090,6 +2387,14 @@ var init_read = __esm({
2090
2387
  }
2091
2388
  return b;
2092
2389
  }
2390
+ notes() {
2391
+ if (!this.footnotes) {
2392
+ const rel = this.pkg.byType("/footnotes");
2393
+ const xml = rel ? this.pkg.text(rel.target) ?? "" : "";
2394
+ this.footnotes = new Map([...xml.matchAll(/<w:footnote\b[^>]*\bw:id="(-?\d+)"[^>]*>([\s\S]*?)<\/w:footnote>/g)].map((m) => [m[1], noteText(m[2])]));
2395
+ }
2396
+ return this.footnotes;
2397
+ }
2093
2398
  src(embed) {
2094
2399
  if (!this.media.has(embed)) {
2095
2400
  const rel = this.pkg.rels.get(embed);
@@ -2135,10 +2440,8 @@ var init_read = __esm({
2135
2440
  const inside = [];
2136
2441
  this.walk(k.kids, ctx, k, inside, { lock: null, task: false, box: false });
2137
2442
  this.span(s.slice(k.start, k.end), inside, out, ctx, hyperlink(attr(s, k, "w:instr") ?? ""));
2138
- } else if (name === "m:oMath") {
2139
- const text = s.slice(k.start, k.end).match(/<m:t(?:\s[^>]*)?>[^<]*<\/m:t>/g)?.map((t) => inner(t, parse2(t).kids[0])).join("") ?? "";
2140
- this.span(s.slice(k.start, k.end), text ? [{ text, raw: null, run: null, ctx, span: null }] : [], out, ctx, null);
2141
- } else if (name === "m:oMathPara") st.lock = "Equation";
2443
+ } else if (name === "m:oMath") out.push({ text: "\uE000", raw: s.slice(k.start, k.end), run: null, ctx, span: null, math: latexOf(s.slice(k.start, k.end)) });
2444
+ else if (name === "m:oMathPara") st.lock = "Equation";
2142
2445
  else out.push({ text: null, raw: s.slice(k.start, k.end), run: null, ctx, span: null });
2143
2446
  }
2144
2447
  }
@@ -2159,17 +2462,17 @@ var init_read = __esm({
2159
2462
  out.push({ text: null, raw: s.slice(k.start, k.end), run: null, ctx, span: null });
2160
2463
  return;
2161
2464
  }
2162
- const run2 = { open: opened(s, k), rPr: rPrEl ? s.slice(rPrEl.start, rPrEl.end) : "", fmt: f, el: k, parent };
2465
+ const run3 = { open: opened(s, k), rPr: rPrEl ? s.slice(rPrEl.start, rPrEl.end) : "", fmt: f, el: k, parent };
2163
2466
  const push = (text, raw, extra) => {
2164
2467
  if (text !== null && st.box) {
2165
2468
  st.box = false;
2166
2469
  if (text.startsWith(" ") && raw === null) {
2167
- out.push({ text: null, raw: '<w:t xml:space="preserve"> </w:t>', run: run2, ctx, span: null, box: true });
2470
+ out.push({ text: null, raw: '<w:t xml:space="preserve"> </w:t>', run: run3, ctx, span: null, box: true });
2168
2471
  text = text.slice(1);
2169
2472
  if (!text) return;
2170
2473
  }
2171
2474
  }
2172
- out.push({ text, raw, run: run2, ctx, span: null, ...extra });
2475
+ out.push({ text, raw, run: run3, ctx, span: null, ...extra });
2173
2476
  };
2174
2477
  for (const c of k.kids) {
2175
2478
  const raw = s.slice(c.start, c.end);
@@ -2202,6 +2505,11 @@ var init_read = __esm({
2202
2505
  else push("\n", raw);
2203
2506
  break;
2204
2507
  }
2508
+ case "w:footnoteReference": {
2509
+ const id = attr(s, c, "w:id") ?? "";
2510
+ push("\uE001", raw, { note: { id, text: this.notes().get(id) ?? "" } });
2511
+ break;
2512
+ }
2205
2513
  case "w:fldChar":
2206
2514
  push(null, raw, { fld: attr(s, c, "w:fldCharType") ?? "" });
2207
2515
  break;
@@ -2339,6 +2647,7 @@ var init_read = __esm({
2339
2647
  return b;
2340
2648
  }
2341
2649
  };
2650
+ noteText = (xml) => [...xml.matchAll(/<w:t(?:\s[^>]*)?>([^<]*)<\/w:t>/g)].map((m) => m[1]).join("").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&amp;/g, "&").trim();
2342
2651
  }
2343
2652
  });
2344
2653
 
@@ -2428,7 +2737,7 @@ function inlineSig(kids) {
2428
2737
  out += (next === key2 ? "" : `${next}`) + k.text;
2429
2738
  key2 = next;
2430
2739
  } else {
2431
- out += `${k.type}${k.type === "image" ? picture2(k.attrs ?? {}) : ""}`;
2740
+ out += `${k.type}${k.type === "image" ? picture2(k.attrs ?? {}) : k.type === "math" ? k.attrs?.latex : k.type === "footnote" ? `${k.attrs?.id}:${k.attrs?.text}` : ""}`;
2432
2741
  key2 = null;
2433
2742
  }
2434
2743
  }
@@ -2561,6 +2870,7 @@ var init_write = __esm({
2561
2870
  init_read();
2562
2871
  init_xml();
2563
2872
  init_zip();
2873
+ init_math();
2564
2874
  P = ["w:pStyle", "w:keepNext", "w:keepLines", "w:pageBreakBefore", "w:framePr", "w:widowControl", "w:numPr", "w:suppressLineNumbers", "w:pBdr", "w:shd", "w:tabs", "w:suppressAutoHyphens", "w:kinsoku", "w:wordWrap", "w:overflowPunct", "w:topLinePunct", "w:autoSpaceDE", "w:autoSpaceDN", "w:bidi", "w:adjustRightInd", "w:snapToGrid", "w:spacing", "w:ind", "w:contextualSpacing", "w:mirrorIndents", "w:suppressOverlap", "w:jc", "w:textDirection", "w:textAlignment", "w:textboxTightWrap", "w:outlineLvl", "w:divId", "w:cnfStyle", "w:rPr", "w:sectPr", "w:pPrChange"];
2565
2875
  R = ["w:rStyle", "w:rFonts", "w:b", "w:bCs", "w:i", "w:iCs", "w:caps", "w:smallCaps", "w:strike", "w:dstrike", "w:outline", "w:shadow", "w:emboss", "w:imprint", "w:noProof", "w:snapToGrid", "w:vanish", "w:webHidden", "w:color", "w:spacing", "w:w", "w:kern", "w:position", "w:sz", "w:szCs", "w:highlight", "w:u", "w:effect", "w:bdr", "w:shd", "w:fitText", "w:vertAlign", "w:rtl", "w:cs", "w:em", "w:lang", "w:eastAsianLayout", "w:specVanish", "w:oMath"];
2566
2876
  TC = ["w:cnfStyle", "w:tcW", "w:gridSpan", "w:hMerge", "w:vMerge", "w:tcBorders", "w:shd", "w:noWrap", "w:tcMar", "w:textDirection", "w:tcFitText", "w:vAlign", "w:hideMark", "w:headers", "w:cellIns", "w:cellDel", "w:cellMerge", "w:tcPrChange"];
@@ -2602,6 +2912,7 @@ var init_write = __esm({
2602
2912
  this.srcs = null;
2603
2913
  this.tocs = false;
2604
2914
  this.revs = /* @__PURE__ */ new Map();
2915
+ this.lastNote = null;
2605
2916
  this.r = new Reader(pkg);
2606
2917
  this.s = pkg.doc;
2607
2918
  for (const id of pkg.rels.keys()) this.relIds.add(id);
@@ -2624,6 +2935,7 @@ var init_write = __esm({
2624
2935
  if (this.last === "tbl" && list[list.length - 1]?.kind !== "tbl") xml += "<w:p/>";
2625
2936
  const changed2 = /* @__PURE__ */ new Map();
2626
2937
  const text = this.marginal(s.slice(0, body.open) + xml + rest + s.slice(tail), setup, changed2);
2938
+ this.footnotes(doc, changed2);
2627
2939
  if (text !== s) changed2.set(this.pkg.main, text);
2628
2940
  if (this.rels.length) {
2629
2941
  const path = this.pkg.relsPath(this.pkg.main);
@@ -2749,6 +3061,37 @@ var init_write = __esm({
2749
3061
  if (o.kind === "toc") return b && sig(o.node) === sig(b.node) ? s.slice(b.start, b.end) : this.toc(o.node);
2750
3062
  return this.code(o);
2751
3063
  }
3064
+ noteId() {
3065
+ const rel = this.pkg.byType("/footnotes");
3066
+ const xml = rel ? this.pkg.text(rel.target) ?? "" : "";
3067
+ this.lastNote ?? (this.lastNote = Math.max(0, ...[...xml.matchAll(/<w:footnote\b[^>]*\bw:id="(-?\d+)"/g)].map((m) => +m[1])));
3068
+ return ++this.lastNote;
3069
+ }
3070
+ footnotes(doc, changed2) {
3071
+ const notes2 = [];
3072
+ const walk = (n) => {
3073
+ if (n.type === "footnote" && n.attrs?.id) notes2.push({ id: String(n.attrs.id), text: String(n.attrs.text ?? "") });
3074
+ n.content?.forEach(walk);
3075
+ };
3076
+ walk(doc);
3077
+ const rel = this.pkg.byType("/footnotes");
3078
+ const old = rel ? this.pkg.text(rel.target) : null;
3079
+ if (!notes2.length) return;
3080
+ const path = rel ? rel.target : "word/footnotes.xml";
3081
+ let xml = old ?? `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
3082
+ <w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="${REL}"><w:footnote w:type="separator" w:id="-1"><w:p><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:type="continuationSeparator" w:id="0"><w:p><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr><w:r><w:continuationSeparator/></w:r></w:p></w:footnote></w:footnotes>`;
3083
+ const fresh2 = (id, words2) => `<w:footnote w:id="${id}"><w:p><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr><w:r><w:rPr><w:vertAlign w:val="superscript"/></w:rPr><w:footnoteRef/></w:r><w:r><w:rPr><w:sz w:val="20"/></w:rPr><w:t xml:space="preserve"> ${escape2(words2)}</w:t></w:r></w:p></w:footnote>`;
3084
+ for (const n of notes2) {
3085
+ const found = new RegExp(`<w:footnote\\b[^>]*\\bw:id="${n.id}"[^>]*>([\\s\\S]*?)</w:footnote>`).exec(xml);
3086
+ if (found && noteText(found[1]) === n.text) continue;
3087
+ xml = found ? xml.replace(found[0], fresh2(n.id, n.text)) : xml.replace(/<\/w:footnotes>\s*$/, fresh2(n.id, n.text) + "</w:footnotes>");
3088
+ }
3089
+ if (xml === old) return;
3090
+ changed2.set(path, xml);
3091
+ if (rel) return;
3092
+ this.rels.push(`<Relationship Id="${this.relId()}" Type="${REL}/footnotes" Target="footnotes.xml"/>`);
3093
+ this.types.add(`<Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/>`);
3094
+ }
2752
3095
  marginal(text, setup, changed2) {
2753
3096
  if (!setup || !setup.page && setup.header === void 0 && setup.footer === void 0 && setup.numbers === void 0) return text;
2754
3097
  const end = text.lastIndexOf("</w:body>");
@@ -2812,11 +3155,11 @@ var init_write = __esm({
2812
3155
  const open = sec.indexOf(">") + 1;
2813
3156
  sec = sec.slice(0, open) + `<w:${kind}Reference w:type="default" r:id="${id}"/>` + sec.slice(open);
2814
3157
  };
2815
- const line = (words, page) => {
3158
+ const line = (words2, page) => {
2816
3159
  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>`;
3160
+ const run3 = words2 ? `<w:r><w:t xml:space="preserve">${escape2(words2)}</w:t></w:r>` : "";
3161
+ if (!words2 && !page) return "";
3162
+ return `<w:p><w:pPr>${page && words2 ? `<w:tabs><w:tab w:val="right" w:pos="${this.textWidth()}"/></w:tabs>` : page ? '<w:jc w:val="right"/>' : ""}</w:pPr>${run3}${page && words2 ? "<w:r><w:tab/></w:r>" : ""}${page ? field : ""}</w:p>`;
2820
3163
  };
2821
3164
  if (setup.header !== void 0) part("header", line(setup.header, false));
2822
3165
  if (setup.footer !== void 0 || setup.numbers !== void 0) part("footer", line(setup.footer ?? "", !!setup.numbers));
@@ -3009,7 +3352,7 @@ var init_write = __esm({
3009
3352
  const base = p.span ? fmtAt({ ...p, span: null }) : fmt;
3010
3353
  if (p.img) units.push({ ch: "\uFFFC", raw: p.raw, run: p.run, ctx: p.ctx, span: null, idx: n++, fmt, base, img: p.img });
3011
3354
  else if (p.text === null) units.push({ ch: null, raw: p.raw, run: p.run, ctx: p.ctx, span: null, idx: n++, fmt, base, box: p.box });
3012
- else if (p.raw !== null) units.push({ ch: p.text, raw: p.raw, run: p.run, ctx: p.ctx, span: p.span, idx: n++, fmt, base });
3355
+ else if (p.raw !== null) units.push({ ch: p.text, raw: p.raw, run: p.run, ctx: p.ctx, span: p.span, idx: n++, fmt, base, math: p.math, note: p.note });
3013
3356
  else for (const ch of p.text) units.push({ ch, raw: null, run: p.run, ctx: p.ctx, span: p.span, idx: n++, fmt, base });
3014
3357
  if (p.run) counts.set(p.run, n);
3015
3358
  }
@@ -3024,6 +3367,8 @@ var init_write = __esm({
3024
3367
  for (const ch of n.text ?? "") B.push({ ch: ch === "\r" ? "\n" : ch, fmt: f, key: k });
3025
3368
  } else if (n.type === "hardBreak") B.push({ ch: "\n", fmt: lastFmt, key: keyOf(lastFmt) });
3026
3369
  else if (n.type === "image") B.push({ ch: "\uFFFC", fmt: lastFmt, key: keyOf(lastFmt), img: n.attrs ?? {} });
3370
+ else if (n.type === "math") B.push({ ch: "\uE000", fmt: lastFmt, key: keyOf(lastFmt), math: String(n.attrs?.latex ?? "") });
3371
+ else if (n.type === "footnote") B.push({ ch: "\uE001", fmt: lastFmt, key: keyOf(lastFmt), note: n.attrs ?? (n.attrs = {}) });
3027
3372
  }
3028
3373
  const boxes3 = units.filter((u) => u.box);
3029
3374
  let box2 = null;
@@ -3079,6 +3424,22 @@ var init_write = __esm({
3079
3424
  } else out.push({ ch: want.ch, raw: this.drawing(want.img), run: { open: "<w:r>", rPr: "", fmt: plain, el: null, parent: null }, ctx: [], u: null, fmt: plain });
3080
3425
  continue;
3081
3426
  }
3427
+ if (want.math !== void 0) {
3428
+ const u = i >= 0 ? A[i] : null;
3429
+ out.push(u?.math === want.math ? { ch: u.ch, raw: u.raw, run: null, ctx: u.ctx, u, fmt: u.fmt } : { ch: want.ch, raw: omml(want.math), run: null, ctx: u?.ctx ?? [], u: null, fmt: plain });
3430
+ continue;
3431
+ }
3432
+ if (want.note) {
3433
+ const u = i >= 0 ? A[i] : null;
3434
+ if (u?.note && (u.note.id === want.note.id || !want.note.id)) {
3435
+ want.note.id = u.note.id;
3436
+ out.push({ ch: u.ch, raw: u.raw, run: u.run, ctx: u.ctx, u, fmt: u.fmt });
3437
+ } else {
3438
+ want.note.id = typeof want.note.id === "string" && want.note.id ? want.note.id : String(this.noteId());
3439
+ out.push({ ch: want.ch, raw: `<w:footnoteReference w:id="${want.note.id}"/>`, run: { open: "<w:r>", rPr: '<w:rPr><w:vertAlign w:val="superscript"/></w:rPr>', fmt: plain, el: null, parent: null }, ctx: [], u: null, fmt: plain });
3440
+ }
3441
+ continue;
3442
+ }
3082
3443
  if (i >= 0) {
3083
3444
  const u = A[i];
3084
3445
  if (u.span && intact.has(u.span)) {
@@ -3088,18 +3449,18 @@ var init_write = __esm({
3088
3449
  const from = u.span ? u.base : u.fmt;
3089
3450
  const keep = u.ch === "\n" || keyOf(from) === want.key;
3090
3451
  const fmt = keep ? from : want.fmt;
3091
- const run2 = keep && u.run ? u.run : this.derive(u.run ?? paraBase.run, from, want.fmt);
3092
- out.push({ ch: u.ch, raw: u.raw, run: run2, ctx: this.revised(this.linked(u.ctx, fmt.link, lastChar()), fmt.rev), u: keep && u.run ? u : null, fmt });
3452
+ const run3 = keep && u.run ? u.run : this.derive(u.run ?? paraBase.run, from, want.fmt);
3453
+ out.push({ ch: u.ch, raw: u.raw, run: run3, ctx: this.revised(this.linked(u.ctx, fmt.link, lastChar()), fmt.rev), u: keep && u.run ? u : null, fmt });
3093
3454
  } else {
3094
3455
  const left = lastChar();
3095
3456
  const right = next[j + 1] >= 0 ? A[next[j + 1]] : null;
3096
3457
  const base = left ? { run: left.run, fmt: left.fmt } : right ? { run: right.run ?? paraBase.run, fmt: right.span ? right.base : right.fmt } : paraBase;
3097
- const run2 = keyOf(base.fmt) === want.key ? base.run : this.derive(base.run, base.fmt, want.fmt);
3458
+ const run3 = keyOf(base.fmt) === want.key ? base.run : this.derive(base.run, base.fmt, want.fmt);
3098
3459
  const shared = [];
3099
3460
  if (left && right) {
3100
3461
  for (let k = 0; k < left.ctx.length && left.ctx[k] === right.ctx[k]; k++) if (!left.ctx[k].link) shared.push(left.ctx[k]);
3101
3462
  }
3102
- out.push({ ch: want.ch, raw: null, run: run2, ctx: this.revised(this.linked(shared, want.fmt.link, left), want.fmt.rev), u: null, fmt: want.fmt });
3463
+ out.push({ ch: want.ch, raw: null, run: run3, ctx: this.revised(this.linked(shared, want.fmt.link, left), want.fmt.rev), u: null, fmt: want.fmt });
3103
3464
  }
3104
3465
  }
3105
3466
  let xml = "";
@@ -3182,10 +3543,10 @@ var init_write = __esm({
3182
3543
  this.relIds.add(`rId${n}`);
3183
3544
  return `rId${n}`;
3184
3545
  }
3185
- derive(run2, from, to) {
3186
- const cache2 = run2.derived ?? (run2.derived = /* @__PURE__ */ new Map());
3546
+ derive(run3, from, to) {
3547
+ const cache2 = run3.derived ?? (run3.derived = /* @__PURE__ */ new Map());
3187
3548
  const key2 = keyOf(from) + ">" + keyOf(to);
3188
- if (!cache2.has(key2)) cache2.set(key2, { open: run2.open, rPr: this.delta(run2.rPr, from, to), fmt: to, el: null, parent: null });
3549
+ if (!cache2.has(key2)) cache2.set(key2, { open: run3.open, rPr: this.delta(run3.rPr, from, to), fmt: to, el: null, parent: null });
3189
3550
  return cache2.get(key2);
3190
3551
  }
3191
3552
  delta(rPr, from, to) {
@@ -3234,8 +3595,8 @@ var init_write = __esm({
3234
3595
  } else if (!to.link && from.link && this.pkg.styles.isLink(style)) set["w:rStyle"] = null;
3235
3596
  return Object.keys(set).length ? rebuild(rPr, "w:rPr", R, set) : rPr;
3236
3597
  }
3237
- runXml(run2, glyphs, counts) {
3238
- if (run2.el && glyphs.length === counts.get(run2) && glyphs.every((g, n) => g.u && g.u.run === run2 && g.u.idx === n)) return this.s.slice(run2.el.start, run2.el.end);
3598
+ runXml(run3, glyphs, counts) {
3599
+ if (run3.el && glyphs.length === counts.get(run3) && glyphs.every((g, n) => g.u && g.u.run === run3 && g.u.idx === n)) return this.s.slice(run3.el.start, run3.el.end);
3239
3600
  let body = "";
3240
3601
  let text = "";
3241
3602
  const tag = glyphs[0]?.ctx.some((w) => w.rev?.startsWith('["del"')) ? "w:delText" : "w:t";
@@ -3250,7 +3611,7 @@ var init_write = __esm({
3250
3611
  } else text += g.ch;
3251
3612
  }
3252
3613
  flush();
3253
- return run2.open + run2.rPr + body + "</w:r>";
3614
+ return run3.open + run3.rPr + body + "</w:r>";
3254
3615
  }
3255
3616
  embed(src) {
3256
3617
  if (!this.srcs) {
@@ -3474,14 +3835,14 @@ async function readDocx(bytes) {
3474
3835
  const size2 = sect && kid(sect, "w:pgSz");
3475
3836
  const mar = sect && kid(sect, "w:pgMar");
3476
3837
  const px2 = (el, name, fallback) => Math.round(Math.abs(+((el && attr(s, el, name)) ?? fallback)) / 15 * 100) / 100;
3477
- const words = (kind) => {
3838
+ const words2 = (kind) => {
3478
3839
  const ref = sect?.kids.find((k) => k.name === `w:${kind}Reference` && attr(s, k, "w:type") === "default");
3479
3840
  const part = ref && pkg.rels.get(attr(s, ref, "r:id") ?? "");
3480
3841
  const xml = part ? pkg.text(part.target) ?? "" : "";
3481
3842
  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
3843
  };
3483
- const head2 = words("header");
3484
- const foot = words("footer");
3844
+ const head2 = words2("header");
3845
+ const foot = words2("footer");
3485
3846
  return {
3486
3847
  marginal: { header: head2.text, footer: foot.page ? foot.text.replace(/\s*\d+$/, "") : foot.text, numbers: foot.page },
3487
3848
  doc: { type: "doc", content: content.length ? content : [{ type: "paragraph", attrs: { align: null, indent: 0, ref: null } }] },
@@ -3572,6 +3933,10 @@ function measure(view) {
3572
3933
  const room = page.height - top - bottom;
3573
3934
  const els = [...view.dom.children];
3574
3935
  const gaps = [];
3936
+ const line = page.width - page.margins[1] - page.margins[3];
3937
+ const area = (list) => list.length ? 14 + list.reduce((h, text) => h + 15 * Math.max(1, Math.ceil(text.length * 5.6 / line)), 0) : 0;
3938
+ let notes2 = [];
3939
+ let count = 0;
3575
3940
  let i = 0;
3576
3941
  let shift = 0;
3577
3942
  let start = 0;
@@ -3585,17 +3950,25 @@ function measure(view) {
3585
3950
  if (!el) return;
3586
3951
  const y = el.offsetTop - shift;
3587
3952
  const end = y + el.offsetHeight;
3953
+ const mine = [];
3954
+ node.descendants((d) => {
3955
+ if (d.type.name === "footnote") mine.push(`${count + mine.length + 1} ${d.attrs.text}`);
3956
+ });
3588
3957
  if (node.type.name === "pageBreak") {
3589
- gaps.push({ pos: offset + node.nodeSize, height: start + room - end + bottom + 24 + top, page: gaps.length + 1 });
3958
+ gaps.push({ pos: offset + node.nodeSize, height: start + room - end + bottom + 24 + top, page: gaps.length + 1, notes: notes2 });
3959
+ notes2 = [];
3590
3960
  start = end;
3591
- } else if (end > start + room && y > start) {
3592
- gaps.push({ pos: offset, height: start + room - y + bottom + 24 + top, page: gaps.length + 1 });
3961
+ } else if (end > start + room - area([...notes2, ...mine]) && y > start) {
3962
+ gaps.push({ pos: offset, height: start + room - y + bottom + 24 + top, page: gaps.length + 1, notes: notes2 });
3963
+ notes2 = [];
3593
3964
  start = y;
3594
3965
  }
3966
+ notes2.push(...mine);
3967
+ count += mine.length;
3595
3968
  while (end > start + room) start += room;
3596
3969
  last2 = end;
3597
3970
  });
3598
- gaps.push({ pos: view.state.doc.content.size, height: Math.max(0, start + room - last2), page: gaps.length + 1, end: true });
3971
+ gaps.push({ pos: view.state.doc.content.size, height: Math.max(0, start + room - last2), page: gaps.length + 1, end: true, notes: notes2 });
3599
3972
  return gaps.map((g) => ({ ...g, height: Math.max(0, Math.round(g.height)) }));
3600
3973
  }
3601
3974
  var import_core, import_state, import_view, a4, letter, paging, skip2, Pager;
@@ -3624,11 +3997,11 @@ var init_pager = __esm({
3624
3997
  view(view) {
3625
3998
  let timer = 0;
3626
3999
  let sig2 = "";
3627
- const run2 = () => {
4000
+ const run3 = () => {
3628
4001
  if (!view.dom.isConnected) return;
3629
4002
  const gaps = measure(view);
3630
4003
  const { marks: marks2 } = paging.getState(view.state);
3631
- const next = gaps.map((g) => `${g.pos}:${g.height}`).join() + `|${marks2.header}|${marks2.footer}`;
4004
+ const next = gaps.map((g) => `${g.pos}:${g.height}:${g.notes.join("\n")}`).join() + `|${marks2.header}|${marks2.footer}`;
3632
4005
  if (next === sig2) return;
3633
4006
  sig2 = next;
3634
4007
  const line = (parent, cls, text) => {
@@ -3653,13 +4026,25 @@ var init_pager = __esm({
3653
4026
  el.contentEditable = "false";
3654
4027
  line(el, "w100n-text-foot", marks2.footer);
3655
4028
  if (!g.end) line(el, "w100n-text-head", marks2.header);
4029
+ if (g.notes.length) {
4030
+ const list = document.createElement("div");
4031
+ list.className = "w100n-text-footnotes";
4032
+ for (const note of g.notes) {
4033
+ const p = document.createElement("p");
4034
+ const n = document.createElement("sup");
4035
+ n.textContent = note.slice(0, note.indexOf(" "));
4036
+ p.append(n, note.slice(note.indexOf(" ")));
4037
+ list.append(p);
4038
+ }
4039
+ el.append(list);
4040
+ }
3656
4041
  return el;
3657
- }, { key: `${g.pos}:${g.height}:${g.page}:${marks2.header}:${marks2.footer}`, side: -1, ignoreSelection: true }))]);
4042
+ }, { key: `${g.pos}:${g.height}:${g.page}:${marks2.header}:${marks2.footer}:${g.notes.join("\n")}`, side: -1, ignoreSelection: true }))]);
3658
4043
  view.dispatch(view.state.tr.setMeta(paging, { set }).setMeta("addToHistory", false));
3659
4044
  };
3660
4045
  const later = (ms) => {
3661
4046
  clearTimeout(timer);
3662
- timer = window.setTimeout(run2, ms);
4047
+ timer = window.setTimeout(run3, ms);
3663
4048
  };
3664
4049
  const watch = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(() => later(200));
3665
4050
  watch?.observe(view.dom);
@@ -3735,7 +4120,7 @@ function kit(kind, t, live) {
3735
4120
  Toc.configure({ relative: kind === "markdown", label: t.toc, empty: t.tocEmpty }),
3736
4121
  Note,
3737
4122
  Notes,
3738
- ...kind === "docx" ? [Pager, Locks.configure({ label: t.locked }), revision("insertion", "ins"), revision("deletion", "del"), Suggest] : [],
4123
+ ...kind === "docx" ? [Formula, Footnote, Pager, Locks.configure({ label: t.locked }), revision("insertion", "ins"), revision("deletion", "del"), Suggest] : [],
3739
4124
  ...live ? [import_extension_collaboration.default.configure({ document: live.doc }), import_extension_collaboration_caret.default.configure({ provider: live.link, user: live.user })] : []
3740
4125
  ];
3741
4126
  }
@@ -3778,7 +4163,7 @@ function locate(doc, list) {
3778
4163
  return range ? [{ id: c.id, from: range.from, to: range.to }] : [];
3779
4164
  });
3780
4165
  }
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;
4166
+ 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, Formula, Footnote, headings, Toc, revision, seen, suggesting, Suggest, Note, locks, locked, scan, Locks, paint, remap, Notes, script, textblocks, align2, spacing, indent, clear;
3782
4167
  var init_extensions = __esm({
3783
4168
  "src/editor/extensions.ts"() {
3784
4169
  "use strict";
@@ -3796,6 +4181,7 @@ var init_extensions = __esm({
3796
4181
  import_starter_kit = __toESM(require("@tiptap/starter-kit"), 1);
3797
4182
  import_y_tiptap = require("@tiptap/y-tiptap");
3798
4183
  init_pager();
4184
+ init_math();
3799
4185
  notes = new import_state2.PluginKey("w100n-notes");
3800
4186
  blocks = [
3801
4187
  "paragraph",
@@ -3943,6 +4329,37 @@ var init_extensions = __esm({
3943
4329
  return ["div", { "data-page-break": "", "data-label": this.options.label, class: "w100n-text-break", contenteditable: "false" }];
3944
4330
  }
3945
4331
  });
4332
+ Formula = import_core2.Node.create({
4333
+ name: "math",
4334
+ group: "inline",
4335
+ inline: true,
4336
+ atom: true,
4337
+ selectable: true,
4338
+ addAttributes: () => ({ latex: { default: "", parseHTML: (el) => el.getAttribute("data-math") ?? "" } }),
4339
+ parseHTML: () => [{ tag: "span[data-math]" }],
4340
+ renderHTML: ({ node }) => ["span", { "data-math": node.attrs.latex, class: "w100n-math" }],
4341
+ addNodeView: () => ({ node }) => {
4342
+ const dom = document.createElement("span");
4343
+ dom.className = "w100n-math";
4344
+ dom.dataset.math = node.attrs.latex;
4345
+ dom.contentEditable = "false";
4346
+ dom.innerHTML = mathml(node.attrs.latex);
4347
+ return { dom };
4348
+ }
4349
+ });
4350
+ Footnote = import_core2.Node.create({
4351
+ name: "footnote",
4352
+ group: "inline",
4353
+ inline: true,
4354
+ atom: true,
4355
+ selectable: true,
4356
+ addAttributes: () => ({
4357
+ id: { default: null, parseHTML: (el) => el.getAttribute("data-note-id") },
4358
+ text: { default: "", parseHTML: (el) => el.getAttribute("title") ?? "" }
4359
+ }),
4360
+ parseHTML: () => [{ tag: "sup[data-footnote]" }],
4361
+ renderHTML: ({ node }) => ["sup", { "data-footnote": "", "data-note-id": node.attrs.id ?? void 0, title: node.attrs.text, class: "w100n-fn", contenteditable: "false" }]
4362
+ });
3946
4363
  headings = (doc, after) => {
3947
4364
  const found = [];
3948
4365
  doc.descendants((node, pos) => {
@@ -4239,7 +4656,7 @@ var init_extensions = __esm({
4239
4656
  var version;
4240
4657
  var init_package = __esm({
4241
4658
  "package.json"() {
4242
- version = "0.14.0";
4659
+ version = "0.15.1";
4243
4660
  }
4244
4661
  });
4245
4662
 
@@ -4401,7 +4818,7 @@ function fromMarkdown(source) {
4401
4818
  function serializer(style, hints, before, cell2 = false) {
4402
4819
  let form = null;
4403
4820
  const hint = (node) => hints[node.attrs.ref] ?? {};
4404
- const run2 = (parent, index, types2) => {
4821
+ const run3 = (parent, index, types2) => {
4405
4822
  let n = 0;
4406
4823
  for (let i = index - 1; i >= 0 && types2.includes(parent.child(i).type.name); i--) n++;
4407
4824
  if (!index && before && types2.includes(before.type.name)) n++;
@@ -4415,7 +4832,7 @@ function serializer(style, hints, before, cell2 = false) {
4415
4832
  state.options.tightLists = was;
4416
4833
  };
4417
4834
  const list = (state, node, parent, index) => {
4418
- const bullet = hint(node).bullet ?? (run2(parent, index, ["bulletList", "taskList"]) ? style.bullet === "-" ? "*" : "-" : style.bullet);
4835
+ const bullet = hint(node).bullet ?? (run3(parent, index, ["bulletList", "taskList"]) ? style.bullet === "-" ? "*" : "-" : style.bullet);
4419
4836
  tight(state, node, () => state.renderList(node, " ", () => `${bullet} `));
4420
4837
  };
4421
4838
  const blank6 = { open: "", close: "", mixable: true };
@@ -4463,7 +4880,7 @@ ${lines2.join("")}<!-- /toc -->`);
4463
4880
  taskList: list,
4464
4881
  orderedList(state, node, parent, index) {
4465
4882
  const start = node.attrs.start ?? 1;
4466
- const delim = hint(node).delim ?? (run2(parent, index, ["orderedList"]) ? style.delim === "." ? ")" : "." : style.delim);
4883
+ const delim = hint(node).delim ?? (run3(parent, index, ["orderedList"]) ? style.delim === "." ? ")" : "." : style.delim);
4467
4884
  const width = String(start + node.childCount - 1).length;
4468
4885
  tight(state, node, () => state.renderList(node, " ".repeat(width + 2), (i) => `${start + i}${delim} `));
4469
4886
  },
@@ -4592,7 +5009,7 @@ var init_markdown = __esm({
4592
5009
  return nodes.length === parsed.raws.length ? { ...parsed, nodes } : { ...parsed, nodes: [], raws: [], head: "", tail: "\n" };
4593
5010
  };
4594
5011
  ticks = (node, side2) => {
4595
- const len = Math.max(0, ...(node.isText ? node.text.match(/`+/g) ?? [] : []).map((run2) => run2.length));
5012
+ const len = Math.max(0, ...(node.isText ? node.text.match(/`+/g) ?? [] : []).map((run3) => run3.length));
4596
5013
  return len ? side2 > 0 ? ` ${"`".repeat(len + 1)}` : `${"`".repeat(len + 1)} ` : "`";
4597
5014
  };
4598
5015
  plain2 = (mark, parent, index) => {
@@ -7157,7 +7574,7 @@ async function save(doc, kind, base, put, load3, note) {
7157
7574
  const changed2 = !same3(bytes, base);
7158
7575
  const id = changed2 ? await put(bytes, note ?? named2((texts[who[0].language] ?? texts.en).editedNote, who)) : null;
7159
7576
  const refs2 = [];
7160
- if (changed2) schema.nodeFromJSON(await parse3(kind, bytes)).descendants((n) => {
7577
+ if (changed2) schema.nodeFromJSON(await parse4(kind, bytes)).descendants((n) => {
7161
7578
  if (n.isBlock) refs2.push([n.type.name, n.attrs.ref ?? null]);
7162
7579
  });
7163
7580
  doc.transact(() => {
@@ -7197,7 +7614,7 @@ async function workbook(doc, kind, base, put, who, note) {
7197
7614
  doc.off("afterTransaction", watch);
7198
7615
  }
7199
7616
  }
7200
- var import_core3, import_transform2, import_y_tiptap2, Y2, ours, schemas, schemaOf, parse3, edits, filled, pending, blocks2, same3, named2;
7617
+ var import_core3, import_transform2, import_y_tiptap2, Y2, ours, schemas, schemaOf, parse4, edits, filled, pending, blocks2, same3, named2;
7201
7618
  var init_collab = __esm({
7202
7619
  "src/collab.ts"() {
7203
7620
  "use strict";
@@ -7216,7 +7633,7 @@ var init_collab = __esm({
7216
7633
  ours = "w100n-collab";
7217
7634
  schemas = /* @__PURE__ */ new Map();
7218
7635
  schemaOf = (kind) => schemas.get(kind) ?? schemas.set(kind, (0, import_core3.getSchema)(kit(kind, texts.en))).get(kind);
7219
- parse3 = async (kind, bytes) => kind === "docx" ? (await readDocx(bytes)).doc : fromMarkdown(new TextDecoder().decode(bytes)).doc;
7636
+ parse4 = async (kind, bytes) => kind === "docx" ? (await readDocx(bytes)).doc : fromMarkdown(new TextDecoder().decode(bytes)).doc;
7220
7637
  edits = (tr) => tr.changedParentTypes.has(tr.doc.get("default")) || tr.changedParentTypes.has(tr.doc.get("book")) || tr.changedParentTypes.has(tr.doc.get("setup"));
7221
7638
  filled = (doc) => doc.getXmlFragment("default").length > 0 || doc.getMap("book").size > 0;
7222
7639
  pending = (doc) => doc.getMap("editors").size > 0;
@@ -7311,13 +7728,13 @@ var init_room = __esm({
7311
7728
  }
7312
7729
  store() {
7313
7730
  const room = this.room;
7314
- const run2 = room.busy.then(async () => {
7731
+ const run3 = room.busy.then(async () => {
7315
7732
  const done = await save(room.doc, this.kind, room.base ?? await this.host.content(this.id), async (bytes, note) => (await this.host.save(this.id, bytes, note)).versionId);
7316
7733
  if (done) room.base = done.bytes;
7317
7734
  return done;
7318
7735
  });
7319
- room.busy = run2.catch(() => null);
7320
- return run2;
7736
+ room.busy = run3.catch(() => null);
7737
+ return run3;
7321
7738
  }
7322
7739
  sendStateless(payload) {
7323
7740
  if (!this.live || this.authorizedScope !== "read-write" || !JSON.parse(payload).save) return;
@@ -7458,6 +7875,8 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7458
7875
  const scroller = (0, import_react10.useRef)(null);
7459
7876
  const root = (0, import_react10.useRef)(null);
7460
7877
  const [pop, setPop] = (0, import_react10.useState)(null);
7878
+ const [dialog, setDialog] = (0, import_react10.useState)(null);
7879
+ const field = (0, import_react10.useRef)(null);
7461
7880
  const [more, setMore] = (0, import_react10.useState)(() => typeof localStorage !== "undefined" && localStorage.getItem("w100n-docs-more") === "1");
7462
7881
  const [zoom, setZoom] = (0, import_react10.useState)(null);
7463
7882
  const [layout2, setLayout] = (0, import_react10.useState)(null);
@@ -7550,11 +7969,11 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7550
7969
  const frame = document.createElement("iframe");
7551
7970
  frame.style.cssText = "position:fixed;width:0;height:0;border:0;opacity:0";
7552
7971
  document.body.append(frame);
7553
- const [mt, mr, mb, ml] = page.margins;
7972
+ const [mt, mr, mb, ml2] = page.margins;
7554
7973
  const size2 = docx2 ? `${page.width}px ${page.height}px` : "A4";
7555
7974
  frame.contentDocument.open();
7556
7975
  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"}; }
7976
+ @page { size: ${size2}; margin: ${docx2 ? `${mt}px ${mr}px ${mb}px ${ml2}px` : "20mm"}; }
7558
7977
  body { margin: 0; font: 11pt/1.5 Arial, sans-serif; color: #111; }
7559
7978
  h1 { font-size: 20pt; } h2 { font-size: 15pt; } h3 { font-size: 13pt; }
7560
7979
  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; }
@@ -7601,7 +8020,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
7601
8020
  if (!editor || !source.data) return;
7602
8021
  let timer = 0;
7603
8022
  let last2 = "";
7604
- const run2 = () => {
8023
+ const run3 = () => {
7605
8024
  const list = [];
7606
8025
  editor.state.doc.forEach((node, offset) => {
7607
8026
  if (node.type.name !== "heading" || !node.textContent.trim()) return;
@@ -7619,9 +8038,9 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
7619
8038
  };
7620
8039
  const later = () => {
7621
8040
  clearTimeout(timer);
7622
- timer = window.setTimeout(run2, 300);
8041
+ timer = window.setTimeout(run3, 300);
7623
8042
  };
7624
- run2();
8043
+ run3();
7625
8044
  editor.on("update", later);
7626
8045
  return () => {
7627
8046
  clearTimeout(timer);
@@ -7875,9 +8294,9 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
7875
8294
  return;
7876
8295
  }
7877
8296
  if (!mod2) return;
7878
- const act = (run2) => {
8297
+ const act = (run3) => {
7879
8298
  e.preventDefault();
7880
- run2();
8299
+ run3();
7881
8300
  };
7882
8301
  if (key2 === "s" && can.edit) act(() => void save2());
7883
8302
  else if (key2 === "k" && can.edit) act(linkUp);
@@ -7889,10 +8308,10 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
7889
8308
  else if (key2 === "enter" && docx2) act(() => editor.chain().focus().insertContent({ type: "pageBreak" }).run());
7890
8309
  else if (e.shiftKey && docx2 && ["l", "e", "r", "j"].includes(key2)) act(() => align2(editor, { l: "left", e: "center", r: "right", j: "justify" }[key2]));
7891
8310
  };
7892
- const tool = (icon, label, run2, pressed, disabled) => {
8311
+ const tool = (icon, label, run3, pressed, disabled) => {
7893
8312
  const Icon = icon;
7894
8313
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "aria-label": label, title: label, "aria-pressed": pressed, disabled, onClick: () => {
7895
- run2();
8314
+ run3();
7896
8315
  }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { "aria-hidden": true }) });
7897
8316
  };
7898
8317
  const gap = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-pdf-gap" });
@@ -7934,7 +8353,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
7934
8353
  }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Trash2, { "aria-hidden": true }) })
7935
8354
  ] })
7936
8355
  ] });
7937
- const words = (c) => editing?.id === c.id ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-text-reply w100n-text-edit", onClick: (e) => e.stopPropagation(), children: [
8356
+ const words2 = (c) => editing?.id === c.id ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-text-reply w100n-text-edit", onClick: (e) => e.stopPropagation(), children: [
7938
8357
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
7939
8358
  "textarea",
7940
8359
  {
@@ -7976,7 +8395,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
7976
8395
  }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("i", { style: { background: c } }) }, i))
7977
8396
  ] });
7978
8397
  const mod = /Mac|iPhone|iPad/.test(navigator.platform) ? "\u2318" : "Ctrl+";
7979
- const item = (label, run2, more2 = {}) => ({ label, run: run2, ...more2 });
8398
+ const item = (label, run3, more2 = {}) => ({ label, run: run3, ...more2 });
7980
8399
  const insertToc = () => {
7981
8400
  const at = editor.state.selection.$from.before(1);
7982
8401
  editor.chain().focus().insertContentAt(at, { type: "toc", attrs: { entries: JSON.stringify(entries(editor.state.doc, !docx2, at - 1)) } }).run();
@@ -8026,10 +8445,14 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
8026
8445
  item(t.rule, () => editor.chain().focus().setHorizontalRule().run()),
8027
8446
  "-",
8028
8447
  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` })
8448
+ can.comment && item(t.addComment, begin, { off: state.empty, keys: `${mod}\u2325M` }),
8449
+ "-",
8450
+ item(t.symbols, () => setDialog({ kind: "symbol", query: "" })),
8451
+ docx2 && item(t.formula, () => setDialog({ kind: "formula", latex: "", at: null })),
8452
+ docx2 && item(t.footnote, () => setDialog({ kind: "note", text: "", at: null }))
8030
8453
  ] : []],
8031
8454
  ["format", t.menuFormat, can.edit ? [
8032
- ...styles2.map(([key2, label, run2]) => item(label, run2, { on: state.style === key2 })),
8455
+ ...styles2.map(([key2, label, run3]) => item(label, run3, { on: state.style === key2 })),
8033
8456
  "-",
8034
8457
  item(t.bold, () => editor.chain().focus().toggleBold().run(), { on: state.bold, keys: `${mod}B` }),
8035
8458
  item(t.italic, () => editor.chain().focus().toggleItalic().run(), { on: state.italic, keys: `${mod}I` }),
@@ -8245,7 +8668,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
8245
8668
  styles2.find(([key2]) => key2 === state.style)?.[1] ?? t.normal,
8246
8669
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.ChevronDown, { "aria-hidden": true })
8247
8670
  ] }),
8248
- pop === "style" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-text-pop w100n-text-styles", role: "listbox", "aria-label": t.paragraphStyle, children: styles2.map(([key2, label, run2]) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
8671
+ pop === "style" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-text-pop w100n-text-styles", role: "listbox", "aria-label": t.paragraphStyle, children: styles2.map(([key2, label, run3]) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
8249
8672
  "button",
8250
8673
  {
8251
8674
  type: "button",
@@ -8253,7 +8676,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
8253
8676
  "data-style": key2,
8254
8677
  "aria-selected": state.style === key2,
8255
8678
  onClick: () => {
8256
- run2();
8679
+ run3();
8257
8680
  setPop(null);
8258
8681
  },
8259
8682
  children: label
@@ -8464,6 +8887,14 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
8464
8887
  status
8465
8888
  ] }),
8466
8889
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: scroller, className: "w100n-text-scroll", "data-paint": !!paint2, onMouseUp: lay, onClick: (e) => {
8890
+ const atom = can.edit ? e.target.closest(".w100n-math, sup[data-footnote]") : null;
8891
+ if (atom) {
8892
+ const at = editor.view.posAtDOM(atom, 0);
8893
+ const node = editor.state.doc.nodeAt(at);
8894
+ if (node?.type.name === "math") setDialog({ kind: "formula", latex: node.attrs.latex, at });
8895
+ if (node?.type.name === "footnote") setDialog({ kind: "note", text: node.attrs.text, at });
8896
+ return;
8897
+ }
8467
8898
  const id = e.target.closest("[data-note]")?.getAttribute("data-note");
8468
8899
  if (!id) return;
8469
8900
  setActive(id);
@@ -8487,6 +8918,104 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
8487
8918
  ] }),
8488
8919
  finder
8489
8920
  ] }) }),
8921
+ dialog && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-pdf-back", onKeyDown: (e) => {
8922
+ if (e.key === "Escape") {
8923
+ e.stopPropagation();
8924
+ setDialog(null);
8925
+ }
8926
+ }, children: dialog.kind === "symbol" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-pdf-dialog w100n-insert", role: "dialog", "aria-modal": true, "aria-label": t.symbols, children: [
8927
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-new-head", children: [
8928
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-new-tile", "data-tone": "pink", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Omega, { "aria-hidden": true }) }),
8929
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("b", { className: "w100n-pdf-dialog-title", children: t.symbols }),
8930
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "w100n-docs-close", onClick: () => setDialog(null), "aria-label": t.close, title: t.close, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.X, { "aria-hidden": true }) })
8931
+ ] }),
8932
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "w100n-docs-field w100n-docs-search", children: [
8933
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Search, { "aria-hidden": true }),
8934
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { autoFocus: true, value: dialog.query, placeholder: t.symbolSearch, "aria-label": t.symbolSearch, onChange: (e) => setDialog({ kind: "symbol", query: e.target.value }) })
8935
+ ] }),
8936
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-insert-grid", role: "group", "aria-label": t.symbols, children: symbols.filter(([ch, name]) => !dialog.query.trim() || name.includes(dialog.query.trim().toLowerCase()) || ch === dialog.query.trim()).map(([ch, name]) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "aria-label": name, title: name, onClick: () => {
8937
+ editor.chain().focus().insertContent(ch).run();
8938
+ setDialog(null);
8939
+ }, children: ch }, ch)) })
8940
+ ] }) : dialog.kind === "formula" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("form", { className: "w100n-pdf-dialog w100n-insert", role: "dialog", "aria-modal": true, "aria-label": t.formula, onSubmit: (e) => {
8941
+ e.preventDefault();
8942
+ const latex = dialog.latex.trim();
8943
+ if (!latex) return;
8944
+ if (dialog.at !== null) editor.chain().focus().command(({ tr }) => {
8945
+ tr.setNodeMarkup(dialog.at, void 0, { latex });
8946
+ return true;
8947
+ }).run();
8948
+ else editor.chain().focus().insertContent({ type: "math", attrs: { latex } }).run();
8949
+ setDialog(null);
8950
+ }, children: [
8951
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-new-head", children: [
8952
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-new-tile", "data-tone": "blue", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Sigma, { "aria-hidden": true }) }),
8953
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("b", { className: "w100n-pdf-dialog-title", children: t.formula }),
8954
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-docs-badge", children: t.formulaHint }),
8955
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "w100n-docs-close", onClick: () => setDialog(null), "aria-label": t.close, title: t.close, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.X, { "aria-hidden": true }) })
8956
+ ] }),
8957
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { ref: field, autoFocus: true, className: "w100n-insert-latex", value: dialog.latex, "aria-label": t.formula, placeholder: "F = 900 + 12 \\\\cdot n", onChange: (e) => setDialog({ ...dialog, latex: e.target.value }) }),
8958
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-insert-tools", role: "group", "aria-label": t.formula, children: helpers.map(([label, code]) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", onClick: () => {
8959
+ const el = field.current;
8960
+ const at = el.selectionStart ?? dialog.latex.length;
8961
+ const latex = dialog.latex.slice(0, at) + code + dialog.latex.slice(el.selectionEnd ?? at);
8962
+ setDialog({ ...dialog, latex });
8963
+ const caret = at + (code.indexOf("{}") >= 0 ? code.indexOf("{}") + 1 : code.length);
8964
+ requestAnimationFrame(() => {
8965
+ el.focus();
8966
+ el.setSelectionRange(caret, caret);
8967
+ });
8968
+ }, children: label }, label)) }),
8969
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-insert-preview", "aria-live": "polite", dangerouslySetInnerHTML: { __html: dialog.latex.trim() ? mathml(dialog.latex) : "" } }),
8970
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-pdf-dialog-end", children: [
8971
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "w100n-pdf-link", onClick: () => setDialog(null), children: t.cancel }),
8972
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "submit", className: "w100n-docs-action", disabled: !dialog.latex.trim(), children: [
8973
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Check, { "aria-hidden": true }),
8974
+ dialog.at !== null ? t.update : t.put
8975
+ ] })
8976
+ ] })
8977
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("form", { className: "w100n-pdf-dialog w100n-insert", role: "dialog", "aria-modal": true, "aria-label": t.footnote, onSubmit: (e) => {
8978
+ e.preventDefault();
8979
+ const text = dialog.text.trim();
8980
+ if (!text) return;
8981
+ if (dialog.at !== null) editor.chain().focus().command(({ tr }) => {
8982
+ tr.setNodeAttribute(dialog.at, "text", text);
8983
+ return true;
8984
+ }).run();
8985
+ else editor.chain().focus().insertContent({ type: "footnote", attrs: { id: null, text } }).run();
8986
+ setDialog(null);
8987
+ }, children: [
8988
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-new-head", children: [
8989
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-new-tile", "data-tone": "violet", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Superscript, { "aria-hidden": true }) }),
8990
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("b", { className: "w100n-pdf-dialog-title", children: t.footnote }),
8991
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "w100n-docs-close", onClick: () => setDialog(null), "aria-label": t.close, title: t.close, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.X, { "aria-hidden": true }) })
8992
+ ] }),
8993
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
8994
+ "textarea",
8995
+ {
8996
+ autoFocus: true,
8997
+ className: "w100n-insert-note",
8998
+ value: dialog.text,
8999
+ "aria-label": t.footnoteText,
9000
+ placeholder: t.footnoteText,
9001
+ onChange: (e) => setDialog({ ...dialog, text: e.target.value }),
9002
+ onKeyDown: (e) => {
9003
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) e.currentTarget.form?.requestSubmit();
9004
+ }
9005
+ }
9006
+ ),
9007
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-pdf-dialog-end", children: [
9008
+ dialog.at !== null && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "w100n-pdf-link", onClick: () => {
9009
+ editor.chain().focus().deleteRange({ from: dialog.at, to: dialog.at + 1 }).run();
9010
+ setDialog(null);
9011
+ }, children: t.removeFootnote }),
9012
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "w100n-pdf-link", onClick: () => setDialog(null), children: t.cancel }),
9013
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "submit", className: "w100n-docs-action", disabled: !dialog.text.trim(), children: [
9014
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Check, { "aria-hidden": true }),
9015
+ dialog.at !== null ? t.update : t.put
9016
+ ] })
9017
+ ] })
9018
+ ] }) }),
8490
9019
  draft2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-pdf-back", onKeyDown: (e) => {
8491
9020
  if (e.key === "Escape") {
8492
9021
  e.stopPropagation();
@@ -8626,10 +9155,10 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
8626
9155
  threads.map((c) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("article", { className: "w100n-text-card", "aria-current": active === c.id, "data-resolved": c.resolved, onClick: () => show(c), children: [
8627
9156
  person(c),
8628
9157
  c.quote && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("blockquote", { children: c.quote }),
8629
- words(c),
9158
+ words2(c),
8630
9159
  all.filter((r) => r.replyTo === c.id).map((r) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-text-reply", children: [
8631
9160
  person(r),
8632
- words(r)
9161
+ words2(r)
8633
9162
  ] }, r.id)),
8634
9163
  reply?.id === c.id && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-text-reply", onClick: (e) => e.stopPropagation(), children: [
8635
9164
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
@@ -8668,7 +9197,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
8668
9197
  ] }), slot)
8669
9198
  ] });
8670
9199
  }
8671
- var import_react9, import_lucide_react5, import_react10, import_react_dom2, import_jsx_runtime6, legal, cm, inks, glows, faces, sizes, uid2;
9200
+ var import_react9, import_lucide_react5, import_react10, import_react_dom2, import_jsx_runtime6, legal, symbols, helpers, cm, inks, glows, faces, sizes, uid2;
8672
9201
  var init_TextEditor = __esm({
8673
9202
  "src/editor/TextEditor.tsx"() {
8674
9203
  "use strict";
@@ -8683,9 +9212,63 @@ var init_TextEditor = __esm({
8683
9212
  init_extensions();
8684
9213
  init_live();
8685
9214
  init_markdown();
9215
+ init_math();
8686
9216
  init_pager();
8687
9217
  import_jsx_runtime6 = require("react/jsx-runtime");
8688
9218
  legal = { width: 816, height: 1344 };
9219
+ symbols = [
9220
+ ["\xA9", "copyright"],
9221
+ ["\xAE", "registered"],
9222
+ ["\u2122", "trademark"],
9223
+ ["\xA7", "section"],
9224
+ ["\xB6", "paragraph"],
9225
+ ["\u2020", "dagger"],
9226
+ ["\u2021", "double dagger"],
9227
+ ["\u2022", "bullet"],
9228
+ ["\u2026", "ellipsis"],
9229
+ ["\u2030", "per mille"],
9230
+ ["\u20AC", "euro"],
9231
+ ["\xA3", "pound"],
9232
+ ["\xA5", "yen"],
9233
+ ["\u20B4", "hryvnia"],
9234
+ ["z\u0142", "zloty"],
9235
+ ["\xB0", "degree"],
9236
+ ["\xB1", "plus minus"],
9237
+ ["\xD7", "times multiply"],
9238
+ ["\xF7", "divide"],
9239
+ ["\u2248", "approximately"],
9240
+ ["\u2260", "not equal"],
9241
+ ["\u2264", "less or equal"],
9242
+ ["\u2265", "greater or equal"],
9243
+ ["\u221E", "infinity"],
9244
+ ["\u221A", "square root"],
9245
+ ["\u2211", "sum"],
9246
+ ["\u03C0", "pi"],
9247
+ ["\u03A9", "omega"],
9248
+ ["\xB5", "micro"],
9249
+ ["\u03B1", "alpha"],
9250
+ ["\u03B2", "beta"],
9251
+ ["\u03B3", "gamma"],
9252
+ ["\u0394", "delta"],
9253
+ ["\u03BB", "lambda"],
9254
+ ["\u2192", "arrow right"],
9255
+ ["\u2190", "arrow left"],
9256
+ ["\u2191", "arrow up"],
9257
+ ["\u2193", "arrow down"],
9258
+ ["\u21D2", "arrow implies"],
9259
+ ["\u2713", "check tick"],
9260
+ ["\u2014", "em dash"],
9261
+ ["\u2013", "en dash"],
9262
+ ["\xAB", "quote left"],
9263
+ ["\xBB", "quote right"],
9264
+ ["\u201E", "quote low"],
9265
+ ["\u2116", "number"],
9266
+ ["\xBD", "half"],
9267
+ ["\xBC", "quarter"],
9268
+ ["\xB2", "squared"],
9269
+ ["\xB3", "cubed"]
9270
+ ];
9271
+ helpers = [["x\xB2", "^{2}"], ["x\u2099", "_{n}"], ["\u221Ax", "\\sqrt{}"], ["a/b", "\\frac{}{}"], ["\u2211", "\\sum_{}^{}"], ["\u222B", "\\int "], ["\u03C0", "\\pi "], ["\u2264", "\\le "], ["\u2265", "\\ge "], ["\u2260", "\\ne "], ["\xB1", "\\pm "], ["\xB7", "\\cdot "]];
8689
9272
  cm = (px2) => Math.round(px2 / 96 * 254) / 100;
8690
9273
  inks = ["#0f172a", "#475569", "#dc2626", "#ea580c", "#ca8a04", "#16a34a", "#0891b2", "#2563eb", "#7c3aed", "#db2777"];
8691
9274
  glows = ["#fef08a", "#bbf7d0", "#bfdbfe", "#fbcfe8", "#fed7aa", "#ddd6fe"];
@@ -8770,7 +9353,7 @@ function bind(api, injector, doc, model, edit) {
8770
9353
  let open = true;
8771
9354
  const looks = wb.getStyles();
8772
9355
  const commands = injector.get(import_core4.ICommandService);
8773
- const run2 = (id, params) => commands.hasCommand(id) && commands.syncExecuteCommand(id, { unitId: unit, ...params }, { fromCollab: true });
9356
+ const run3 = (id, params) => commands.hasCommand(id) && commands.syncExecuteCommand(id, { unitId: unit, ...params }, { fromCollab: true });
8774
9357
  const ws = (sid) => wb.getSheetBySheetId(sid);
8775
9358
  const at = /* @__PURE__ */ new Map();
8776
9359
  const index = (sid) => at.get(sid) ?? at.set(sid, { rows: new Map(lines2[sid].rows.map((id, i) => [id, i])), cols: new Map(lines2[sid].cols.map((id, i) => [id, i])) }).get(sid);
@@ -9007,7 +9590,7 @@ function bind(api, injector, doc, model, edit) {
9007
9590
  const r = rows.get(row2), c = cols.get(col);
9008
9591
  if (r !== void 0 && c !== void 0) (cellValue[r] ?? (cellValue[r] = {}))[c] = full(sid, key2, cells.get(key2));
9009
9592
  }
9010
- if (Object.keys(cellValue).length) run2("sheet.mutation.set-range-values", { subUnitId: sid, cellValue, isOverrideStyle: true });
9593
+ if (Object.keys(cellValue).length) run3("sheet.mutation.set-range-values", { subUnitId: sid, cellValue, isOverrideStyle: true });
9011
9594
  };
9012
9595
  const linesTo = (sid, ids, row2) => {
9013
9596
  const { rowData, colData } = pieces(sheets.get(sid));
@@ -9026,11 +9609,11 @@ function bind(api, injector, doc, model, edit) {
9026
9609
  }
9027
9610
  if (!ranges.length) return;
9028
9611
  if (row2) {
9029
- run2("sheet.mutation.set-row-data", { subUnitId: sid, rowData: info });
9030
- run2("sheet.mutation.set-worksheet-row-height", { subUnitId: sid, ranges, rowHeight: sizes2 });
9612
+ run3("sheet.mutation.set-row-data", { subUnitId: sid, rowData: info });
9613
+ run3("sheet.mutation.set-worksheet-row-height", { subUnitId: sid, ranges, rowHeight: sizes2 });
9031
9614
  } else {
9032
- run2("sheet.mutation.set-col-data", { subUnitId: sid, columnData: info });
9033
- run2("sheet.mutation.set-worksheet-col-width", { subUnitId: sid, ranges, colWidth: sizes2 });
9615
+ run3("sheet.mutation.set-col-data", { subUnitId: sid, columnData: info });
9616
+ run3("sheet.mutation.set-worksheet-col-width", { subUnitId: sid, ranges, colWidth: sizes2 });
9034
9617
  }
9035
9618
  };
9036
9619
  const mergesTo = (sid) => {
@@ -9039,16 +9622,16 @@ function bind(api, injector, doc, model, edit) {
9039
9622
  const want = [...kept.keys()].map((k) => k.split(":")).map(([r0, c0, r1, c1]) => ({ startRow: rows.get(r0), startColumn: cols.get(c0), endRow: rows.get(r1), endColumn: cols.get(c1) })).filter((b) => [b.startRow, b.startColumn, b.endRow, b.endColumn].every((n) => n !== void 0));
9040
9623
  const has = ws(sid).getMergeData().map((b) => ({ startRow: b.startRow, startColumn: b.startColumn, endRow: b.endRow, endColumn: b.endColumn }));
9041
9624
  const gone = has.filter((b) => !want.some((w) => canon(w) === canon(b))), added = want.filter((w) => !has.some((b) => canon(w) === canon(b)));
9042
- if (gone.length) run2("sheet.mutation.remove-worksheet-merge", { subUnitId: sid, ranges: gone });
9043
- if (added.length) run2("sheet.mutation.add-worksheet-merge", { subUnitId: sid, ranges: added });
9625
+ if (gone.length) run3("sheet.mutation.remove-worksheet-merge", { subUnitId: sid, ranges: gone });
9626
+ if (added.length) run3("sheet.mutation.add-worksheet-merge", { subUnitId: sid, ranges: added });
9044
9627
  };
9045
9628
  const notesTo = (sid) => {
9046
9629
  const want = notesOf2(sheets.get(sid), lines2[sid]);
9047
9630
  const shown = api.getWorkbook(unit).getSheetBySheetId(sid).getNotes();
9048
- for (const n of shown) if (!want.some((w) => w.row === n.row && w.col === n.col)) run2("sheet.mutation.remove-note", { sheetId: sid, noteId: n.id, row: n.row, col: n.col });
9631
+ for (const n of shown) if (!want.some((w) => w.row === n.row && w.col === n.col)) run3("sheet.mutation.remove-note", { sheetId: sid, noteId: n.id, row: n.row, col: n.col });
9049
9632
  for (const w of want) {
9050
9633
  const n = shown.find((x) => x.row === w.row && x.col === w.col);
9051
- if (!n || n.note !== w.note || n.width !== w.width || n.height !== w.height) run2("sheet.mutation.update-note", { sheetId: sid, row: w.row, col: w.col, note: { note: w.note, width: w.width, height: w.height } });
9634
+ if (!n || n.note !== w.note || n.width !== w.width || n.height !== w.height) run3("sheet.mutation.update-note", { sheetId: sid, row: w.row, col: w.col, note: { note: w.note, width: w.width, height: w.height } });
9052
9635
  }
9053
9636
  };
9054
9637
  const shape3 = () => {
@@ -9060,7 +9643,7 @@ function bind(api, injector, doc, model, edit) {
9060
9643
  const other = want.find((x) => wb.getSheetBySheetId(x));
9061
9644
  if (other) api.syncExecuteCommand("sheet.operation.set-worksheet-active", { unitId: unit, subUnitId: other });
9062
9645
  }
9063
- run2("sheet.mutation.remove-sheet", { subUnitId: sid });
9646
+ run3("sheet.mutation.remove-sheet", { subUnitId: sid });
9064
9647
  delete lines2[sid];
9065
9648
  at.delete(sid);
9066
9649
  }
@@ -9068,12 +9651,12 @@ function bind(api, injector, doc, model, edit) {
9068
9651
  if (wb.getSheetBySheetId(sid)) return;
9069
9652
  const { rows, cols } = pieces(sheets.get(sid));
9070
9653
  lines2[sid] = { rows: rows.toArray(), cols: cols.toArray() };
9071
- run2("sheet.mutation.insert-sheet", { index: Math.min(i, wb.getSheets().length), sheet: (0, import_core4.mergeWorksheetSnapshotWithDefault)(sheetOf(doc, sid, lines2[sid])), styles: styles2.toJSON() });
9654
+ run3("sheet.mutation.insert-sheet", { index: Math.min(i, wb.getSheets().length), sheet: (0, import_core4.mergeWorksheetSnapshotWithDefault)(sheetOf(doc, sid, lines2[sid])), styles: styles2.toJSON() });
9072
9655
  notesTo(sid);
9073
9656
  });
9074
9657
  want.forEach((sid, i) => {
9075
9658
  const now = wb.getSheetOrders().indexOf(sid);
9076
- if (now >= 0 && now !== i) run2("sheet.mutation.set-worksheet-order", { subUnitId: sid, fromOrder: now, toOrder: i });
9659
+ if (now >= 0 && now !== i) run3("sheet.mutation.set-worksheet-order", { subUnitId: sid, fromOrder: now, toOrder: i });
9077
9660
  });
9078
9661
  };
9079
9662
  const move2 = (sid, delta, row2) => {
@@ -9085,15 +9668,15 @@ function bind(api, injector, doc, model, edit) {
9085
9668
  if (d.retain) i += d.retain;
9086
9669
  if (d.delete) {
9087
9670
  const end = i + d.delete - 1;
9088
- if (row2) run2("sheet.mutation.remove-rows", { subUnitId: sid, range: { startRow: i, endRow: end, startColumn: 0, endColumn: lines2[sid].cols.length - 1, rangeType: 1 } });
9089
- else run2("sheet.mutation.remove-col", { subUnitId: sid, range: { startRow: 0, endRow: lines2[sid].rows.length - 1, startColumn: i, endColumn: end, rangeType: 2 } });
9671
+ if (row2) run3("sheet.mutation.remove-rows", { subUnitId: sid, range: { startRow: i, endRow: end, startColumn: 0, endColumn: lines2[sid].cols.length - 1, rangeType: 1 } });
9672
+ else run3("sheet.mutation.remove-col", { subUnitId: sid, range: { startRow: 0, endRow: lines2[sid].rows.length - 1, startColumn: i, endColumn: end, rangeType: 2 } });
9090
9673
  list.splice(i, d.delete);
9091
9674
  }
9092
9675
  if (d.insert) {
9093
9676
  const ids = d.insert;
9094
9677
  const end = i + ids.length - 1;
9095
- if (row2) run2("sheet.mutation.insert-row", { subUnitId: sid, range: { startRow: i, endRow: end, startColumn: 0, endColumn: lines2[sid].cols.length - 1 } });
9096
- else run2("sheet.mutation.insert-col", { subUnitId: sid, range: { startRow: 0, endRow: lines2[sid].rows.length - 1, startColumn: i, endColumn: end } });
9678
+ if (row2) run3("sheet.mutation.insert-row", { subUnitId: sid, range: { startRow: i, endRow: end, startColumn: 0, endColumn: lines2[sid].cols.length - 1 } });
9679
+ else run3("sheet.mutation.insert-col", { subUnitId: sid, range: { startRow: 0, endRow: lines2[sid].rows.length - 1, startColumn: i, endColumn: end } });
9097
9680
  list.splice(i, 0, ...ids);
9098
9681
  ids.forEach((id) => added.add(id));
9099
9682
  i += ids.length;
@@ -9139,7 +9722,7 @@ function bind(api, injector, doc, model, edit) {
9139
9722
  if (s.rows || s.cols) structural = true;
9140
9723
  for (const [name, id, key2, empty] of setters) if (s.props.has(name)) {
9141
9724
  const v = sheets.get(sid).get(name) ?? empty;
9142
- run2(id, { subUnitId: sid, ...key2 ? { [key2]: v } : v });
9725
+ run3(id, { subUnitId: sid, ...key2 ? { [key2]: v } : v });
9143
9726
  }
9144
9727
  const keys2 = new Set(s.cells);
9145
9728
  if (rows.size || cols.size) {
@@ -9472,7 +10055,7 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
9472
10055
  });
9473
10056
  useRestore(pop !== null);
9474
10057
  const api = () => live.current?.api;
9475
- const run2 = (id, params) => {
10058
+ const run3 = (id, params) => {
9476
10059
  void api()?.executeCommand(id, params);
9477
10060
  setPop(null);
9478
10061
  };
@@ -9582,18 +10165,18 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
9582
10165
  tool(import_lucide_react6.DecimalsArrowLeft, t.fewerDecimals, () => places(-1)),
9583
10166
  tool(import_lucide_react6.DecimalsArrowRight, t.moreDecimals, () => places(1)),
9584
10167
  gap,
9585
- tool(import_lucide_react6.Bold, t.bold, () => run2("sheet.command.set-range-bold"), look?.bl),
9586
- tool(import_lucide_react6.Italic, t.italic, () => run2("sheet.command.set-range-italic"), look?.it),
9587
- tool(import_lucide_react6.Underline, t.underline, () => run2("sheet.command.set-range-underline"), look?.ul),
9588
- tool(import_lucide_react6.Strikethrough, t.strike, () => run2("sheet.command.set-range-stroke"), look?.st),
10168
+ tool(import_lucide_react6.Bold, t.bold, () => run3("sheet.command.set-range-bold"), look?.bl),
10169
+ tool(import_lucide_react6.Italic, t.italic, () => run3("sheet.command.set-range-italic"), look?.it),
10170
+ tool(import_lucide_react6.Underline, t.underline, () => run3("sheet.command.set-range-underline"), look?.ul),
10171
+ tool(import_lucide_react6.Strikethrough, t.strike, () => run3("sheet.command.set-range-stroke"), look?.st),
9589
10172
  anchor(
9590
10173
  "text",
9591
10174
  opener("text", import_lucide_react6.Baseline, t.textColour, look?.cl ?? ""),
9592
10175
  swatches(
9593
10176
  ["#0f172a", "#475569", "#dc2626", "#ea580c", "#ca8a04", "#16a34a", "#0891b2", "#2563eb", "#7c3aed", "#db2777"],
9594
- (c) => run2("sheet.command.set-range-text-color", { value: c }),
10177
+ (c) => run3("sheet.command.set-range-text-color", { value: c }),
9595
10178
  t.automatic,
9596
- () => run2("sheet.command.reset-range-text-color"),
10179
+ () => run3("sheet.command.reset-range-text-color"),
9597
10180
  look?.cl ?? ""
9598
10181
  )
9599
10182
  ),
@@ -9602,9 +10185,9 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
9602
10185
  opener("fill", import_lucide_react6.PaintBucket, t.fill, look?.bg ?? ""),
9603
10186
  swatches(
9604
10187
  ["#fee2e2", "#ffedd5", "#fef9c3", "#dcfce7", "#cffafe", "#dbeafe", "#ede9fe", "#fce7f3", "#f1f5f9", "#cbd5e1"],
9605
- (c) => run2("sheet.command.set-background-color", { value: c }),
10188
+ (c) => run3("sheet.command.set-background-color", { value: c }),
9606
10189
  t.noFill,
9607
- () => run2("sheet.command.reset-background-color"),
10190
+ () => run3("sheet.command.reset-background-color"),
9608
10191
  look?.bg ?? ""
9609
10192
  )
9610
10193
  ),
@@ -9617,16 +10200,16 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
9617
10200
  ] }, type)) })
9618
10201
  ),
9619
10202
  gap,
9620
- tool(import_lucide_react6.TextAlignStart, t.alignLeft, () => run2("sheet.command.set-horizontal-text-align", { value: 1 }), look?.ht === 1),
9621
- tool(import_lucide_react6.TextAlignCenter, t.alignCenter, () => run2("sheet.command.set-horizontal-text-align", { value: 2 }), look?.ht === 2),
9622
- tool(import_lucide_react6.TextAlignEnd, t.alignRight, () => run2("sheet.command.set-horizontal-text-align", { value: 3 }), look?.ht === 3),
9623
- tool(import_lucide_react6.TextWrap, t.wrap, () => run2("sheet.command.set-text-wrap", { value: look?.tb ? 1 : 3 }), look?.tb),
9624
- look?.merged ? tool(import_lucide_react6.TableCellsSplit, t.unmerge, () => run2("sheet.command.remove-worksheet-merge"), true) : tool(import_lucide_react6.TableCellsMerge, t.merge, () => run2("sheet.command.add-worksheet-merge-all")),
10203
+ tool(import_lucide_react6.TextAlignStart, t.alignLeft, () => run3("sheet.command.set-horizontal-text-align", { value: 1 }), look?.ht === 1),
10204
+ tool(import_lucide_react6.TextAlignCenter, t.alignCenter, () => run3("sheet.command.set-horizontal-text-align", { value: 2 }), look?.ht === 2),
10205
+ tool(import_lucide_react6.TextAlignEnd, t.alignRight, () => run3("sheet.command.set-horizontal-text-align", { value: 3 }), look?.ht === 3),
10206
+ tool(import_lucide_react6.TextWrap, t.wrap, () => run3("sheet.command.set-text-wrap", { value: look?.tb ? 1 : 3 }), look?.tb),
10207
+ look?.merged ? tool(import_lucide_react6.TableCellsSplit, t.unmerge, () => run3("sheet.command.remove-worksheet-merge"), true) : tool(import_lucide_react6.TableCellsMerge, t.merge, () => run3("sheet.command.add-worksheet-merge-all")),
9625
10208
  gap,
9626
- tool(import_lucide_react6.BetweenHorizontalStart, t.rowAbove, () => run2("sheet.command.insert-row-before")),
9627
- tool(import_lucide_react6.BetweenHorizontalEnd, t.rowBelow, () => run2("sheet.command.insert-row-after")),
9628
- tool(import_lucide_react6.BetweenVerticalStart, t.columnLeft, () => run2("sheet.command.insert-col-before")),
9629
- tool(import_lucide_react6.BetweenVerticalEnd, t.columnRight, () => run2("sheet.command.insert-col-after")),
10209
+ tool(import_lucide_react6.BetweenHorizontalStart, t.rowAbove, () => run3("sheet.command.insert-row-before")),
10210
+ tool(import_lucide_react6.BetweenHorizontalEnd, t.rowBelow, () => run3("sheet.command.insert-row-after")),
10211
+ tool(import_lucide_react6.BetweenVerticalStart, t.columnLeft, () => run3("sheet.command.insert-col-before")),
10212
+ tool(import_lucide_react6.BetweenVerticalEnd, t.columnRight, () => run3("sheet.command.insert-col-after")),
9630
10213
  tool(import_lucide_react6.TableRowsSplit, t.deleteRows, () => lines2(true)),
9631
10214
  tool(import_lucide_react6.TableColumnsSplit, t.deleteColumns, () => lines2(false)),
9632
10215
  anchor(
@@ -9641,7 +10224,7 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
9641
10224
  sheet2()?.setFrozenColumns(1);
9642
10225
  setPop(null);
9643
10226
  }, children: t.freezeColumn }),
9644
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", onClick: () => run2("sheet.command.set-selection-frozen"), children: t.freezeHere }),
10227
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", onClick: () => run3("sheet.command.set-selection-frozen"), children: t.freezeHere }),
9645
10228
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", onClick: () => {
9646
10229
  sheet2()?.cancelFreeze();
9647
10230
  setPop(null);
@@ -9650,13 +10233,13 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
9650
10233
  ),
9651
10234
  gap,
9652
10235
  tool(import_lucide_react6.Sigma, t.sum, sum),
9653
- tool(import_lucide_react6.ArrowDownAZ, t.sortUp, () => run2("sheet.command.sort-range-asc")),
9654
- tool(import_lucide_react6.ArrowDownZA, t.sortDown, () => run2("sheet.command.sort-range-desc")),
9655
- !room && tool(import_lucide_react6.Funnel, t.filter, () => run2("sheet.command.smart-toggle-filter")),
10236
+ tool(import_lucide_react6.ArrowDownAZ, t.sortUp, () => run3("sheet.command.sort-range-asc")),
10237
+ tool(import_lucide_react6.ArrowDownZA, t.sortDown, () => run3("sheet.command.sort-range-desc")),
10238
+ !room && tool(import_lucide_react6.Funnel, t.filter, () => run3("sheet.command.smart-toggle-filter")),
9656
10239
  gap
9657
10240
  ] }),
9658
- (edit || notes2) && tool(import_lucide_react6.StickyNote, t.note, () => run2("sheet.operation.add-note-popup")),
9659
- tool(import_lucide_react6.Search, t.find, () => run2("ui.operation.open-find-dialog"))
10241
+ (edit || notes2) && tool(import_lucide_react6.StickyNote, t.note, () => run3("sheet.operation.add-note-popup")),
10242
+ tool(import_lucide_react6.Search, t.find, () => run3("ui.operation.open-find-dialog"))
9660
10243
  ] }),
9661
10244
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "w100n-sheet-end", children: [
9662
10245
  room && (room.ready ? !room.online : room.late || room.denied) && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "w100n-text-live", title: room.denied ? void 0 : t.offlineHint, children: [
@@ -9771,8 +10354,8 @@ function readable(name, mimeType) {
9771
10354
  return kind !== "sheet" || /\.(xlsx|csv)$/i.test(name) || /spreadsheetml|text\/csv/.test(mimeType ?? "") ? kind : null;
9772
10355
  }
9773
10356
  function matches(doc, query, picked) {
9774
- const words = query.toLocaleLowerCase().split(/\s+/).filter(Boolean);
9775
- return (!picked.length || picked.includes(doc.kind)) && words.every((word) => doc.name.toLocaleLowerCase().includes(word));
10357
+ const words2 = query.toLocaleLowerCase().split(/\s+/).filter(Boolean);
10358
+ return (!picked.length || picked.includes(doc.kind)) && words2.every((word) => doc.name.toLocaleLowerCase().includes(word));
9776
10359
  }
9777
10360
 
9778
10361
  // src/slides/SlidesView.tsx
@@ -10280,8 +10863,8 @@ function moveSlide(deck, from, to) {
10280
10863
  const slide = deck.slides[from];
10281
10864
  const rest = deck.slides.filter((_, i) => i !== from);
10282
10865
  let at = Math.max(0, Math.min(rest.length, to));
10283
- const run2 = rest.flatMap((other, i) => slide.stack !== null && other.stack === slide.stack ? [i] : []);
10284
- if (run2.length) at = Math.max(run2[0], Math.min(run2[run2.length - 1] + 1, at));
10866
+ const run3 = rest.flatMap((other, i) => slide.stack !== null && other.stack === slide.stack ? [i] : []);
10867
+ if (run3.length) at = Math.max(run3[0], Math.min(run3[run3.length - 1] + 1, at));
10285
10868
  else if (at > 0 && at < rest.length && rest[at].stack !== null && rest[at - 1].stack === rest[at].stack) {
10286
10869
  let end = at;
10287
10870
  while (end < rest.length && rest[end].stack === rest[at].stack) end++;
@@ -10871,7 +11454,7 @@ function SlidesView({ html, name, rights, language = "en", theme = "light", base
10871
11454
  popup.close();
10872
11455
  };
10873
11456
  }, [popup]);
10874
- const tool = (Icon, text, run2, disabled = false) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", "aria-label": text, title: text, disabled, onClick: run2, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { "aria-hidden": true }) });
11457
+ const tool = (Icon, text, run3, disabled = false) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", "aria-label": text, title: text, disabled, onClick: run3, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { "aria-hidden": true }) });
10875
11458
  const thumb = 148;
10876
11459
  const seconds = Math.floor(Math.max(0, (timer.stop ?? now) - timer.from) / 1e3);
10877
11460
  const elapsed = `${seconds >= 3600 ? `${Math.floor(seconds / 3600)}:` : ""}${String(Math.floor(seconds / 60) % 60).padStart(2, "0")}:${String(seconds % 60).padStart(2, "0")}`;
@@ -11123,7 +11706,7 @@ var same = (a, b) => !!b && a.page === b.page && a.start === b.start;
11123
11706
  var spot = (b, size2) => ({ left: pct(b.x / size2.w), top: pct(b.y / size2.h), width: pct(b.w / size2.w), height: pct(b.h / size2.h) });
11124
11707
  function PdfPage({ pdf, n, size: size2, scale, live, id, layers }) {
11125
11708
  const paint2 = (0, import_react5.useRef)(null);
11126
- const words = (0, import_react5.useRef)(null);
11709
+ const words2 = (0, import_react5.useRef)(null);
11127
11710
  const forms = (0, import_react5.useRef)(null);
11128
11711
  const focus = (0, import_react5.useRef)(null);
11129
11712
  const rubbed = (0, import_react5.useRef)(null);
@@ -11135,7 +11718,7 @@ function PdfPage({ pdf, n, size: size2, scale, live, id, layers }) {
11135
11718
  const hitKey = layers ? layers.hits.map((hit) => `${hit.start}:${hit.end}`).join() : "";
11136
11719
  (0, import_react5.useEffect)(() => {
11137
11720
  if (!live) return;
11138
- const holders = [paint2, words, forms].flatMap((ref) => ref.current ? [ref.current] : []);
11721
+ const holders = [paint2, words2, forms].flatMap((ref) => ref.current ? [ref.current] : []);
11139
11722
  return () => {
11140
11723
  for (const holder of holders) {
11141
11724
  for (const canvas of holder.querySelectorAll("canvas")) {
@@ -11220,7 +11803,7 @@ function PdfPage({ pdf, n, size: size2, scale, live, id, layers }) {
11220
11803
  const end = document.createElement("div");
11221
11804
  end.className = "endOfContent";
11222
11805
  layer.append(end);
11223
- words.current.replaceChildren(layer);
11806
+ words2.current.replaceChildren(layer);
11224
11807
  const annotations = await page.getAnnotations();
11225
11808
  for (const a of annotations) {
11226
11809
  if (!a.fieldName || a.pushButton || !["Tx", "Btn", "Ch"].includes(a.fieldType)) continue;
@@ -11256,7 +11839,7 @@ function PdfPage({ pdf, n, size: size2, scale, live, id, layers }) {
11256
11839
  };
11257
11840
  }, [pdf, n, live, fill3]);
11258
11841
  (0, import_react5.useLayoutEffect)(() => {
11259
- const layer = words.current?.firstElementChild;
11842
+ const layer = words2.current?.firstElementChild;
11260
11843
  if (!layers || !layer || !hitKey) {
11261
11844
  setBoxes([]);
11262
11845
  return;
@@ -11351,7 +11934,7 @@ function PdfPage({ pdf, n, size: size2, scale, live, id, layers }) {
11351
11934
  };
11352
11935
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "w100n-pdf-page", id, "data-n": n, style, children: [
11353
11936
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: paint2, className: "w100n-pdf-paint" }),
11354
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: words, className: "w100n-pdf-words" }),
11937
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: words2, className: "w100n-pdf-words" }),
11355
11938
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: forms, className: "w100n-pdf-forms" }),
11356
11939
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { className: "w100n-pdf-marks", viewBox: `0 0 ${size2.w} ${size2.h}`, preserveAspectRatio: "none", "aria-hidden": true, children: [
11357
11940
  marks2.map((mark) => {
@@ -11467,7 +12050,7 @@ function PdfView({ bytes, t, language, worker, rights, host, documentId, onSaved
11467
12050
  const pad = (0, import_react6.useRef)(null);
11468
12051
  const inked = (0, import_react6.useRef)(null);
11469
12052
  const widgets = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
11470
- const words = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
12053
+ const words2 = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
11471
12054
  const anchor = (0, import_react6.useRef)({ scale: 0, page: 0, frac: 0 });
11472
12055
  const [pdf, setPdf] = (0, import_react6.useState)(null);
11473
12056
  const [sizes2, setSizes] = (0, import_react6.useState)([]);
@@ -11509,7 +12092,7 @@ function PdfView({ bytes, t, language, worker, rights, host, documentId, onSaved
11509
12092
  setFilled(false);
11510
12093
  setOpen(null);
11511
12094
  widgets.current = /* @__PURE__ */ new Map();
11512
- words.current = /* @__PURE__ */ new Map();
12095
+ words2.current = /* @__PURE__ */ new Map();
11513
12096
  (async () => {
11514
12097
  var _a;
11515
12098
  const pdfjs = await import("pdfjs-dist");
@@ -11634,11 +12217,11 @@ function PdfView({ bytes, t, language, worker, rights, host, documentId, onSaved
11634
12217
  const timer = setTimeout(async () => {
11635
12218
  const found = [];
11636
12219
  for (let n = 1; n <= pdf.numPages && !stop; n++) {
11637
- let text = words.current.get(n);
12220
+ let text = words2.current.get(n);
11638
12221
  if (text === void 0) {
11639
12222
  const content = await (await pdf.getPage(n)).getTextContent();
11640
12223
  text = content.items.map((piece) => "str" in piece ? piece.str + (piece.hasEOL ? " " : "") : "").join("").toLowerCase();
11641
- words.current.set(n, text);
12224
+ words2.current.set(n, text);
11642
12225
  }
11643
12226
  for (let i = text.indexOf(needle); i >= 0; i = text.indexOf(needle, i + needle.length)) found.push({ page: n, start: i, end: i + needle.length });
11644
12227
  if (!stop && (n % 20 === 0 || n === pdf.numPages)) setHits({ list: [...found], done: n === pdf.numPages });
@@ -12313,12 +12896,12 @@ var templates = {
12313
12896
  [null, "What comes next and who owns it."]
12314
12897
  ]
12315
12898
  };
12316
- var run = (text) => text ? `<w:r><w:t xml:space="preserve">${escape2(text)}</w:t></w:r>` : "";
12317
- var para = ([style, text]) => `<w:p>${style ? `<w:pPr><w:pStyle w:val="${style}"/></w:pPr>` : ""}${run(text)}</w:p>`;
12899
+ var run2 = (text) => text ? `<w:r><w:t xml:space="preserve">${escape2(text)}</w:t></w:r>` : "";
12900
+ var para = ([style, text]) => `<w:p>${style ? `<w:pPr><w:pStyle w:val="${style}"/></w:pPr>` : ""}${run2(text)}</w:p>`;
12318
12901
  var table2 = (rows) => {
12319
12902
  const width = Math.floor(9638 / rows[0].length);
12320
12903
  const border = (side2) => `<w:${side2} w:val="single" w:sz="4" w:space="0" w:color="94A3B8"/>`;
12321
- return `<w:tbl><w:tblPr><w:tblW w:w="5000" w:type="pct"/><w:tblBorders>${["top", "left", "bottom", "right", "insideH", "insideV"].map(border).join("")}</w:tblBorders></w:tblPr><w:tblGrid>${rows[0].map(() => `<w:gridCol w:w="${width}"/>`).join("")}</w:tblGrid>` + rows.map((row2, r) => `<w:tr>${row2.map((cell2) => `<w:tc><w:tcPr><w:tcW w:w="${width}" w:type="dxa"/></w:tcPr><w:p>${r === 0 ? `<w:r><w:rPr><w:b/></w:rPr><w:t xml:space="preserve">${escape2(cell2)}</w:t></w:r>` : run(cell2)}</w:p></w:tc>`).join("")}</w:tr>`).join("") + "</w:tbl><w:p/>";
12904
+ return `<w:tbl><w:tblPr><w:tblW w:w="5000" w:type="pct"/><w:tblBorders>${["top", "left", "bottom", "right", "insideH", "insideV"].map(border).join("")}</w:tblBorders></w:tblPr><w:tblGrid>${rows[0].map(() => `<w:gridCol w:w="${width}"/>`).join("")}</w:tblGrid>` + rows.map((row2, r) => `<w:tr>${row2.map((cell2) => `<w:tc><w:tcPr><w:tcW w:w="${width}" w:type="dxa"/></w:tcPr><w:p>${r === 0 ? `<w:r><w:rPr><w:b/></w:rPr><w:t xml:space="preserve">${escape2(cell2)}</w:t></w:r>` : run2(cell2)}</w:p></w:tc>`).join("")}</w:tr>`).join("") + "</w:tbl><w:p/>";
12322
12905
  };
12323
12906
  var styles = `${head}<w:styles xmlns:w="${W}"><w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:eastAsia="Arial" w:cs="Arial"/><w:sz w:val="22"/><w:szCs w:val="22"/></w:rPr></w:rPrDefault><w:pPrDefault><w:pPr><w:spacing w:after="120" w:line="276" w:lineRule="auto"/></w:pPr></w:pPrDefault></w:docDefaults><w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:qFormat/></w:style><w:style w:type="paragraph" w:styleId="Title"><w:name w:val="Title"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:qFormat/><w:pPr><w:spacing w:after="80"/></w:pPr><w:rPr><w:b/><w:sz w:val="48"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:qFormat/><w:pPr><w:keepNext/><w:spacing w:before="360" w:after="120"/><w:outlineLvl w:val="0"/></w:pPr><w:rPr><w:b/><w:sz w:val="32"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading2"><w:name w:val="heading 2"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:qFormat/><w:pPr><w:keepNext/><w:spacing w:before="240" w:after="80"/><w:outlineLvl w:val="1"/></w:pPr><w:rPr><w:b/><w:sz w:val="26"/></w:rPr></w:style></w:styles>`;
12324
12907
  function docx(blocks3) {
@@ -13191,8 +13774,8 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
13191
13774
  }, []);
13192
13775
  const now = reading?.documentId === here.documentId ? reading : null;
13193
13776
  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));
13777
+ const words2 = hunt.toLocaleLowerCase().split(/\s+/).filter(Boolean);
13778
+ const hit = (h) => words2.every((w) => h.text.toLocaleLowerCase().includes(w));
13196
13779
  const reach = (h) => h.go ? h.go() : document.getElementById(h.id)?.scrollIntoView({ behavior: "smooth", block: "start" });
13197
13780
  const crumbs = doc.data ? [names2.get(doc.data.spaceId), doc.data.folder].filter(Boolean) : space ? [space.name] : [];
13198
13781
  const panelTabs = [["outline", import_lucide_react10.ListTree, t.outline], ["versions", import_lucide_react10.History, t.versions], ["details", import_lucide_react10.Info, t.details]];
@@ -13427,7 +14010,7 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
13427
14010
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "w100n-docs-head", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "w100n-docs-row", children: [
13428
14011
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "w100n-docs-tabs", role: "tablist", "aria-label": t.details, "data-compact": panelTabs.length > 3, onKeyDown: rove, children: panelTabs.map(([key2, Icon, label]) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", role: "tab", "aria-selected": tab === key2, tabIndex: tab === key2 ? 0 : -1, "aria-label": label, title: label, onClick: () => setTab(key2), children: [
13429
14012
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { "aria-hidden": true }),
13430
- (panelTabs.length < 4 || tab === key2) && label
14013
+ (panelTabs.length < 4 || tab === key2 && panelTabs.length < 5) && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: label })
13431
14014
  ] }, key2)) }),
13432
14015
  /* @__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 }) })
13433
14016
  ] }) }),
@@ -13446,9 +14029,9 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
13446
14029
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { value: hunt, onChange: (e) => setHunt(e.target.value), placeholder: t.findHeading, "aria-label": t.findHeading })
13447
14030
  ] }),
13448
14031
  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);
14032
+ const subs = words2.length ? c.subs.filter(hit) : c.subs;
14033
+ if (words2.length && !hit(c.head) && !subs.length) return null;
14034
+ const opened3 = words2.length > 0 || (fold[c.head.id] ?? i === reached);
13452
14035
  const named3 = /^(\d+)[.)]?\s+(.+)$/.exec(c.head.text);
13453
14036
  const mark = c.subs.findIndex((s) => s.id === now?.id);
13454
14037
  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: [