gutterpress 0.11.23-alpha.7 → 0.11.23-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +3 -1
  2. package/dist/{README-syg2hn83.md → README-8rct3axy.md} +2 -2
  3. package/dist/api/index.d.ts +3 -3
  4. package/dist/api/index.js +8 -6
  5. package/dist/{build-w572wq10.js → build-3e18wnqj.js} +9 -8
  6. package/dist/{cli-mmgtqnmr.js → cli-0ep11b0q.js} +1 -1
  7. package/dist/cli-65gy8ask.js +82 -0
  8. package/dist/{cli-6pv84kf3.js → cli-88arpdke.js} +6 -84
  9. package/dist/{cli-eatdqx3z.js → cli-9n9kg58f.js} +1 -1
  10. package/dist/{cli-58fsk6d7.js → cli-pd2cje5b.js} +187 -44
  11. package/dist/{cli-3cvq3n1c.js → cli-pnrararp.js} +189 -85
  12. package/dist/{cli-wyg7qstd.js → cli-tgnyvra3.js} +15 -5
  13. package/dist/{cli-31anr0r9.js → cli-v0evdpdf.js} +68 -28
  14. package/dist/{cli-5ba6bm6z.js → cli-x7gcdg6w.js} +1 -1
  15. package/dist/cli.js +12 -12
  16. package/dist/{doctor-2f3zqmza.js → doctor-2f4s9dyn.js} +3 -3
  17. package/dist/engine/compiler/postprocess.d.ts +3 -0
  18. package/dist/engine/shared/page-vars.d.ts +32 -0
  19. package/dist/engine/shared/pdf-inspect.d.ts +33 -0
  20. package/dist/{engine-4rabsgwq.js → engine-c4pxz79g.js} +2 -1
  21. package/dist/{engine-wm4fggac.js → engine-cs5g2ez0.js} +3 -3
  22. package/dist/{ext-0cgky8n3.js → ext-70gv86v5.js} +9 -8
  23. package/dist/{extension-restore-vghc58vx.js → extension-restore-chj5nx3t.js} +3 -3
  24. package/dist/{extension-restore-e7je32pr.js → extension-restore-pd87p8r2.js} +5 -4
  25. package/dist/{gutterpress-agent-d29ry3ak.js → gutterpress-agent-wyryqehx.js} +13 -4
  26. package/dist/{gutterpress-viewer-mafsby5k.js → gutterpress-viewer-ywkf49q5.js} +90 -166
  27. package/dist/{index-nfysshcc.js → index-0k43evt0.js} +309 -155
  28. package/dist/{index-wm4x7xbf.js → index-2t1gdma7.js} +178 -35
  29. package/dist/{index-cw03e9p4.js → index-7j3hkwya.js} +68 -28
  30. package/dist/{index-fp7xwvpr.js → index-80vg3ed6.js} +15 -5
  31. package/dist/{index-2vxzxyyj.js → index-swfdgn2n.js} +10 -10
  32. package/dist/index-tayzfr9c.js +99 -0
  33. package/dist/{index-hphcn7th.js → index-ytjkvwy5.js} +5 -85
  34. package/dist/index.d.ts +2 -0
  35. package/dist/index.js +234 -7
  36. package/dist/lib/book-css.d.ts +56 -0
  37. package/dist/lib/markdown/assemble.d.ts +58 -0
  38. package/dist/lib/markdown/gutterpress-css.d.ts +1 -1
  39. package/dist/lib/publish/google-drive.d.ts +12 -4
  40. package/dist/lib/publish/manifest-publish.d.ts +6 -0
  41. package/dist/lib/publish/providers/gdrive-folder.d.ts +30 -0
  42. package/dist/lib/publish/run-publish.d.ts +6 -1
  43. package/dist/lib/publish/types.d.ts +52 -5
  44. package/dist/lib/remote-auth/converge-merge.d.ts +3 -3
  45. package/dist/lib/remote-auth/sync-messages.d.ts +2 -2
  46. package/dist/lib/root-tokens.d.ts +76 -0
  47. package/dist/lib/source-provider.d.ts +27 -0
  48. package/dist/lib/version-changes.d.ts +26 -16
  49. package/dist/{manifest-79zsgkpn.yaml → manifest-0vwaskj2.yaml} +1 -1
  50. package/dist/{manifest-2kc56wvw.yaml → manifest-aya31jwt.yaml} +1 -1
  51. package/dist/{manifest-41ddzm13.yaml → manifest-mffah3hr.yaml} +1 -1
  52. package/dist/{manifest-sqzm4681.yaml → manifest-wbcv8cbp.yaml} +2 -2
  53. package/dist/{manifest.schema-93sd7zje.json → manifest.schema-0jgj0jt1.json} +1 -1
  54. package/dist/{new-88rkrv71.js → new-d61n5cn0.js} +9 -8
  55. package/dist/{page-rules-ytj9p04v.css → page-rules-vnja6grt.css} +2 -2
  56. package/dist/{plugins-3aj0wc5h.js → plugins-0hhw6s17.js} +1 -1
  57. package/dist/{plugins-sprxsz5d.js → plugins-e0n46s6m.js} +3 -3
  58. package/dist/{preflight-11dg1qkk.js → preflight-fjayhjr5.js} +9 -8
  59. package/dist/{preview-nftp782j.js → preview-h815jrfb.js} +9 -8
  60. package/dist/{publish-6tgxfck9.js → publish-ft39zgma.js} +25 -9
  61. package/dist/render.js +77 -26
  62. package/dist/schema/manifest.types.d.ts +2 -1
  63. package/dist/{source-provider-n7vehh6t.js → source-provider-j1w7byeq.js} +5 -1
  64. package/dist/{source-provider-tgzet3j5.js → source-provider-tjaf303m.js} +5 -1
  65. package/dist/test-helpers/vocabulary.d.ts +12 -0
  66. package/dist/{tokens-n82t4k9h.css → tokens-a7grv940.css} +4 -5
  67. package/dist/{validate-pktqrye5.js → validate-b201dbrb.js} +9 -8
  68. package/package.json +1 -1
  69. package/dist/index-46ycxe6r.js +0 -18
@@ -34,12 +34,12 @@
34
34
  makeOverflowFragmentable: () => makeOverflowFragmentable,
35
35
  loadStyleSources: () => loadStyleSources,
36
36
  injectViewerCss: () => injectViewerCss,
37
+ injectPageVars: () => injectPageVars,
37
38
  injectBreakMapping: () => injectBreakMapping,
38
39
  indexInStrip: () => indexInStrip,
39
40
  fragmentDocument: () => fragmentDocument,
40
41
  cssZoomOf: () => cssZoomOf,
41
42
  contentEdgeRect: () => contentEdgeRect,
42
- compensateRepeatedHeaders: () => compensateRepeatedHeaders,
43
43
  compensateRectoBreaks: () => compensateRectoBreaks,
44
44
  columnReserve: () => columnReserve,
45
45
  collectCssText: () => collectCssText,
@@ -192,6 +192,29 @@
192
192
  no extractable body text; \`rabbit-walking.png\` (1379x2530, unique) sits on
193
193
  PDF p134 vs viewer folio 135. */
194
194
 
195
+ /* Repeated table headers and footers. Print draws a table's header group
196
+ (\`thead\`) at the top of every page the table spans, and its footer group
197
+ (\`tfoot\`) at the foot of each, and never leaves a header alone at the foot
198
+ of a page. Chromium does the same in a multicol column, through the same
199
+ table fragmentation, when the group is unbreakable; print media treats
200
+ every header and footer group so, the screen only one that is
201
+ \`break-inside: avoid\` (measured: on screen, a plain \`thead\` printed once and
202
+ a \`break-inside: avoid\` one on every column, exactly as print media does).
203
+ Setting it here makes the columns repeat the groups print repeats, where
204
+ print repeats them, and break around them as print does. A group the author
205
+ set to another \`display\` is not a header group and repeats in neither.
206
+
207
+ The viewer used to imitate this in script, cloning the header into each
208
+ continuation column and forcing a break before a table whose header would
209
+ be left alone. It moved a lead-in paragraph whole where print splits it,
210
+ left a clone at a column's foot, drew a second header wherever Chromium
211
+ already drew one, and shifted pages after the forced-break spacers had been
212
+ placed, losing a chapter's break (the gp-dimm-city design guide's reference
213
+ tables: #454). docs/fixtures/repeated-table-header pins it. */
214
+ .gp-strip :is(thead, tfoot) {
215
+ break-inside: avoid;
216
+ }
217
+
195
218
  /* View mode (\`applySpreadMode\` in fragment.ts): wraps this run's multicol
196
219
  columns into \`--gp-wrap-cols\` ROWS instead of one long row — 2 for
197
220
  two-up/spread, 1 for single (a plain vertical stack of pages), using
@@ -1118,6 +1141,7 @@
1118
1141
  }
1119
1142
 
1120
1143
  // src/engine/shared/print-area.ts
1144
+ var round3 = (n) => Math.round(n * 1000) / 1000;
1121
1145
  function printAreaFromMeta(doc) {
1122
1146
  const raw = doc.querySelector('meta[name="gp-print-area"]')?.getAttribute("content");
1123
1147
  if (!raw)
@@ -1200,6 +1224,33 @@
1200
1224
  return { kind, gap, need };
1201
1225
  }
1202
1226
 
1227
+ // src/engine/shared/page-vars.ts
1228
+ var decls = (pairs) => pairs.map(([name, n]) => `--gp-page-${name}: ${round3(n)}pt;`).join(" ");
1229
+ function pageDecls(model, name) {
1230
+ const { width, height, margin } = resolvePage(model, { name, pseudos: ["right"] }).geometry;
1231
+ return decls([
1232
+ ["width", width],
1233
+ ["height", height],
1234
+ ["margin-top", margin.top],
1235
+ ["margin-bottom", margin.bottom],
1236
+ ["margin-inside", margin.left],
1237
+ ["margin-outside", margin.right]
1238
+ ]);
1239
+ }
1240
+ function pageGeometryVarsCss(model, area) {
1241
+ const bookWide = decls([
1242
+ ["bleed", area?.bleed ?? 0],
1243
+ ["safe", area?.safe ?? 0],
1244
+ ["gutter", area?.gutter ?? 0],
1245
+ ["art-safe", area?.artSafe ?? 0]
1246
+ ]);
1247
+ return [
1248
+ `:root { ${pageDecls(model)} ${bookWide} }`,
1249
+ ...model.pageAssignments.map((a) => `${a.selector} { ${pageDecls(model, a.page)} }`)
1250
+ ].join(`
1251
+ `);
1252
+ }
1253
+
1203
1254
  // src/engine/viewer/fragment.ts
1204
1255
  var PX_PER_PT = 96 / 72;
1205
1256
  function injectViewerCss(doc = document) {
@@ -1210,6 +1261,15 @@
1210
1261
  style.textContent = viewer_default;
1211
1262
  doc.head.appendChild(style);
1212
1263
  }
1264
+ function injectPageVars(model, doc = document) {
1265
+ let style = doc.getElementById("gp-page-vars");
1266
+ if (!style) {
1267
+ style = doc.createElement("style");
1268
+ style.id = "gp-page-vars";
1269
+ doc.head.appendChild(style);
1270
+ }
1271
+ style.textContent = pageGeometryVarsCss(model, printAreaFromMeta(doc));
1272
+ }
1213
1273
  var pt = (v) => v * PX_PER_PT;
1214
1274
  function collectCssText(doc = document) {
1215
1275
  let out = "";
@@ -1444,10 +1504,13 @@
1444
1504
  function clearLeadingForcedBreaks(strip) {
1445
1505
  for (let el = strip.firstElementChild;el; el = el.firstElementChild) {
1446
1506
  const cs = getComputedStyle(el);
1447
- if (FORCED_BREAK.test(cs.breakBefore))
1448
- el.style.breakBefore = "auto";
1507
+ if (!FORCED_BREAK.test(cs.breakBefore))
1508
+ continue;
1509
+ clearedLeadingBreaks.set(el, cs.breakBefore);
1510
+ el.style.breakBefore = "auto";
1449
1511
  }
1450
1512
  }
1513
+ var clearedLeadingBreaks = new WeakMap;
1451
1514
  function stabilizeFullHeightPageRoots(model, strips) {
1452
1515
  let stabilized = 0;
1453
1516
  for (const strip of strips) {
@@ -1650,164 +1713,28 @@
1650
1713
  clearLeadingForcedBreaks(s.el);
1651
1714
  return strips;
1652
1715
  }
1653
- var AVOID_BREAK = /^avoid(-page|-column)?$/;
1654
- function keepChainHead(el) {
1655
- let head = el;
1656
- for (let prev = head.previousElementSibling;prev instanceof HTMLElement; prev = head.previousElementSibling) {
1657
- const linked = AVOID_BREAK.test(getComputedStyle(prev).breakAfter) || AVOID_BREAK.test(getComputedStyle(head).breakBefore);
1658
- if (!linked)
1659
- break;
1660
- head = prev;
1661
- }
1662
- return head;
1663
- }
1664
- var pushTargets = new WeakMap;
1665
- function repeatingHead(table) {
1666
- const head = table.tHead;
1667
- return head && getComputedStyle(head).display === "table-header-group" ? head : null;
1668
- }
1669
- function repeatingFoot(table) {
1670
- const foot = table.tFoot;
1671
- return foot && getComputedStyle(foot).display === "table-footer-group" ? foot : null;
1672
- }
1673
- function compensateRepeatedHeaders(strips, maxPasses = 24) {
1674
- const warnings = [];
1675
- let passes = 0;
1676
- let touched = 0;
1677
- for (const strip of strips) {
1678
- const tables = Array.from(strip.el.querySelectorAll("table")).filter((t) => repeatingHead(t) || repeatingFoot(t));
1679
- if (!tables.length)
1680
- continue;
1681
- for (const table of tables) {
1682
- for (const shim of Array.from(table.querySelectorAll("tr.gp-thead-shim, tr.gp-tfoot-shim")))
1683
- shim.remove();
1684
- table.style.breakBefore = "";
1685
- const target = pushTargets.get(table);
1686
- if (target)
1687
- target.style.breakBefore = "";
1688
- pushTargets.delete(table);
1689
- }
1690
- const pushed = new Set;
1691
- const footClaims = new Map;
1692
- let previous = "";
1693
- for (let pass = 0;pass < maxPasses; pass++) {
1694
- passes = Math.max(passes, pass + 1);
1695
- const { stride, height: colBottom } = stripMetrics(strip.el);
1696
- const stripLeft = strip.el.getBoundingClientRect().left - strip.el.scrollLeft;
1697
- const zoom = cssZoomOf(strip.el);
1698
- const colOf = (r) => Math.floor(((r.left - stripLeft) / zoom + 1) / stride);
1699
- const stripTop = strip.el.getBoundingClientRect().top;
1700
- const plans = [];
1701
- for (const table of tables) {
1702
- const head = repeatingHead(table);
1703
- const headRect = head?.getClientRects()[0];
1704
- const footHeight = (repeatingFoot(table)?.getBoundingClientRect().height ?? 0) / zoom;
1705
- const rows = Array.from(table.querySelectorAll("tbody > tr")).filter((r) => !r.classList.contains("gp-thead-shim") && !r.classList.contains("gp-tfoot-shim"));
1706
- if (!rows.length)
1707
- continue;
1708
- const rects = rows.map((r) => r.getClientRects()[0] ?? r.getBoundingClientRect());
1709
- const cols = rects.map(colOf);
1710
- const claims = footClaims.get(table) ?? new Map;
1711
- footClaims.set(table, claims);
1712
- let newClaim;
1713
- if (footHeight > 0) {
1714
- const lastCol = cols[cols.length - 1];
1715
- for (let i = 0;i < rows.length; i++) {
1716
- const row = rows[i];
1717
- if (cols[i] === lastCol || claims.has(row))
1718
- continue;
1719
- const bottom = (rects[i].bottom - stripTop) / zoom;
1720
- if (bottom > colBottom - footHeight + 0.5) {
1721
- newClaim = row;
1722
- claims.set(row, colBottom - (rects[i].top - stripTop) / zoom);
1723
- break;
1724
- }
1725
- }
1726
- }
1727
- plans.push({
1728
- table,
1729
- push: headRect ? colOf(headRect) < cols[0] : false,
1730
- headHeight: (headRect?.height ?? 0) / zoom,
1731
- footHeight,
1732
- breakRows: headRect ? rows.filter((_, i) => i > 0 && cols[i] > cols[i - 1]) : [],
1733
- footRows: [...claims.entries()],
1734
- grew: newClaim !== undefined,
1735
- cells: Math.max(1, ...rows.map((r) => r.cells.length))
1736
- });
1737
- }
1738
- const signature = plans.map((p) => `${p.push || pushed.has(p.table) ? "P" : ""}${p.breakRows.map((r) => r.rowIndex).join(".")}~${p.footRows.map(([r]) => r.rowIndex).join(".")}`).join("|");
1739
- const anyGrowth = plans.some((p) => p.grew);
1740
- if (!anyGrowth && signature === previous)
1741
- break;
1742
- previous = signature;
1743
- for (const plan of plans) {
1744
- for (const shim of Array.from(plan.table.querySelectorAll("tr.gp-thead-shim, tr.gp-tfoot-shim")))
1745
- shim.remove();
1746
- if (plan.push && !pushed.has(plan.table)) {
1747
- pushed.add(plan.table);
1748
- const target = keepChainHead(plan.table);
1749
- target.style.breakBefore = "column";
1750
- pushTargets.set(plan.table, target);
1751
- touched++;
1752
- continue;
1753
- }
1754
- for (const row of plan.breakRows) {
1755
- row.before(headerShim(plan.table.tHead, plan.headHeight, plan.cells));
1756
- touched++;
1757
- }
1758
- for (const [row, height] of plan.footRows) {
1759
- row.before(sectionShim(plan.table.tFoot, height, plan.cells, "gp-tfoot-shim"));
1760
- touched++;
1761
- }
1762
- }
1763
- }
1764
- }
1765
- return { tables: touched, passes, warnings };
1766
- }
1767
- function headerShim(head, height, cells) {
1768
- return sectionShim(head, height, cells, "gp-thead-shim");
1769
- }
1770
- function sectionShim(section, height, cells, className) {
1771
- const shim = document.createElement("tr");
1772
- shim.className = className;
1773
- shim.setAttribute("aria-hidden", "true");
1774
- shim.style.height = `${height}px`;
1775
- if (className === "gp-tfoot-shim")
1776
- shim.style.verticalAlign = "bottom";
1777
- const source = section.rows[0];
1778
- if (source) {
1779
- for (const cell of Array.from(source.cells)) {
1780
- const td = document.createElement("td");
1781
- td.colSpan = cell.colSpan;
1782
- td.innerHTML = cell.innerHTML;
1783
- const cs = getComputedStyle(cell);
1784
- td.style.cssText = `font:${cs.font};color:${cs.color};letter-spacing:${cs.letterSpacing};text-transform:${cs.textTransform};vertical-align:${cs.verticalAlign};text-align:${cs.textAlign};padding:${cs.padding};border:${cs.border};background:${cs.backgroundColor};`;
1785
- shim.appendChild(td);
1786
- }
1787
- } else {
1788
- const td = document.createElement("td");
1789
- td.colSpan = cells;
1790
- td.style.cssText = `height:${height}px;padding:0;border:0;`;
1791
- shim.appendChild(td);
1792
- }
1793
- return shim;
1794
- }
1795
1716
  function compensateRectoBreaks(model, strips) {
1796
- const decls = model.breaks.filter(isRectoVersoBreak);
1717
+ const decls2 = model.breaks.filter(isRectoVersoBreak);
1797
1718
  for (const spacer of Array.from(document.querySelectorAll(".gp-recto-spacer")))
1798
1719
  spacer.remove();
1799
- if (!decls.length)
1720
+ if (!decls2.length)
1800
1721
  return 0;
1801
1722
  const sites = [];
1802
- for (const d of decls) {
1723
+ const seen = new Set;
1724
+ for (const d of decls2) {
1803
1725
  let els = [];
1804
1726
  try {
1805
1727
  els = Array.from(document.querySelectorAll(d.selector));
1806
1728
  } catch {
1807
1729
  continue;
1808
1730
  }
1809
- for (const el of els)
1810
- sites.push({ el, wantsRecto: wantsRecto(d.value) });
1731
+ for (const el of els) {
1732
+ const value = clearedLeadingBreaks.get(el) ?? getComputedStyle(el).breakBefore;
1733
+ if (seen.has(el) || !RECTO_VERSO_VALUES.test(value))
1734
+ continue;
1735
+ seen.add(el);
1736
+ sites.push({ el, wantsRecto: wantsRecto(value) });
1737
+ }
1811
1738
  }
1812
1739
  sites.sort((a, b) => a.el.compareDocumentPosition(b.el) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1);
1813
1740
  const plan = planRectoBlanks(sites.map((site) => ({ page: pageOf(site.el, strips) + 1, wantsRecto: site.wantsRecto })));
@@ -1993,6 +1920,7 @@
1993
1920
  document.head.appendChild(style);
1994
1921
  }
1995
1922
  const model = extract(css);
1923
+ injectPageVars(model);
1996
1924
  injectBreakMapping(model);
1997
1925
  const authoring = [];
1998
1926
  const strips = buildStrips(model, opts, authoring);
@@ -2004,7 +1932,6 @@
2004
1932
  const blanks = compensateRectoBreaks(model, strips);
2005
1933
  if (blanks)
2006
1934
  measure(strips);
2007
- const headers = opts.compensateHeaders === false ? { tables: 0, passes: 0, warnings: [] } : compensateRepeatedHeaders(strips);
2008
1935
  const contentPages = measure(strips).totalPages;
2009
1936
  const totalPages = padToSignature(strips, contentPages);
2010
1937
  fitVersoPinRoots(model, strips);
@@ -2012,7 +1939,7 @@
2012
1939
  model,
2013
1940
  strips,
2014
1941
  totalPages,
2015
- warnings: [...new Set([...authoring, ...headers.warnings])],
1942
+ warnings: [...new Set(authoring)],
2016
1943
  blankPages: blanks,
2017
1944
  blankPageIndices: blankPageIndices(strips),
2018
1945
  paddedPageIndices: pagesAfter(contentPages, totalPages),
@@ -2033,10 +1960,7 @@
2033
1960
  synthesizeColumnBreaks(model);
2034
1961
  measure(strips);
2035
1962
  api.blankPages = compensateRectoBreaks(model, strips);
2036
- if (opts.compensateHeaders !== false)
2037
- api.warnings = [
2038
- ...new Set([...authoring, ...compensateRepeatedHeaders(strips).warnings])
2039
- ];
1963
+ api.warnings = [...new Set(authoring)];
2040
1964
  const content = measure(strips).totalPages;
2041
1965
  padToSignature(strips, content);
2042
1966
  const r = measure(strips);
@@ -2861,8 +2785,8 @@
2861
2785
  } catch {}
2862
2786
  return document.getElementById(id);
2863
2787
  }
2864
- function applyPageBackground(sheet, decls) {
2865
- for (const [prop, value] of Object.entries(decls)) {
2788
+ function applyPageBackground(sheet, decls2) {
2789
+ for (const [prop, value] of Object.entries(decls2)) {
2866
2790
  const p = prop.toLowerCase();
2867
2791
  if (p !== "background" && !p.startsWith("background-"))
2868
2792
  continue;
@@ -2941,8 +2865,8 @@
2941
2865
  }
2942
2866
  if (blankPages.has(bookIndex)) {
2943
2867
  const pseudos2 = ["blank"];
2944
- const { geometry: geometry2, marginBoxes: marginBoxes2, decls: decls2 } = resolvePage(model, { pseudos: pseudos2 });
2945
- return { index: bookIndex, strip, pseudos: pseudos2, geometry: geometry2, marginBoxes: marginBoxes2, decls: decls2 };
2868
+ const { geometry: geometry2, marginBoxes: marginBoxes2, decls: decls3 } = resolvePage(model, { pseudos: pseudos2 });
2869
+ return { index: bookIndex, strip, pseudos: pseudos2, geometry: geometry2, marginBoxes: marginBoxes2, decls: decls3 };
2946
2870
  }
2947
2871
  const pseudos = [];
2948
2872
  if (bookIndex === 0)
@@ -2950,11 +2874,11 @@
2950
2874
  if (indexInStrip2 === 0)
2951
2875
  pseudos.push("nth-first-of-run");
2952
2876
  pseudos.push(bookIndex % 2 === 0 ? "right" : "left");
2953
- const { geometry, marginBoxes, decls } = resolvePage(model, {
2877
+ const { geometry, marginBoxes, decls: decls2 } = resolvePage(model, {
2954
2878
  name: strip.page,
2955
2879
  pseudos
2956
2880
  });
2957
- return { index: bookIndex, strip, pseudos, geometry, marginBoxes, decls };
2881
+ return { index: bookIndex, strip, pseudos, geometry, marginBoxes, decls: decls2 };
2958
2882
  }
2959
2883
  function buildMaps() {
2960
2884
  api.stringMap = new Map;
@@ -3150,10 +3074,10 @@
3150
3074
  function drawMarginBoxes(sheet, ctx, totalPages) {
3151
3075
  const g = ctx.geometry;
3152
3076
  for (const name of MARGIN_BOX_NAMES) {
3153
- const decls = ctx.marginBoxes[`@${name}`];
3154
- if (!decls?.content)
3077
+ const decls2 = ctx.marginBoxes[`@${name}`];
3078
+ if (!decls2?.content)
3155
3079
  continue;
3156
- const text = evaluate(decls.content, {
3080
+ const text = evaluate(decls2.content, {
3157
3081
  page: api.pageNumbers[ctx.index] ?? ctx.index + 1,
3158
3082
  pages: totalPages,
3159
3083
  strings: (n, w) => stringAt(n, w, ctx.index),
@@ -3169,7 +3093,7 @@
3169
3093
  const content = document.createElement("span");
3170
3094
  content.className = "gp-marginbox-content";
3171
3095
  content.textContent = text;
3172
- for (const [prop, value] of Object.entries(decls)) {
3096
+ for (const [prop, value] of Object.entries(decls2)) {
3173
3097
  if (prop.toLowerCase() === "content" || isIgnoredMarginBoxProperty(prop))
3174
3098
  continue;
3175
3099
  content.style.setProperty(prop, value);