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
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/charts/bubbleMap.ts"],
4
+ "sourcesContent": ["/**\n * Bubble map \u2014 one circle per row at its longitude/latitude, its area \u221D `size`,\n * colored by an optional numeric (sequential ramp) or categorical (palette)\n * field, over an optional GeoJSON basemap.\n *\n * With a basemap the projection is fitted to it, so the map stays put as data\n * changes; without one it is fitted to the bubbles. Rows that can't be placed\n * (non-finite or out-of-range coordinates, non-finite sizes, or \u2014 over a\n * basemap \u2014 positions outside the map) are counted as omitted, never guessed.\n * Negative sizes can't be drawn as area, so their location is marked by a\n * hollow ring instead of a sized disc.\n */\n\nimport { contrastRatio, ordinalColorScale, parseColor, rgbaToCss, sequential, sequentialColorScale, withAlpha } from '../color';\nimport { formatValue } from '../format';\nimport { backOut } from '../animation/easing';\nimport { staggerProgress } from '../animation/stagger';\nimport type { MarkBoundary } from '../render/evidence';\nimport { boxesOverlap, fitLabel } from '../render/labelLedger';\nimport { overlayTextToCanvasCmd } from '../render/overlayText';\nimport type { Surface } from '../render/surface';\nimport { fontString, measureText } from '../render/text';\nimport { RoughPen } from '../rough';\nimport { roundedRect } from '../shape';\nimport { resolveSketch } from '../spec/sketch';\nimport type { SelectionValue } from '../spec/selection';\nimport type { BubbleMapSpec, ChartSpec, GeoFeatureCollection, MapProjection } from '../spec/types';\nimport type { ThemeTokens } from '../theme';\nimport type { Datum, Rect, RGBA, Size } from '../types';\nimport { accessor, inferType, toKey, toNumber } from '../util/data';\nimport type { InteractionModel, TooltipContent, TooltipRow } from '../interaction/types';\nimport { FOCUS_VEIL, hoverFocusEnabled, paintCutoutVeil } from '../interaction/veil';\nimport { resolvePalette } from '../runtime/categories';\nimport { addOverlayText, drawCategoricalLegend, drawTitleBlock, type LegendEntry } from './chrome';\nimport { drawColorRampLegend } from './colorRamp';\nimport { rowAlpha } from './emphasis';\nimport { albersParallels, centralMeridianOf, fitBounds, polygonsOf, projector, wrapDegrees, type MapFit, type ProjectedBounds, type Projector } from './geo';\nimport { compositeOver, contrastTarget, inkOn, knownBackdrop, toneForContrast } from './legibility';\nimport { lerp, mixColor, mixFill, morphInput, morphKeyed, rampAt, stashMorphFrame, switchAt, type MorphPlan, type RampStop } from './morphFrame';\nimport { drawNoData } from './noData';\nimport type { RenderContext } from './index';\n\nconst TAU = Math.PI * 2;\n/** Fill opacity of a bubble at full strength (overlaps stay legible); dark themes run a little denser so hues don't muddy. */\nconst bubbleAlpha = (tokens: ThemeTokens): number => (tokens.dark ? 0.8 : 0.7);\n/** Radius of a zero-size bubble \u2014 still a visible dot. */\nconst MIN_RADIUS = 2;\n/** Radius of the ring marking a negative size (which has no area to draw). */\nconst HOLLOW_RADIUS = 3;\n/** A bubble fainter than this against the backdrop gets an outline in its own deepened hue. */\nconst PALE_CONTRAST = 1.6;\n/** Rings carry no fill, so their stroke needs a firmer contrast. */\nconst RING_CONTRAST = 3;\n/** Pointer slop (px) for hovering bubbles too small to hit exactly. */\nconst HIT_SLOP = 6;\n/** Fraction of the entrance spread across bubbles as a west \u2192 east wave. */\nconst ENTRANCE_STAGGER = 0.45;\n/** Labels are tried largest-first; beyond this many the rest are omitted. */\nconst MAX_LABELS = 60;\n/** Map area (px\u00B2) per label: keeps a labeled map calm rather than crowded. */\nconst LABEL_AREA = 14000;\nconst LABEL_GAP = 3;\n\ntype ColorMode = 'none' | 'numeric' | 'categorical';\ntype Polygon = number[][][];\n\n/** A bubble as painted, in pixel space, keyed so an update carries it to its new place. */\ninterface BubbleMark {\n key: string;\n x: number;\n y: number;\n r: number;\n fill: string;\n /** Where a numeric color sits on its ramp, so a morph can travel along it. */\n ramp?: RampStop;\n /** Separation outline: the backdrop, or a deepened tone of a pale fill (or a ring's color). */\n stroke: string;\n /** The outline identifies a pale fill (recorded as the mark's boundary). */\n outlined: boolean;\n /** Negative size: drawn as a ring, since it has no area. */\n hollow: boolean;\n /** Formatted label ('' for none). */\n label: string;\n /** Highlight alpha, carried so emphasis changes fade instead of snapping. */\n emph: number;\n /** Fade for bubbles arriving or leaving mid-morph. */\n alpha: number;\n}\n\n/** The observation behind a static bubble. */\ninterface Bubble extends BubbleMark {\n row: Datum;\n index: number;\n lon: number;\n lat: number;\n size: number | null;\n colorValue: unknown;\n colorNoData: boolean;\n rawLabel: unknown;\n}\n\ninterface Observation {\n row: Datum;\n index: number;\n lon: number;\n lat: number;\n /** Finite size, or null when no size is encoded. */\n size: number | null;\n}\n\ninterface ColorPlan {\n mode: ColorMode;\n domain: [number, number] | null;\n scheme: string;\n entries: LegendEntry[];\n fillOf(row: Datum): { fill: string; ramp?: RampStop; value: unknown; noData: boolean };\n}\n\ninterface RadiusLimits {\n rMax: number;\n rMin: number;\n /** Radius of every dot when no size is encoded. */\n dot: number;\n}\n\nconst clamp = (v: number, lo: number, hi: number): number => (v < lo ? lo : v > hi ? hi : v);\n\n/** Finite numbers and numeric strings only: booleans and dates are not coordinates or sizes. */\nfunction numeric(value: unknown): number {\n return typeof value === 'number' || typeof value === 'string' ? toNumber(value) : NaN;\n}\n\nfunction fieldOf(def: unknown): string | undefined {\n const field = (def as { field?: unknown } | undefined)?.field;\n return typeof field === 'string' && field !== '' ? field : undefined;\n}\n\nfunction insetRect(rect: Rect, pad: number): Rect {\n const p = Math.max(0, Math.min(pad, rect.width / 4, rect.height / 4));\n return { x: rect.x + p, y: rect.y + p, width: rect.width - p * 2, height: rect.height - p * 2 };\n}\n\n/** The map area inside `spec.padding` (ignored if it would leave no room). */\nfunction applyPadding(rect: Rect, padding: unknown): Rect {\n if (!padding || typeof padding !== 'object') return rect;\n const p = padding as Record<string, unknown>;\n const side = (v: unknown): number => (typeof v === 'number' && Number.isFinite(v) && v > 0 ? v : 0);\n const [top, right, bottom, left] = [side(p.top), side(p.right), side(p.bottom), side(p.left)];\n const out = { x: rect.x + left, y: rect.y + top, width: rect.width - left - right, height: rect.height - top - bottom };\n return out.width >= 8 && out.height >= 8 ? out : rect;\n}\n\n/** Rows that can be placed: finite in-range coordinates (any finite pair under 'identity') and a finite size. */\nfunction readObservations(map: BubbleMapSpec, planar: boolean): Observation[] {\n const rows = Array.isArray(map.data) ? map.data : [];\n const lonField = fieldOf(map.encoding?.longitude);\n const latField = fieldOf(map.encoding?.latitude);\n if (!lonField || !latField) return [];\n const readLon = accessor(lonField);\n const readLat = accessor(latField);\n const sizeField = fieldOf(map.encoding?.size);\n const readSize = sizeField ? accessor(sizeField) : null;\n const out: Observation[] = [];\n rows.forEach((row, index) => {\n if (row == null || typeof row !== 'object') return;\n const lon = numeric(readLon(row));\n const lat = numeric(readLat(row));\n if (!Number.isFinite(lon) || !Number.isFinite(lat)) return;\n if (!planar && (Math.abs(lon) > 180 || Math.abs(lat) > 90)) return;\n let size: number | null = null;\n if (readSize) {\n size = numeric(readSize(row));\n if (!Number.isFinite(size)) return;\n }\n out.push({ row, index, lon, lat, size });\n });\n return out;\n}\n\n/**\n * Basemap polygons (rings of finite [x, y] positions); malformed geometry is\n * skipped. Geographic positions must be plausible degrees \u2014 latitude within \u00B190\n * and longitude within \u00B1360 (0\u2013360 basemaps stay valid) \u2014 so one corrupt vertex\n * can't drag the projection and fit off the planet.\n */\nfunction basemapPolygons(geo: GeoFeatureCollection | undefined, planar: boolean): Polygon[] {\n const features = geo && Array.isArray(geo.features) ? geo.features : [];\n const out: Polygon[] = [];\n for (const feature of features) {\n if (!feature || typeof feature !== 'object') continue;\n const parts: unknown = polygonsOf(feature);\n if (!Array.isArray(parts)) continue;\n for (const polygon of parts) {\n if (!Array.isArray(polygon)) continue;\n const rings: number[][][] = [];\n for (const ring of polygon) {\n if (!Array.isArray(ring)) continue;\n const points: number[][] = [];\n for (const pos of ring) {\n if (!Array.isArray(pos)) continue;\n const [x, y] = pos as unknown[];\n if (typeof x !== 'number' || typeof y !== 'number' || !Number.isFinite(x) || !Number.isFinite(y)) continue;\n if (!planar && (Math.abs(x) > 360 || Math.abs(y) > 90)) continue;\n points.push([x, y]);\n }\n if (points.length) rings.push(points);\n }\n if (rings.length) out.push(rings);\n }\n }\n return out;\n}\n\nfunction radiusLimits(map: BubbleMapSpec, mapRect: Rect): RadiusLimits {\n const extent = Math.max(0, Math.min(mapRect.width, mapRect.height));\n const ceiling = Math.max(4, extent / 2);\n const requested = typeof map.maxRadius === 'number' && Number.isFinite(map.maxRadius) && map.maxRadius > 0 ? Math.min(map.maxRadius, ceiling) : null;\n const rMax = requested ?? clamp(extent * 0.06, 4, 40);\n return { rMax, rMin: Math.min(MIN_RADIUS, rMax), dot: requested ?? clamp(extent * 0.012, 4, 6) };\n}\n\nfunction paletteOf(map: BubbleMapSpec, tokens: ThemeTokens): string[] {\n const valid = (colors: unknown): string[] =>\n Array.isArray(colors) ? colors.filter((c): c is string => typeof c === 'string' && parseColor(c) != null) : [];\n const resolved = valid(resolvePalette(map.palette, tokens));\n if (resolved.length) return resolved;\n const theme = valid(tokens.color.palette);\n return theme.length ? theme : ['#3b82f6'];\n}\n\nfunction categoryLabel(value: unknown, format?: string): string {\n const key = toKey(value);\n return key === '' ? '(blank)' : formatValue(value, format) || key;\n}\n\nfunction resolveColors(map: BubbleMapSpec, observations: readonly Observation[], tokens: ThemeTokens): ColorPlan {\n const palette = paletteOf(map, tokens);\n const scheme = map.scheme ?? 'teal';\n const field = fieldOf(map.encoding?.color);\n if (!field) {\n const fill = palette[0];\n return { mode: 'none', domain: null, scheme, entries: [], fillOf: () => ({ fill, value: undefined, noData: false }) };\n }\n const read = accessor(field);\n const rows = observations.map((o) => o.row);\n const declared = map.encoding.color?.type;\n if ((declared ?? inferType(rows, field)) === 'quantitative') {\n let min = Infinity;\n let max = -Infinity;\n for (const row of rows) {\n const v = numeric(read(row));\n if (!Number.isFinite(v)) continue;\n if (v < min) min = v;\n if (v > max) max = v;\n }\n const domain: [number, number] | null = min <= max ? [min, max] : null;\n const scale = domain && sequentialColorScale({ domain, interpolator: sequential(scheme) });\n const noData = tokens.color.textMuted;\n return {\n mode: 'numeric',\n domain,\n scheme,\n entries: [],\n fillOf: (row) => {\n const raw = read(row);\n const v = numeric(raw);\n if (!scale || !domain || !Number.isFinite(v)) return { fill: noData, value: raw, noData: true };\n return { fill: rgbaToCss(scale.map(v)), ramp: { scheme, at: rampAt(domain, v) }, value: v, noData: false };\n },\n };\n }\n const keys: string[] = [];\n const raws = new Map<string, unknown>();\n for (const row of rows) {\n const raw = read(row);\n const key = toKey(raw);\n if (!raws.has(key)) {\n raws.set(key, raw);\n keys.push(key);\n }\n }\n const scale = ordinalColorScale({ domain: keys, palette });\n const format = map.encoding.color?.format;\n return {\n mode: 'categorical',\n domain: null,\n scheme,\n entries: keys.map((key) => ({ label: categoryLabel(raws.get(key), format), color: rgbaToCss(scale.map(key)), symbol: 'circle' as const })),\n fillOf: (row) => {\n const raw = read(row);\n return { fill: rgbaToCss(scale.map(toKey(raw))), value: raw, noData: false };\n },\n };\n}\n\nfunction legendVisible(legend: BubbleMapSpec['legend']): boolean {\n if (legend === false) return false;\n return !(legend && typeof legend === 'object' && legend.show === false);\n}\n\n/**\n * Where a categorical legend goes: as requested, else into the margin the map\n * leaves anyway \u2014 beside a tall map, below a wide one.\n */\nfunction legendPosition(map: BubbleMapSpec, area: Rect, bounds: ProjectedBounds | null): 'top' | 'right' | 'bottom' | 'left' {\n const requested = map.legend && typeof map.legend === 'object' ? map.legend.position : undefined;\n if (requested === 'top' || requested === 'right' || requested === 'bottom' || requested === 'left') return requested;\n if (!(area.width > 0) || !(area.height > 0)) return 'bottom';\n const spanX = bounds ? bounds.maxX - bounds.minX : 0;\n const spanY = bounds ? bounds.maxY - bounds.minY : 0;\n const mapAspect = spanX > 0 && spanY > 0 ? spanX / spanY : 1.5;\n return mapAspect > area.width / area.height ? 'bottom' : 'right';\n}\n\nfunction boundsOf(points: readonly (readonly number[])[]): ProjectedBounds {\n let minX = Infinity;\n let maxX = -Infinity;\n let minY = Infinity;\n let maxY = -Infinity;\n for (const [x, y] of points) {\n if (x < minX) minX = x;\n if (x > maxX) maxX = x;\n if (y < minY) minY = y;\n if (y > maxY) maxY = y;\n }\n return { minX, maxX, minY, maxY };\n}\n\n/** Bubbles-only fit: their bounds, widened to a small default extent when they all coincide. */\nfunction pointBounds(projected: readonly [number, number][], observations: readonly Observation[], project: Projector, planar: boolean): ProjectedBounds {\n const b = boundsOf(projected);\n const tolerance = 1e-9 * Math.max(1, Math.abs(b.minX), Math.abs(b.maxX), Math.abs(b.minY), Math.abs(b.maxY));\n if (b.maxX - b.minX > tolerance || b.maxY - b.minY > tolerance) return b;\n let halfX = 1;\n let halfY = 1;\n if (!planar) {\n // About a degree around the spot, in the projection's own units.\n const { lon, lat } = observations[0];\n const [x0, y0] = project([lon - 1, clamp(lat - 1, -89, 89)]);\n const [x1, y1] = project([lon + 1, clamp(lat + 1, -89, 89)]);\n halfX = Math.abs(x1 - x0) / 2 || 1;\n halfY = Math.abs(y1 - y0) / 2 || 1;\n }\n const cx = (b.minX + b.maxX) / 2;\n const cy = (b.minY + b.maxY) / 2;\n return { minX: cx - halfX, maxX: cx + halfX, minY: cy - halfY, maxY: cy + halfY };\n}\n\n/** Project the basemap (when it has extent) and choose the projection the bubbles share. */\nfunction resolveProjection(\n kind: MapProjection,\n basemap: readonly Polygon[],\n observations: readonly Observation[],\n): { project: Projector; lon0: number; basemap: Polygon[] | null; bounds: ProjectedBounds | null } {\n const planar = kind === 'identity';\n const cone = (lats: readonly number[]) => {\n let lo = Infinity;\n let hi = -Infinity;\n for (const lat of lats) {\n if (lat < lo) lo = lat;\n if (lat > hi) hi = lat;\n }\n return lo <= hi ? albersParallels([lo, hi]) : undefined;\n };\n if (basemap.length) {\n const lons: number[] = [];\n const lats: number[] = [];\n for (const polygon of basemap) {\n for (const ring of polygon) {\n for (const [x, y] of ring) {\n lons.push(x);\n lats.push(y);\n }\n }\n }\n const lon0 = planar ? 0 : centralMeridianOf(lons);\n const project = projector(kind, lon0, kind === 'albers' ? cone(lats) : undefined);\n const projected: Polygon[] = [];\n const all: number[][] = [];\n for (const polygon of basemap) {\n const rings: number[][][] = [];\n for (const ring of polygon) {\n const pts: number[][] = [];\n for (const pos of ring) {\n const p = project(pos as [number, number]);\n if (!Number.isFinite(p[0]) || !Number.isFinite(p[1])) continue;\n pts.push(p);\n all.push(p);\n }\n if (pts.length >= 3) rings.push(pts);\n }\n if (rings.length) projected.push(rings);\n }\n const bounds = boundsOf(all);\n if (projected.length && bounds.maxX - bounds.minX > 0 && bounds.maxY - bounds.minY > 0) {\n return { project, lon0, basemap: projected, bounds };\n }\n }\n const lon0 = planar ? 0 : centralMeridianOf(observations.map((o) => o.lon));\n const project = projector(kind, lon0, kind === 'albers' ? cone(observations.map((o) => o.lat)) : undefined);\n return { project, lon0, basemap: null, bounds: null };\n}\n\n/** Graticule spacings (degrees) to pick from: about ten lines across the data. */\nconst GRATICULE_STEPS = [0.1, 0.2, 0.5, 1, 2, 5, 10, 15, 30];\n\n/**\n * A hairline graticule for maps without a basemap, so the bubbles still read as\n * places on a globe (and the projection's shape shows). Lines run well past\n * the data and are clipped to the map. Planar ('identity') maps have none.\n */\nfunction graticuleLines(kind: MapProjection, project: Projector, fit: MapFit, observations: readonly Observation[], lon0: number): number[][][] {\n if (kind === 'identity' || observations.length === 0) return [];\n let relMin = Infinity;\n let relMax = -Infinity;\n let latMin = Infinity;\n let latMax = -Infinity;\n for (const o of observations) {\n const d = wrapDegrees(o.lon - lon0);\n relMin = Math.min(relMin, d);\n relMax = Math.max(relMax, d);\n latMin = Math.min(latMin, o.lat);\n latMax = Math.max(latMax, o.lat);\n }\n const span = Math.max(relMax - relMin, latMax - latMin, 2);\n const step = GRATICULE_STEPS.find((s) => span / s <= 10) ?? 30;\n const latLimit = kind === 'mercator' ? 80 : 90;\n const lonLo = lon0 + Math.max(-180, relMin - span * 3);\n const lonHi = lon0 + Math.min(180, relMax + span * 3);\n const latLo = Math.max(-latLimit, latMin - span * 3);\n const latHi = Math.min(latLimit, latMax + span * 3);\n const toScreen = (lon: number, lat: number): number[] | null => {\n const [x, y] = project([lon, lat]);\n const sx = fit.x(x);\n const sy = fit.y(y);\n return Number.isFinite(sx) && Number.isFinite(sy) ? [sx, sy] : null;\n };\n const lines: number[][][] = [];\n const add = (points: Array<number[] | null>): void => {\n const line = points.filter((p): p is number[] => p != null);\n if (line.length >= 2) lines.push(line);\n };\n // Meridians are straight in all three projections; Albers parallels are arcs.\n const arcSteps = kind === 'albers' ? 48 : 1;\n for (let k = Math.ceil(lonLo / step); k * step <= lonHi && lines.length < 200; k += 1) {\n add([toScreen(k * step, latLo), toScreen(k * step, latHi)]);\n }\n for (let k = Math.ceil(latLo / step); k * step <= latHi && lines.length < 400; k += 1) {\n const lat = k * step;\n add(Array.from({ length: arcSteps + 1 }, (_, i) => toScreen(lonLo + ((lonHi - lonLo) * i) / arcSteps, lat)));\n }\n return lines;\n}\n\nfunction paintGraticule(surface: Surface, tokens: ThemeTokens, lines: readonly number[][][], clip: Rect, pen: RoughPen | null): void {\n if (!lines.length) return;\n const ctx = surface.marks.ctx;\n ctx.save();\n ctx.beginPath();\n ctx.rect(clip.x, clip.y, clip.width, clip.height);\n ctx.clip();\n ctx.setLineDash([]);\n ctx.globalAlpha = 1;\n ctx.lineWidth = 1;\n ctx.strokeStyle = tokens.color.grid;\n for (const line of lines) {\n if (pen) {\n pen.polyline(line.map(([x, y]) => ({ x, y })), { stroke: tokens.color.grid, strokeWidth: 1 });\n continue;\n }\n ctx.beginPath();\n line.forEach(([x, y], i) => (i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y)));\n ctx.stroke();\n }\n ctx.restore();\n}\n\nfunction niceFloor(value: number): number {\n if (!(value > 0) || !Number.isFinite(value)) return 0;\n const unit = 10 ** Math.floor(Math.log10(value));\n const clean = (n: number): number => Number(n.toPrecision(12));\n let nice = clean(Math.floor(value / unit + 1e-9) * unit);\n if (nice < value * 0.7) nice = clean(Math.floor((value * 10) / unit + 1e-9) * (unit / 10));\n return nice > 0 ? nice : value;\n}\n\n/**\n * The size key's number format: the field's own, but large round values in a\n * plain (grouped/fixed/integer) format read better compact \u2014 20M, not 20,000,000.\n */\nfunction legendFormat(format: string | undefined, largest: number): string | undefined {\n if (largest < 1e4) return format ?? (largest >= 1e3 ? ',' : undefined);\n if (format == null) return 's';\n const plain = /^(\\$)?,?(\\.\\d+)?[fd]?$/.exec(format.trim());\n return plain ? `${plain[1] ?? ''}s` : format;\n}\n\nfunction formatLocation(b: Pick<Bubble, 'lon' | 'lat'>, planar: boolean, map: BubbleMapSpec): string {\n const lonFormat = map.encoding?.longitude?.format;\n const latFormat = map.encoding?.latitude?.format;\n if (planar) return `${formatValue(b.lon, lonFormat)}, ${formatValue(b.lat, latFormat)}`;\n const deg = (v: number, pos: string, neg: string, format?: string): string => {\n const text = format ? formatValue(Math.abs(v), format) : formatValue(Math.round(Math.abs(v) * 100) / 100);\n return `${text}\u00B0${v < 0 ? neg : v > 0 ? pos : ''}`;\n };\n return `${deg(b.lat, 'N', 'S', latFormat)}, ${deg(b.lon, 'E', 'W', lonFormat)}`;\n}\n\nconst BUBBLE_MORPH: MorphPlan<BubbleMark> = {\n lerp: (a, b, t) => ({\n key: b.key,\n x: lerp(a.x, b.x, t),\n y: lerp(a.y, b.y, t),\n r: lerp(a.r, b.r, t),\n ...mixFill(a, b, t),\n stroke: mixColor(a.stroke, b.stroke, t),\n outlined: switchAt(a.outlined, b.outlined, t),\n hollow: switchAt(a.hollow, b.hollow, t),\n label: b.label,\n emph: lerp(a.emph, b.emph, t),\n alpha: lerp(a.alpha, b.alpha, t),\n }),\n enter: (b, t) => ({ ...b, r: b.r * t, alpha: t }),\n exit: (a, t) => ({ ...a, r: a.r * (1 - t), alpha: a.alpha * (1 - t) }),\n};\n\nconst toMark = (b: Bubble): BubbleMark => ({\n key: b.key, x: b.x, y: b.y, r: b.r, fill: b.fill, ramp: b.ramp, stroke: b.stroke,\n outlined: b.outlined, hollow: b.hollow, label: b.label, emph: b.emph, alpha: b.alpha,\n});\n\n/** Paint bubbles in order (each at its highlight \u00D7 fade alpha), clipped to the map. */\nfunction paintBubbles(surface: Surface, marks: readonly BubbleMark[], clip: Rect, pen: RoughPen | null, fillAlpha: number): void {\n const ctx = surface.marks.ctx;\n ctx.save();\n ctx.beginPath();\n ctx.rect(clip.x, clip.y, clip.width, clip.height);\n ctx.clip();\n ctx.setLineDash([]);\n for (const m of marks) {\n const a = m.emph * m.alpha;\n if (!(m.r > 0) || !(a > 0) || !Number.isFinite(m.x) || !Number.isFinite(m.y)) continue;\n const dimmed = m.emph < 1;\n if (pen) {\n ctx.globalAlpha = a;\n pen.circle(m.x, m.y, m.r, m.hollow\n ? { stroke: m.stroke, strokeWidth: 1.5 }\n : { fill: m.fill, fillAlpha, stroke: m.stroke, strokeWidth: 1 });\n } else {\n ctx.beginPath();\n ctx.arc(m.x, m.y, m.r, 0, TAU);\n if (m.hollow) {\n ctx.globalAlpha = a;\n ctx.strokeStyle = m.stroke;\n ctx.lineWidth = 1.5;\n ctx.stroke();\n } else {\n ctx.globalAlpha = fillAlpha * a;\n ctx.fillStyle = m.fill;\n ctx.fill();\n ctx.globalAlpha = a;\n ctx.strokeStyle = m.stroke;\n ctx.lineWidth = 1;\n ctx.stroke();\n }\n }\n if (m.hollow) {\n surface.evidence?.mark('point', m.x - m.r - 0.75, m.y - m.r - 0.75, m.r * 2 + 1.5, m.r * 2 + 1.5, m.stroke, a, clip, 1, undefined, dimmed);\n } else {\n const boundary: MarkBoundary | undefined = m.outlined ? { color: m.stroke, opacity: a, width: 1 } : undefined;\n surface.evidence?.mark('point', m.x - m.r, m.y - m.r, m.r * 2, m.r * 2, m.fill, fillAlpha * a, clip, 1, undefined, dimmed, boundary);\n }\n }\n ctx.globalAlpha = 1;\n ctx.restore();\n}\n\n/** Quiet land under the bubbles: a soft neutral fill, hairline borders in the backdrop. */\nfunction paintBasemap(surface: Surface, tokens: ThemeTokens, polygons: readonly Polygon[], bg: string, pen: RoughPen | null): void {\n const ctx = surface.marks.ctx;\n ctx.save();\n ctx.lineJoin = 'round';\n ctx.setLineDash([]);\n ctx.globalAlpha = 1;\n ctx.fillStyle = withAlpha(tokens.color.textMuted, tokens.dark ? 0.2 : 0.13);\n ctx.strokeStyle = bg;\n ctx.lineWidth = 0.8;\n for (const polygon of polygons) {\n ctx.beginPath();\n for (const ring of polygon) {\n ring.forEach(([x, y], i) => (i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y)));\n ctx.closePath();\n }\n ctx.fill('evenodd');\n if (!pen) ctx.stroke();\n }\n if (pen) {\n const stroke = withAlpha(tokens.color.textMuted, 0.45);\n for (const polygon of polygons) {\n for (const ring of polygon) pen.polygon(ring.map(([x, y]) => ({ x, y })), { stroke, strokeWidth: 0.8 });\n }\n }\n ctx.restore();\n}\n\n/** No map to draw: bubbles on screen shrink away, and a later update grows its bubbles in. */\nfunction drawLeavingBubbles(surface: Surface, clip: Rect, fillAlpha: number, context?: RenderContext): void {\n const morph = morphInput<BubbleMark[]>(context);\n const leaving = morph && Array.isArray(morph.from) ? morphKeyed(morph.from, [], morph.t, BUBBLE_MORPH).exits : [];\n stashMorphFrame(surface, 'bubbleMap', leaving);\n if (leaving.length) paintBubbles(surface, leaving, clip, null, fillAlpha);\n}\n\n/** Entrance pop-in: each bubble grows from its center with a slight overshoot, as a west \u2192 east wave. */\nfunction entranceMarks(marks: readonly BubbleMark[], t: number): BubbleMark[] {\n const n = marks.length;\n const rank = new Array<number>(n);\n marks\n .map((_, i) => i)\n .sort((a, b) => marks[a].x - marks[b].x || a - b)\n .forEach((index, position) => (rank[index] = position));\n const stagger = n >= 3 ? ENTRANCE_STAGGER : 0;\n return marks.map((m, i) => ({ ...m, r: m.r * Math.max(0, staggerProgress(t, rank[i], n, stagger, backOut)) }));\n}\n\nfunction intersectArea(a: Rect, b: Rect): number {\n const w = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const h = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n return w > 0 && h > 0 ? w * h : 0;\n}\n\nfunction pointInRing(x: number, y: number, ring: readonly number[][]): boolean {\n let inside = false;\n for (let i = 0, j = ring.length - 1; i < ring.length; j = i, i += 1) {\n const [xi, yi] = ring[i];\n const [xj, yj] = ring[j];\n if (yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi) inside = !inside;\n }\n return inside;\n}\n\n/** Share of a rect covered by land, sampled on a small grid. */\nfunction landShare(rect: Rect, polygons: readonly Polygon[] | null): number {\n if (!polygons?.length) return 0;\n let hits = 0;\n let total = 0;\n for (let i = 0; i < 4; i += 1) {\n for (let j = 0; j < 3; j += 1) {\n const x = rect.x + ((i + 0.5) / 4) * rect.width;\n const y = rect.y + ((j + 0.5) / 3) * rect.height;\n total += 1;\n if (polygons.some((polygon) => polygon.length > 0 && pointInRing(x, y, polygon[0]) && !polygon.slice(1).some((hole) => pointInRing(x, y, hole)))) hits += 1;\n }\n }\n return hits / total;\n}\n\n/**\n * A compact size key \u2014 two or three nested reference circles on the map's own\n * scale \u2014 in whichever corner of the map hides the fewest bubbles. Skipped when\n * the map is small or every corner is crowded. Returns the panel it occupies.\n */\nfunction drawSizeLegend(\n surface: Surface,\n tokens: ThemeTokens,\n map: BubbleMapSpec,\n args: { mapRect: Rect; bubbles: readonly Bubble[]; sMax: number; limits: RadiusLimits; basemap: Polygon[] | null; bg: string; pen: RoughPen | null },\n): Rect | null {\n const { mapRect, bubbles, sMax, limits, basemap, bg, pen } = args;\n const sizeDef = map.encoding?.size;\n const sizeField = fieldOf(sizeDef);\n if (!sizeField || !(sMax > 0) || limits.rMax < 6 || mapRect.width < 260 || mapRect.height < 150) return null;\n const labelSize = tokens.font.size.tiny;\n const labelH = labelSize * 1.2;\n const radius = (v: number): number => Math.max(limits.rMin, limits.rMax * Math.sqrt(v / sMax));\n const refs: Array<{ value: number; r: number }> = [];\n for (let v = niceFloor(sMax); refs.length < 3 && v > 0; v = niceFloor(v / 4)) {\n const r = radius(v);\n const prev = refs[refs.length - 1];\n if (prev && (2 * (prev.r - r) < labelH + 1 || r < 3)) break;\n refs.push({ value: v, r });\n }\n if (!refs.length) return null;\n const texts = refs.map((ref) => formatValue(ref.value, legendFormat(sizeDef?.format, refs[0].value)));\n const font = fontString(labelSize, tokens.font.family, tokens.font.weight.normal);\n const titleFont = fontString(labelSize, tokens.font.family, tokens.font.weight.medium);\n const title = sizeDef?.title ?? sizeField;\n const r1 = refs[0].r;\n const padX = 8;\n const padY = 6;\n const gap = 8;\n const labelW = Math.max(...texts.map((text) => measureText(text, font).width));\n const width = Math.min(180, Math.max(r1 * 2 + gap + labelW, measureText(title, titleFont).width) + padX * 2);\n const titleH = labelH * 1.5 + 2;\n const height = padY * 2 + titleH + r1 * 2;\n if (width > mapRect.width * 0.45 || height > mapRect.height * 0.6) return null;\n const m = 6;\n const corners: Rect[] = [\n { x: mapRect.x + m, y: mapRect.y + mapRect.height - m - height, width, height },\n { x: mapRect.x + mapRect.width - m - width, y: mapRect.y + mapRect.height - m - height, width, height },\n { x: mapRect.x + m, y: mapRect.y + m, width, height },\n { x: mapRect.x + mapRect.width - m - width, y: mapRect.y + m, width, height },\n ];\n let best: Rect | null = null;\n let bestScore = Infinity;\n let bestOverlap = 0;\n for (const rect of corners) {\n let overlap = 0;\n for (const b of bubbles) overlap += intersectArea(rect, { x: b.x - b.r, y: b.y - b.r, width: b.r * 2, height: b.r * 2 });\n const score = overlap + landShare(rect, basemap) * width * height * 0.25;\n if (score < bestScore) {\n best = rect;\n bestScore = score;\n bestOverlap = overlap;\n }\n }\n if (!best || bestOverlap > width * height * 0.08) return null;\n\n const ctx = surface.marks.ctx;\n const muted = tokens.color.textMuted;\n ctx.save();\n ctx.globalAlpha = 1;\n ctx.setLineDash([]);\n ctx.beginPath();\n roundedRect(ctx, best.x, best.y, best.width, best.height, 6);\n ctx.fillStyle = withAlpha(bg, 0.88);\n ctx.fill();\n ctx.lineWidth = 1;\n ctx.strokeStyle = tokens.color.border;\n ctx.stroke();\n const cx = best.x + padX + r1;\n const baseY = best.y + best.height - padY;\n const labelX = best.x + padX + r1 * 2 + gap;\n refs.forEach(({ r }) => {\n if (pen) {\n pen.circle(cx, baseY - r, r, { stroke: muted, strokeWidth: 1 });\n } else {\n ctx.beginPath();\n ctx.arc(cx, baseY - r, r, 0, TAU);\n ctx.fillStyle = withAlpha(muted, 0.06);\n ctx.fill();\n ctx.strokeStyle = muted;\n ctx.lineWidth = 1;\n ctx.stroke();\n }\n ctx.beginPath();\n ctx.moveTo(cx, baseY - r * 2);\n ctx.lineTo(labelX - 3, baseY - r * 2);\n ctx.globalAlpha = 0.6;\n ctx.strokeStyle = muted;\n ctx.lineWidth = 0.75;\n ctx.stroke();\n ctx.globalAlpha = 1;\n });\n ctx.restore();\n addOverlayText(surface, tokens, {\n left: best.x + padX,\n top: best.y + padY,\n text: title,\n maxWidth: best.width - padX * 2,\n color: muted,\n size: labelSize,\n weight: tokens.font.weight.medium,\n role: 'legend',\n path: '/encoding/size',\n });\n refs.forEach(({ r }, i) => {\n addOverlayText(surface, tokens, {\n left: labelX,\n top: baseY - r * 2 - labelH / 2,\n text: texts[i],\n color: muted,\n size: labelSize,\n role: 'legend',\n path: '/encoding/size',\n });\n });\n return best;\n}\n\n/** A label with a soft halo in the backdrop so it reads over land and bubbles alike. */\nfunction addHaloLabel(\n surface: Surface,\n tokens: ThemeTokens,\n o: { left: number; top: number; text: string; maxWidth: number; color: string; size: number; weight: number; opacity: number; halo: string | null; background: string },\n): void {\n if (o.halo && surface.headless) {\n const font = fontString(o.size, tokens.font.family, o.weight);\n const fitted = fitLabel(o.text, o.maxWidth, font);\n const cmd = overlayTextToCanvasCmd({ left: o.left, top: o.top, text: fitted.text, color: o.color, size: o.size }, font);\n const ctx = surface.marks.ctx;\n ctx.save();\n ctx.globalAlpha = 0.9 * o.opacity;\n ctx.font = font;\n ctx.textAlign = cmd.align ?? 'left';\n ctx.textBaseline = cmd.baseline ?? 'top';\n ctx.lineJoin = 'round';\n ctx.lineWidth = 3;\n ctx.strokeStyle = o.halo;\n ctx.strokeText(fitted.text, cmd.x, cmd.y);\n ctx.restore();\n }\n const el = addOverlayText(surface, tokens, {\n left: o.left,\n top: o.top,\n text: o.text,\n maxWidth: o.maxWidth,\n color: o.color,\n size: o.size,\n weight: o.weight,\n opacity: o.opacity < 1 ? o.opacity : undefined,\n role: 'data-label',\n background: o.background,\n path: '/labels',\n });\n if (o.halo && el) el.style.textShadow = `0 0 1px ${o.halo}, 0 0 2px ${o.halo}, 0 0 3px ${o.halo}`;\n}\n\n/**\n * Name the largest bubbles: inside when the name fits (in contrast-aware ink),\n * else beside, above or below with a halo \u2014 never over another label, another\n * bubble's center, the size key, or the map edge. The rest are recorded as omitted.\n */\nfunction drawBubbleLabels(\n surface: Surface,\n tokens: ThemeTokens,\n args: { marks: readonly BubbleMark[]; mapRect: Rect; obstacles: readonly Rect[]; opacity: number; bg: string; backdrop: RGBA | null; fillAlpha: number },\n): void {\n const { marks, mapRect, obstacles, opacity, bg, backdrop, fillAlpha } = args;\n const size = tokens.font.size.small;\n const weight = tokens.font.weight.medium;\n const font = fontString(size, tokens.font.family, weight);\n const h = size * 1.2;\n const maxWidth = Math.max(24, Math.min(160, mapRect.width * 0.4));\n const bounds = { x: mapRect.x + 1, y: mapRect.y + 1, width: mapRect.width - 2, height: mapRect.height - 2 };\n const within = (box: Rect): boolean =>\n box.x >= bounds.x && box.y >= bounds.y && box.x + box.width <= bounds.x + bounds.width && box.y + box.height <= bounds.y + bounds.height;\n const placed: Rect[] = [...obstacles];\n const omit = (reason: 'space' | 'collision' | 'unreadable', example: string): void =>\n surface.labels?.omit({ role: 'data-label', reason, required: false, example, path: '/labels' });\n // Only the largest few get names: about one per LABEL_AREA px\u00B2 of map.\n const budget = Math.max(3, Math.min(MAX_LABELS, Math.round((mapRect.width * mapRect.height) / LABEL_AREA)));\n const covers = (box: Rect, self: number): boolean =>\n marks.some((o, j) => {\n if (j === self || !(o.r > 0)) return false;\n const dx = Math.max(box.x - o.x, 0, o.x - (box.x + box.width));\n const dy = Math.max(box.y - o.y, 0, o.y - (box.y + box.height));\n return dx * dx + dy * dy < Math.max(0, o.r - 1) ** 2 || (dx === 0 && dy === 0);\n });\n const order = marks\n .map((_, i) => i)\n .filter((i) => marks[i].label !== '' && marks[i].r > 0 && marks[i].emph * marks[i].alpha >= 0.5)\n .sort((a, b) => marks[b].r - marks[a].r || a - b);\n order.forEach((index, rank) => {\n const m = marks[index];\n if (rank >= budget) return omit('space', m.label);\n const fitted = fitLabel(m.label, maxWidth, font);\n if (!fitted.text || (fitted.truncated && fitted.text.length < m.label.length * 0.5)) return omit('unreadable', m.label);\n const w = measureText(fitted.text, font).width;\n const spots: Array<{ x: number; y: number; inside: boolean }> = [];\n if (!m.hollow && Math.hypot(w / 2, h / 2) <= m.r - 1.5) spots.push({ x: m.x - w / 2, y: m.y - h / 2, inside: true });\n spots.push(\n { x: m.x + m.r + LABEL_GAP, y: m.y - h / 2, inside: false },\n { x: m.x - m.r - LABEL_GAP - w, y: m.y - h / 2, inside: false },\n { x: m.x - w / 2, y: m.y - m.r - LABEL_GAP + 1 - h, inside: false },\n { x: m.x - w / 2, y: m.y + m.r + LABEL_GAP - 1, inside: false },\n );\n // A spot must stay on the map, clear of other labels and the size key, and\n // off every other bubble (so no label hides a neighbour).\n const spot = spots.find((s) => {\n const box = { x: s.x, y: s.y, width: w, height: h };\n return within(box) && !placed.some((p) => boxesOverlap(p, box, -1)) && !covers(box, index);\n });\n if (!spot) return omit('collision', m.label);\n placed.push({ x: spot.x, y: spot.y, width: w, height: h });\n let color = tokens.color.text;\n let background = bg;\n if (spot.inside) {\n const fill = parseColor(m.fill);\n const under = fill && backdrop ? compositeOver(fill, fillAlpha * m.emph * m.alpha, backdrop) : null;\n if (under) {\n color = inkOn(under, tokens);\n background = rgbaToCss(under);\n }\n }\n addHaloLabel(surface, tokens, {\n left: spot.x, top: spot.y, text: m.label, maxWidth, color, size, weight, opacity, halo: spot.inside ? null : bg, background,\n });\n });\n}\n\nfunction tooltipFor(map: BubbleMapSpec, b: Bubble, planar: boolean): TooltipContent {\n const enc = map.encoding;\n const location = formatLocation(b, planar, map);\n const rows: TooltipRow[] = [];\n const sizeField = fieldOf(enc.size);\n const colorField = fieldOf(enc.color);\n if (sizeField && b.size != null) {\n const value = formatValue(b.size, enc.size?.format);\n rows.push({ swatch: b.hollow ? b.stroke : b.fill, label: enc.size?.title ?? sizeField, value: b.hollow ? `${value} (not sized)` : value });\n }\n if (colorField && colorField !== sizeField) {\n rows.push({\n swatch: rows.length ? undefined : b.fill,\n label: enc.color?.title ?? colorField,\n value: b.colorNoData ? 'no data' : formatValue(b.colorValue, enc.color?.format),\n });\n }\n if (b.label) return { title: b.label, rows: [...rows, { label: 'location', value: location, muted: true }] };\n // Unnamed bubbles are titled by where they are (or, with nothing else to show, list it).\n if (rows.length) return { title: location, rows };\n return { rows: [{ swatch: b.fill, label: 'location', value: location }] };\n}\n\nfunction pickFor(map: BubbleMapSpec, b: Bubble): SelectionValue | null {\n const labelField = fieldOf(map.encoding?.label);\n if (labelField && toKey(b.rawLabel) !== '') return { kind: 'point', fields: [labelField], tuples: [[b.rawLabel]] };\n const lonField = fieldOf(map.encoding?.longitude);\n const latField = fieldOf(map.encoding?.latitude);\n if (!lonField || !latField) return null;\n return { kind: 'point', fields: [lonField, latField], tuples: [[accessor(lonField)(b.row), accessor(latField)(b.row)]] };\n}\n\nfunction buildInteraction(\n map: BubbleMapSpec,\n tokens: ThemeTokens,\n mapRect: Rect,\n bubbles: readonly Bubble[],\n bg: string,\n planar: boolean,\n): InteractionModel {\n const tt = map.tooltip;\n const tooltipOn = !(tt === false || (tt && typeof tt === 'object' && tt.show === false));\n const focusOn = hoverFocusEnabled(map);\n const hit = (px: number, py: number): Bubble | null => {\n // Smaller bubbles paint last, so the topmost hit is the last drawn.\n for (let i = bubbles.length - 1; i >= 0; i -= 1) {\n const b = bubbles[i];\n const dx = px - b.x;\n const dy = py - b.y;\n if (dx * dx + dy * dy <= b.r * b.r) return b;\n }\n let best: Bubble | null = null;\n let bestGap = HIT_SLOP;\n for (const b of bubbles) {\n const gap = Math.hypot(px - b.x, py - b.y) - b.r;\n if (gap <= bestGap) {\n best = b;\n bestGap = gap;\n }\n }\n return best;\n };\n // Focus recedes the map behind a veil with the hovered bubble cut out; a\n // backdrop halo and an ink ring then outline it.\n const paintHover = (ictx: CanvasRenderingContext2D, b: Bubble, strength: number): void => {\n if (focusOn) {\n paintCutoutVeil(ictx, mapRect, bg, FOCUS_VEIL * strength, (c) => {\n c.moveTo(b.x + b.r + 1, b.y);\n c.arc(b.x, b.y, b.r + 1, 0, TAU);\n });\n }\n ictx.save();\n ictx.globalAlpha = strength;\n for (const [width, color] of [[3, bg], [1.5, tokens.color.text]] as const) {\n ictx.beginPath();\n ictx.arc(b.x, b.y, b.r + 1.5, 0, TAU);\n ictx.lineWidth = width;\n ictx.strokeStyle = color;\n ictx.stroke();\n }\n ictx.restore();\n };\n return {\n region: mapRect,\n hitTest: (px, py) => {\n if (!tooltipOn) return null;\n const b = hit(px, py);\n if (!b) return null;\n return {\n key: String(b.index),\n anchorX: b.x,\n anchorY: b.y,\n content: tooltipFor(map, b, planar),\n paint: (ictx, state) => paintHover(ictx, b, state.focus),\n draw: (ictx) => paintHover(ictx, b, 1),\n };\n },\n pick: (px, py) => {\n const b = hit(px, py);\n return b ? pickFor(map, b) : null;\n },\n };\n}\n\nexport function drawBubbleMap(\n surface: Surface,\n spec: ChartSpec,\n tokens: ThemeTokens,\n size: Size,\n context?: RenderContext,\n): InteractionModel | void {\n surface.evidence?.begin('rows');\n surface.evidence?.data(0);\n const map = spec as BubbleMapSpec;\n const content = drawTitleBlock(surface, tokens, size, map.title);\n const kind: MapProjection = map.projection ?? 'mercator';\n const planar = kind === 'identity';\n const observations = readObservations(map, planar);\n const bg = map.background ?? tokens.color.background;\n const fillAlpha = bubbleAlpha(tokens);\n if (content.width <= 0 || content.height <= 0) {\n drawLeavingBubbles(surface, content, fillAlpha, context);\n drawNoData(surface, tokens, content);\n return;\n }\n\n // The projection comes first: a categorical legend sits in the margin the map leaves.\n const projection = resolveProjection(kind, basemapPolygons(map.geo, planar), observations);\n const projected = observations.map((o) => projection.project([o.lon, o.lat]));\n const bounds = projection.bounds ?? (projected.length ? pointBounds(projected, observations, projection.project, planar) : null);\n\n // Legends reserve their space before the map is fitted into what remains.\n const showLegend = legendVisible(map.legend);\n const colors = resolveColors(map, observations, tokens);\n let area = content;\n let rampRect: Rect | null = null;\n if (showLegend && colors.mode === 'numeric' && colors.domain) {\n const legendHeight = Math.ceil(tokens.font.size.small + 26);\n area = { ...content, height: Math.max(10, content.height - legendHeight) };\n rampRect = { x: content.x, y: area.y + area.height + 4, width: content.width, height: legendHeight };\n } else if (showLegend && colors.mode === 'categorical' && colors.entries.length) {\n area = drawCategoricalLegend(surface, tokens, content, colors.entries, legendPosition(map, content, bounds));\n }\n const mapRect = applyPadding(area, map.padding);\n const limits = radiusLimits(map, mapRect);\n const sized = fieldOf(map.encoding?.size) != null;\n // Fitted to the bubbles, the extreme ones need room for their full radius; over\n // a basemap the land's edge is rarely a bubble's center, so half suffices.\n const reach = sized ? limits.rMax : limits.dot;\n const fitRect = insetRect(mapRect, (projection.basemap ? reach / 2 : reach) + 1);\n\n if (!bounds) {\n drawLeavingBubbles(surface, mapRect, fillAlpha, context);\n if (rampRect) drawRamp(surface, tokens, map, colors, rampRect);\n drawNoData(surface, tokens, content);\n return;\n }\n const fit: MapFit = fitBounds(bounds, fitRect, !planar);\n const basemap = projection.basemap?.map((polygon) => polygon.map((ring) => ring.map(([x, y]) => [fit.x(x), fit.y(y)]))) ?? null;\n\n // Place every observation; over a basemap, ones that land outside the map are omitted.\n const placed: Array<{ o: Observation; x: number; y: number }> = [];\n observations.forEach((o, i) => {\n const x = fit.x(projected[i][0]);\n const y = fit.y(projected[i][1]);\n if (!Number.isFinite(x) || !Number.isFinite(y)) return;\n if (x < mapRect.x || x > mapRect.x + mapRect.width || y < mapRect.y || y > mapRect.y + mapRect.height) return;\n placed.push({ o, x, y });\n });\n let sMax = 0;\n for (const { o } of placed) if (o.size != null && o.size > sMax) sMax = o.size;\n const radiusOf = (s: number | null): number => {\n if (!sized || s == null) return limits.dot;\n if (s < 0) return Math.min(HOLLOW_RADIUS, limits.rMax);\n if (!(sMax > 0)) return limits.rMin;\n return Math.max(limits.rMin, limits.rMax * Math.sqrt(s / sMax));\n };\n\n const backdrop = knownBackdrop(surface, tokens);\n const target = contrastTarget(backdrop, tokens);\n const tones = new Map<string, { pale: string | null; ring: string }>();\n const toneOf = (fill: string) => {\n let tone = tones.get(fill);\n if (!tone) {\n const rgba = parseColor(fill);\n const faint = rgba && backdrop && contrastRatio(compositeOver(rgba, fillAlpha, backdrop), backdrop) < PALE_CONTRAST;\n tone = {\n pale: faint ? toneForContrast(fill, target, backdrop, PALE_CONTRAST) : null,\n ring: toneForContrast(fill, target, backdrop, RING_CONTRAST),\n };\n tones.set(fill, tone);\n }\n return tone;\n };\n const emphasis = context?.emphasis ?? null;\n const labelField = fieldOf(map.encoding?.label);\n const readLabel = labelField ? accessor(labelField) : null;\n const labelFormat = map.encoding?.label?.format;\n const bubbles: Bubble[] = placed.map(({ o, x, y }) => {\n const color = colors.fillOf(o.row);\n const hollow = sized && o.size != null && o.size < 0;\n const tone = toneOf(color.fill);\n const rawLabel = readLabel ? readLabel(o.row) : undefined;\n const labelKey = toKey(rawLabel);\n return {\n key: labelKey !== '' ? `l\\u0000${labelKey}` : `p\\u0000${o.lon},${o.lat}`,\n x,\n y,\n r: radiusOf(o.size),\n fill: color.fill,\n ramp: color.ramp,\n stroke: hollow ? tone.ring : tone.pale ?? bg,\n outlined: !hollow && tone.pale != null,\n hollow,\n label: labelKey === '' ? '' : formatValue(rawLabel, labelFormat),\n emph: rowAlpha(emphasis, o.row),\n alpha: 1,\n row: o.row,\n index: o.index,\n lon: o.lon,\n lat: o.lat,\n size: o.size,\n colorValue: color.value,\n colorNoData: color.noData,\n rawLabel,\n };\n });\n // Larger bubbles paint first so small ones stay visible on top.\n bubbles.sort((a, b) => b.r - a.r || a.index - b.index);\n const finalMarks = bubbles.map(toMark);\n\n // Update morph: bubbles glide, resize and recolor from the ones on screen\n // (arrivals grow in, leavers shrink away beneath), and a changed highlight\n // fades. The entrance pops bubbles in; the basemap and legends stay put.\n const morph = morphInput<BubbleMark[]>(context);\n const moved = morph && Array.isArray(morph.from) ? morphKeyed(morph.from, finalMarks, morph.t, BUBBLE_MORPH) : null;\n const entrance = !moved && context?.entranceProgress != null && context.entranceProgress < 1 ? Math.max(0, context.entranceProgress) : null;\n const frame = moved ? [...moved.exits, ...moved.items] : entrance != null ? entranceMarks(finalMarks, entrance) : finalMarks;\n stashMorphFrame(surface, 'bubbleMap', frame);\n\n const sketch = resolveSketch(map);\n const pen = sketch ? new RoughPen(surface.marks.ctx, sketch) : null;\n if (basemap) paintBasemap(surface, tokens, basemap, bg, pen);\n else paintGraticule(surface, tokens, graticuleLines(kind, projection.project, fit, observations, projection.lon0), mapRect, pen);\n paintBubbles(surface, frame, mapRect, pen, fillAlpha);\n surface.evidence?.data(bubbles.length);\n\n if (rampRect) drawRamp(surface, tokens, map, colors, rampRect);\n const sizeKey = showLegend\n ? drawSizeLegend(surface, tokens, map, { mapRect, bubbles, sMax, limits, basemap, bg, pen })\n : null;\n if (map.labels === true && readLabel) {\n const labelOpacity = entrance == null ? 1 : clamp((entrance - 0.8) / 0.2, 0, 1);\n if (labelOpacity > 0) {\n drawBubbleLabels(surface, tokens, {\n marks: moved ? moved.items : finalMarks,\n mapRect,\n obstacles: sizeKey ? [sizeKey] : [],\n opacity: labelOpacity,\n bg,\n backdrop,\n fillAlpha,\n });\n }\n }\n if (bubbles.length === 0) drawNoData(surface, tokens, content);\n return buildInteraction(map, tokens, mapRect, bubbles, bg, planar);\n}\n\nfunction drawRamp(surface: Surface, tokens: ThemeTokens, map: BubbleMapSpec, colors: ColorPlan, rect: Rect): void {\n if (!colors.domain) return;\n drawColorRampLegend(surface, tokens, rect, {\n domain: colors.domain,\n scheme: colors.scheme,\n format: map.encoding?.color?.format,\n widthRatio: 0.5,\n minWidth: 120,\n maxWidth: 240,\n path: '/encoding/color',\n });\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["scale", "lon0", "project"]
7
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"bullet.d.ts","sourceRoot":"","sources":["../../src/charts/bullet.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAIjD,OAAO,KAAK,EAAc,SAAS,EAAY,MAAM,eAAe,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAS,IAAI,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAElD,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,sBAAsB,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAwB7C,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,MAAM,CAG3F;AAyKD,wBAAgB,UAAU,CACxB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,aAAa,GACtB,gBAAgB,GAAG,IAAI,CAwFzB"}
1
+ {"version":3,"file":"bullet.d.ts","sourceRoot":"","sources":["../../src/charts/bullet.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAIjD,OAAO,KAAK,EAAc,SAAS,EAAY,MAAM,eAAe,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAS,IAAI,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAElD,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,sBAAsB,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAyB7C,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,MAAM,CAG3F;AAsPD,wBAAgB,UAAU,CACxB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,aAAa,GACtB,gBAAgB,GAAG,IAAI,CAoFzB"}
@@ -7,6 +7,7 @@ import { resolveSketch } from "../spec/sketch.js";
7
7
  import { accessor } from "../util/data.js";
8
8
  import { addOverlayText, drawTitleBlock } from "./chrome.js";
9
9
  import { drawNoData } from "./noData.js";
10
+ import { lerp, lerpRect, lerpValue, mixColor, morphInput, morphKeyed, stashMorphFrame } from "./morphFrame.js";
10
11
  function clamp(value, min, max) {
11
12
  return Math.max(min, Math.min(max, value));
12
13
  }
@@ -45,59 +46,96 @@ function niceTicks(min, max) {
45
46
  const mid = min + (max - min) / 2;
46
47
  return [min, mid, max];
47
48
  }
48
- function paintBulletTrack(args) {
49
- const { ctx, pen, tokens, finiteRanges, track, min, max, value, target, xOf, mixGrey, accentCss, barY, barH } = args;
50
- ctx.save();
49
+ function bulletMarks(layout) {
50
+ const { tokens, finiteRanges, track, min, max, value, target, xOf, mixGrey, accentCss, barY, barH } = layout;
51
+ const end = track.x + track.width;
52
+ const marks = [];
51
53
  const bounds = [min, ...finiteRanges.filter((r) => r > min && r < max), max];
52
54
  if (bounds.length <= 2 && finiteRanges.length === 0) {
53
- if (pen) pen.rect(track.x, track.y, track.width, track.height, { fill: mixGrey(0.15), stroke: tokens.color.border });
54
- else fillRect(ctx, track.x, track.y, track.width, track.height, mixGrey(0.15));
55
+ marks.push({ key: "range:0", rect: track, color: mixGrey(0.15), anchor: end, value: max, alpha: 1 });
55
56
  } else {
56
57
  for (let i = 0; i < bounds.length - 1; i++) {
57
58
  const x0 = xOf(bounds[i]);
58
59
  const x1 = xOf(bounds[i + 1]);
59
60
  const fill = mixGrey(bounds.length === 2 ? 0.15 : 0.15 + i / Math.max(1, bounds.length - 2) * 0.65);
60
- if (pen) pen.rect(x0, track.y, x1 - x0, track.height, { fill, stroke: fill });
61
- else fillRect(ctx, x0, track.y, x1 - x0, track.height, fill);
61
+ const rect = { x: x0, y: track.y, width: x1 - x0, height: track.height };
62
+ marks.push({ key: `range:${i}`, rect, color: fill, anchor: end, value: bounds[i + 1], alpha: 1 });
62
63
  }
63
64
  }
64
65
  const barX = Math.min(xOf(min), xOf(value));
65
66
  const barW = Math.max(0, Math.abs(xOf(value) - xOf(min)));
66
- if (pen) pen.rect(barX, barY, barW, barH, { fill: accentCss, stroke: accentCss });
67
- else fillRect(ctx, barX, barY, barW, barH, accentCss);
67
+ const bar = { x: barX, y: barY, width: barW, height: barH };
68
+ marks.push({ key: "value", rect: bar, color: accentCss, anchor: xOf(min), value, alpha: 1 });
68
69
  if (target != null && Number.isFinite(target)) {
69
70
  const tx = xOf(target);
70
- if (pen) pen.polyline([{ x: tx, y: track.y - 1 }, { x: tx, y: track.y + track.height + 1 }], { stroke: tokens.color.text, strokeWidth: 3 });
71
- else drawLine(ctx, tx, track.y - 1, tx, track.y + track.height + 1, tokens.color.text, 3);
71
+ const tick = { x: tx, y: track.y, width: 0, height: track.height };
72
+ marks.push({ key: "target", rect: tick, color: tokens.color.text, anchor: tx, value: target, alpha: 1 });
72
73
  }
73
- if (!pen) {
74
+ return marks;
75
+ }
76
+ function grownMark(mark, k, alpha) {
77
+ return { ...mark, rect: { ...mark.rect, x: lerp(mark.anchor, mark.rect.x, k), width: mark.rect.width * k }, alpha };
78
+ }
79
+ const BULLET_MORPH = {
80
+ lerp: (a, b, t) => ({
81
+ key: b.key,
82
+ rect: lerpRect(a.rect, b.rect, t),
83
+ color: mixColor(a.color, b.color, t),
84
+ anchor: lerp(a.anchor, b.anchor, t),
85
+ value: lerpValue(a.value, b.value, t),
86
+ alpha: lerp(a.alpha, b.alpha, t)
87
+ }),
88
+ enter: (b, t) => grownMark(b, t, t),
89
+ exit: (a, t) => grownMark(a, 1 - t, a.alpha * (1 - t))
90
+ };
91
+ const PAINT_LAYER = { value: 1, target: 2 };
92
+ function layered(marks) {
93
+ return marks.sort((a, b) => (PAINT_LAYER[a.key] ?? 0) - (PAINT_LAYER[b.key] ?? 0));
94
+ }
95
+ function paintBulletMarks(ctx, pen, tokens, track, marks, plainTrack) {
96
+ ctx.save();
97
+ for (const { key, rect, color, alpha } of marks) {
98
+ if (alpha !== 1) ctx.globalAlpha = alpha;
99
+ if (key === "target") {
100
+ const top = rect.y - 1;
101
+ const bottom = rect.y + rect.height + 1;
102
+ if (pen) pen.polyline([{ x: rect.x, y: top }, { x: rect.x, y: bottom }], { stroke: color, strokeWidth: 3 });
103
+ else drawLine(ctx, rect.x, top, rect.x, bottom, color, 3);
104
+ } else if (pen) {
105
+ const stroke = plainTrack && key !== "value" ? tokens.color.border : color;
106
+ pen.rect(rect.x, rect.y, rect.width, rect.height, { fill: color, stroke });
107
+ } else fillRect(ctx, rect.x, rect.y, rect.width, rect.height, color);
108
+ if (alpha !== 1) ctx.globalAlpha = 1;
109
+ }
110
+ if (!pen && track) {
74
111
  ctx.strokeStyle = tokens.color.border;
75
112
  ctx.lineWidth = 1;
76
113
  ctx.strokeRect(track.x, track.y, track.width, track.height);
77
114
  }
78
115
  ctx.restore();
79
116
  }
80
- function addBulletValueAndTicks(surface, tokens, content, track, value, min, max, fmt, valueTextColor, accentCss, barY, xOf) {
117
+ function addBulletValueAndTicks(surface, tokens, content, track, label, min, max, fmt, valueTextColor, accentCss, xOf) {
81
118
  const valueFont = fontString(tokens.font.size.small, tokens.font.family, tokens.font.weight.normal);
82
- const valueText = formatValue(value, fmt);
119
+ const valueText = formatValue(label.value, fmt);
83
120
  const valueLabelW = measureText(valueText, valueFont).width + 14;
84
- const valueLeft = clamp(xOf(value) - valueLabelW / 2, content.x, content.x + content.width - valueLabelW);
121
+ const valueLeft = clamp(label.x - valueLabelW / 2, content.x, content.x + content.width - valueLabelW);
85
122
  surface.evidence?.mark(
86
123
  "value",
87
124
  valueLeft,
88
- Math.max(content.y, barY - tokens.font.size.small - 6),
125
+ Math.max(content.y, label.barY - tokens.font.size.small - 6),
89
126
  valueLabelW,
90
127
  tokens.font.size.small + 4,
91
128
  accentCss
92
129
  );
93
130
  addOverlayText(surface, tokens, {
94
131
  left: valueLeft,
95
- top: Math.max(content.y, barY - tokens.font.size.small - 6),
132
+ top: Math.max(content.y, label.barY - tokens.font.size.small - 6),
96
133
  text: valueText,
97
134
  color: valueTextColor,
98
135
  size: tokens.font.size.small,
99
136
  weight: tokens.font.weight.bold,
100
- pill: { background: accentCss, padX: 6, padY: 2 }
137
+ pill: { background: accentCss, padX: 6, padY: 2 },
138
+ opacity: label.opacity
101
139
  });
102
140
  for (const tick of niceTicks(min, max)) {
103
141
  const tickText = formatValue(tick, fmt);
@@ -112,7 +150,6 @@ function addBulletValueAndTicks(surface, tokens, content, track, value, min, max
112
150
  size: tokens.font.size.tiny
113
151
  });
114
152
  }
115
- return valueText;
116
153
  }
117
154
  function buildBulletInteraction(content, track, caption, measureLabel, accentCss, valueText, target, fmt) {
118
155
  const inTrack = (px, py) => px >= track.x && px <= track.x + track.width && py >= track.y && py <= track.y + track.height;
@@ -141,7 +178,6 @@ function buildBulletInteraction(content, track, caption, measureLabel, accentCss
141
178
  };
142
179
  }
143
180
  function drawBullet(surface, spec, tokens, size, context) {
144
- void context;
145
181
  const bullet = spec;
146
182
  surface.evidence?.begin(typeof bullet.value === "number" ? "literal" : "aggregate");
147
183
  if (typeof bullet.value === "number") surface.evidence?.data(0, "literal");
@@ -160,7 +196,11 @@ function drawBullet(surface, spec, tokens, size, context) {
160
196
  const span = Math.max(1, Math.abs(value - min));
161
197
  max = min + span;
162
198
  }
199
+ const morph = morphInput(context);
163
200
  if (value == null || !Number.isFinite(min) || !Number.isFinite(max) || max <= min || content.width <= 0 || content.height <= 0) {
201
+ const leaving = morph ? layered(morphKeyed(morph.from, [], morph.t, BULLET_MORPH).exits) : [];
202
+ if (leaving.length) paintBulletMarks(ctx, null, tokens, null, leaving, false);
203
+ stashMorphFrame(surface, "bullet", leaving);
164
204
  drawNoData(surface, tokens, content, "No value", typeof bullet.value === "number" ? "literal" : "aggregate");
165
205
  return;
166
206
  }
@@ -199,38 +239,16 @@ function drawBullet(surface, spec, tokens, size, context) {
199
239
  size: tokens.font.size.small,
200
240
  weight: tokens.font.weight.bold
201
241
  });
202
- paintBulletTrack({
203
- ctx,
204
- pen,
205
- tokens,
206
- finiteRanges,
207
- track,
208
- min,
209
- max,
210
- value,
211
- target,
212
- xOf,
213
- mixGrey,
214
- accentCss,
215
- barY,
216
- barH
217
- });
218
- const valueText = addBulletValueAndTicks(
219
- surface,
220
- tokens,
221
- content,
222
- track,
223
- value,
224
- min,
225
- max,
226
- fmt,
227
- valueTextColor,
228
- accentCss,
229
- barY,
230
- xOf
231
- );
242
+ const finalMarks = bulletMarks({ tokens, finiteRanges, track, min, max, value, target, xOf, mixGrey, accentCss, barY, barH });
243
+ const moved = morph ? morphKeyed(morph.from, finalMarks, morph.t, BULLET_MORPH) : null;
244
+ const marks = moved ? layered([...moved.exits, ...moved.items]) : finalMarks;
245
+ stashMorphFrame(surface, "bullet", marks);
246
+ paintBulletMarks(ctx, pen, tokens, track, marks, finiteRanges.length === 0);
247
+ const shown = moved?.items.find((mark) => mark.key === "value");
248
+ const label = shown ? { value: shown.value, x: shown.rect.x + shown.rect.width, barY: shown.rect.y, opacity: shown.alpha } : { value, x: xOf(value), barY };
249
+ addBulletValueAndTicks(surface, tokens, content, track, label, min, max, fmt, valueTextColor, accentCss, xOf);
232
250
  const measureLabel = valueField(bullet.value) ?? caption;
233
- return buildBulletInteraction(content, track, caption, measureLabel, accentCss, valueText, target, fmt);
251
+ return buildBulletInteraction(content, track, caption, measureLabel, accentCss, formatValue(value, fmt), target, fmt);
234
252
  }
235
253
  export {
236
254
  bulletValueToX,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/charts/bullet.ts"],
4
- "sourcesContent": ["import { parseColor, rgbaToCss, readableTextColor } from '../color';\nimport { formatValue } from '../format';\nimport { aggregateValues } from '../pivot';\nimport type { Surface } from '../render/surface';\nimport { fontString, measureText } from '../render/text';\nimport { RoughPen } from '../rough';\nimport { resolveSketch } from '../spec/sketch';\nimport type { BulletSpec, ChartSpec, ValueRef } from '../spec/types';\nimport type { ThemeTokens } from '../theme';\nimport type { Datum, Rect, Size } from '../types';\nimport { accessor } from '../util/data';\nimport type { InteractionModel, TooltipRow } from '../interaction/types';\nimport type { RenderContext } from './index';\nimport { addOverlayText, drawTitleBlock } from './chrome';\nimport { drawNoData } from './noData';\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction titleText(title: BulletSpec['title']): string | undefined {\n if (typeof title === 'string') return title;\n if (title && typeof title === 'object') return title.text;\n return undefined;\n}\n\nfunction valueField(ref: ValueRef): string | null {\n return typeof ref === 'number' ? null : ref.field;\n}\n\nfunction resolveValue(ref: ValueRef | undefined, data: readonly Datum[]): number | null {\n if (ref == null) return null;\n if (typeof ref === 'number') return Number.isFinite(ref) ? ref : null;\n return aggregateValues((data ?? []).map(accessor(ref.field)), ref.aggregate ?? 'sum');\n}\n\nexport function bulletValueToX(value: number, min: number, max: number, track: Rect): number {\n if (max <= min) return track.x;\n return track.x + ((value - min) / (max - min)) * track.width;\n}\n\nfunction fillRect(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, fill: string): void {\n if (w <= 0 || h <= 0) return;\n ctx.fillStyle = fill;\n ctx.fillRect(x, y, w, h);\n}\n\nfunction drawLine(\n ctx: CanvasRenderingContext2D,\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n stroke: string,\n width: number,\n): void {\n ctx.beginPath();\n ctx.moveTo(x1, y1);\n ctx.lineTo(x2, y2);\n ctx.strokeStyle = stroke;\n ctx.lineWidth = width;\n ctx.lineCap = 'round';\n ctx.stroke();\n}\n\nfunction niceTicks(min: number, max: number): number[] {\n const mid = min + (max - min) / 2;\n return [min, mid, max];\n}\n\ninterface BulletPaintArgs {\n ctx: CanvasRenderingContext2D;\n pen: RoughPen | null;\n tokens: ThemeTokens;\n finiteRanges: number[];\n track: Rect;\n min: number;\n max: number;\n value: number;\n target: number | null;\n xOf: (v: number) => number;\n mixGrey: (t: number) => string;\n accentCss: string;\n barY: number;\n barH: number;\n}\n\nfunction paintBulletTrack(args: BulletPaintArgs): void {\n const { ctx, pen, tokens, finiteRanges, track, min, max, value, target, xOf, mixGrey, accentCss, barY, barH } = args;\n ctx.save();\n const bounds = [min, ...finiteRanges.filter((r) => r > min && r < max), max];\n if (bounds.length <= 2 && finiteRanges.length === 0) {\n if (pen) pen.rect(track.x, track.y, track.width, track.height, { fill: mixGrey(0.15), stroke: tokens.color.border });\n else fillRect(ctx, track.x, track.y, track.width, track.height, mixGrey(0.15));\n } else {\n for (let i = 0; i < bounds.length - 1; i++) {\n const x0 = xOf(bounds[i]);\n const x1 = xOf(bounds[i + 1]);\n const fill = mixGrey(bounds.length === 2 ? 0.15 : 0.15 + (i / Math.max(1, bounds.length - 2)) * 0.65);\n if (pen) pen.rect(x0, track.y, x1 - x0, track.height, { fill, stroke: fill });\n else fillRect(ctx, x0, track.y, x1 - x0, track.height, fill);\n }\n }\n\n const barX = Math.min(xOf(min), xOf(value));\n const barW = Math.max(0, Math.abs(xOf(value) - xOf(min)));\n if (pen) pen.rect(barX, barY, barW, barH, { fill: accentCss, stroke: accentCss });\n else fillRect(ctx, barX, barY, barW, barH, accentCss);\n\n if (target != null && Number.isFinite(target)) {\n const tx = xOf(target);\n if (pen) pen.polyline([{ x: tx, y: track.y - 1 }, { x: tx, y: track.y + track.height + 1 }], { stroke: tokens.color.text, strokeWidth: 3 });\n else drawLine(ctx, tx, track.y - 1, tx, track.y + track.height + 1, tokens.color.text, 3);\n }\n\n if (!pen) {\n ctx.strokeStyle = tokens.color.border;\n ctx.lineWidth = 1;\n ctx.strokeRect(track.x, track.y, track.width, track.height);\n }\n ctx.restore();\n}\n\nfunction addBulletValueAndTicks(\n surface: Surface,\n tokens: ThemeTokens,\n content: Rect,\n track: Rect,\n value: number,\n min: number,\n max: number,\n fmt: string | undefined,\n valueTextColor: string,\n accentCss: string,\n barY: number,\n xOf: (v: number) => number,\n): string {\n const valueFont = fontString(tokens.font.size.small, tokens.font.family, tokens.font.weight.normal);\n const valueText = formatValue(value, fmt);\n const valueLabelW = measureText(valueText, valueFont).width + 14;\n const valueLeft = clamp(xOf(value) - valueLabelW / 2, content.x, content.x + content.width - valueLabelW);\n surface.evidence?.mark('value', valueLeft, Math.max(content.y, barY - tokens.font.size.small - 6),\n valueLabelW, tokens.font.size.small + 4, accentCss);\n addOverlayText(surface, tokens, {\n left: valueLeft,\n top: Math.max(content.y, barY - tokens.font.size.small - 6),\n text: valueText,\n color: valueTextColor,\n size: tokens.font.size.small,\n weight: tokens.font.weight.bold,\n pill: { background: accentCss, padX: 6, padY: 2 },\n });\n\n for (const tick of niceTicks(min, max)) {\n const tickText = formatValue(tick, fmt);\n const tickW = measureText(tickText, fontString(tokens.font.size.tiny, tokens.font.family)).width;\n const tx = xOf(tick);\n drawLine(surface.marks.ctx, tx, track.y + track.height, tx, track.y + track.height + 4, tokens.color.textMuted, 1);\n addOverlayText(surface, tokens, {\n left: clamp(tx - tickW / 2, track.x, track.x + track.width - tickW),\n top: track.y + track.height + 6,\n text: tickText,\n color: tokens.color.textMuted,\n size: tokens.font.size.tiny,\n });\n }\n return valueText;\n}\n\nfunction buildBulletInteraction(\n content: Rect,\n track: Rect,\n caption: string,\n measureLabel: string,\n accentCss: string,\n valueText: string,\n target: number | null,\n fmt: string | undefined,\n): InteractionModel {\n const inTrack = (px: number, py: number): boolean =>\n px >= track.x && px <= track.x + track.width && py >= track.y && py <= track.y + track.height;\n\n const tooltipRows = (): TooltipRow[] => {\n const rows: TooltipRow[] = [{ swatch: accentCss, label: measureLabel, value: valueText }];\n if (target != null && Number.isFinite(target)) {\n rows.push({ label: 'target', value: formatValue(target, fmt), muted: true });\n }\n return rows;\n };\n\n return {\n region: { x: content.x, y: content.y, width: content.width, height: content.height },\n hitTest: (px, py) => {\n if (!inTrack(px, py)) return null;\n return {\n key: 'value',\n anchorX: px,\n anchorY: py,\n content: {\n title: caption,\n rows: tooltipRows(),\n },\n };\n },\n pick: () => null,\n };\n}\n\nexport function drawBullet(\n surface: Surface,\n spec: ChartSpec,\n tokens: ThemeTokens,\n size: Size,\n context?: RenderContext,\n): InteractionModel | void {\n void context;\n const bullet = spec as BulletSpec;\n surface.evidence?.begin(typeof bullet.value === 'number' ? 'literal' : 'aggregate');\n if (typeof bullet.value === 'number') surface.evidence?.data(0, 'literal');\n const ctx = surface.marks.ctx;\n const content = drawTitleBlock(surface, tokens, size, bullet.title);\n const data = bullet.data ?? [];\n const value = resolveValue(bullet.value, data);\n const target = resolveValue(bullet.target, data);\n const caption = bullet.label ?? titleText(bullet.title) ?? valueField(bullet.value) ?? 'Value';\n const fmt = bullet.format;\n const finiteRanges = (bullet.ranges ?? []).filter((r) => Number.isFinite(r)).sort((a, b) => a - b);\n const min = bullet.min ?? 0;\n const derivedMax = Math.max(value ?? Number.NEGATIVE_INFINITY, target ?? Number.NEGATIVE_INFINITY, ...finiteRanges);\n let max = bullet.max ?? derivedMax;\n if (value != null && Number.isFinite(min) && Number.isFinite(max) && max <= min) {\n const span = Math.max(1, Math.abs(value - min));\n max = min + span;\n }\n\n if (value == null || !Number.isFinite(min) || !Number.isFinite(max) || max <= min || content.width <= 0 || content.height <= 0) {\n drawNoData(surface, tokens, content, 'No value', typeof bullet.value === 'number' ? 'literal' : 'aggregate');\n return;\n }\n const labelFont = fontString(tokens.font.size.small, tokens.font.family, tokens.font.weight.bold);\n // Size the label gutter to the actual caption width (+ a small gap) so short labels\n // don't leave a huge void before the track; cap it so long labels still leave room.\n const labelW = clamp(measureText(caption, labelFont).width + 14, 44, Math.max(72, content.width * 0.4));\n const axisReserve = Math.max(24, tokens.font.size.tiny * 2);\n const availableTrackW = Math.max(0, content.width - labelW);\n const trackW = Math.max(0, availableTrackW - 4);\n const trackH = clamp(content.height * 0.22, 28, 40);\n const trackX = content.x + labelW + 4;\n const trackY = content.y + Math.max(0, (content.height - axisReserve - trackH) / 2);\n const track: Rect = { x: trackX, y: trackY, width: trackW, height: trackH };\n const barH = Math.max(6, trackH / 3);\n const barY = track.y + (track.height - barH) / 2;\n const accent = tokens.color.palette[0] ?? tokens.color.text;\n const accentRgba = parseColor(accent) ?? parseColor(tokens.color.text);\n const accentCss = accentRgba ? rgbaToCss(accentRgba) : accent;\n const valueTextColor = accentRgba ? rgbaToCss(readableTextColor(accentRgba)) : tokens.color.surface;\n const sketch = resolveSketch(spec);\n const pen = sketch ? new RoughPen(ctx, sketch) : null;\n const greyStart = parseColor(tokens.color.surface) ?? { r: 245, g: 245, b: 245, a: 1 };\n const greyEnd = parseColor(tokens.color.border) ?? { r: 180, g: 180, b: 180, a: 1 };\n const mixGrey = (t: number): string =>\n rgbaToCss({\n r: greyStart.r + (greyEnd.r - greyStart.r) * t,\n g: greyStart.g + (greyEnd.g - greyStart.g) * t,\n b: greyStart.b + (greyEnd.b - greyStart.b) * t,\n a: 1,\n });\n const xOf = (v: number): number => clamp(bulletValueToX(v, min, max, track), track.x, track.x + track.width);\n\n addOverlayText(surface, tokens, {\n left: content.x,\n top: track.y + track.height / 2 - tokens.font.size.small / 2,\n width: Math.max(0, labelW - 8),\n text: caption,\n color: tokens.color.text,\n size: tokens.font.size.small,\n weight: tokens.font.weight.bold,\n });\n\n paintBulletTrack({\n ctx,\n pen,\n tokens,\n finiteRanges,\n track,\n min,\n max,\n value,\n target,\n xOf,\n mixGrey,\n accentCss,\n barY,\n barH,\n });\n\n const valueText = addBulletValueAndTicks(\n surface, tokens, content, track, value, min, max, fmt, valueTextColor, accentCss, barY, xOf,\n );\n\n const measureLabel = valueField(bullet.value) ?? caption;\n return buildBulletInteraction(content, track, caption, measureLabel, accentCss, valueText, target, fmt);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { parseColor, rgbaToCss, readableTextColor } from '../color';\nimport { formatValue } from '../format';\nimport { aggregateValues } from '../pivot';\nimport type { Surface } from '../render/surface';\nimport { fontString, measureText } from '../render/text';\nimport { RoughPen } from '../rough';\nimport { resolveSketch } from '../spec/sketch';\nimport type { BulletSpec, ChartSpec, ValueRef } from '../spec/types';\nimport type { ThemeTokens } from '../theme';\nimport type { Datum, Rect, Size } from '../types';\nimport { accessor } from '../util/data';\nimport type { InteractionModel, TooltipRow } from '../interaction/types';\nimport type { RenderContext } from './index';\nimport { addOverlayText, drawTitleBlock } from './chrome';\nimport { drawNoData } from './noData';\nimport { lerp, lerpRect, lerpValue, mixColor, morphInput, morphKeyed, stashMorphFrame, type MorphPlan } from './morphFrame';\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction titleText(title: BulletSpec['title']): string | undefined {\n if (typeof title === 'string') return title;\n if (title && typeof title === 'object') return title.text;\n return undefined;\n}\n\nfunction valueField(ref: ValueRef): string | null {\n return typeof ref === 'number' ? null : ref.field;\n}\n\nfunction resolveValue(ref: ValueRef | undefined, data: readonly Datum[]): number | null {\n if (ref == null) return null;\n if (typeof ref === 'number') return Number.isFinite(ref) ? ref : null;\n return aggregateValues((data ?? []).map(accessor(ref.field)), ref.aggregate ?? 'sum');\n}\n\nexport function bulletValueToX(value: number, min: number, max: number, track: Rect): number {\n if (max <= min) return track.x;\n return track.x + ((value - min) / (max - min)) * track.width;\n}\n\nfunction fillRect(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, fill: string): void {\n if (w <= 0 || h <= 0) return;\n ctx.fillStyle = fill;\n ctx.fillRect(x, y, w, h);\n}\n\nfunction drawLine(\n ctx: CanvasRenderingContext2D,\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n stroke: string,\n width: number,\n): void {\n ctx.beginPath();\n ctx.moveTo(x1, y1);\n ctx.lineTo(x2, y2);\n ctx.strokeStyle = stroke;\n ctx.lineWidth = width;\n ctx.lineCap = 'round';\n ctx.stroke();\n}\n\nfunction niceTicks(min: number, max: number): number[] {\n const mid = min + (max - min) / 2;\n return [min, mid, max];\n}\n\ninterface BulletLayout {\n tokens: ThemeTokens;\n finiteRanges: number[];\n track: Rect;\n min: number;\n max: number;\n value: number;\n target: number | null;\n xOf: (v: number) => number;\n mixGrey: (t: number) => string;\n accentCss: string;\n barY: number;\n barH: number;\n}\n\n/**\n * A mark as drawn \u2014 a qualitative band (`range:<i>`), the measure bar (`value`)\n * or the target tick (`target`) \u2014 keyed so an update can carry it to its new\n * extent, color and value.\n */\ninterface BulletMark {\n key: string;\n /** Pixel extent; the target tick is a zero-width rect spanning the track. */\n rect: Rect;\n color: string;\n /** Pixel x the mark grows out of when it arrives and collapses onto when it leaves. */\n anchor: number;\n /** The value the mark encodes (the measure counts through a morph on its label). */\n value: number;\n /** Fade for marks arriving or leaving mid-morph. */\n alpha: number;\n}\n\nfunction bulletMarks(layout: BulletLayout): BulletMark[] {\n const { tokens, finiteRanges, track, min, max, value, target, xOf, mixGrey, accentCss, barY, barH } = layout;\n // New bands open out of (and surplus ones close into) the track's far end, so\n // the bands keep tiling the track while their count changes.\n const end = track.x + track.width;\n const marks: BulletMark[] = [];\n const bounds = [min, ...finiteRanges.filter((r) => r > min && r < max), max];\n if (bounds.length <= 2 && finiteRanges.length === 0) {\n marks.push({ key: 'range:0', rect: track, color: mixGrey(0.15), anchor: end, value: max, alpha: 1 });\n } else {\n for (let i = 0; i < bounds.length - 1; i++) {\n const x0 = xOf(bounds[i]);\n const x1 = xOf(bounds[i + 1]);\n const fill = mixGrey(bounds.length === 2 ? 0.15 : 0.15 + (i / Math.max(1, bounds.length - 2)) * 0.65);\n const rect = { x: x0, y: track.y, width: x1 - x0, height: track.height };\n marks.push({ key: `range:${i}`, rect, color: fill, anchor: end, value: bounds[i + 1], alpha: 1 });\n }\n }\n\n const barX = Math.min(xOf(min), xOf(value));\n const barW = Math.max(0, Math.abs(xOf(value) - xOf(min)));\n const bar = { x: barX, y: barY, width: barW, height: barH };\n marks.push({ key: 'value', rect: bar, color: accentCss, anchor: xOf(min), value, alpha: 1 });\n\n if (target != null && Number.isFinite(target)) {\n const tx = xOf(target);\n const tick = { x: tx, y: track.y, width: 0, height: track.height };\n marks.push({ key: 'target', rect: tick, color: tokens.color.text, anchor: tx, value: target, alpha: 1 });\n }\n return marks;\n}\n\n/** `mark` grown to fraction `k` of its width, out of its anchor. */\nfunction grownMark(mark: BulletMark, k: number, alpha: number): BulletMark {\n return { ...mark, rect: { ...mark.rect, x: lerp(mark.anchor, mark.rect.x, k), width: mark.rect.width * k }, alpha };\n}\n\nconst BULLET_MORPH: MorphPlan<BulletMark> = {\n lerp: (a, b, t) => ({\n key: b.key,\n rect: lerpRect(a.rect, b.rect, t),\n color: mixColor(a.color, b.color, t),\n anchor: lerp(a.anchor, b.anchor, t),\n value: lerpValue(a.value, b.value, t),\n alpha: lerp(a.alpha, b.alpha, t),\n }),\n enter: (b, t) => grownMark(b, t, t),\n exit: (a, t) => grownMark(a, 1 - t, a.alpha * (1 - t)),\n};\n\nconst PAINT_LAYER: Record<string, number> = { value: 1, target: 2 };\n\n/** Marks in paint order (bands, then the measure bar, then the target tick), leaving marks first. */\nfunction layered(marks: BulletMark[]): BulletMark[] {\n return marks.sort((a, b) => (PAINT_LAYER[a.key] ?? 0) - (PAINT_LAYER[b.key] ?? 0));\n}\n\n/** Paint bands, measure bar and target tick; `track` (when set) gets its border on top. */\nfunction paintBulletMarks(\n ctx: CanvasRenderingContext2D,\n pen: RoughPen | null,\n tokens: ThemeTokens,\n track: Rect | null,\n marks: readonly BulletMark[],\n plainTrack: boolean,\n): void {\n ctx.save();\n for (const { key, rect, color, alpha } of marks) {\n if (alpha !== 1) ctx.globalAlpha = alpha;\n if (key === 'target') {\n const top = rect.y - 1;\n const bottom = rect.y + rect.height + 1;\n if (pen) pen.polyline([{ x: rect.x, y: top }, { x: rect.x, y: bottom }], { stroke: color, strokeWidth: 3 });\n else drawLine(ctx, rect.x, top, rect.x, bottom, color, 3);\n } else if (pen) {\n // A plain (range-less) sketched track keeps a border-colored outline.\n const stroke = plainTrack && key !== 'value' ? tokens.color.border : color;\n pen.rect(rect.x, rect.y, rect.width, rect.height, { fill: color, stroke });\n } else fillRect(ctx, rect.x, rect.y, rect.width, rect.height, color);\n if (alpha !== 1) ctx.globalAlpha = 1;\n }\n\n if (!pen && track) {\n ctx.strokeStyle = tokens.color.border;\n ctx.lineWidth = 1;\n ctx.strokeRect(track.x, track.y, track.width, track.height);\n }\n ctx.restore();\n}\n\n/** The measure label as shown: its (possibly mid-morph) value, anchor x, bar top and fade. */\ninterface BulletValueLabel {\n value: number;\n x: number;\n barY: number;\n opacity?: number;\n}\n\nfunction addBulletValueAndTicks(\n surface: Surface,\n tokens: ThemeTokens,\n content: Rect,\n track: Rect,\n label: BulletValueLabel,\n min: number,\n max: number,\n fmt: string | undefined,\n valueTextColor: string,\n accentCss: string,\n xOf: (v: number) => number,\n): void {\n const valueFont = fontString(tokens.font.size.small, tokens.font.family, tokens.font.weight.normal);\n const valueText = formatValue(label.value, fmt);\n const valueLabelW = measureText(valueText, valueFont).width + 14;\n const valueLeft = clamp(label.x - valueLabelW / 2, content.x, content.x + content.width - valueLabelW);\n surface.evidence?.mark('value', valueLeft, Math.max(content.y, label.barY - tokens.font.size.small - 6),\n valueLabelW, tokens.font.size.small + 4, accentCss);\n addOverlayText(surface, tokens, {\n left: valueLeft,\n top: Math.max(content.y, label.barY - tokens.font.size.small - 6),\n text: valueText,\n color: valueTextColor,\n size: tokens.font.size.small,\n weight: tokens.font.weight.bold,\n pill: { background: accentCss, padX: 6, padY: 2 },\n opacity: label.opacity,\n });\n\n for (const tick of niceTicks(min, max)) {\n const tickText = formatValue(tick, fmt);\n const tickW = measureText(tickText, fontString(tokens.font.size.tiny, tokens.font.family)).width;\n const tx = xOf(tick);\n drawLine(surface.marks.ctx, tx, track.y + track.height, tx, track.y + track.height + 4, tokens.color.textMuted, 1);\n addOverlayText(surface, tokens, {\n left: clamp(tx - tickW / 2, track.x, track.x + track.width - tickW),\n top: track.y + track.height + 6,\n text: tickText,\n color: tokens.color.textMuted,\n size: tokens.font.size.tiny,\n });\n }\n}\n\nfunction buildBulletInteraction(\n content: Rect,\n track: Rect,\n caption: string,\n measureLabel: string,\n accentCss: string,\n valueText: string,\n target: number | null,\n fmt: string | undefined,\n): InteractionModel {\n const inTrack = (px: number, py: number): boolean =>\n px >= track.x && px <= track.x + track.width && py >= track.y && py <= track.y + track.height;\n\n const tooltipRows = (): TooltipRow[] => {\n const rows: TooltipRow[] = [{ swatch: accentCss, label: measureLabel, value: valueText }];\n if (target != null && Number.isFinite(target)) {\n rows.push({ label: 'target', value: formatValue(target, fmt), muted: true });\n }\n return rows;\n };\n\n return {\n region: { x: content.x, y: content.y, width: content.width, height: content.height },\n hitTest: (px, py) => {\n if (!inTrack(px, py)) return null;\n return {\n key: 'value',\n anchorX: px,\n anchorY: py,\n content: {\n title: caption,\n rows: tooltipRows(),\n },\n };\n },\n pick: () => null,\n };\n}\n\nexport function drawBullet(\n surface: Surface,\n spec: ChartSpec,\n tokens: ThemeTokens,\n size: Size,\n context?: RenderContext,\n): InteractionModel | void {\n const bullet = spec as BulletSpec;\n surface.evidence?.begin(typeof bullet.value === 'number' ? 'literal' : 'aggregate');\n if (typeof bullet.value === 'number') surface.evidence?.data(0, 'literal');\n const ctx = surface.marks.ctx;\n const content = drawTitleBlock(surface, tokens, size, bullet.title);\n const data = bullet.data ?? [];\n const value = resolveValue(bullet.value, data);\n const target = resolveValue(bullet.target, data);\n const caption = bullet.label ?? titleText(bullet.title) ?? valueField(bullet.value) ?? 'Value';\n const fmt = bullet.format;\n const finiteRanges = (bullet.ranges ?? []).filter((r) => Number.isFinite(r)).sort((a, b) => a - b);\n const min = bullet.min ?? 0;\n const derivedMax = Math.max(value ?? Number.NEGATIVE_INFINITY, target ?? Number.NEGATIVE_INFINITY, ...finiteRanges);\n let max = bullet.max ?? derivedMax;\n if (value != null && Number.isFinite(min) && Number.isFinite(max) && max <= min) {\n const span = Math.max(1, Math.abs(value - min));\n max = min + span;\n }\n // Update morph: the bands, measure bar and target tick travel from the marks\n // on screen while the value label counts; caption and ticks are the new frame's.\n const morph = morphInput<BulletMark[]>(context);\n\n if (value == null || !Number.isFinite(min) || !Number.isFinite(max) || max <= min || content.width <= 0 || content.height <= 0) {\n const leaving = morph ? layered(morphKeyed(morph.from, [], morph.t, BULLET_MORPH).exits) : [];\n if (leaving.length) paintBulletMarks(ctx, null, tokens, null, leaving, false);\n stashMorphFrame(surface, 'bullet', leaving);\n drawNoData(surface, tokens, content, 'No value', typeof bullet.value === 'number' ? 'literal' : 'aggregate');\n return;\n }\n const labelFont = fontString(tokens.font.size.small, tokens.font.family, tokens.font.weight.bold);\n // Size the label gutter to the actual caption width (+ a small gap) so short labels\n // don't leave a huge void before the track; cap it so long labels still leave room.\n const labelW = clamp(measureText(caption, labelFont).width + 14, 44, Math.max(72, content.width * 0.4));\n const axisReserve = Math.max(24, tokens.font.size.tiny * 2);\n const availableTrackW = Math.max(0, content.width - labelW);\n const trackW = Math.max(0, availableTrackW - 4);\n const trackH = clamp(content.height * 0.22, 28, 40);\n const trackX = content.x + labelW + 4;\n const trackY = content.y + Math.max(0, (content.height - axisReserve - trackH) / 2);\n const track: Rect = { x: trackX, y: trackY, width: trackW, height: trackH };\n const barH = Math.max(6, trackH / 3);\n const barY = track.y + (track.height - barH) / 2;\n const accent = tokens.color.palette[0] ?? tokens.color.text;\n const accentRgba = parseColor(accent) ?? parseColor(tokens.color.text);\n const accentCss = accentRgba ? rgbaToCss(accentRgba) : accent;\n const valueTextColor = accentRgba ? rgbaToCss(readableTextColor(accentRgba)) : tokens.color.surface;\n const sketch = resolveSketch(spec);\n const pen = sketch ? new RoughPen(ctx, sketch) : null;\n const greyStart = parseColor(tokens.color.surface) ?? { r: 245, g: 245, b: 245, a: 1 };\n const greyEnd = parseColor(tokens.color.border) ?? { r: 180, g: 180, b: 180, a: 1 };\n const mixGrey = (t: number): string =>\n rgbaToCss({\n r: greyStart.r + (greyEnd.r - greyStart.r) * t,\n g: greyStart.g + (greyEnd.g - greyStart.g) * t,\n b: greyStart.b + (greyEnd.b - greyStart.b) * t,\n a: 1,\n });\n const xOf = (v: number): number => clamp(bulletValueToX(v, min, max, track), track.x, track.x + track.width);\n\n addOverlayText(surface, tokens, {\n left: content.x,\n top: track.y + track.height / 2 - tokens.font.size.small / 2,\n width: Math.max(0, labelW - 8),\n text: caption,\n color: tokens.color.text,\n size: tokens.font.size.small,\n weight: tokens.font.weight.bold,\n });\n\n const finalMarks = bulletMarks({ tokens, finiteRanges, track, min, max, value, target, xOf, mixGrey, accentCss, barY, barH });\n const moved = morph ? morphKeyed(morph.from, finalMarks, morph.t, BULLET_MORPH) : null;\n const marks = moved ? layered([...moved.exits, ...moved.items]) : finalMarks;\n stashMorphFrame(surface, 'bullet', marks);\n paintBulletMarks(ctx, pen, tokens, track, marks, finiteRanges.length === 0);\n\n const shown = moved?.items.find((mark) => mark.key === 'value');\n const label: BulletValueLabel = shown\n ? { value: shown.value, x: shown.rect.x + shown.rect.width, barY: shown.rect.y, opacity: shown.alpha }\n : { value, x: xOf(value), barY };\n addBulletValueAndTicks(surface, tokens, content, track, label, min, max, fmt, valueTextColor, accentCss, xOf);\n\n const measureLabel = valueField(bullet.value) ?? caption;\n return buildBulletInteraction(content, track, caption, measureLabel, accentCss, formatValue(value, fmt), target, fmt);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"calendarHeatmap.d.ts","sourceRoot":"","sources":["../../src/charts/calendarHeatmap.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAKjD,OAAO,KAAK,EAAuB,SAAS,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAQ,IAAI,EAAE,MAAM,UAAU,CAAC;AAElD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAwB7C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,KAAK,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,KAAK,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,IAAI,CAAC;IACZ,GAAG,EAAE,IAAI,CAAC;IACV,MAAM,EAAE,IAAI,CAAC;IACb,MAAM,EAAE,IAAI,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC1C;AAyED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,gBAAgB,EAAE,GAC9D,YAAY,CA0Cd;AA6QD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,aAAa,GACtB,gBAAgB,GAAG,IAAI,CAoCzB"}
1
+ {"version":3,"file":"calendarHeatmap.d.ts","sourceRoot":"","sources":["../../src/charts/calendarHeatmap.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAKjD,OAAO,KAAK,EAAuB,SAAS,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAQ,IAAI,EAAE,MAAM,UAAU,CAAC;AAElD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAyB7C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,KAAK,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,KAAK,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,IAAI,CAAC;IACZ,GAAG,EAAE,IAAI,CAAC;IACV,MAAM,EAAE,IAAI,CAAC;IACb,MAAM,EAAE,IAAI,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC1C;AAyED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,gBAAgB,EAAE,GAC9D,YAAY,CA0Cd;AA2TD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,aAAa,GACtB,gBAAgB,GAAG,IAAI,CA+CzB"}