graphein 0.20.0 → 0.22.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 (319) hide show
  1. package/dist/animation/animate.d.ts +6 -1
  2. package/dist/animation/animate.d.ts.map +1 -1
  3. package/dist/animation/animate.js +2 -2
  4. package/dist/animation/animate.js.map +2 -2
  5. package/dist/animation/env.d.ts +5 -0
  6. package/dist/animation/env.d.ts.map +1 -1
  7. package/dist/animation/env.js +4 -0
  8. package/dist/animation/env.js.map +2 -2
  9. package/dist/animation/index.d.ts +1 -0
  10. package/dist/animation/index.d.ts.map +1 -1
  11. package/dist/animation/index.js +1 -0
  12. package/dist/animation/index.js.map +2 -2
  13. package/dist/animation/stagger.d.ts +13 -0
  14. package/dist/animation/stagger.d.ts.map +1 -0
  15. package/dist/animation/stagger.js +13 -0
  16. package/dist/animation/stagger.js.map +7 -0
  17. package/dist/axes/draw.d.ts +5 -1
  18. package/dist/axes/draw.d.ts.map +1 -1
  19. package/dist/axes/draw.js +13 -1
  20. package/dist/axes/draw.js.map +2 -2
  21. package/dist/axes/morph.d.ts +111 -0
  22. package/dist/axes/morph.d.ts.map +1 -0
  23. package/dist/axes/morph.js +207 -0
  24. package/dist/axes/morph.js.map +7 -0
  25. package/dist/axes/overlay.d.ts.map +1 -1
  26. package/dist/axes/overlay.js +88 -25
  27. package/dist/axes/overlay.js.map +2 -2
  28. package/dist/axes/text.d.ts +2 -0
  29. package/dist/axes/text.d.ts.map +1 -1
  30. package/dist/axes/text.js +1 -0
  31. package/dist/axes/text.js.map +2 -2
  32. package/dist/axes/tickLabels.d.ts +2 -0
  33. package/dist/axes/tickLabels.d.ts.map +1 -1
  34. package/dist/axes/tickLabels.js +2 -2
  35. package/dist/axes/tickLabels.js.map +2 -2
  36. package/dist/charts/annotations.d.ts +9 -3
  37. package/dist/charts/annotations.d.ts.map +1 -1
  38. package/dist/charts/annotations.js +82 -27
  39. package/dist/charts/annotations.js.map +2 -2
  40. package/dist/charts/area.d.ts +37 -1
  41. package/dist/charts/area.d.ts.map +1 -1
  42. package/dist/charts/area.js +35 -17
  43. package/dist/charts/area.js.map +2 -2
  44. package/dist/charts/bar.d.ts +53 -0
  45. package/dist/charts/bar.d.ts.map +1 -1
  46. package/dist/charts/bar.js +117 -83
  47. package/dist/charts/bar.js.map +2 -2
  48. package/dist/charts/box.d.ts +31 -0
  49. package/dist/charts/box.d.ts.map +1 -1
  50. package/dist/charts/box.js +93 -70
  51. package/dist/charts/box.js.map +2 -2
  52. package/dist/charts/bubbleMap.d.ts +20 -0
  53. package/dist/charts/bubbleMap.d.ts.map +1 -0
  54. package/dist/charts/bubbleMap.js +951 -0
  55. package/dist/charts/bubbleMap.js.map +7 -0
  56. package/dist/charts/bullet.d.ts.map +1 -1
  57. package/dist/charts/bullet.js +69 -51
  58. package/dist/charts/bullet.js.map +2 -2
  59. package/dist/charts/calendarHeatmap.d.ts.map +1 -1
  60. package/dist/charts/calendarHeatmap.js +56 -19
  61. package/dist/charts/calendarHeatmap.js.map +2 -2
  62. package/dist/charts/candlestick.d.ts +40 -0
  63. package/dist/charts/candlestick.d.ts.map +1 -0
  64. package/dist/charts/candlestick.js +325 -0
  65. package/dist/charts/candlestick.js.map +7 -0
  66. package/dist/charts/choropleth.d.ts.map +1 -1
  67. package/dist/charts/choropleth.js +46 -67
  68. package/dist/charts/choropleth.js.map +2 -2
  69. package/dist/charts/combo.d.ts.map +1 -1
  70. package/dist/charts/combo.js +127 -27
  71. package/dist/charts/combo.js.map +3 -3
  72. package/dist/charts/dumbbell.d.ts.map +1 -1
  73. package/dist/charts/dumbbell.js +100 -31
  74. package/dist/charts/dumbbell.js.map +2 -2
  75. package/dist/charts/funnel.d.ts.map +1 -1
  76. package/dist/charts/funnel.js +93 -28
  77. package/dist/charts/funnel.js.map +3 -3
  78. package/dist/charts/gantt.d.ts +22 -0
  79. package/dist/charts/gantt.d.ts.map +1 -0
  80. package/dist/charts/gantt.js +564 -0
  81. package/dist/charts/gantt.js.map +7 -0
  82. package/dist/charts/gauge.d.ts.map +1 -1
  83. package/dist/charts/gauge.js +30 -4
  84. package/dist/charts/gauge.js.map +2 -2
  85. package/dist/charts/geo.d.ts +87 -0
  86. package/dist/charts/geo.d.ts.map +1 -0
  87. package/dist/charts/geo.js +140 -0
  88. package/dist/charts/geo.js.map +7 -0
  89. package/dist/charts/geometry.d.ts +20 -0
  90. package/dist/charts/geometry.d.ts.map +1 -0
  91. package/dist/charts/geometry.js +25 -0
  92. package/dist/charts/geometry.js.map +7 -0
  93. package/dist/charts/heatmap.d.ts.map +1 -1
  94. package/dist/charts/heatmap.js +58 -49
  95. package/dist/charts/heatmap.js.map +2 -2
  96. package/dist/charts/histogram.d.ts +1 -1
  97. package/dist/charts/histogram.d.ts.map +1 -1
  98. package/dist/charts/histogram.js +49 -31
  99. package/dist/charts/histogram.js.map +2 -2
  100. package/dist/charts/index.d.ts +35 -1
  101. package/dist/charts/index.d.ts.map +1 -1
  102. package/dist/charts/index.js +12 -0
  103. package/dist/charts/index.js.map +2 -2
  104. package/dist/charts/legibility.d.ts +38 -0
  105. package/dist/charts/legibility.d.ts.map +1 -0
  106. package/dist/charts/legibility.js +72 -0
  107. package/dist/charts/legibility.js.map +7 -0
  108. package/dist/charts/line.d.ts +39 -1
  109. package/dist/charts/line.d.ts.map +1 -1
  110. package/dist/charts/line.js +48 -16
  111. package/dist/charts/line.js.map +2 -2
  112. package/dist/charts/matrix.d.ts +2 -1
  113. package/dist/charts/matrix.d.ts.map +1 -1
  114. package/dist/charts/matrix.js +481 -319
  115. package/dist/charts/matrix.js.map +3 -3
  116. package/dist/charts/morphFrame.d.ts +83 -0
  117. package/dist/charts/morphFrame.d.ts.map +1 -0
  118. package/dist/charts/morphFrame.js +128 -0
  119. package/dist/charts/morphFrame.js.map +7 -0
  120. package/dist/charts/pie.d.ts.map +1 -1
  121. package/dist/charts/pie.js +89 -26
  122. package/dist/charts/pie.js.map +2 -2
  123. package/dist/charts/pieState.d.ts +27 -0
  124. package/dist/charts/pieState.d.ts.map +1 -0
  125. package/dist/charts/pieState.js +55 -0
  126. package/dist/charts/pieState.js.map +7 -0
  127. package/dist/charts/radar.d.ts +62 -0
  128. package/dist/charts/radar.d.ts.map +1 -0
  129. package/dist/charts/radar.js +912 -0
  130. package/dist/charts/radar.js.map +7 -0
  131. package/dist/charts/radialBar.d.ts +60 -0
  132. package/dist/charts/radialBar.d.ts.map +1 -0
  133. package/dist/charts/radialBar.js +708 -0
  134. package/dist/charts/radialBar.js.map +7 -0
  135. package/dist/charts/sankey.d.ts.map +1 -1
  136. package/dist/charts/sankey.js +223 -57
  137. package/dist/charts/sankey.js.map +3 -3
  138. package/dist/charts/scatter.d.ts +31 -0
  139. package/dist/charts/scatter.d.ts.map +1 -1
  140. package/dist/charts/scatter.js +48 -12
  141. package/dist/charts/scatter.js.map +2 -2
  142. package/dist/charts/slope.d.ts.map +1 -1
  143. package/dist/charts/slope.js +55 -3
  144. package/dist/charts/slope.js.map +2 -2
  145. package/dist/charts/sunburst.d.ts +14 -0
  146. package/dist/charts/sunburst.d.ts.map +1 -0
  147. package/dist/charts/sunburst.js +885 -0
  148. package/dist/charts/sunburst.js.map +7 -0
  149. package/dist/charts/table.d.ts +2 -1
  150. package/dist/charts/table.d.ts.map +1 -1
  151. package/dist/charts/table.js +214 -224
  152. package/dist/charts/table.js.map +3 -3
  153. package/dist/charts/tableView/canvas.d.ts +16 -1
  154. package/dist/charts/tableView/canvas.d.ts.map +1 -1
  155. package/dist/charts/tableView/canvas.js +361 -252
  156. package/dist/charts/tableView/canvas.js.map +3 -3
  157. package/dist/charts/tableView/conditional.d.ts +66 -40
  158. package/dist/charts/tableView/conditional.d.ts.map +1 -1
  159. package/dist/charts/tableView/conditional.js +163 -256
  160. package/dist/charts/tableView/conditional.js.map +3 -3
  161. package/dist/charts/tableView/dom.d.ts +26 -2
  162. package/dist/charts/tableView/dom.d.ts.map +1 -1
  163. package/dist/charts/tableView/dom.js +609 -269
  164. package/dist/charts/tableView/dom.js.map +3 -3
  165. package/dist/charts/tableView/layout.d.ts +22 -0
  166. package/dist/charts/tableView/layout.d.ts.map +1 -0
  167. package/dist/charts/tableView/layout.js +246 -0
  168. package/dist/charts/tableView/layout.js.map +7 -0
  169. package/dist/charts/tableView/sketch.d.ts +3 -2
  170. package/dist/charts/tableView/sketch.d.ts.map +1 -1
  171. package/dist/charts/tableView/sketch.js +2 -2
  172. package/dist/charts/tableView/sketch.js.map +2 -2
  173. package/dist/charts/tableView/sketchBar.d.ts +7 -0
  174. package/dist/charts/tableView/sketchBar.d.ts.map +1 -0
  175. package/dist/charts/tableView/sketchBar.js +32 -0
  176. package/dist/charts/tableView/sketchBar.js.map +7 -0
  177. package/dist/charts/tableView/sort.d.ts +9 -0
  178. package/dist/charts/tableView/sort.d.ts.map +1 -0
  179. package/dist/charts/tableView/sort.js +70 -0
  180. package/dist/charts/tableView/sort.js.map +7 -0
  181. package/dist/charts/tableView/sparkline.d.ts +30 -0
  182. package/dist/charts/tableView/sparkline.d.ts.map +1 -0
  183. package/dist/charts/tableView/sparkline.js +63 -0
  184. package/dist/charts/tableView/sparkline.js.map +7 -0
  185. package/dist/charts/tableView/style.d.ts +67 -0
  186. package/dist/charts/tableView/style.d.ts.map +1 -0
  187. package/dist/charts/tableView/style.js +131 -0
  188. package/dist/charts/tableView/style.js.map +7 -0
  189. package/dist/charts/tableView/types.d.ts +69 -46
  190. package/dist/charts/tableView/types.d.ts.map +1 -1
  191. package/dist/charts/tableView/types.js +22 -87
  192. package/dist/charts/tableView/types.js.map +2 -2
  193. package/dist/charts/tableView.d.ts +10 -5
  194. package/dist/charts/tableView.d.ts.map +1 -1
  195. package/dist/charts/tableView.js +12 -8
  196. package/dist/charts/tableView.js.map +2 -2
  197. package/dist/charts/treemap.d.ts.map +1 -1
  198. package/dist/charts/treemap.js +177 -68
  199. package/dist/charts/treemap.js.map +3 -3
  200. package/dist/charts/trendline.d.ts +13 -5
  201. package/dist/charts/trendline.d.ts.map +1 -1
  202. package/dist/charts/trendline.js +205 -56
  203. package/dist/charts/trendline.js.map +2 -2
  204. package/dist/charts/waterfall.d.ts.map +1 -1
  205. package/dist/charts/waterfall.js +76 -5
  206. package/dist/charts/waterfall.js.map +2 -2
  207. package/dist/index.d.ts +1 -1
  208. package/dist/index.js +1 -1
  209. package/dist/index.js.map +1 -1
  210. package/dist/interaction/cartesian.d.ts +4 -1
  211. package/dist/interaction/cartesian.d.ts.map +1 -1
  212. package/dist/interaction/cartesian.js +104 -34
  213. package/dist/interaction/cartesian.js.map +2 -2
  214. package/dist/interaction/controller.d.ts +29 -1
  215. package/dist/interaction/controller.d.ts.map +1 -1
  216. package/dist/interaction/controller.js +131 -8
  217. package/dist/interaction/controller.js.map +2 -2
  218. package/dist/interaction/focus.d.ts +23 -0
  219. package/dist/interaction/focus.d.ts.map +1 -0
  220. package/dist/interaction/focus.js +65 -0
  221. package/dist/interaction/focus.js.map +7 -0
  222. package/dist/interaction/tooltip.d.ts +6 -0
  223. package/dist/interaction/tooltip.d.ts.map +1 -1
  224. package/dist/interaction/tooltip.js +41 -16
  225. package/dist/interaction/tooltip.js.map +2 -2
  226. package/dist/interaction/types.d.ts +19 -0
  227. package/dist/interaction/types.d.ts.map +1 -1
  228. package/dist/interaction/veil.d.ts +25 -0
  229. package/dist/interaction/veil.d.ts.map +1 -0
  230. package/dist/interaction/veil.js +35 -0
  231. package/dist/interaction/veil.js.map +7 -0
  232. package/dist/pivot/pivot.d.ts +18 -0
  233. package/dist/pivot/pivot.d.ts.map +1 -1
  234. package/dist/pivot/pivot.js +46 -34
  235. package/dist/pivot/pivot.js.map +2 -2
  236. package/dist/render/chromeMotion.d.ts +65 -0
  237. package/dist/render/chromeMotion.d.ts.map +1 -0
  238. package/dist/render/chromeMotion.js +79 -0
  239. package/dist/render/chromeMotion.js.map +7 -0
  240. package/dist/render/pathSample.d.ts +24 -0
  241. package/dist/render/pathSample.d.ts.map +1 -0
  242. package/dist/render/pathSample.js +76 -0
  243. package/dist/render/pathSample.js.map +7 -0
  244. package/dist/render/transient.d.ts +18 -0
  245. package/dist/render/transient.d.ts.map +1 -0
  246. package/dist/render/transient.js +19 -0
  247. package/dist/render/transient.js.map +7 -0
  248. package/dist/runtime/candlestick.d.ts +112 -0
  249. package/dist/runtime/candlestick.d.ts.map +1 -0
  250. package/dist/runtime/candlestick.js +531 -0
  251. package/dist/runtime/candlestick.js.map +7 -0
  252. package/dist/runtime/cartesian.d.ts +14 -3
  253. package/dist/runtime/cartesian.d.ts.map +1 -1
  254. package/dist/runtime/cartesian.js.map +2 -2
  255. package/dist/runtime/chartAnimation.d.ts +54 -7
  256. package/dist/runtime/chartAnimation.d.ts.map +1 -1
  257. package/dist/runtime/chartAnimation.js +146 -28
  258. package/dist/runtime/chartAnimation.js.map +2 -2
  259. package/dist/runtime/chartRuntime.d.ts +42 -0
  260. package/dist/runtime/chartRuntime.d.ts.map +1 -1
  261. package/dist/runtime/chartRuntime.js +196 -30
  262. package/dist/runtime/chartRuntime.js.map +2 -2
  263. package/dist/runtime/dashboardDom.d.ts.map +1 -1
  264. package/dist/runtime/dashboardDom.js +45 -0
  265. package/dist/runtime/dashboardDom.js.map +2 -2
  266. package/dist/runtime/facet.d.ts +1 -1
  267. package/dist/runtime/facet.d.ts.map +1 -1
  268. package/dist/runtime/gantt.d.ts +137 -0
  269. package/dist/runtime/gantt.d.ts.map +1 -0
  270. package/dist/runtime/gantt.js +647 -0
  271. package/dist/runtime/gantt.js.map +7 -0
  272. package/dist/runtime/morph.d.ts +33 -0
  273. package/dist/runtime/morph.d.ts.map +1 -0
  274. package/dist/runtime/morph.js +332 -0
  275. package/dist/runtime/morph.js.map +7 -0
  276. package/dist/runtime/radar.d.ts +75 -0
  277. package/dist/runtime/radar.d.ts.map +1 -0
  278. package/dist/runtime/radar.js +201 -0
  279. package/dist/runtime/radar.js.map +7 -0
  280. package/dist/runtime/radialBar.d.ts +81 -0
  281. package/dist/runtime/radialBar.d.ts.map +1 -0
  282. package/dist/runtime/radialBar.js +125 -0
  283. package/dist/runtime/radialBar.js.map +7 -0
  284. package/dist/runtime/report/constants.d.ts +2 -2
  285. package/dist/runtime/report/constants.d.ts.map +1 -1
  286. package/dist/runtime/runtimeShared.d.ts +3 -3
  287. package/dist/runtime/runtimeShared.d.ts.map +1 -1
  288. package/dist/runtime/sunburst.d.ts +74 -0
  289. package/dist/runtime/sunburst.d.ts.map +1 -0
  290. package/dist/runtime/sunburst.js +150 -0
  291. package/dist/runtime/sunburst.js.map +7 -0
  292. package/dist/runtime/wire.d.ts.map +1 -1
  293. package/dist/runtime/wire.js +3 -1
  294. package/dist/runtime/wire.js.map +2 -2
  295. package/dist/shape/arc.d.ts +15 -2
  296. package/dist/shape/arc.d.ts.map +1 -1
  297. package/dist/shape/arc.js +204 -32
  298. package/dist/shape/arc.js.map +2 -2
  299. package/dist/spec/chartDefinitions.d.ts +6 -0
  300. package/dist/spec/chartDefinitions.d.ts.map +1 -1
  301. package/dist/spec/chartDefinitions.js +7 -1
  302. package/dist/spec/chartDefinitions.js.map +2 -2
  303. package/dist/spec/templates.d.ts.map +1 -1
  304. package/dist/spec/templates.js +177 -2
  305. package/dist/spec/templates.js.map +2 -2
  306. package/dist/spec/types.d.ts +258 -6
  307. package/dist/spec/types.d.ts.map +1 -1
  308. package/dist/spec/types.js +6 -0
  309. package/dist/spec/types.js.map +2 -2
  310. package/dist/spec/validate/charts.js +147 -15
  311. package/dist/spec/validate/charts.js.map +2 -2
  312. package/dist/spec/validate/common.d.ts +6 -0
  313. package/dist/spec/validate/common.d.ts.map +1 -1
  314. package/dist/spec/validate/overlays.js +2 -2
  315. package/dist/spec/validate/overlays.js.map +2 -2
  316. package/dist/spec/validate.data.d.ts.map +1 -1
  317. package/dist/spec/validate.data.js +8 -3
  318. package/dist/spec/validate.data.js.map +2 -2
  319. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/charts/tableView/dom.ts"],
4
- "sourcesContent": ["import { recordDomLabels } from '../../render/labelLedger';\nimport { applyConditionalFormatting, applyNegativeStyle, gridBorderColor, rowBackground, setCellBaseStyles } from './conditional';\nimport { BuildTableOptions, SKETCH_BORDER_RADIUS, computeFittedWidths, densityMetrics, normalizedHeaderRows, clampInt, setStyles, leftOffset, formatDisplayValue } from './types';\n\nlet cachedScrollbarWidth: number | null = null;\nexport function buildTable(opts: BuildTableOptions): void {\n const { container, rect, tokens } = opts;\n // When the body is taller than the container a vertical scrollbar appears and\n // eats horizontal space; reserve its (platform-specific) width so the last\n // column isn't clipped behind a spurious horizontal scrollbar.\n const reserve = willScrollVertically(opts) ? scrollbarWidth() : 0;\n const available = Math.max(0, rect.width - 2 - reserve);\n opts.widths = computeFittedWidths(opts.columns, available);\n const tableWidth = Math.max(available, sumWidths(opts.widths));\n setStyles(container, {\n position: 'absolute',\n left: `${rect.x}px`,\n top: `${rect.y}px`,\n width: `${Math.max(0, rect.width)}px`,\n height: `${Math.max(0, rect.height)}px`,\n overflow: 'auto',\n pointerEvents: 'auto',\n boxSizing: 'border-box',\n border: `1px solid ${opts.sketch ? 'transparent' : tokens.color.border}`,\n borderRadius: opts.sketch ? SKETCH_BORDER_RADIUS : `${tokens.radius.sm}px`,\n background: tokens.color.background,\n });\n\n container.replaceChildren();\n\n const table = document.createElement('table');\n table.setAttribute('role', 'table');\n setStyles(table, {\n width: `${tableWidth}px`,\n minWidth: '100%',\n borderCollapse: 'separate',\n borderSpacing: '0',\n tableLayout: 'fixed',\n fontFamily: tokens.font.family,\n fontSize: `${tokens.font.size.small}px`,\n lineHeight: '1.35',\n color: tokens.color.text,\n });\n\n table.appendChild(buildColGroup(opts.widths));\n table.appendChild(buildHeader(opts));\n table.appendChild(buildBody(opts));\n const footer = buildFooter(opts);\n if (footer) table.appendChild(footer);\n container.appendChild(table);\n opts.refreshEvidence = () => recordTableDom(opts, table);\n opts.refreshEvidence();\n}\n\nfunction recordTableDom(opts: BuildTableOptions, table: HTMLTableElement): void {\n if (!opts.evidence) return;\n const metrics = densityMetrics(opts.density);\n const host = opts.container.getBoundingClientRect();\n const origin = { x: host.left - opts.rect.x, y: host.top - opts.rect.y };\n const rowHeight = opts.visibleRange?.rowHeight ?? metrics.rowHeight;\n const headerHeight = normalizedHeaderRows(opts).length * metrics.headerHeight;\n const first = opts.visibleRange ? clampInt(opts.visibleRange.start, 0, opts.rowCount) : 0;\n const last = opts.visibleRange ? clampInt(opts.visibleRange.end, first, opts.rowCount) : opts.rowCount;\n recordTableDataEvidence(opts, first, last);\n const bodyRows = table.tBodies[0]?.rows;\n if (!bodyRows) return;\n let rowIndex = first;\n for (let i = 0; i < bodyRows.length; i++) {\n const tr = bodyRows[i];\n if (tr.getAttribute('aria-hidden') === 'true') continue;\n let x = opts.rect.x - opts.container.scrollLeft;\n for (let colIndex = 0; colIndex < tr.cells.length; colIndex++) {\n const td = tr.cells[colIndex];\n const actual = td.getBoundingClientRect();\n const width = opts.widths?.[colIndex] ?? 0;\n const measured = actual.width > 0 && actual.height > 0;\n if (!measured) opts.evidence.partial('geometry', 'text');\n const box = measured ? { x: actual.left - origin.x, y: actual.top - origin.y, width: actual.width, height: actual.height } :\n { x, y: opts.rect.y + headerHeight + rowIndex * rowHeight - opts.container.scrollTop, width, height: rowHeight };\n const color = td.style.color || opts.tokens.color.text;\n const background = td.style.backgroundColor || opts.tokens.color.background;\n const value = opts.getCell(rowIndex, colIndex);\n if (opts.dataRepresentation !== 'aggregate' ||\n (colIndex >= (opts.rowHeaderSpan ?? 0) && value.raw != null && Number.isFinite(value.raw))) {\n opts.evidence.mark('cell', box.x, box.y, box.width, box.height, color, 1, opts.rect, 1, background);\n }\n if (measured) recordDomLabels(opts.labels, td, origin, background, 'data-label', undefined, opts.rect);\n x += width;\n }\n rowIndex++;\n }\n for (const th of Array.from(table.querySelectorAll('th'))) {\n if (!recordDomLabels(opts.labels, th, origin, opts.tokens.color.surface, 'axis-label', '/columns', opts.rect)) opts.evidence.partial('text');\n }\n}\n\nfunction recordTableDataEvidence(opts: BuildTableOptions, first: number, last: number): void {\n if (!opts.evidence) return;\n if (opts.dataRepresentation === 'rows') {\n opts.evidence.data(opts.columns.length ? last - first : 0, 'rows', 0,\n opts.columns.length ? opts.rowCount - (last - first) : 0);\n } else if (opts.visibleRange && opts.dataRepresentation === 'aggregate') {\n const deferred = opts.columns.length ? Math.max(0, opts.rowCount - (last - first)) : 0;\n opts.evidence.data(opts.sourceRepresentedRows ?? Math.max(0, opts.evidence.snapshot().data.inputRows - deferred), 'aggregate', 0, deferred);\n }\n}\nfunction scrollbarWidth(): number {\n if (cachedScrollbarWidth != null) return cachedScrollbarWidth;\n if (typeof document === 'undefined' || !document.body) return 0;\n const probe = document.createElement('div');\n probe.style.cssText =\n 'position:absolute;top:-9999px;width:100px;height:100px;overflow:scroll;visibility:hidden';\n document.body.appendChild(probe);\n cachedScrollbarWidth = probe.offsetWidth - probe.clientWidth;\n probe.remove();\n return cachedScrollbarWidth;\n}\n\n/** Predicted total content height, used to decide whether the body will scroll. */\nfunction contentHeight(opts: BuildTableOptions): number {\n const headerRows = opts.headerRows?.length ?? 1;\n const metrics = densityMetrics(opts.density);\n const rowHeight = opts.visibleRange?.rowHeight ?? metrics.rowHeight;\n return headerRows * metrics.headerHeight + opts.rowCount * rowHeight + (opts.footerRow ? metrics.rowHeight : 0);\n}\n\nfunction willScrollVertically(opts: BuildTableOptions): boolean {\n return contentHeight(opts) > opts.rect.height + 1;\n}\n\nfunction sumWidths(widths: readonly number[]): number {\n return widths.reduce((sum, w) => sum + w, 0);\n}\n\nfunction buildColGroup(widths: readonly number[]): HTMLTableColElement {\n const colgroup = document.createElement('colgroup');\n for (const width of widths) {\n const col = document.createElement('col');\n col.style.width = `${width}px`;\n colgroup.appendChild(col);\n }\n return colgroup;\n}\n\nfunction buildHeader(opts: BuildTableOptions): HTMLTableSectionElement {\n const thead = document.createElement('thead');\n if (opts.headerRows) {\n opts.headerRows.forEach((row, rowIndex) => {\n const tr = document.createElement('tr');\n for (const cell of row) {\n const th = makeHeaderCell(opts, cell.title, cell.colIndex, cell.align, rowIndex);\n if (cell.colSpan && cell.colSpan > 1) th.colSpan = cell.colSpan;\n if (cell.rowSpan && cell.rowSpan > 1) th.rowSpan = cell.rowSpan;\n tr.appendChild(th);\n }\n thead.appendChild(tr);\n });\n return thead;\n }\n\n const tr = document.createElement('tr');\n opts.columns.forEach((column, colIndex) => {\n tr.appendChild(makeHeaderCell(opts, column.title, colIndex, column.align));\n });\n thead.appendChild(tr);\n return thead;\n}\n\nfunction makeHeaderCell(\n opts: BuildTableOptions,\n title: string,\n colIndex: number | undefined,\n align: 'left' | 'center' | 'right' | undefined,\n rowIndex = 0,\n): HTMLTableCellElement {\n const th = document.createElement('th');\n const metrics = densityMetrics(opts.density);\n th.scope = 'col';\n th.textContent = title;\n const isSorted = colIndex != null && opts.sortState?.col === colIndex;\n if (isSorted) th.setAttribute('aria-sort', opts.sortState?.dir === 'desc' ? 'descending' : 'ascending');\n setCellBaseStyles(th, opts.tokens, align ?? 'left', opts.stickyHeader !== false, metrics.padding, gridBorderColor(opts));\n setStyles(th, {\n top: `${rowIndex * metrics.headerHeight}px`,\n zIndex: '4',\n background: opts.tokens.color.surface,\n color: opts.tokens.color.text,\n fontWeight: String(opts.tokens.font.weight.bold),\n borderBottom: `1px solid ${gridBorderColor(opts)}`,\n userSelect: 'none',\n height: `${metrics.headerHeight}px`,\n });\n\n if (colIndex != null && opts.onSort && opts.columns[colIndex]?.sortable !== false) {\n th.textContent = '';\n const button = document.createElement('button');\n button.type = 'button';\n button.addEventListener('click', () => opts.onSort?.(colIndex));\n setStyles(button, {\n all: 'unset',\n boxSizing: 'border-box',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: align === 'right' ? 'flex-end' : align === 'center' ? 'center' : 'flex-start',\n gap: '5px',\n width: '100%',\n cursor: 'pointer',\n color: 'inherit',\n font: 'inherit',\n });\n const label = document.createElement('span');\n label.textContent = title;\n label.style.overflow = 'hidden';\n label.style.textOverflow = 'ellipsis';\n const glyph = document.createElement('span');\n glyph.textContent = isSorted ? (opts.sortState?.dir === 'desc' ? '\u2193' : '\u2191') : '';\n glyph.setAttribute('aria-hidden', 'true');\n glyph.style.color = opts.tokens.color.textMuted;\n button.append(label, glyph);\n th.appendChild(button);\n }\n\n applyStickyColumn(th, opts, colIndex, true);\n return th;\n}\n\nfunction buildBody(opts: BuildTableOptions): HTMLTableSectionElement {\n const tbody = document.createElement('tbody');\n const range = opts.visibleRange;\n const start = range ? clampInt(range.start, 0, opts.rowCount) : 0;\n const end = range ? clampInt(range.end, start, opts.rowCount) : opts.rowCount;\n if (range && start > 0) tbody.appendChild(makeSpacerRow(opts, start * range.rowHeight));\n for (let rowIndex = start; rowIndex < end; rowIndex += 1) {\n tbody.appendChild(makeBodyRow(opts, rowIndex, range?.rowHeight));\n }\n if (range && end < opts.rowCount) {\n tbody.appendChild(makeSpacerRow(opts, (opts.rowCount - end) * range.rowHeight));\n }\n return tbody;\n}\n\nfunction makeBodyRow(opts: BuildTableOptions, rowIndex: number, rowHeight?: number): HTMLTableRowElement {\n const tr = document.createElement('tr');\n const cls = opts.rowClass?.(rowIndex) ?? 'normal';\n const metrics = densityMetrics(opts.density);\n if (rowHeight) tr.style.height = `${rowHeight}px`;\n opts.columns.forEach((column, colIndex) => {\n const td = document.createElement('td');\n const cell = opts.getCell(rowIndex, colIndex);\n const rowBg = rowBackground(opts, rowIndex, cls);\n setCellBaseStyles(td, opts.tokens, column.align, false, metrics.padding, gridBorderColor(opts));\n setStyles(td, {\n position: colIndex < (opts.rowHeaderSpan ?? 0) ? 'sticky' : 'relative',\n background: rowBg,\n fontWeight: cls === 'normal' ? String(opts.tokens.font.weight.normal) : String(opts.tokens.font.weight.bold),\n color: opts.tokens.color.text,\n borderBottom: `1px solid ${gridBorderColor(opts)}`,\n height: rowHeight ? `${rowHeight}px` : `${metrics.rowHeight}px`,\n whiteSpace: column.wrap === true ? 'normal' : 'nowrap',\n });\n const indent = opts.cellIndent?.(rowIndex, colIndex) ?? 0;\n if (indent > 0) td.style.paddingLeft = `${metrics.paddingX + indent}px`;\n applyConditionalFormatting(td, opts, column, colIndex, cell, rowBg, rowIndex);\n if (td.childNodes.length === 0) {\n td.textContent = formatDisplayValue(cell.value, column);\n applyNegativeStyle(td, cell.value, column);\n }\n applyStickyColumn(td, opts, colIndex, false);\n tr.appendChild(td);\n });\n return tr;\n}\n\nfunction buildFooter(opts: BuildTableOptions): HTMLTableSectionElement | null {\n if (!opts.footerRow) return null;\n const tfoot = document.createElement('tfoot');\n const tr = document.createElement('tr');\n const metrics = densityMetrics(opts.density);\n opts.columns.forEach((column, colIndex) => {\n const td = document.createElement('td');\n const cell = opts.footerRow?.cells[colIndex] ?? { value: null, raw: null };\n setCellBaseStyles(td, opts.tokens, column.align, false, metrics.padding, gridBorderColor(opts));\n setStyles(td, {\n position: colIndex < (opts.rowHeaderSpan ?? 0) ? 'sticky' : 'sticky',\n bottom: '0',\n zIndex: colIndex < (opts.rowHeaderSpan ?? 0) ? '5' : '4',\n background: opts.tokens.color.surface,\n color: opts.tokens.color.text,\n fontWeight: String(opts.tokens.font.weight.bold),\n borderTop: `1px solid ${gridBorderColor(opts)}`,\n borderBottom: `1px solid ${gridBorderColor(opts)}`,\n height: `${metrics.rowHeight}px`,\n whiteSpace: column.wrap === true ? 'normal' : 'nowrap',\n });\n td.textContent = cell.label ? String(cell.value ?? '') : formatDisplayValue(cell.value, column);\n applyNegativeStyle(td, cell.value, column);\n applyStickyColumn(td, opts, colIndex, false);\n tr.appendChild(td);\n });\n tfoot.appendChild(tr);\n return tfoot;\n}\n\nfunction makeSpacerRow(opts: BuildTableOptions, height: number): HTMLTableRowElement {\n const tr = document.createElement('tr');\n tr.setAttribute('aria-hidden', 'true');\n const td = document.createElement('td');\n td.colSpan = Math.max(1, opts.columns.length);\n setStyles(td, {\n height: `${Math.max(0, height)}px`,\n padding: '0',\n border: '0',\n background: opts.tokens.color.background,\n });\n tr.appendChild(td);\n return tr;\n}\nfunction applyStickyColumn(\n cell: HTMLTableCellElement,\n opts: BuildTableOptions,\n colIndex: number | undefined,\n isHeader: boolean,\n): void {\n if (colIndex == null || colIndex >= (opts.rowHeaderSpan ?? 0)) return;\n cell.style.position = 'sticky';\n cell.style.left = `${leftOffset(opts, colIndex)}px`;\n cell.style.zIndex = isHeader ? '6' : '3';\n}\n"],
5
- "mappings": "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",
6
- "names": ["tr"]
4
+ "sourcesContent": ["import { recordDomLabels } from '../../render/labelLedger';\nimport { measureText } from '../../render/text';\nimport {\n BAR_LANE_ALPHA,\n BAR_OVERLAY_ALPHA,\n barFill,\n barTrack,\n buildColumnFormatter,\n negativeTextColor,\n type CellPaint,\n type ColumnFormatter,\n} from './conditional';\nimport { buildSketchDataBar } from './sketchBar';\nimport { createSketchGridCanvas, paintSketchGridOverlay } from './sketch';\nimport { columnOffsets, layoutColumns, type ColumnLayout } from './layout';\nimport { fontFor, resolveTableStyle, rowBackground, tableStylesheet, type TableStyle } from './style';\nimport { sparklinePath } from './sparkline';\nimport {\n SKETCH_BORDER_RADIUS,\n cellText,\n clampInt,\n defaultRowInfo,\n normalizedHeaderRows,\n setStyles,\n sumWidths,\n type RowKind,\n type TableViewInput,\n type ViewCell,\n type ViewColumn,\n type ViewRowInfo,\n} from './types';\n\nexport interface DomTableOptions extends TableViewInput {\n /** The overlay layer that hosts the scroll container. */\n container: HTMLElement;\n stickyHeader?: boolean;\n onSort?(colIndex: number): void;\n onToggle?(rowIndex: number): void;\n onRowClick?(rowIndex: number, colIndex: number, event: Event): void;\n /** Rows the table measures for column widths (all hierarchy rows of a matrix). */\n measure?: Pick<TableViewInput, 'rowCount' | 'getCell' | 'rowInfo'>;\n scrollTop?: number;\n scrollLeft?: number;\n onScroll?(top: number, left: number): void;\n}\n\nexport interface DomTableView {\n readonly host: HTMLDivElement;\n readonly widths: number[];\n /** Rebind header, rows and footer to new input; column widths stay stable unless `relayout`. */\n update(next: DomTableOptions, relayout?: boolean): void;\n /** Re-measure the live DOM into the evidence/label ledgers (render report). */\n recordEvidence(): void;\n}\n\n/** Tables with at most this many rows and body cells render every row (no windowing). */\nexport const RENDER_ALL_CELLS = 2400;\nexport const RENDER_ALL_ROWS = 250;\nconst BUFFER_ROWS = 6;\nconst DEFAULT_FORMAT_KINDS: readonly RowKind[] = ['leaf'];\n\nlet scopeSeq = 0;\nlet cachedScrollbarWidth: number | null = null;\n\ninterface CellSlot {\n el: HTMLTableCellElement;\n kind: 'text' | 'bar' | 'icon' | 'spark' | 'rh';\n val?: HTMLSpanElement;\n bar?: HTMLElement;\n zero?: HTMLDivElement;\n icon?: HTMLSpanElement;\n toggle?: HTMLButtonElement;\n pad?: HTMLSpanElement;\n styled: boolean;\n titled: boolean;\n}\n\ninterface RowSlot {\n tr: HTMLTableRowElement;\n cells: CellSlot[];\n row: number;\n}\n\nexport function mountTable(opts: DomTableOptions): DomTableView {\n return new TableDom(opts);\n}\n\nclass TableDom implements DomTableView {\n readonly host: HTMLDivElement;\n widths: number[] = [];\n private opts: DomTableOptions;\n private readonly scope = `gtv-${++scopeSeq}`;\n private style!: TableStyle;\n private formatters: Array<ColumnFormatter | null> = [];\n private layout!: ColumnLayout;\n private offsets: number[] = [];\n private baseClass: string[] = [];\n private table!: HTMLTableElement;\n private tbody!: HTMLTableSectionElement;\n private topSpacer!: HTMLTableRowElement;\n private bottomSpacer!: HTMLTableRowElement;\n private pool: RowSlot[] = [];\n private start = 0;\n private end = 0;\n private windowed = false;\n private frame = 0;\n private mounted = false;\n private headerRowCount = 1;\n private hierarchy = false;\n private bodyFont = '';\n private boldFont = '';\n private readonly textWidths = new Map<string, number>();\n private sketchCanvas: ReturnType<typeof createSketchGridCanvas> | null = null;\n\n constructor(opts: DomTableOptions) {\n this.opts = opts;\n this.host = document.createElement('div');\n this.host.className = `graphein-table ${this.scope}`;\n opts.container.appendChild(this.host);\n this.host.addEventListener('scroll', () => this.onScroll(), { passive: true });\n this.build(true);\n }\n\n update(next: DomTableOptions, relayout = false): void {\n this.opts = next;\n this.build(relayout || next.columns.length !== this.widths.length);\n }\n\n private build(relayout: boolean): void {\n const o = this.opts;\n this.style = resolveTableStyle(o.tokens, o.density, o.gridlines);\n const m = this.style.metrics;\n this.bodyFont = fontFor(this.style, this.style.weight.normal);\n this.boldFont = fontFor(this.style, this.style.weight.bold);\n this.formatters = o.formatters ?? o.columns.map((column, i) =>\n buildColumnFormatter(column.conditionalFormat, o.conditionalDomains?.[i] ?? null, o.tokens, this.style.color.background));\n const headerRows = normalizedHeaderRows(o);\n this.headerRowCount = headerRows.length;\n this.hierarchy = this.hasHierarchy();\n const contentHeight = headerRows.length * m.headerHeight + o.rowCount * m.rowHeight + (o.footerRow ? m.rowHeight : 0) + 2;\n const scrollsY = contentHeight > o.rect.height + 1;\n if (relayout || !this.layout) {\n const available = Math.max(0, o.rect.width - 2 - (scrollsY ? scrollbarWidth() : 0));\n const measureInput = o.measure ? { ...o, ...o.measure } : o;\n this.layout = layoutColumns(measureInput, this.style, this.formatters, available, 'scroll');\n }\n this.widths = this.layout.widths;\n o.widths = this.widths;\n this.offsets = columnOffsets(this.widths);\n this.windowed = o.rowCount > RENDER_ALL_ROWS || o.rowCount * Math.max(1, o.columns.length) > RENDER_ALL_CELLS;\n const frozen = Math.min(o.frozenColumns ?? 0, o.columns.length);\n this.baseClass = o.columns.map((column, i) => columnClass(column, i, frozen, this.windowed));\n\n setStyles(this.host, {\n position: 'absolute',\n left: `${o.rect.x}px`,\n top: `${o.rect.y}px`,\n width: `${Math.max(0, o.rect.width)}px`,\n maxHeight: `${Math.max(0, o.rect.height)}px`,\n overflow: 'auto',\n pointerEvents: 'auto',\n boxSizing: 'border-box',\n border: `1px solid ${o.sketch ? 'transparent' : o.tokens.color.border}`,\n borderRadius: o.sketch ? SKETCH_BORDER_RADIUS : `${this.style.radius}px`,\n background: this.style.color.background,\n overscrollBehavior: 'contain',\n });\n\n const sheet = document.createElement('style');\n sheet.textContent = tableStylesheet(this.style, {\n scope: this.scope,\n stickyHeader: o.stickyHeader !== false,\n frozenOffsets: this.offsets.slice(0, frozen),\n sketch: Boolean(o.sketch),\n });\n const table = document.createElement('table');\n table.setAttribute('role', 'table');\n table.style.width = `${sumWidths(this.widths)}px`;\n if (this.windowed) table.setAttribute('aria-rowcount', String(headerRows.length + o.rowCount + (o.footerRow ? 1 : 0)));\n table.appendChild(this.buildColgroup());\n table.appendChild(this.buildHeader(headerRows, frozen));\n this.tbody = document.createElement('tbody');\n this.topSpacer = spacerRow(o.columns.length);\n this.bottomSpacer = spacerRow(o.columns.length);\n this.tbody.addEventListener('click', (event) => this.onBodyClick(event));\n this.tbody.addEventListener('keydown', (event) => this.onBodyKey(event));\n this.host.classList.toggle('gtv-pick', Boolean(o.onRowClick));\n table.appendChild(this.tbody);\n const footer = this.buildFooter(headerRows.length);\n if (footer) table.appendChild(footer);\n this.table = table;\n this.pool = [];\n this.start = 0;\n this.end = 0;\n // First mount restores a persisted position; rebuilds keep the live one.\n const restore = this.mounted\n ? { top: this.host.scrollTop || 0, left: this.host.scrollLeft || 0 }\n : { top: o.scrollTop ?? 0, left: o.scrollLeft ?? 0 };\n this.mounted = true;\n this.host.replaceChildren(sheet, table);\n this.renderWindow(true, restore.top);\n if (this.host.scrollTop !== restore.top) this.host.scrollTop = restore.top;\n if (this.host.scrollLeft !== restore.left) this.host.scrollLeft = restore.left;\n this.mountSketch(Math.min(o.rect.height, contentHeight));\n this.recordEvidence();\n }\n\n private buildColgroup(): HTMLTableColElement {\n const colgroup = document.createElement('colgroup');\n for (const width of this.widths) {\n const col = document.createElement('col');\n col.style.width = `${width}px`;\n colgroup.appendChild(col);\n }\n return colgroup;\n }\n\n private buildHeader(headerRows: ReturnType<typeof normalizedHeaderRows>, frozen: number): HTMLTableSectionElement {\n const o = this.opts;\n const m = this.style.metrics;\n const thead = document.createElement('thead');\n headerRows.forEach((row, rowIndex) => {\n const tr = document.createElement('tr');\n let cursor = 0;\n for (const cell of row) {\n const start = cell.colIndex ?? cursor;\n const span = Math.max(1, cell.colSpan ?? 1);\n cursor = start + span;\n const th = document.createElement('th');\n th.scope = span > 1 ? 'colgroup' : 'col';\n if (span > 1) th.colSpan = span;\n if ((cell.rowSpan ?? 1) > 1) th.rowSpan = cell.rowSpan!;\n const classes: string[] = [];\n const align = cell.align ?? 'left';\n if (align !== 'left') classes.push(align === 'right' ? 'a-r' : 'a-c');\n if (cell.colIndex == null && span > 1) classes.push('gtv-hg');\n if (start + span <= frozen) classes.push('fz', `fz${start}`);\n if (start > 0 && o.columns[start]?.groupStart) classes.push('gs');\n th.style.top = o.stickyHeader === false ? '' : `${rowIndex * m.headerHeight}px`;\n if ((cell.rowSpan ?? 1) > 1) th.style.height = `${(cell.rowSpan ?? 1) * m.headerHeight}px`;\n th.title = cell.title;\n const colIndex = cell.colIndex;\n const sorted = colIndex != null && o.sortState?.col === colIndex;\n if (sorted) {\n classes.push('sorted');\n th.setAttribute('aria-sort', o.sortState?.dir === 'desc' ? 'descending' : 'ascending');\n }\n th.className = classes.join(' ');\n if (colIndex != null && o.onSort && o.columns[colIndex]?.sortable !== false) {\n const button = document.createElement('button');\n button.type = 'button';\n button.className = 'gtv-sort';\n button.addEventListener('click', () => o.onSort?.(colIndex));\n const label = document.createElement('span');\n label.className = 'gtv-lbl';\n label.textContent = cell.title;\n const glyph = document.createElement('span');\n glyph.className = 'gtv-glyph';\n glyph.setAttribute('aria-hidden', 'true');\n glyph.textContent = sorted ? (o.sortState?.dir === 'desc' ? '\u2193' : '\u2191') : '';\n button.append(label, glyph);\n th.appendChild(button);\n } else {\n th.textContent = cell.title;\n }\n tr.appendChild(th);\n }\n thead.appendChild(tr);\n });\n return thead;\n }\n\n private buildFooter(headerRowCount: number): HTMLTableSectionElement | null {\n const o = this.opts;\n if (!o.footerRow) return null;\n const tfoot = document.createElement('tfoot');\n const tr = document.createElement('tr');\n if (this.windowed) tr.setAttribute('aria-rowindex', String(headerRowCount + o.rowCount + 1));\n const kind: RowKind = o.footerRow.kind === 'grandtotal' ? 'grandtotal' : 'subtotal';\n o.columns.forEach((column, col) => {\n const el = document.createElement(column.rowHeader ? 'th' : 'td');\n if (column.rowHeader) (el as HTMLTableCellElement).scope = 'row';\n const slot: CellSlot = { el, kind: 'text', styled: false, titled: false };\n const cell = o.footerRow?.cells[col] ?? { value: null, raw: null };\n this.bindCell(slot, -1, col, { kind, depth: 0 }, cell);\n tr.appendChild(el);\n });\n tfoot.appendChild(tr);\n return tfoot;\n }\n\n private onScroll(): void {\n this.opts.onScroll?.(this.host.scrollTop || 0, this.host.scrollLeft || 0);\n if (this.frame !== 0) return;\n let ran = false;\n const run = () => {\n ran = true;\n this.frame = 0;\n this.renderWindow(false);\n this.paintSketch();\n };\n const id = typeof requestAnimationFrame === 'function'\n ? requestAnimationFrame(run)\n : (setTimeout(run, 16) as unknown as number);\n if (!ran) this.frame = id || -1;\n }\n\n private visibleRange(scrollTop = this.host.scrollTop || 0): [number, number] {\n const o = this.opts;\n if (!this.windowed) return [0, o.rowCount];\n const m = this.style.metrics;\n const header = this.headerRowCount * m.headerHeight;\n // The frame height bounds the viewport; reading the host's own height here would\n // force a layout mid-rebuild that clamps (and loses) the scroll position.\n const viewport = o.rect.height;\n const top = Math.max(0, scrollTop - header);\n const start = Math.max(0, Math.floor(top / m.rowHeight) - BUFFER_ROWS);\n const end = Math.min(o.rowCount, Math.ceil((top + viewport) / m.rowHeight) + BUFFER_ROWS);\n return [start, Math.max(start, end)];\n }\n\n private renderWindow(force: boolean, scrollTop?: number): void {\n const [start, end] = this.visibleRange(scrollTop);\n if (!force && start === this.start && end === this.end) return;\n this.start = start;\n this.end = end;\n const count = end - start;\n while (this.pool.length < count) this.pool.push(this.createRow());\n while (this.pool.length > count) this.pool.pop()!.tr.remove();\n const rh = this.style.metrics.rowHeight;\n const info = this.opts.rowInfo ?? defaultRowInfo;\n for (let i = 0; i < count; i++) this.bindRow(this.pool[i], start + i, info(start + i));\n this.setSpacer(this.topSpacer, start * rh, true);\n this.setSpacer(this.bottomSpacer, (this.opts.rowCount - end) * rh, false);\n }\n\n /** Spacer rows stand in for windowed-out rows and exist only while they have height. */\n private setSpacer(tr: HTMLTableRowElement, height: number, top: boolean): void {\n if (height <= 0) {\n tr.remove();\n return;\n }\n const td = tr.firstElementChild as HTMLElement;\n const h = `${height}px`;\n if (td.style.height !== h) td.style.height = h;\n if (tr.parentNode !== this.tbody) {\n if (top) this.tbody.insertBefore(tr, this.tbody.firstChild);\n else this.tbody.appendChild(tr);\n }\n }\n\n private createRow(): RowSlot {\n const tr = document.createElement('tr');\n if (this.opts.onRowClick) tr.tabIndex = 0;\n const cells = this.opts.columns.map((column): CellSlot => {\n const el = document.createElement(column.rowHeader ? 'th' : 'td');\n if (column.rowHeader) (el as HTMLTableCellElement).scope = 'row';\n tr.appendChild(el);\n return { el, kind: 'text', styled: false, titled: false };\n });\n this.tbody.insertBefore(tr, this.bottomSpacer.parentNode === this.tbody ? this.bottomSpacer : null);\n return { tr, cells, row: -1 };\n }\n\n private bindRow(slot: RowSlot, row: number, info: ViewRowInfo): void {\n const o = this.opts;\n slot.row = row;\n const tr = slot.tr;\n let cls = 'gtv-r';\n if (info.kind === 'group') cls += ' k-group';\n else if (info.kind === 'subtotal') cls += ' k-sub';\n else if (info.kind === 'grandtotal') cls += ' k-grand';\n else if (o.striped && row % 2 === 1) cls += ' s';\n if (o.highlighted?.(row)) cls += ' hl';\n if (tr.className !== cls) tr.className = cls;\n tr.dataset.row = String(row);\n if (this.windowed) tr.setAttribute('aria-rowindex', String(this.headerRowCount + row + 1));\n for (let col = 0; col < slot.cells.length; col++) this.bindCell(slot.cells[col], row, col, info, o.getCell(row, col));\n }\n\n private bindCell(slot: CellSlot, row: number, col: number, info: ViewRowInfo, cell: ViewCell): void {\n const o = this.opts;\n const column = o.columns[col];\n const el = slot.el;\n const formatter = o.rowFormatters\n ? (row >= 0 ? o.rowFormatters(row)?.[col] ?? null : null)\n : (o.formatKinds ?? DEFAULT_FORMAT_KINDS).includes(info.kind) ? this.formatters[col] : null;\n const paint = formatter ? formatter(cell) : null;\n const text = paint?.showValue === false ? '' : cellText(cell, column);\n const className = this.baseClass[col];\n if (el.className !== className) el.className = className;\n if (slot.styled) {\n el.style.cssText = '';\n slot.styled = false;\n }\n const color = paint?.color ?? negativeTextColor(cell.value, column, '', this.style.color.negative);\n if (paint?.background) this.setStyle(slot, 'background', paint.background);\n if (color) this.setStyle(slot, 'color', color);\n if (paint?.weight) this.setStyle(slot, 'fontWeight', String(paint.weight));\n if (column.rowHeader) this.bindRowHeader(slot, info, text, row);\n else if (column.sparkline && Array.isArray(cell.value)) this.bindSpark(slot, cell.value, column);\n else if (paint?.bar) this.bindBar(slot, paint, text, col, row);\n else if (paint?.icon) this.bindIcon(slot, paint, text);\n else {\n slot.kind = 'text';\n if (el.firstChild?.nodeType !== 3 || el.childNodes.length !== 1 || el.firstChild.nodeValue !== text) el.textContent = text;\n }\n this.syncTitle(slot, text, col, info.kind !== 'leaf' || Boolean(paint?.weight), info.depth);\n }\n\n private setStyle(slot: CellSlot, key: 'background' | 'color' | 'fontWeight' | 'paddingLeft', value: string): void {\n slot.el.style[key] = value;\n slot.styled = true;\n }\n\n private bindRowHeader(slot: CellSlot, info: ViewRowInfo, text: string, row: number): void {\n const m = this.style.metrics;\n if (slot.kind !== 'rh') {\n slot.el.replaceChildren();\n slot.toggle = document.createElement('button');\n slot.toggle.type = 'button';\n slot.toggle.className = 'gtv-tog';\n slot.toggle.innerHTML = '<svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden=\"true\"><path d=\"M2 3.5 5 6.5 8 3.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>';\n slot.pad = document.createElement('span');\n slot.pad.className = 'gtv-pad';\n slot.val = document.createElement('span');\n slot.el.append(slot.toggle, slot.pad, slot.val);\n slot.kind = 'rh';\n }\n const indent = m.paddingX + info.depth * m.indent;\n if (indent !== m.paddingX) this.setStyle(slot, 'paddingLeft', `${indent}px`);\n const expandable = Boolean(info.expandable) && row >= 0 && Boolean(this.opts.onToggle);\n slot.toggle!.style.display = expandable ? '' : 'none';\n slot.pad!.style.display = expandable || !this.hierarchy ? 'none' : '';\n if (expandable) {\n slot.toggle!.setAttribute('aria-expanded', String(info.expanded !== false));\n slot.toggle!.setAttribute('aria-label', `${info.expanded !== false ? 'Collapse' : 'Expand'} ${text}`);\n }\n if (slot.val!.textContent !== text) slot.val!.textContent = text;\n }\n\n private hasHierarchy(): boolean {\n const info = this.opts.measure?.rowInfo ?? this.opts.rowInfo;\n if (!info) return false;\n const count = this.opts.measure?.rowCount ?? this.opts.rowCount;\n for (let i = 0; i < Math.min(count, 200); i++) if (info(i).expandable) return true;\n return false;\n }\n\n private bindBar(slot: CellSlot, paint: CellPaint, text: string, col: number, row: number): void {\n const o = this.opts;\n const bar = paint.bar!;\n const column = o.columns[col];\n const track = barTrack(this.widths[col] ?? 0, this.style.metrics.paddingX, this.layout.valueWidths[col] ?? 0, column.align, paint.showValue !== false);\n const left = track.left + bar.from * track.width;\n const width = Math.max(0, (bar.to - bar.from) * track.width);\n const fill = barFill(bar.color, track.overlay ? BAR_OVERLAY_ALPHA : BAR_LANE_ALPHA);\n if (slot.kind !== 'bar') {\n slot.el.replaceChildren();\n slot.bar = document.createElement('div');\n slot.zero = document.createElement('div');\n slot.zero.className = 'gtv-zero';\n slot.val = document.createElement('span');\n slot.val.className = 'gtv-val';\n slot.el.append(slot.bar, slot.zero, slot.val);\n slot.kind = 'bar';\n }\n if (o.sketch) {\n const seed = (o.sketch.seed ^ Math.imul(row + 2, 374761393) ^ Math.imul(col + 1, 668265263)) >>> 0;\n const m = this.style.metrics;\n const next = buildSketchDataBar(o.sketch, fill, left, width, m.barHeight, seed) ?? document.createElement('div');\n slot.bar!.replaceWith(next);\n slot.bar = next;\n } else {\n const s = slot.bar!.style;\n if (slot.bar!.className !== 'gtv-bar') slot.bar!.className = 'gtv-bar';\n s.left = `${left}px`;\n s.width = `${width}px`;\n s.background = fill;\n }\n slot.zero!.style.display = bar.zero === undefined ? 'none' : '';\n if (bar.zero !== undefined) slot.zero!.style.left = `${Math.round(track.left + bar.zero * track.width)}px`;\n if (slot.val!.textContent !== text) slot.val!.textContent = text;\n }\n\n private bindIcon(slot: CellSlot, paint: CellPaint, text: string): void {\n if (slot.kind !== 'icon') {\n slot.el.replaceChildren();\n const wrap = document.createElement('span');\n wrap.className = 'gtv-flex';\n slot.icon = document.createElement('span');\n slot.icon.className = 'gtv-icon';\n slot.icon.setAttribute('aria-hidden', 'true');\n slot.val = document.createElement('span');\n slot.val.className = 'gtv-val';\n wrap.append(slot.icon, slot.val);\n slot.el.appendChild(wrap);\n slot.kind = 'icon';\n }\n const wrap = slot.icon!.parentElement!;\n if (paint.iconPosition === 'right') {\n if (wrap.firstChild !== slot.val) wrap.insertBefore(slot.val!, slot.icon!);\n } else if (wrap.firstChild !== slot.icon) wrap.insertBefore(slot.icon!, slot.val!);\n slot.icon!.textContent = paint.icon ?? '';\n slot.icon!.style.color = paint.iconColor ?? '';\n if (slot.val!.textContent !== text) slot.val!.textContent = text;\n }\n\n private bindSpark(slot: CellSlot, values: unknown[], column: ViewColumn): void {\n const spark = column.sparkline!;\n if (slot.kind !== 'spark') {\n slot.el.replaceChildren();\n slot.el.innerHTML = '<svg class=\"gtv-spark\" viewBox=\"0 0 100 20\" preserveAspectRatio=\"none\" aria-hidden=\"true\"><path vector-effect=\"non-scaling-stroke\"/><path vector-effect=\"non-scaling-stroke\"/></svg>';\n slot.kind = 'spark';\n }\n const color = spark.color ?? this.opts.tokens.color.accent;\n const shape = sparklinePath(values, spark, 100, 20);\n const [fillPath, linePath] = Array.from(slot.el.querySelectorAll('path'));\n fillPath.setAttribute('d', shape.area);\n fillPath.setAttribute('fill', spark.type === 'line' ? 'none' : barFill(color, spark.type === 'bar' ? 0.85 : 0.18));\n fillPath.setAttribute('stroke', 'none');\n linePath.setAttribute('d', shape.line);\n linePath.setAttribute('fill', 'none');\n linePath.setAttribute('stroke', spark.type === 'bar' ? 'none' : color);\n linePath.setAttribute('stroke-width', '1.5');\n linePath.setAttribute('stroke-linejoin', 'round');\n slot.el.setAttribute('aria-label', shape.summary);\n }\n\n /** Full text on hover for anything the column width cuts short. */\n private syncTitle(slot: CellSlot, text: string, col: number, strong: boolean, depth: number): void {\n const column = this.opts.columns[col];\n let clipped = false;\n if (text && !column.wrap) {\n const m = this.style.metrics;\n const font = strong ? this.boldFont : this.bodyFont;\n const key = `${strong ? 'b' : 'n'}${text}`;\n let w = this.textWidths.get(key);\n if (w === undefined) {\n w = measureText(text, font).width;\n if (this.textWidths.size < 8192) this.textWidths.set(key, w);\n }\n const budget = (this.widths[col] ?? 0) - m.paddingX * 2 - (column.rowHeader ? depth * m.indent + m.toggle + 4 : 0);\n clipped = w > budget + 0.5;\n }\n if (clipped) {\n if (slot.el.title !== text) slot.el.title = text;\n slot.titled = true;\n } else if (slot.titled) {\n slot.el.removeAttribute('title');\n slot.titled = false;\n }\n }\n\n private onBodyClick(event: MouseEvent): void {\n const target = event.target as Element | null;\n const tr = target?.closest('tr');\n const row = tr?.dataset.row == null ? -1 : Number(tr.dataset.row);\n if (row < 0 || !Number.isFinite(row)) return;\n if (target?.closest('.gtv-tog')) {\n this.opts.onToggle?.(row);\n return;\n }\n const cell = target?.closest('td,th') as HTMLTableCellElement | null;\n if (cell && this.opts.onRowClick) this.opts.onRowClick(row, cell.cellIndex, event);\n }\n\n /** Selectable rows are focusable; Enter or Space selects like a click. */\n private onBodyKey(event: KeyboardEvent): void {\n if (event.key !== 'Enter' && event.key !== ' ') return;\n const tr = event.target as HTMLElement | null;\n if (!tr || tr.tagName !== 'TR' || !this.opts.onRowClick) return;\n const row = Number(tr.dataset.row);\n if (!Number.isFinite(row) || row < 0) return;\n event.preventDefault();\n this.opts.onRowClick(row, 0, event);\n }\n\n private mountSketch(height: number): void {\n const o = this.opts;\n this.sketchCanvas?.canvas.remove();\n this.sketchCanvas = null;\n if (!o.sketch) return;\n const overlay = createSketchGridCanvas({ ...o.rect, height });\n o.container.appendChild(overlay.canvas);\n this.sketchCanvas = overlay;\n this.paintSketch();\n }\n\n private paintSketch(): void {\n const o = this.opts;\n const canvas = this.sketchCanvas;\n if (!o.sketch || !canvas?.ctx) return;\n const height = parseFloat(canvas.canvas.style.height) || o.rect.height;\n paintSketchGridOverlay(canvas.ctx, {\n sketch: o.sketch,\n tokens: o.tokens,\n rect: { ...o.rect, height },\n dpr: canvas.dpr,\n columns: o.columns,\n widths: this.widths,\n rowCount: o.rowCount,\n headerRowCount: this.headerRowCount,\n hasFooter: Boolean(o.footerRow),\n rowHeaderSpan: o.frozenColumns ?? 0,\n metrics: this.style.metrics,\n scrollLeft: this.host.scrollLeft || 0,\n scrollTop: this.host.scrollTop || 0,\n });\n }\n\n recordEvidence(): void {\n const o = this.opts;\n const evidence = o.evidence;\n if (!evidence) return;\n const m = this.style.metrics;\n const first = clampInt(this.start, 0, o.rowCount);\n const last = clampInt(this.end, first, o.rowCount);\n recordDataEvidence(o, first, last);\n const host = this.host.getBoundingClientRect();\n const origin = { x: host.left - o.rect.x, y: host.top - o.rect.y };\n const headerHeight = this.headerRowCount * m.headerHeight;\n const viewTop = this.host.scrollTop || 0;\n const viewBottom = viewTop + (this.host.clientHeight || o.rect.height);\n const info = o.rowInfo ?? defaultRowInfo;\n for (const slot of this.pool) {\n const row = slot.row;\n if (row < first || row >= last) continue;\n const kind = info(row).kind;\n const y = headerHeight + row * m.rowHeight;\n // Rows scrolled out of view still count as drawn marks, measured arithmetically.\n const inView = y + m.rowHeight >= viewTop - m.rowHeight && y <= viewBottom + m.rowHeight;\n let x = o.rect.x - (this.host.scrollLeft || 0);\n for (let col = 0; col < slot.cells.length; col++) {\n const el = slot.cells[col].el;\n const width = this.widths[col] ?? 0;\n const cell = o.getCell(row, col);\n const background = el.style.background || rowBackground(this.style, kind, o.striped === true && row % 2 === 1);\n const color = el.style.color || this.style.color.text;\n const actual = inView ? el.getBoundingClientRect() : null;\n const measured = Boolean(actual && actual.width > 0 && actual.height > 0);\n if (inView && !measured) evidence.partial('geometry', 'text');\n const box = measured && actual\n ? { x: actual.left - origin.x, y: actual.top - origin.y, width: actual.width, height: actual.height }\n : { x, y: o.rect.y + y - viewTop, width, height: m.rowHeight };\n if (countsAsMark(o, col, cell)) evidence.mark('cell', box.x, box.y, box.width, box.height, color, 1, o.rect, 1, background);\n if (measured) recordDomLabels(o.labels, el, origin, background, 'data-label', undefined, o.rect);\n x += width;\n }\n }\n for (const th of Array.from(this.table.tHead?.querySelectorAll('th') ?? [])) {\n if (!recordDomLabels(o.labels, th, origin, this.style.color.headerBg, 'axis-label', '/columns', o.rect)) evidence.partial('text');\n }\n const foot = this.table.tFoot?.rows[0];\n if (foot) {\n for (let col = 0; col < foot.cells.length; col++) {\n const el = foot.cells[col];\n const actual = el.getBoundingClientRect();\n if (actual.width <= 0 || actual.height <= 0) continue;\n if (o.dataRepresentation === 'aggregate' && countsAsMark(o, col, o.footerRow?.cells[col] ?? { value: null, raw: null })) {\n evidence.mark('cell', actual.left - origin.x, actual.top - origin.y, actual.width, actual.height,\n el.style.color || this.style.color.text, 1, o.rect, 1, el.style.background || this.style.color.totalBg);\n }\n recordDomLabels(o.labels, el, origin, el.style.background || this.style.color.totalBg, 'data-label', undefined, o.rect);\n }\n }\n }\n}\n\nfunction countsAsMark(o: TableViewInput, col: number, cell: ViewCell): boolean {\n if (o.dataRepresentation !== 'aggregate') return true;\n return !o.columns[col]?.rowHeader && typeof cell.raw === 'number' && Number.isFinite(cell.raw);\n}\n\nfunction recordDataEvidence(o: TableViewInput, first: number, last: number): void {\n const evidence = o.evidence;\n if (!evidence) return;\n const rendered = o.columns.length ? last - first : 0;\n const deferred = o.columns.length ? Math.max(0, o.rowCount - rendered) : 0;\n if (o.dataRepresentation === 'rows') {\n evidence.data(rendered, 'rows', 0, deferred);\n } else if (o.dataRepresentation === 'aggregate') {\n evidence.data(o.sourceRepresentedRows ?? Math.max(0, evidence.snapshot().data.inputRows - deferred), 'aggregate', 0, deferred);\n }\n}\n\nfunction columnClass(column: ViewColumn, index: number, frozen: number, windowed: boolean): string {\n const classes: string[] = [];\n if (column.align === 'right') classes.push('a-r');\n else if (column.align === 'center') classes.push('a-c');\n if (column.isMeasure || column.type === 'quantitative') classes.push('num');\n if (index < frozen) classes.push('fz', `fz${index}`);\n if (index === frozen - 1) classes.push('fz-edge');\n if (index > 0 && column.groupStart) classes.push('gs');\n if (column.total) classes.push('tc');\n if (column.wrap && !windowed) classes.push('wrap');\n return classes.join(' ');\n}\n\nfunction spacerRow(columns: number): HTMLTableRowElement {\n const tr = document.createElement('tr');\n tr.className = 'gtv-sp';\n tr.setAttribute('aria-hidden', 'true');\n const td = document.createElement('td');\n td.colSpan = Math.max(1, columns);\n tr.appendChild(td);\n return tr;\n}\n\nfunction scrollbarWidth(): number {\n if (cachedScrollbarWidth != null) return cachedScrollbarWidth;\n if (typeof document === 'undefined' || !document.body) return 0;\n const probe = document.createElement('div');\n probe.style.cssText = 'position:absolute;top:-9999px;width:100px;height:100px;overflow:scroll;visibility:hidden';\n document.body.appendChild(probe);\n cachedScrollbarWidth = probe.offsetWidth - probe.clientWidth;\n probe.remove();\n return cachedScrollbarWidth;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["wrap"]
7
7
  }
@@ -0,0 +1,22 @@
1
+ import { type ColumnFormatter } from './conditional.js';
2
+ import { type TableStyle } from './style.js';
3
+ import { type TableViewInput } from './types.js';
4
+ export interface ColumnLayout {
5
+ widths: number[];
6
+ /** Widest formatted value per column; bar tracks are laid out beside it. */
7
+ valueWidths: number[];
8
+ /** Leading columns that fit; static exports drop trailing columns that cannot. */
9
+ visibleCount: number;
10
+ }
11
+ export declare function sampleRows(rowCount: number): number[];
12
+ /**
13
+ * Content-aware column sizing shared by the DOM and canvas renderers: header
14
+ * labels and a bounded sample of formatted cells set each column's widths.
15
+ * Space is reclaimed from free text first, then from bar lanes; values are
16
+ * never cut. A scrollable table scrolls rather than squeezing headers, and a
17
+ * static export drops trailing columns that cannot fit.
18
+ */
19
+ export declare function layoutColumns(input: TableViewInput, style: TableStyle, formatters: ReadonlyArray<ColumnFormatter | null>, available: number, mode: 'scroll' | 'static'): ColumnLayout;
20
+ /** Prefix sums of column widths: left edge of each column. */
21
+ export declare function columnOffsets(widths: readonly number[]): number[];
22
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/charts/tableView/layout.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,EAA6B,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAkG,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9I,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,4EAA4E;IAC5E,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,kFAAkF;IAClF,YAAY,EAAE,MAAM,CAAC;CACtB;AAgBD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAOrD;AAgDD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,cAAc,EACrB,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,aAAa,CAAC,eAAe,GAAG,IAAI,CAAC,EACjD,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GACxB,YAAY,CAqBd;AAkLD,8DAA8D;AAC9D,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAQjE"}
@@ -0,0 +1,246 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ import { measureText } from "../../render/text.js";
5
+ import { BAR_GAP, MIN_BAR_LANE } from "./conditional.js";
6
+ import { fontFor, SORT_GLYPH_SPACE } from "./style.js";
7
+ import { cellText, defaultRowInfo, formatDisplayValue, normalizedHeaderRows, sumWidths } from "./types.js";
8
+ const HEAD_SAMPLE = 120;
9
+ const SPREAD_SAMPLE = 280;
10
+ const MAX_TEXT_WIDTH = 320;
11
+ const MAX_VALUE_WIDTH = 480;
12
+ const MIN_TEXT_WIDTH = 64;
13
+ const TEXT_FLOOR = { scroll: 112, static: 80 };
14
+ const PREFERRED_BAR_LANE = 72;
15
+ const SPARKLINE_WIDTH = 88;
16
+ const MIN_SPARKLINE_WIDTH = 40;
17
+ const ICON_GAP = 6;
18
+ const READABLE_HEADER = 0.56;
19
+ function sampleRows(rowCount) {
20
+ if (rowCount <= HEAD_SAMPLE + SPREAD_SAMPLE) return Array.from({ length: rowCount }, (_, i) => i);
21
+ const out = [];
22
+ for (let i = 0; i < HEAD_SAMPLE; i++) out.push(i);
23
+ const step = (rowCount - HEAD_SAMPLE) / SPREAD_SAMPLE;
24
+ for (let i = 0; i < SPREAD_SAMPLE; i++) out.push(HEAD_SAMPLE + Math.floor(i * step));
25
+ return out;
26
+ }
27
+ class Measurer {
28
+ constructor(font) {
29
+ __publicField(this, "font", font);
30
+ __publicField(this, "cache", /* @__PURE__ */ new Map());
31
+ __publicField(this, "widestDigit", null);
32
+ }
33
+ width(text) {
34
+ if (!text) return 0;
35
+ let w = this.cache.get(text);
36
+ if (w === void 0) {
37
+ w = measureText(text, this.font).width;
38
+ if (this.cache.size < 8192) this.cache.set(text, w);
39
+ }
40
+ return w;
41
+ }
42
+ /** Width with tabular figures: every digit advances like the widest one. */
43
+ numeric(text) {
44
+ if (this.widestDigit === null) {
45
+ let best = 0;
46
+ this.widestDigit = "0";
47
+ for (const d of "0123456789") {
48
+ const w = this.width(d);
49
+ if (w > best) {
50
+ best = w;
51
+ this.widestDigit = d;
52
+ }
53
+ }
54
+ }
55
+ return Math.ceil(this.width(text.replace(/[0-9]/g, this.widestDigit)) + 1);
56
+ }
57
+ }
58
+ function layoutColumns(input, style, formatters, available, mode) {
59
+ const needs = measureColumns(input, style, formatters, mode);
60
+ const frozen = Math.min(input.frozenColumns ?? 0, needs.length);
61
+ let visibleCount = needs.length;
62
+ let widths = fitWidths(needs, available);
63
+ if (mode === "static" && sumWidths(widths) > available + 0.5 && needs.length > 1) {
64
+ if (sumWidths(needs.map((n) => n.min)) <= available + 0.5) {
65
+ widths = squeeze(needs, widths, available);
66
+ } else {
67
+ visibleCount = Math.max(1, frozen);
68
+ let used = sumWidths(needs.map((n) => n.comfortable), 0, visibleCount);
69
+ while (visibleCount < needs.length && used + needs[visibleCount].comfortable <= available + 0.5) {
70
+ used += needs[visibleCount].comfortable;
71
+ visibleCount++;
72
+ }
73
+ widths = fitWidths(needs.slice(0, visibleCount), available);
74
+ }
75
+ }
76
+ return { widths: roundWidths(widths), valueWidths: needs.map((n) => n.valueWidth), visibleCount };
77
+ }
78
+ function measureColumns(input, style, formatters, mode) {
79
+ const m = style.metrics;
80
+ const pad = m.paddingX * 2;
81
+ const body = new Measurer(fontFor(style, style.weight.normal));
82
+ const bold = new Measurer(fontFor(style, style.weight.bold));
83
+ const rows = sampleRows(input.rowCount);
84
+ const info = input.rowInfo ?? defaultRowInfo;
85
+ const hierarchy = rows.some((row) => info(row).expandable);
86
+ const headerRows = normalizedHeaderRows(input);
87
+ const headerWidth = input.columns.map(() => 0);
88
+ const headerFloor = input.columns.map(() => 0);
89
+ for (const row of headerRows) {
90
+ for (const cell of row) {
91
+ if (cell.colIndex == null || (cell.colSpan ?? 1) > 1) continue;
92
+ const column = input.columns[cell.colIndex];
93
+ const arrow = input.sortState?.col === cell.colIndex || mode === "scroll" && column?.sortable !== false;
94
+ const text = bold.width(cell.title);
95
+ const chrome = pad + (arrow ? SORT_GLYPH_SPACE : 0);
96
+ headerWidth[cell.colIndex] = Math.max(headerWidth[cell.colIndex], text + chrome);
97
+ headerFloor[cell.colIndex] = Math.max(headerFloor[cell.colIndex], (mode === "scroll" ? text : Math.ceil(text * READABLE_HEADER)) + chrome);
98
+ }
99
+ }
100
+ const needs = input.columns.map((column, col) => {
101
+ const numeric = column.isMeasure || column.type === "quantitative";
102
+ const measure = (text, strong) => {
103
+ const m2 = strong ? bold : body;
104
+ return numeric ? m2.numeric(text) : m2.width(text);
105
+ };
106
+ let valueWidth = 0;
107
+ let extra = 0;
108
+ const formatter = formatters[col];
109
+ for (const row of rows) {
110
+ const cell = input.getCell(row, col);
111
+ const rowInfo = info(row);
112
+ const strong = rowInfo.kind !== "leaf" || Boolean(column.total);
113
+ const indent = column.rowHeader && hierarchy ? rowInfo.depth * m.indent + m.toggle + 4 : 0;
114
+ valueWidth = Math.max(valueWidth, measure(cellText(cell, column), strong) + indent);
115
+ if (formatter && !column.rowHeader) {
116
+ const paint = formatter(cell);
117
+ if (paint?.icon) extra = Math.max(extra, bold.width(paint.icon) + ICON_GAP + 1);
118
+ }
119
+ }
120
+ const extreme = input.extremes?.[col];
121
+ if (extreme && !column.rowHeader && !column.sparkline) {
122
+ for (const v of extreme) valueWidth = Math.max(valueWidth, measure(formatDisplayValue(v, column), Boolean(column.total)));
123
+ }
124
+ const footer = input.footerRow?.cells[col];
125
+ if (footer) valueWidth = Math.max(valueWidth, measure(cellText(footer, column), true) + (column.rowHeader && hierarchy ? m.toggle + 4 : 0));
126
+ valueWidth = Math.ceil(valueWidth);
127
+ const head = headerWidth[col] || bold.width(column.title) + pad;
128
+ const headFloor = Math.min(head, headerFloor[col] || head);
129
+ if (column.width) return { kind: "fixed", natural: column.width, comfortable: column.width, min: column.width, valueWidth };
130
+ if (column.sparkline) {
131
+ const natural2 = Math.max(head, SPARKLINE_WIDTH + pad);
132
+ return { kind: "spark", natural: natural2, comfortable: Math.max(headFloor, MIN_SPARKLINE_WIDTH + pad), min: MIN_SPARKLINE_WIDTH + pad, valueWidth: 0 };
133
+ }
134
+ if (column.conditionalFormat?.type === "bar") {
135
+ const showValue = column.conditionalFormat.showValue !== false;
136
+ const lane = showValue ? valueWidth + BAR_GAP + PREFERRED_BAR_LANE : PREFERRED_BAR_LANE;
137
+ const min = showValue ? valueWidth + pad : MIN_BAR_LANE + pad;
138
+ return { kind: "bar", natural: Math.min(MAX_VALUE_WIDTH, Math.max(head, lane + pad)), comfortable: Math.max(headFloor, min), min, valueWidth };
139
+ }
140
+ const content = valueWidth + extra + pad;
141
+ if (!numeric && !column.sparkline && column.align !== "right") {
142
+ const natural2 = Math.max(MIN_TEXT_WIDTH, Math.min(MAX_TEXT_WIDTH, Math.max(head, content)));
143
+ const floor = column.rowHeader && hierarchy ? Math.min(natural2, Math.max(TEXT_FLOOR[mode], m.toggle + m.indent * 2 + pad + 48)) : Math.min(natural2, TEXT_FLOOR[mode]);
144
+ return { kind: column.rowHeader ? "label" : "text", natural: natural2, comfortable: floor, min: floor, valueWidth, ...column.rowHeader ? { cap: natural2 + 48 } : {} };
145
+ }
146
+ const natural = Math.max(MIN_TEXT_WIDTH, Math.min(MAX_VALUE_WIDTH, Math.max(head, content)));
147
+ const comfortable = Math.min(natural, Math.max(headFloor, content));
148
+ return { kind: "number", natural, comfortable, min: Math.min(comfortable, content), valueWidth };
149
+ });
150
+ widenForBandHeaders(needs, headerRows, bold, pad);
151
+ return needs;
152
+ }
153
+ function widenForBandHeaders(needs, headerRows, header, pad) {
154
+ for (const row of headerRows) {
155
+ let cursor = 0;
156
+ for (const cell of row) {
157
+ const start = cell.colIndex ?? cursor;
158
+ const span = Math.max(1, cell.colSpan ?? 1);
159
+ cursor = start + span;
160
+ if (cell.colIndex != null && span < 2) continue;
161
+ const slice = needs.slice(start, start + span).filter((n) => n.kind !== "fixed");
162
+ if (!slice.length) continue;
163
+ const want = Math.min(MAX_TEXT_WIDTH, header.width(cell.title) + pad);
164
+ for (const key of ["natural", "comfortable"]) {
165
+ const have = slice.reduce((s, n) => s + n[key], 0);
166
+ if (want <= have) continue;
167
+ const add = (want - have) / slice.length;
168
+ for (const n of slice) n[key] += add;
169
+ }
170
+ }
171
+ }
172
+ }
173
+ const SHRINK_PASSES = [
174
+ { kinds: ["text"], to: "min" },
175
+ { kinds: ["bar", "spark"], to: "comfortable" },
176
+ { kinds: ["label"], to: "min" },
177
+ { kinds: ["number"], to: "comfortable" }
178
+ ];
179
+ function fitWidths(needs, available) {
180
+ const widths = needs.map((n) => n.natural);
181
+ if (!(available > 0)) return widths;
182
+ const total = sumWidths(widths);
183
+ if (total <= available) {
184
+ let extra = available - total;
185
+ const open = needs.map((n) => n.kind !== "fixed");
186
+ for (let pass = 0; pass < 3 && extra > 0.5; pass++) {
187
+ const weights = needs.map((n, i) => open[i] ? n.natural * (n.kind === "text" || n.kind === "label" ? 1.6 : 1) : 0);
188
+ const weightTotal = weights.reduce((s, w) => s + w, 0);
189
+ if (weightTotal <= 0) break;
190
+ let given = 0;
191
+ for (let i = 0; i < widths.length; i++) {
192
+ if (!weights[i]) continue;
193
+ const want = extra * weights[i] / weightTotal;
194
+ const room = needs[i].cap === void 0 ? want : Math.max(0, needs[i].cap - widths[i]);
195
+ const add = Math.min(want, room);
196
+ if (add < want) open[i] = false;
197
+ widths[i] += add;
198
+ given += add;
199
+ }
200
+ extra -= given;
201
+ }
202
+ return widths;
203
+ }
204
+ let excess = total - available;
205
+ for (const pass of SHRINK_PASSES) {
206
+ const slack = needs.map((n, i) => pass.kinds.includes(n.kind) ? Math.max(0, widths[i] - n[pass.to]) : 0);
207
+ const slackTotal = slack.reduce((s, v) => s + v, 0);
208
+ if (slackTotal <= 0) continue;
209
+ const take = Math.min(excess, slackTotal);
210
+ for (let i = 0; i < widths.length; i++) widths[i] -= take * slack[i] / slackTotal;
211
+ excess -= take;
212
+ if (excess <= 0.5) break;
213
+ }
214
+ return widths;
215
+ }
216
+ function squeeze(needs, widths, available) {
217
+ const out = widths.slice();
218
+ const excess = sumWidths(out) - available;
219
+ const slack = needs.map((n, i) => Math.max(0, out[i] - n.min));
220
+ const slackTotal = slack.reduce((s, v) => s + v, 0);
221
+ if (excess <= 0 || slackTotal <= 0) return out;
222
+ const take = Math.min(excess, slackTotal);
223
+ for (let i = 0; i < out.length; i++) out[i] -= take * slack[i] / slackTotal;
224
+ return out;
225
+ }
226
+ function roundWidths(widths) {
227
+ const out = widths.map((w) => Math.max(1, Math.floor(w + 1e-6)));
228
+ const diff = Math.floor(sumWidths(widths) + 1e-6) - sumWidths(out);
229
+ if (out.length && diff > 0) out[out.length - 1] += diff;
230
+ return out;
231
+ }
232
+ function columnOffsets(widths) {
233
+ const out = [];
234
+ let x = 0;
235
+ for (const w of widths) {
236
+ out.push(x);
237
+ x += w;
238
+ }
239
+ return out;
240
+ }
241
+ export {
242
+ columnOffsets,
243
+ layoutColumns,
244
+ sampleRows
245
+ };
246
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/charts/tableView/layout.ts"],
4
+ "sourcesContent": ["import { measureText } from '../../render/text';\nimport { BAR_GAP, MIN_BAR_LANE, type ColumnFormatter } from './conditional';\nimport { fontFor, SORT_GLYPH_SPACE, type TableStyle } from './style';\nimport { cellText, defaultRowInfo, formatDisplayValue, normalizedHeaderRows, sumWidths, type HeaderCell, type TableViewInput } from './types';\n\nexport interface ColumnLayout {\n widths: number[];\n /** Widest formatted value per column; bar tracks are laid out beside it. */\n valueWidths: number[];\n /** Leading columns that fit; static exports drop trailing columns that cannot. */\n visibleCount: number;\n}\n\n/** Rows measured per column: the head of the table plus an even spread of the rest. */\nconst HEAD_SAMPLE = 120;\nconst SPREAD_SAMPLE = 280;\nconst MAX_TEXT_WIDTH = 320;\nconst MAX_VALUE_WIDTH = 480;\nconst MIN_TEXT_WIDTH = 64;\nconst TEXT_FLOOR = { scroll: 112, static: 80 } as const;\nconst PREFERRED_BAR_LANE = 72;\nconst SPARKLINE_WIDTH = 88;\nconst MIN_SPARKLINE_WIDTH = 40;\nconst ICON_GAP = 6;\n/** Share of a header's text a static snapshot keeps before it would rather drop a column. */\nconst READABLE_HEADER = 0.56;\n\nexport function sampleRows(rowCount: number): number[] {\n if (rowCount <= HEAD_SAMPLE + SPREAD_SAMPLE) return Array.from({ length: rowCount }, (_, i) => i);\n const out: number[] = [];\n for (let i = 0; i < HEAD_SAMPLE; i++) out.push(i);\n const step = (rowCount - HEAD_SAMPLE) / SPREAD_SAMPLE;\n for (let i = 0; i < SPREAD_SAMPLE; i++) out.push(HEAD_SAMPLE + Math.floor(i * step));\n return out;\n}\n\nclass Measurer {\n private readonly cache = new Map<string, number>();\n private widestDigit: string | null = null;\n constructor(private readonly font: string) {}\n width(text: string): number {\n if (!text) return 0;\n let w = this.cache.get(text);\n if (w === undefined) {\n w = measureText(text, this.font).width;\n if (this.cache.size < 8192) this.cache.set(text, w);\n }\n return w;\n }\n /** Width with tabular figures: every digit advances like the widest one. */\n numeric(text: string): number {\n if (this.widestDigit === null) {\n let best = 0;\n this.widestDigit = '0';\n for (const d of '0123456789') {\n const w = this.width(d);\n if (w > best) {\n best = w;\n this.widestDigit = d;\n }\n }\n }\n return Math.ceil(this.width(text.replace(/[0-9]/g, this.widestDigit)) + 1);\n }\n}\n\n/** A `label` column is a matrix row header: identifying text that gives way only after bar lanes. */\ntype ColumnKind = 'text' | 'label' | 'number' | 'bar' | 'spark' | 'fixed';\n\ninterface ColumnNeeds {\n kind: ColumnKind;\n /** Header and content at ease (bar lanes and sparklines at their preferred size). */\n natural: number;\n /** Smallest width that still shows the full header and values. */\n comfortable: number;\n /** Smallest width that shows full values; headers may ellipsize. */\n min: number;\n valueWidth: number;\n /** Most a column grows when spare width is shared out (the matrix row header). */\n cap?: number;\n}\n\n/**\n * Content-aware column sizing shared by the DOM and canvas renderers: header\n * labels and a bounded sample of formatted cells set each column's widths.\n * Space is reclaimed from free text first, then from bar lanes; values are\n * never cut. A scrollable table scrolls rather than squeezing headers, and a\n * static export drops trailing columns that cannot fit.\n */\nexport function layoutColumns(\n input: TableViewInput,\n style: TableStyle,\n formatters: ReadonlyArray<ColumnFormatter | null>,\n available: number,\n mode: 'scroll' | 'static',\n): ColumnLayout {\n const needs = measureColumns(input, style, formatters, mode);\n const frozen = Math.min(input.frozenColumns ?? 0, needs.length);\n let visibleCount = needs.length;\n let widths = fitWidths(needs, available);\n if (mode === 'static' && sumWidths(widths) > available + 0.5 && needs.length > 1) {\n if (sumWidths(needs.map((n) => n.min)) <= available + 0.5) {\n // Every column fits once headers give way: keep them all, values whole.\n widths = squeeze(needs, widths, available);\n } else {\n // A static snapshot keeps whole values and readable headers, so it shows fewer columns instead.\n visibleCount = Math.max(1, frozen);\n let used = sumWidths(needs.map((n) => n.comfortable), 0, visibleCount);\n while (visibleCount < needs.length && used + needs[visibleCount].comfortable <= available + 0.5) {\n used += needs[visibleCount].comfortable;\n visibleCount++;\n }\n widths = fitWidths(needs.slice(0, visibleCount), available);\n }\n }\n return { widths: roundWidths(widths), valueWidths: needs.map((n) => n.valueWidth), visibleCount };\n}\n\nfunction measureColumns(\n input: TableViewInput,\n style: TableStyle,\n formatters: ReadonlyArray<ColumnFormatter | null>,\n mode: 'scroll' | 'static',\n): ColumnNeeds[] {\n const m = style.metrics;\n const pad = m.paddingX * 2;\n const body = new Measurer(fontFor(style, style.weight.normal));\n const bold = new Measurer(fontFor(style, style.weight.bold));\n const rows = sampleRows(input.rowCount);\n const info = input.rowInfo ?? defaultRowInfo;\n const hierarchy = rows.some((row) => info(row).expandable);\n const headerRows = normalizedHeaderRows(input);\n // Full header width, and the narrowest width that still reads clearly. A\n // scrollable table keeps whole headers; a static snapshot may shorten them\n // (never past about half their text) before it drops columns.\n const headerWidth = input.columns.map(() => 0);\n const headerFloor = input.columns.map(() => 0);\n for (const row of headerRows) {\n for (const cell of row) {\n if (cell.colIndex == null || (cell.colSpan ?? 1) > 1) continue;\n const column = input.columns[cell.colIndex];\n const arrow = input.sortState?.col === cell.colIndex || (mode === 'scroll' && column?.sortable !== false);\n const text = bold.width(cell.title);\n const chrome = pad + (arrow ? SORT_GLYPH_SPACE : 0);\n headerWidth[cell.colIndex] = Math.max(headerWidth[cell.colIndex], text + chrome);\n headerFloor[cell.colIndex] = Math.max(headerFloor[cell.colIndex], (mode === 'scroll' ? text : Math.ceil(text * READABLE_HEADER)) + chrome);\n }\n }\n const needs = input.columns.map((column, col): ColumnNeeds => {\n // DOM numbers use tabular figures, so measure digits at the widest figure's advance.\n const numeric = column.isMeasure || column.type === 'quantitative';\n const measure = (text: string, strong: boolean) => {\n const m = strong ? bold : body;\n return numeric ? m.numeric(text) : m.width(text);\n };\n let valueWidth = 0;\n let extra = 0;\n const formatter = formatters[col];\n for (const row of rows) {\n const cell = input.getCell(row, col);\n const rowInfo = info(row);\n const strong = rowInfo.kind !== 'leaf' || Boolean(column.total);\n const indent = column.rowHeader && hierarchy ? rowInfo.depth * m.indent + m.toggle + 4 : 0;\n valueWidth = Math.max(valueWidth, measure(cellText(cell, column), strong) + indent);\n if (formatter && !column.rowHeader) {\n const paint = formatter(cell);\n if (paint?.icon) extra = Math.max(extra, bold.width(paint.icon) + ICON_GAP + 1);\n }\n }\n const extreme = input.extremes?.[col];\n if (extreme && !column.rowHeader && !column.sparkline) {\n for (const v of extreme) valueWidth = Math.max(valueWidth, measure(formatDisplayValue(v, column), Boolean(column.total)));\n }\n const footer = input.footerRow?.cells[col];\n if (footer) valueWidth = Math.max(valueWidth, measure(cellText(footer, column), true) + (column.rowHeader && hierarchy ? m.toggle + 4 : 0));\n valueWidth = Math.ceil(valueWidth);\n const head = headerWidth[col] || bold.width(column.title) + pad;\n const headFloor = Math.min(head, headerFloor[col] || head);\n if (column.width) return { kind: 'fixed', natural: column.width, comfortable: column.width, min: column.width, valueWidth };\n if (column.sparkline) {\n const natural = Math.max(head, SPARKLINE_WIDTH + pad);\n return { kind: 'spark', natural, comfortable: Math.max(headFloor, MIN_SPARKLINE_WIDTH + pad), min: MIN_SPARKLINE_WIDTH + pad, valueWidth: 0 };\n }\n if (column.conditionalFormat?.type === 'bar') {\n const showValue = column.conditionalFormat.showValue !== false;\n const lane = showValue ? valueWidth + BAR_GAP + PREFERRED_BAR_LANE : PREFERRED_BAR_LANE;\n const min = showValue ? valueWidth + pad : MIN_BAR_LANE + pad;\n return { kind: 'bar', natural: Math.min(MAX_VALUE_WIDTH, Math.max(head, lane + pad)), comfortable: Math.max(headFloor, min), min, valueWidth };\n }\n const content = valueWidth + extra + pad;\n if (!numeric && !column.sparkline && column.align !== 'right') {\n const natural = Math.max(MIN_TEXT_WIDTH, Math.min(MAX_TEXT_WIDTH, Math.max(head, content)));\n const floor = column.rowHeader && hierarchy\n ? Math.min(natural, Math.max(TEXT_FLOOR[mode], m.toggle + m.indent * 2 + pad + 48))\n : Math.min(natural, TEXT_FLOOR[mode]);\n return { kind: column.rowHeader ? 'label' : 'text', natural, comfortable: floor, min: floor, valueWidth, ...(column.rowHeader ? { cap: natural + 48 } : {}) };\n }\n const natural = Math.max(MIN_TEXT_WIDTH, Math.min(MAX_VALUE_WIDTH, Math.max(head, content)));\n const comfortable = Math.min(natural, Math.max(headFloor, content));\n return { kind: 'number', natural, comfortable, min: Math.min(comfortable, content), valueWidth };\n });\n widenForBandHeaders(needs, headerRows, bold, pad);\n return needs;\n}\n\n/** Group header bands must fit over the columns they span. */\nfunction widenForBandHeaders(needs: ColumnNeeds[], headerRows: HeaderCell[][], header: Measurer, pad: number): void {\n for (const row of headerRows) {\n let cursor = 0;\n for (const cell of row) {\n const start = cell.colIndex ?? cursor;\n const span = Math.max(1, cell.colSpan ?? 1);\n cursor = start + span;\n if (cell.colIndex != null && span < 2) continue;\n const slice = needs.slice(start, start + span).filter((n) => n.kind !== 'fixed');\n if (!slice.length) continue;\n const want = Math.min(MAX_TEXT_WIDTH, header.width(cell.title) + pad);\n for (const key of ['natural', 'comfortable'] as const) {\n const have = slice.reduce((s, n) => s + n[key], 0);\n if (want <= have) continue;\n const add = (want - have) / slice.length;\n for (const n of slice) n[key] += add;\n }\n }\n }\n}\n\n/** Free text gives way first, then bar lanes; headers and values are never cut to fit. */\nconst SHRINK_PASSES: ReadonlyArray<{ kinds: readonly ColumnKind[]; to: 'min' | 'comfortable' }> = [\n { kinds: ['text'], to: 'min' },\n { kinds: ['bar', 'spark'], to: 'comfortable' },\n { kinds: ['label'], to: 'min' },\n { kinds: ['number'], to: 'comfortable' },\n];\n\nfunction fitWidths(needs: readonly ColumnNeeds[], available: number): number[] {\n const widths = needs.map((n) => n.natural);\n if (!(available > 0)) return widths;\n const total = sumWidths(widths);\n if (total <= available) {\n // Share spare width by weight (text a little more), re-sharing whatever capped columns refuse.\n let extra = available - total;\n const open = needs.map((n) => n.kind !== 'fixed');\n for (let pass = 0; pass < 3 && extra > 0.5; pass++) {\n const weights = needs.map((n, i) => (open[i] ? n.natural * (n.kind === 'text' || n.kind === 'label' ? 1.6 : 1) : 0));\n const weightTotal = weights.reduce((s, w) => s + w, 0);\n if (weightTotal <= 0) break;\n let given = 0;\n for (let i = 0; i < widths.length; i++) {\n if (!weights[i]) continue;\n const want = (extra * weights[i]) / weightTotal;\n const room = needs[i].cap === undefined ? want : Math.max(0, needs[i].cap! - widths[i]);\n const add = Math.min(want, room);\n if (add < want) open[i] = false;\n widths[i] += add;\n given += add;\n }\n extra -= given;\n }\n return widths;\n }\n let excess = total - available;\n for (const pass of SHRINK_PASSES) {\n const slack = needs.map((n, i) => (pass.kinds.includes(n.kind) ? Math.max(0, widths[i] - n[pass.to]) : 0));\n const slackTotal = slack.reduce((s, v) => s + v, 0);\n if (slackTotal <= 0) continue;\n const take = Math.min(excess, slackTotal);\n for (let i = 0; i < widths.length; i++) widths[i] -= (take * slack[i]) / slackTotal;\n excess -= take;\n if (excess <= 0.5) break;\n }\n return widths;\n}\n\n/** Shrink columns between their comfortable and minimum widths just enough to fit. */\nfunction squeeze(needs: readonly ColumnNeeds[], widths: number[], available: number): number[] {\n const out = widths.slice();\n const excess = sumWidths(out) - available;\n const slack = needs.map((n, i) => Math.max(0, out[i] - n.min));\n const slackTotal = slack.reduce((s, v) => s + v, 0);\n if (excess <= 0 || slackTotal <= 0) return out;\n const take = Math.min(excess, slackTotal);\n for (let i = 0; i < out.length; i++) out[i] -= (take * slack[i]) / slackTotal;\n return out;\n}\n\n/** Integer column widths keep grid lines crisp; rounding error lands on the last column. */\nfunction roundWidths(widths: number[]): number[] {\n const out = widths.map((w) => Math.max(1, Math.floor(w + 1e-6)));\n const diff = Math.floor(sumWidths(widths) + 1e-6) - sumWidths(out);\n if (out.length && diff > 0) out[out.length - 1] += diff;\n return out;\n}\n\n/** Prefix sums of column widths: left edge of each column. */\nexport function columnOffsets(widths: readonly number[]): number[] {\n const out: number[] = [];\n let x = 0;\n for (const w of widths) {\n out.push(x);\n x += w;\n }\n return out;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["m", "natural"]
7
+ }
@@ -1,7 +1,8 @@
1
1
  import type { ResolvedSketch } from '../../spec/sketch.js';
2
2
  import type { ThemeTokens } from '../../theme/index.js';
3
3
  import type { Rect } from '../../types.js';
4
- import { BuildTableOptions, ViewColumn } from './types.js';
4
+ import { type ViewColumn } from './types.js';
5
+ import type { TableMetrics } from './style.js';
5
6
  export interface SketchGridOverlay {
6
7
  sketch: ResolvedSketch;
7
8
  tokens: ThemeTokens;
@@ -13,7 +14,7 @@ export interface SketchGridOverlay {
13
14
  headerRowCount: number;
14
15
  hasFooter: boolean;
15
16
  rowHeaderSpan?: number;
16
- density?: BuildTableOptions['density'];
17
+ metrics: TableMetrics;
17
18
  scrollLeft: number;
18
19
  scrollTop: number;
19
20
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sketch.d.ts","sourceRoot":"","sources":["../../../src/charts/tableView/sketch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAGxC,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAA6B,MAAM,SAAS,CAAC;AACnF,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG;IAClD,MAAM,EAAE,iBAAiB,CAAC;IAC1B,GAAG,EAAE,wBAAwB,GAAG,IAAI,CAAC;IACrC,GAAG,EAAE,MAAM,CAAC;CACb,CAgBA;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,wBAAwB,EAAE,CAAC,EAAE,iBAAiB,GAAG,IAAI,CA2DhG"}
1
+ {"version":3,"file":"sketch.d.ts","sourceRoot":"","sources":["../../../src/charts/tableView/sketch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAGxC,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG;IAClD,MAAM,EAAE,iBAAiB,CAAC;IAC1B,GAAG,EAAE,wBAAwB,GAAG,IAAI,CAAC;IACrC,GAAG,EAAE,MAAM,CAAC;CACb,CAgBA;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,wBAAwB,EAAE,CAAC,EAAE,iBAAiB,GAAG,IAAI,CA2DhG"}
@@ -1,6 +1,6 @@
1
1
  import { getDevicePixelRatio } from "../../render/env.js";
2
2
  import { RoughPen } from "../../rough/index.js";
3
- import { densityMetrics, setStyles } from "./types.js";
3
+ import { setStyles } from "./types.js";
4
4
  function createSketchGridCanvas(rect) {
5
5
  const dpr = getDevicePixelRatio();
6
6
  const w = Math.max(0, rect.width);
@@ -24,7 +24,7 @@ function paintSketchGridOverlay(ctx, o) {
24
24
  ctx.save();
25
25
  ctx.setTransform(o.dpr, 0, 0, o.dpr, 0, 0);
26
26
  ctx.clearRect(0, 0, w, h);
27
- const metrics = densityMetrics(o.density);
27
+ const metrics = o.metrics;
28
28
  const headerHeight = o.headerRowCount * metrics.headerHeight;
29
29
  const footerHeight = o.hasFooter ? metrics.rowHeight : 0;
30
30
  const bodyTop = headerHeight;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/charts/tableView/sketch.ts"],
4
- "sourcesContent": ["import type { ResolvedSketch } from '../../spec/sketch';\nimport type { ThemeTokens } from '../../theme';\nimport type { Rect } from '../../types';\nimport { getDevicePixelRatio } from '../../render/env';\nimport { RoughPen } from '../../rough';\nimport { BuildTableOptions, ViewColumn, densityMetrics, setStyles } from './types';\nexport interface SketchGridOverlay {\n sketch: ResolvedSketch;\n tokens: ThemeTokens;\n rect: Rect;\n dpr: number;\n columns: readonly ViewColumn[];\n widths: readonly number[];\n rowCount: number;\n headerRowCount: number;\n hasFooter: boolean;\n rowHeaderSpan?: number;\n density?: BuildTableOptions['density'];\n scrollLeft: number;\n scrollTop: number;\n}\n\n/**\n * Create a DPR-scaled overlay `<canvas>` positioned exactly over the table\n * rect. It lives as a sibling of the scroll host (`pointer-events: none`) so it\n * survives the host's `replaceChildren()` and lets scroll/click pass through.\n */\nexport function createSketchGridCanvas(rect: Rect): {\n canvas: HTMLCanvasElement;\n ctx: CanvasRenderingContext2D | null;\n dpr: number;\n} {\n const dpr = getDevicePixelRatio();\n const w = Math.max(0, rect.width);\n const h = Math.max(0, rect.height);\n const canvas = document.createElement('canvas');\n canvas.width = Math.max(1, Math.round(w * dpr));\n canvas.height = Math.max(1, Math.round(h * dpr));\n setStyles(canvas, {\n position: 'absolute',\n left: `${rect.x}px`,\n top: `${rect.y}px`,\n width: `${w}px`,\n height: `${h}px`,\n pointerEvents: 'none',\n });\n return { canvas, ctx: canvas.getContext('2d'), dpr };\n}\n\n/**\n * Draw the hand-drawn frame + column/row separators + header rule onto a\n * viewport-pinned overlay canvas. Vertical separators track horizontal scroll;\n * body row separators track vertical scroll and are clipped to the body band so\n * they never bleed over the sticky header/footer. Every line is seeded from its\n * own index so the wobble stays stable across scroll frames.\n */\nexport function paintSketchGridOverlay(ctx: CanvasRenderingContext2D, o: SketchGridOverlay): void {\n const w = Math.max(0, o.rect.width);\n const h = Math.max(0, o.rect.height);\n ctx.save();\n ctx.setTransform(o.dpr, 0, 0, o.dpr, 0, 0);\n ctx.clearRect(0, 0, w, h);\n\n const metrics = densityMetrics(o.density);\n const headerHeight = o.headerRowCount * metrics.headerHeight;\n const footerHeight = o.hasFooter ? metrics.rowHeight : 0;\n const bodyTop = headerHeight;\n const bodyBottom = Math.max(bodyTop, h - footerHeight);\n const border = o.tokens.color.border;\n const base = o.sketch.seed >>> 0;\n const stroke = (x1: number, y1: number, x2: number, y2: number, seed: number): void => {\n const pen = new RoughPen(ctx, { ...o.sketch, seed: seed >>> 0 });\n pen.polyline(\n [\n { x: x1, y: y1 },\n { x: x2, y: y2 },\n ],\n { stroke: border, strokeWidth: 1 },\n );\n };\n\n // Vertical separators (internal column boundaries). Sticky row-header columns\n // stay pinned; scrolling columns shift with the horizontal scroll offset.\n let cursor = 0;\n for (let i = 0; i < o.columns.length - 1; i += 1) {\n cursor += o.widths[i] ?? 0;\n const pinned = i < (o.rowHeaderSpan ?? 0);\n const x = pinned ? cursor : cursor - o.scrollLeft;\n if (x <= 0 || x >= w) continue;\n stroke(x, 0, x, h, base ^ Math.imul(i + 1, 2246822519));\n }\n\n // Body row separators \u2014 clipped to the body band, shifted by vertical scroll.\n ctx.save();\n ctx.beginPath();\n ctx.rect(0, bodyTop, w, Math.max(0, bodyBottom - bodyTop));\n ctx.clip();\n const firstRow = Math.max(0, Math.floor(o.scrollTop / metrics.rowHeight) - 1);\n for (let r = firstRow; r < o.rowCount; r += 1) {\n const y = bodyTop + (r + 1) * metrics.rowHeight - o.scrollTop;\n if (y <= bodyTop) continue;\n if (y >= bodyBottom) break;\n stroke(0, y, w, y, base ^ Math.imul(r + 1, 3266489917));\n }\n ctx.restore();\n\n // Pinned header rule + footer top border.\n if (headerHeight > 0 && headerHeight < h) stroke(0, headerHeight, w, headerHeight, (base ^ 0x9e3779b9) >>> 0);\n if (footerHeight > 0 && bodyBottom > bodyTop) stroke(0, bodyBottom, w, bodyBottom, (base ^ 0x85ebca6b) >>> 0);\n\n // Wobbly frame (inset so its outer wobble isn't clipped at the canvas edge).\n const framePen = new RoughPen(ctx, { ...o.sketch, seed: base });\n framePen.rect(1.5, 1.5, Math.max(0, w - 3), Math.max(0, h - 3), { stroke: border, strokeWidth: 1 });\n\n ctx.restore();\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { ResolvedSketch } from '../../spec/sketch';\nimport type { ThemeTokens } from '../../theme';\nimport type { Rect } from '../../types';\nimport { getDevicePixelRatio } from '../../render/env';\nimport { RoughPen } from '../../rough';\nimport { setStyles, type ViewColumn } from './types';\nimport type { TableMetrics } from './style';\nexport interface SketchGridOverlay {\n sketch: ResolvedSketch;\n tokens: ThemeTokens;\n rect: Rect;\n dpr: number;\n columns: readonly ViewColumn[];\n widths: readonly number[];\n rowCount: number;\n headerRowCount: number;\n hasFooter: boolean;\n rowHeaderSpan?: number;\n metrics: TableMetrics;\n scrollLeft: number;\n scrollTop: number;\n}\n\n/**\n * Create a DPR-scaled overlay `<canvas>` positioned exactly over the table\n * rect. It lives as a sibling of the scroll host (`pointer-events: none`) so it\n * survives the host's `replaceChildren()` and lets scroll/click pass through.\n */\nexport function createSketchGridCanvas(rect: Rect): {\n canvas: HTMLCanvasElement;\n ctx: CanvasRenderingContext2D | null;\n dpr: number;\n} {\n const dpr = getDevicePixelRatio();\n const w = Math.max(0, rect.width);\n const h = Math.max(0, rect.height);\n const canvas = document.createElement('canvas');\n canvas.width = Math.max(1, Math.round(w * dpr));\n canvas.height = Math.max(1, Math.round(h * dpr));\n setStyles(canvas, {\n position: 'absolute',\n left: `${rect.x}px`,\n top: `${rect.y}px`,\n width: `${w}px`,\n height: `${h}px`,\n pointerEvents: 'none',\n });\n return { canvas, ctx: canvas.getContext('2d'), dpr };\n}\n\n/**\n * Draw the hand-drawn frame + column/row separators + header rule onto a\n * viewport-pinned overlay canvas. Vertical separators track horizontal scroll;\n * body row separators track vertical scroll and are clipped to the body band so\n * they never bleed over the sticky header/footer. Every line is seeded from its\n * own index so the wobble stays stable across scroll frames.\n */\nexport function paintSketchGridOverlay(ctx: CanvasRenderingContext2D, o: SketchGridOverlay): void {\n const w = Math.max(0, o.rect.width);\n const h = Math.max(0, o.rect.height);\n ctx.save();\n ctx.setTransform(o.dpr, 0, 0, o.dpr, 0, 0);\n ctx.clearRect(0, 0, w, h);\n\n const metrics = o.metrics;\n const headerHeight = o.headerRowCount * metrics.headerHeight;\n const footerHeight = o.hasFooter ? metrics.rowHeight : 0;\n const bodyTop = headerHeight;\n const bodyBottom = Math.max(bodyTop, h - footerHeight);\n const border = o.tokens.color.border;\n const base = o.sketch.seed >>> 0;\n const stroke = (x1: number, y1: number, x2: number, y2: number, seed: number): void => {\n const pen = new RoughPen(ctx, { ...o.sketch, seed: seed >>> 0 });\n pen.polyline(\n [\n { x: x1, y: y1 },\n { x: x2, y: y2 },\n ],\n { stroke: border, strokeWidth: 1 },\n );\n };\n\n // Vertical separators (internal column boundaries). Sticky row-header columns\n // stay pinned; scrolling columns shift with the horizontal scroll offset.\n let cursor = 0;\n for (let i = 0; i < o.columns.length - 1; i += 1) {\n cursor += o.widths[i] ?? 0;\n const pinned = i < (o.rowHeaderSpan ?? 0);\n const x = pinned ? cursor : cursor - o.scrollLeft;\n if (x <= 0 || x >= w) continue;\n stroke(x, 0, x, h, base ^ Math.imul(i + 1, 2246822519));\n }\n\n // Body row separators \u2014 clipped to the body band, shifted by vertical scroll.\n ctx.save();\n ctx.beginPath();\n ctx.rect(0, bodyTop, w, Math.max(0, bodyBottom - bodyTop));\n ctx.clip();\n const firstRow = Math.max(0, Math.floor(o.scrollTop / metrics.rowHeight) - 1);\n for (let r = firstRow; r < o.rowCount; r += 1) {\n const y = bodyTop + (r + 1) * metrics.rowHeight - o.scrollTop;\n if (y <= bodyTop) continue;\n if (y >= bodyBottom) break;\n stroke(0, y, w, y, base ^ Math.imul(r + 1, 3266489917));\n }\n ctx.restore();\n\n // Pinned header rule + footer top border.\n if (headerHeight > 0 && headerHeight < h) stroke(0, headerHeight, w, headerHeight, (base ^ 0x9e3779b9) >>> 0);\n if (footerHeight > 0 && bodyBottom > bodyTop) stroke(0, bodyBottom, w, bodyBottom, (base ^ 0x85ebca6b) >>> 0);\n\n // Wobbly frame (inset so its outer wobble isn't clipped at the canvas edge).\n const framePen = new RoughPen(ctx, { ...o.sketch, seed: base });\n framePen.rect(1.5, 1.5, Math.max(0, w - 3), Math.max(0, h - 3), { stroke: border, strokeWidth: 1 });\n\n ctx.restore();\n}\n"],
5
+ "mappings": "AAGA,SAAS,2BAA2B;AACpC,SAAS,gBAAgB;AACzB,SAAS,iBAAkC;AAuBpC,SAAS,uBAAuB,MAIrC;AACA,QAAM,MAAM,oBAAoB;AAChC,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,KAAK;AAChC,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM;AACjC,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,CAAC;AAC9C,SAAO,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,CAAC;AAC/C,YAAU,QAAQ;AAAA,IAChB,UAAU;AAAA,IACV,MAAM,GAAG,KAAK,CAAC;AAAA,IACf,KAAK,GAAG,KAAK,CAAC;AAAA,IACd,OAAO,GAAG,CAAC;AAAA,IACX,QAAQ,GAAG,CAAC;AAAA,IACZ,eAAe;AAAA,EACjB,CAAC;AACD,SAAO,EAAE,QAAQ,KAAK,OAAO,WAAW,IAAI,GAAG,IAAI;AACrD;AASO,SAAS,uBAAuB,KAA+B,GAA4B;AAChG,QAAM,IAAI,KAAK,IAAI,GAAG,EAAE,KAAK,KAAK;AAClC,QAAM,IAAI,KAAK,IAAI,GAAG,EAAE,KAAK,MAAM;AACnC,MAAI,KAAK;AACT,MAAI,aAAa,EAAE,KAAK,GAAG,GAAG,EAAE,KAAK,GAAG,CAAC;AACzC,MAAI,UAAU,GAAG,GAAG,GAAG,CAAC;AAExB,QAAM,UAAU,EAAE;AAClB,QAAM,eAAe,EAAE,iBAAiB,QAAQ;AAChD,QAAM,eAAe,EAAE,YAAY,QAAQ,YAAY;AACvD,QAAM,UAAU;AAChB,QAAM,aAAa,KAAK,IAAI,SAAS,IAAI,YAAY;AACrD,QAAM,SAAS,EAAE,OAAO,MAAM;AAC9B,QAAM,OAAO,EAAE,OAAO,SAAS;AAC/B,QAAM,SAAS,CAAC,IAAY,IAAY,IAAY,IAAY,SAAuB;AACrF,UAAM,MAAM,IAAI,SAAS,KAAK,EAAE,GAAG,EAAE,QAAQ,MAAM,SAAS,EAAE,CAAC;AAC/D,QAAI;AAAA,MACF;AAAA,QACE,EAAE,GAAG,IAAI,GAAG,GAAG;AAAA,QACf,EAAE,GAAG,IAAI,GAAG,GAAG;AAAA,MACjB;AAAA,MACA,EAAE,QAAQ,QAAQ,aAAa,EAAE;AAAA,IACnC;AAAA,EACF;AAIA,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,SAAS,GAAG,KAAK,GAAG;AAChD,cAAU,EAAE,OAAO,CAAC,KAAK;AACzB,UAAM,SAAS,KAAK,EAAE,iBAAiB;AACvC,UAAM,IAAI,SAAS,SAAS,SAAS,EAAE;AACvC,QAAI,KAAK,KAAK,KAAK,EAAG;AACtB,WAAO,GAAG,GAAG,GAAG,GAAG,OAAO,KAAK,KAAK,IAAI,GAAG,UAAU,CAAC;AAAA,EACxD;AAGA,MAAI,KAAK;AACT,MAAI,UAAU;AACd,MAAI,KAAK,GAAG,SAAS,GAAG,KAAK,IAAI,GAAG,aAAa,OAAO,CAAC;AACzD,MAAI,KAAK;AACT,QAAM,WAAW,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,YAAY,QAAQ,SAAS,IAAI,CAAC;AAC5E,WAAS,IAAI,UAAU,IAAI,EAAE,UAAU,KAAK,GAAG;AAC7C,UAAM,IAAI,WAAW,IAAI,KAAK,QAAQ,YAAY,EAAE;AACpD,QAAI,KAAK,QAAS;AAClB,QAAI,KAAK,WAAY;AACrB,WAAO,GAAG,GAAG,GAAG,GAAG,OAAO,KAAK,KAAK,IAAI,GAAG,UAAU,CAAC;AAAA,EACxD;AACA,MAAI,QAAQ;AAGZ,MAAI,eAAe,KAAK,eAAe,EAAG,QAAO,GAAG,cAAc,GAAG,eAAe,OAAO,gBAAgB,CAAC;AAC5G,MAAI,eAAe,KAAK,aAAa,QAAS,QAAO,GAAG,YAAY,GAAG,aAAa,OAAO,gBAAgB,CAAC;AAG5G,QAAM,WAAW,IAAI,SAAS,KAAK,EAAE,GAAG,EAAE,QAAQ,MAAM,KAAK,CAAC;AAC9D,WAAS,KAAK,KAAK,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,QAAQ,QAAQ,aAAa,EAAE,CAAC;AAElG,MAAI,QAAQ;AACd;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,7 @@
1
+ import type { ResolvedSketch } from '../../spec/sketch.js';
2
+ /**
3
+ * A hand-drawn data bar as an embedded canvas, vertically centered in its cell
4
+ * like the clean `.gtv-bar`. A small pad keeps the outer wobble from clipping.
5
+ */
6
+ export declare function buildSketchDataBar(sketch: ResolvedSketch, color: string, left: number, width: number, barHeight: number, seed: number): HTMLCanvasElement | null;
7
+ //# sourceMappingURL=sketchBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sketchBar.d.ts","sourceRoot":"","sources":["../../../src/charts/tableView/sketchBar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAKxD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,iBAAiB,GAAG,IAAI,CAwB1B"}