@openpresentation/opf 0.20.4 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/browser.js +16 -16
  2. package/dist/{chunk-Z75YB54S.js → chunk-2X4ZG2CN.js} +5 -5
  3. package/dist/{chunk-WD4W7KKK.js → chunk-6UBIR2U3.js} +54 -11
  4. package/dist/{chunk-DYGYMBBW.js → chunk-7YFMWEPQ.js} +2 -2
  5. package/dist/{chunk-7PQZDC2H.js → chunk-ARLOTG23.js} +1 -1
  6. package/dist/{chunk-VFMHM2IL.js → chunk-BWWGYOOG.js} +22 -0
  7. package/dist/{chunk-IDMQWS6O.js → chunk-D2XIDBUB.js} +6 -6
  8. package/dist/{chunk-5SQ6CIWR.js → chunk-D7WZVSNV.js} +5 -5
  9. package/dist/{chunk-OIGCC6VA.js → chunk-EFICNDGV.js} +2 -2
  10. package/dist/{chunk-YOLDSF7U.js → chunk-THEUCQZZ.js} +1 -1
  11. package/dist/{chunk-S4FR7ATF.js → chunk-U55BQQKU.js} +1 -1
  12. package/dist/{chunk-V66KJA3H.js → chunk-VLFDWV7L.js} +1 -1
  13. package/dist/{chunk-52GKVP3I.js → chunk-W62CX2WG.js} +22 -12
  14. package/dist/{chunk-URUNMZFO.js → chunk-WZPFIPOO.js} +2 -2
  15. package/dist/{chunk-XAYMPBNE.js → chunk-X6SB52RP.js} +333 -149
  16. package/dist/{chunk-2M7U4WL3.js → chunk-XQARTOZJ.js} +260 -104
  17. package/dist/{chunk-TZ5IZETE.js → chunk-YD44KIRA.js} +1 -1
  18. package/dist/{chunk-TCBEF5OY.js → chunk-YZ7RZ4MU.js} +1 -1
  19. package/dist/{composition-QtS1rnhv.d.ts → composition-DzAV0cfU.d.ts} +133 -3
  20. package/dist/composition.d.ts +1 -1
  21. package/dist/composition.js +1 -1
  22. package/dist/conversion-524P44NX.js +19 -0
  23. package/dist/{conversion-Cqwu0Ds9.d.ts → conversion-CtTg2ivR.d.ts} +6 -5
  24. package/dist/convert.d.ts +3 -3
  25. package/dist/convert.js +7 -7
  26. package/dist/data.d.ts +1 -1
  27. package/dist/data.js +2 -2
  28. package/dist/{deck-report-BdG5H3Qj.d.ts → deck-report-971nEzTY.d.ts} +2 -2
  29. package/dist/deck.d.ts +6 -6
  30. package/dist/deck.js +10 -10
  31. package/dist/diff.d.ts +1 -1
  32. package/dist/diff.js +5 -5
  33. package/dist/docs.js +16 -10
  34. package/dist/examples.d.ts +1 -1
  35. package/dist/{finding-DqgwzUmr.d.ts → finding-l9dlQ2NF.d.ts} +4 -0
  36. package/dist/format.js +2 -2
  37. package/dist/index.d.ts +21 -15
  38. package/dist/index.js +20 -20
  39. package/dist/markdown.d.ts +4 -4
  40. package/dist/markdown.js +7 -7
  41. package/dist/node-engine.d.ts +30 -9
  42. package/dist/node-engine.js +20 -20
  43. package/dist/{pagination-CAX6mHG6.d.ts → pagination-BTqRj7dM.d.ts} +2 -2
  44. package/dist/pagination.d.ts +2 -2
  45. package/dist/pagination.js +4 -4
  46. package/dist/patch.d.ts +1 -1
  47. package/dist/patch.js +4 -4
  48. package/dist/{presentation-BG4QCcdB.d.ts → presentation-ZNcXSpvm.d.ts} +50 -4
  49. package/dist/repo-readme.js +1 -1
  50. package/dist/schemas.js +1 -1
  51. package/dist/spec/schemas/finding.schema.json +6 -1
  52. package/dist/spec/schemas/opf.schema.json +8 -0
  53. package/dist/types.d.ts +2 -2
  54. package/dist/{validation-types-DRaNnieo.d.ts → validation-types-uLDSrJgM.d.ts} +3 -3
  55. package/dist/{validator-BJtXHJKh.d.ts → validator-DxAjRPmE.d.ts} +4 -10
  56. package/dist/validator.d.ts +5 -5
  57. package/dist/validator.js +3 -3
  58. package/dist/yaml.d.ts +4 -4
  59. package/dist/yaml.js +7 -7
  60. package/package.json +1 -1
  61. package/dist/conversion-DRCJIMWS.js +0 -19
@@ -1875,6 +1875,159 @@ function tableCellDisplayValue(cell, columnFormat2) {
1875
1875
  return formatDataNumber(cell, columnFormat2);
1876
1876
  }
1877
1877
 
1878
+ // src/chart-axis.ts
1879
+ var CHART_TEXT_PX = 20;
1880
+ function chartTextSize(geometry) {
1881
+ const { width, height, scale } = geometry;
1882
+ const minimum = geometry.minFontSize ?? 16;
1883
+ if (![width, height, scale].every(Number.isFinite) || width <= 0 || height <= 0 || scale <= 0) return Math.max(CHART_TEXT_PX, minimum);
1884
+ return Math.max(Math.floor(Math.min(CHART_TEXT_PX, height / scale / 18, width / scale / 30)), minimum);
1885
+ }
1886
+ function clean(value) {
1887
+ const rounded = Number(value.toPrecision(12));
1888
+ return Object.is(rounded, -0) ? 0 : rounded;
1889
+ }
1890
+ function scaleFrom(min, max, step) {
1891
+ const ticks = [];
1892
+ const count = Math.round((max - min) / step);
1893
+ for (let index = 0; index <= count; index++) ticks.push(clean(min + index * step));
1894
+ return { min, max, step, ticks };
1895
+ }
1896
+ function pickStep(min, max, limit, steps) {
1897
+ return steps.find((step) => Math.round((max - min) / step) <= limit) ?? max - min;
1898
+ }
1899
+ function niceScale(dataMin, dataMax, maxIntervals = 10, { percent = false } = {}) {
1900
+ const limit = Number.isFinite(maxIntervals) ? Math.max(1, Math.floor(maxIntervals)) : 10;
1901
+ if (percent) {
1902
+ const min = dataMin < -1e-9 ? -1 : 0;
1903
+ const max = dataMax > 1e-9 || min === 0 ? 1 : 0;
1904
+ return scaleFrom(min, max, pickStep(min, max, limit, [0.1, 0.2, 0.25, 0.5, 1]));
1905
+ }
1906
+ if (!Number.isFinite(dataMin) || !Number.isFinite(dataMax)) {
1907
+ dataMin = 0;
1908
+ dataMax = 1;
1909
+ }
1910
+ let lo = Math.min(dataMin, 0);
1911
+ let hi = Math.max(dataMax, 0);
1912
+ if (dataMin > 0 && dataMax - dataMin < dataMax / 6) lo = dataMin;
1913
+ if (dataMax < 0 && dataMax - dataMin < -dataMin / 6) hi = dataMax;
1914
+ if (hi === lo) {
1915
+ if (hi === 0) hi = 1;
1916
+ else if (hi > 0) lo = 0;
1917
+ else hi = 0;
1918
+ }
1919
+ const span = hi - lo;
1920
+ const top = hi > 0 ? hi + span / 20 : hi;
1921
+ const bottom = lo < 0 ? lo - span / 20 : lo > 0 ? Math.max(0, lo - span / 20) : lo;
1922
+ const raw = (top - bottom) / limit;
1923
+ if (!(raw > 0) || !Number.isFinite(raw)) return normalizedScale(dataMin, dataMax, limit);
1924
+ let exponent = Math.floor(Math.log10(raw)) - 1;
1925
+ for (; exponent <= 308; exponent++) {
1926
+ for (const mantissa of [1, 2, 5]) {
1927
+ const step = mantissa * 10 ** exponent;
1928
+ if (!(step > 0) || !Number.isFinite(step)) continue;
1929
+ const min = Math.floor(bottom / step + 1e-9) * step;
1930
+ const max = Math.ceil(top / step - 1e-9) * step;
1931
+ if (Number.isFinite(min) && Number.isFinite(max) && Math.round((max - min) / step) <= limit) return scaleFrom(clean(min), clean(max), step);
1932
+ }
1933
+ }
1934
+ return normalizedScale(dataMin, dataMax, limit);
1935
+ }
1936
+ function normalizedScale(dataMin, dataMax, limit) {
1937
+ const magnitude = Math.max(Math.abs(dataMin), Math.abs(dataMax));
1938
+ const unit = 10 ** Math.floor(Math.log10(magnitude)) || Number.MIN_VALUE;
1939
+ const normalized = niceScale(dataMin / unit, dataMax / unit, limit);
1940
+ const restore = (value) => {
1941
+ const scaled = value * unit;
1942
+ return Number.isFinite(scaled) ? scaled : Math.sign(value) * Number.MAX_VALUE;
1943
+ };
1944
+ const min = Math.min(restore(normalized.min), dataMin);
1945
+ const max = Math.max(restore(normalized.max), dataMax);
1946
+ const ticks = [.../* @__PURE__ */ new Set([min, ...normalized.ticks.map(restore), max])].sort((a, b) => a - b);
1947
+ return { min, max, step: restore(normalized.step) || Number.MIN_VALUE, ticks };
1948
+ }
1949
+ function maxIntervalsFor(length, labelExtent) {
1950
+ return Math.max(1, Math.min(10, Math.floor(length / Math.max(1, labelExtent))));
1951
+ }
1952
+ var bar = (horizontal, grouping) => ({ kind: "bar", horizontal, grouping });
1953
+ var line = (grouping) => ({ kind: "line", horizontal: false, grouping });
1954
+ var area = (grouping) => ({ kind: "area", horizontal: false, grouping });
1955
+ var CATEGORY_CHARTS = {
1956
+ column: bar(false, "clustered"),
1957
+ "stacked-column": bar(false, "stacked"),
1958
+ "100pct-stacked-column": bar(false, "percentStacked"),
1959
+ bar: bar(true, "clustered"),
1960
+ "stacked-bar": bar(true, "stacked"),
1961
+ "100pct-stacked-bar": bar(true, "percentStacked"),
1962
+ line: line("standard"),
1963
+ "line-with-markers": line("standard"),
1964
+ "stacked-line": line("stacked"),
1965
+ "stacked-line-with-markers": line("stacked"),
1966
+ area: area("standard"),
1967
+ "stacked-area": area("stacked"),
1968
+ "100pct-stacked-area": area("percentStacked")
1969
+ };
1970
+ function stackCategoryValues(series, count, kind2, grouping, path = "chart") {
1971
+ const percent = grouping === "percentStacked";
1972
+ const stacked = grouping === "stacked" || percent;
1973
+ const fail = (aggregate) => new RangeError(`Cannot render ${path}: ${aggregate} exceeds the finite numeric range. Rescale the chart values before rendering.`);
1974
+ const totals = Array.from({ length: count }, (_, i) => series.reduce((sum, entry) => sum + Math.abs(entry.values[i] ?? 0), 0));
1975
+ if (percent && totals.some((total) => !Number.isFinite(total))) throw fail("percentage total");
1976
+ const positive2 = new Array(count).fill(0);
1977
+ const negative = new Array(count).fill(0);
1978
+ const running = new Array(count).fill(0);
1979
+ return series.map(
1980
+ (entry) => entry.values.map((raw, i) => {
1981
+ if (raw === null && kind2 !== "area") return null;
1982
+ let value = raw ?? 0;
1983
+ if (percent) value = totals[i] ? value / totals[i] : 0;
1984
+ if (!stacked) return { value, from: 0, to: value };
1985
+ if (kind2 === "bar") {
1986
+ const base = value >= 0 ? positive2 : negative;
1987
+ const from2 = base[i];
1988
+ base[i] += value;
1989
+ if (!Number.isFinite(base[i])) throw fail("stacked total");
1990
+ return { value, from: from2, to: base[i] };
1991
+ }
1992
+ const from = running[i];
1993
+ running[i] += value;
1994
+ if (!Number.isFinite(running[i])) throw fail("stacked total");
1995
+ return { value, from, to: running[i] };
1996
+ })
1997
+ );
1998
+ }
1999
+ function chartValueAxis(chart, resolved, geometry) {
2000
+ const type = typeof chart === "object" && chart !== null ? chart.type : void 0;
2001
+ const id = typeof type === "string" ? type.trim().toLowerCase() : "";
2002
+ const spec = Object.hasOwn(CATEGORY_CHARTS, id) ? CATEGORY_CHARTS[id] : void 0;
2003
+ if (!spec || !resolved.ok || resolved.combo) return void 0;
2004
+ const { scale, width, height } = geometry;
2005
+ if (![width, height, scale].every(Number.isFinite) || width <= 0 || height <= 0 || scale <= 0) return void 0;
2006
+ const series = resolved.columns.slice(1).map((_, offset) => ({ values: resolved.rows.map((row) => chartNumber(row[offset + 1])) }));
2007
+ if (!series.length || !resolved.rows.length) return void 0;
2008
+ const percent = spec.grouping === "percentStacked";
2009
+ let stacks;
2010
+ try {
2011
+ stacks = stackCategoryValues(series, resolved.rows.length, spec.kind, spec.grouping);
2012
+ } catch {
2013
+ return void 0;
2014
+ }
2015
+ const stackedGrouping = spec.grouping === "stacked" || percent;
2016
+ const extents = stacks.flat().flatMap((point) => point === null ? [] : spec.kind === "line" || !stackedGrouping ? [point.to] : [point.from, point.to]);
2017
+ const anchor = spec.kind === "bar" || spec.kind === "area" ? [0] : [];
2018
+ const dataMin = extents.length ? Math.min(...extents, ...anchor) : 0;
2019
+ const dataMax = extents.length ? Math.max(...extents, ...anchor) : 1;
2020
+ const pad = 10 * scale;
2021
+ const fontPx = chartTextSize(geometry) * scale;
2022
+ const lineHeight = fontPx * 1.5;
2023
+ const options = resolveChartOptions(chart, chartOptionTarget(id));
2024
+ const legendBand = options.legend === "top" || options.legend === "bottom" ? lineHeight + pad : 0;
2025
+ const titleBand = options.axisTitles.category ? lineHeight : 0;
2026
+ const length = spec.horizontal ? width * 0.7 - 2 * pad - fontPx : height - 2 * pad - lineHeight * 1.5 - legendBand - titleBand;
2027
+ const fitted = niceScale(dataMin, dataMax, maxIntervalsFor(Math.max(1, length), spec.horizontal ? 4 * fontPx : lineHeight * 1.2), { percent });
2028
+ return { min: fitted.min, max: fitted.max, majorUnit: fitted.step, ...percent ? { percent: true } : {} };
2029
+ }
2030
+
1878
2031
  // src/image-aspect.ts
1879
2032
  var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1880
2033
  function sourceOf(value) {
@@ -2170,20 +2323,20 @@ function parse(layout) {
2170
2323
  if (reserved.has(name)) region(`/regions/${pointerSegment(name)}`, `'${name}' is reserved and cannot name a region (reserved: ${RESERVED_REGION_NAMES.join(", ")})`);
2171
2324
  else if (!bounds.has(name)) region(`/regions/${pointerSegment(name)}`, `region '${name}' has no area in areas`);
2172
2325
  }
2173
- for (const area of list) {
2174
- if (area.heading) continue;
2175
- if (reserved.has(area.name)) {
2176
- if (!Object.hasOwn(entries, area.name)) region("/areas", `'${area.name}' is reserved and cannot name a body area (reserved: ${RESERVED_REGION_NAMES.join(", ")})`);
2326
+ for (const area2 of list) {
2327
+ if (area2.heading) continue;
2328
+ if (reserved.has(area2.name)) {
2329
+ if (!Object.hasOwn(entries, area2.name)) region("/areas", `'${area2.name}' is reserved and cannot name a body area (reserved: ${RESERVED_REGION_NAMES.join(", ")})`);
2177
2330
  continue;
2178
2331
  }
2179
- if (!Object.hasOwn(entries, area.name)) region("/regions", `body area '${area.name}' has no entry in regions`);
2332
+ if (!Object.hasOwn(entries, area2.name)) region("/regions", `body area '${area2.name}' has no entry in regions`);
2180
2333
  }
2181
2334
  if (bounds.has("subtitle") && !bounds.has("title")) region("/areas", "a 'subtitle' area needs a 'title' area");
2182
2335
  for (const [name, entry] of Object.entries(entries)) {
2183
2336
  const raw = record4(entry);
2184
2337
  if (raw.flow === "none" && raw.max !== void 0 && raw.max !== 1) region(`/regions/${pointerSegment(name)}/max`, `a region with flow "none" holds one block; max must be 1, not ${JSON.stringify(raw.max)}`);
2185
2338
  }
2186
- const regions = list.filter((area) => !area.heading && !reserved.has(area.name) && Object.hasOwn(entries, area.name)).map((area) => layoutRegion(area.name, entries[area.name]));
2339
+ const regions = list.filter((area2) => !area2.heading && !reserved.has(area2.name) && Object.hasOwn(entries, area2.name)).map((area2) => layoutRegion(area2.name, entries[area2.name]));
2187
2340
  for (const entry of regions) if (!entry.accepts.length) region(`/regions/${pointerSegment(entry.name)}/accepts`, `region '${entry.name}' accepts no content kind`);
2188
2341
  if (value.overflowRegion !== void 0 && !regions.some((entry) => entry.name === value.overflowRegion)) region("/overflowRegion", `overflowRegion ${JSON.stringify(value.overflowRegion)} is not a region of this layout`);
2189
2342
  if (issues.length) return { issues };
@@ -3406,6 +3559,8 @@ function labWithLightness(l, a, b) {
3406
3559
  function labDifference(a, b) {
3407
3560
  return Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2]);
3408
3561
  }
3562
+ var CHART_SERIES_TIER_SIZE = 6;
3563
+ var tierOf = (index) => Math.floor(index / CHART_SERIES_TIER_SIZE);
3409
3564
  var CHART_SERIES_SHORTFALL_WEIGHT = 8;
3410
3565
  function chartPaletteForFill(fill, palette) {
3411
3566
  const opaqueFill = colorContrast(fill, fill) !== void 0;
@@ -3426,7 +3581,7 @@ function chartPaletteForFill(fill, palette) {
3426
3581
  const baseLab = labOf(opaqueChannels(base));
3427
3582
  const needs = palette.flatMap((_2, other) => {
3428
3583
  const before = preferredLab[other], lab = placedLab[other];
3429
- return other !== index && before && lab && placed[other] !== void 0 ? [{ lab, adjacent: Math.abs(other - index) === 1, wide: Math.min(labDifference(before, wanted), CHART_SERIES_MIN_DIFFERENCE), step: Math.min(Math.abs(before[0] - wanted[0]), CHART_SERIES_MIN_LIGHTNESS_STEP) }] : [];
3584
+ return other !== index && tierOf(other) <= tierOf(index) && before && lab && placed[other] !== void 0 ? [{ lab, adjacent: Math.abs(other - index) === 1, wide: Math.min(labDifference(before, wanted), CHART_SERIES_MIN_DIFFERENCE), step: Math.min(Math.abs(before[0] - wanted[0]), CHART_SERIES_MIN_LIGHTNESS_STEP) }] : [];
3430
3585
  });
3431
3586
  const shortfall = (candidate) => needs.reduce((worst, need) => {
3432
3587
  const lightness = Math.abs(need.lab[0] - candidate[0]) - need.step, difference = labDifference(need.lab, candidate) - need.wide;
@@ -3452,6 +3607,28 @@ function chartPaletteForFill(fill, palette) {
3452
3607
  });
3453
3608
  return placed;
3454
3609
  }
3610
+ var CHART_SERIES_TINT_MIX = 0.4;
3611
+ function chartSeriesPalette(colorScheme = {}, colors, context = {}) {
3612
+ const accents = [1, 2, 3, 4, 5, 6].map((number) => {
3613
+ const slot = `accent${number}`;
3614
+ return normalizeHexColor(colorScheme?.[slot]) ?? normalizeHexColor(ENGINE_DEFAULT_COLOR_SCHEME[slot]) ?? "#000000";
3615
+ });
3616
+ const palette = [...accents, ...accents.map((accent) => mixChannels(opaqueChannels(accent), [255, 255, 255], CHART_SERIES_TINT_MIX))];
3617
+ resolveChartColors(colors, colorScheme, context).forEach((color, index) => {
3618
+ if (color === void 0) return;
3619
+ while (palette.length < index) palette.push(palette[palette.length % 12]);
3620
+ palette[index] = color;
3621
+ });
3622
+ return palette;
3623
+ }
3624
+ function resolveChartColors(colors, colorScheme = {}, context = {}) {
3625
+ if (!Array.isArray(colors)) return [];
3626
+ return colors.map((entry) => {
3627
+ if (typeof entry !== "string") return void 0;
3628
+ const resolved = resolveColorRef(entry.trim(), { colorScheme, roles: context.roles, variables: context.variables, fallback: "" });
3629
+ return normalizeHexColor(resolved);
3630
+ });
3631
+ }
3455
3632
  var CHART_HIGHLIGHT_MUTED_MIX = 0.3;
3456
3633
  var CHART_HIGHLIGHT_MUTED_MIN_CONTRAST = 1.6;
3457
3634
  var mixChannels = (from, to, amount) => hexOfChannels(from.map((channel, index) => channel + (to[index] - channel) * amount));
@@ -4258,10 +4435,10 @@ function metricTrendMark(layout, options) {
4258
4435
  if (!part || !part.visible || !part.fit || part.fit.sourceLines.length === 0) return void 0;
4259
4436
  const trend = part.text.trim();
4260
4437
  if (!Object.hasOwn(METRIC_TREND_SHAPES, trend)) return void 0;
4261
- const line = part.fit.sourceLines[0], origin = part.linePositions[0];
4262
- if (!origin || line.width <= 0) return void 0;
4438
+ const line2 = part.fit.sourceLines[0], origin = part.linePositions[0];
4439
+ if (!origin || line2.width <= 0) return void 0;
4263
4440
  const size = part.fit.fontSize * 0.72, gap = part.fit.fontSize * 0.3, left = part.box.x, right = part.box.x + part.box.width;
4264
- const after = origin.x + line.width + gap, before = origin.x - gap - size;
4441
+ const after = origin.x + line2.width + gap, before = origin.x - gap - size;
4265
4442
  const fitsAfter = after + size <= right + 0.01, fitsBefore = before >= left - 0.01;
4266
4443
  const x = layout.alignment === "left" ? fitsAfter ? after : fitsBefore ? before : void 0 : fitsBefore ? before : fitsAfter ? after : void 0;
4267
4444
  if (x === void 0) return void 0;
@@ -4321,7 +4498,7 @@ function codeHighlightLines(highlight, source) {
4321
4498
  return;
4322
4499
  }
4323
4500
  if (end > lineCount) issues.push({ code: "code-highlight-out-of-range", index, message: `The highlight ${start === end ? `line ${start}` : `range [${start}, ${end}]`} is past the last line (the code has ${lineCount} ${lineCount === 1 ? "line" : "lines"}); lines beyond it are ignored.` });
4324
- for (let line = start; line <= Math.min(end, lineCount); line++) marked.add(line);
4501
+ for (let line2 = start; line2 <= Math.min(end, lineCount); line2++) marked.add(line2);
4325
4502
  });
4326
4503
  return { lineCount, lines: [...marked].sort((a, b) => a - b), issues };
4327
4504
  }
@@ -4336,10 +4513,10 @@ function codeHighlightList(lines) {
4336
4513
  return out;
4337
4514
  }
4338
4515
  function codeLineNumbers(sourceLines) {
4339
- let line = 1;
4516
+ let line2 = 1;
4340
4517
  return sourceLines.map((entry) => {
4341
- const number = line;
4342
- if (entry.boundary === "hard") line++;
4518
+ const number = line2;
4519
+ if (entry.boundary === "hard") line2++;
4343
4520
  return number;
4344
4521
  });
4345
4522
  }
@@ -4359,7 +4536,7 @@ function codeHighlightSlice(highlight, source, start, end) {
4359
4536
  if (!lines.length) return void 0;
4360
4537
  const breaks = (text2) => (text2.match(/\r\n|\r|\n/g) ?? []).length;
4361
4538
  const before = breaks(source.slice(0, start)), count = codeLineCount(source.slice(start, end));
4362
- const kept = lines.filter((line) => line > before && line <= before + count).map((line) => line - before);
4539
+ const kept = lines.filter((line2) => line2 > before && line2 <= before + count).map((line2) => line2 - before);
4363
4540
  return kept.length ? codeHighlightList(kept) : void 0;
4364
4541
  }
4365
4542
  var CODE_HIGHLIGHT_DIM = 0.35;
@@ -4812,24 +4989,24 @@ function placeTextLines(lines, box, alignment = "left", rasterPadding = 0, direc
4812
4989
  if (!Array.isArray(lines) || !box || ![box.x, box.y, box.width, box.height, rasterPadding].every(Number.isFinite) || box.width <= 0 || box.height <= 0 || rasterPadding < 0 || !["left", "center", "right"].includes(alignment)) throw new RangeError("Text placement requires lines, finite positive dimensions, nonnegative padding and a valid alignment.");
4813
4990
  const placed = [];
4814
4991
  let shift = 0, bottom = box.y, height = 0, overflow = false;
4815
- for (const [lineIndex, line] of lines.entries()) {
4992
+ for (const [lineIndex, line2] of lines.entries()) {
4816
4993
  const lineAlignment = physicalAlignment(alignment, directions?.[lineIndex]), factor = lineAlignment === "right" ? 1 : lineAlignment === "center" ? 0.5 : 0;
4817
- if (!line || ![line.width, line.y, line.baseline, line.height].every(Number.isFinite) || line.width < 0 || line.height <= 0 || line.y < 0 || line.baseline < line.y) throw new RangeError("Text lines require finite coordinates, nonnegative advances and a baseline at or below their top.");
4818
- const ink = line.outline;
4994
+ if (!line2 || ![line2.width, line2.y, line2.baseline, line2.height].every(Number.isFinite) || line2.width < 0 || line2.height <= 0 || line2.y < 0 || line2.baseline < line2.y) throw new RangeError("Text lines require finite coordinates, nonnegative advances and a baseline at or below their top.");
4995
+ const ink = line2.outline;
4819
4996
  if (ink !== null && (!ink || ![ink.x, ink.y, ink.width, ink.height].every(Number.isFinite) || ink.width < 0 || ink.height < 0)) throw new RangeError("Text outlines must be null or finite coordinates with nonnegative dimensions.");
4820
- let x = box.x + (box.width - line.width) * factor;
4997
+ let x = box.x + (box.width - line2.width) * factor;
4821
4998
  if (ink) {
4822
4999
  const low = box.x + rasterPadding - ink.x, high = box.x + box.width - rasterPadding - ink.x - ink.width;
4823
5000
  if (low > high + 0.01) overflow = true;
4824
5001
  else x = Math.max(low, Math.min(x, high));
4825
- shift += Math.max(0, bottom + rasterPadding - (box.y + line.baseline + shift + ink.y));
5002
+ shift += Math.max(0, bottom + rasterPadding - (box.y + line2.baseline + shift + ink.y));
4826
5003
  }
4827
- const y = box.y + line.y + shift, baseline = box.y + line.baseline + shift;
5004
+ const y = box.y + line2.y + shift, baseline = box.y + line2.baseline + shift;
4828
5005
  const outline = ink ? { ...ink, x: x + ink.x, y: baseline + ink.y } : null;
4829
5006
  if (outline) bottom = outline.y + outline.height + rasterPadding;
4830
- height = Math.max(height, y + line.height - box.y, outline ? bottom - box.y : 0);
4831
- if (line.width > box.width + 0.01 || height > box.height + 0.01) overflow = true;
4832
- placed.push({ x, y, baseline, height: line.height, width: line.width, outline, ...directions ? { alignment: lineAlignment } : {} });
5007
+ height = Math.max(height, y + line2.height - box.y, outline ? bottom - box.y : 0);
5008
+ if (line2.width > box.width + 0.01 || height > box.height + 0.01) overflow = true;
5009
+ placed.push({ x, y, baseline, height: line2.height, width: line2.width, outline, ...directions ? { alignment: lineAlignment } : {} });
4833
5010
  }
4834
5011
  return { alignment, rasterPadding, lines: placed, height, overflow };
4835
5012
  }
@@ -4839,11 +5016,11 @@ function translateTextFit(fit, dy) {
4839
5016
  ...fit,
4840
5017
  placement: {
4841
5018
  ...fit.placement,
4842
- lines: fit.placement.lines.map((line) => ({
4843
- ...line,
4844
- y: line.y + dy,
4845
- baseline: line.baseline + dy,
4846
- outline: line.outline ? { ...line.outline, y: line.outline.y + dy } : line.outline
5019
+ lines: fit.placement.lines.map((line2) => ({
5020
+ ...line2,
5021
+ y: line2.y + dy,
5022
+ baseline: line2.baseline + dy,
5023
+ outline: line2.outline ? { ...line2.outline, y: line2.outline.y + dy } : line2.outline
4847
5024
  }))
4848
5025
  }
4849
5026
  };
@@ -5016,9 +5193,9 @@ var FURNITURE_IMAGE_SHARE = 0.4;
5016
5193
  var SPACED_WORD_CHARACTER = /^[\p{L}\p{N}\p{M}]$/u;
5017
5194
  var UNSPACED_SCRIPT = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Thai}\p{Script=Lao}\p{Script=Khmer}\p{Script=Myanmar}\p{Script=Tibetan}]/u;
5018
5195
  function breaksInsideWord(text2, fit) {
5019
- return fit.sourceLines.some((line) => {
5020
- if (line.boundary !== "soft" || line.nextStart <= 0 || line.nextStart >= text2.length) return false;
5021
- const before = [...text2.slice(0, line.nextStart)].at(-1) ?? "", after = [...text2.slice(line.nextStart, line.nextStart + 2)][0] ?? "";
5196
+ return fit.sourceLines.some((line2) => {
5197
+ if (line2.boundary !== "soft" || line2.nextStart <= 0 || line2.nextStart >= text2.length) return false;
5198
+ const before = [...text2.slice(0, line2.nextStart)].at(-1) ?? "", after = [...text2.slice(line2.nextStart, line2.nextStart + 2)][0] ?? "";
5022
5199
  return SPACED_WORD_CHARACTER.test(before) && SPACED_WORD_CHARACTER.test(after) && !UNSPACED_SCRIPT.test(before) && !UNSPACED_SCRIPT.test(after);
5023
5200
  });
5024
5201
  }
@@ -5101,10 +5278,10 @@ function layoutFurniture(input, options = {}) {
5101
5278
  }
5102
5279
  const fitPart = (part, boxWidth) => {
5103
5280
  const fit = fitText(part.text, { width: Math.max(Number.MIN_VALUE, boxWidth - (outlines ? 2 * padding : 0)), height: Number.MAX_VALUE }, size, size, textWidthMeasurer(part.style, options.textMeasurement));
5104
- const ink = fit.sourceLines.map((line, index2) => {
5281
+ const ink = fit.sourceLines.map((line2, index2) => {
5105
5282
  let outline = null;
5106
5283
  if (outlines) {
5107
- for (const segment2 of line.segments) if (segment2.kind === "text") {
5284
+ for (const segment2 of line2.segments) if (segment2.kind === "text") {
5108
5285
  const bounds = measureTextOutline(part.text.slice(segment2.start, segment2.end), size, part.style, options.textMeasurement);
5109
5286
  if (bounds) {
5110
5287
  const next = { ...bounds, x: bounds.x + segment2.x };
@@ -5119,7 +5296,7 @@ function layoutFurniture(input, options = {}) {
5119
5296
  }
5120
5297
  }
5121
5298
  }
5122
- return { width: line.width, y: index2 * fit.lineHeight, baseline: size + index2 * fit.lineHeight, height: fit.lineHeight, outline };
5299
+ return { width: line2.width, y: index2 * fit.lineHeight, baseline: size + index2 * fit.lineHeight, height: fit.lineHeight, outline };
5123
5300
  });
5124
5301
  const natural = outlines ? placeTextLines(ink, { x: 0, y: 0, width: boxWidth, height: Number.MAX_VALUE }, side, padding) : void 0;
5125
5302
  const partHeight = natural?.height ?? fit.sourceLines.length * fit.lineHeight;
@@ -5127,7 +5304,7 @@ function layoutFurniture(input, options = {}) {
5127
5304
  return { fit, ink, height: Math.max(scale, partHeight) };
5128
5305
  };
5129
5306
  const gap = FURNITURE_GAP * scale, gaps = gap * Math.max(0, pending.length - 1);
5130
- const widths = pending.map((part) => part.type === "image" ? pending.length > 1 ? Math.min(part.width, zoneWidth * FURNITURE_IMAGE_SHARE) : part.width : pending.length === 1 ? zoneWidth : Math.max(scale, ...fitPart(part, 1e7).ink.map((line) => Math.max(line.width + (outlines ? 2 * padding : 0), line.outline ? line.outline.width + 2 * padding : 0))));
5307
+ const widths = pending.map((part) => part.type === "image" ? pending.length > 1 ? Math.min(part.width, zoneWidth * FURNITURE_IMAGE_SHARE) : part.width : pending.length === 1 ? zoneWidth : Math.max(scale, ...fitPart(part, 1e7).ink.map((line2) => Math.max(line2.width + (outlines ? 2 * padding : 0), line2.outline ? line2.outline.width + 2 * padding : 0))));
5131
5308
  if (pending.length > 1 && widths.reduce((sum, entry) => sum + entry, 0) + gaps > zoneWidth + 0.01) {
5132
5309
  const texts = pending.map((_, index2) => index2).filter((index2) => pending[index2].type === "text").sort((a, b) => widths[a] - widths[b]);
5133
5310
  let remaining = zoneWidth - gaps - pending.reduce((sum, part, index2) => sum + (part.type === "image" ? widths[index2] : 0), 0), count = texts.length;
@@ -5170,10 +5347,10 @@ function layoutFurniture(input, options = {}) {
5170
5347
  else footerTop = top;
5171
5348
  for (const zone of zones) for (const part of zone) {
5172
5349
  part.box.y += top;
5173
- if (part.type === "text" && part.fit.placement) for (const line of part.fit.placement.lines) {
5174
- line.y += top;
5175
- line.baseline += top;
5176
- if (line.outline) line.outline.y += top;
5350
+ if (part.type === "text" && part.fit.placement) for (const line2 of part.fit.placement.lines) {
5351
+ line2.y += top;
5352
+ line2.baseline += top;
5353
+ if (line2.outline) line2.outline.y += top;
5177
5354
  }
5178
5355
  if (part.box.y + part.box.height > height - height * 0.04 + 0.01) error(part.path, "Repeated header/footer content extends beyond the usable slide height. Change its content or design before pagination.");
5179
5356
  parts.push(part);
@@ -5262,11 +5439,11 @@ function layoutQuote(value, box, options = {}) {
5262
5439
  const diagnostics = [], parts = [];
5263
5440
  const report = (reason, diagnosticPath, roles, message) => diagnostics.push({ code: "text-overflow", reason, path: diagnosticPath, parts: roles, message });
5264
5441
  const source = (sourcePath, text2, outputStart) => ({ path: sourcePath, start: 0, end: text2.length, outputStart, outputEnd: outputStart + text2.length });
5265
- const add = (role, text2, sources, area, fontSize, fontFamily, fontWeight, partPath, runs) => {
5442
+ const add = (role, text2, sources, area2, fontSize, fontFamily, fontWeight, partPath, runs) => {
5266
5443
  const requestedStyle = { fontFamily, fontWeight, italic: false, path: partPath };
5267
5444
  const style = resolveTextStyle({ ...requestedStyle }, options.textMeasurement);
5268
5445
  const requestedFontSize = gridFontSize(fontSize * scale, minimum);
5269
- const part = { role, path: partPath, text: text2, sources, box: area, requestedFontSize, minFontSize: minimum, requestedStyle, style, ...runs ? { runs } : {} };
5446
+ const part = { role, path: partPath, text: text2, sources, box: area2, requestedFontSize, minFontSize: minimum, requestedStyle, style, ...runs ? { runs } : {} };
5270
5447
  parts.push(part);
5271
5448
  return part;
5272
5449
  };
@@ -5304,8 +5481,8 @@ function layoutQuote(value, box, options = {}) {
5304
5481
  path
5305
5482
  ) : void 0;
5306
5483
  const footerRequested = attribution?.requestedFontSize ?? gridFontSize(17 * scale, minimum);
5307
- const usable2 = (area) => [area.x, area.y, area.width, area.height].every(Number.isFinite) && area.width > 0 && area.height > 0;
5308
- const fit = (part, area, size = part.requestedFontSize, floor = minimum) => !usable2(area) ? void 0 : part.runs ? fitRichText(part.runs, area, size, floor, { style: part.style, textMeasurement: options.textMeasurement, ...options.citationMarker ? { citationMarker: options.citationMarker } : {}, ...options.direction ? { direction: options.direction } : {} }) : fitText(part.text, area, size, floor, textWidthMeasurer(part.style, options.textMeasurement), options.direction);
5484
+ const usable2 = (area2) => [area2.x, area2.y, area2.width, area2.height].every(Number.isFinite) && area2.width > 0 && area2.height > 0;
5485
+ const fit = (part, area2, size = part.requestedFontSize, floor = minimum) => !usable2(area2) ? void 0 : part.runs ? fitRichText(part.runs, area2, size, floor, { style: part.style, textMeasurement: options.textMeasurement, ...options.citationMarker ? { citationMarker: options.citationMarker } : {}, ...options.direction ? { direction: options.direction } : {} }) : fitText(part.text, area2, size, floor, textWidthMeasurer(part.style, options.textMeasurement), options.direction);
5309
5486
  const heightOf = (fit2) => "richLines" in fit2 ? fit2.height : fit2.lines.length * fit2.lineHeight;
5310
5487
  const inner = { x: box.x + 18, y: box.y + 18, width: box.width - 36, height: box.height - 36 };
5311
5488
  let photo, photoFits = true;
@@ -5369,13 +5546,13 @@ function layoutQuote(value, box, options = {}) {
5369
5546
  }
5370
5547
  if (hasPhoto && !photo) photoFits = false;
5371
5548
  for (const part of parts) {
5372
- const area = part.box;
5549
+ const area2 = part.box;
5373
5550
  if (!part.fit) {
5374
5551
  report("invalid-part-box", part.path, [part.role], `Quote ${part.role} has no usable space after its insets; increase the cell size or change the arrangement.`);
5375
5552
  } else if (part.fit.overflow) {
5376
5553
  report("text-fit", part.path, [part.role], `Quote ${part.role} exceeds its available space at the readability floor; increase its space or change the arrangement.`);
5377
5554
  }
5378
- if (usable2(area) && (area.x < box.x || area.y < box.y || area.x + area.width > box.x + box.width + 0.01 || area.y + area.height > box.y + box.height + 0.01)) {
5555
+ if (usable2(area2) && (area2.x < box.x || area2.y < box.y || area2.x + area2.width > box.x + box.width + 0.01 || area2.y + area2.height > box.y + box.height + 0.01)) {
5379
5556
  report("part-outside-cell", part.path, [part.role], `Quote ${part.role} extends outside its cell; increase the cell size or change the arrangement.`);
5380
5557
  }
5381
5558
  }
@@ -5388,7 +5565,7 @@ function layoutQuote(value, box, options = {}) {
5388
5565
  if (diagnostics.length && options.overflow === "error") throw new OPFCompositionError(diagnostics);
5389
5566
  const occupiedParts = parts.filter((part) => part.fit).map((part) => ({ ...part.box, height: part.fit.placement?.height ?? heightOf(part.fit) }));
5390
5567
  if (photo) occupiedParts.push(photo.box);
5391
- const bottom = Math.max(box.y, ...occupiedParts.map((area) => area.y + area.height));
5568
+ const bottom = Math.max(box.y, ...occupiedParts.map((area2) => area2.y + area2.height));
5392
5569
  const bounds = { x: box.x, y: box.y, width: box.width, height: bottom - box.y };
5393
5570
  return { bounds, algorithm: "quote-flow-v1", textMeasurement: options.textMeasurement ? "provided" : "estimated", parts, ...photo ? { photo } : {}, diagnostics, overflow: diagnostics.length > 0 };
5394
5571
  }
@@ -5434,12 +5611,12 @@ function layoutMetric(value, box, options = {}) {
5434
5611
  const primary = parts[0], metadata = parts.filter((part) => part !== primary && part.visible), unit = metadata.find((part) => part.role === "unit");
5435
5612
  const metricDirection = options.direction === "rtl" ? paragraphDirection(["label", "description", "unit"].map((role) => parts.find((part) => part.role === role)?.text).find(Boolean) ?? primary.text, "rtl") : void 0;
5436
5613
  const alignment = physicalAlignment(requestedAlignment, metricDirection);
5437
- const usable2 = (area) => [area.x, area.y, area.width, area.height, area.x + area.width, area.y + area.height].every(Number.isFinite) && area.width > 0 && area.height > 0;
5614
+ const usable2 = (area2) => [area2.x, area2.y, area2.width, area2.height, area2.x + area2.width, area2.y + area2.height].every(Number.isFinite) && area2.width > 0 && area2.height > 0;
5438
5615
  const occupied = (fit) => fit.placement?.height ?? fit.lines.length * fit.lineHeight;
5439
5616
  const gap = 8 * scale, primaryGap = 12 * scale;
5440
- const lineInk = (part, fit) => fit.sourceLines.map((line, index) => {
5617
+ const lineInk = (part, fit) => fit.sourceLines.map((line2, index) => {
5441
5618
  let outline = null;
5442
- for (const segment2 of line.segments) {
5619
+ for (const segment2 of line2.segments) {
5443
5620
  if (segment2.kind !== "text") continue;
5444
5621
  const bounds2 = measureTextOutline(part.text.slice(segment2.start, segment2.end), fit.fontSize, part.style, options.textMeasurement);
5445
5622
  if (!bounds2) continue;
@@ -5453,7 +5630,7 @@ function layoutMetric(value, box, options = {}) {
5453
5630
  outline.height = bottom2 - outline.y;
5454
5631
  }
5455
5632
  }
5456
- return { width: line.width, y: index * fit.lineHeight, baseline: fit.fontSize + index * fit.lineHeight, height: fit.lineHeight, outline };
5633
+ return { width: line2.width, y: index * fit.lineHeight, baseline: fit.fontSize + index * fit.lineHeight, height: fit.lineHeight, outline };
5457
5634
  });
5458
5635
  const place = (part, fit, width) => {
5459
5636
  if (!hasOutlines) return fit;
@@ -5461,8 +5638,8 @@ function layoutMetric(value, box, options = {}) {
5461
5638
  return { ...fit, placement, overflow: placement.overflow };
5462
5639
  };
5463
5640
  const naturalWidth = (part, fit) => {
5464
- if (!hasOutlines) return Math.max(...fit.sourceLines.map((line) => line.width));
5465
- const width = Math.max(...lineInk(part, fit).map((line) => Math.max(line.width, line.outline ? line.outline.x + line.outline.width : 0) - Math.min(0, line.outline?.x ?? 0)));
5641
+ if (!hasOutlines) return Math.max(...fit.sourceLines.map((line2) => line2.width));
5642
+ const width = Math.max(...lineInk(part, fit).map((line2) => Math.max(line2.width, line2.outline ? line2.outline.x + line2.outline.width : 0) - Math.min(0, line2.outline?.x ?? 0)));
5466
5643
  return width > 0 ? width + 2 * rasterPadding : 0;
5467
5644
  };
5468
5645
  const cache2 = /* @__PURE__ */ new Map();
@@ -5477,12 +5654,12 @@ function layoutMetric(value, box, options = {}) {
5477
5654
  }
5478
5655
  return fit;
5479
5656
  };
5480
- const fitValue = (area, singleLine) => {
5481
- if (!usable2(area)) return void 0;
5657
+ const fitValue = (area2, singleLine) => {
5658
+ if (!usable2(area2)) return void 0;
5482
5659
  for (let step = 0; step <= 76; step++) {
5483
5660
  const size = gridFontSize(primary.requestedFontSize - step * scale, minimum);
5484
- const natural = measure(primary, size, area.width);
5485
- const fit = { ...natural, overflow: !!natural.placement?.overflow || singleLine && natural.lines.length !== 1 || occupied(natural) > area.height + 0.01 || natural.sourceLines.some((line) => line.width > area.width + 0.01) };
5661
+ const natural = measure(primary, size, area2.width);
5662
+ const fit = { ...natural, overflow: !!natural.placement?.overflow || singleLine && natural.lines.length !== 1 || occupied(natural) > area2.height + 0.01 || natural.sourceLines.some((line2) => line2.width > area2.width + 0.01) };
5486
5663
  if (!fit.overflow || size === minimum) return fit;
5487
5664
  }
5488
5665
  };
@@ -5499,8 +5676,8 @@ function layoutMetric(value, box, options = {}) {
5499
5676
  const tail = metadata.filter((part) => arrangement !== "inline-unit" || part !== unit);
5500
5677
  const tailHeight = tail.reduce((sum, part) => sum + occupied(measured.get(part)), 0) + Math.max(0, tail.length - 1) * gap;
5501
5678
  if (!Number.isFinite(tailHeight)) throw new RangeError("Metric metadata exceeds finite coordinates.");
5502
- const area = { ...box, width: arrangement === "inline-unit" ? box.width - unitWidth - gap : box.width, height: box.height - tailHeight - (tail.length ? primaryGap : 0) };
5503
- const valueFit = fitValue(area, arrangement === "inline-unit"), valueHeight = valueFit ? occupied(valueFit) : 0;
5679
+ const area2 = { ...box, width: arrangement === "inline-unit" ? box.width - unitWidth - gap : box.width, height: box.height - tailHeight - (tail.length ? primaryGap : 0) };
5680
+ const valueFit = fitValue(area2, arrangement === "inline-unit"), valueHeight = valueFit ? occupied(valueFit) : 0;
5504
5681
  const allocations = [];
5505
5682
  let primaryHeight = valueHeight;
5506
5683
  if (arrangement === "inline-unit" && unit && unitFit && valueFit) {
@@ -5508,18 +5685,18 @@ function layoutMetric(value, box, options = {}) {
5508
5685
  const unitBaseline = unitFit.placement?.lines.at(-1)?.baseline ?? occupied(unitFit) - unitFit.lineHeight + unitFit.fontSize;
5509
5686
  const valueY = box.y + Math.max(0, unitBaseline - valueBaseline), unitY = box.y + Math.max(0, valueBaseline - unitBaseline);
5510
5687
  const measuredWidth = naturalWidth(primary, valueFit);
5511
- const valueWidth = Math.min(area.width, measuredWidth || valueFit.fontSize);
5512
- allocations.push({ part: primary, box: { ...area, y: valueY, width: valueWidth, height: valueHeight }, fit: place(primary, valueFit, valueWidth) });
5688
+ const valueWidth = Math.min(area2.width, measuredWidth || valueFit.fontSize);
5689
+ allocations.push({ part: primary, box: { ...area2, y: valueY, width: valueWidth, height: valueHeight }, fit: place(primary, valueFit, valueWidth) });
5513
5690
  allocations.push({ part: unit, box: { x: box.x + valueWidth + gap, y: unitY, width: unitWidth, height: occupied(unitFit) }, fit: { ...unitFit, overflow: !!unitFit.placement?.overflow } });
5514
5691
  primaryHeight = Math.max(valueY - box.y + valueHeight, unitY - box.y + occupied(unitFit));
5515
- } else allocations.push({ part: primary, box: valueFit ? { ...area, height: valueHeight } : area, fit: valueFit });
5692
+ } else allocations.push({ part: primary, box: valueFit ? { ...area2, height: valueHeight } : area2, fit: valueFit });
5516
5693
  let y = box.y + primaryHeight + (tail.length ? primaryGap : 0);
5517
5694
  for (const part of tail) {
5518
5695
  const natural = measured.get(part), height = occupied(natural);
5519
- allocations.push({ part, box: { ...box, y, height }, fit: { ...natural, overflow: !!natural.placement?.overflow || natural.sourceLines.some((line) => line.width > box.width + 0.01) } });
5696
+ allocations.push({ part, box: { ...box, y, height }, fit: { ...natural, overflow: !!natural.placement?.overflow || natural.sourceLines.some((line2) => line2.width > box.width + 0.01) } });
5520
5697
  y += height + gap;
5521
5698
  }
5522
- const overflow = !valueFit || valueFit.overflow || arrangement === "inline-unit" && valueFit.lines.length !== 1 || primaryHeight > area.height + 0.01 || allocations.some(({ box: area2, fit }) => !fit || fit.overflow || !usable2(area2) || area2.y + area2.height > box.y + box.height + 0.01);
5699
+ const overflow = !valueFit || valueFit.overflow || arrangement === "inline-unit" && valueFit.lines.length !== 1 || primaryHeight > area2.height + 0.01 || allocations.some(({ box: area3, fit }) => !fit || fit.overflow || !usable2(area3) || area3.y + area3.height > box.y + box.height + 0.01);
5523
5700
  const score = allocations.reduce((sum, { part, fit }) => sum + (part.requestedFontSize - (fit?.fontSize ?? minimum)) / scale, 0);
5524
5701
  const candidate = { arrangement, allocations, score, overflow };
5525
5702
  if (!selected || !overflow && (selected.overflow || score < selected.score) || overflow && selected.overflow) selected = candidate;
@@ -5538,10 +5715,10 @@ function layoutMetric(value, box, options = {}) {
5538
5715
  }
5539
5716
  for (const part of parts) if (part.fit) {
5540
5717
  if (part.fit.placement) {
5541
- part.fit = { ...part.fit, placement: { ...part.fit.placement, lines: part.fit.placement.lines.map((line) => ({ ...line, x: line.x + part.box.x, y: line.y + part.box.y, baseline: line.baseline + part.box.y, outline: line.outline ? { ...line.outline, x: line.outline.x + part.box.x, y: line.outline.y + part.box.y } : null })) } };
5718
+ part.fit = { ...part.fit, placement: { ...part.fit.placement, lines: part.fit.placement.lines.map((line2) => ({ ...line2, x: line2.x + part.box.x, y: line2.y + part.box.y, baseline: line2.baseline + part.box.y, outline: line2.outline ? { ...line2.outline, x: line2.outline.x + part.box.x, y: line2.outline.y + part.box.y } : null })) } };
5542
5719
  part.linePositions = part.fit.placement.lines.map(({ x, baseline }) => ({ x, baseline }));
5543
- } else part.linePositions = part.fit.sourceLines.map((line, index) => ({
5544
- x: part.box.x + (part.box.width - line.width) * alignmentFactor,
5720
+ } else part.linePositions = part.fit.sourceLines.map((line2, index) => ({
5721
+ x: part.box.x + (part.box.width - line2.width) * alignmentFactor,
5545
5722
  baseline: part.box.y + part.fit.fontSize + index * part.fit.lineHeight
5546
5723
  }));
5547
5724
  }
@@ -5601,10 +5778,10 @@ function layoutTimeline(value, box, options = {}) {
5601
5778
  let measured = cache2.get(key);
5602
5779
  if (measured) return measured;
5603
5780
  const fit = fitText(part.text, { width: Math.max(Number.MIN_VALUE, width - (outlines ? 2 * padding : 0)), height: Number.MAX_VALUE }, size, size, textWidthMeasurer(part.style, options.textMeasurement), options.direction);
5604
- const ink = fit.sourceLines.map((line, index) => {
5781
+ const ink = fit.sourceLines.map((line2, index) => {
5605
5782
  let left = Infinity, top = Infinity, right = -Infinity, bottom = -Infinity, hasInk = false;
5606
5783
  if (outlines) {
5607
- for (const segment2 of line.segments) if (segment2.kind === "text") {
5784
+ for (const segment2 of line2.segments) if (segment2.kind === "text") {
5608
5785
  const outline = measureTextOutline(part.text.slice(segment2.start, segment2.end), size, part.style, options.textMeasurement);
5609
5786
  if (outline) {
5610
5787
  hasInk = true;
@@ -5615,7 +5792,7 @@ function layoutTimeline(value, box, options = {}) {
5615
5792
  }
5616
5793
  }
5617
5794
  }
5618
- return { width: line.width, y: index * fit.lineHeight, baseline: size + index * fit.lineHeight, height: fit.lineHeight, outline: hasInk ? { x: left, y: top, width: right - left, height: bottom - top } : null };
5795
+ return { width: line2.width, y: index * fit.lineHeight, baseline: size + index * fit.lineHeight, height: fit.lineHeight, outline: hasInk ? { x: left, y: top, width: right - left, height: bottom - top } : null };
5619
5796
  });
5620
5797
  const placement = outlines ? placeTextLines(ink, { x: 0, y: 0, width, height: Number.MAX_VALUE }, alignment, padding, fit.directions) : void 0;
5621
5798
  const height = placement?.height ?? fit.sourceLines.length * fit.lineHeight;
@@ -5639,13 +5816,13 @@ function layoutTimeline(value, box, options = {}) {
5639
5816
  };
5640
5817
  const place = (part, x, y2, width, alignment) => {
5641
5818
  const measured = measure(part, gridFontSize(part.requestedFontSize - reduction * scale, minimum), Math.max(scale, width), alignment);
5642
- const area = { x, y: y2, width: Math.max(scale, width), height: Math.max(scale, measured.height) }, placement = outlines ? placeTextLines(measured.ink, area, alignment, padding, measured.fit.directions) : void 0;
5819
+ const area2 = { x, y: y2, width: Math.max(scale, width), height: Math.max(scale, measured.height) }, placement = outlines ? placeTextLines(measured.ink, area2, alignment, padding, measured.fit.directions) : void 0;
5643
5820
  const fit = { ...measured.fit, ...placement ? { placement } : {}, overflow: measured.fit.overflow || !!placement?.overflow };
5644
- const accepted = { ...part, box: area, alignment, fit };
5821
+ const accepted = { ...part, box: area2, alignment, fit };
5645
5822
  parts.push(accepted);
5646
5823
  if (fit.overflow) report(accepted, "text-fit", "Timeline field exceeds its readable width; increase its space or split the timeline.");
5647
5824
  if (breaksInsideWord(part.text, fit)) report(accepted, "text-fit", "Timeline field would split a word; use a wider vertical arrangement or paginate events.");
5648
- if (area.x < box.x - 0.01 || area.y < box.y - 0.01 || area.x + area.width > box.x + box.width + 0.01 || area.y + area.height > box.y + box.height + 0.01) report(accepted, "part-outside-cell", "Timeline field extends outside its cell; increase the cell or paginate events.", Math.max(area.x + area.width - box.x - box.width, area.y + area.height - box.y - box.height));
5825
+ if (area2.x < box.x - 0.01 || area2.y < box.y - 0.01 || area2.x + area2.width > box.x + box.width + 0.01 || area2.y + area2.height > box.y + box.height + 0.01) report(accepted, "part-outside-cell", "Timeline field extends outside its cell; increase the cell or paginate events.", Math.max(area2.x + area2.width - box.x - box.width, area2.y + area2.height - box.y - box.height));
5649
5826
  return accepted;
5650
5827
  };
5651
5828
  let y = box.y;
@@ -5787,14 +5964,14 @@ function fitSourceText(text2, box, size, minimum, step, measure, prose = false,
5787
5964
  push(end, end, "end");
5788
5965
  const lineHeight = fontSize * 1.22;
5789
5966
  return {
5790
- lines: sourceLines.map((line) => text2.slice(line.start, line.end)),
5967
+ lines: sourceLines.map((line2) => text2.slice(line2.start, line2.end)),
5791
5968
  sourceLines,
5792
5969
  fontSize,
5793
5970
  lineHeight,
5794
5971
  tabSize: 4,
5795
5972
  tabWidth,
5796
- ...directionAt ? { directions: sourceLines.map((line) => directionAt(line.start)) } : {},
5797
- overflow: sourceLines.length * lineHeight > box.height + 0.01 || sourceLines.some((line) => line.width > box.width + 0.01)
5973
+ ...directionAt ? { directions: sourceLines.map((line2) => directionAt(line2.start)) } : {},
5974
+ overflow: sourceLines.length * lineHeight > box.height + 0.01 || sourceLines.some((line2) => line2.width > box.width + 0.01)
5798
5975
  };
5799
5976
  };
5800
5977
  return fitAtSizes(layout, size, minimum, step, snap);
@@ -5832,8 +6009,8 @@ function layoutCode(value, box, options = {}) {
5832
6009
  if (code.language) add("language", code.language, `${path}.language`);
5833
6010
  if (!parts.length) add("language", "code", path, true);
5834
6011
  const body = add("body", code.source, shorthand ? path : `${path}.source`), headers = parts.filter((part) => part !== body);
5835
- const usable2 = (area) => [area.x, area.y, area.width, area.height].every(Number.isFinite) && area.width > 0 && area.height > 0;
5836
- const fit = (part, area, size = part.requestedFontSize, floor = minimum) => usable2(area) ? fitCodeText(part.text, area, size, floor, scale, textWidthMeasurer(part.style, options.textMeasurement)) : void 0;
6012
+ const usable2 = (area2) => [area2.x, area2.y, area2.width, area2.height].every(Number.isFinite) && area2.width > 0 && area2.height > 0;
6013
+ const fit = (part, area2, size = part.requestedFontSize, floor = minimum) => usable2(area2) ? fitCodeText(part.text, area2, size, floor, scale, textWidthMeasurer(part.style, options.textMeasurement)) : void 0;
5837
6014
  if (usable2(inner)) {
5838
6015
  const combinations = headers.reduce((choices, part) => choices.flatMap((choice) => [.../* @__PURE__ */ new Set([part.requestedFontSize, minimum])].map((size) => [...choice, { part, size }])), [[]]);
5839
6016
  let selected;
@@ -5842,12 +6019,12 @@ function layoutCode(value, box, options = {}) {
5842
6019
  const allocations = [];
5843
6020
  for (const [index, { part, size }] of combination.entries()) {
5844
6021
  const measured = fitCodeText(part.text, inner, size, size, scale, textWidthMeasurer(part.style, options.textMeasurement));
5845
- const area2 = { ...inner, y, height: measured.lines.length * measured.lineHeight };
5846
- allocations.push({ part, box: area2, fit: usable2(area2) ? { ...measured, overflow: measured.sourceLines.some((line) => line.width > area2.width + 0.01) } : void 0 });
5847
- y += area2.height + (index < headers.length - 1 ? 8 : 12);
6022
+ const area3 = { ...inner, y, height: measured.lines.length * measured.lineHeight };
6023
+ allocations.push({ part, box: area3, fit: usable2(area3) ? { ...measured, overflow: measured.sourceLines.some((line2) => line2.width > area3.width + 0.01) } : void 0 });
6024
+ y += area3.height + (index < headers.length - 1 ? 8 : 12);
5848
6025
  }
5849
- const area = { ...inner, y, height: inner.y + inner.height - y };
5850
- allocations.push({ part: body, box: area, fit: fit(body, area) });
6026
+ const area2 = { ...inner, y, height: inner.y + inner.height - y };
6027
+ allocations.push({ part: body, box: area2, fit: fit(body, area2) });
5851
6028
  const overflow = allocations.some(({ box: box2, fit: fit2 }) => !fit2 || fit2.overflow || !usable2(box2) || box2.y + box2.height > inner.y + inner.height + 0.01);
5852
6029
  const score = allocations.reduce((sum, { part, fit: fit2 }) => sum + (part.requestedFontSize - (fit2?.fontSize ?? minimum)) / scale, 0);
5853
6030
  if (!selected || !overflow && (selected.overflow || score < selected.score) || overflow && selected.overflow) selected = { allocations, score, overflow };
@@ -5861,8 +6038,8 @@ function layoutCode(value, box, options = {}) {
5861
6038
  for (const part of parts) {
5862
6039
  if (!part.fit) report("invalid-part-box", part, [part.role], `Code ${part.role} has no usable space after metadata and insets; increase the cell or change the arrangement.`);
5863
6040
  else if (part.fit.overflow) report("text-fit", part, [part.role], `Code ${part.role} exceeds its space at the readability floor; increase its space or change the arrangement.`);
5864
- const area = part.box;
5865
- if (usable2(area) && (area.x < box.x || area.y < box.y || area.x + area.width > box.x + box.width + 0.01 || area.y + area.height > box.y + box.height + 0.01)) {
6041
+ const area2 = part.box;
6042
+ if (usable2(area2) && (area2.x < box.x || area2.y < box.y || area2.x + area2.width > box.x + box.width + 0.01 || area2.y + area2.height > box.y + box.height + 0.01)) {
5866
6043
  report("part-outside-cell", part, [part.role], `Code ${part.role} extends outside its cell; increase the cell or change the arrangement.`);
5867
6044
  }
5868
6045
  }
@@ -5990,27 +6167,27 @@ function richTextLayouter(input, box, requestedSize, options, minimum = 0) {
5990
6167
  let y = 0;
5991
6168
  const richLines = ranges.map((range, rangeIndex) => {
5992
6169
  const parts = fragments(range.start, range.end), shown = hung.get(rangeIndex) ?? range.end, ascent = Math.max(fontSize, ...parts.map((part) => part.fontSize - part.baselineShift)), descent = Math.max(fontSize * 0.22, ...parts.map((part) => part.fontSize * 0.22 + part.baselineShift));
5993
- const height = ascent + descent, line = { fragments: parts, width: shown === range.end ? parts.reduce((sum, p) => sum + p.width, 0) : width(range.start, shown), y, baseline: y + ascent, height };
6170
+ const height = ascent + descent, line2 = { fragments: parts, width: shown === range.end ? parts.reduce((sum, p) => sum + p.width, 0) : width(range.start, shown), y, baseline: y + ascent, height };
5994
6171
  y += height;
5995
- return line;
6172
+ return line2;
5996
6173
  });
5997
6174
  if (options.uniformLineHeight) {
5998
- const height = Math.max(...richLines.map((line) => line.height));
6175
+ const height = Math.max(...richLines.map((line2) => line2.height));
5999
6176
  y = 0;
6000
- for (const line of richLines) {
6001
- line.baseline += y - line.y;
6002
- line.y = y;
6003
- line.height = height;
6177
+ for (const line2 of richLines) {
6178
+ line2.baseline += y - line2.y;
6179
+ line2.y = y;
6180
+ line2.height = height;
6004
6181
  y += height;
6005
6182
  }
6006
6183
  }
6007
6184
  return {
6008
6185
  lines: ranges.map((range) => whole.slice(range.start, range.end)),
6009
6186
  fontSize,
6010
- lineHeight: Math.max(fontSize * 1.22, ...richLines.map((line) => line.height)),
6187
+ lineHeight: Math.max(fontSize * 1.22, ...richLines.map((line2) => line2.height)),
6011
6188
  richLines,
6012
6189
  height: y,
6013
- overflow: y > box.height + 0.01 || richLines.some((line) => line.width > box.width + 0.01),
6190
+ overflow: y > box.height + 0.01 || richLines.some((line2) => line2.width > box.width + 0.01),
6014
6191
  ...directionAt ? { directions: ranges.map((range) => directionAt(range.start)) } : {}
6015
6192
  };
6016
6193
  };
@@ -6200,15 +6377,15 @@ function regionParts(key) {
6200
6377
  }
6201
6378
  return void 0;
6202
6379
  }
6203
- function regionBox(parts, area, requestedGap) {
6204
- const gap = Math.min(requestedGap, area.width / 6, area.height / 6);
6205
- const cw = (area.width - gap * 2) / 3, ch = (area.height - gap * 2) / 3;
6380
+ function regionBox(parts, area2, requestedGap) {
6381
+ const gap = Math.min(requestedGap, area2.width / 6, area2.height / 6);
6382
+ const cw = (area2.width - gap * 2) / 3, ch = (area2.height - gap * 2) / 3;
6206
6383
  const [r, c] = parts;
6207
- return { x: area.x + Math.min(...c) * (cw + gap), y: area.y + Math.min(...r) * (ch + gap), width: (Math.max(...c) - Math.min(...c) + 1) * (cw + gap) - gap, height: (Math.max(...r) - Math.min(...r) + 1) * (ch + gap) - gap };
6384
+ return { x: area2.x + Math.min(...c) * (cw + gap), y: area2.y + Math.min(...r) * (ch + gap), width: (Math.max(...c) - Math.min(...c) + 1) * (cw + gap) - gap, height: (Math.max(...r) - Math.min(...r) + 1) * (ch + gap) - gap };
6208
6385
  }
6209
- function gridGeometry(count, area, cols, gap, weights, vertical) {
6386
+ function gridGeometry(count, area2, cols, gap, weights, vertical) {
6210
6387
  const rowCount = Math.ceil(count / cols);
6211
- gap = Math.min(gap, area.width / (cols * 2), area.height / (rowCount * 2));
6388
+ gap = Math.min(gap, area2.width / (cols * 2), area2.height / (rowCount * 2));
6212
6389
  const tracks = (length, total, weighted) => {
6213
6390
  const values = Array.from({ length }, (_, i) => weighted ? weights[i] ?? 1 : 1);
6214
6391
  const sum = values.reduce((a, b) => a + b, 0);
@@ -6220,12 +6397,12 @@ function gridGeometry(count, area, cols, gap, weights, vertical) {
6220
6397
  return track;
6221
6398
  });
6222
6399
  };
6223
- const xs = tracks(cols, area.width, !vertical), ys = tracks(rowCount, area.height, vertical);
6224
- const boxes = Array.from({ length: count }, (_, i) => ({ x: area.x + xs[i % cols].offset, y: area.y + ys[Math.floor(i / cols)].offset, width: xs[i % cols].size, height: ys[Math.floor(i / cols)].size }));
6400
+ const xs = tracks(cols, area2.width, !vertical), ys = tracks(rowCount, area2.height, vertical);
6401
+ const boxes = Array.from({ length: count }, (_, i) => ({ x: area2.x + xs[i % cols].offset, y: area2.y + ys[Math.floor(i / cols)].offset, width: xs[i % cols].size, height: ys[Math.floor(i / cols)].size }));
6225
6402
  return { boxes, columns: xs, rows: ys, gap };
6226
6403
  }
6227
- function gridBoxes(count, area, cols, gap, weights, vertical) {
6228
- return gridGeometry(count, area, cols, gap, weights, vertical).boxes;
6404
+ function gridBoxes(count, area2, cols, gap, weights, vertical) {
6405
+ return gridGeometry(count, area2, cols, gap, weights, vertical).boxes;
6229
6406
  }
6230
6407
  function assertComposition(value) {
6231
6408
  if (value.mode !== void 0 && !["auto", "grid", "row", "column"].includes(value.mode)) throw new RangeError("Unknown composition mode.");
@@ -6252,13 +6429,13 @@ function composeLayoutAreas(layout, options = {}) {
6252
6429
  ...mirror !== void 0 ? { design: { mirror } } : {}
6253
6430
  };
6254
6431
  const result = composeSlide(slide, { ...compose, layout: kept, [LAYOUT_MASTER]: true });
6255
- const areas = template.areas.map((area) => {
6256
- if (area.heading) {
6257
- const found = result.headingAreas?.find((entry) => entry.name === area.name);
6258
- return { name: area.name, heading: true, box: found ? { ...found.box } : { x: 0, y: 0, width: 0, height: 0 }, ...found?.parts ? { parts: found.parts } : {} };
6432
+ const areas = template.areas.map((area2) => {
6433
+ if (area2.heading) {
6434
+ const found = result.headingAreas?.find((entry) => entry.name === area2.name);
6435
+ return { name: area2.name, heading: true, box: found ? { ...found.box } : { x: 0, y: 0, width: 0, height: 0 }, ...found?.parts ? { parts: found.parts } : {} };
6259
6436
  }
6260
- const region = result.regions.find((entry) => entry.name === area.name);
6261
- return { name: area.name, heading: false, box: { ...!bleed && region.areaBox ? region.areaBox : region.box } };
6437
+ const region = result.regions.find((entry) => entry.name === area2.name);
6438
+ return { name: area2.name, heading: false, box: { ...!bleed && region.areaBox ? region.areaBox : region.box } };
6262
6439
  });
6263
6440
  return { contentBox: { ...result.contentBox }, areas };
6264
6441
  }
@@ -6305,9 +6482,9 @@ function composeSlide(input, options = {}) {
6305
6482
  const raw = start - trial * scale, last = trial === 64 || raw <= floor, fontSize = last ? floor : gridFontSize(raw, floor);
6306
6483
  const fit = richLayout ? richLayout(fontSize) : fitText(text2, box, fontSize, fontSize, measure, textDirection);
6307
6484
  const richLines = "richLines" in fit ? fit.richLines : void 0;
6308
- const lines = richLines ? richLines.map((line) => {
6485
+ const lines = richLines ? richLines.map((line2) => {
6309
6486
  let outline = null;
6310
- for (const fragment of line.fragments) {
6487
+ for (const fragment of line2.fragments) {
6311
6488
  if (fragment.kind === "tab") continue;
6312
6489
  const bounds = measureTextOutline(fragment.text, fragment.fontSize, fragment.style, options.textMeasurement);
6313
6490
  if (!bounds) continue;
@@ -6321,10 +6498,10 @@ function composeSlide(input, options = {}) {
6321
6498
  outline.height = bottom - outline.y;
6322
6499
  }
6323
6500
  }
6324
- return { width: line.width, y: line.y, baseline: line.baseline, height: line.height, outline };
6325
- }) : fit.sourceLines.map((line, index) => {
6501
+ return { width: line2.width, y: line2.y, baseline: line2.baseline, height: line2.height, outline };
6502
+ }) : fit.sourceLines.map((line2, index) => {
6326
6503
  let outline = null;
6327
- for (const segment2 of line.segments) {
6504
+ for (const segment2 of line2.segments) {
6328
6505
  if (segment2.kind === "tab") continue;
6329
6506
  const bounds = measureTextOutline(text2.slice(segment2.start, segment2.end), fontSize, style, options.textMeasurement);
6330
6507
  if (!bounds) continue;
@@ -6338,7 +6515,7 @@ function composeSlide(input, options = {}) {
6338
6515
  outline.height = bottom - outline.y;
6339
6516
  }
6340
6517
  }
6341
- return { width: line.width, y: index * fit.lineHeight, baseline: fontSize + index * fit.lineHeight, height: fit.lineHeight, outline };
6518
+ return { width: line2.width, y: index * fit.lineHeight, baseline: fontSize + index * fit.lineHeight, height: fit.lineHeight, outline };
6342
6519
  });
6343
6520
  const placement = placeTextLines(lines, box, alignment, rasterPadding, fit.directions), result = { ...fit, placement, overflow: fit.overflow || placement.overflow };
6344
6521
  if (!result.overflow || last) return result;
@@ -6355,7 +6532,7 @@ function composeSlide(input, options = {}) {
6355
6532
  const regions = Object.keys(slide).filter((key) => regionParts(key)).sort();
6356
6533
  const assets = record8(options.presentation).assets;
6357
6534
  const imageContext = (placement) => ({ fit: hints.imageFit, scale, mirrorSide, diagnostics: imageDiagnostics, assets, ...placement ? { placement } : {} });
6358
- const area = { left: 0, top: 0, right: width, bottom: height };
6535
+ const area2 = { left: 0, top: 0, right: width, bottom: height };
6359
6536
  const topImages = regions.length ? [] : Array.isArray(slide.blocks) ? slide.blocks.flatMap((block, index) => !Array.isArray(record8(block).blocks) && record8(block).image !== void 0 ? [{ host: record8(block), hostPath: `${path}.blocks.${index}`, block: index }] : []) : slide.image !== void 0 ? [{ host: { type: "image", image: slide.image }, hostPath: path }] : [];
6360
6537
  const placed = [], usedEdges = /* @__PURE__ */ new Set();
6361
6538
  topImages.forEach((node) => {
@@ -6366,13 +6543,13 @@ function composeSlide(input, options = {}) {
6366
6543
  if (usedEdges.has(edge)) return;
6367
6544
  usedEdges.add(edge);
6368
6545
  const size = finite(value.size, 0.1, 0.9) ?? PLACEMENT_BAND;
6369
- const across = edge === "left" || edge === "right" ? area.right - area.left : area.bottom - area.top;
6546
+ const across = edge === "left" || edge === "right" ? area2.right - area2.left : area2.bottom - area2.top;
6370
6547
  const band = Math.max(0, Math.min(across, round2((edge === "left" || edge === "right" ? width : height) * size)));
6371
- const region = edge === "left" ? { x: area.left, y: area.top, width: band, height: area.bottom - area.top } : edge === "right" ? { x: round2(area.right - band), y: area.top, width: band, height: area.bottom - area.top } : edge === "top" ? { x: area.left, y: area.top, width: area.right - area.left, height: band } : { x: area.left, y: round2(area.bottom - band), width: area.right - area.left, height: band };
6372
- if (edge === "left") area.left += band;
6373
- else if (edge === "right") area.right = region.x;
6374
- else if (edge === "top") area.top += band;
6375
- else area.bottom = region.y;
6548
+ const region = edge === "left" ? { x: area2.left, y: area2.top, width: band, height: area2.bottom - area2.top } : edge === "right" ? { x: round2(area2.right - band), y: area2.top, width: band, height: area2.bottom - area2.top } : edge === "top" ? { x: area2.left, y: area2.top, width: area2.right - area2.left, height: band } : { x: area2.left, y: round2(area2.bottom - band), width: area2.right - area2.left, height: band };
6549
+ if (edge === "left") area2.left += band;
6550
+ else if (edge === "right") area2.right = region.x;
6551
+ else if (edge === "top") area2.top += band;
6552
+ else area2.bottom = region.y;
6376
6553
  const placement = { edge, size, inset: value.inset === true, path: `${node.hostPath}.placement` };
6377
6554
  placed.push({ ...node, placement, region });
6378
6555
  });
@@ -6382,11 +6559,11 @@ function composeSlide(input, options = {}) {
6382
6559
  const measuredFurniture = layoutFurniture(slide, options);
6383
6560
  const furniture = measuredFurniture.configured || measuredFurniture.diagnostics.length ? measuredFurniture : void 0;
6384
6561
  if (furniture) diagnostics.push(...furniture.diagnostics);
6385
- let bodyBottom = Math.min(area.bottom - padding, furniture && furniture.footerTop < height ? furniture.footerTop - gap * 0.5 : height - padding);
6386
- const headingTop = Math.max(area.top + padding, furniture?.headerBottom ? furniture.headerBottom + gap * 0.5 : padding);
6562
+ let bodyBottom = Math.min(area2.bottom - padding, furniture && furniture.footerTop < height ? furniture.footerTop - gap * 0.5 : height - padding);
6563
+ const headingTop = Math.max(area2.top + padding, furniture?.headerBottom ? furniture.headerBottom + gap * 0.5 : padding);
6387
6564
  let footnotes;
6388
6565
  if (citations) {
6389
- footnotes = layoutFootnotes(citations, { ...annotationOptions, x: area.left + padding, width: area.right - area.left - padding * 2, bottom: bodyBottom, maxHeight: Math.max(minSize * 1.22 + 2 * scale, (bodyBottom - headingTop) * FOOTNOTE_MAX_RATIO), path });
6566
+ footnotes = layoutFootnotes(citations, { ...annotationOptions, x: area2.left + padding, width: area2.right - area2.left - padding * 2, bottom: bodyBottom, maxHeight: Math.max(minSize * 1.22 + 2 * scale, (bodyBottom - headingTop) * FOOTNOTE_MAX_RATIO), path });
6390
6567
  diagnostics.push(...footnotes.diagnostics);
6391
6568
  bodyBottom = footnotes.box.y - gap * 0.5;
6392
6569
  }
@@ -6403,8 +6580,8 @@ function composeSlide(input, options = {}) {
6403
6580
  const resolved = resolveLogo(options.presentation, slide, { shape: "full", onDark: options.darkBackground, slideIndex: options.slideIndex });
6404
6581
  if (resolved) {
6405
6582
  const logoHeight = 56 * scale;
6406
- const logoWidth = Math.max(scale, Math.min(4 * logoHeight, area.right - area.left - 2 * padding));
6407
- const box = { x: round2(rtl ? area.right - padding - logoWidth : area.left + padding), y: round2(headingTop), width: round2(logoWidth), height: round2(logoHeight) };
6583
+ const logoWidth = Math.max(scale, Math.min(4 * logoHeight, area2.right - area2.left - 2 * padding));
6584
+ const box = { x: round2(rtl ? area2.right - padding - logoWidth : area2.left + padding), y: round2(headingTop), width: round2(logoWidth), height: round2(logoHeight) };
6408
6585
  logo = { box, shape: resolved.shape, path: resolved.path, source: resolved.source, variant: resolved.variant, reference: resolved.reference, anchor: rtl ? "right" : "left" };
6409
6586
  }
6410
6587
  }
@@ -6414,7 +6591,7 @@ function composeSlide(input, options = {}) {
6414
6591
  if (!slide[field] || Array.isArray(slide[field]) && !annotationText(slide[field])) continue;
6415
6592
  const requested = (field === "title" ? 54 : field === "tag" ? 16 : 25) * scale;
6416
6593
  const maxHeight = Math.max(height * (field === "title" ? 0.26 : field === "subtitle" ? 0.12 : 0.045), minSize * 1.22 + 2 * rasterPadding);
6417
- const box = { x: area.left + padding, y, width: area.right - area.left - padding * 2, height: maxHeight };
6594
+ const box = { x: area2.left + padding, y, width: area2.right - area2.left - padding * 2, height: maxHeight };
6418
6595
  const text2 = fitPlacedText(field, slide[field], annotationText(slide[field]), box, requested, minSize, `${path}.${field}`);
6419
6596
  box.height = Math.min(maxHeight, Math.max("richLines" in text2 ? text2.height : text2.lines.length * text2.lineHeight, text2.placement?.height ?? 0));
6420
6597
  if (furniture && box.y + box.height > bodyBottom + 0.01) diagnostics.push({ code: "text-overflow", path: `${path}.${field}`, message: "Repeated furniture leaves too little room for this heading. Change the header/footer or slide design." });
@@ -6458,7 +6635,7 @@ function composeSlide(input, options = {}) {
6458
6635
  ...caption ? { caption } : {}
6459
6636
  });
6460
6637
  }
6461
- const contentBox = { x: area.left + padding, y, width: area.right - area.left - padding * 2, height: Math.max(scale, bodyBottom - y) };
6638
+ const contentBox = { x: area2.left + padding, y, width: area2.right - area2.left - padding * 2, height: Math.max(scale, bodyBottom - y) };
6462
6639
  const collect = (host, basePath, depth = 0, ancestors = []) => {
6463
6640
  if (Array.isArray(host.blocks)) {
6464
6641
  if (depth >= MAX_COMPOSITION_DEPTH || ancestors.includes(host)) throw new RangeError(`Content groups must be acyclic and nest at most ${MAX_COMPOSITION_DEPTH} levels.`);
@@ -6579,29 +6756,29 @@ function composeSlide(input, options = {}) {
6579
6756
  return score;
6580
6757
  };
6581
6758
  const modeFor = (settings) => settings.mode ?? "auto";
6582
- const defaultColumns = (count, area2, settings) => {
6759
+ const defaultColumns = (count, area3, settings) => {
6583
6760
  const mode = modeFor(settings);
6584
- return mode === "column" ? 1 : mode === "row" ? Math.max(1, count) : settings.columns ?? Math.max(1, Math.min(count, Math.ceil(Math.sqrt(count * area2.width / area2.height / 1.6))));
6761
+ return mode === "column" ? 1 : mode === "row" ? Math.max(1, count) : settings.columns ?? Math.max(1, Math.min(count, Math.ceil(Math.sqrt(count * area3.width / area3.height / 1.6))));
6585
6762
  };
6586
6763
  const scoreNode = (node, box, settings, penalties) => {
6587
6764
  if (!node.children) return leafScore(node, box, settings, penalties);
6588
- const own3 = inheritedSettings(settings, node.composition), area2 = inset(box, own3), slotCount = Math.max(node.children.length, 0);
6589
- const cols = defaultColumns(slotCount, area2, own3);
6590
- const boxes = gridBoxes(slotCount, area2, cols, (own3.gap ?? 1 / 30) * Math.min(box.width, box.height), own3.weights ?? [], modeFor(own3) === "column");
6765
+ const own3 = inheritedSettings(settings, node.composition), area3 = inset(box, own3), slotCount = Math.max(node.children.length, 0);
6766
+ const cols = defaultColumns(slotCount, area3, own3);
6767
+ const boxes = gridBoxes(slotCount, area3, cols, (own3.gap ?? 1 / 30) * Math.min(box.width, box.height), own3.weights ?? [], modeFor(own3) === "column");
6591
6768
  return node.children.reduce((score, child, index) => score + scoreNode(child, boxes[index], own3, penalties), 0);
6592
6769
  };
6593
- const arrange = (nodes, area2, settings, reserved2 = 0, gapOverride, containerPath = path, recorded = true) => {
6770
+ const arrange = (nodes, area3, settings, reserved2 = 0, gapOverride, containerPath = path, recorded = true) => {
6594
6771
  const count = Math.max(nodes.length, reserved2);
6595
6772
  if (!count) return;
6596
- const mode = modeFor(settings), localGap = (settings.gap ?? 1 / 30) * Math.min(area2.width, area2.height);
6773
+ const mode = modeFor(settings), localGap = (settings.gap ?? 1 / 30) * Math.min(area3.width, area3.height);
6597
6774
  const actualGap = gapOverride ?? (settings === rootSettings ? gap : localGap);
6598
- let cols = defaultColumns(count, area2, settings);
6775
+ let cols = defaultColumns(count, area3, settings);
6599
6776
  const hasRegions = nodes.some((node) => node.region);
6600
6777
  const candidates = decisions && recorded ? [] : void 0;
6601
6778
  if (mode === "auto" && !hasRegions) {
6602
6779
  let best = Infinity;
6603
6780
  for (let candidate = 1; candidate <= Math.min(count, settings.columns ?? 6); candidate++) {
6604
- const boxes2 = gridBoxes(count, area2, candidate, actualGap, settings.weights ?? [], false);
6781
+ const boxes2 = gridBoxes(count, area3, candidate, actualGap, settings.weights ?? [], false);
6605
6782
  const emptySlots = (Math.ceil(count / candidate) * candidate - count) * 2;
6606
6783
  const penalties = candidates ? { cellProportions: 0, fontReduction: 0, textOverflow: 0, tableOverflow: 0, smallCells: 0, emptySlots } : void 0;
6607
6784
  const score = nodes.reduce((sum, node, i) => sum + scoreNode(node, boxes2[i], settings, penalties), 0) + emptySlots;
@@ -6619,16 +6796,21 @@ function composeSlide(input, options = {}) {
6619
6796
  ...hasRegions ? {} : { selectedColumns: cols },
6620
6797
  candidates: candidates ?? []
6621
6798
  });
6622
- const grid = gridGeometry(count, area2, cols, actualGap, settings.weights ?? [], mode === "column");
6623
- const mirrored = (box) => rtl ? { ...box, x: area2.x + area2.width - (box.x - area2.x) - box.width } : box;
6799
+ const grid = gridGeometry(count, area3, cols, actualGap, settings.weights ?? [], mode === "column");
6800
+ const mirrored = (box) => rtl ? { ...box, x: area3.x + area3.width - (box.x - area3.x) - box.width } : box;
6624
6801
  const boxes = grid.boxes.map(mirrored);
6625
- if (recorded && !hasRegions) flows.push({ path: containerPath, box: { ...area2 }, composition: { ...settings }, columns: rtl ? grid.columns.map((track) => ({ offset: area2.width - track.offset - track.size, size: track.size })) : grid.columns, rows: grid.rows, gap: grid.gap, itemCount: nodes.length, slotCount: count });
6802
+ if (recorded && !hasRegions) flows.push({ path: containerPath, box: { ...area3 }, composition: { ...settings }, columns: rtl ? grid.columns.map((track) => ({ offset: area3.width - track.offset - track.size, size: track.size })) : grid.columns, rows: grid.rows, gap: grid.gap, itemCount: nodes.length, slotCount: count });
6626
6803
  nodes.forEach((node, index) => {
6627
- const box = node.region ? mirrored(regionBox(node.region, area2, actualGap)) : boxes[index];
6804
+ const box = node.region ? mirrored(regionBox(node.region, area3, actualGap)) : boxes[index];
6628
6805
  placeNode(node, box, settings);
6629
6806
  });
6630
6807
  };
6631
6808
  let regionTag, templateCell = false;
6809
+ const composeChart = (node, box, settings) => {
6810
+ const resolved = resolveChartData(node.value, options.presentation, { path: node.path });
6811
+ const valueAxis = chartValueAxis(node.value, resolved, { width: box.width, height: box.height, scale, minFontSize: settings.minFontSize });
6812
+ return valueAxis ? { valueAxis } : void 0;
6813
+ };
6632
6814
  const placeNode = (node, box, settings, cards = hasCards, listColumns, metricReferenceHeight) => {
6633
6815
  if (node.children) {
6634
6816
  const own3 = inheritedSettings(settings, node.composition), inner = inset(box, own3);
@@ -6653,6 +6835,7 @@ function composeSlide(input, options = {}) {
6653
6835
  const columns2 = textValue !== void 0 && !internal ? listColumnsFor(node, box, settings, listColumns) : void 0;
6654
6836
  const text2 = internal ? body?.fit : columns2 ? columns2.length > 1 ? mergeListColumns(columns2) : columns2[0].text : textValue !== void 0 ? fitContent(node.field, node.value, textValue, box, contentNominalSize(node.field) * scale, snapFontSizeUp((settings.minFontSize ?? 16) * scale), node.path, node.payload.numbering) : void 0;
6655
6837
  const image = node.field === "image" ? composeImage(node.host ?? {}, node.hostPath ?? node.path, box, box, imageContext()) : void 0;
6838
+ const chart = node.field === "chart" ? composeChart(node, box, settings) : void 0;
6656
6839
  items.push({
6657
6840
  path: node.path,
6658
6841
  field: node.field,
@@ -6661,6 +6844,7 @@ function composeSlide(input, options = {}) {
6661
6844
  payload: node.payload,
6662
6845
  box: internal ? acceptedBox(box) : box,
6663
6846
  ...image ? { image } : {},
6847
+ ...chart ? { chart } : {},
6664
6848
  ...frameBox ? { frameBox } : {},
6665
6849
  text: text2,
6666
6850
  textStyle: body?.style ?? styleFor(node.field, node.path),
@@ -6877,9 +7061,9 @@ function composeSlide(input, options = {}) {
6877
7061
  const physical = (cell) => flip ? { ...cell, x: frame.x + frame.width - (cell.x - frame.x) - cell.width } : cell;
6878
7062
  const bleed = (cell) => {
6879
7063
  const near = (a, b) => Math.abs(a - b) < 0.01;
6880
- const left = near(cell.x, frame.x) ? area.left : cell.x, top = near(cell.y, frame.y) ? area.top : cell.y;
6881
- const right = near(cell.x + cell.width, frame.x + frame.width) ? area.right : cell.x + cell.width;
6882
- const bottom = near(cell.y + cell.height, frame.y + frame.height) ? area.bottom : cell.y + cell.height;
7064
+ const left = near(cell.x, frame.x) ? area2.left : cell.x, top = near(cell.y, frame.y) ? area2.top : cell.y;
7065
+ const right = near(cell.x + cell.width, frame.x + frame.width) ? area2.right : cell.x + cell.width;
7066
+ const bottom = near(cell.y + cell.height, frame.y + frame.height) ? area2.bottom : cell.y + cell.height;
6883
7067
  return { x: left, y: top, width: right - left, height: bottom - top };
6884
7068
  };
6885
7069
  const placeHeadings = (name, fields2) => {
@@ -6915,9 +7099,9 @@ function composeSlide(input, options = {}) {
6915
7099
  const slideComposition = record8(slide.composition);
6916
7100
  const overridden = ["mode", "columns", "weights"].some((key) => slideComposition[key] !== void 0) ? plan2.regions.find((region) => region.role === "primary" && region.flow !== "none")?.name : void 0;
6917
7101
  const settings = { ...composition };
6918
- const placeRegion = (region, units, area2) => {
7102
+ const placeRegion = (region, units, area3) => {
6919
7103
  regionTag = region.name === BELOW ? void 0 : region.name;
6920
- const cell = { ...area2, width: Math.max(scale, area2.width), height: Math.max(scale, area2.height) };
7104
+ const cell = { ...area3, width: Math.max(scale, area3.width), height: Math.max(scale, area3.height) };
6921
7105
  templateCell = true;
6922
7106
  try {
6923
7107
  const cards = hasCards && !region.bleed;
@@ -7065,4 +7249,4 @@ function resolveCanvasDimensions(input) {
7065
7249
  return { width, height };
7066
7250
  }
7067
7251
 
7068
- export { AUTO_LAYOUT, CAPTIONABLE_FIELDS, CAPTION_FONT_RATIO, CAPTION_MAX_RATIO, CATALOG_GROUP_PATTERN, CATALOG_REFERENCE_PATTERN, CHART_HIGHLIGHT_MUTED_MIN_CONTRAST, CHART_HIGHLIGHT_MUTED_MIX, CHART_SERIES_MIN_DIFFERENCE, CHART_SERIES_MIN_LIGHTNESS_STEP, CHART_TYPES, CITATION_MARKER_RAISE, CITATION_MARKER_SCALE, CODE_HIGHLIGHT_LANGUAGES, CODE_HIGHLIGHT_MAX_LENGTH, CODE_PANEL_BACKGROUND, CODE_PANEL_FOREGROUND, CODE_SYNTAX_MIN_CONTRAST, DARK_BACKGROUND_LUMINANCE, DEFAULT_CHART_LABEL_SEPARATOR, DEFAULT_FURNITURE_DATE_FORMAT, DEFAULT_VARIABLE_DATE_FORMAT, DESIGN_HINT_KEYS, ENGINE_DEFAULT_CHART_TYPES, ENGINE_DEFAULT_COLOR_SCHEME, ENGINE_DEFAULT_FONT_SCHEME, ENGINE_DEFAULT_THEME, FONT_SIZE_GRID_PER_PX, FOOTNOTE_MAX_RATIO, FURNITURE_GAP, FURNITURE_IMAGE_SHARE, HEADING_AREAS, LANGUAGES, LAYOUT_BODY_KINDS, LOGO_SHAPES, MAX_COMPOSITION_DEPTH, MAX_NUMBERING_LEVELS, MAX_NUMBERING_VALUE, MAX_REGION_BLOCKS, MAX_ROMAN_VALUE, MAX_TEMPLATE_TRACKS, METRIC_TREND_MIN_CONTRAST, METRIC_TREND_SHAPES, NUMBERING_STYLES, NUMBERING_SUFFIXES, OPFCatalogsOptionError, OPFCompositionError, OPFLayoutTemplateError, OPFUnresolvedReferenceError, OPFVariableError, PATTERN_PRESETS, PATTERN_PRESET_ALIASES, PATTERN_TILE_SIZE, PICTURE_BULLET_SCALE, PROMOTED_REGION_KEY, REGION_ANCHORS, REGION_FLOWS, REGION_KINDS, REGION_ROLES, RESERVED_REGION_NAMES, SLIDE_SCOPED_BUILTINS, SOCIAL_PLATFORMS, SURFACE_ALT_MIN_CONTRAST, SURFACE_ALT_MIX, THEME_DESIGN_KEYS, TIMELINE_OUTLINE_MIN_CONTRAST, TIMELINE_STATUSES, TIMELINE_TEXT_MIN_CONTRAST, VARIABLE_KINDS, allocateRows, annotationText, bindRegions, blockKind, captionSettings, catalogGroupDeclared, catalogGroupSource, catalogKinds, catalogRecords, catalogReferenceSites, chartColorForFill, chartHighlightColors, chartHighlightMarks, chartLabelText, chartNumber, chartNumberFixesByCell, chartOptionSupport, chartOptionTarget, chartPaletteForFill, checkCatalogsOption, citationMarkerText, codeHighlightBands, codeHighlightColors, codeHighlightLines, codeHighlightSlice, codeLineNumbers, codeLineRuns, codeSyntaxPalette, codeSyntaxPaletteForScheme, coerceVariableValue, collectCitations, colorContrast, composeLayoutAreas, composeSlide, datasetDiagnostics, defaultSlideBackground, dottedPath, embeddedCopy, fitImage, fitList, fitRichText, fitText, formatChartLabelNumber, formatChartLabelPercent, formatDataNumber, formatFurnitureDate, formatListNumber, formatVariableNumber, fromExcelNumberFormat, gridFlowShape, hasContentVariables, imageBackground, imageShape, inlineChartData, inlineDatasets, inlineTableData, instantiateForValidation, intrinsicImageAspect, intrinsicImageSize, isDarkColor, isDatasetRef, isLayoutTemplate, isRecord, isTemplate, isXYChartType, layoutCaption, layoutCode, layoutContent, layoutFootnotes, layoutFurniture, layoutMetric, layoutQuote, layoutRegion, layoutStructure, layoutTable, layoutTemplate, layoutTemplateIssues, layoutTimeline, layoutWatermark, listBuiltinVariables, listColumnBreaks, listNumbers, listVariables, measureText, measureTextOutline, metricTrendColor, metricTrendMark, metricTrendPoints, normalizeHexColor, normalizeLanguageFamily, numberFormatError, numberingAtLevel, numberingFindings, numberingStyleDraws, paragraphDirection, paragraphDirectionAt, parseReference, pathFor, patternBitmap, patternRuns, physicalAlignment, placeTextLines, placedImageBlocks, pointerPath, promotedRegionKeys, provenanceOf, readingRows, recordReferenceSites, referencesSlide, regionAccepts, regionRoleRank, registeredCatalog, resolveCanvasDimensions, resolveChartData, resolveChartOptions, resolveCodeLanguage, resolveColorRef, resolveColorRoles, resolveDesignHints, resolveDesignRecords, resolveFontFamilies, resolveFontScheme, resolveLogo, resolveNumbering, resolvePatternPreset, resolveReference, resolveScriptFonts, resolveSlideDirection, resolveSlideVariables, resolveSocialProfile, resolveTableData, resolveTextStyle, resolveVariables, rootNodes, scriptFontRole, sliceNumberedItems, slideCitations, slideTokenSpans, snapFontSizeDown, snapFontSizeUp, suggestChartNumberFix, surfaceAltColor, tableCellDisplayValue, tableGrid, tableRowBoundaries, textColorForFill, textWidthMeasurer, timelineMarkerShapes, timelineTextColor, toExcelNumberFormat, tokenizeCode, unresolvedReference, unusedDatasets, usesSlideBuiltin, variableDeclarations, visitContentPayloads, visualReadingOrder, walkCitationRuns, wrapText };
7252
+ export { AUTO_LAYOUT, CAPTIONABLE_FIELDS, CAPTION_FONT_RATIO, CAPTION_MAX_RATIO, CATALOG_GROUP_PATTERN, CATALOG_REFERENCE_PATTERN, CHART_HIGHLIGHT_MUTED_MIN_CONTRAST, CHART_HIGHLIGHT_MUTED_MIX, CHART_SERIES_MIN_DIFFERENCE, CHART_SERIES_MIN_LIGHTNESS_STEP, CHART_SERIES_TIER_SIZE, CHART_SERIES_TINT_MIX, CHART_TEXT_PX, CHART_TYPES, CITATION_MARKER_RAISE, CITATION_MARKER_SCALE, CODE_HIGHLIGHT_LANGUAGES, CODE_HIGHLIGHT_MAX_LENGTH, CODE_PANEL_BACKGROUND, CODE_PANEL_FOREGROUND, CODE_SYNTAX_MIN_CONTRAST, DARK_BACKGROUND_LUMINANCE, DEFAULT_CHART_LABEL_SEPARATOR, DEFAULT_FURNITURE_DATE_FORMAT, DEFAULT_VARIABLE_DATE_FORMAT, DESIGN_HINT_KEYS, ENGINE_DEFAULT_CHART_TYPES, ENGINE_DEFAULT_COLOR_SCHEME, ENGINE_DEFAULT_FONT_SCHEME, ENGINE_DEFAULT_THEME, FONT_SIZE_GRID_PER_PX, FOOTNOTE_MAX_RATIO, FURNITURE_GAP, FURNITURE_IMAGE_SHARE, HEADING_AREAS, LANGUAGES, LAYOUT_BODY_KINDS, LOGO_SHAPES, MAX_COMPOSITION_DEPTH, MAX_NUMBERING_LEVELS, MAX_NUMBERING_VALUE, MAX_REGION_BLOCKS, MAX_ROMAN_VALUE, MAX_TEMPLATE_TRACKS, METRIC_TREND_MIN_CONTRAST, METRIC_TREND_SHAPES, NUMBERING_STYLES, NUMBERING_SUFFIXES, OPFCatalogsOptionError, OPFCompositionError, OPFLayoutTemplateError, OPFUnresolvedReferenceError, OPFVariableError, PATTERN_PRESETS, PATTERN_PRESET_ALIASES, PATTERN_TILE_SIZE, PICTURE_BULLET_SCALE, PROMOTED_REGION_KEY, REGION_ANCHORS, REGION_FLOWS, REGION_KINDS, REGION_ROLES, RESERVED_REGION_NAMES, SLIDE_SCOPED_BUILTINS, SOCIAL_PLATFORMS, SURFACE_ALT_MIN_CONTRAST, SURFACE_ALT_MIX, THEME_DESIGN_KEYS, TIMELINE_OUTLINE_MIN_CONTRAST, TIMELINE_STATUSES, TIMELINE_TEXT_MIN_CONTRAST, VARIABLE_KINDS, allocateRows, annotationText, bindRegions, blockKind, captionSettings, catalogGroupDeclared, catalogGroupSource, catalogKinds, catalogRecords, catalogReferenceSites, chartColorForFill, chartHighlightColors, chartHighlightMarks, chartLabelText, chartNumber, chartNumberFixesByCell, chartOptionSupport, chartOptionTarget, chartPaletteForFill, chartSeriesPalette, chartTextSize, chartValueAxis, checkCatalogsOption, citationMarkerText, codeHighlightBands, codeHighlightColors, codeHighlightLines, codeHighlightSlice, codeLineNumbers, codeLineRuns, codeSyntaxPalette, codeSyntaxPaletteForScheme, coerceVariableValue, collectCitations, colorContrast, composeLayoutAreas, composeSlide, datasetDiagnostics, defaultSlideBackground, dottedPath, embeddedCopy, fitImage, fitList, fitRichText, fitText, formatChartLabelNumber, formatChartLabelPercent, formatDataNumber, formatFurnitureDate, formatListNumber, formatVariableNumber, fromExcelNumberFormat, gridFlowShape, hasContentVariables, imageBackground, imageShape, inlineChartData, inlineDatasets, inlineTableData, instantiateForValidation, intrinsicImageAspect, intrinsicImageSize, isDarkColor, isDatasetRef, isLayoutTemplate, isRecord, isTemplate, isXYChartType, layoutCaption, layoutCode, layoutContent, layoutFootnotes, layoutFurniture, layoutMetric, layoutQuote, layoutRegion, layoutStructure, layoutTable, layoutTemplate, layoutTemplateIssues, layoutTimeline, layoutWatermark, listBuiltinVariables, listColumnBreaks, listNumbers, listVariables, maxIntervalsFor, measureText, measureTextOutline, metricTrendColor, metricTrendMark, metricTrendPoints, niceScale, normalizeHexColor, normalizeLanguageFamily, numberFormatError, numberingAtLevel, numberingFindings, numberingStyleDraws, paragraphDirection, paragraphDirectionAt, parseReference, pathFor, patternBitmap, patternRuns, physicalAlignment, placeTextLines, placedImageBlocks, pointerPath, promotedRegionKeys, provenanceOf, readingRows, recordReferenceSites, referencesSlide, regionAccepts, regionRoleRank, registeredCatalog, resolveCanvasDimensions, resolveChartColors, resolveChartData, resolveChartOptions, resolveCodeLanguage, resolveColorRef, resolveColorRoles, resolveDesignHints, resolveDesignRecords, resolveFontFamilies, resolveFontScheme, resolveLogo, resolveNumbering, resolvePatternPreset, resolveReference, resolveScriptFonts, resolveSlideDirection, resolveSlideVariables, resolveSocialProfile, resolveTableData, resolveTextStyle, resolveVariables, rootNodes, scriptFontRole, sliceNumberedItems, slideCitations, slideTokenSpans, snapFontSizeDown, snapFontSizeUp, stackCategoryValues, suggestChartNumberFix, surfaceAltColor, tableCellDisplayValue, tableGrid, tableRowBoundaries, textColorForFill, textWidthMeasurer, timelineMarkerShapes, timelineTextColor, toExcelNumberFormat, tokenizeCode, unresolvedReference, unusedDatasets, usesSlideBuiltin, variableDeclarations, visitContentPayloads, visualReadingOrder, walkCitationRuns, wrapText };