ggaction 0.0.17 → 0.0.18

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 (263) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +2 -2
  3. package/knowledge/action-card.schema.json +1 -1
  4. package/knowledge/action-cards.json +1 -1
  5. package/knowledge/intent-taxonomy.json +1 -1
  6. package/knowledge/mcp-resources.json +1 -1
  7. package/knowledge/task-resolver.js +1 -1
  8. package/package.json +3 -3
  9. package/src/BasicChartProgram.js +1 -1
  10. package/src/accessibility.js +3 -2
  11. package/src/actions/boxPlots/create.js +14 -4
  12. package/src/actions/boxPlots/edit.js +39 -33
  13. package/src/actions/boxPlots/materialize.js +7 -3
  14. package/src/actions/boxPlots/options.js +37 -11
  15. package/src/actions/canvas/actions.js +70 -95
  16. package/src/actions/canvas/fitting.js +16 -1
  17. package/src/actions/canvas/index.js +3 -0
  18. package/src/actions/canvas/plotBorder.js +28 -0
  19. package/src/actions/charts/area.js +2 -2
  20. package/src/actions/charts/bar.js +34 -7
  21. package/src/actions/charts/ecdf.js +4 -18
  22. package/src/actions/charts/endpoints.js +4 -18
  23. package/src/actions/charts/heatmap.js +4 -4
  24. package/src/actions/charts/index.js +2 -0
  25. package/src/actions/charts/interval-regression.js +2 -2
  26. package/src/actions/charts/line.js +1 -1
  27. package/src/actions/charts/pie.js +3 -47
  28. package/src/actions/charts/radial.js +34 -12
  29. package/src/actions/charts/scatter.js +16 -2
  30. package/src/actions/charts/shared.js +2 -2
  31. package/src/actions/charts/text.js +35 -0
  32. package/src/actions/composition/actions.js +6 -2
  33. package/src/actions/data/box.js +2 -1
  34. package/src/actions/data/edit.js +1 -1
  35. package/src/actions/data/regression.js +2 -1
  36. package/src/actions/data/shared.js +3 -2
  37. package/src/actions/data/stack.js +3 -1
  38. package/src/actions/encodings/appearance.js +37 -29
  39. package/src/actions/encodings/barWidth.js +36 -11
  40. package/src/actions/encodings/channels.js +0 -1
  41. package/src/actions/encodings/color/continuous.js +1 -1
  42. package/src/actions/encodings/color/index.js +1 -1
  43. package/src/actions/encodings/color/policy.js +10 -3
  44. package/src/actions/encodings/density/resolve.js +1 -6
  45. package/src/actions/encodings/position/policies/arc.js +12 -10
  46. package/src/actions/encodings/position/policies/area.js +3 -3
  47. package/src/actions/encodings/position/policies/bar.js +15 -6
  48. package/src/actions/encodings/position/policies/line.js +17 -6
  49. package/src/actions/encodings/position/resolve.js +3 -2
  50. package/src/actions/encodings/ranged.js +17 -0
  51. package/src/actions/encodings/remove.js +3 -2
  52. package/src/actions/encodings/seriesLayout.js +1 -0
  53. package/src/actions/encodings/text.js +6 -3
  54. package/src/actions/errorBands/create.js +2 -2
  55. package/src/actions/errorBands/edit.js +2 -1
  56. package/src/actions/facets/actions.js +158 -240
  57. package/src/actions/gradientPlots/resolve.js +2 -17
  58. package/src/actions/guides/applicability.js +1 -1
  59. package/src/actions/guides/axes/axis.js +16 -4
  60. package/src/actions/guides/axes/edit.js +4 -4
  61. package/src/actions/guides/axes/labels.js +120 -46
  62. package/src/actions/guides/axes/lines.js +6 -5
  63. package/src/actions/guides/axes/parallel/lifecycle.js +1 -1
  64. package/src/actions/guides/axes/parallel/policy.js +8 -7
  65. package/src/actions/guides/axes/remove.js +3 -2
  66. package/src/actions/guides/axes/tickGroups.js +5 -2
  67. package/src/actions/guides/axes/ticks.js +6 -3
  68. package/src/actions/guides/axes/titles.js +71 -26
  69. package/src/actions/guides/basic.js +2 -0
  70. package/src/actions/guides/facadeLegend.js +10 -2
  71. package/src/actions/guides/grids/grid.js +7 -1
  72. package/src/actions/guides/grids/resolve.js +59 -12
  73. package/src/actions/guides/legends/blocks.js +3 -1
  74. package/src/actions/guides/legends/categorical/actions.js +70 -17
  75. package/src/actions/guides/legends/categorical/components.js +12 -8
  76. package/src/actions/guides/legends/categorical/index.js +6 -0
  77. package/src/actions/guides/legends/categorical/layout.js +37 -8
  78. package/src/actions/guides/legends/categorical/options.js +31 -20
  79. package/src/actions/guides/legends/categorical/resolve.js +2 -2
  80. package/src/actions/guides/legends/categorical/symbols.js +18 -12
  81. package/src/actions/guides/legends/categorical/validation.js +1 -6
  82. package/src/actions/guides/legends/continuous/colorSymbols.js +1 -0
  83. package/src/actions/guides/legends/continuous/common.js +1 -447
  84. package/src/actions/guides/legends/continuous/gradient.js +47 -34
  85. package/src/actions/guides/legends/continuous/interval.js +4 -4
  86. package/src/actions/guides/legends/continuous/opacity.js +19 -12
  87. package/src/actions/guides/legends/edit.js +1 -604
  88. package/src/actions/guides/legends/focused.js +2 -2
  89. package/src/actions/guides/legends/group.js +1 -0
  90. package/src/actions/guides/legends/lane.js +1 -516
  91. package/src/actions/guides/legends/remove.js +3 -0
  92. package/src/actions/guides/legends/sampling.js +1 -1
  93. package/src/actions/guides/legends/size.js +51 -43
  94. package/src/actions/guides/legends/strokeWidth.js +11 -29
  95. package/src/actions/guides/legends/target.js +3 -3
  96. package/src/actions/guides/legends/transition.js +21 -7
  97. package/src/actions/guides/polar/axes/labels.js +4 -2
  98. package/src/actions/guides/polar/axes/titles.js +7 -5
  99. package/src/actions/guides/polar/resolve.js +6 -14
  100. package/src/actions/index.js +16 -16
  101. package/src/actions/marks/arc/actions.js +3 -10
  102. package/src/actions/marks/area/actions.js +8 -5
  103. package/src/actions/marks/area/materialize.js +8 -9
  104. package/src/actions/marks/bar/create.js +10 -4
  105. package/src/actions/marks/bar/edit.js +8 -4
  106. package/src/actions/marks/bar/materialize.js +9 -6
  107. package/src/actions/marks/line/actions.js +11 -4
  108. package/src/actions/marks/line/materialize.js +9 -5
  109. package/src/actions/marks/point/edit.js +1 -1
  110. package/src/actions/marks/rect/actions.js +3 -3
  111. package/src/actions/marks/remove.js +2 -0
  112. package/src/actions/marks/rule/actions.js +7 -4
  113. package/src/actions/marks/text/actions.js +17 -5
  114. package/src/actions/marks/text/layout.js +3 -0
  115. package/src/actions/primitives/semanticValidation/layer.js +4 -0
  116. package/src/actions/regression/create.js +1 -1
  117. package/src/actions/regression/edit.js +3 -3
  118. package/src/actions/regression/resolve.js +2 -6
  119. package/src/actions/scales/channels.js +9 -4
  120. package/src/actions/scales/consumers/families.js +16 -5
  121. package/src/actions/scales/create.js +8 -3
  122. package/src/actions/scales/definitions.js +1 -425
  123. package/src/actions/scales/edit.js +2 -2
  124. package/src/actions/scales/editPolicy.js +9 -3
  125. package/src/actions/scales/materialize.js +1 -1
  126. package/src/actions/scales/preview.js +21 -1
  127. package/src/actions/scales/quantitativeColor.js +3 -3
  128. package/src/actions/selection/actions.js +1 -13
  129. package/src/actions/theme/reconcile.js +81 -27
  130. package/src/actions/theme/state.js +12 -0
  131. package/src/actions/titles/actions.js +5 -18
  132. package/src/actions/titles/resolve.js +41 -19
  133. package/src/actions/violinPlots/edit.js +3 -20
  134. package/src/core/compositionState.js +4 -1
  135. package/src/core/font.js +9 -2
  136. package/src/core/optionRequirements.js +1 -0
  137. package/src/core/resourceReferences.js +3 -0
  138. package/src/core/textMetricProfile.js +3 -2
  139. package/src/core/textMetrics.js +41 -4
  140. package/src/core/validation.js +26 -0
  141. package/src/core/vocabulary.js +4 -0
  142. package/src/grammar/aggregate.js +4 -18
  143. package/src/grammar/arcs.js +1 -386
  144. package/src/grammar/areaPaint.js +10 -0
  145. package/src/grammar/areaSeries.js +18 -10
  146. package/src/grammar/bars/geometry.js +30 -3
  147. package/src/grammar/bars/policy.js +12 -1
  148. package/src/grammar/bin.js +2 -12
  149. package/src/grammar/bin2d.js +1 -6
  150. package/src/grammar/boxPlot.js +56 -9
  151. package/src/grammar/categoryOrder.js +1 -6
  152. package/src/grammar/complete.js +15 -19
  153. package/src/grammar/computed.js +92 -25
  154. package/src/grammar/curveCommands.js +29 -16
  155. package/src/grammar/datasetSchema.js +3 -7
  156. package/src/grammar/displayLabels.js +28 -0
  157. package/src/grammar/ecdf.js +2 -9
  158. package/src/grammar/facets/dependencies.js +6 -2
  159. package/src/grammar/facets/guides.js +5 -0
  160. package/src/grammar/facets/index.js +2 -5
  161. package/src/grammar/fold.js +2 -12
  162. package/src/grammar/gradientProfile.js +1 -6
  163. package/src/grammar/impute.js +21 -48
  164. package/src/grammar/interval.js +2 -9
  165. package/src/grammar/legendGradient.js +18 -0
  166. package/src/grammar/legendGroups.js +1 -0
  167. package/src/grammar/legendTitleStyle.js +22 -0
  168. package/src/grammar/lineSeries.js +32 -17
  169. package/src/grammar/markLabels.js +5 -2
  170. package/src/grammar/normalize.js +4 -54
  171. package/src/grammar/numeric.js +1 -290
  172. package/src/grammar/parallelCoordinates.js +1 -6
  173. package/src/grammar/parseTime.js +41 -0
  174. package/src/grammar/pathCommands.js +11 -4
  175. package/src/grammar/polar.js +1 -184
  176. package/src/grammar/positionCompatibility.js +3 -3
  177. package/src/grammar/regression/derive.js +7 -1
  178. package/src/grammar/regression/models.js +83 -55
  179. package/src/grammar/regression/parameters.js +14 -3
  180. package/src/grammar/roundedRect.js +42 -54
  181. package/src/grammar/scales/appearance.js +1 -206
  182. package/src/grammar/scales/color.js +1 -382
  183. package/src/grammar/scales/colorConsumers.js +5 -2
  184. package/src/grammar/scales/definition.js +1 -197
  185. package/src/grammar/scales/discretized.js +1 -195
  186. package/src/grammar/scales/size.js +1 -456
  187. package/src/grammar/scales/temporal.js +2 -13
  188. package/src/grammar/scales/transformed.js +1 -383
  189. package/src/grammar/scales/types.js +1 -1
  190. package/src/grammar/scales/validation.js +1 -66
  191. package/src/grammar/schemas/concreteGraphic.js +11 -0
  192. package/src/grammar/schemas/graphic.js +3 -0
  193. package/src/grammar/schemas/semanticPath.js +2 -1
  194. package/src/grammar/stack.js +2 -10
  195. package/src/grammar/statisticalReference.js +1 -6
  196. package/src/grammar/summary.js +3 -26
  197. package/src/grammar/text.js +19 -0
  198. package/src/grammar/timeUnit.js +16 -7
  199. package/src/grammar/transformKeys.js +47 -0
  200. package/src/grammar/transforms.js +4 -1
  201. package/src/grammar/valueFormat.js +17 -5
  202. package/src/grammar/weightedStatistics.js +1 -6
  203. package/src/grammar/window.js +4 -58
  204. package/src/inspectionDescriptors.js +1 -1
  205. package/src/layout/canvas.js +1 -110
  206. package/src/layout/facets.js +1 -244
  207. package/src/layout/labels.js +1 -0
  208. package/src/layout/legend.js +13 -0
  209. package/src/layout/legendGroup.js +1 -0
  210. package/src/layout/legendItems.js +59 -15
  211. package/src/layout/legendLane.js +1 -441
  212. package/src/layout/legendText.js +1 -0
  213. package/src/layout/title.js +35 -13
  214. package/src/materialization/bars/aggregate.js +11 -5
  215. package/src/materialization/bars/histogram.js +4 -1
  216. package/src/materialization/bars/ranged.js +19 -6
  217. package/src/materialization/bars/resolve.js +22 -1
  218. package/src/materialization/coordinateBounds.js +8 -0
  219. package/src/materialization/dependencies.js +4 -44
  220. package/src/materialization/facetGuides/layout.js +1 -0
  221. package/src/materialization/facetGuides/placement.js +19 -8
  222. package/src/materialization/facetGuides/preparation.js +15 -7
  223. package/src/materialization/facetHeaders.js +1 -347
  224. package/src/materialization/facets.js +1 -185
  225. package/src/materialization/graphicHierarchy.js +1 -1
  226. package/src/materialization/guides/layout.js +1 -57
  227. package/src/materialization/guides/resources.js +1 -123
  228. package/src/materialization/layout.js +53 -0
  229. package/src/materialization/legendGroups.js +1 -0
  230. package/src/materialization/legendText.js +1 -0
  231. package/src/materialization/legends.js +1 -1
  232. package/src/materialization/marks/capabilities.js +5 -6
  233. package/src/materialization/rect.js +1 -1
  234. package/src/materialization/scaleGuideDependencies.js +1 -1
  235. package/src/materialization/scales/map.js +3 -0
  236. package/src/materialization/scales/policies/arc.js +8 -7
  237. package/src/materialization/scales/policies/bar.js +19 -7
  238. package/src/materialization/scales/policies/series.js +2 -1
  239. package/src/materialization/scales/resolve.js +5 -3
  240. package/src/materialization/selection/items/arc.js +1 -1
  241. package/src/materialization/selection/items/bar.js +7 -6
  242. package/src/materialization/selection/items/path.js +7 -6
  243. package/src/materialization/selection/items/rect.js +2 -2
  244. package/src/materialization/text.js +13 -4
  245. package/src/materialization/textLines.js +15 -0
  246. package/src/persistence/codec.js +37 -6
  247. package/src/persistence/validation.js +47 -0
  248. package/src/persistence.js +18 -5
  249. package/src/renderers/canvas/circle.js +6 -3
  250. package/src/renderers/canvas/fill.js +7 -1
  251. package/src/renderers/canvas/index.js +2 -1
  252. package/src/renderers/canvas/line.js +1 -0
  253. package/src/renderers/canvas/path.js +1 -1
  254. package/src/renderers/canvas/rect.js +11 -8
  255. package/src/renderers/canvas/stroke.js +2 -1
  256. package/src/renderers/canvas/text.js +5 -3
  257. package/src/renderers/svg.js +4 -1
  258. package/src/selectors/layers.js +19 -0
  259. package/src/theme/defaults.js +8 -2
  260. package/src/version.js +1 -1
  261. package/types/basic.d.ts +1 -0
  262. package/types/index.d.ts +7 -0
  263. package/types/program.d.ts +347 -85
@@ -1 +1 @@
1
- var ze=Object.defineProperty;var p=(o,t)=>ze(o,"name",{value:t,configurable:!0});import{IMPUTE_REQUIRED_OPTIONS as Te}from"../src/core/optionRequirements.js";import{readFileSync as fe}from"node:fs";import he from"node:path";import{fileURLToPath as Me}from"node:url";const me=Me(new URL("../",import.meta.url)),te=JSON.parse(fe(he.join(me,"knowledge/action-cards.json"),"utf8")),T=JSON.parse(fe(he.join(me,"knowledge/intent-taxonomy.json"),"utf8")),A=new Map(te.cards.map(o=>[o.name,o])),oe=new Map(T.constraints.map(o=>[o.id,o])),ge=Object.freeze(["hconcat","vconcat","render"]),se=Object.freeze({renderToSVG:Object.freeze({entry:"ggaction/svg",output:"svg"}),renderToPNG:Object.freeze({entry:"ggaction/png",output:"png"}),renderToPDF:Object.freeze({entry:"ggaction/pdf",output:"pdf"})}),de=Object.freeze(["createCanvas","createData"]),Re=Object.freeze({width:"800",height:"600",margin:"{ top: 140, right: 220, bottom: 120, left: 260 }"}),ve=new Set(["createScatterPlot","createLinePlot","createAreaPlot","createBarPlot","createBoxPlot","createGradientPlot","createViolinPlot","createPolarScatterPlot","createPolarLinePlot","createRadarPlot","createRugPlot","createStripPlot"]),Be=new Set(["createAxes","createXAxis","createYAxis","createGrid","createLegend","createGuides"]),ye=Object.freeze({"chart.type":"ggaction://docs/choose-chart-type","renderer.format":"ggaction://docs/choose-renderer","layout.responsive":"ggaction://docs/responsive-layout","output.accessibility":"ggaction://docs/accessibility","renderer.svg.accessibleText":"ggaction://docs/accessibility","renderer.pixelRatio":"ggaction://docs/responsive-layout","query.intent":"ggaction://docs/getting-started"});class qe extends Error{static{p(this,"TaskPacketBudgetError")}constructor(t){super(`Compact task packet is ${t} bytes; the hard ceiling is 6144 bytes.`),this.name="TaskPacketBudgetError",this.bytes=t}}function D(o){return[...new Set(o)]}p(D,"unique");function Z(o){return o.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g," ").trim().replace(/\s+/g," ")}p(Z,"normalize");const be=/\b(?:no|not|without|exclude|excluding|omit|omitting|avoid|avoiding|don['’]t|doesn['’]t|isn['’]t|aren['’]t|never|neither|nor)\b/i;function Ae(o){let t=o.normalize("NFKC").replace(/(^|[\s=:(,])("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')/g,(e,i,n)=>i+" ".repeat(n.length));for(const e of T.constraints)for(const i of e.phrases.filter(n=>be.test(n))){const n=Z(i).split(" ").join("\\s+");t=t.replace(new RegExp(`\\b${n}\\b`,"gi")," ")}return be.test(t)}p(Ae,"hasUnresolvedNegation");function le(o,t){const e=Z(t),i=` ${o} `,n=` ${e} `,r=[];let a=0;for(;a<i.length;){const d=i.indexOf(n,a);if(d===-1)break;r.push({start:d+1,end:d+n.length-1}),a=d+1}return r}p(le,"phraseOccurrences");function De(o){return te.cards.filter(t=>new RegExp(`(?:^|[^A-Za-z0-9])${t.name}(?:$|[^A-Za-z0-9])`,"i").test(o)).map(t=>t.name)}p(De,"exactActionNames");function Ee(o){const t=T.constraints.flatMap(r=>r.phrases.flatMap(a=>le(o,a).map(d=>({constraint:r,...d})))),e=t.filter(r=>!t.some(a=>a.constraint.shadows?.includes(r.constraint.id)&&a.start<=r.start&&a.end>=r.end)),i=T.constraints.filter(r=>e.some(a=>a.constraint.id===r.id)),n=new Map(i.map(r=>[r.id,Math.min(...e.filter(a=>a.constraint.id===r.id).map(a=>a.start))]));return{matched:i,positions:n}}p(Ee,"semanticMatchResult");function pe(o){return o.name==="createCanvas"?10:o.name==="createData"?20:o.name.endsWith("Data")?30:o.domain==="charts"||o.domain==="marks"&&o.name.startsWith("create")?40:o.domain==="encodings"?/^encode(X|Y|X2|Y2|XRange|YRange|Theta|R|Radius|ParallelCoordinates)/.test(o.name)?50:o.name==="encodeGroup"||o.name==="encodePathOrder"?52:55:o.domain==="statistics"?60:["axes","grid","legend_and_title"].includes(o.domain)?70:o.domain==="mark-selection"?75:o.domain==="composition"||/^(layout|jitter|order|replace)/.test(o.name)?80:65}p(pe,"orderForCard");function Le(o,t){const e=A.get(o),i=T.providers.filter(n=>n.kind==="action"&&n.name===o).map(n=>({provider:n,coverage:n.covers.filter(r=>t.has(r)).length})).filter(n=>n.coverage>0).sort((n,r)=>r.coverage-n.coverage||n.provider.order-r.provider.order||n.provider.id.localeCompare(r.provider.id))[0]?.provider;return i?{...i,id:`exact.${o}`,anchors:[`action.${o}`],covers:D([`action.${o}`,...i.covers.filter(n=>t.has(n))])}:{id:`exact.${o}`,kind:"action",name:o,order:pe(e),anchors:[`action.${o}`],covers:[`action.${o}`],exactCall:e.snippet,exactOptionNames:e.options.filter(n=>new RegExp(`\\b${n.name}\\s*:`).test(e.snippet)).map(n=>n.name)}}p(Le,"exactProvider");function Ne(o){const t=new Map;for(const n of o){if(!n.exclusiveGroup)continue;const r=t.get(n.exclusiveGroup)??[];r.push(n),t.set(n.exclusiveGroup,r)}const e=new Set,i=[];for(const[n,r]of t)if(!(r.length<2)){for(const a of r)e.add(a.id);for(const a of r)i.push({constraint:a.id,reason:`This conflicts within ${n}: ${r.map(d=>d.id).join(", ")}.`,resources:[n==="legend.position"?"ggaction://docs/legend-layout":"ggaction://docs/choose-chart-type"]})}return{blocked:e,unresolved:i}}p(Ne,"conflictResult");function We(o,t){const e=T.providers.filter(i=>i.anchors.some(n=>o.has(n)));for(const i of t)e.push(Le(i,o));return e}p(We,"candidateProviders");function je(o,t){const e=new Set(o),i=[];for(;e.size>0;){const n=t.filter(a=>!i.some(d=>d.provider.id===a.id)).map(a=>({provider:a,coverage:a.covers.filter(d=>e.has(d))})).filter(a=>a.coverage.length>0).sort((a,d)=>d.coverage.length-a.coverage.length||a.provider.order-d.provider.order||a.provider.id.localeCompare(d.provider.id));if(n.length===0)break;const r=n[0];i.push(r);for(const a of r.coverage)e.delete(a)}return{selected:i,uncovered:e}}p(je,"selectProviders");function _e(o){let t=o;o.some(a=>a.provider.name==="selectMarks")&&(t=t.map(a=>a.provider.name!=="highlightMarks"?a:{...a,provider:{...a.provider,baseOptions:{selection:'"selection-1"',color:'"#f28e2b"'}}}));const i=t.some(a=>a.provider.name==="createRegression"&&!a.provider.id.startsWith("exact.")),n=t.some(a=>["createPointMark","createScatterPlot","createPolarScatterPlot"].includes(a.provider.name));i&&!n&&(t=[ne("createPointMark",{}),...t]);const r=t.find(a=>a.provider.name==="editLegendLayout"&&a.coverage.some(d=>d.startsWith("layout.legend.")));if(r){const a=t.find(d=>d.coverage.includes("guide.legend")&&(d.provider.name==="createLegend"||d.provider.optionsByConstraint?.["guide.legend"]?.guides!==void 0));if(a){const d=r.provider.baseOptions?.position;if(d===void 0)throw new Error(`${r.provider.id} lacks a legend position.`);const w=r.coverage.filter(h=>h.startsWith("layout.legend."));t=t.filter(h=>h!==r).map(h=>{if(h!==a)return h;const $=d==='"left"'?"96":d==='"bottom"'?$e:void 0;return{provider:h.provider.name==="createLegend"?{...h.provider,baseOptions:{...h.provider.baseOptions??{},position:d,...$===void 0?{}:{offset:$}}}:{...h.provider,optionsByConstraint:{...h.provider.optionsByConstraint??{},"guide.legend":{...h.provider.optionsByConstraint?.["guide.legend"]??{},guides:`{ legend: { position: ${d}${$===void 0?"":`, offset: ${$}`} } }`}}},coverage:[...h.coverage,...w]}})}}return t}p(_e,"adaptProviderDependencies");function S(o,t){return{...o,provider:{...o.provider,baseOptions:{...o.provider.baseOptions??{},...t}}}}p(S,"withBaseOptions");function ne(o,t,e=[]){const i=A.get(o);if(!i)throw new Error(`Unknown runtime dependency action ${o}.`);return{provider:{id:`action.${o}`,kind:"action",name:o,order:pe(i),anchors:[],covers:[],baseOptions:t},coverage:e}}p(ne,"dependencyEntry");function Ge(o){const t=o.find(n=>!n.provider.id.startsWith("exact.")&&ve.has(n.provider.name));if(!t)return o;const e=o.filter(n=>!n.provider.id.startsWith("exact.")&&Be.has(n.provider.name));if(e.length===0)return o;const i=e.flatMap(n=>n.coverage);return o.filter(n=>!e.includes(n)).map(n=>n===t?{...n,coverage:D([...n.coverage,...i])}:n)}p(Ge,"absorbFacadeGuides");function we(o,t,e){const i=o.indexOf(t);return i===-1?o:[...o.slice(0,i),...e,...o.slice(i+1)]}p(we,"replaceEntry");function Ie(o){const t=p(v=>o.find(M=>M.provider.name===v&&!M.provider.id.startsWith("exact.")),"semantic"),e=t("createPointMark"),i=t("createTextMark"),n=t("encodeText"),r=new Set(["encodeX","encodeY","encodeColor","encodeSize","encodeShape","encodeAngle","encodeOpacity"]),a=o.filter(v=>!v.provider.id.startsWith("exact.")&&r.has(v.provider.name));if(!e||!i||!n||!a.some(v=>v.provider.name==="encodeX")||!a.some(v=>v.provider.name==="encodeY"))return o;const d=[e,...a,i,n],w=new Set(d),h=Math.min(...d.map(v=>o.indexOf(v))),$=o.slice(0,h).filter(v=>!w.has(v)).length,u=o.filter(v=>!w.has(v));return[...u.slice(0,$),...d,...u.slice($)]}p(Ie,"orderInheritedTextOverlay");function Ve(o){const t=o.find(u=>u.provider.name==="createBarMark"&&!u.provider.id.startsWith("exact."));if(!t)return o;const e=o.indexOf(t),i=o.findIndex((u,v)=>v>e&&!u.provider.id.startsWith("exact.")&&u.provider.name.startsWith("create")&&(u.provider.name.endsWith("Mark")||u.provider.name.endsWith("Plot"))),n=i===-1?o.length:i,r=o.slice(e+1,n).filter(u=>["encodeX","encodeY"].includes(u.provider.name)&&!u.provider.id.startsWith("exact.")),a=r.find(u=>['"nominal"','"ordinal"','"temporal"'].includes(u.provider.baseOptions?.fieldType)),d=r.find(u=>u.provider.baseOptions?.fieldType==='"quantitative"');if(!a||!d||o.indexOf(a)<o.indexOf(d))return o;const w=[...o],h=w.indexOf(a),$=w.indexOf(d);return w[$]=a,w[h]=d,w}p(Ve,"orderBarCategoryBeforeMeasure");function He(o){let t=Ge(o);const e=p(s=>t.find(x=>x.provider.name===s&&!x.provider.id.startsWith("exact.")),"semantic"),i=p(s=>t.find(x=>x.coverage.includes(s)),"chartOwner"),n=p((s,{before:x=[],after:b=[]})=>{if(!s)return;const C=t.indexOf(s);t=[...t.slice(0,C),...x,s,...b,...t.slice(C+1)]},"expandChartOwner"),r=p((s,x)=>{const b=t.find(C=>C.provider.name===s&&!C.provider.id.startsWith("exact."));return b?(t=t.filter(C=>C!==b),S(b,x)):ne(s,x)},"chartDependency"),a=p((s,x)=>{const b=i(s);b&&n(b,x())},"expandChartConstraint");a("chart.bar.horizontal",()=>({after:[r("encodeY",{field:'"category"',fieldType:'"nominal"'}),r("encodeX",{field:'"value"',fieldType:'"quantitative"'})]})),a("chart.radar",()=>({}));const d=e("createData");d&&(t=t.map(s=>s===d?S(s,{values:"values"}):s));const w=e("createCanvas");w&&(t=t.map(s=>s===w?S(s,Re):s));const h=e("createScatterPlot");h&&(t=t.map(s=>s===h?S(s,{x:'{ field: "x", fieldType: "quantitative" }',y:'{ field: "y", fieldType: "quantitative" }'}):s));const $=e("createLinePlot"),u=e("encodeOpacity");$&&u&&(t=t.filter(s=>s!==u).map(s=>s===$?{...S(s,{line:"{ opacity: 0.8 }"}),coverage:D([...s.coverage,...u.coverage])}:s));const v=e("createBarPlot");if(v){const s=e("createScale")?.provider.id==="action.createColorScale",x='{ field: "category", scale: { id: "color-scale" } }';t=t.map(b=>{if(b!==v)return b;const C=S(b,{x:'{ field: "category", fieldType: "nominal" }',y:'{ field: "value", fieldType: "quantitative" }',...s?{color:x}:{}});return s?{...C,provider:{...C.provider,optionsByConstraint:{...C.provider.optionsByConstraint??{},"encoding.color":{color:x}}}}:C})}const M=e("createTimeUnitData"),G=e("createBarPlot");M&&G&&(t=t.map(s=>s===G?S(s,{data:'"monthly"',x:'{ field: "month", fieldType: "ordinal" }',y:'{ field: "value", fieldType: "quantitative" }'}):s));const X=e("createBoxPlot");X&&(t=t.map(s=>s===X?S(s,{x:'{ field: "category", fieldType: "nominal" }',y:'{ field: "value", fieldType: "quantitative" }'}):s));const E=e("createWindowData"),q=e("createLinePlot");if(E&&q){const s=e("createScale")?.provider.id==="action.createTimeScale";t=t.map(x=>x===q?S(x,{data:'"windowed"',x:s?'{ field: "date", fieldType: "temporal", scale: { id: "scale-1" } }':'{ field: "x", fieldType: "quantitative" }',y:'{ field: "movingMean", fieldType: "quantitative" }'}):x)}const H=e("createIntervalData"),L=e("createBoxPlot"),y=e("createErrorBar");H&&L&&y&&(t=t.map(s=>s===H?S(s,{source:'"data"',groupBy:'"category"'}):s===L?S(s,{data:'"data"',x:'{ field: "category", fieldType: "nominal" }',y:'{ field: "value", fieldType: "quantitative" }'}):s===y?S(s,{data:'"interval"',x:'{ field: "category", fieldType: "nominal", scale: { id: "errorBarX" } }',y:'{ center: "__interval_center", lower: "__interval_lower", upper: "__interval_upper", scale: { id: "errorBarY" } }'}):s));const I=e("createDensityData"),V=e("createViolinPlot");I&&V&&(t=t.filter(s=>s!==I).map(s=>s===V?{...S(s,{data:'"data"',...s.coverage.includes("guide.legend")?{color:'"category"'}:{}}),coverage:D([...s.coverage,...I.coverage])}:s));const f=e("createGradientPlot"),O=e("createScale")?.provider.id==="action.createLogScale"?e("createScale"):void 0;f&&(t=t.map(s=>s===f?S(s,{data:'"data"',x:`{ field: "value", fieldType: "quantitative"${O?', scale: { id: "scale-1" }':""} }`,y:'{ field: "category", fieldType: "nominal" }'}):s));const j=e("encodeDensity"),J=e("createAreaMark");if(j&&!J){const s=ne("createAreaMark",{id:'"densityArea"'}),x=t.indexOf(j);t=[...t.slice(0,x),s,...t.slice(x)].map(b=>b===j?S(b,{target:'"densityArea"'}):b)}const N=e("createBin2DData"),F=e("createRectMark");if(N&&F){t=t.map(R=>R===N?S(R,{source:'"data"'}):R===F?S(R,{id:'"rect"',data:'"bins"'}):R.provider.id==="action.createColorScale"?S(R,{type:'"sequential"',range:'{ palette: "viridis" }'}):R);const s=e("encodeX"),x=e("encodeY");s&&(t=we(t,s,[S(s,{field:'"__bins_x0"',fieldType:'"quantitative"',target:'"rect"'}),ne("encodeX2",{field:'"__bins_x1"',fieldType:'"quantitative"',target:'"rect"'})])),x&&(t=we(t,x,[S(x,{field:'"__bins_y0"',fieldType:'"quantitative"',target:'"rect"'}),ne("encodeY2",{field:'"__bins_y1"',fieldType:'"quantitative"',target:'"rect"'})]));const b=e("encodeColor");b&&(t=t.map(R=>R===b?S(R,{field:'"__bins_count"',fieldType:'"quantitative"',target:'"rect"',scale:'{ id: "color-scale" }'}):R));const C=e("createLegend");C&&(t=t.map(R=>R===C?S(R,{target:'"rect"',channels:'["color"]'}):R))}let K,_,Y;const ie=Object.freeze({createPointMark:"point",createLineMark:"line",createAreaMark:"area",createBarMark:"bar",createRuleMark:"rule",createArcMark:"arc",createRectMark:"rect",createTextMark:"text",createScatterPlot:"scatterPlot",createLinePlot:"linePlot",createPolarScatterPlot:"polarScatterPlot",createPolarLinePlot:"polarLinePlot",createRadarPlot:"radarPlot",createRugPlot:"rugPlot",createStripPlot:"stripPlot",createAreaPlot:"areaPlot",createBarPlot:"barPlot",createBoxPlot:"boxPlot",createGradientPlot:"gradientPlot",createViolinPlot:"violinPlot",createPiePlot:"piePlot",createRosePlot:"rosePlot",createRadialBarPlot:"radialBarPlot",createDensityPlot:"densityPlot",createHorizonPlot:"horizonPlot"}),ee=Object.freeze({createPointMark:"point",createLineMark:"line",createAreaMark:"area",createBarMark:"bar",createRuleMark:"rule",createArcMark:"arc",createRectMark:"rect",createTextMark:"text",createScatterPlot:"point",createLinePlot:"line",createPolarScatterPlot:"point",createPolarLinePlot:"line",createRadarPlot:"line",createRugPlot:"tick",createStripPlot:"point",createAreaPlot:"area",createBarPlot:"bar",createBoxPlot:"bar",createGradientPlot:"rect",createViolinPlot:"area",createPiePlot:"arc",createRosePlot:"arc",createRadialBarPlot:"arc",createDensityPlot:"area",createHorizonPlot:"area"});return t=t.map(s=>{if(s.provider.id.startsWith("exact."))return s;if(s.provider.name==="createScale")return Y=s.provider.id==="action.createColorScale"?void 0:s.provider.baseOptions?.id,s;const x=ie[s.provider.name];if(x!==void 0)return K=s.provider.baseOptions?.id?.replaceAll('"',"")??x,_=s.coverage.includes("chart.bar.horizontal")?"bar-horizontal":ee[s.provider.name],s;if(!K||s.provider.name==="createErrorBar")return s;const b={};return["area","rule","arc"].includes(_)&&["encodeX","encodeY","encodeR"].includes(s.provider.name)&&(b.fieldType='"quantitative"'),s.provider.name==="encodeTheta"&&_==="arc"&&s.provider.baseOptions?.fieldType===void 0&&(b.fieldType='"ordinal"'),_==="bar"&&s.provider.name==="encodeX"&&(b.field='"category"',b.fieldType='"nominal"'),_==="bar"&&s.provider.name==="encodeY"&&(b.field='"value"',b.fieldType='"quantitative"'),_==="bar-horizontal"&&s.provider.name==="encodeX"&&(b.field='"value"',b.fieldType='"quantitative"'),_==="bar-horizontal"&&s.provider.name==="encodeY"&&(b.field='"category"',b.fieldType='"nominal"'),Y&&["encodeX","encodeY"].includes(s.provider.name)&&(b.scale=`{ id: ${Y} }`,Y=void 0),Object.keys(b).length===0?s:S(s,b)}),Ie(Ve(t))}p(He,"closeRuntimeDependencies");function xe(o,t){const e=o.coverage.map(i=>t.get(i)).filter(i=>i!==void 0);return e.length===0?Number.POSITIVE_INFINITY:Math.min(...e)}p(xe,"providerRequestPosition");function re(o,t){const e=new Map(Object.entries(o.baseOptions??{}));for(const i of t)for(const[n,r]of Object.entries(o.optionsByConstraint?.[i]??{})){const a=e.get(n);if(a!==void 0&&a!==r){if(n==="guides"&&(a==="{}"||r==="{}")){e.set(n,a==="{}"?r:a);continue}throw new Error(`${o.id} assigns conflicting values to option ${n}.`)}e.set(n,r)}return e}p(re,"mergeOptionValues");function ue(o,t){if(o.exactCall)return o.exactCall;if(A.get(o.name).options.length===0)return`program.${o.name}()`;const i=[...t].map(([n,r])=>`${n}: ${r}`).join(", ");return`program.${o.name}(${i.length===0?"{}":`{ ${i} }`})`}p(ue,"actionCall");function Ye(o){const t=new Map;return o.map(e=>{if(e.provider.kind!=="action")return e;const i=e.provider.name,n=ue(e.provider,re(e.provider,e.coverage));if(/^create.+Data$/.test(i)){const r=n.match(/\bid\s*:\s*"([A-Za-z0-9_-]+)"/)?.[1];r&&t.set(i,r)}if(/^edit.+Data$/.test(i)){const r=t.get(i.replace(/^edit/,"create"));if(r)return Pe(e,new Map([["target",B(r)]]))}return e})}p(Ye,"linkCreatedDataEditors");function Xe(o,t){const e=o.options.filter(i=>i.required).map(i=>i.name);if(o.name==="createImputedData"){const i=t.match(/\bmethod\s*:\s*["'](constant|forward|backward|linear)["']/)?.[1];e.push(...Te[i]??[])}return D(e)}p(Xe,"requiredOptionNames");function Fe(o,t){const{provider:e,coverage:i}=o,n=re(e,i);if(e.kind==="runtime")return{plan:{step:t,id:e.id,kind:e.kind,name:e.name,constraints:i,requiredOptions:[],signature:e.signature,route:e.route},call:e.call};const r=A.get(e.name),a=new Map(r.options.filter(d=>n.has(d.name)).map(d=>[d.name,n.get(d.name)]));return{plan:{step:t,id:e.id,kind:e.kind,name:e.name,constraints:i,requiredOptions:Xe(r,ue(e,a)),signature:r.signature,route:r.route},call:ue(e,a)}}p(Fe,"planEntry");function Ue(o){const t=new Set(o.filter(i=>i.plan.kind==="runtime").map(i=>i.plan.name));return[`import { ${["chart",...ge.filter(i=>t.has(i))].join(", ")} } from "ggaction";`,...Object.entries(se).filter(([i])=>t.has(i)).map(([i,n])=>`import { ${i} } from "${n.entry}";`)]}p(Ue,"authoringImports");function Ze(o){const t=o.filter(e=>se[e.plan.name]);return o.map(e=>{if(e.plan.kind==="action"||["hconcat","vconcat"].includes(e.plan.name))return`program = ${e.call}`;if(e.plan.name==="render")return e.call;const i=se[e.plan.name];if(!i)throw new Error(`Unknown authoring runtime ${e.plan.name}.`);return`const ${t.length===1?"output":`${i.output}Output`} = ${e.call}`})}p(Ze,"authoringSteps");function Je(o){const t=new Set(o.map(e=>e.plan.name).filter(e=>de.includes(e)));return{imports:Ue(o),initialize:"let program = chart()",prerequisites:de.filter(e=>!t.has(e)).map(e=>{const i=A.get(e);return{id:`action.${e}`,signature:i.signature,call:e==="createCanvas"?"program = program.createCanvas({ width: 800, height: 600, margin: { top: 140, right: 220, bottom: 120, left: 260 } })":"program = program.createData({ values })",bindings:e==="createData"?["values"]:[]}}),steps:Ze(o)}}p(Je,"authoringBlock");function B(o){return JSON.stringify(o)}p(B,"codeString");function Ke(o,t){if(!o||t.size===0)return o;const e=o.lastIndexOf("})"),i=o.indexOf("({");if(i===-1||e===-1||e<i)throw new Error(`Cannot apply requested options to exact call: ${o}`);let n=o.slice(i+2,e).trim();for(const[r,a]of t){const d=new RegExp(`(^|,\\s*)${r}\\s*:\\s*(?:"[^"]*"|'[^']*'|-?[0-9]+(?:\\.[0-9]+)?|true|false)(?=\\s*,|$)`);d.test(n)?n=n.replace(d,(w,h)=>`${h}${r}: ${a}`):n=`${n}${n.length===0?"":", "}${r}: ${a}`}return`${o.slice(0,i+2)}${n}${o.slice(e)}`}p(Ke,"mergeExactCallOptions");function Pe(o,t){if(o.provider.exactCall)return{...o,provider:{...o.provider,exactCall:Ke(o.provider.exactCall,t),exactOptionNames:D([...o.provider.exactOptionNames??[],...t.keys()])}};const e=Object.fromEntries(Object.entries(o.provider.optionsByConstraint??{}).map(([n,r])=>[n,Object.fromEntries(Object.entries(r).filter(([a])=>!t.has(a)))])),i=S(o,Object.fromEntries(t));return{...i,provider:{...i.provider,optionsByConstraint:e}}}p(Pe,"entryWithRequestedOptions");const $e="70";function W(o,...t){return t.map(e=>o?.[e]).find(e=>e!==void 0)?.trim()}p(W,"requestedText");const ce=new Set(["and","as","at","axes","axis","coordinate","coordinates","encoding","field","for","is","legend","on","option","options","palette","scale","then","to","using","with","without","no","not"]);function Qe(o,t){const e=o.match(new RegExp(`\\b${t}(?:(?:\\s+(?:field|encoding|by|is))|\\s*[:=]|\\s+)\\s*(?:"([^"]+)"|'([^']+)'|([A-Za-z_$][A-Za-z0-9_$.-]*))`,"i"));if(!e)return;const i=W(e,1,2,3);return e[3]!==void 0&&ce.has(i.toLowerCase())?void 0:{value:i,source:e[0]}}p(Qe,"fieldRequest");function et(o,t){const e=o.match(new RegExp(`\\b${t}(?:\\s+(?:by|field|encoding))?\\s*(?:"([^"]+)"|'([^']+)'|([A-Za-z_$][A-Za-z0-9_$.-]*))`,"i"));if(!e)return;const i=W(e,1,2,3);if(!(e[3]!==void 0&&ce.has(i.toLowerCase())))return{value:i,source:e[0]}}p(et,"appearanceFieldRequest");function tt(o,t){const e=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),i=t.replace(/([a-z0-9])([A-Z])/g,"$1 $2"),n=i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),r=o.match(new RegExp(`\\b(?:${e}|${n})\\b\\s*(?:=|:|\\bis\\b|\\bto\\b)\\s*[^,;]+`,"i"));if(r)return r[0].trim();if(t!==i)return o.match(new RegExp(`\\b${e}\\b`,"i"))?.[0]}p(tt,"explicitOptionMention");function ot(o,t){let e=o;const i=[],n=[],r=[],a=p((c,l,m)=>{const g=e.find(P=>c.includes(P.provider.name));if(!g||l.size===0)return!1;e=e.map(P=>P===g?Pe(P,l):P);for(const[P,z]of l)i.push({owner:g.provider.name,option:P,value:z,source:m});return!0},"apply"),d=p((c,l,m)=>{n.push(c),r.push(k(l,m))},"rejectRequirement"),w=p(c=>{const l=e.filter(g=>c.includes(g.provider.name)),m=e.filter(g=>g.provider.kind==="action"&&A.get(g.provider.name)?.domain==="charts");return l.length===1&&m.length===1?l[0]:void 0},"singleFacade"),h=p((c,l,m)=>{let g=e.find(P=>P.provider.name===c);if(!g){const P=A.get(c);g={provider:{id:`request.${c}`,kind:"action",name:c,order:pe(P),anchors:[],covers:[],baseOptions:Object.fromEntries(l)},coverage:[]};const z=e.findIndex(Q=>Q.provider.kind==="runtime");e=[...e],e.splice(z<0?e.length:z,0,g)}a([c],l,m)},"addEditor"),$=[...t.matchAll(/\b(red|blue|green|orange|purple|black|white|yellow|pink|gray|grey)\s+(?:points|markers)\b/gi)];if($.length){const c=D($.map(m=>m[1].toLowerCase())),l=w(["createScatterPlot","createPolarScatterPlot"]);if(c.length===1&&l)for(const m of $)a([l.provider.name],new Map([["point",`{ fill: ${B(c[0])} }`]]),m[0]);else for(const m of $)d(m[0],"request.pointColor","Point color requires one unambiguous point chart and one requested color.")}const u=["createScatterPlot","createLinePlot","createAreaPlot","createBarPlot","createHeatmap"],v=[...t.matchAll(/\b(?:rotate|tilt)\s+(?:the\s+)?([xy])[ -]+axis\s+labels?\s+(?:by|to)\s+(-?\d+(?:\.\d+)?)\s*(degrees?|radians?)\b/gi)];for(const c of v){const l=c[1].toUpperCase(),m=Number(c[2]),g=c[3].toLowerCase().startsWith("degree")?"degrees":"radians",P=v.filter(z=>z[1].toUpperCase()===l);w(u)&&Number.isFinite(m)&&D(P.map(z=>`${z[2]}:${z[3]}`)).length===1?h(`edit${l}AxisLabels`,new Map([["rotation",`{ value: ${m}, unit: "${g}" }`]]),c[0]):d(c[0],`request.${l.toLowerCase()}AxisRotation`,"Axis label rotation requires one Cartesian chart and an unambiguous angle with units.")}for(const c of t.matchAll(/\b(?:logarithmic|log)\s+([xy])\s+(?:axis|scale)\b/gi))w(u)?h(`edit${c[1].toUpperCase()}Scale`,new Map([["type",'"log"']]),c[0]):d(c[0],"request.logScale","A logarithmic scale requires one unambiguous Cartesian chart and compatible nonzero data.");const M=t.match(/\b(?:(one|two|three|four|five|six|seven|eight|nine|ten|\d+)\s+bands?|bands?\s*(?:of|=|:)?\s*(one|two|three|four|five|six|seven|eight|nine|ten|\d+))\b/i);if(M){const c=W(M,1,2),l=Number({one:1,two:2,three:3,four:4,five:5,six:6,seven:7,eight:8,nine:9,ten:10}[c.toLowerCase()]??c);Number.isInteger(l)&&l>0?a(["createHorizonPlot","encodeHorizon","editHorizon"],new Map([["bands",String(l)]]),M[0]):(n.push(M[0]),r.push(k("request.option.horizon.bands","Horizon bands must be a positive integer.")))}const G=/\b(?:legend|encoding key)\b/i.test(t),X=e.some(c=>c.provider.id.startsWith("exact.")&&/Legend/.test(c.provider.name)),E=e.some(c=>c.provider.name==="facet"),q=new Set(["encoding.color","encoding.opacity","encoding.shape","encoding.size","encoding.strokeDash","encoding.strokeWidth"]),H=e.some(c=>["createPiePlot","createRosePlot","createRadialBarPlot"].includes(c.provider.name)||c.coverage.some(l=>q.has(l)));if(G&&!H&&!X&&!E){const c=D(e.flatMap(l=>l.coverage).filter(l=>l==="guide.legend"||l.startsWith("layout.legend.")));e=e.map(l=>({...l,coverage:l.coverage.filter(m=>m!=="guide.legend"&&!m.startsWith("layout.legend."))})).filter(l=>l.coverage.length>0||l.provider.id.startsWith("exact.")),n.push("legend channel");for(const l of c)r.push(k(l,"A legend requires a concrete compatible encoding channel such as color, shape, size, opacity, stroke dash, or stroke width."))}const L=t.match(/\blegend\s+(?:at|on)\s+(top|bottom|left|right)\b/i),y=G?t.match(/\b(?:(\d+)\s+columns?|columns?\s*(?:=|:)?\s*(\d+))\b/i):void 0,I=G?void 0:t.match(/\b(?:(\d+)\s+columns?|columns?\s*(?:=|:)?\s*(\d+))\b/i),V=G?t.match(/\b(?:(horizontal|vertical)(?:\s+direction)?\s+legend|legend(?:\s+direction)?\s*(?:=|:|is)?\s*(horizontal|vertical)|direction\s*(?:=|:|is)?\s*(horizontal|vertical)|legend\b[^,;]{0,60}\b(horizontal|vertical)|(horizontal|vertical)\s+direction)\b/i):void 0,f=new Map;if(L&&f.set("position",B(L[1].toLowerCase())),y){const c=Number(W(y,1,2));Number.isInteger(c)&&c>0?f.set("columns",String(c)):(n.push(y[0]),r.push(k("request.option.legend.columns","Legend columns must be a positive integer.")))}if(V&&f.set("direction",B(W(V,1,2,3,4,5).toLowerCase())),L?.[1].toLowerCase()==="bottom"&&f.set("offset",$e),I&&(n.push(I[0]),r.push(k("request.option.columns","A column count requires a concrete owner such as a legend or composition layout."))),f.size>0&&(H||X||E)){const c=[L?.[0],y?.[0],V?.[0]].filter(Boolean).join(", ");if(!a(["editLegendLayout","createLegend"],f,c)){const l=[...f].map(([m,g])=>`${m}: ${g}`).join(", ");a([...ve],new Map([["guides",`{ legend: { ${l} } }`]]),c)}}const O=t.match(/\b(\d+)\s+x[ -]?bins?\b/i),j=t.match(/\b(\d+)\s+y[ -]?bins?\b/i),J=t.match(/\b(\d+)\s+(?:bins?|bins? per axis)\b/i),N=new Map,F=[];if(O||j)if(O&&j){const c=Number(O[1]),l=Number(j[1]);if(c>0&&l>0)N.set("bins",`{ x: ${c}, y: ${l} }`),F.push(O[0],j[0]);else{const m=`${O[0]}; ${j[0]}`;n.push(m),r.push(k("request.option.bin2d.bins","Two-dimensional x and y bin counts must be positive integers."))}}else{const c=O?"y":"x",l=(O??j)[0];n.push(l),r.push(k(`transform.bin2d.bins.${c}`,`Two-dimensional bin counts require both x and y; the request specifies only ${l}.`))}else if(J){const c=Number(J[1]);Number.isInteger(c)&&c>0?(N.set("bins",String(c)),F.push(J[0])):(n.push(J[0]),r.push(k("request.option.bin2d.bins","Two-dimensional bin counts must be positive integers.")))}const K=t.match(/\b(include|exclude|omit)\s+empty\s+(?:bins|cells)\b/i);if(K&&(N.set("includeEmpty",String(K[1].toLowerCase()==="include")),F.push(K[0])),N.size>0){const c=F.join("; ");if(!a(["createBin2DData","editBin2DData"],N,c)){const l=[...N].map(([z,Q])=>`${z}: ${Q}`).join(", "),m=a(["createHeatmap"],new Map([["bin",`{ ${l} }`]]),c),g=N.get("bins"),P=!m&&g!==void 0&&/^\d+$/.test(g)&&!N.has("includeEmpty")&&a(["createHistogram"],new Map([["maxBins",g]]),c);!m&&!P&&(n.push(c),r.push(k("request.option.bin2d","Two-dimensional bin options require a heatmap or a create/edit Bin2D data action.")))}}const _=t.match(/\b(?:titled\b|(?:chart\s+)?title\b(?:\s+(?:is|text))?)\s*[:=]?\s*(?:"([^"]+)"|'([^']+)'|([A-Za-z0-9][^,;]*?))(?=\s+(?:(?:and|with)\s+)?(?:font(?:[ -]?size)?|subtitle|on\s+|as\s+)|$)/i),Y=W(_,1,2,3);Y&&!ce.has(Y.toLowerCase())&&a(["createTitle","editTitle"],new Map([["text",B(Y)]]),_[0]);const ie=t.match(/\bsubtitle(?:\s+(?:is|text))?\s*[:=]?\s*(?:"([^"]+)"|'([^']+)'|([A-Za-z0-9][^,;]*?))(?=\s+(?:(?:and|with)\s+)?(?:font(?:[ -]?size)?|title|on\s+|as\s+)|$)/i),ee=W(ie,1,2,3);ee&&!ce.has(ee.toLowerCase())&&a(["createTitle","editTitle"],new Map([["subtitle",B(ee)]]),ie[0]);const s=t.match(/\bfont[ -]?size\s*(?:=|:)?\s*(\d+(?:\.\d+)?)\b/i);if(s){const c=Number(s[1]);c>0&&a(["createTitle","editTitle"],new Map([["titleStyle",`{ fontSize: ${s[1]} }`]]),s[0])||(n.push(s[0]),r.push(k("request.option.fontSize",c>0?"A font size requires a concrete text owner such as a chart title, axis, legend, or text mark.":"Font size must be a positive finite number.")))}const x=Object.freeze({x:["createScatterPlot","createLinePlot","createAreaPlot","createBarPlot","createHeatmap","createBoxPlot","createViolinPlot","createGradientPlot","createRegressionData","createBin2DData","encodeHorizon","createHorizonPlot"],y:["createScatterPlot","createLinePlot","createAreaPlot","createBarPlot","createHeatmap","createBoxPlot","createViolinPlot","createGradientPlot","createRegressionData","createBin2DData","encodeHorizon","createHorizonPlot"]}),b=new Set;for(const c of["x","y"]){const l=Qe(t,c);if(!l||/^(?:bins?|axis|encoding|field)$/i.test(l.value))continue;(a(x[c],new Map([[c,B(l.value)]]),l.source)||a([`encode${c.toUpperCase()}`],new Map([["field",B(l.value)]]),l.source))&&b.add(c)}const C=t.match(/\b(?:plot|chart)\s+of\s+(?:"([^"]+)"|'([^']+)'|([A-Za-z_$][A-Za-z0-9_$.-]*))\s+(?:vs\.?|versus|against)\s+(?:"([^"]+)"|'([^']+)'|([A-Za-z_$][A-Za-z0-9_$.-]*))/i);if(C&&b.size===0){const c=W(C,1,2,3),l=W(C,4,5,6);for(const[m,g]of[["x",l],["y",c]])a(x[m],new Map([[m,B(g)]]),C[0])||a([`encode${m.toUpperCase()}`],new Map([["field",B(g)]]),C[0])}const R=Object.freeze({color:["createScatterPlot","createLinePlot","createAreaPlot","createBarPlot","createViolinPlot","createPiePlot","createRosePlot","createRadialBarPlot","createPolarScatterPlot","createPolarLinePlot","createRadarPlot"],size:["createScatterPlot","createPolarScatterPlot"],shape:["createScatterPlot","createPolarScatterPlot"]});for(const c of["color","size","shape"]){const l=et(t,c);if(!l)continue;a(R[c],new Map([[c,B(l.value)]]),l.source)||a([`encode${c[0].toUpperCase()}${c.slice(1)}`],new Map([["field",B(l.value)]]),l.source)}const ae=e.find(c=>c.provider.name==="renderToSVG");if(ae){const c=t.match(/\bsvg\s+title\s*(?:=|:)?\s*(?:"([^"]+)"|'([^']+)')/i),l=t.match(/\bdescription\s*(?:=|:)?\s*(?:"([^"]+)"|'([^']+)')/i),m=new Map;if(c&&m.set("title",B(W(c,1,2))),l&&m.set("description",B(W(l,1,2))),m.size>0){const g=[...m].map(([P,z])=>`${P}: ${z}`).join(", ");e=e.map(P=>P===ae?{...P,provider:{...P.provider,call:`renderToSVG(program, { ${g} })`}}:P);for(const[P,z]of m)i.push({owner:"renderToSVG",option:P,value:z,source:P==="title"?c[0]:l[0]})}}const U=t.match(/\bpixel[ -]?ratio\s*(?:=|:)?\s*(\d+(?:\.\d+)?)\b/i);if(U){const c=Number(U[1]),l=e.find(m=>["render","renderToPNG"].includes(m.provider.name));if(l&&c>0){const m=l.provider.name==="render"?`render(program, context, { pixelRatio: ${U[1]} })`:l.provider.call.replace(/\s*}\)$/,`, pixelRatio: ${U[1]} })`);e=e.map(g=>g===l?{...g,provider:{...g.provider,call:m}}:g),i.push({owner:l.provider.name,option:"pixelRatio",value:U[1],source:U[0]})}else n.push(U[0]),r.push(k("renderer.pixelRatio",c>0?"pixelRatio applies only to Browser Canvas or PNG output; choose one of those renderers or remove the requirement.":"pixelRatio must be a positive finite number."))}else if(/\b(?:high[ -]?dpi|retina)\b/i.test(t)){const c=t.match(/\b(?:high[ -]?dpi|retina)\b/i)[0];n.push(c),r.push(k("renderer.pixelRatio","High-density raster or Canvas output requires an explicit positive pixelRatio."))}/\bresponsive\b/i.test(t)&&(n.push("responsive"),r.push(k("layout.responsive","Responsive charts require host resize observation and immutable program rebuilding; no container size was supplied."))),/\b(?:accessible|accessibility|aria)\b/i.test(t)&&(i.some(l=>l.owner==="renderToSVG"&&l.option==="title")&&i.some(l=>l.owner==="renderToSVG"&&l.option==="description")||(n.push("accessible output"),r.push(k(ae?"renderer.svg.accessibleText":"output.accessibility",ae?"Accessible SVG output requires concrete title and description strings.":"Accessibility requires an output-specific accessible name, description, and host fallback strategy."))));const Se=new Set(i.map(c=>`${c.owner}.${Z(c.option)}`)),Oe=Z(t);for(const c of e.filter(l=>l.provider.kind==="action")){const l=A.get(c.provider.name),m=re(c.provider,c.coverage);for(const g of l?.options??[]){const P=Z(g.name);if(P.length<3||!le(Oe,P).length||Se.has(`${c.provider.name}.${P}`)||m.has(g.name)||g.name==="stroke"&&/\b(?:stroke[ -]?dash|dashed?\s+stroke)\b/i.test(t)||g.name==="bins"&&r.some(Ce=>Ce.constraint.startsWith("transform.bin2d.bins.")))continue;const z=tt(t,g.name);if(!z)continue;const Q=`${c.provider.name}.${g.name}: ${z}`;n.includes(Q)||(n.push(Q),r.push(k(`request.option.${c.provider.name}.${g.name}`,`The request mentions ${g.name}, but its value could not be parsed safely for ${c.provider.name}.`)))}}return{entries:e,appliedOptions:i,unmatchedRequirements:D(n),unresolved:r}}p(ot,"applyRequestedOptions");function nt(o,t=[]){const e=new Map,i=p((r,a,d,w)=>{const h=`${a}:${r}`,$=e.get(h)??{name:r,kind:a,required:!0,usedBy:[],reason:w};$.usedBy=D([...$.usedBy,d]),e.set(h,$)},"add"),n=o.find(r=>r.plan.name==="createData");(!n||/\bvalues\s*:\s*values\b/.test(n.call))&&i("values","binding","createData","Supply the caller-owned dataset rows before running the authoring block.");for(const r of o){r.plan.name==="render"&&i("context","runtime","render","Supply a CanvasRenderingContext2D from the host page."),["hconcat","vconcat"].includes(r.plan.name)&&i("programs","program",r.plan.name,"Replace the repeated sample program with two complete child ChartPrograms.");const a=r.call.matchAll(/\b(?:field|x|y|theta|radius|color|size|shape|groupBy|weight):\s*"(x|y|value|category|label|angle|distance|date|a|b|series)"/g);for(const d of a)i(d[1],"field",r.plan.name,"Replace this template name unless the input dataset declares the same field.");if(r.call.includes('"Chart title"')&&i("Chart title","text",r.plan.name,"Replace the sample title with user-approved chart text."),r.plan.id.startsWith("exact.")){const d=A.get(r.plan.name);for(const w of d?.resources.prerequisites??[])i(w,"resource",r.plan.name,"Provide or create this action-card prerequisite before applying the exact call.")}}for(const r of t){if(!new Set(["color","field","groupBy","shape","size","weight","x","y","theta","radius"]).has(r.option))continue;let a;try{a=JSON.parse(r.value)}catch{continue}typeof a!="string"||a.length===0||i(a,"field",r.owner,"Confirm that this request-supplied field exists in the caller-owned dataset.")}return[...e.values()]}p(nt,"placeholderBindings");function rt(o){let t=!1,e=new Set;const i=p(()=>t&&e.has("encodeX")&&e.has("encodeY")&&!e.has("encodeX2")&&!e.has("encodeY2"),"incomplete");for(const n of o){if(n.provider.id.startsWith("exact."))continue;const r=n.provider.name;if(r.startsWith("create")&&(r.endsWith("Mark")||r.endsWith("Plot"))){if(i())return!0;t=r==="createRuleMark",e=new Set;continue}t&&["encodeX","encodeY","encodeX2","encodeY2"].includes(r)&&e.add(r)}return i()}p(rt,"hasIncompleteRulePrimaryPair");function it(o){return o.filter(e=>e.provider.name==="createScale"&&!e.provider.id.startsWith("exact.")).filter(e=>{const i=e.provider.baseOptions?.id;if(i===void 0)return!1;const n=`id: ${i}`;return!o.some(r=>r!==e&&[...re(r.provider,r.coverage).values()].some(a=>a.includes(n)))}).map(e=>e.provider.baseOptions.id.replaceAll('"',""))}p(it,"unconsumedScaleIds");function at(o){const t=new Set(o.filter(d=>!d.provider.id.startsWith("exact.")).map(d=>d.provider.name)),e=[],i=[],n=new Set(o.flatMap(d=>d.coverage)),a=[...t].filter(d=>d.startsWith("create")&&(d.endsWith("Mark")||d.endsWith("Plot"))).length>0||[...t].some(d=>["createHistogram","createHeatmap","createParallelCoordinates"].includes(d));["selectMarks","filterMarks","highlightMarks","facet"].some(d=>t.has(d))&&!a&&e.push(k("chart.type","Selection and faceting require one explicit chart or mark owner before those actions can be addressed.")),["hconcat","vconcat"].some(d=>t.has(d))&&!a&&e.push(k("composition.children","Composition requires at least two complete child ChartPrograms; name or provide the child charts first.")),t.has("layoutLabels")&&t.has("createTextMark")&&!t.has("encodeX")&&!t.has("encodeY")&&e.push(k("encoding.position","Collision-aware labels require a positioned source layer or explicit x and y encodings.")),t.has("createLegend")&&!["encodeColor","encodeSize","encodeShape","encodeOpacity","encodeStrokeDash","encodeStrokeWidth"].some(d=>t.has(d))&&e.push(k("guide.legend.channel","A legend requires an explicit compatible visual encoding such as color, size, shape, opacity, dash, or width.")),rt(o)&&e.push(k("encoding.rule.endpoint","A rule with both x and y primary positions also requires x2 or y2; otherwise choose one primary position for a full-span rule."));for(const d of it(o))e.push(k("scale.consumer",`Scale "${d}" is not connected to a compatible encoding; choose the channel that should consume it.`));return(t.has("createAreaMark")||t.has("createAreaPlot"))&&t.has("encodeStrokeDash")&&i.push({constraint:"unsupported.areaStrokeDash",reason:"Field-driven stroke dash is not supported for area marks; use a line or rule mark for dash encoding."}),{unresolved:e,unsupported:i}}p(at,"runtimeClosureDecisions");function k(o,t){const e=ye[o]??(o.startsWith("layout.legend.")?"ggaction://docs/legend-layout":"ggaction://docs/action-reference");return{constraint:o,reason:t,resources:[e]}}p(k,"unresolvedDecision");function st(o,t){const e=[],i=["chart.pie","chart.donut"].some(a=>o.has(a)&&!t.has(a)),n=o.has("chart.horizon")&&!t.has("chart.horizon"),r=o.has("chart.density")&&!t.has("chart.density");for(const a of o){let d;i&&["encoding.x","encoding.y","guide.axes","guide.xAxis","guide.yAxis","guide.grid"].includes(a)&&(d="A pie has categorical sectors and a color legend. Cartesian positions, axes, and grids require a different chart or an explicit lower-level recipe."),n&&(a==="guide.yAxis"||a==="encoding.color"||a==="guide.legend"||a.startsWith("layout.legend."))&&(d="Horizon's y scale and palette describe internal folded bands. Choose an explicit lower-level guide or a separate original-amplitude guide; the facade only creates original-x guides."),r&&(a==="encoding.color"||a==="guide.legend"||a.startsWith("layout.legend."))&&(d="Density color requires an explicit groupBy field and matching color field. Its derived data does not retain arbitrary raw categories; choose that grouping before requesting a color legend."),d&&(t.add(a),e.push(k(a,d)))}return e}p(st,"completeChartBoundaries");function ct(o,t,e,i){const n=p(u=>u.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").trim().replace(/\s+/g," "),"normalizeWords"),r=` ${n(o)} `,a=new Uint8Array(r.length),d=[...i.appliedOptions.map(u=>u.source),...i.unmatchedRequirements,...i.unresolved.some(u=>["renderer.svg.accessibleText","output.accessibility"].includes(u.constraint))||["title","description"].every(u=>i.appliedOptions.some(v=>v.owner==="renderToSVG"&&v.option===u))?["accessible","accessibility"]:[],...i.entries.some(u=>u.provider.name==="facet"&&/legend:\s*"shared"/.test(re(u.provider,u.coverage).get("guides")??""))?["shared legend"]:[],...t.flatMap(u=>u.phrases),...e].map(n).filter(Boolean).sort((u,v)=>v.length-u.length);for(const u of d){const v=` ${u} `;let M=r.indexOf(v);for(;M!==-1;)a.fill(1,M,M+v.length),M=r.indexOf(v,M+1)}const w=r.split("").map((u,v)=>a[v]?" ":u).join(""),h=new Set("a an the and then with using use as at on in to of for by from create draw make build show add apply set please chart plot output export render i want would like me can you it this that is be should must into also put charts".split(" "));return w.trim().split(/\s+/).filter(u=>u&&!h.has(u)).length===0?[]:o.trim().match(/[\s\S]{1,176}/g)??[]}p(ct,"unconsumedRequirements");function dt(o,t,e){const i=[],n=[...t].filter(r=>!r.startsWith("renderer.")&&!r.startsWith("unsupported."));return/\b(chart|plot)\b/.test(o)&&n.length===0&&![...t].some(r=>r.startsWith("unsupported."))&&e.length===0&&i.push(k("chart.type","A chart or mark type is required; for example scatter plot, line chart, bar chart, or tick mark.")),/\b(render|export|output)\b/.test(o)&&![...t].some(r=>r.startsWith("renderer."))&&i.push(k("renderer.format","A supported output format is required: Browser Canvas, SVG, PNG, or PDF.")),i}p(dt,"genericUnresolved");function ke(){if(te.schemaVersion!==3||T.schemaVersion!==2)throw new Error("Compact action cards must use schemaVersion 3 and the intent taxonomy must use schemaVersion 2.");if(T.packageVersion!==te.packageVersion)throw new Error("Compact action cards and the intent taxonomy must use one packageVersion.");if(oe.size!==T.constraints.length)throw new Error("Intent constraint IDs must be unique.");if(new Set(T.providers.map(n=>n.id)).size!==T.providers.length)throw new Error("Intent provider IDs must be unique.");const t=new Set;for(const n of T.constraints)for(const r of n.shadows??[])if(!oe.has(r)||r===n.id)throw new Error(`${n.id} shadows invalid constraint ${r}.`);for(const n of T.providers){for(const r of[...n.anchors,...n.covers])if(!oe.has(r))throw new Error(`${n.id} references unknown constraint ${r}.`);if(n.anchors.some(r=>!n.covers.includes(r)))throw new Error(`${n.id} does not cover every anchor.`);for(const r of n.anchors)t.add(r);if(n.kind==="action"){const r=A.get(n.name);if(!r)throw new Error(`${n.id} references unknown action ${n.name}.`);const a=new Set(r.options.map(w=>w.name)),d=[n.baseOptions??{},...Object.values(n.optionsByConstraint??{})];for(const w of d)for(const[h,$]of Object.entries(w)){if(!a.has(h))throw new Error(`${n.id} references undeclared option ${h}.`);if(typeof $!="string"||$.length===0)throw new Error(`${n.id}.${h} must be a JavaScript expression string.`)}}else{if(n.kind!=="runtime"||typeof n.signature!="string"||typeof n.call!="string"||!n.route.startsWith("/reference/"))throw new Error(`${n.id} has an invalid runtime contract.`);if(!ge.includes(n.name)&&se[n.name]===void 0)throw new Error(`${n.id} lacks an authoring runtime mapping.`)}}const e=T.constraints.filter(n=>n.unsupported===void 0&&!t.has(n.id));if(e.length>0)throw new Error(`Supported constraints lack providers: ${e.map(n=>n.id).join(", ")}.`);const i=T.constraints.filter(n=>n.unsupported!==void 0!==n.id.startsWith("unsupported.")||n.unsupported!==void 0&&t.has(n.id));if(i.length>0)throw new Error(`Terminal constraints must use unsupported.* IDs without providers: ${i.map(n=>n.id).join(", ")}.`);for(const n of de)if(!A.has(n))throw new Error(`Missing authoring prerequisite action card: ${n}.`);return{cards:A.size,constraints:oe.size,providers:T.providers.length,supported:T.constraints.filter(n=>n.unsupported===void 0).length,unsupported:T.constraints.filter(n=>n.unsupported!==void 0).length}}p(ke,"validateResolverKnowledge");function mt(o){if(typeof o!="string"||o.trim().length===0)throw new TypeError("searchGgaction query must be a non-empty string.");if(o.length>500)throw new RangeError("searchGgaction query must be at most 500 characters.");ke();const t=Ae(o),e=t?"":o,i=Z(e),n=De(e),{matched:r,positions:a}=Ee(i);for(const f of n){const[O]=le(i,Z(f));O&&a.set(`action.${f}`,O.start)}const d=new Set([...r.map(f=>f.id),...n.map(f=>`action.${f}`)]),w=r.filter(f=>f.unsupported!==void 0).map(f=>({constraint:f.id,reason:f.unsupported})),h=t?[k("request.negation","Negation or exclusion requires explicit interpretation. No authoring steps are proposed; preserve the restriction when choosing action options.")]:[],{blocked:$,unresolved:u}=Ne(r);h.push(...u),h.push(...st(d,$));const v=new Set([...d].filter(f=>{const O=oe.get(f);return!$.has(f)&&(O===void 0||O.unsupported===void 0)})),M=We(v,n),{selected:G,uncovered:X}=je(v,M);for(const f of X)h.push(k(f,"No current action or runtime operation covers this recognized constraint."));h.push(...dt(i,d,n)),d.size===0&&h.length===0&&h.push(k("query.intent","No current ggaction constraint was recognized; use an exact action name or a supported chart task."));let E=He(_e(G).sort((f,O)=>f.provider.order-O.provider.order||xe(f,a)-xe(O,a)||f.provider.id.localeCompare(O.provider.id)));const q=ot(Ye(E),e);E=q.entries,h.push(...q.unresolved);const H=t?[]:ct(e,r,n,q);H.length>0&&(q.unmatchedRequirements.push(...H),h.push(k("request.unconsumed","Part of the original request was not interpreted. Review unmatchedRequirements before claiming the requested chart is complete.")));const L=at(E);w.push(...L.unsupported),h.push(...L.unresolved),L.unsupported.some(f=>f.constraint==="unsupported.areaStrokeDash")&&(E=E.filter(f=>f.provider.name!=="encodeStrokeDash"));const y=E.map((f,O)=>Fe(f,O+1)),I={schemaVersion:5,packageVersion:te.packageVersion,query:o.trim(),matchedConstraints:[...d],actionPlan:y.map(f=>f.plan),exactCalls:y.map(f=>f.call),appliedOptions:q.appliedOptions,placeholderBindings:nt(y,q.appliedOptions),unmatchedRequirements:t?o.trim().length<=180?[o.trim()]:o.trim().match(/[\s\S]{1,176}/g).map((f,O)=>`${O+1}. ${f}`):q.unmatchedRequirements,authoring:Je(y),unsupported:w,unresolved:D(h.map(f=>JSON.stringify(f))).map(JSON.parse),candidates:y.slice(0,3).map(f=>({id:f.plan.id,kind:f.plan.kind,name:f.plan.name,route:f.plan.route}))},V=Buffer.byteLength(JSON.stringify(I),"utf8");if(V>6144)throw new qe(V);return I}p(mt,"searchGgaction");function gt(o){return Buffer.byteLength(JSON.stringify(o),"utf8")}p(gt,"taskPacketBytes"),ke();export{qe as TaskPacketBudgetError,mt as searchGgaction,gt as taskPacketBytes,ke as validateResolverKnowledge};
1
+ var ze=Object.defineProperty;var p=(o,t)=>ze(o,"name",{value:t,configurable:!0});import{IMPUTE_REQUIRED_OPTIONS as Te}from"../src/core/optionRequirements.js";import{readFileSync as fe}from"node:fs";import he from"node:path";import{fileURLToPath as Me}from"node:url";const me=Me(new URL("../",import.meta.url)),te=JSON.parse(fe(he.join(me,"knowledge/action-cards.json"),"utf8")),T=JSON.parse(fe(he.join(me,"knowledge/intent-taxonomy.json"),"utf8")),A=new Map(te.cards.map(o=>[o.name,o])),oe=new Map(T.constraints.map(o=>[o.id,o])),ge=Object.freeze(["hconcat","vconcat","render"]),se=Object.freeze({renderToSVG:Object.freeze({entry:"ggaction/svg",output:"svg"}),renderToPNG:Object.freeze({entry:"ggaction/png",output:"png"}),renderToPDF:Object.freeze({entry:"ggaction/pdf",output:"pdf"})}),de=Object.freeze(["createCanvas","createData"]),Re=Object.freeze({width:"800",height:"600",margin:"{ top: 140, right: 220, bottom: 120, left: 260 }"}),ve=new Set(["createScatterPlot","createLinePlot","createAreaPlot","createBarPlot","createBoxPlot","createGradientPlot","createViolinPlot","createPolarScatterPlot","createPolarLinePlot","createRadarPlot","createRugPlot","createStripPlot"]),Be=new Set(["createAxes","createXAxis","createYAxis","createGrid","createLegend","createGuides"]),ye=Object.freeze({"chart.type":"ggaction://docs/choose-chart-type","renderer.format":"ggaction://docs/choose-renderer","layout.responsive":"ggaction://docs/responsive-layout","output.accessibility":"ggaction://docs/accessibility","renderer.svg.accessibleText":"ggaction://docs/accessibility","renderer.pixelRatio":"ggaction://docs/responsive-layout","query.intent":"ggaction://docs/getting-started"});class qe extends Error{static{p(this,"TaskPacketBudgetError")}constructor(t){super(`Compact task packet is ${t} bytes; the hard ceiling is 6144 bytes.`),this.name="TaskPacketBudgetError",this.bytes=t}}function D(o){return[...new Set(o)]}p(D,"unique");function Z(o){return o.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g," ").trim().replace(/\s+/g," ")}p(Z,"normalize");const be=/\b(?:no|not|without|exclude|excluding|omit|omitting|avoid|avoiding|don['’]t|doesn['’]t|isn['’]t|aren['’]t|never|neither|nor)\b/i;function Ae(o){let t=o.normalize("NFKC").replace(/(^|[\s=:(,])("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')/g,(e,i,n)=>i+" ".repeat(n.length));for(const e of T.constraints)for(const i of e.phrases.filter(n=>be.test(n))){const n=Z(i).split(" ").join("\\s+");t=t.replace(new RegExp(`\\b${n}\\b`,"gi")," ")}return be.test(t)}p(Ae,"hasUnresolvedNegation");function le(o,t){const e=Z(t),i=` ${o} `,n=` ${e} `,r=[];let a=0;for(;a<i.length;){const d=i.indexOf(n,a);if(d===-1)break;r.push({start:d+1,end:d+n.length-1}),a=d+1}return r}p(le,"phraseOccurrences");function De(o){return te.cards.filter(t=>new RegExp(`(?:^|[^A-Za-z0-9])${t.name}(?:$|[^A-Za-z0-9])`,"i").test(o)).map(t=>t.name)}p(De,"exactActionNames");function Ee(o){const t=T.constraints.flatMap(r=>r.phrases.flatMap(a=>le(o,a).map(d=>({constraint:r,...d})))),e=t.filter(r=>!t.some(a=>a.constraint.shadows?.includes(r.constraint.id)&&a.start<=r.start&&a.end>=r.end)),i=T.constraints.filter(r=>e.some(a=>a.constraint.id===r.id)),n=new Map(i.map(r=>[r.id,Math.min(...e.filter(a=>a.constraint.id===r.id).map(a=>a.start))]));return{matched:i,positions:n}}p(Ee,"semanticMatchResult");function pe(o){return o.name==="createCanvas"?10:o.name==="createData"?20:o.name.endsWith("Data")?30:o.domain==="charts"||o.domain==="marks"&&o.name.startsWith("create")?40:o.domain==="encodings"?/^encode(X|Y|X2|Y2|XRange|YRange|Theta|R|Radius|ParallelCoordinates)/.test(o.name)?50:o.name==="encodeGroup"||o.name==="encodePathOrder"?52:55:o.domain==="statistics"?60:["axes","grid","legend_and_title"].includes(o.domain)?70:o.domain==="mark-selection"?75:o.domain==="composition"||/^(layout|jitter|order|replace)/.test(o.name)?80:65}p(pe,"orderForCard");function Le(o,t){const e=A.get(o),i=T.providers.filter(n=>n.kind==="action"&&n.name===o).map(n=>({provider:n,coverage:n.covers.filter(r=>t.has(r)).length})).filter(n=>n.coverage>0).sort((n,r)=>r.coverage-n.coverage||n.provider.order-r.provider.order||n.provider.id.localeCompare(r.provider.id))[0]?.provider;return i?{...i,id:`exact.${o}`,anchors:[`action.${o}`],covers:D([`action.${o}`,...i.covers.filter(n=>t.has(n))])}:{id:`exact.${o}`,kind:"action",name:o,order:pe(e),anchors:[`action.${o}`],covers:[`action.${o}`],exactCall:e.snippet,exactOptionNames:e.options.filter(n=>new RegExp(`\\b${n.name}\\s*:`).test(e.snippet)).map(n=>n.name)}}p(Le,"exactProvider");function Ne(o){const t=new Map;for(const n of o){if(!n.exclusiveGroup)continue;const r=t.get(n.exclusiveGroup)??[];r.push(n),t.set(n.exclusiveGroup,r)}const e=new Set,i=[];for(const[n,r]of t)if(!(r.length<2)){for(const a of r)e.add(a.id);for(const a of r)i.push({constraint:a.id,reason:`This conflicts within ${n}: ${r.map(d=>d.id).join(", ")}.`,resources:[n==="legend.position"?"ggaction://docs/legend-layout":"ggaction://docs/choose-chart-type"]})}return{blocked:e,unresolved:i}}p(Ne,"conflictResult");function We(o,t){const e=T.providers.filter(i=>i.anchors.some(n=>o.has(n)));for(const i of t)e.push(Le(i,o));return e}p(We,"candidateProviders");function je(o,t){const e=new Set(o),i=[];for(;e.size>0;){const n=t.filter(a=>!i.some(d=>d.provider.id===a.id)).map(a=>({provider:a,coverage:a.covers.filter(d=>e.has(d))})).filter(a=>a.coverage.length>0).sort((a,d)=>d.coverage.length-a.coverage.length||a.provider.order-d.provider.order||a.provider.id.localeCompare(d.provider.id));if(n.length===0)break;const r=n[0];i.push(r);for(const a of r.coverage)e.delete(a)}return{selected:i,uncovered:e}}p(je,"selectProviders");function _e(o){let t=o;o.some(a=>a.provider.name==="selectMarks")&&(t=t.map(a=>a.provider.name!=="highlightMarks"?a:{...a,provider:{...a.provider,baseOptions:{selection:'"selection-1"',color:'"#f28e2b"'}}}));const i=t.some(a=>a.provider.name==="createRegression"&&!a.provider.id.startsWith("exact.")),n=t.some(a=>["createPointMark","createScatterPlot","createPolarScatterPlot"].includes(a.provider.name));i&&!n&&(t=[ne("createPointMark",{}),...t]);const r=t.find(a=>a.provider.name==="editLegendLayout"&&a.coverage.some(d=>d.startsWith("layout.legend.")));if(r){const a=t.find(d=>d.coverage.includes("guide.legend")&&(d.provider.name==="createLegend"||d.provider.optionsByConstraint?.["guide.legend"]?.guides!==void 0));if(a){const d=r.provider.baseOptions?.position;if(d===void 0)throw new Error(`${r.provider.id} lacks a legend position.`);const w=r.coverage.filter(h=>h.startsWith("layout.legend."));t=t.filter(h=>h!==r).map(h=>{if(h!==a)return h;const $=d==='"left"'?"96":d==='"bottom"'?$e:void 0;return{provider:h.provider.name==="createLegend"?{...h.provider,baseOptions:{...h.provider.baseOptions??{},position:d,...$===void 0?{}:{offset:$}}}:{...h.provider,optionsByConstraint:{...h.provider.optionsByConstraint??{},"guide.legend":{...h.provider.optionsByConstraint?.["guide.legend"]??{},guides:`{ legend: { position: ${d}${$===void 0?"":`, offset: ${$}`} } }`}}},coverage:[...h.coverage,...w]}})}}return t}p(_e,"adaptProviderDependencies");function S(o,t){return{...o,provider:{...o.provider,baseOptions:{...o.provider.baseOptions??{},...t}}}}p(S,"withBaseOptions");function ne(o,t,e=[]){const i=A.get(o);if(!i)throw new Error(`Unknown runtime dependency action ${o}.`);return{provider:{id:`action.${o}`,kind:"action",name:o,order:pe(i),anchors:[],covers:[],baseOptions:t},coverage:e}}p(ne,"dependencyEntry");function Ge(o){const t=o.find(n=>!n.provider.id.startsWith("exact.")&&ve.has(n.provider.name));if(!t)return o;const e=o.filter(n=>!n.provider.id.startsWith("exact.")&&Be.has(n.provider.name));if(e.length===0)return o;const i=e.flatMap(n=>n.coverage);return o.filter(n=>!e.includes(n)).map(n=>n===t?{...n,coverage:D([...n.coverage,...i])}:n)}p(Ge,"absorbFacadeGuides");function we(o,t,e){const i=o.indexOf(t);return i===-1?o:[...o.slice(0,i),...e,...o.slice(i+1)]}p(we,"replaceEntry");function Ie(o){const t=p(v=>o.find(M=>M.provider.name===v&&!M.provider.id.startsWith("exact.")),"semantic"),e=t("createPointMark"),i=t("createTextMark"),n=t("encodeText"),r=new Set(["encodeX","encodeY","encodeColor","encodeSize","encodeShape","encodeAngle","encodeOpacity"]),a=o.filter(v=>!v.provider.id.startsWith("exact.")&&r.has(v.provider.name));if(!e||!i||!n||!a.some(v=>v.provider.name==="encodeX")||!a.some(v=>v.provider.name==="encodeY"))return o;const d=[e,...a,i,n],w=new Set(d),h=Math.min(...d.map(v=>o.indexOf(v))),$=o.slice(0,h).filter(v=>!w.has(v)).length,u=o.filter(v=>!w.has(v));return[...u.slice(0,$),...d,...u.slice($)]}p(Ie,"orderInheritedTextOverlay");function Ve(o){const t=o.find(u=>u.provider.name==="createBarMark"&&!u.provider.id.startsWith("exact."));if(!t)return o;const e=o.indexOf(t),i=o.findIndex((u,v)=>v>e&&!u.provider.id.startsWith("exact.")&&u.provider.name.startsWith("create")&&(u.provider.name.endsWith("Mark")||u.provider.name.endsWith("Plot"))),n=i===-1?o.length:i,r=o.slice(e+1,n).filter(u=>["encodeX","encodeY"].includes(u.provider.name)&&!u.provider.id.startsWith("exact.")),a=r.find(u=>['"nominal"','"ordinal"','"temporal"'].includes(u.provider.baseOptions?.fieldType)),d=r.find(u=>u.provider.baseOptions?.fieldType==='"quantitative"');if(!a||!d||o.indexOf(a)<o.indexOf(d))return o;const w=[...o],h=w.indexOf(a),$=w.indexOf(d);return w[$]=a,w[h]=d,w}p(Ve,"orderBarCategoryBeforeMeasure");function He(o){let t=Ge(o);const e=p(s=>t.find(x=>x.provider.name===s&&!x.provider.id.startsWith("exact.")),"semantic"),i=p(s=>t.find(x=>x.coverage.includes(s)),"chartOwner"),n=p((s,{before:x=[],after:b=[]})=>{if(!s)return;const C=t.indexOf(s);t=[...t.slice(0,C),...x,s,...b,...t.slice(C+1)]},"expandChartOwner"),r=p((s,x)=>{const b=t.find(C=>C.provider.name===s&&!C.provider.id.startsWith("exact."));return b?(t=t.filter(C=>C!==b),S(b,x)):ne(s,x)},"chartDependency"),a=p((s,x)=>{const b=i(s);b&&n(b,x())},"expandChartConstraint");a("chart.bar.horizontal",()=>({after:[r("encodeY",{field:'"category"',fieldType:'"nominal"'}),r("encodeX",{field:'"value"',fieldType:'"quantitative"'})]})),a("chart.radar",()=>({}));const d=e("createData");d&&(t=t.map(s=>s===d?S(s,{values:"values"}):s));const w=e("createCanvas");w&&(t=t.map(s=>s===w?S(s,Re):s));const h=e("createScatterPlot");h&&(t=t.map(s=>s===h?S(s,{x:'{ field: "x", fieldType: "quantitative" }',y:'{ field: "y", fieldType: "quantitative" }'}):s));const $=e("createLinePlot"),u=e("encodeOpacity");$&&u&&(t=t.filter(s=>s!==u).map(s=>s===$?{...S(s,{line:"{ opacity: 0.8 }"}),coverage:D([...s.coverage,...u.coverage])}:s));const v=e("createBarPlot");if(v){const s=e("createScale")?.provider.id==="action.createColorScale",x='{ field: "category", scale: { id: "color-scale" } }';t=t.map(b=>{if(b!==v)return b;const C=S(b,{x:'{ field: "category", fieldType: "nominal" }',y:'{ field: "value", fieldType: "quantitative" }',...s?{color:x}:{}});return s?{...C,provider:{...C.provider,optionsByConstraint:{...C.provider.optionsByConstraint??{},"encoding.color":{color:x}}}}:C})}const M=e("createTimeUnitData"),G=e("createBarPlot");M&&G&&(t=t.map(s=>s===G?S(s,{data:'"monthly"',x:'{ field: "month", fieldType: "ordinal" }',y:'{ field: "value", fieldType: "quantitative" }'}):s));const X=e("createBoxPlot");X&&(t=t.map(s=>s===X?S(s,{x:'{ field: "category", fieldType: "nominal" }',y:'{ field: "value", fieldType: "quantitative" }'}):s));const E=e("createWindowData"),q=e("createLinePlot");if(E&&q){const s=e("createScale")?.provider.id==="action.createTimeScale";t=t.map(x=>x===q?S(x,{data:'"windowed"',x:s?'{ field: "date", fieldType: "temporal", scale: { id: "scale-1" } }':'{ field: "x", fieldType: "quantitative" }',y:'{ field: "movingMean", fieldType: "quantitative" }'}):x)}const H=e("createIntervalData"),L=e("createBoxPlot"),y=e("createErrorBar");H&&L&&y&&(t=t.map(s=>s===H?S(s,{source:'"data"',groupBy:'"category"'}):s===L?S(s,{data:'"data"',x:'{ field: "category", fieldType: "nominal" }',y:'{ field: "value", fieldType: "quantitative" }'}):s===y?S(s,{data:'"interval"',x:'{ field: "category", fieldType: "nominal", scale: { id: "errorBarX" } }',y:'{ center: "__interval_center", lower: "__interval_lower", upper: "__interval_upper", scale: { id: "errorBarY" } }'}):s));const I=e("createDensityData"),V=e("createViolinPlot");I&&V&&(t=t.filter(s=>s!==I).map(s=>s===V?{...S(s,{data:'"data"',...s.coverage.includes("guide.legend")?{color:'"category"'}:{}}),coverage:D([...s.coverage,...I.coverage])}:s));const f=e("createGradientPlot"),O=e("createScale")?.provider.id==="action.createLogScale"?e("createScale"):void 0;f&&(t=t.map(s=>s===f?S(s,{data:'"data"',x:`{ field: "value", fieldType: "quantitative"${O?', scale: { id: "scale-1" }':""} }`,y:'{ field: "category", fieldType: "nominal" }'}):s));const j=e("encodeDensity"),J=e("createAreaMark");if(j&&!J){const s=ne("createAreaMark",{id:'"densityArea"'}),x=t.indexOf(j);t=[...t.slice(0,x),s,...t.slice(x)].map(b=>b===j?S(b,{target:'"densityArea"'}):b)}const N=e("createBin2DData"),F=e("createRectMark");if(N&&F){t=t.map(R=>R===N?S(R,{source:'"data"'}):R===F?S(R,{id:'"rect"',data:'"bins"'}):R.provider.id==="action.createColorScale"?S(R,{type:'"sequential"',range:'{ palette: "viridis" }'}):R);const s=e("encodeX"),x=e("encodeY");s&&(t=we(t,s,[S(s,{field:'"__bins_x0"',fieldType:'"quantitative"',target:'"rect"'}),ne("encodeX2",{field:'"__bins_x1"',fieldType:'"quantitative"',target:'"rect"'})])),x&&(t=we(t,x,[S(x,{field:'"__bins_y0"',fieldType:'"quantitative"',target:'"rect"'}),ne("encodeY2",{field:'"__bins_y1"',fieldType:'"quantitative"',target:'"rect"'})]));const b=e("encodeColor");b&&(t=t.map(R=>R===b?S(R,{field:'"__bins_count"',fieldType:'"quantitative"',target:'"rect"',scale:'{ id: "color-scale" }'}):R));const C=e("createLegend");C&&(t=t.map(R=>R===C?S(R,{target:'"rect"',channels:'["color"]'}):R))}let K,_,Y;const ie=Object.freeze({createPointMark:"point",createLineMark:"line",createAreaMark:"area",createBarMark:"bar",createRuleMark:"rule",createArcMark:"arc",createRectMark:"rect",createTextMark:"text",createScatterPlot:"scatterPlot",createLinePlot:"linePlot",createPolarScatterPlot:"polarScatterPlot",createPolarLinePlot:"polarLinePlot",createRadarPlot:"radarPlot",createRugPlot:"rugPlot",createStripPlot:"stripPlot",createAreaPlot:"areaPlot",createBarPlot:"barPlot",createBoxPlot:"boxPlot",createGradientPlot:"gradientPlot",createViolinPlot:"violinPlot",createPiePlot:"piePlot",createRosePlot:"rosePlot",createRadialBarPlot:"radialBarPlot",createDensityPlot:"densityPlot",createHorizonPlot:"horizonPlot"}),ee=Object.freeze({createPointMark:"point",createLineMark:"line",createAreaMark:"area",createBarMark:"bar",createRuleMark:"rule",createArcMark:"arc",createRectMark:"rect",createTextMark:"text",createScatterPlot:"point",createLinePlot:"line",createPolarScatterPlot:"point",createPolarLinePlot:"line",createRadarPlot:"line",createRugPlot:"tick",createStripPlot:"point",createAreaPlot:"area",createBarPlot:"bar",createBoxPlot:"bar",createGradientPlot:"rect",createViolinPlot:"area",createPiePlot:"arc",createRosePlot:"arc",createRadialBarPlot:"arc",createDensityPlot:"area",createHorizonPlot:"area"});return t=t.map(s=>{if(s.provider.id.startsWith("exact."))return s;if(s.provider.name==="createScale")return Y=s.provider.id==="action.createColorScale"?void 0:s.provider.baseOptions?.id,s;const x=ie[s.provider.name];if(x!==void 0)return K=s.provider.baseOptions?.id?.replaceAll('"',"")??x,_=s.coverage.includes("chart.bar.horizontal")?"bar-horizontal":ee[s.provider.name],s;if(!K||s.provider.name==="createErrorBar")return s;const b={};return["area","rule","arc"].includes(_)&&["encodeX","encodeY","encodeR"].includes(s.provider.name)&&(b.fieldType='"quantitative"'),s.provider.name==="encodeTheta"&&_==="arc"&&s.provider.baseOptions?.fieldType===void 0&&(b.fieldType='"ordinal"'),_==="bar"&&s.provider.name==="encodeX"&&(b.field='"category"',b.fieldType='"nominal"'),_==="bar"&&s.provider.name==="encodeY"&&(b.field='"value"',b.fieldType='"quantitative"'),_==="bar-horizontal"&&s.provider.name==="encodeX"&&(b.field='"value"',b.fieldType='"quantitative"'),_==="bar-horizontal"&&s.provider.name==="encodeY"&&(b.field='"category"',b.fieldType='"nominal"'),Y&&["encodeX","encodeY"].includes(s.provider.name)&&(b.scale=`{ id: ${Y} }`,Y=void 0),Object.keys(b).length===0?s:S(s,b)}),Ie(Ve(t))}p(He,"closeRuntimeDependencies");function xe(o,t){const e=o.coverage.map(i=>t.get(i)).filter(i=>i!==void 0);return e.length===0?Number.POSITIVE_INFINITY:Math.min(...e)}p(xe,"providerRequestPosition");function re(o,t){const e=new Map(Object.entries(o.baseOptions??{}));for(const i of t)for(const[n,r]of Object.entries(o.optionsByConstraint?.[i]??{})){const a=e.get(n);if(a!==void 0&&a!==r){if(n==="guides"&&(a==="{}"||r==="{}")){e.set(n,a==="{}"?r:a);continue}throw new Error(`${o.id} assigns conflicting values to option ${n}.`)}e.set(n,r)}return e}p(re,"mergeOptionValues");function ue(o,t){if(o.exactCall)return o.exactCall;if(A.get(o.name).options.length===0)return`program.${o.name}()`;const i=[...t].map(([n,r])=>`${n}: ${r}`).join(", ");return`program.${o.name}(${i.length===0?"{}":`{ ${i} }`})`}p(ue,"actionCall");function Ye(o){const t=new Map;return o.map(e=>{if(e.provider.kind!=="action")return e;const i=e.provider.name,n=ue(e.provider,re(e.provider,e.coverage));if(/^create.+Data$/.test(i)){const r=n.match(/\bid\s*:\s*"([A-Za-z0-9_-]+)"/)?.[1];r&&t.set(i,r)}if(/^edit.+Data$/.test(i)){const r=t.get(i.replace(/^edit/,"create"));if(r)return Pe(e,new Map([["target",B(r)]]))}return e})}p(Ye,"linkCreatedDataEditors");function Xe(o,t){const e=o.options.filter(i=>i.required).map(i=>i.name);if(o.name==="createImputedData"){const i=t.match(/\bmethod\s*:\s*["'](constant|forward|backward|linear|mean)["']/)?.[1];i&&i!=="mean"&&e.push("method"),e.push(...Te[i]??[])}return D(e)}p(Xe,"requiredOptionNames");function Fe(o,t){const{provider:e,coverage:i}=o,n=re(e,i);if(e.kind==="runtime")return{plan:{step:t,id:e.id,kind:e.kind,name:e.name,constraints:i,requiredOptions:[],signature:e.signature,route:e.route},call:e.call};const r=A.get(e.name),a=new Map(r.options.filter(d=>n.has(d.name)).map(d=>[d.name,n.get(d.name)]));return{plan:{step:t,id:e.id,kind:e.kind,name:e.name,constraints:i,requiredOptions:Xe(r,ue(e,a)),signature:r.signature,route:r.route},call:ue(e,a)}}p(Fe,"planEntry");function Ue(o){const t=new Set(o.filter(i=>i.plan.kind==="runtime").map(i=>i.plan.name));return[`import { ${["chart",...ge.filter(i=>t.has(i))].join(", ")} } from "ggaction";`,...Object.entries(se).filter(([i])=>t.has(i)).map(([i,n])=>`import { ${i} } from "${n.entry}";`)]}p(Ue,"authoringImports");function Ze(o){const t=o.filter(e=>se[e.plan.name]);return o.map(e=>{if(e.plan.kind==="action"||["hconcat","vconcat"].includes(e.plan.name))return`program = ${e.call}`;if(e.plan.name==="render")return e.call;const i=se[e.plan.name];if(!i)throw new Error(`Unknown authoring runtime ${e.plan.name}.`);return`const ${t.length===1?"output":`${i.output}Output`} = ${e.call}`})}p(Ze,"authoringSteps");function Je(o){const t=new Set(o.map(e=>e.plan.name).filter(e=>de.includes(e)));return{imports:Ue(o),initialize:"let program = chart()",prerequisites:de.filter(e=>!t.has(e)).map(e=>{const i=A.get(e);return{id:`action.${e}`,signature:i.signature,call:e==="createCanvas"?"program = program.createCanvas({ width: 800, height: 600, margin: { top: 140, right: 220, bottom: 120, left: 260 } })":"program = program.createData({ values })",bindings:e==="createData"?["values"]:[]}}),steps:Ze(o)}}p(Je,"authoringBlock");function B(o){return JSON.stringify(o)}p(B,"codeString");function Ke(o,t){if(!o||t.size===0)return o;const e=o.lastIndexOf("})"),i=o.indexOf("({");if(i===-1||e===-1||e<i)throw new Error(`Cannot apply requested options to exact call: ${o}`);let n=o.slice(i+2,e).trim();for(const[r,a]of t){const d=new RegExp(`(^|,\\s*)${r}\\s*:\\s*(?:"[^"]*"|'[^']*'|-?[0-9]+(?:\\.[0-9]+)?|true|false)(?=\\s*,|$)`);d.test(n)?n=n.replace(d,(w,h)=>`${h}${r}: ${a}`):n=`${n}${n.length===0?"":", "}${r}: ${a}`}return`${o.slice(0,i+2)}${n}${o.slice(e)}`}p(Ke,"mergeExactCallOptions");function Pe(o,t){if(o.provider.exactCall)return{...o,provider:{...o.provider,exactCall:Ke(o.provider.exactCall,t),exactOptionNames:D([...o.provider.exactOptionNames??[],...t.keys()])}};const e=Object.fromEntries(Object.entries(o.provider.optionsByConstraint??{}).map(([n,r])=>[n,Object.fromEntries(Object.entries(r).filter(([a])=>!t.has(a)))])),i=S(o,Object.fromEntries(t));return{...i,provider:{...i.provider,optionsByConstraint:e}}}p(Pe,"entryWithRequestedOptions");const $e="70";function W(o,...t){return t.map(e=>o?.[e]).find(e=>e!==void 0)?.trim()}p(W,"requestedText");const ce=new Set(["and","as","at","axes","axis","coordinate","coordinates","encoding","field","for","is","legend","on","option","options","palette","scale","then","to","using","with","without","no","not"]);function Qe(o,t){const e=o.match(new RegExp(`\\b${t}(?:(?:\\s+(?:field|encoding|by|is))|\\s*[:=]|\\s+)\\s*(?:"([^"]+)"|'([^']+)'|([A-Za-z_$][A-Za-z0-9_$.-]*))`,"i"));if(!e)return;const i=W(e,1,2,3);return e[3]!==void 0&&ce.has(i.toLowerCase())?void 0:{value:i,source:e[0]}}p(Qe,"fieldRequest");function et(o,t){const e=o.match(new RegExp(`\\b${t}(?:\\s+(?:by|field|encoding))?\\s*(?:"([^"]+)"|'([^']+)'|([A-Za-z_$][A-Za-z0-9_$.-]*))`,"i"));if(!e)return;const i=W(e,1,2,3);if(!(e[3]!==void 0&&ce.has(i.toLowerCase())))return{value:i,source:e[0]}}p(et,"appearanceFieldRequest");function tt(o,t){const e=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),i=t.replace(/([a-z0-9])([A-Z])/g,"$1 $2"),n=i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),r=o.match(new RegExp(`\\b(?:${e}|${n})\\b\\s*(?:=|:|\\bis\\b|\\bto\\b)\\s*[^,;]+`,"i"));if(r)return r[0].trim();if(t!==i)return o.match(new RegExp(`\\b${e}\\b`,"i"))?.[0]}p(tt,"explicitOptionMention");function ot(o,t){let e=o;const i=[],n=[],r=[],a=p((c,l,m)=>{const g=e.find(P=>c.includes(P.provider.name));if(!g||l.size===0)return!1;e=e.map(P=>P===g?Pe(P,l):P);for(const[P,z]of l)i.push({owner:g.provider.name,option:P,value:z,source:m});return!0},"apply"),d=p((c,l,m)=>{n.push(c),r.push(k(l,m))},"rejectRequirement"),w=p(c=>{const l=e.filter(g=>c.includes(g.provider.name)),m=e.filter(g=>g.provider.kind==="action"&&A.get(g.provider.name)?.domain==="charts");return l.length===1&&m.length===1?l[0]:void 0},"singleFacade"),h=p((c,l,m)=>{let g=e.find(P=>P.provider.name===c);if(!g){const P=A.get(c);g={provider:{id:`request.${c}`,kind:"action",name:c,order:pe(P),anchors:[],covers:[],baseOptions:Object.fromEntries(l)},coverage:[]};const z=e.findIndex(Q=>Q.provider.kind==="runtime");e=[...e],e.splice(z<0?e.length:z,0,g)}a([c],l,m)},"addEditor"),$=[...t.matchAll(/\b(red|blue|green|orange|purple|black|white|yellow|pink|gray|grey)\s+(?:points|markers)\b/gi)];if($.length){const c=D($.map(m=>m[1].toLowerCase())),l=w(["createScatterPlot","createPolarScatterPlot"]);if(c.length===1&&l)for(const m of $)a([l.provider.name],new Map([["point",`{ fill: ${B(c[0])} }`]]),m[0]);else for(const m of $)d(m[0],"request.pointColor","Point color requires one unambiguous point chart and one requested color.")}const u=["createScatterPlot","createLinePlot","createAreaPlot","createBarPlot","createHeatmap"],v=[...t.matchAll(/\b(?:rotate|tilt)\s+(?:the\s+)?([xy])[ -]+axis\s+labels?\s+(?:by|to)\s+(-?\d+(?:\.\d+)?)\s*(degrees?|radians?)\b/gi)];for(const c of v){const l=c[1].toUpperCase(),m=Number(c[2]),g=c[3].toLowerCase().startsWith("degree")?"degrees":"radians",P=v.filter(z=>z[1].toUpperCase()===l);w(u)&&Number.isFinite(m)&&D(P.map(z=>`${z[2]}:${z[3]}`)).length===1?h(`edit${l}AxisLabels`,new Map([["rotation",`{ value: ${m}, unit: "${g}" }`]]),c[0]):d(c[0],`request.${l.toLowerCase()}AxisRotation`,"Axis label rotation requires one Cartesian chart and an unambiguous angle with units.")}for(const c of t.matchAll(/\b(?:logarithmic|log)\s+([xy])\s+(?:axis|scale)\b/gi))w(u)?h(`edit${c[1].toUpperCase()}Scale`,new Map([["type",'"log"']]),c[0]):d(c[0],"request.logScale","A logarithmic scale requires one unambiguous Cartesian chart and compatible nonzero data.");const M=t.match(/\b(?:(one|two|three|four|five|six|seven|eight|nine|ten|\d+)\s+bands?|bands?\s*(?:of|=|:)?\s*(one|two|three|four|five|six|seven|eight|nine|ten|\d+))\b/i);if(M){const c=W(M,1,2),l=Number({one:1,two:2,three:3,four:4,five:5,six:6,seven:7,eight:8,nine:9,ten:10}[c.toLowerCase()]??c);Number.isInteger(l)&&l>0?a(["createHorizonPlot","encodeHorizon","editHorizon"],new Map([["bands",String(l)]]),M[0]):(n.push(M[0]),r.push(k("request.option.horizon.bands","Horizon bands must be a positive integer.")))}const G=/\b(?:legend|encoding key)\b/i.test(t),X=e.some(c=>c.provider.id.startsWith("exact.")&&/Legend/.test(c.provider.name)),E=e.some(c=>c.provider.name==="facet"),q=new Set(["encoding.color","encoding.opacity","encoding.shape","encoding.size","encoding.strokeDash","encoding.strokeWidth"]),H=e.some(c=>["createPiePlot","createRosePlot","createRadialBarPlot"].includes(c.provider.name)||c.coverage.some(l=>q.has(l)));if(G&&!H&&!X&&!E){const c=D(e.flatMap(l=>l.coverage).filter(l=>l==="guide.legend"||l.startsWith("layout.legend.")));e=e.map(l=>({...l,coverage:l.coverage.filter(m=>m!=="guide.legend"&&!m.startsWith("layout.legend."))})).filter(l=>l.coverage.length>0||l.provider.id.startsWith("exact.")),n.push("legend channel");for(const l of c)r.push(k(l,"A legend requires a concrete compatible encoding channel such as color, shape, size, opacity, stroke dash, or stroke width."))}const L=t.match(/\blegend\s+(?:at|on)\s+(top|bottom|left|right)\b/i),y=G?t.match(/\b(?:(\d+)\s+columns?|columns?\s*(?:=|:)?\s*(\d+))\b/i):void 0,I=G?void 0:t.match(/\b(?:(\d+)\s+columns?|columns?\s*(?:=|:)?\s*(\d+))\b/i),V=G?t.match(/\b(?:(horizontal|vertical)(?:\s+direction)?\s+legend|legend(?:\s+direction)?\s*(?:=|:|is)?\s*(horizontal|vertical)|direction\s*(?:=|:|is)?\s*(horizontal|vertical)|legend\b[^,;]{0,60}\b(horizontal|vertical)|(horizontal|vertical)\s+direction)\b/i):void 0,f=new Map;if(L&&f.set("position",B(L[1].toLowerCase())),y){const c=Number(W(y,1,2));Number.isInteger(c)&&c>0?f.set("columns",String(c)):(n.push(y[0]),r.push(k("request.option.legend.columns","Legend columns must be a positive integer.")))}if(V&&f.set("direction",B(W(V,1,2,3,4,5).toLowerCase())),L?.[1].toLowerCase()==="bottom"&&f.set("offset",$e),I&&(n.push(I[0]),r.push(k("request.option.columns","A column count requires a concrete owner such as a legend or composition layout."))),f.size>0&&(H||X||E)){const c=[L?.[0],y?.[0],V?.[0]].filter(Boolean).join(", ");if(!a(["editLegendLayout","createLegend"],f,c)){const l=[...f].map(([m,g])=>`${m}: ${g}`).join(", ");a([...ve],new Map([["guides",`{ legend: { ${l} } }`]]),c)}}const O=t.match(/\b(\d+)\s+x[ -]?bins?\b/i),j=t.match(/\b(\d+)\s+y[ -]?bins?\b/i),J=t.match(/\b(\d+)\s+(?:bins?|bins? per axis)\b/i),N=new Map,F=[];if(O||j)if(O&&j){const c=Number(O[1]),l=Number(j[1]);if(c>0&&l>0)N.set("bins",`{ x: ${c}, y: ${l} }`),F.push(O[0],j[0]);else{const m=`${O[0]}; ${j[0]}`;n.push(m),r.push(k("request.option.bin2d.bins","Two-dimensional x and y bin counts must be positive integers."))}}else{const c=O?"y":"x",l=(O??j)[0];n.push(l),r.push(k(`transform.bin2d.bins.${c}`,`Two-dimensional bin counts require both x and y; the request specifies only ${l}.`))}else if(J){const c=Number(J[1]);Number.isInteger(c)&&c>0?(N.set("bins",String(c)),F.push(J[0])):(n.push(J[0]),r.push(k("request.option.bin2d.bins","Two-dimensional bin counts must be positive integers.")))}const K=t.match(/\b(include|exclude|omit)\s+empty\s+(?:bins|cells)\b/i);if(K&&(N.set("includeEmpty",String(K[1].toLowerCase()==="include")),F.push(K[0])),N.size>0){const c=F.join("; ");if(!a(["createBin2DData","editBin2DData"],N,c)){const l=[...N].map(([z,Q])=>`${z}: ${Q}`).join(", "),m=a(["createHeatmap"],new Map([["bin",`{ ${l} }`]]),c),g=N.get("bins"),P=!m&&g!==void 0&&/^\d+$/.test(g)&&!N.has("includeEmpty")&&a(["createHistogram"],new Map([["maxBins",g]]),c);!m&&!P&&(n.push(c),r.push(k("request.option.bin2d","Two-dimensional bin options require a heatmap or a create/edit Bin2D data action.")))}}const _=t.match(/\b(?:titled\b|(?:chart\s+)?title\b(?:\s+(?:is|text))?)\s*[:=]?\s*(?:"([^"]+)"|'([^']+)'|([A-Za-z0-9][^,;]*?))(?=\s+(?:(?:and|with)\s+)?(?:font(?:[ -]?size)?|subtitle|on\s+|as\s+)|$)/i),Y=W(_,1,2,3);Y&&!ce.has(Y.toLowerCase())&&a(["createTitle","editTitle"],new Map([["text",B(Y)]]),_[0]);const ie=t.match(/\bsubtitle(?:\s+(?:is|text))?\s*[:=]?\s*(?:"([^"]+)"|'([^']+)'|([A-Za-z0-9][^,;]*?))(?=\s+(?:(?:and|with)\s+)?(?:font(?:[ -]?size)?|title|on\s+|as\s+)|$)/i),ee=W(ie,1,2,3);ee&&!ce.has(ee.toLowerCase())&&a(["createTitle","editTitle"],new Map([["subtitle",B(ee)]]),ie[0]);const s=t.match(/\bfont[ -]?size\s*(?:=|:)?\s*(\d+(?:\.\d+)?)\b/i);if(s){const c=Number(s[1]);c>0&&a(["createTitle","editTitle"],new Map([["titleStyle",`{ fontSize: ${s[1]} }`]]),s[0])||(n.push(s[0]),r.push(k("request.option.fontSize",c>0?"A font size requires a concrete text owner such as a chart title, axis, legend, or text mark.":"Font size must be a positive finite number.")))}const x=Object.freeze({x:["createScatterPlot","createLinePlot","createAreaPlot","createBarPlot","createHeatmap","createBoxPlot","createViolinPlot","createGradientPlot","createRegressionData","createBin2DData","encodeHorizon","createHorizonPlot"],y:["createScatterPlot","createLinePlot","createAreaPlot","createBarPlot","createHeatmap","createBoxPlot","createViolinPlot","createGradientPlot","createRegressionData","createBin2DData","encodeHorizon","createHorizonPlot"]}),b=new Set;for(const c of["x","y"]){const l=Qe(t,c);if(!l||/^(?:bins?|axis|encoding|field)$/i.test(l.value))continue;(a(x[c],new Map([[c,B(l.value)]]),l.source)||a([`encode${c.toUpperCase()}`],new Map([["field",B(l.value)]]),l.source))&&b.add(c)}const C=t.match(/\b(?:plot|chart)\s+of\s+(?:"([^"]+)"|'([^']+)'|([A-Za-z_$][A-Za-z0-9_$.-]*))\s+(?:vs\.?|versus|against)\s+(?:"([^"]+)"|'([^']+)'|([A-Za-z_$][A-Za-z0-9_$.-]*))/i);if(C&&b.size===0){const c=W(C,1,2,3),l=W(C,4,5,6);for(const[m,g]of[["x",l],["y",c]])a(x[m],new Map([[m,B(g)]]),C[0])||a([`encode${m.toUpperCase()}`],new Map([["field",B(g)]]),C[0])}const R=Object.freeze({color:["createScatterPlot","createLinePlot","createAreaPlot","createBarPlot","createViolinPlot","createPiePlot","createRosePlot","createRadialBarPlot","createPolarScatterPlot","createPolarLinePlot","createRadarPlot"],size:["createScatterPlot","createPolarScatterPlot"],shape:["createScatterPlot","createPolarScatterPlot"]});for(const c of["color","size","shape"]){const l=et(t,c);if(!l)continue;a(R[c],new Map([[c,B(l.value)]]),l.source)||a([`encode${c[0].toUpperCase()}${c.slice(1)}`],new Map([["field",B(l.value)]]),l.source)}const ae=e.find(c=>c.provider.name==="renderToSVG");if(ae){const c=t.match(/\bsvg\s+title\s*(?:=|:)?\s*(?:"([^"]+)"|'([^']+)')/i),l=t.match(/\bdescription\s*(?:=|:)?\s*(?:"([^"]+)"|'([^']+)')/i),m=new Map;if(c&&m.set("title",B(W(c,1,2))),l&&m.set("description",B(W(l,1,2))),m.size>0){const g=[...m].map(([P,z])=>`${P}: ${z}`).join(", ");e=e.map(P=>P===ae?{...P,provider:{...P.provider,call:`renderToSVG(program, { ${g} })`}}:P);for(const[P,z]of m)i.push({owner:"renderToSVG",option:P,value:z,source:P==="title"?c[0]:l[0]})}}const U=t.match(/\bpixel[ -]?ratio\s*(?:=|:)?\s*(\d+(?:\.\d+)?)\b/i);if(U){const c=Number(U[1]),l=e.find(m=>["render","renderToPNG"].includes(m.provider.name));if(l&&c>0){const m=l.provider.name==="render"?`render(program, context, { pixelRatio: ${U[1]} })`:l.provider.call.replace(/\s*}\)$/,`, pixelRatio: ${U[1]} })`);e=e.map(g=>g===l?{...g,provider:{...g.provider,call:m}}:g),i.push({owner:l.provider.name,option:"pixelRatio",value:U[1],source:U[0]})}else n.push(U[0]),r.push(k("renderer.pixelRatio",c>0?"pixelRatio applies only to Browser Canvas or PNG output; choose one of those renderers or remove the requirement.":"pixelRatio must be a positive finite number."))}else if(/\b(?:high[ -]?dpi|retina)\b/i.test(t)){const c=t.match(/\b(?:high[ -]?dpi|retina)\b/i)[0];n.push(c),r.push(k("renderer.pixelRatio","High-density raster or Canvas output requires an explicit positive pixelRatio."))}/\bresponsive\b/i.test(t)&&(n.push("responsive"),r.push(k("layout.responsive","Responsive charts require host resize observation and immutable program rebuilding; no container size was supplied."))),/\b(?:accessible|accessibility|aria)\b/i.test(t)&&(i.some(l=>l.owner==="renderToSVG"&&l.option==="title")&&i.some(l=>l.owner==="renderToSVG"&&l.option==="description")||(n.push("accessible output"),r.push(k(ae?"renderer.svg.accessibleText":"output.accessibility",ae?"Accessible SVG output requires concrete title and description strings.":"Accessibility requires an output-specific accessible name, description, and host fallback strategy."))));const Se=new Set(i.map(c=>`${c.owner}.${Z(c.option)}`)),Oe=Z(t);for(const c of e.filter(l=>l.provider.kind==="action")){const l=A.get(c.provider.name),m=re(c.provider,c.coverage);for(const g of l?.options??[]){const P=Z(g.name);if(P.length<3||!le(Oe,P).length||Se.has(`${c.provider.name}.${P}`)||m.has(g.name)||g.name==="stroke"&&/\b(?:stroke[ -]?dash|dashed?\s+stroke)\b/i.test(t)||g.name==="bins"&&r.some(Ce=>Ce.constraint.startsWith("transform.bin2d.bins.")))continue;const z=tt(t,g.name);if(!z)continue;const Q=`${c.provider.name}.${g.name}: ${z}`;n.includes(Q)||(n.push(Q),r.push(k(`request.option.${c.provider.name}.${g.name}`,`The request mentions ${g.name}, but its value could not be parsed safely for ${c.provider.name}.`)))}}return{entries:e,appliedOptions:i,unmatchedRequirements:D(n),unresolved:r}}p(ot,"applyRequestedOptions");function nt(o,t=[]){const e=new Map,i=p((r,a,d,w)=>{const h=`${a}:${r}`,$=e.get(h)??{name:r,kind:a,required:!0,usedBy:[],reason:w};$.usedBy=D([...$.usedBy,d]),e.set(h,$)},"add"),n=o.find(r=>r.plan.name==="createData");(!n||/\bvalues\s*:\s*values\b/.test(n.call))&&i("values","binding","createData","Supply the caller-owned dataset rows before running the authoring block.");for(const r of o){r.plan.name==="render"&&i("context","runtime","render","Supply a CanvasRenderingContext2D from the host page."),["hconcat","vconcat"].includes(r.plan.name)&&i("programs","program",r.plan.name,"Replace the repeated sample program with two complete child ChartPrograms.");const a=r.call.matchAll(/\b(?:field|x|y|theta|radius|color|size|shape|groupBy|weight):\s*"(x|y|value|category|label|angle|distance|date|a|b|series)"/g);for(const d of a)i(d[1],"field",r.plan.name,"Replace this template name unless the input dataset declares the same field.");if(r.call.includes('"Chart title"')&&i("Chart title","text",r.plan.name,"Replace the sample title with user-approved chart text."),r.plan.id.startsWith("exact.")){const d=A.get(r.plan.name);for(const w of d?.resources.prerequisites??[])i(w,"resource",r.plan.name,"Provide or create this action-card prerequisite before applying the exact call.")}}for(const r of t){if(!new Set(["color","field","groupBy","shape","size","weight","x","y","theta","radius"]).has(r.option))continue;let a;try{a=JSON.parse(r.value)}catch{continue}typeof a!="string"||a.length===0||i(a,"field",r.owner,"Confirm that this request-supplied field exists in the caller-owned dataset.")}return[...e.values()]}p(nt,"placeholderBindings");function rt(o){let t=!1,e=new Set;const i=p(()=>t&&e.has("encodeX")&&e.has("encodeY")&&!e.has("encodeX2")&&!e.has("encodeY2"),"incomplete");for(const n of o){if(n.provider.id.startsWith("exact."))continue;const r=n.provider.name;if(r.startsWith("create")&&(r.endsWith("Mark")||r.endsWith("Plot"))){if(i())return!0;t=r==="createRuleMark",e=new Set;continue}t&&["encodeX","encodeY","encodeX2","encodeY2"].includes(r)&&e.add(r)}return i()}p(rt,"hasIncompleteRulePrimaryPair");function it(o){return o.filter(e=>e.provider.name==="createScale"&&!e.provider.id.startsWith("exact.")).filter(e=>{const i=e.provider.baseOptions?.id;if(i===void 0)return!1;const n=`id: ${i}`;return!o.some(r=>r!==e&&[...re(r.provider,r.coverage).values()].some(a=>a.includes(n)))}).map(e=>e.provider.baseOptions.id.replaceAll('"',""))}p(it,"unconsumedScaleIds");function at(o){const t=new Set(o.filter(d=>!d.provider.id.startsWith("exact.")).map(d=>d.provider.name)),e=[],i=[],n=new Set(o.flatMap(d=>d.coverage)),a=[...t].filter(d=>d.startsWith("create")&&(d.endsWith("Mark")||d.endsWith("Plot"))).length>0||[...t].some(d=>["createHistogram","createHeatmap","createParallelCoordinates"].includes(d));["selectMarks","filterMarks","highlightMarks","facet"].some(d=>t.has(d))&&!a&&e.push(k("chart.type","Selection and faceting require one explicit chart or mark owner before those actions can be addressed.")),["hconcat","vconcat"].some(d=>t.has(d))&&!a&&e.push(k("composition.children","Composition requires at least two complete child ChartPrograms; name or provide the child charts first.")),t.has("layoutLabels")&&t.has("createTextMark")&&!t.has("encodeX")&&!t.has("encodeY")&&e.push(k("encoding.position","Collision-aware labels require a positioned source layer or explicit x and y encodings.")),t.has("createLegend")&&!["encodeColor","encodeSize","encodeShape","encodeOpacity","encodeStrokeDash","encodeStrokeWidth"].some(d=>t.has(d))&&e.push(k("guide.legend.channel","A legend requires an explicit compatible visual encoding such as color, size, shape, opacity, dash, or width.")),rt(o)&&e.push(k("encoding.rule.endpoint","A rule with both x and y primary positions also requires x2 or y2; otherwise choose one primary position for a full-span rule."));for(const d of it(o))e.push(k("scale.consumer",`Scale "${d}" is not connected to a compatible encoding; choose the channel that should consume it.`));return(t.has("createAreaMark")||t.has("createAreaPlot"))&&t.has("encodeStrokeDash")&&i.push({constraint:"unsupported.areaStrokeDash",reason:"Field-driven stroke dash is not supported for area marks; use a line or rule mark for dash encoding."}),{unresolved:e,unsupported:i}}p(at,"runtimeClosureDecisions");function k(o,t){const e=ye[o]??(o.startsWith("layout.legend.")?"ggaction://docs/legend-layout":"ggaction://docs/action-reference");return{constraint:o,reason:t,resources:[e]}}p(k,"unresolvedDecision");function st(o,t){const e=[],i=["chart.pie","chart.donut"].some(a=>o.has(a)&&!t.has(a)),n=o.has("chart.horizon")&&!t.has("chart.horizon"),r=o.has("chart.density")&&!t.has("chart.density");for(const a of o){let d;i&&["encoding.x","encoding.y","guide.axes","guide.xAxis","guide.yAxis","guide.grid"].includes(a)&&(d="A pie has categorical sectors and a color legend. Cartesian positions, axes, and grids require a different chart or an explicit lower-level recipe."),n&&(a==="guide.yAxis"||a==="encoding.color"||a==="guide.legend"||a.startsWith("layout.legend."))&&(d="Horizon's y scale and palette describe internal folded bands. Choose an explicit lower-level guide or a separate original-amplitude guide; the facade only creates original-x guides."),r&&(a==="encoding.color"||a==="guide.legend"||a.startsWith("layout.legend."))&&(d="Density color requires an explicit groupBy field and matching color field. Its derived data does not retain arbitrary raw categories; choose that grouping before requesting a color legend."),d&&(t.add(a),e.push(k(a,d)))}return e}p(st,"completeChartBoundaries");function ct(o,t,e,i){const n=p(u=>u.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").trim().replace(/\s+/g," "),"normalizeWords"),r=` ${n(o)} `,a=new Uint8Array(r.length),d=[...i.appliedOptions.map(u=>u.source),...i.unmatchedRequirements,...i.unresolved.some(u=>["renderer.svg.accessibleText","output.accessibility"].includes(u.constraint))||["title","description"].every(u=>i.appliedOptions.some(v=>v.owner==="renderToSVG"&&v.option===u))?["accessible","accessibility"]:[],...i.entries.some(u=>u.provider.name==="facet"&&/legend:\s*"shared"/.test(re(u.provider,u.coverage).get("guides")??""))?["shared legend"]:[],...t.flatMap(u=>u.phrases),...e].map(n).filter(Boolean).sort((u,v)=>v.length-u.length);for(const u of d){const v=` ${u} `;let M=r.indexOf(v);for(;M!==-1;)a.fill(1,M,M+v.length),M=r.indexOf(v,M+1)}const w=r.split("").map((u,v)=>a[v]?" ":u).join(""),h=new Set("a an the and then with using use as at on in to of for by from create draw make build show add apply set please chart plot output export render i want would like me can you it this that is be should must into also put charts".split(" "));return w.trim().split(/\s+/).filter(u=>u&&!h.has(u)).length===0?[]:o.trim().match(/[\s\S]{1,176}/g)??[]}p(ct,"unconsumedRequirements");function dt(o,t,e){const i=[],n=[...t].filter(r=>!r.startsWith("renderer.")&&!r.startsWith("unsupported."));return/\b(chart|plot)\b/.test(o)&&n.length===0&&![...t].some(r=>r.startsWith("unsupported."))&&e.length===0&&i.push(k("chart.type","A chart or mark type is required; for example scatter plot, line chart, bar chart, or tick mark.")),/\b(render|export|output)\b/.test(o)&&![...t].some(r=>r.startsWith("renderer."))&&i.push(k("renderer.format","A supported output format is required: Browser Canvas, SVG, PNG, or PDF.")),i}p(dt,"genericUnresolved");function ke(){if(te.schemaVersion!==3||T.schemaVersion!==2)throw new Error("Compact action cards must use schemaVersion 3 and the intent taxonomy must use schemaVersion 2.");if(T.packageVersion!==te.packageVersion)throw new Error("Compact action cards and the intent taxonomy must use one packageVersion.");if(oe.size!==T.constraints.length)throw new Error("Intent constraint IDs must be unique.");if(new Set(T.providers.map(n=>n.id)).size!==T.providers.length)throw new Error("Intent provider IDs must be unique.");const t=new Set;for(const n of T.constraints)for(const r of n.shadows??[])if(!oe.has(r)||r===n.id)throw new Error(`${n.id} shadows invalid constraint ${r}.`);for(const n of T.providers){for(const r of[...n.anchors,...n.covers])if(!oe.has(r))throw new Error(`${n.id} references unknown constraint ${r}.`);if(n.anchors.some(r=>!n.covers.includes(r)))throw new Error(`${n.id} does not cover every anchor.`);for(const r of n.anchors)t.add(r);if(n.kind==="action"){const r=A.get(n.name);if(!r)throw new Error(`${n.id} references unknown action ${n.name}.`);const a=new Set(r.options.map(w=>w.name)),d=[n.baseOptions??{},...Object.values(n.optionsByConstraint??{})];for(const w of d)for(const[h,$]of Object.entries(w)){if(!a.has(h))throw new Error(`${n.id} references undeclared option ${h}.`);if(typeof $!="string"||$.length===0)throw new Error(`${n.id}.${h} must be a JavaScript expression string.`)}}else{if(n.kind!=="runtime"||typeof n.signature!="string"||typeof n.call!="string"||!n.route.startsWith("/reference/"))throw new Error(`${n.id} has an invalid runtime contract.`);if(!ge.includes(n.name)&&se[n.name]===void 0)throw new Error(`${n.id} lacks an authoring runtime mapping.`)}}const e=T.constraints.filter(n=>n.unsupported===void 0&&!t.has(n.id));if(e.length>0)throw new Error(`Supported constraints lack providers: ${e.map(n=>n.id).join(", ")}.`);const i=T.constraints.filter(n=>n.unsupported!==void 0!==n.id.startsWith("unsupported.")||n.unsupported!==void 0&&t.has(n.id));if(i.length>0)throw new Error(`Terminal constraints must use unsupported.* IDs without providers: ${i.map(n=>n.id).join(", ")}.`);for(const n of de)if(!A.has(n))throw new Error(`Missing authoring prerequisite action card: ${n}.`);return{cards:A.size,constraints:oe.size,providers:T.providers.length,supported:T.constraints.filter(n=>n.unsupported===void 0).length,unsupported:T.constraints.filter(n=>n.unsupported!==void 0).length}}p(ke,"validateResolverKnowledge");function mt(o){if(typeof o!="string"||o.trim().length===0)throw new TypeError("searchGgaction query must be a non-empty string.");if(o.length>500)throw new RangeError("searchGgaction query must be at most 500 characters.");ke();const t=Ae(o),e=t?"":o,i=Z(e),n=De(e),{matched:r,positions:a}=Ee(i);for(const f of n){const[O]=le(i,Z(f));O&&a.set(`action.${f}`,O.start)}const d=new Set([...r.map(f=>f.id),...n.map(f=>`action.${f}`)]),w=r.filter(f=>f.unsupported!==void 0).map(f=>({constraint:f.id,reason:f.unsupported})),h=t?[k("request.negation","Negation or exclusion requires explicit interpretation. No authoring steps are proposed; preserve the restriction when choosing action options.")]:[],{blocked:$,unresolved:u}=Ne(r);h.push(...u),h.push(...st(d,$));const v=new Set([...d].filter(f=>{const O=oe.get(f);return!$.has(f)&&(O===void 0||O.unsupported===void 0)})),M=We(v,n),{selected:G,uncovered:X}=je(v,M);for(const f of X)h.push(k(f,"No current action or runtime operation covers this recognized constraint."));h.push(...dt(i,d,n)),d.size===0&&h.length===0&&h.push(k("query.intent","No current ggaction constraint was recognized; use an exact action name or a supported chart task."));let E=He(_e(G).sort((f,O)=>f.provider.order-O.provider.order||xe(f,a)-xe(O,a)||f.provider.id.localeCompare(O.provider.id)));const q=ot(Ye(E),e);E=q.entries,h.push(...q.unresolved);const H=t?[]:ct(e,r,n,q);H.length>0&&(q.unmatchedRequirements.push(...H),h.push(k("request.unconsumed","Part of the original request was not interpreted. Review unmatchedRequirements before claiming the requested chart is complete.")));const L=at(E);w.push(...L.unsupported),h.push(...L.unresolved),L.unsupported.some(f=>f.constraint==="unsupported.areaStrokeDash")&&(E=E.filter(f=>f.provider.name!=="encodeStrokeDash"));const y=E.map((f,O)=>Fe(f,O+1)),I={schemaVersion:5,packageVersion:te.packageVersion,query:o.trim(),matchedConstraints:[...d],actionPlan:y.map(f=>f.plan),exactCalls:y.map(f=>f.call),appliedOptions:q.appliedOptions,placeholderBindings:nt(y,q.appliedOptions),unmatchedRequirements:t?o.trim().length<=180?[o.trim()]:o.trim().match(/[\s\S]{1,176}/g).map((f,O)=>`${O+1}. ${f}`):q.unmatchedRequirements,authoring:Je(y),unsupported:w,unresolved:D(h.map(f=>JSON.stringify(f))).map(JSON.parse),candidates:y.slice(0,3).map(f=>({id:f.plan.id,kind:f.plan.kind,name:f.plan.name,route:f.plan.route}))},V=Buffer.byteLength(JSON.stringify(I),"utf8");if(V>6144)throw new qe(V);return I}p(mt,"searchGgaction");function gt(o){return Buffer.byteLength(JSON.stringify(o),"utf8")}p(gt,"taskPacketBytes"),ke();export{qe as TaskPacketBudgetError,mt as searchGgaction,gt as taskPacketBytes,ke as validateResolverKnowledge};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ggaction",
3
- "version": "0.0.17",
3
+ "version": "0.0.18",
4
4
  "description": "Build charts through immutable, traceable graphical actions.",
5
5
  "license": "MIT",
6
6
  "author": "Hyeon Jeon",
@@ -164,7 +164,7 @@
164
164
  },
165
165
  "devDependencies": {
166
166
  "@axe-core/playwright": "^4.12.1",
167
- "@modelcontextprotocol/sdk": "1.30.0",
167
+ "@modelcontextprotocol/sdk": "1.32.1",
168
168
  "@napi-rs/canvas": "^1.0.2",
169
169
  "ajv": "^8.20.0",
170
170
  "es-module-lexer": "^1.7.0",
@@ -175,7 +175,7 @@
175
175
  "vite": "^6.4.3"
176
176
  },
177
177
  "peerDependencies": {
178
- "@modelcontextprotocol/sdk": "1.30.0",
178
+ "@modelcontextprotocol/sdk": "1.32.1",
179
179
  "@napi-rs/canvas": "^1.0.2"
180
180
  },
181
181
  "peerDependenciesMeta": {
@@ -5,7 +5,7 @@ import { ChartProgram as CoreChartProgram } from "./core/ChartProgram.js";
5
5
  export class BasicChartProgram extends CoreChartProgram {}
6
6
 
7
7
  registerBasicActions(BasicChartProgram);
8
- recordBuiltinActions(BasicChartProgram, ["hconcat", "vconcat", "rematerializeEncodingScales"]);
8
+ recordBuiltinActions(BasicChartProgram, ["hconcat", "vconcat", "rematerializeEncodingScales", "encodeStroke"]);
9
9
 
10
10
  export function chart() {
11
11
  return new BasicChartProgram();
@@ -31,14 +31,15 @@ function pathRows(program, layer) {
31
31
  const x = layer.encoding.x;
32
32
  derived = deriveLineSeries(rows, layer, {
33
33
  ...(x?.bin === undefined ? {} : { xBinBoundaries: resolveLineBins(rows, layer, requireSemanticScale(program, x.scale)).boundaries }),
34
+ xDomain: program.resolvedScales[x?.scale]?.domain,
34
35
  thetaDomain: program.resolvedScales[layer.encoding.theta?.scale]?.domain
35
36
  });
36
37
  } else {
37
38
  const transform = findUpstreamTransform(program, dataset, "density");
38
39
  derived = transform === undefined
39
40
  ? layer.encoding.y?.stack === "center"
40
- ? deriveCenteredAreaSeries(rows, layer)
41
- : deriveAreaSeries(rows, layer)
41
+ ? deriveCenteredAreaSeries(rows, layer, { xDomain: program.resolvedScales[layer.encoding.x?.scale]?.domain, yDomain: program.resolvedScales[layer.encoding.y?.scale]?.domain })
42
+ : deriveAreaSeries(rows, layer, { xDomain: program.resolvedScales[layer.encoding.x?.scale]?.domain, yDomain: program.resolvedScales[layer.encoding.y?.scale]?.domain })
42
43
  : deriveDensityAreaSeries(rows, layer, transform);
43
44
  if (transform !== undefined && transform.placement?.type !== "category") {
44
45
  derived = layoutDensityAreaSeries(derived, layer.layout?.mode ?? layer.encoding.color?.layout ?? "overlay");
@@ -1,5 +1,6 @@
1
1
  import { closedAction } from "../../core/action.js";
2
2
 
3
+ import { normalizeBoxSummary } from "../../grammar/boxPlot.js";
3
4
  import { findSemanticScale } from "../../selectors/scales.js";
4
5
  import { resolveFacadeData } from "../charts/shared.js";
5
6
  import {
@@ -34,9 +35,17 @@ export const createBoxPlot = /* @__PURE__ */ closedAction(
34
35
  args.data ?? source?.data,
35
36
  "createBoxPlot"
36
37
  );
37
- const x = resolveBoxPosition(args.x, "x") ?? source?.encoding?.x;
38
- const y = resolveBoxPosition(args.y, "y") ?? source?.encoding?.y;
39
- const whisker = resolveBoxWhisker(args.whisker);
38
+ const summary = normalizeBoxSummary(args.summary);
39
+ let x = resolveBoxPosition(args.x, "x") ?? source?.encoding?.x;
40
+ let y = resolveBoxPosition(args.y, "y") ?? source?.encoding?.y;
41
+ if (summary !== undefined) {
42
+ if (x !== undefined && y === undefined) y = { field: summary.median, fieldType: "quantitative" };
43
+ if (y !== undefined && x === undefined) x = { field: summary.median, fieldType: "quantitative" };
44
+ }
45
+ const whisker = resolveBoxWhisker(args.whisker, "createBoxPlot", summary === undefined ? "tukey" : "minmax");
46
+ if (summary !== undefined && (whisker.type !== "minmax" || args.outliers === true)) {
47
+ throw new Error("Precomputed box summaries require minmax whiskers and do not infer outliers.");
48
+ }
40
49
  const width = resolveBoxWidth(args.width);
41
50
  if (args.outliers !== undefined && typeof args.outliers !== "boolean") {
42
51
  throw new TypeError("createBoxPlot outliers must be a boolean.");
@@ -63,7 +72,8 @@ export const createBoxPlot = /* @__PURE__ */ closedAction(
63
72
  boxPlot: {
64
73
  whisker,
65
74
  width,
66
- outliers: args.outliers ?? true,
75
+ outliers: args.outliers ?? (summary === undefined),
76
+ ...(summary === undefined ? {} : { summary }),
67
77
  box,
68
78
  median,
69
79
  outlier,
@@ -1,13 +1,12 @@
1
1
  import { closedAction } from "../../core/action.js";
2
2
  import { isPlainObject } from "../../core/immutable.js";
3
3
  import { validateUserId } from "../../core/identifiers.js";
4
- import { validateKeys } from "../../core/validation.js";
5
- import { BOX_FIELDS, deriveBoxData, normalizeBoxTransform } from
4
+ import { BOX_FIELDS, deriveBoxData, normalizeBoxTransform, normalizeBoxSummary } from
6
5
  "../../grammar/boxPlot.js";
7
6
  import { planDerivedDataRevision } from
8
7
  "../../materialization/dataProvenance.js";
9
8
  import { findDataset } from "../../selectors/datasets.js";
10
- import { findLayer } from "../../selectors/layers.js";
9
+ import { findLayer, resolveConfiguredOwner } from "../../selectors/layers.js";
11
10
  import { removeOwnedMark } from "../marks/remove.js";
12
11
  import {
13
12
  resolveDistributionRoles,
@@ -16,6 +15,8 @@ import {
16
15
  updateDistributionPositions
17
16
  } from "../distributions/revision.js";
18
17
  import {
18
+ boxBarWidth,
19
+ boxWhiskerAppearance,
19
20
  resolveBoxAppearance,
20
21
  resolveBoxMedianAppearance,
21
22
  resolveBoxOutlierAppearance,
@@ -28,28 +29,11 @@ import { requestedRectStyleDetails } from "../../grammar/roundedRect.js";
28
29
  import { requestedStrokeDetails } from "../../grammar/strokeStyle.js";
29
30
 
30
31
  const OPTIONS = Object.freeze([
31
- "target", "data", "x", "y", "whisker", "width", "outliers", "box",
32
+ "target", "data", "x", "y", "summary", "whisker", "width", "outliers", "box",
32
33
  "median", "outlier"
33
34
  ]);
34
35
 
35
- function resolveBoxOwner(program, requested) {
36
- const eligible = program.semanticSpec.layers.filter(
37
- layer => program.markConfigs[layer.id]?.boxPlot?.materialized === true
38
- );
39
- if (requested !== undefined) {
40
- const id = validateUserId(requested, "Box-plot owner id");
41
- const layer = findLayer(program, id);
42
- if (layer === undefined || !eligible.includes(layer)) {
43
- throw new Error(`Unknown box-plot owner "${id}".`);
44
- }
45
- return layer;
46
- }
47
- const current = findLayer(program, program.context.currentMark);
48
- if (current !== undefined && eligible.includes(current)) return current;
49
- if (eligible.length === 1) return eligible[0];
50
- if (eligible.length === 0) throw new Error("No box-plot owner is available.");
51
- throw new Error("Box-plot owner is ambiguous; provide target.");
52
- }
36
+
53
37
 
54
38
  function requirePatch(value, label) {
55
39
  if (!isPlainObject(value)) {
@@ -61,7 +45,6 @@ function requirePatch(value, label) {
61
45
  function resolveEditedWhisker(current, value) {
62
46
  if (value === undefined) return current;
63
47
  const patch = requirePatch(value, "whisker");
64
- validateKeys(patch, ["type", "factor"], "editBoxPlot whisker");
65
48
  const type = patch.type ?? current.type;
66
49
  const candidate = type === "minmax"
67
50
  ? { type, ...(Object.hasOwn(patch, "factor") ? { factor: patch.factor } : {}) }
@@ -71,7 +54,7 @@ function resolveEditedWhisker(current, value) {
71
54
  ? patch.factor
72
55
  : current.type === "tukey" ? current.factor : 1.5
73
56
  };
74
- return resolveBoxWhisker(candidate, "editBoxPlot");
57
+ return resolveBoxWhisker({ ...boxWhiskerAppearance(current), ...patch, ...candidate }, "editBoxPlot");
75
58
  }
76
59
 
77
60
  function roleCandidate(program, owner, current, args) {
@@ -109,7 +92,7 @@ function updateBoxPositions(program, owner, current, candidate, {
109
92
  const capIds = [
110
93
  whiskerConfig.errorBar.lowerCapId,
111
94
  whiskerConfig.errorBar.upperCapId
112
- ].filter(Boolean);
95
+ ].filter(id => id !== undefined && findLayer(program, id) !== undefined);
113
96
  const owned = [owner.id, current.whiskerId, ...capIds, current.medianId,
114
97
  ...(findLayer(program, current.outlierId) ? [current.outlierId] : [])];
115
98
  let next = updateDistributionPositions(
@@ -222,16 +205,29 @@ export const editBoxPlot = /* @__PURE__ */ closedAction(
222
205
  if (!OPTIONS.slice(1).some(key => Object.hasOwn(args, key))) {
223
206
  throw new Error("editBoxPlot requires at least one box-plot option.");
224
207
  }
225
- const owner = resolveBoxOwner(this, args.target);
208
+ const owner = resolveConfiguredOwner(this, args.target, {
209
+ config: "boxPlot", kind: "box", materialized: true,
210
+ missing: "No box-plot owner is available.",
211
+ ambiguous: "Box-plot owner is ambiguous; provide target."
212
+ }, validateUserId);
226
213
  const current = this.markConfigs[owner.id].boxPlot;
227
- const whisker = resolveEditedWhisker(current.whisker, args.whisker);
214
+ const summary = args.summary !== undefined
215
+ ? args.summary === false ? undefined : normalizeBoxSummary(args.summary)
216
+ : current.summary;
217
+ const whisker = resolveEditedWhisker(current.whisker, args.whisker !== undefined ? args.whisker :
218
+ (summary !== undefined && current.summary === undefined ? { type: "minmax" } : undefined));
219
+ const whiskerAppearance = Object.fromEntries(Object.keys(boxWhiskerAppearance(args.whisker ?? {}))
220
+ .map(key => [key, whisker[key]]));
228
221
  const width = Object.hasOwn(args, "width")
229
222
  ? resolveBoxWidth(args.width, "editBoxPlot")
230
223
  : current.width;
231
224
  if (Object.hasOwn(args, "outliers") && typeof args.outliers !== "boolean") {
232
225
  throw new TypeError("editBoxPlot outliers must be a boolean.");
233
226
  }
234
- const outliers = args.outliers ?? current.outliers;
227
+ const outliers = args.outliers ?? (summary !== undefined ? false : current.outliers);
228
+ if (summary !== undefined && (whisker.type !== "minmax" || outliers)) {
229
+ throw new Error("Precomputed box summaries require minmax whiskers and do not infer outliers.");
230
+ }
235
231
  const boxPatch = Object.hasOwn(args, "box")
236
232
  ? requirePatch(args.box, "box")
237
233
  : {};
@@ -270,8 +266,8 @@ export const editBoxPlot = /* @__PURE__ */ closedAction(
270
266
  key => Object.hasOwn(args, key)
271
267
  );
272
268
  const changesRoles = !sameRoleCandidate(current, candidate);
273
- const revisesData = JSON.stringify(whisker) !== JSON.stringify(current.whisker) ||
274
- outliers !== current.outliers;
269
+ const revisesData = whisker.type !== current.whisker.type || whisker.factor !== current.whisker.factor ||
270
+ JSON.stringify(summary) !== JSON.stringify(current.summary) || outliers !== current.outliers;
275
271
  if (changesRoles || revisesData) {
276
272
  const derived = deriveBoxData(
277
273
  sourceDataset.values,
@@ -279,6 +275,7 @@ export const editBoxPlot = /* @__PURE__ */ closedAction(
279
275
  type: "boxSummary",
280
276
  category: candidate.category,
281
277
  field: candidate.measure,
278
+ ...(summary === undefined ? {} : { summary }),
282
279
  whisker: whisker.type,
283
280
  ...(whisker.factor === undefined ? {} : { factor: whisker.factor })
284
281
  })
@@ -289,7 +286,7 @@ export const editBoxPlot = /* @__PURE__ */ closedAction(
289
286
  const capIds = [
290
287
  whiskerConfig.errorBar.lowerCapId,
291
288
  whiskerConfig.errorBar.upperCapId
292
- ].filter(Boolean);
289
+ ].filter(id => id !== undefined && findLayer(this, id) !== undefined);
293
290
  const summaryRevision = planDerivedDataRevision(this, {
294
291
  owner: owner.id,
295
292
  role: "SummaryData",
@@ -313,6 +310,7 @@ export const editBoxPlot = /* @__PURE__ */ closedAction(
313
310
  source: candidate.source,
314
311
  category: candidate.category,
315
312
  field: candidate.measure,
313
+ ...(summary === undefined ? {} : { summary }),
316
314
  whisker: whisker.type,
317
315
  ...(whisker.factor === undefined ? {} : { factor: whisker.factor })
318
316
  });
@@ -348,6 +346,7 @@ export const editBoxPlot = /* @__PURE__ */ closedAction(
348
346
  boxPlot: {
349
347
  ...current,
350
348
  whisker,
349
+ summary,
351
350
  width,
352
351
  outliers,
353
352
  box,
@@ -360,7 +359,7 @@ export const editBoxPlot = /* @__PURE__ */ closedAction(
360
359
  summaryId: summaryRevision.id,
361
360
  outlierDataId: outlierRevision?.id
362
361
  },
363
- barWidth: { band: width },
362
+ barWidth: boxBarWidth(width),
364
363
  fill: box.fill,
365
364
  opacity: box.opacity,
366
365
  stroke: box.stroke,
@@ -373,6 +372,9 @@ export const editBoxPlot = /* @__PURE__ */ closedAction(
373
372
  outlierDataId: outlierRevision?.id,
374
373
  hasOutliers
375
374
  });
375
+ if (Object.keys(whiskerAppearance).length > 0) {
376
+ next = next.editErrorBar({ target: current.whiskerId, ...whiskerAppearance });
377
+ }
376
378
  if (!hadOutlierLayer && hasOutliers) {
377
379
  const category = candidate.orientation === "vertical"
378
380
  ? candidate.x
@@ -448,6 +450,7 @@ export const editBoxPlot = /* @__PURE__ */ closedAction(
448
450
  boxPlot: {
449
451
  ...current,
450
452
  whisker,
453
+ summary,
451
454
  width,
452
455
  outliers,
453
456
  box,
@@ -456,7 +459,7 @@ export const editBoxPlot = /* @__PURE__ */ closedAction(
456
459
  summaryId: current.summaryId,
457
460
  outlierDataId: current.outlierDataId
458
461
  },
459
- barWidth: { band: width },
462
+ barWidth: boxBarWidth(width),
460
463
  fill: box.fill,
461
464
  opacity: box.opacity,
462
465
  stroke: box.stroke,
@@ -466,6 +469,9 @@ export const editBoxPlot = /* @__PURE__ */ closedAction(
466
469
  : { barAppearance: boxStyleDetails })
467
470
  });
468
471
 
472
+ if (Object.keys(whiskerAppearance).length > 0) {
473
+ next = next.editErrorBar({ target: current.whiskerId, ...whiskerAppearance });
474
+ }
469
475
  if (changesBox) next = next.rematerializeBarMark({ id: owner.id });
470
476
  if (changesMedian) {
471
477
  next = next
@@ -1,3 +1,4 @@
1
+ import { boxBarWidth, boxWhiskerAppearance } from "./options.js";
1
2
  import { applyFacadeGuides } from "../charts/shared.js";
2
3
  import { action } from "../../core/action.js";
3
4
  import { validateUserId } from "../../core/identifiers.js";
@@ -60,7 +61,7 @@ export const materializeBoxPlot = /* @__PURE__ */ action(
60
61
  medianId,
61
62
  outlierId
62
63
  },
63
- barWidth: { band: config.width },
64
+ barWidth: boxBarWidth(config.width),
64
65
  fill: config.box.fill,
65
66
  opacity: config.box.opacity,
66
67
  stroke: config.box.stroke,
@@ -73,6 +74,7 @@ export const materializeBoxPlot = /* @__PURE__ */ action(
73
74
  source,
74
75
  category: category.field,
75
76
  field: measure.field,
77
+ ...(config.summary === undefined ? {} : { summary: config.summary }),
76
78
  whisker: config.whisker.type,
77
79
  ...(config.whisker.factor === undefined
78
80
  ? {}
@@ -144,7 +146,8 @@ export const materializeBoxPlot = /* @__PURE__ */ action(
144
146
  }),
145
147
  coordinate: layer.coordinate,
146
148
  stroke: "#111111",
147
- strokeWidth: 1.5
149
+ strokeWidth: 1.5,
150
+ ...boxWhiskerAppearance(config.whisker)
148
151
  });
149
152
  next = next
150
153
  .editSemantic({
@@ -156,7 +159,8 @@ export const materializeBoxPlot = /* @__PURE__ */ action(
156
159
  id: ownerId,
157
160
  type: "rect",
158
161
  length: 0,
159
- ...resolvePlotGraphicPlacement(next)
162
+ ...resolvePlotGraphicPlacement(next, next.graphicSpec.objects.plotBorder === undefined
163
+ ? {} : { before: "plotBorder" })
160
164
  })
161
165
  .rematerializeBarMark({ id: ownerId })
162
166
  .createBoxMedian({