@w100n/documents 0.14.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,20 @@ 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) out.push({ ch: u.ch, raw: u.raw, run: u.run, ctx: u.ctx, u, fmt: u.fmt });
3435
+ else {
3436
+ want.note.id = typeof want.note.id === "string" && want.note.id ? want.note.id : String(this.noteId());
3437
+ 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 });
3438
+ }
3439
+ continue;
3440
+ }
3082
3441
  if (i >= 0) {
3083
3442
  const u = A[i];
3084
3443
  if (u.span && intact.has(u.span)) {
@@ -3088,18 +3447,18 @@ var init_write = __esm({
3088
3447
  const from = u.span ? u.base : u.fmt;
3089
3448
  const keep = u.ch === "\n" || keyOf(from) === want.key;
3090
3449
  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 });
3450
+ const run3 = keep && u.run ? u.run : this.derive(u.run ?? paraBase.run, from, want.fmt);
3451
+ 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
3452
  } else {
3094
3453
  const left = lastChar();
3095
3454
  const right = next[j + 1] >= 0 ? A[next[j + 1]] : null;
3096
3455
  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);
3456
+ const run3 = keyOf(base.fmt) === want.key ? base.run : this.derive(base.run, base.fmt, want.fmt);
3098
3457
  const shared = [];
3099
3458
  if (left && right) {
3100
3459
  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
3460
  }
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 });
3461
+ 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
3462
  }
3104
3463
  }
3105
3464
  let xml = "";
@@ -3182,10 +3541,10 @@ var init_write = __esm({
3182
3541
  this.relIds.add(`rId${n}`);
3183
3542
  return `rId${n}`;
3184
3543
  }
3185
- derive(run2, from, to) {
3186
- const cache2 = run2.derived ?? (run2.derived = /* @__PURE__ */ new Map());
3544
+ derive(run3, from, to) {
3545
+ const cache2 = run3.derived ?? (run3.derived = /* @__PURE__ */ new Map());
3187
3546
  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 });
3547
+ if (!cache2.has(key2)) cache2.set(key2, { open: run3.open, rPr: this.delta(run3.rPr, from, to), fmt: to, el: null, parent: null });
3189
3548
  return cache2.get(key2);
3190
3549
  }
3191
3550
  delta(rPr, from, to) {
@@ -3234,8 +3593,8 @@ var init_write = __esm({
3234
3593
  } else if (!to.link && from.link && this.pkg.styles.isLink(style)) set["w:rStyle"] = null;
3235
3594
  return Object.keys(set).length ? rebuild(rPr, "w:rPr", R, set) : rPr;
3236
3595
  }
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);
3596
+ runXml(run3, glyphs, counts) {
3597
+ 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
3598
  let body = "";
3240
3599
  let text = "";
3241
3600
  const tag = glyphs[0]?.ctx.some((w) => w.rev?.startsWith('["del"')) ? "w:delText" : "w:t";
@@ -3250,7 +3609,7 @@ var init_write = __esm({
3250
3609
  } else text += g.ch;
3251
3610
  }
3252
3611
  flush();
3253
- return run2.open + run2.rPr + body + "</w:r>";
3612
+ return run3.open + run3.rPr + body + "</w:r>";
3254
3613
  }
3255
3614
  embed(src) {
3256
3615
  if (!this.srcs) {
@@ -3474,14 +3833,14 @@ async function readDocx(bytes) {
3474
3833
  const size2 = sect && kid(sect, "w:pgSz");
3475
3834
  const mar = sect && kid(sect, "w:pgMar");
3476
3835
  const px2 = (el, name, fallback) => Math.round(Math.abs(+((el && attr(s, el, name)) ?? fallback)) / 15 * 100) / 100;
3477
- const words = (kind) => {
3836
+ const words2 = (kind) => {
3478
3837
  const ref = sect?.kids.find((k) => k.name === `w:${kind}Reference` && attr(s, k, "w:type") === "default");
3479
3838
  const part = ref && pkg.rels.get(attr(s, ref, "r:id") ?? "");
3480
3839
  const xml = part ? pkg.text(part.target) ?? "" : "";
3481
3840
  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
3841
  };
3483
- const head2 = words("header");
3484
- const foot = words("footer");
3842
+ const head2 = words2("header");
3843
+ const foot = words2("footer");
3485
3844
  return {
3486
3845
  marginal: { header: head2.text, footer: foot.page ? foot.text.replace(/\s*\d+$/, "") : foot.text, numbers: foot.page },
3487
3846
  doc: { type: "doc", content: content.length ? content : [{ type: "paragraph", attrs: { align: null, indent: 0, ref: null } }] },
@@ -3572,6 +3931,10 @@ function measure(view) {
3572
3931
  const room = page.height - top - bottom;
3573
3932
  const els = [...view.dom.children];
3574
3933
  const gaps = [];
3934
+ const line = page.width - page.margins[1] - page.margins[3];
3935
+ const area = (list) => list.length ? 14 + list.reduce((h, text) => h + 15 * Math.max(1, Math.ceil(text.length * 5.6 / line)), 0) : 0;
3936
+ let notes2 = [];
3937
+ let count = 0;
3575
3938
  let i = 0;
3576
3939
  let shift = 0;
3577
3940
  let start = 0;
@@ -3585,17 +3948,25 @@ function measure(view) {
3585
3948
  if (!el) return;
3586
3949
  const y = el.offsetTop - shift;
3587
3950
  const end = y + el.offsetHeight;
3951
+ const mine = [];
3952
+ node.descendants((d) => {
3953
+ if (d.type.name === "footnote") mine.push(`${count + mine.length + 1} ${d.attrs.text}`);
3954
+ });
3588
3955
  if (node.type.name === "pageBreak") {
3589
- gaps.push({ pos: offset + node.nodeSize, height: start + room - end + bottom + 24 + top, page: gaps.length + 1 });
3956
+ gaps.push({ pos: offset + node.nodeSize, height: start + room - end + bottom + 24 + top, page: gaps.length + 1, notes: notes2 });
3957
+ notes2 = [];
3590
3958
  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 });
3959
+ } else if (end > start + room - area([...notes2, ...mine]) && y > start) {
3960
+ gaps.push({ pos: offset, height: start + room - y + bottom + 24 + top, page: gaps.length + 1, notes: notes2 });
3961
+ notes2 = [];
3593
3962
  start = y;
3594
3963
  }
3964
+ notes2.push(...mine);
3965
+ count += mine.length;
3595
3966
  while (end > start + room) start += room;
3596
3967
  last2 = end;
3597
3968
  });
3598
- gaps.push({ pos: view.state.doc.content.size, height: Math.max(0, start + room - last2), page: gaps.length + 1, end: true });
3969
+ gaps.push({ pos: view.state.doc.content.size, height: Math.max(0, start + room - last2), page: gaps.length + 1, end: true, notes: notes2 });
3599
3970
  return gaps.map((g) => ({ ...g, height: Math.max(0, Math.round(g.height)) }));
3600
3971
  }
3601
3972
  var import_core, import_state, import_view, a4, letter, paging, skip2, Pager;
@@ -3624,11 +3995,11 @@ var init_pager = __esm({
3624
3995
  view(view) {
3625
3996
  let timer = 0;
3626
3997
  let sig2 = "";
3627
- const run2 = () => {
3998
+ const run3 = () => {
3628
3999
  if (!view.dom.isConnected) return;
3629
4000
  const gaps = measure(view);
3630
4001
  const { marks: marks2 } = paging.getState(view.state);
3631
- const next = gaps.map((g) => `${g.pos}:${g.height}`).join() + `|${marks2.header}|${marks2.footer}`;
4002
+ const next = gaps.map((g) => `${g.pos}:${g.height}:${g.notes.join("\n")}`).join() + `|${marks2.header}|${marks2.footer}`;
3632
4003
  if (next === sig2) return;
3633
4004
  sig2 = next;
3634
4005
  const line = (parent, cls, text) => {
@@ -3653,13 +4024,25 @@ var init_pager = __esm({
3653
4024
  el.contentEditable = "false";
3654
4025
  line(el, "w100n-text-foot", marks2.footer);
3655
4026
  if (!g.end) line(el, "w100n-text-head", marks2.header);
4027
+ if (g.notes.length) {
4028
+ const list = document.createElement("div");
4029
+ list.className = "w100n-text-footnotes";
4030
+ for (const note of g.notes) {
4031
+ const p = document.createElement("p");
4032
+ const n = document.createElement("sup");
4033
+ n.textContent = note.slice(0, note.indexOf(" "));
4034
+ p.append(n, note.slice(note.indexOf(" ")));
4035
+ list.append(p);
4036
+ }
4037
+ el.append(list);
4038
+ }
3656
4039
  return el;
3657
- }, { key: `${g.pos}:${g.height}:${g.page}:${marks2.header}:${marks2.footer}`, side: -1, ignoreSelection: true }))]);
4040
+ }, { key: `${g.pos}:${g.height}:${g.page}:${marks2.header}:${marks2.footer}:${g.notes.join("\n")}`, side: -1, ignoreSelection: true }))]);
3658
4041
  view.dispatch(view.state.tr.setMeta(paging, { set }).setMeta("addToHistory", false));
3659
4042
  };
3660
4043
  const later = (ms) => {
3661
4044
  clearTimeout(timer);
3662
- timer = window.setTimeout(run2, ms);
4045
+ timer = window.setTimeout(run3, ms);
3663
4046
  };
3664
4047
  const watch = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(() => later(200));
3665
4048
  watch?.observe(view.dom);
@@ -3735,7 +4118,7 @@ function kit(kind, t, live) {
3735
4118
  Toc.configure({ relative: kind === "markdown", label: t.toc, empty: t.tocEmpty }),
3736
4119
  Note,
3737
4120
  Notes,
3738
- ...kind === "docx" ? [Pager, Locks.configure({ label: t.locked }), revision("insertion", "ins"), revision("deletion", "del"), Suggest] : [],
4121
+ ...kind === "docx" ? [Formula, Footnote, Pager, Locks.configure({ label: t.locked }), revision("insertion", "ins"), revision("deletion", "del"), Suggest] : [],
3739
4122
  ...live ? [import_extension_collaboration.default.configure({ document: live.doc }), import_extension_collaboration_caret.default.configure({ provider: live.link, user: live.user })] : []
3740
4123
  ];
3741
4124
  }
@@ -3778,7 +4161,7 @@ function locate(doc, list) {
3778
4161
  return range ? [{ id: c.id, from: range.from, to: range.to }] : [];
3779
4162
  });
3780
4163
  }
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;
4164
+ 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
4165
  var init_extensions = __esm({
3783
4166
  "src/editor/extensions.ts"() {
3784
4167
  "use strict";
@@ -3796,6 +4179,7 @@ var init_extensions = __esm({
3796
4179
  import_starter_kit = __toESM(require("@tiptap/starter-kit"), 1);
3797
4180
  import_y_tiptap = require("@tiptap/y-tiptap");
3798
4181
  init_pager();
4182
+ init_math();
3799
4183
  notes = new import_state2.PluginKey("w100n-notes");
3800
4184
  blocks = [
3801
4185
  "paragraph",
@@ -3943,6 +4327,37 @@ var init_extensions = __esm({
3943
4327
  return ["div", { "data-page-break": "", "data-label": this.options.label, class: "w100n-text-break", contenteditable: "false" }];
3944
4328
  }
3945
4329
  });
4330
+ Formula = import_core2.Node.create({
4331
+ name: "math",
4332
+ group: "inline",
4333
+ inline: true,
4334
+ atom: true,
4335
+ selectable: true,
4336
+ addAttributes: () => ({ latex: { default: "", parseHTML: (el) => el.getAttribute("data-math") ?? "" } }),
4337
+ parseHTML: () => [{ tag: "span[data-math]" }],
4338
+ renderHTML: ({ node }) => ["span", { "data-math": node.attrs.latex, class: "w100n-math" }],
4339
+ addNodeView: () => ({ node }) => {
4340
+ const dom = document.createElement("span");
4341
+ dom.className = "w100n-math";
4342
+ dom.dataset.math = node.attrs.latex;
4343
+ dom.contentEditable = "false";
4344
+ dom.innerHTML = mathml(node.attrs.latex);
4345
+ return { dom };
4346
+ }
4347
+ });
4348
+ Footnote = import_core2.Node.create({
4349
+ name: "footnote",
4350
+ group: "inline",
4351
+ inline: true,
4352
+ atom: true,
4353
+ selectable: true,
4354
+ addAttributes: () => ({
4355
+ id: { default: null, parseHTML: (el) => el.getAttribute("data-note-id") },
4356
+ text: { default: "", parseHTML: (el) => el.getAttribute("title") ?? "" }
4357
+ }),
4358
+ parseHTML: () => [{ tag: "sup[data-footnote]" }],
4359
+ renderHTML: ({ node }) => ["sup", { "data-footnote": "", "data-note-id": node.attrs.id ?? void 0, title: node.attrs.text, class: "w100n-fn", contenteditable: "false" }]
4360
+ });
3946
4361
  headings = (doc, after) => {
3947
4362
  const found = [];
3948
4363
  doc.descendants((node, pos) => {
@@ -4239,7 +4654,7 @@ var init_extensions = __esm({
4239
4654
  var version;
4240
4655
  var init_package = __esm({
4241
4656
  "package.json"() {
4242
- version = "0.14.0";
4657
+ version = "0.15.0";
4243
4658
  }
4244
4659
  });
4245
4660
 
@@ -4401,7 +4816,7 @@ function fromMarkdown(source) {
4401
4816
  function serializer(style, hints, before, cell2 = false) {
4402
4817
  let form = null;
4403
4818
  const hint = (node) => hints[node.attrs.ref] ?? {};
4404
- const run2 = (parent, index, types2) => {
4819
+ const run3 = (parent, index, types2) => {
4405
4820
  let n = 0;
4406
4821
  for (let i = index - 1; i >= 0 && types2.includes(parent.child(i).type.name); i--) n++;
4407
4822
  if (!index && before && types2.includes(before.type.name)) n++;
@@ -4415,7 +4830,7 @@ function serializer(style, hints, before, cell2 = false) {
4415
4830
  state.options.tightLists = was;
4416
4831
  };
4417
4832
  const list = (state, node, parent, index) => {
4418
- const bullet = hint(node).bullet ?? (run2(parent, index, ["bulletList", "taskList"]) ? style.bullet === "-" ? "*" : "-" : style.bullet);
4833
+ const bullet = hint(node).bullet ?? (run3(parent, index, ["bulletList", "taskList"]) ? style.bullet === "-" ? "*" : "-" : style.bullet);
4419
4834
  tight(state, node, () => state.renderList(node, " ", () => `${bullet} `));
4420
4835
  };
4421
4836
  const blank6 = { open: "", close: "", mixable: true };
@@ -4463,7 +4878,7 @@ ${lines2.join("")}<!-- /toc -->`);
4463
4878
  taskList: list,
4464
4879
  orderedList(state, node, parent, index) {
4465
4880
  const start = node.attrs.start ?? 1;
4466
- const delim = hint(node).delim ?? (run2(parent, index, ["orderedList"]) ? style.delim === "." ? ")" : "." : style.delim);
4881
+ const delim = hint(node).delim ?? (run3(parent, index, ["orderedList"]) ? style.delim === "." ? ")" : "." : style.delim);
4467
4882
  const width = String(start + node.childCount - 1).length;
4468
4883
  tight(state, node, () => state.renderList(node, " ".repeat(width + 2), (i) => `${start + i}${delim} `));
4469
4884
  },
@@ -4592,7 +5007,7 @@ var init_markdown = __esm({
4592
5007
  return nodes.length === parsed.raws.length ? { ...parsed, nodes } : { ...parsed, nodes: [], raws: [], head: "", tail: "\n" };
4593
5008
  };
4594
5009
  ticks = (node, side2) => {
4595
- const len = Math.max(0, ...(node.isText ? node.text.match(/`+/g) ?? [] : []).map((run2) => run2.length));
5010
+ const len = Math.max(0, ...(node.isText ? node.text.match(/`+/g) ?? [] : []).map((run3) => run3.length));
4596
5011
  return len ? side2 > 0 ? ` ${"`".repeat(len + 1)}` : `${"`".repeat(len + 1)} ` : "`";
4597
5012
  };
4598
5013
  plain2 = (mark, parent, index) => {
@@ -7157,7 +7572,7 @@ async function save(doc, kind, base, put, load3, note) {
7157
7572
  const changed2 = !same3(bytes, base);
7158
7573
  const id = changed2 ? await put(bytes, note ?? named2((texts[who[0].language] ?? texts.en).editedNote, who)) : null;
7159
7574
  const refs2 = [];
7160
- if (changed2) schema.nodeFromJSON(await parse3(kind, bytes)).descendants((n) => {
7575
+ if (changed2) schema.nodeFromJSON(await parse4(kind, bytes)).descendants((n) => {
7161
7576
  if (n.isBlock) refs2.push([n.type.name, n.attrs.ref ?? null]);
7162
7577
  });
7163
7578
  doc.transact(() => {
@@ -7197,7 +7612,7 @@ async function workbook(doc, kind, base, put, who, note) {
7197
7612
  doc.off("afterTransaction", watch);
7198
7613
  }
7199
7614
  }
7200
- var import_core3, import_transform2, import_y_tiptap2, Y2, ours, schemas, schemaOf, parse3, edits, filled, pending, blocks2, same3, named2;
7615
+ var import_core3, import_transform2, import_y_tiptap2, Y2, ours, schemas, schemaOf, parse4, edits, filled, pending, blocks2, same3, named2;
7201
7616
  var init_collab = __esm({
7202
7617
  "src/collab.ts"() {
7203
7618
  "use strict";
@@ -7216,7 +7631,7 @@ var init_collab = __esm({
7216
7631
  ours = "w100n-collab";
7217
7632
  schemas = /* @__PURE__ */ new Map();
7218
7633
  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;
7634
+ parse4 = async (kind, bytes) => kind === "docx" ? (await readDocx(bytes)).doc : fromMarkdown(new TextDecoder().decode(bytes)).doc;
7220
7635
  edits = (tr) => tr.changedParentTypes.has(tr.doc.get("default")) || tr.changedParentTypes.has(tr.doc.get("book")) || tr.changedParentTypes.has(tr.doc.get("setup"));
7221
7636
  filled = (doc) => doc.getXmlFragment("default").length > 0 || doc.getMap("book").size > 0;
7222
7637
  pending = (doc) => doc.getMap("editors").size > 0;
@@ -7311,13 +7726,13 @@ var init_room = __esm({
7311
7726
  }
7312
7727
  store() {
7313
7728
  const room = this.room;
7314
- const run2 = room.busy.then(async () => {
7729
+ const run3 = room.busy.then(async () => {
7315
7730
  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
7731
  if (done) room.base = done.bytes;
7317
7732
  return done;
7318
7733
  });
7319
- room.busy = run2.catch(() => null);
7320
- return run2;
7734
+ room.busy = run3.catch(() => null);
7735
+ return run3;
7321
7736
  }
7322
7737
  sendStateless(payload) {
7323
7738
  if (!this.live || this.authorizedScope !== "read-write" || !JSON.parse(payload).save) return;
@@ -7458,6 +7873,8 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7458
7873
  const scroller = (0, import_react10.useRef)(null);
7459
7874
  const root = (0, import_react10.useRef)(null);
7460
7875
  const [pop, setPop] = (0, import_react10.useState)(null);
7876
+ const [dialog, setDialog] = (0, import_react10.useState)(null);
7877
+ const field = (0, import_react10.useRef)(null);
7461
7878
  const [more, setMore] = (0, import_react10.useState)(() => typeof localStorage !== "undefined" && localStorage.getItem("w100n-docs-more") === "1");
7462
7879
  const [zoom, setZoom] = (0, import_react10.useState)(null);
7463
7880
  const [layout2, setLayout] = (0, import_react10.useState)(null);
@@ -7550,11 +7967,11 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
7550
7967
  const frame = document.createElement("iframe");
7551
7968
  frame.style.cssText = "position:fixed;width:0;height:0;border:0;opacity:0";
7552
7969
  document.body.append(frame);
7553
- const [mt, mr, mb, ml] = page.margins;
7970
+ const [mt, mr, mb, ml2] = page.margins;
7554
7971
  const size2 = docx2 ? `${page.width}px ${page.height}px` : "A4";
7555
7972
  frame.contentDocument.open();
7556
7973
  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"}; }
7974
+ @page { size: ${size2}; margin: ${docx2 ? `${mt}px ${mr}px ${mb}px ${ml2}px` : "20mm"}; }
7558
7975
  body { margin: 0; font: 11pt/1.5 Arial, sans-serif; color: #111; }
7559
7976
  h1 { font-size: 20pt; } h2 { font-size: 15pt; } h3 { font-size: 13pt; }
7560
7977
  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 +8018,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
7601
8018
  if (!editor || !source.data) return;
7602
8019
  let timer = 0;
7603
8020
  let last2 = "";
7604
- const run2 = () => {
8021
+ const run3 = () => {
7605
8022
  const list = [];
7606
8023
  editor.state.doc.forEach((node, offset) => {
7607
8024
  if (node.type.name !== "heading" || !node.textContent.trim()) return;
@@ -7619,9 +8036,9 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
7619
8036
  };
7620
8037
  const later = () => {
7621
8038
  clearTimeout(timer);
7622
- timer = window.setTimeout(run2, 300);
8039
+ timer = window.setTimeout(run3, 300);
7623
8040
  };
7624
- run2();
8041
+ run3();
7625
8042
  editor.on("update", later);
7626
8043
  return () => {
7627
8044
  clearTimeout(timer);
@@ -7875,9 +8292,9 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
7875
8292
  return;
7876
8293
  }
7877
8294
  if (!mod2) return;
7878
- const act = (run2) => {
8295
+ const act = (run3) => {
7879
8296
  e.preventDefault();
7880
- run2();
8297
+ run3();
7881
8298
  };
7882
8299
  if (key2 === "s" && can.edit) act(() => void save2());
7883
8300
  else if (key2 === "k" && can.edit) act(linkUp);
@@ -7889,10 +8306,10 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
7889
8306
  else if (key2 === "enter" && docx2) act(() => editor.chain().focus().insertContent({ type: "pageBreak" }).run());
7890
8307
  else if (e.shiftKey && docx2 && ["l", "e", "r", "j"].includes(key2)) act(() => align2(editor, { l: "left", e: "center", r: "right", j: "justify" }[key2]));
7891
8308
  };
7892
- const tool = (icon, label, run2, pressed, disabled) => {
8309
+ const tool = (icon, label, run3, pressed, disabled) => {
7893
8310
  const Icon = icon;
7894
8311
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "aria-label": label, title: label, "aria-pressed": pressed, disabled, onClick: () => {
7895
- run2();
8312
+ run3();
7896
8313
  }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { "aria-hidden": true }) });
7897
8314
  };
7898
8315
  const gap = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-pdf-gap" });
@@ -7934,7 +8351,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
7934
8351
  }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Trash2, { "aria-hidden": true }) })
7935
8352
  ] })
7936
8353
  ] });
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: [
8354
+ 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
8355
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
7939
8356
  "textarea",
7940
8357
  {
@@ -7976,7 +8393,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
7976
8393
  }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("i", { style: { background: c } }) }, i))
7977
8394
  ] });
7978
8395
  const mod = /Mac|iPhone|iPad/.test(navigator.platform) ? "\u2318" : "Ctrl+";
7979
- const item = (label, run2, more2 = {}) => ({ label, run: run2, ...more2 });
8396
+ const item = (label, run3, more2 = {}) => ({ label, run: run3, ...more2 });
7980
8397
  const insertToc = () => {
7981
8398
  const at = editor.state.selection.$from.before(1);
7982
8399
  editor.chain().focus().insertContentAt(at, { type: "toc", attrs: { entries: JSON.stringify(entries(editor.state.doc, !docx2, at - 1)) } }).run();
@@ -8026,10 +8443,14 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
8026
8443
  item(t.rule, () => editor.chain().focus().setHorizontalRule().run()),
8027
8444
  "-",
8028
8445
  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` })
8446
+ can.comment && item(t.addComment, begin, { off: state.empty, keys: `${mod}\u2325M` }),
8447
+ "-",
8448
+ item(t.symbols, () => setDialog({ kind: "symbol", query: "" })),
8449
+ docx2 && item(t.formula, () => setDialog({ kind: "formula", latex: "", at: null })),
8450
+ docx2 && item(t.footnote, () => setDialog({ kind: "note", text: "", at: null }))
8030
8451
  ] : []],
8031
8452
  ["format", t.menuFormat, can.edit ? [
8032
- ...styles2.map(([key2, label, run2]) => item(label, run2, { on: state.style === key2 })),
8453
+ ...styles2.map(([key2, label, run3]) => item(label, run3, { on: state.style === key2 })),
8033
8454
  "-",
8034
8455
  item(t.bold, () => editor.chain().focus().toggleBold().run(), { on: state.bold, keys: `${mod}B` }),
8035
8456
  item(t.italic, () => editor.chain().focus().toggleItalic().run(), { on: state.italic, keys: `${mod}I` }),
@@ -8245,7 +8666,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
8245
8666
  styles2.find(([key2]) => key2 === state.style)?.[1] ?? t.normal,
8246
8667
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.ChevronDown, { "aria-hidden": true })
8247
8668
  ] }),
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)(
8669
+ 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
8670
  "button",
8250
8671
  {
8251
8672
  type: "button",
@@ -8253,7 +8674,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
8253
8674
  "data-style": key2,
8254
8675
  "aria-selected": state.style === key2,
8255
8676
  onClick: () => {
8256
- run2();
8677
+ run3();
8257
8678
  setPop(null);
8258
8679
  },
8259
8680
  children: label
@@ -8464,6 +8885,14 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
8464
8885
  status
8465
8886
  ] }),
8466
8887
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: scroller, className: "w100n-text-scroll", "data-paint": !!paint2, onMouseUp: lay, onClick: (e) => {
8888
+ const atom = can.edit ? e.target.closest(".w100n-math, sup[data-footnote]") : null;
8889
+ if (atom) {
8890
+ const at = editor.view.posAtDOM(atom, 0);
8891
+ const node = editor.state.doc.nodeAt(at);
8892
+ if (node?.type.name === "math") setDialog({ kind: "formula", latex: node.attrs.latex, at });
8893
+ if (node?.type.name === "footnote") setDialog({ kind: "note", text: node.attrs.text, at });
8894
+ return;
8895
+ }
8467
8896
  const id = e.target.closest("[data-note]")?.getAttribute("data-note");
8468
8897
  if (!id) return;
8469
8898
  setActive(id);
@@ -8487,6 +8916,104 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
8487
8916
  ] }),
8488
8917
  finder
8489
8918
  ] }) }),
8919
+ dialog && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-pdf-back", onKeyDown: (e) => {
8920
+ if (e.key === "Escape") {
8921
+ e.stopPropagation();
8922
+ setDialog(null);
8923
+ }
8924
+ }, 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: [
8925
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-new-head", children: [
8926
+ /* @__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 }) }),
8927
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("b", { className: "w100n-pdf-dialog-title", children: t.symbols }),
8928
+ /* @__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 }) })
8929
+ ] }),
8930
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "w100n-docs-field w100n-docs-search", children: [
8931
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Search, { "aria-hidden": true }),
8932
+ /* @__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 }) })
8933
+ ] }),
8934
+ /* @__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: () => {
8935
+ editor.chain().focus().insertContent(ch).run();
8936
+ setDialog(null);
8937
+ }, children: ch }, ch)) })
8938
+ ] }) : 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) => {
8939
+ e.preventDefault();
8940
+ const latex = dialog.latex.trim();
8941
+ if (!latex) return;
8942
+ if (dialog.at !== null) editor.chain().focus().command(({ tr }) => {
8943
+ tr.setNodeMarkup(dialog.at, void 0, { latex });
8944
+ return true;
8945
+ }).run();
8946
+ else editor.chain().focus().insertContent({ type: "math", attrs: { latex } }).run();
8947
+ setDialog(null);
8948
+ }, children: [
8949
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-new-head", children: [
8950
+ /* @__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 }) }),
8951
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("b", { className: "w100n-pdf-dialog-title", children: t.formula }),
8952
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w100n-docs-badge", children: t.formulaHint }),
8953
+ /* @__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 }) })
8954
+ ] }),
8955
+ /* @__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 }) }),
8956
+ /* @__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: () => {
8957
+ const el = field.current;
8958
+ const at = el.selectionStart ?? dialog.latex.length;
8959
+ const latex = dialog.latex.slice(0, at) + code + dialog.latex.slice(el.selectionEnd ?? at);
8960
+ setDialog({ ...dialog, latex });
8961
+ const caret = at + (code.indexOf("{}") >= 0 ? code.indexOf("{}") + 1 : code.length);
8962
+ requestAnimationFrame(() => {
8963
+ el.focus();
8964
+ el.setSelectionRange(caret, caret);
8965
+ });
8966
+ }, children: label }, label)) }),
8967
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-insert-preview", "aria-live": "polite", dangerouslySetInnerHTML: { __html: dialog.latex.trim() ? mathml(dialog.latex) : "" } }),
8968
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-pdf-dialog-end", children: [
8969
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "w100n-pdf-link", onClick: () => setDialog(null), children: t.cancel }),
8970
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "submit", className: "w100n-docs-action", disabled: !dialog.latex.trim(), children: [
8971
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Check, { "aria-hidden": true }),
8972
+ dialog.at !== null ? t.update : t.put
8973
+ ] })
8974
+ ] })
8975
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("form", { className: "w100n-pdf-dialog w100n-insert", role: "dialog", "aria-modal": true, "aria-label": t.footnote, onSubmit: (e) => {
8976
+ e.preventDefault();
8977
+ const text = dialog.text.trim();
8978
+ if (!text) return;
8979
+ if (dialog.at !== null) editor.chain().focus().command(({ tr }) => {
8980
+ tr.setNodeAttribute(dialog.at, "text", text);
8981
+ return true;
8982
+ }).run();
8983
+ else editor.chain().focus().insertContent({ type: "footnote", attrs: { id: null, text } }).run();
8984
+ setDialog(null);
8985
+ }, children: [
8986
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-new-head", children: [
8987
+ /* @__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 }) }),
8988
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("b", { className: "w100n-pdf-dialog-title", children: t.footnote }),
8989
+ /* @__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 }) })
8990
+ ] }),
8991
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
8992
+ "textarea",
8993
+ {
8994
+ autoFocus: true,
8995
+ className: "w100n-insert-note",
8996
+ value: dialog.text,
8997
+ "aria-label": t.footnoteText,
8998
+ placeholder: t.footnoteText,
8999
+ onChange: (e) => setDialog({ ...dialog, text: e.target.value }),
9000
+ onKeyDown: (e) => {
9001
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) e.currentTarget.form?.requestSubmit();
9002
+ }
9003
+ }
9004
+ ),
9005
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "w100n-pdf-dialog-end", children: [
9006
+ dialog.at !== null && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "w100n-pdf-link", onClick: () => {
9007
+ editor.chain().focus().deleteRange({ from: dialog.at, to: dialog.at + 1 }).run();
9008
+ setDialog(null);
9009
+ }, children: t.removeFootnote }),
9010
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "w100n-pdf-link", onClick: () => setDialog(null), children: t.cancel }),
9011
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "submit", className: "w100n-docs-action", disabled: !dialog.text.trim(), children: [
9012
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Check, { "aria-hidden": true }),
9013
+ dialog.at !== null ? t.update : t.put
9014
+ ] })
9015
+ ] })
9016
+ ] }) }),
8490
9017
  draft2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w100n-pdf-back", onKeyDown: (e) => {
8491
9018
  if (e.key === "Escape") {
8492
9019
  e.stopPropagation();
@@ -8626,10 +9153,10 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
8626
9153
  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
9154
  person(c),
8628
9155
  c.quote && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("blockquote", { children: c.quote }),
8629
- words(c),
9156
+ words2(c),
8630
9157
  all.filter((r) => r.replyTo === c.id).map((r) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-text-reply", children: [
8631
9158
  person(r),
8632
- words(r)
9159
+ words2(r)
8633
9160
  ] }, r.id)),
8634
9161
  reply?.id === c.id && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w100n-text-reply", onClick: (e) => e.stopPropagation(), children: [
8635
9162
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
@@ -8668,7 +9195,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
8668
9195
  ] }), slot)
8669
9196
  ] });
8670
9197
  }
8671
- var import_react9, import_lucide_react5, import_react10, import_react_dom2, import_jsx_runtime6, legal, cm, inks, glows, faces, sizes, uid2;
9198
+ var import_react9, import_lucide_react5, import_react10, import_react_dom2, import_jsx_runtime6, legal, symbols, helpers, cm, inks, glows, faces, sizes, uid2;
8672
9199
  var init_TextEditor = __esm({
8673
9200
  "src/editor/TextEditor.tsx"() {
8674
9201
  "use strict";
@@ -8683,9 +9210,63 @@ var init_TextEditor = __esm({
8683
9210
  init_extensions();
8684
9211
  init_live();
8685
9212
  init_markdown();
9213
+ init_math();
8686
9214
  init_pager();
8687
9215
  import_jsx_runtime6 = require("react/jsx-runtime");
8688
9216
  legal = { width: 816, height: 1344 };
9217
+ symbols = [
9218
+ ["\xA9", "copyright"],
9219
+ ["\xAE", "registered"],
9220
+ ["\u2122", "trademark"],
9221
+ ["\xA7", "section"],
9222
+ ["\xB6", "paragraph"],
9223
+ ["\u2020", "dagger"],
9224
+ ["\u2021", "double dagger"],
9225
+ ["\u2022", "bullet"],
9226
+ ["\u2026", "ellipsis"],
9227
+ ["\u2030", "per mille"],
9228
+ ["\u20AC", "euro"],
9229
+ ["\xA3", "pound"],
9230
+ ["\xA5", "yen"],
9231
+ ["\u20B4", "hryvnia"],
9232
+ ["z\u0142", "zloty"],
9233
+ ["\xB0", "degree"],
9234
+ ["\xB1", "plus minus"],
9235
+ ["\xD7", "times multiply"],
9236
+ ["\xF7", "divide"],
9237
+ ["\u2248", "approximately"],
9238
+ ["\u2260", "not equal"],
9239
+ ["\u2264", "less or equal"],
9240
+ ["\u2265", "greater or equal"],
9241
+ ["\u221E", "infinity"],
9242
+ ["\u221A", "square root"],
9243
+ ["\u2211", "sum"],
9244
+ ["\u03C0", "pi"],
9245
+ ["\u03A9", "omega"],
9246
+ ["\xB5", "micro"],
9247
+ ["\u03B1", "alpha"],
9248
+ ["\u03B2", "beta"],
9249
+ ["\u03B3", "gamma"],
9250
+ ["\u0394", "delta"],
9251
+ ["\u03BB", "lambda"],
9252
+ ["\u2192", "arrow right"],
9253
+ ["\u2190", "arrow left"],
9254
+ ["\u2191", "arrow up"],
9255
+ ["\u2193", "arrow down"],
9256
+ ["\u21D2", "arrow implies"],
9257
+ ["\u2713", "check tick"],
9258
+ ["\u2014", "em dash"],
9259
+ ["\u2013", "en dash"],
9260
+ ["\xAB", "quote left"],
9261
+ ["\xBB", "quote right"],
9262
+ ["\u201E", "quote low"],
9263
+ ["\u2116", "number"],
9264
+ ["\xBD", "half"],
9265
+ ["\xBC", "quarter"],
9266
+ ["\xB2", "squared"],
9267
+ ["\xB3", "cubed"]
9268
+ ];
9269
+ 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
9270
  cm = (px2) => Math.round(px2 / 96 * 254) / 100;
8690
9271
  inks = ["#0f172a", "#475569", "#dc2626", "#ea580c", "#ca8a04", "#16a34a", "#0891b2", "#2563eb", "#7c3aed", "#db2777"];
8691
9272
  glows = ["#fef08a", "#bbf7d0", "#bfdbfe", "#fbcfe8", "#fed7aa", "#ddd6fe"];
@@ -8770,7 +9351,7 @@ function bind(api, injector, doc, model, edit) {
8770
9351
  let open = true;
8771
9352
  const looks = wb.getStyles();
8772
9353
  const commands = injector.get(import_core4.ICommandService);
8773
- const run2 = (id, params) => commands.hasCommand(id) && commands.syncExecuteCommand(id, { unitId: unit, ...params }, { fromCollab: true });
9354
+ const run3 = (id, params) => commands.hasCommand(id) && commands.syncExecuteCommand(id, { unitId: unit, ...params }, { fromCollab: true });
8774
9355
  const ws = (sid) => wb.getSheetBySheetId(sid);
8775
9356
  const at = /* @__PURE__ */ new Map();
8776
9357
  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 +9588,7 @@ function bind(api, injector, doc, model, edit) {
9007
9588
  const r = rows.get(row2), c = cols.get(col);
9008
9589
  if (r !== void 0 && c !== void 0) (cellValue[r] ?? (cellValue[r] = {}))[c] = full(sid, key2, cells.get(key2));
9009
9590
  }
9010
- if (Object.keys(cellValue).length) run2("sheet.mutation.set-range-values", { subUnitId: sid, cellValue, isOverrideStyle: true });
9591
+ if (Object.keys(cellValue).length) run3("sheet.mutation.set-range-values", { subUnitId: sid, cellValue, isOverrideStyle: true });
9011
9592
  };
9012
9593
  const linesTo = (sid, ids, row2) => {
9013
9594
  const { rowData, colData } = pieces(sheets.get(sid));
@@ -9026,11 +9607,11 @@ function bind(api, injector, doc, model, edit) {
9026
9607
  }
9027
9608
  if (!ranges.length) return;
9028
9609
  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 });
9610
+ run3("sheet.mutation.set-row-data", { subUnitId: sid, rowData: info });
9611
+ run3("sheet.mutation.set-worksheet-row-height", { subUnitId: sid, ranges, rowHeight: sizes2 });
9031
9612
  } 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 });
9613
+ run3("sheet.mutation.set-col-data", { subUnitId: sid, columnData: info });
9614
+ run3("sheet.mutation.set-worksheet-col-width", { subUnitId: sid, ranges, colWidth: sizes2 });
9034
9615
  }
9035
9616
  };
9036
9617
  const mergesTo = (sid) => {
@@ -9039,16 +9620,16 @@ function bind(api, injector, doc, model, edit) {
9039
9620
  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
9621
  const has = ws(sid).getMergeData().map((b) => ({ startRow: b.startRow, startColumn: b.startColumn, endRow: b.endRow, endColumn: b.endColumn }));
9041
9622
  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 });
9623
+ if (gone.length) run3("sheet.mutation.remove-worksheet-merge", { subUnitId: sid, ranges: gone });
9624
+ if (added.length) run3("sheet.mutation.add-worksheet-merge", { subUnitId: sid, ranges: added });
9044
9625
  };
9045
9626
  const notesTo = (sid) => {
9046
9627
  const want = notesOf2(sheets.get(sid), lines2[sid]);
9047
9628
  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 });
9629
+ 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
9630
  for (const w of want) {
9050
9631
  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 } });
9632
+ 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
9633
  }
9053
9634
  };
9054
9635
  const shape3 = () => {
@@ -9060,7 +9641,7 @@ function bind(api, injector, doc, model, edit) {
9060
9641
  const other = want.find((x) => wb.getSheetBySheetId(x));
9061
9642
  if (other) api.syncExecuteCommand("sheet.operation.set-worksheet-active", { unitId: unit, subUnitId: other });
9062
9643
  }
9063
- run2("sheet.mutation.remove-sheet", { subUnitId: sid });
9644
+ run3("sheet.mutation.remove-sheet", { subUnitId: sid });
9064
9645
  delete lines2[sid];
9065
9646
  at.delete(sid);
9066
9647
  }
@@ -9068,12 +9649,12 @@ function bind(api, injector, doc, model, edit) {
9068
9649
  if (wb.getSheetBySheetId(sid)) return;
9069
9650
  const { rows, cols } = pieces(sheets.get(sid));
9070
9651
  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() });
9652
+ 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
9653
  notesTo(sid);
9073
9654
  });
9074
9655
  want.forEach((sid, i) => {
9075
9656
  const now = wb.getSheetOrders().indexOf(sid);
9076
- if (now >= 0 && now !== i) run2("sheet.mutation.set-worksheet-order", { subUnitId: sid, fromOrder: now, toOrder: i });
9657
+ if (now >= 0 && now !== i) run3("sheet.mutation.set-worksheet-order", { subUnitId: sid, fromOrder: now, toOrder: i });
9077
9658
  });
9078
9659
  };
9079
9660
  const move2 = (sid, delta, row2) => {
@@ -9085,15 +9666,15 @@ function bind(api, injector, doc, model, edit) {
9085
9666
  if (d.retain) i += d.retain;
9086
9667
  if (d.delete) {
9087
9668
  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 } });
9669
+ if (row2) run3("sheet.mutation.remove-rows", { subUnitId: sid, range: { startRow: i, endRow: end, startColumn: 0, endColumn: lines2[sid].cols.length - 1, rangeType: 1 } });
9670
+ else run3("sheet.mutation.remove-col", { subUnitId: sid, range: { startRow: 0, endRow: lines2[sid].rows.length - 1, startColumn: i, endColumn: end, rangeType: 2 } });
9090
9671
  list.splice(i, d.delete);
9091
9672
  }
9092
9673
  if (d.insert) {
9093
9674
  const ids = d.insert;
9094
9675
  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 } });
9676
+ if (row2) run3("sheet.mutation.insert-row", { subUnitId: sid, range: { startRow: i, endRow: end, startColumn: 0, endColumn: lines2[sid].cols.length - 1 } });
9677
+ else run3("sheet.mutation.insert-col", { subUnitId: sid, range: { startRow: 0, endRow: lines2[sid].rows.length - 1, startColumn: i, endColumn: end } });
9097
9678
  list.splice(i, 0, ...ids);
9098
9679
  ids.forEach((id) => added.add(id));
9099
9680
  i += ids.length;
@@ -9139,7 +9720,7 @@ function bind(api, injector, doc, model, edit) {
9139
9720
  if (s.rows || s.cols) structural = true;
9140
9721
  for (const [name, id, key2, empty] of setters) if (s.props.has(name)) {
9141
9722
  const v = sheets.get(sid).get(name) ?? empty;
9142
- run2(id, { subUnitId: sid, ...key2 ? { [key2]: v } : v });
9723
+ run3(id, { subUnitId: sid, ...key2 ? { [key2]: v } : v });
9143
9724
  }
9144
9725
  const keys2 = new Set(s.cells);
9145
9726
  if (rows.size || cols.size) {
@@ -9472,7 +10053,7 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
9472
10053
  });
9473
10054
  useRestore(pop !== null);
9474
10055
  const api = () => live.current?.api;
9475
- const run2 = (id, params) => {
10056
+ const run3 = (id, params) => {
9476
10057
  void api()?.executeCommand(id, params);
9477
10058
  setPop(null);
9478
10059
  };
@@ -9582,18 +10163,18 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
9582
10163
  tool(import_lucide_react6.DecimalsArrowLeft, t.fewerDecimals, () => places(-1)),
9583
10164
  tool(import_lucide_react6.DecimalsArrowRight, t.moreDecimals, () => places(1)),
9584
10165
  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),
10166
+ tool(import_lucide_react6.Bold, t.bold, () => run3("sheet.command.set-range-bold"), look?.bl),
10167
+ tool(import_lucide_react6.Italic, t.italic, () => run3("sheet.command.set-range-italic"), look?.it),
10168
+ tool(import_lucide_react6.Underline, t.underline, () => run3("sheet.command.set-range-underline"), look?.ul),
10169
+ tool(import_lucide_react6.Strikethrough, t.strike, () => run3("sheet.command.set-range-stroke"), look?.st),
9589
10170
  anchor(
9590
10171
  "text",
9591
10172
  opener("text", import_lucide_react6.Baseline, t.textColour, look?.cl ?? ""),
9592
10173
  swatches(
9593
10174
  ["#0f172a", "#475569", "#dc2626", "#ea580c", "#ca8a04", "#16a34a", "#0891b2", "#2563eb", "#7c3aed", "#db2777"],
9594
- (c) => run2("sheet.command.set-range-text-color", { value: c }),
10175
+ (c) => run3("sheet.command.set-range-text-color", { value: c }),
9595
10176
  t.automatic,
9596
- () => run2("sheet.command.reset-range-text-color"),
10177
+ () => run3("sheet.command.reset-range-text-color"),
9597
10178
  look?.cl ?? ""
9598
10179
  )
9599
10180
  ),
@@ -9602,9 +10183,9 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
9602
10183
  opener("fill", import_lucide_react6.PaintBucket, t.fill, look?.bg ?? ""),
9603
10184
  swatches(
9604
10185
  ["#fee2e2", "#ffedd5", "#fef9c3", "#dcfce7", "#cffafe", "#dbeafe", "#ede9fe", "#fce7f3", "#f1f5f9", "#cbd5e1"],
9605
- (c) => run2("sheet.command.set-background-color", { value: c }),
10186
+ (c) => run3("sheet.command.set-background-color", { value: c }),
9606
10187
  t.noFill,
9607
- () => run2("sheet.command.reset-background-color"),
10188
+ () => run3("sheet.command.reset-background-color"),
9608
10189
  look?.bg ?? ""
9609
10190
  )
9610
10191
  ),
@@ -9617,16 +10198,16 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
9617
10198
  ] }, type)) })
9618
10199
  ),
9619
10200
  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")),
10201
+ tool(import_lucide_react6.TextAlignStart, t.alignLeft, () => run3("sheet.command.set-horizontal-text-align", { value: 1 }), look?.ht === 1),
10202
+ tool(import_lucide_react6.TextAlignCenter, t.alignCenter, () => run3("sheet.command.set-horizontal-text-align", { value: 2 }), look?.ht === 2),
10203
+ tool(import_lucide_react6.TextAlignEnd, t.alignRight, () => run3("sheet.command.set-horizontal-text-align", { value: 3 }), look?.ht === 3),
10204
+ tool(import_lucide_react6.TextWrap, t.wrap, () => run3("sheet.command.set-text-wrap", { value: look?.tb ? 1 : 3 }), look?.tb),
10205
+ 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
10206
  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")),
10207
+ tool(import_lucide_react6.BetweenHorizontalStart, t.rowAbove, () => run3("sheet.command.insert-row-before")),
10208
+ tool(import_lucide_react6.BetweenHorizontalEnd, t.rowBelow, () => run3("sheet.command.insert-row-after")),
10209
+ tool(import_lucide_react6.BetweenVerticalStart, t.columnLeft, () => run3("sheet.command.insert-col-before")),
10210
+ tool(import_lucide_react6.BetweenVerticalEnd, t.columnRight, () => run3("sheet.command.insert-col-after")),
9630
10211
  tool(import_lucide_react6.TableRowsSplit, t.deleteRows, () => lines2(true)),
9631
10212
  tool(import_lucide_react6.TableColumnsSplit, t.deleteColumns, () => lines2(false)),
9632
10213
  anchor(
@@ -9641,7 +10222,7 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
9641
10222
  sheet2()?.setFrozenColumns(1);
9642
10223
  setPop(null);
9643
10224
  }, children: t.freezeColumn }),
9644
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", onClick: () => run2("sheet.command.set-selection-frozen"), children: t.freezeHere }),
10225
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", onClick: () => run3("sheet.command.set-selection-frozen"), children: t.freezeHere }),
9645
10226
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", onClick: () => {
9646
10227
  sheet2()?.cancelFreeze();
9647
10228
  setPop(null);
@@ -9650,13 +10231,13 @@ function SheetView({ bytes, name, kind, rights, language, theme, onChange, onSav
9650
10231
  ),
9651
10232
  gap,
9652
10233
  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")),
10234
+ tool(import_lucide_react6.ArrowDownAZ, t.sortUp, () => run3("sheet.command.sort-range-asc")),
10235
+ tool(import_lucide_react6.ArrowDownZA, t.sortDown, () => run3("sheet.command.sort-range-desc")),
10236
+ !room && tool(import_lucide_react6.Funnel, t.filter, () => run3("sheet.command.smart-toggle-filter")),
9656
10237
  gap
9657
10238
  ] }),
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"))
10239
+ (edit || notes2) && tool(import_lucide_react6.StickyNote, t.note, () => run3("sheet.operation.add-note-popup")),
10240
+ tool(import_lucide_react6.Search, t.find, () => run3("ui.operation.open-find-dialog"))
9660
10241
  ] }),
9661
10242
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "w100n-sheet-end", children: [
9662
10243
  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 +10352,8 @@ function readable(name, mimeType) {
9771
10352
  return kind !== "sheet" || /\.(xlsx|csv)$/i.test(name) || /spreadsheetml|text\/csv/.test(mimeType ?? "") ? kind : null;
9772
10353
  }
9773
10354
  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));
10355
+ const words2 = query.toLocaleLowerCase().split(/\s+/).filter(Boolean);
10356
+ return (!picked.length || picked.includes(doc.kind)) && words2.every((word) => doc.name.toLocaleLowerCase().includes(word));
9776
10357
  }
9777
10358
 
9778
10359
  // src/slides/SlidesView.tsx
@@ -10280,8 +10861,8 @@ function moveSlide(deck, from, to) {
10280
10861
  const slide = deck.slides[from];
10281
10862
  const rest = deck.slides.filter((_, i) => i !== from);
10282
10863
  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));
10864
+ const run3 = rest.flatMap((other, i) => slide.stack !== null && other.stack === slide.stack ? [i] : []);
10865
+ if (run3.length) at = Math.max(run3[0], Math.min(run3[run3.length - 1] + 1, at));
10285
10866
  else if (at > 0 && at < rest.length && rest[at].stack !== null && rest[at - 1].stack === rest[at].stack) {
10286
10867
  let end = at;
10287
10868
  while (end < rest.length && rest[end].stack === rest[at].stack) end++;
@@ -10871,7 +11452,7 @@ function SlidesView({ html, name, rights, language = "en", theme = "light", base
10871
11452
  popup.close();
10872
11453
  };
10873
11454
  }, [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 }) });
11455
+ 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
11456
  const thumb = 148;
10876
11457
  const seconds = Math.floor(Math.max(0, (timer.stop ?? now) - timer.from) / 1e3);
10877
11458
  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 +11704,7 @@ var same = (a, b) => !!b && a.page === b.page && a.start === b.start;
11123
11704
  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
11705
  function PdfPage({ pdf, n, size: size2, scale, live, id, layers }) {
11125
11706
  const paint2 = (0, import_react5.useRef)(null);
11126
- const words = (0, import_react5.useRef)(null);
11707
+ const words2 = (0, import_react5.useRef)(null);
11127
11708
  const forms = (0, import_react5.useRef)(null);
11128
11709
  const focus = (0, import_react5.useRef)(null);
11129
11710
  const rubbed = (0, import_react5.useRef)(null);
@@ -11135,7 +11716,7 @@ function PdfPage({ pdf, n, size: size2, scale, live, id, layers }) {
11135
11716
  const hitKey = layers ? layers.hits.map((hit) => `${hit.start}:${hit.end}`).join() : "";
11136
11717
  (0, import_react5.useEffect)(() => {
11137
11718
  if (!live) return;
11138
- const holders = [paint2, words, forms].flatMap((ref) => ref.current ? [ref.current] : []);
11719
+ const holders = [paint2, words2, forms].flatMap((ref) => ref.current ? [ref.current] : []);
11139
11720
  return () => {
11140
11721
  for (const holder of holders) {
11141
11722
  for (const canvas of holder.querySelectorAll("canvas")) {
@@ -11220,7 +11801,7 @@ function PdfPage({ pdf, n, size: size2, scale, live, id, layers }) {
11220
11801
  const end = document.createElement("div");
11221
11802
  end.className = "endOfContent";
11222
11803
  layer.append(end);
11223
- words.current.replaceChildren(layer);
11804
+ words2.current.replaceChildren(layer);
11224
11805
  const annotations = await page.getAnnotations();
11225
11806
  for (const a of annotations) {
11226
11807
  if (!a.fieldName || a.pushButton || !["Tx", "Btn", "Ch"].includes(a.fieldType)) continue;
@@ -11256,7 +11837,7 @@ function PdfPage({ pdf, n, size: size2, scale, live, id, layers }) {
11256
11837
  };
11257
11838
  }, [pdf, n, live, fill3]);
11258
11839
  (0, import_react5.useLayoutEffect)(() => {
11259
- const layer = words.current?.firstElementChild;
11840
+ const layer = words2.current?.firstElementChild;
11260
11841
  if (!layers || !layer || !hitKey) {
11261
11842
  setBoxes([]);
11262
11843
  return;
@@ -11351,7 +11932,7 @@ function PdfPage({ pdf, n, size: size2, scale, live, id, layers }) {
11351
11932
  };
11352
11933
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "w100n-pdf-page", id, "data-n": n, style, children: [
11353
11934
  /* @__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" }),
11935
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: words2, className: "w100n-pdf-words" }),
11355
11936
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: forms, className: "w100n-pdf-forms" }),
11356
11937
  /* @__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
11938
  marks2.map((mark) => {
@@ -11467,7 +12048,7 @@ function PdfView({ bytes, t, language, worker, rights, host, documentId, onSaved
11467
12048
  const pad = (0, import_react6.useRef)(null);
11468
12049
  const inked = (0, import_react6.useRef)(null);
11469
12050
  const widgets = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
11470
- const words = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
12051
+ const words2 = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
11471
12052
  const anchor = (0, import_react6.useRef)({ scale: 0, page: 0, frac: 0 });
11472
12053
  const [pdf, setPdf] = (0, import_react6.useState)(null);
11473
12054
  const [sizes2, setSizes] = (0, import_react6.useState)([]);
@@ -11509,7 +12090,7 @@ function PdfView({ bytes, t, language, worker, rights, host, documentId, onSaved
11509
12090
  setFilled(false);
11510
12091
  setOpen(null);
11511
12092
  widgets.current = /* @__PURE__ */ new Map();
11512
- words.current = /* @__PURE__ */ new Map();
12093
+ words2.current = /* @__PURE__ */ new Map();
11513
12094
  (async () => {
11514
12095
  var _a;
11515
12096
  const pdfjs = await import("pdfjs-dist");
@@ -11634,11 +12215,11 @@ function PdfView({ bytes, t, language, worker, rights, host, documentId, onSaved
11634
12215
  const timer = setTimeout(async () => {
11635
12216
  const found = [];
11636
12217
  for (let n = 1; n <= pdf.numPages && !stop; n++) {
11637
- let text = words.current.get(n);
12218
+ let text = words2.current.get(n);
11638
12219
  if (text === void 0) {
11639
12220
  const content = await (await pdf.getPage(n)).getTextContent();
11640
12221
  text = content.items.map((piece) => "str" in piece ? piece.str + (piece.hasEOL ? " " : "") : "").join("").toLowerCase();
11641
- words.current.set(n, text);
12222
+ words2.current.set(n, text);
11642
12223
  }
11643
12224
  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
12225
  if (!stop && (n % 20 === 0 || n === pdf.numPages)) setHits({ list: [...found], done: n === pdf.numPages });
@@ -12313,12 +12894,12 @@ var templates = {
12313
12894
  [null, "What comes next and who owns it."]
12314
12895
  ]
12315
12896
  };
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>`;
12897
+ var run2 = (text) => text ? `<w:r><w:t xml:space="preserve">${escape2(text)}</w:t></w:r>` : "";
12898
+ var para = ([style, text]) => `<w:p>${style ? `<w:pPr><w:pStyle w:val="${style}"/></w:pPr>` : ""}${run2(text)}</w:p>`;
12318
12899
  var table2 = (rows) => {
12319
12900
  const width = Math.floor(9638 / rows[0].length);
12320
12901
  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/>";
12902
+ 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
12903
  };
12323
12904
  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
12905
  function docx(blocks3) {
@@ -13191,8 +13772,8 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
13191
13772
  }, []);
13192
13773
  const now = reading?.documentId === here.documentId ? reading : null;
13193
13774
  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));
13775
+ const words2 = hunt.toLocaleLowerCase().split(/\s+/).filter(Boolean);
13776
+ const hit = (h) => words2.every((w) => h.text.toLocaleLowerCase().includes(w));
13196
13777
  const reach = (h) => h.go ? h.go() : document.getElementById(h.id)?.scrollIntoView({ behavior: "smooth", block: "start" });
13197
13778
  const crumbs = doc.data ? [names2.get(doc.data.spaceId), doc.data.folder].filter(Boolean) : space ? [space.name] : [];
13198
13779
  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 +14008,7 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
13427
14008
  /* @__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
14009
  /* @__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
14010
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { "aria-hidden": true }),
13430
- (panelTabs.length < 4 || tab === key2) && label
14011
+ (panelTabs.length < 4 || tab === key2 && panelTabs.length < 5) && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: label })
13431
14012
  ] }, key2)) }),
13432
14013
  /* @__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
14014
  ] }) }),
@@ -13446,9 +14027,9 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place: pla
13446
14027
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { value: hunt, onChange: (e) => setHunt(e.target.value), placeholder: t.findHeading, "aria-label": t.findHeading })
13447
14028
  ] }),
13448
14029
  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);
14030
+ const subs = words2.length ? c.subs.filter(hit) : c.subs;
14031
+ if (words2.length && !hit(c.head) && !subs.length) return null;
14032
+ const opened3 = words2.length > 0 || (fold[c.head.id] ?? i === reached);
13452
14033
  const named3 = /^(\d+)[.)]?\s+(.+)$/.exec(c.head.text);
13453
14034
  const mark = c.subs.findIndex((s) => s.id === now?.id);
13454
14035
  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: [