@opendata-ai/openchart-core 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +26 -1
- package/dist/index.js +1368 -43
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/types/index.ts +1 -0
- package/src/types/spec.ts +28 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types/encoding.ts","../src/types/spec.ts","../src/colors/colorblind.ts","../src/colors/contrast.ts","../src/colors/palettes.ts","../src/theme/dark-mode.ts","../src/theme/defaults.ts","../src/theme/resolve.ts","../src/layout/text-measure.ts","../src/layout/chrome.ts","../src/responsive/breakpoints.ts","../src/labels/collision.ts","../src/locale/format.ts","../src/accessibility/alt-text.ts","../src/accessibility/aria.ts","../src/helpers/spec-builders.ts"],"sourcesContent":["/**\n * Per-chart-type encoding validation rules.\n *\n * Defines which encoding channels are required vs optional for each chart type.\n * The engine compiler uses these rules to validate specs at runtime (TypeScript\n * catches compile-time errors; these catch runtime JSON from Claude or APIs).\n */\n\nimport type { ChartType, FieldType } from './spec';\n\n// ---------------------------------------------------------------------------\n// Encoding rule types\n// ---------------------------------------------------------------------------\n\n/** Constraint on what field types are valid for an encoding channel. */\nexport interface ChannelRule {\n /** Whether this channel is required for the chart type. */\n required: boolean;\n /** Allowed field types. If empty, any field type is accepted. */\n allowedTypes: FieldType[];\n}\n\n/** Encoding rules for a single chart type: which channels are required/optional. */\nexport interface EncodingRule {\n x: ChannelRule;\n y: ChannelRule;\n color: ChannelRule;\n size: ChannelRule;\n detail: ChannelRule;\n}\n\n// ---------------------------------------------------------------------------\n// Chart encoding rules\n// ---------------------------------------------------------------------------\n\n/** Helper to create a required channel rule. */\nfunction required(...types: FieldType[]): ChannelRule {\n return { required: true, allowedTypes: types };\n}\n\n/** Helper to create an optional channel rule. */\nfunction optional(...types: FieldType[]): ChannelRule {\n return { required: false, allowedTypes: types };\n}\n\n/**\n * Encoding rules per chart type.\n *\n * Defines which channels are required and what field types they accept.\n * The compiler uses this map to validate user specs at runtime.\n *\n * Key design decisions:\n * - line/area: x is temporal/ordinal (the axis), y is quantitative (the value)\n * - bar: horizontal bars, so y is the category axis, x is the value\n * - column: vertical columns, so x is the category axis, y is the value\n * - pie/donut: no x axis; y is the value (quantitative), color is the category\n * - dot: y is the category, x is quantitative\n * - scatter: both axes are quantitative\n */\nexport const CHART_ENCODING_RULES: Record<ChartType, EncodingRule> = {\n line: {\n x: required('temporal', 'ordinal'),\n y: required('quantitative'),\n color: optional('nominal', 'ordinal'),\n size: optional('quantitative'),\n detail: optional('nominal'),\n },\n area: {\n x: required('temporal', 'ordinal'),\n y: required('quantitative'),\n color: optional('nominal', 'ordinal'),\n size: optional('quantitative'),\n detail: optional('nominal'),\n },\n bar: {\n x: required('quantitative'),\n y: required('nominal', 'ordinal'),\n color: optional('nominal', 'ordinal', 'quantitative'),\n size: optional('quantitative'),\n detail: optional('nominal'),\n },\n column: {\n x: required('nominal', 'ordinal', 'temporal'),\n y: required('quantitative'),\n color: optional('nominal', 'ordinal', 'quantitative'),\n size: optional('quantitative'),\n detail: optional('nominal'),\n },\n pie: {\n x: optional(),\n y: required('quantitative'),\n color: required('nominal', 'ordinal'),\n size: optional('quantitative'),\n detail: optional('nominal'),\n },\n donut: {\n x: optional(),\n y: required('quantitative'),\n color: required('nominal', 'ordinal'),\n size: optional('quantitative'),\n detail: optional('nominal'),\n },\n dot: {\n x: required('quantitative'),\n y: required('nominal', 'ordinal'),\n color: optional('nominal', 'ordinal'),\n size: optional('quantitative'),\n detail: optional('nominal'),\n },\n scatter: {\n x: required('quantitative'),\n y: required('quantitative'),\n color: optional('nominal', 'ordinal'),\n size: optional('quantitative'),\n detail: optional('nominal'),\n },\n};\n\n// ---------------------------------------------------------------------------\n// Graph encoding rules\n// ---------------------------------------------------------------------------\n\n/** Encoding rule for a single graph visual channel. */\nexport interface GraphChannelRule {\n /** Whether this channel is required. */\n required: boolean;\n /** Allowed field types. Empty means any type. */\n allowedTypes: FieldType[];\n}\n\n/**\n * Encoding rules for graph visualizations.\n *\n * All graph encoding channels are optional since a graph can be rendered\n * with just nodes and edges (uniform appearance). Encoding channels add\n * visual differentiation based on data fields.\n */\nexport const GRAPH_ENCODING_RULES: Record<string, GraphChannelRule> = {\n nodeColor: { required: false, allowedTypes: ['nominal', 'ordinal'] },\n nodeSize: { required: false, allowedTypes: ['quantitative'] },\n edgeColor: { required: false, allowedTypes: ['nominal', 'ordinal'] },\n edgeWidth: { required: false, allowedTypes: ['quantitative'] },\n nodeLabel: { required: false, allowedTypes: [] },\n};\n","/**\n * Spec types: the user-facing input contract.\n *\n * These types define what a user (or Claude) writes to describe a visualization.\n * The engine validates, normalizes, and compiles specs into layout objects.\n *\n * Encoding vocabulary follows Vega-Lite conventions (field/type/aggregate)\n * with editorial extensions for chrome, annotations, responsive, and dark mode.\n */\n\n// Re-import for use in LegendConfig (avoids circular by importing from sibling)\nimport type { LegendPosition } from '../responsive/breakpoints';\nimport type { ColumnConfig } from './table';\n\n// ---------------------------------------------------------------------------\n// Chart type union\n// ---------------------------------------------------------------------------\n\n/** Supported chart types. Graph is separate since it uses nodes/edges, not data + encoding. */\nexport type ChartType = 'line' | 'area' | 'bar' | 'column' | 'pie' | 'donut' | 'dot' | 'scatter';\n\n// ---------------------------------------------------------------------------\n// Encoding\n// ---------------------------------------------------------------------------\n\n/** Data field type, following Vega-Lite conventions. */\nexport type FieldType = 'quantitative' | 'temporal' | 'nominal' | 'ordinal';\n\n/** Aggregate function applied to a field before encoding. */\nexport type AggregateOp = 'count' | 'sum' | 'mean' | 'median' | 'min' | 'max';\n\n/** Axis configuration for an encoding channel. */\nexport interface AxisConfig {\n /** Axis label text. If omitted, the field name is used. */\n label?: string;\n /** Number format string (d3-format). e.g. \",.0f\" for comma-separated integers. */\n format?: string;\n /** Override tick count. Engine picks a sensible default if omitted. */\n tickCount?: number;\n /** Whether to show gridlines for this axis. */\n grid?: boolean;\n /** Rotation angle in degrees for tick labels. Common values: -45, -90, 90. */\n tickAngle?: number;\n}\n\n/** Scale configuration for an encoding channel. */\nexport interface ScaleConfig {\n /** Explicit domain override. Auto-derived from data if omitted. */\n domain?: [number, number] | string[];\n /** Scale type override. Usually inferred from field type. */\n type?: 'linear' | 'log' | 'time' | 'band' | 'point' | 'ordinal';\n /** Whether to nice-ify the domain for clean tick values. Defaults to true. */\n nice?: boolean;\n /** Whether the domain should include zero. Defaults to true for quantitative. */\n zero?: boolean;\n /** When true and domain is set, filter out data rows with values outside the domain range. */\n clip?: boolean;\n}\n\n/**\n * A single encoding channel mapping a data field to a visual property.\n *\n * Follows the Vega-Lite encoding model: field identifies the column,\n * type determines how the engine interprets values, aggregate applies\n * a transformation before encoding.\n */\nexport interface EncodingChannel {\n /** Data field name (column in the data array). */\n field: string;\n /**\n * How to interpret the field values.\n * - quantitative: continuous numbers (scale: linear)\n * - temporal: dates/times (scale: time)\n * - nominal: unordered categories (scale: ordinal)\n * - ordinal: ordered categories (scale: ordinal)\n */\n type: FieldType;\n /** Optional aggregate to apply before encoding. */\n aggregate?: AggregateOp;\n /** Axis configuration. Only relevant for x and y channels. */\n axis?: AxisConfig;\n /** Scale configuration. */\n scale?: ScaleConfig;\n}\n\n/**\n * Encoding object mapping visual channels to data fields.\n * Which channels are required depends on the chart type.\n * See ChartEncodingRules in encoding.ts for per-type requirements.\n */\nexport interface Encoding {\n /** Horizontal position channel. */\n x?: EncodingChannel;\n /** Vertical position channel. */\n y?: EncodingChannel;\n /** Color channel (series differentiation or heatmap). */\n color?: EncodingChannel;\n /** Size channel (bubble charts, dot plots). */\n size?: EncodingChannel;\n /** Detail channel (group without encoding to a visual property). */\n detail?: EncodingChannel;\n}\n\n// ---------------------------------------------------------------------------\n// Graph-specific encoding\n// ---------------------------------------------------------------------------\n\n/** Encoding channel for graph nodes and edges. Same structure as EncodingChannel. */\nexport interface GraphEncodingChannel {\n /** Data field name on the node/edge object. */\n field: string;\n /** How to interpret the field values. */\n type?: FieldType;\n}\n\n/** Graph-specific encoding mapping visual properties to node/edge data fields. */\nexport interface GraphEncoding {\n /** Color mapping for nodes. */\n nodeColor?: GraphEncodingChannel;\n /** Size mapping for nodes. */\n nodeSize?: GraphEncodingChannel;\n /** Color mapping for edges. */\n edgeColor?: GraphEncodingChannel;\n /** Width mapping for edges. */\n edgeWidth?: GraphEncodingChannel;\n /** Style mapping for edges (solid, dashed, dotted). */\n edgeStyle?: GraphEncodingChannel;\n /** Label field for nodes. */\n nodeLabel?: GraphEncodingChannel;\n}\n\n/** Layout algorithm for graph visualization. */\nexport interface GraphLayoutConfig {\n /** Layout algorithm type. */\n type: 'force' | 'radial' | 'hierarchical';\n /** Optional clustering configuration. */\n clustering?: {\n /** Field to group nodes by for cluster forces. */\n field: string;\n };\n /** Charge strength for force layout. Negative values create repulsion. */\n chargeStrength?: number;\n /** Target distance between linked nodes. */\n linkDistance?: number;\n /** Extra px added to node radius for collision detection (default 2). */\n collisionPadding?: number;\n /** Link force strength override. */\n linkStrength?: number;\n /** Whether to apply center force (default true). */\n centerForce?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Chrome (editorial text elements)\n// ---------------------------------------------------------------------------\n\n/** Style overrides for a chrome text element. */\nexport interface ChromeTextStyle {\n /** Font size in pixels. */\n fontSize?: number;\n /** Font weight (400 = normal, 600 = semibold, 700 = bold). */\n fontWeight?: number;\n /** Font family override. */\n fontFamily?: string;\n /** Text color (CSS color string). */\n color?: string;\n}\n\n/** A chrome text element with optional style overrides. */\nexport interface ChromeText {\n /** The text content to display. */\n text: string;\n /** Optional style overrides. Theme defaults are used for any omitted property. */\n style?: ChromeTextStyle;\n /** Pixel offset for fine-tuning position. */\n offset?: AnnotationOffset;\n}\n\n/**\n * Editorial chrome elements: title, subtitle, source attribution, byline, footer.\n * These are first-class structural elements, not string-only afterthoughts.\n * Each element can be a simple string or a ChromeText object with style overrides.\n */\nexport interface Chrome {\n /** Main title displayed above the visualization. */\n title?: string | ChromeText;\n /** Subtitle displayed below the title, typically providing context. */\n subtitle?: string | ChromeText;\n /** Data source attribution, displayed below the chart area. */\n source?: string | ChromeText;\n /** Author or organization byline. */\n byline?: string | ChromeText;\n /** Footer text, displayed at the very bottom. */\n footer?: string | ChromeText;\n}\n\n// ---------------------------------------------------------------------------\n// Annotations\n// ---------------------------------------------------------------------------\n\n/** Pixel offset for fine-grained annotation positioning. */\nexport interface AnnotationOffset {\n /** Horizontal pixel offset. */\n dx?: number;\n /** Vertical pixel offset. */\n dy?: number;\n}\n\n/** Anchor direction for annotation label placement relative to the data point. */\nexport type AnnotationAnchor = 'top' | 'bottom' | 'left' | 'right' | 'auto';\n\n/** Base properties shared by all annotation types. */\ninterface AnnotationBase {\n /** Human-readable label for the annotation. */\n label?: string;\n /** Fill color for the annotation element. */\n fill?: string;\n /** Stroke color for the annotation element. */\n stroke?: string;\n /** Opacity from 0 to 1. */\n opacity?: number;\n /** Z-index for render ordering. Higher values render on top. */\n zIndex?: number;\n}\n\n/**\n * Text annotation positioned at a data coordinate.\n * Shows a callout label at a specific point in the chart.\n */\nexport interface TextAnnotation extends AnnotationBase {\n type: 'text';\n /** X-axis data value or position. */\n x: string | number;\n /** Y-axis data value or position. */\n y: string | number;\n /** The annotation text. Required for text annotations. */\n text: string;\n /** Font size override. */\n fontSize?: number;\n /** Font weight override. */\n fontWeight?: number;\n /** Pixel offset from the computed position. */\n offset?: AnnotationOffset;\n /** Anchor direction for label placement relative to the data point. */\n anchor?: AnnotationAnchor;\n /**\n * Connector from label to anchor point.\n * - `true` (default): straight line\n * - `'curve'`: curved arrow with arrowhead\n * - `false`: no connector\n */\n connector?: boolean | 'curve';\n /** Per-endpoint offsets for the connector line. Allows fine-tuning where the connector starts and ends. */\n connectorOffset?: {\n /** Offset for the label-end of the connector. */\n from?: AnnotationOffset;\n /** Offset for the data-point-end of the connector. */\n to?: AnnotationOffset;\n };\n /** Background color behind the text. Useful for readability over chart lines. */\n background?: string;\n}\n\n/**\n * Range annotation highlighting a region of the chart.\n * Defined by x1/x2 (vertical band) or y1/y2 (horizontal band) or both (rectangle).\n */\nexport interface RangeAnnotation extends AnnotationBase {\n type: 'range';\n /** Start of the range on the x-axis. */\n x1?: string | number;\n /** End of the range on the x-axis. */\n x2?: string | number;\n /** Start of the range on the y-axis. */\n y1?: string | number;\n /** End of the range on the y-axis. */\n y2?: string | number;\n /** Pixel offset for the range label. */\n labelOffset?: AnnotationOffset;\n /** Anchor direction for the range label. */\n labelAnchor?: AnnotationAnchor;\n}\n\n/**\n * Reference line annotation: a horizontal or vertical line at a data value.\n * Useful for baselines (zero), targets, or thresholds.\n */\nexport interface RefLineAnnotation extends AnnotationBase {\n type: 'refline';\n /** X-axis value for a vertical reference line. */\n x?: string | number;\n /** Y-axis value for a horizontal reference line. */\n y?: string | number;\n /** Line style. */\n style?: 'solid' | 'dashed' | 'dotted';\n /** Line width in pixels. */\n strokeWidth?: number;\n /** Pixel offset for the reference line label. */\n labelOffset?: AnnotationOffset;\n /** Anchor direction for the reference line label. */\n labelAnchor?: AnnotationAnchor;\n}\n\n/** Discriminated union of all annotation types. */\nexport type Annotation = TextAnnotation | RangeAnnotation | RefLineAnnotation;\n\n// ---------------------------------------------------------------------------\n// Theme + Dark Mode\n// ---------------------------------------------------------------------------\n\n/**\n * Dark mode behavior.\n * - \"auto\": respect system preference (prefers-color-scheme)\n * - \"force\": always render in dark mode\n * - \"off\": always render in light mode (default)\n */\nexport type DarkMode = 'auto' | 'force' | 'off';\n\n/**\n * User-facing theme configuration for overriding defaults.\n * All fields are optional. The engine deep-merges these onto the default theme.\n */\nexport interface ThemeConfig {\n /**\n * Color palette overrides.\n * Pass a flat string[] as shorthand for categorical colors,\n * or an object for full control over categorical, sequential, diverging, etc.\n */\n colors?:\n | string[]\n | {\n /** Categorical palette for nominal data (array of CSS color strings). */\n categorical?: string[];\n /** Sequential palettes keyed by name. Each is an array of color stops. */\n sequential?: Record<string, string[]>;\n /** Diverging palettes keyed by name. Each is an array of color stops with a neutral midpoint. */\n diverging?: Record<string, string[]>;\n /** Background color. */\n background?: string;\n /** Default text color. */\n text?: string;\n /** Gridline color. */\n gridline?: string;\n /** Axis line and tick color. */\n axis?: string;\n };\n /** Font overrides. */\n fonts?: {\n /** Primary font family. */\n family?: string;\n /** Monospace font family (for tabular numbers). */\n mono?: string;\n };\n /** Spacing overrides in pixels. */\n spacing?: {\n /** Padding inside the chart container. */\n padding?: number;\n /** Gap between chrome elements (title to subtitle, etc.). */\n chromeGap?: number;\n };\n /** Border radius for chart container and tooltips. */\n borderRadius?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Label configuration\n// ---------------------------------------------------------------------------\n\n/**\n * Label density mode controlling how many data labels are shown.\n * - 'all': show every label, skip collision detection\n * - 'auto': show labels with collision detection (default)\n * - 'endpoints': show only first and last per series (useful for line charts)\n * - 'none': hide all labels (rely on tooltips and legend)\n */\nexport type LabelDensity = 'all' | 'auto' | 'endpoints' | 'none';\n\n/** Label display configuration for chart data labels. */\nexport interface LabelConfig {\n /** How many labels to show. Defaults to 'auto'. */\n density?: LabelDensity;\n /** Number format override for label values (d3-format string, e.g. \",.0f\"). */\n format?: string;\n /** Per-series pixel offsets for fine-tuning label positions, keyed by series name. */\n offsets?: Record<string, AnnotationOffset>;\n}\n\n// ---------------------------------------------------------------------------\n// Legend configuration\n// ---------------------------------------------------------------------------\n\n/** Legend display configuration. Overrides the responsive-default position. */\nexport interface LegendConfig {\n /** Override the legend position. If omitted, the responsive strategy decides. */\n position?: LegendPosition;\n /** Pixel offset for fine-tuning legend position. */\n offset?: AnnotationOffset;\n}\n\n// ---------------------------------------------------------------------------\n// Spec types (the top-level discriminated union)\n// ---------------------------------------------------------------------------\n\n/** Data row: a plain object with string keys. */\nexport type DataRow = Record<string, unknown>;\n\n/** Per-series visual style overrides for line/area charts. */\nexport interface SeriesStyle {\n /** Line dash style. Defaults to 'solid'. */\n lineStyle?: 'solid' | 'dashed' | 'dotted';\n /** Whether to show data point markers. Defaults to true. */\n showPoints?: boolean;\n /** Stroke width override. */\n strokeWidth?: number;\n /** Opacity override (0-1). */\n opacity?: number;\n}\n\n/**\n * Chart specification: the primary input for standard chart types.\n *\n * Combines a chart type with data, encoding channels, editorial chrome,\n * annotations, and configuration. The engine validates, normalizes, and\n * compiles this into a ChartLayout.\n */\nexport interface ChartSpec {\n /** The chart type to render. */\n type: ChartType;\n /** Data array: each element is a row with field values. */\n data: DataRow[];\n /** Encoding mapping data fields to visual channels. */\n encoding: Encoding;\n /** Editorial chrome (title, subtitle, source, etc.). */\n chrome?: Chrome;\n /** Data annotations (text callouts, highlighted ranges, reference lines). */\n annotations?: Annotation[];\n /** Label display configuration (density, format). */\n labels?: LabelConfig;\n /** Legend display configuration (position override). */\n legend?: LegendConfig;\n /** Whether the chart adapts to container width. Defaults to true. */\n responsive?: boolean;\n /** Theme configuration overrides. */\n theme?: ThemeConfig;\n /** Dark mode behavior. Defaults to \"off\". */\n darkMode?: DarkMode;\n /** Series names to hide from rendering. Hidden series remain in the legend but are visually dimmed. */\n hiddenSeries?: string[];\n /** Per-series visual overrides, keyed by series name (the color field value). */\n seriesStyles?: Record<string, SeriesStyle>;\n}\n\n/**\n * Table specification: input for data table visualizations.\n *\n * Tables are a visualization type, not just an HTML grid. They support\n * heatmap coloring, inline sparklines, sorted columns, search, and pagination.\n */\nexport interface TableSpec {\n /** Discriminant: always \"table\". */\n type: 'table';\n /** Data array: each element is a row. */\n data: DataRow[];\n /** Column definitions controlling display, sorting, formatting, and mini-charts. */\n columns: ColumnConfig[];\n /** Optional field to use as a unique row identifier. */\n rowKey?: string;\n /** Editorial chrome. */\n chrome?: Chrome;\n /** Theme configuration overrides. */\n theme?: ThemeConfig;\n /** Dark mode behavior. */\n darkMode?: DarkMode;\n /** Enable client-side search/filter. */\n search?: boolean;\n /** Pagination configuration. True for defaults, or an object with pageSize. */\n pagination?: boolean | { pageSize: number };\n /** Whether to stick the first column during horizontal scroll. */\n stickyFirstColumn?: boolean;\n /** Compact mode: reduced padding and font sizes. */\n compact?: boolean;\n /** Whether the table adapts to container width. Defaults to true. */\n responsive?: boolean;\n}\n\n/** Graph node: must have an id, plus arbitrary data fields. */\nexport interface GraphNode {\n /** Unique identifier for the node. */\n id: string;\n /** Arbitrary data fields. */\n [key: string]: unknown;\n}\n\n/** Graph edge: connects two nodes by id. */\nexport interface GraphEdge {\n /** Source node id. */\n source: string;\n /** Target node id. */\n target: string;\n /** Arbitrary data fields (weight, type, confidence, etc.). */\n [key: string]: unknown;\n}\n\n/**\n * Graph specification: input for network/relationship visualizations.\n *\n * Uses a nodes + edges data model instead of the flat data + encoding model\n * used by chart types. The graph type is defined here for forward compatibility\n * but rendering is deferred to a future phase.\n */\n/** Per-node visual overrides, keyed by node id. */\nexport interface NodeOverride {\n /** Override fill color. */\n fill?: string;\n /** Override radius. */\n radius?: number;\n /** Override stroke width. */\n strokeWidth?: number;\n /** Override stroke color. */\n stroke?: string;\n /** Force label to always show regardless of zoom/priority. */\n alwaysShowLabel?: boolean;\n}\n\nexport interface GraphSpec {\n /** Discriminant: always \"graph\". */\n type: 'graph';\n /** Node array. Each node must have an id field. */\n nodes: GraphNode[];\n /** Edge array. Each edge connects source and target node ids. */\n edges: GraphEdge[];\n /** Graph-specific encoding mapping visual properties to node/edge fields. */\n encoding?: GraphEncoding;\n /** Layout algorithm configuration. */\n layout?: GraphLayoutConfig;\n /** Per-node visual overrides, keyed by node id. */\n nodeOverrides?: Record<string, NodeOverride>;\n /** Editorial chrome. */\n chrome?: Chrome;\n /** Annotations. */\n annotations?: Annotation[];\n /** Theme configuration overrides. */\n theme?: ThemeConfig;\n /** Dark mode behavior. */\n darkMode?: DarkMode;\n}\n\n/**\n * Top-level visualization spec: discriminated union on the `type` field.\n *\n * This is the primary API contract. Users (and Claude) write VizSpec objects,\n * the engine validates and compiles them into layout objects for rendering.\n */\nexport type VizSpec = ChartSpec | TableSpec | GraphSpec;\n\n/** Chart spec without runtime data, for persistence/storage. */\nexport type ChartSpecWithoutData = Omit<ChartSpec, 'data'>;\n/** Table spec without runtime data and columns, for persistence/storage. Columns can be auto-generated via dataTable(). */\nexport type TableSpecWithoutData = Omit<TableSpec, 'data' | 'columns'>;\n/** Graph spec without runtime data, for persistence/storage. */\nexport type GraphSpecWithoutData = Omit<GraphSpec, 'nodes' | 'edges'>;\n/** Union of data-stripped spec types for persistence/storage. */\nexport type StoredVizSpec = ChartSpecWithoutData | TableSpecWithoutData | GraphSpecWithoutData;\n\n// ---------------------------------------------------------------------------\n// Type guards\n// ---------------------------------------------------------------------------\n\n/** All valid chart type strings for runtime checking. */\nexport const CHART_TYPES: ReadonlySet<string> = new Set<ChartType>([\n 'line',\n 'area',\n 'bar',\n 'column',\n 'pie',\n 'donut',\n 'dot',\n 'scatter',\n]);\n\n/** Check if a spec is a ChartSpec (any standard chart type). */\nexport function isChartSpec(spec: VizSpec): spec is ChartSpec {\n return CHART_TYPES.has(spec.type);\n}\n\n/** Check if a spec is a TableSpec. */\nexport function isTableSpec(spec: VizSpec): spec is TableSpec {\n return spec.type === 'table';\n}\n\n/** Check if a spec is a GraphSpec. */\nexport function isGraphSpec(spec: VizSpec): spec is GraphSpec {\n return spec.type === 'graph';\n}\n\n// ---------------------------------------------------------------------------\n// Annotation type guards\n// ---------------------------------------------------------------------------\n\n/** Check if an annotation is a TextAnnotation. */\nexport function isTextAnnotation(annotation: Annotation): annotation is TextAnnotation {\n return annotation.type === 'text';\n}\n\n/** Check if an annotation is a RangeAnnotation. */\nexport function isRangeAnnotation(annotation: Annotation): annotation is RangeAnnotation {\n return annotation.type === 'range';\n}\n\n/** Check if an annotation is a RefLineAnnotation. */\nexport function isRefLineAnnotation(annotation: Annotation): annotation is RefLineAnnotation {\n return annotation.type === 'refline';\n}\n","/**\n * Color blindness simulation and palette distinguishability checks.\n *\n * Uses Brettel, Vienot, and Mollon (1997) simulation matrices for\n * protanopia, deuteranopia, and tritanopia.\n *\n * These are approximations suitable for checking palette accessibility,\n * not medical-grade simulations.\n */\n\nimport { rgb } from 'd3-color';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** The three common types of color vision deficiency. */\nexport type ColorBlindnessType = 'protanopia' | 'deuteranopia' | 'tritanopia';\n\n// ---------------------------------------------------------------------------\n// Simulation matrices\n// ---------------------------------------------------------------------------\n\n// 3x3 color transformation matrices for each deficiency type.\n// Applied in linear RGB space to simulate how colors appear.\n// Source: Brettel, Vienot & Mollon (1997), simplified.\n\ntype Matrix3x3 = readonly [\n readonly [number, number, number],\n readonly [number, number, number],\n readonly [number, number, number],\n];\n\nconst PROTAN_MATRIX: Matrix3x3 = [\n [0.567, 0.433, 0.0],\n [0.558, 0.442, 0.0],\n [0.0, 0.242, 0.758],\n];\n\nconst DEUTAN_MATRIX: Matrix3x3 = [\n [0.625, 0.375, 0.0],\n [0.7, 0.3, 0.0],\n [0.0, 0.3, 0.7],\n];\n\nconst TRITAN_MATRIX: Matrix3x3 = [\n [0.95, 0.05, 0.0],\n [0.0, 0.433, 0.567],\n [0.0, 0.475, 0.525],\n];\n\nconst MATRICES: Record<ColorBlindnessType, Matrix3x3> = {\n protanopia: PROTAN_MATRIX,\n deuteranopia: DEUTAN_MATRIX,\n tritanopia: TRITAN_MATRIX,\n};\n\n// ---------------------------------------------------------------------------\n// sRGB linearization helpers\n// ---------------------------------------------------------------------------\n\nfunction linearize(v: number): number {\n const s = v / 255;\n return s <= 0.04045 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n}\n\nfunction delinearize(v: number): number {\n const s = v <= 0.0031308 ? v * 12.92 : 1.055 * v ** (1 / 2.4) - 0.055;\n return Math.round(Math.max(0, Math.min(255, s * 255)));\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Simulate how a color appears under a given color blindness type.\n * Returns a hex color string.\n */\nexport function simulateColorBlindness(color: string, type: ColorBlindnessType): string {\n const c = rgb(color);\n if (c == null) return color;\n\n const lin = [linearize(c.r), linearize(c.g), linearize(c.b)];\n const m = MATRICES[type];\n\n const r = m[0][0] * lin[0] + m[0][1] * lin[1] + m[0][2] * lin[2];\n const g = m[1][0] * lin[0] + m[1][1] * lin[1] + m[1][2] * lin[2];\n const b = m[2][0] * lin[0] + m[2][1] * lin[1] + m[2][2] * lin[2];\n\n return rgb(delinearize(r), delinearize(g), delinearize(b)).formatHex();\n}\n\n/**\n * Check if colors in a palette are distinguishable under a given\n * color blindness type.\n *\n * Uses a minimum perceptual distance threshold in simulated space.\n * Returns true if all pairs of colors are sufficiently different.\n */\nexport function checkPaletteDistinguishability(\n colors: string[],\n type: ColorBlindnessType,\n minDistance = 30,\n): boolean {\n const simulated = colors.map((c) => {\n const s = rgb(simulateColorBlindness(c, type));\n return s ? [s.r, s.g, s.b] : [0, 0, 0];\n });\n\n for (let i = 0; i < simulated.length; i++) {\n for (let j = i + 1; j < simulated.length; j++) {\n const dr = simulated[i][0] - simulated[j][0];\n const dg = simulated[i][1] - simulated[j][1];\n const db = simulated[i][2] - simulated[j][2];\n const dist = Math.sqrt(dr * dr + dg * dg + db * db);\n if (dist < minDistance) return false;\n }\n }\n\n return true;\n}\n","/**\n * WCAG contrast ratio utilities.\n *\n * Uses d3-color for color space parsing and manipulation.\n * All functions accept CSS color strings (hex, rgb, hsl, named colors).\n */\n\nimport { rgb } from 'd3-color';\n\n// ---------------------------------------------------------------------------\n// Relative luminance (WCAG 2.1)\n// ---------------------------------------------------------------------------\n\n/**\n * Compute the relative luminance of a color per WCAG 2.1 definition.\n * https://www.w3.org/TR/WCAG21/#dfn-relative-luminance\n */\nfunction relativeLuminance(color: string): number {\n const c = rgb(color);\n if (c == null) return 0;\n\n const srgb = [c.r / 255, c.g / 255, c.b / 255];\n const linear = srgb.map((v) => (v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4));\n return 0.2126 * linear[0] + 0.7152 * linear[1] + 0.0722 * linear[2];\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute the WCAG contrast ratio between two colors.\n * Returns a value between 1 (identical) and 21 (black on white).\n */\nexport function contrastRatio(fg: string, bg: string): number {\n const l1 = relativeLuminance(fg);\n const l2 = relativeLuminance(bg);\n const lighter = Math.max(l1, l2);\n const darker = Math.min(l1, l2);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * Check if two colors meet WCAG AA contrast requirements.\n * Normal text: 4.5:1, large text (18px+ bold or 24px+): 3:1.\n */\nexport function meetsAA(fg: string, bg: string, largeText = false): boolean {\n const ratio = contrastRatio(fg, bg);\n return largeText ? ratio >= 3 : ratio >= 4.5;\n}\n\n/**\n * Find an accessible variant of `baseColor` against `bg`.\n *\n * Preserves the hue and saturation of baseColor but adjusts lightness\n * until the target contrast ratio is met. Returns the original color\n * if it already meets the target.\n */\nexport function findAccessibleColor(baseColor: string, bg: string, targetRatio = 4.5): string {\n if (contrastRatio(baseColor, bg) >= targetRatio) {\n return baseColor;\n }\n\n const c = rgb(baseColor);\n if (c == null) return baseColor;\n\n const bgLum = relativeLuminance(bg);\n // Determine direction: darken if bg is light, lighten if bg is dark.\n const bgIsLight = bgLum > 0.5;\n\n // Binary search for the lightness adjustment that hits the target ratio.\n let lo = 0;\n let hi = 1;\n let best = baseColor;\n\n for (let i = 0; i < 20; i++) {\n const mid = (lo + hi) / 2;\n const adjusted = bgIsLight\n ? rgb(c.r * (1 - mid), c.g * (1 - mid), c.b * (1 - mid))\n : rgb(c.r + (255 - c.r) * mid, c.g + (255 - c.g) * mid, c.b + (255 - c.b) * mid);\n\n const hex = adjusted.formatHex();\n const ratio = contrastRatio(hex, bg);\n\n if (ratio >= targetRatio) {\n best = hex;\n hi = mid; // try less adjustment\n } else {\n lo = mid; // need more adjustment\n }\n }\n\n return best;\n}\n","/**\n * Color palettes for @opendata-ai.\n *\n * Categorical palette is Infrographic-influenced with WCAG AA contrast\n * for large text (3:1 ratio) on both light (#ffffff) and dark (#1a1a2e)\n * backgrounds. Several colors do not meet the stricter 4.5:1 ratio\n * required for normal-sized body text. This is acceptable because chart\n * marks (bars, lines, areas, points) are large visual elements.\n *\n * Sequential palettes: 5-7 stops from light to dark.\n * Diverging palettes: 7 stops with a neutral midpoint.\n */\n\n// ---------------------------------------------------------------------------\n// Categorical\n// ---------------------------------------------------------------------------\n\n/**\n * Default categorical palette. 10 visually distinct colors that meet\n * WCAG AA contrast for large text (3:1) on both white and near-black\n * backgrounds. Some colors fall below the 4.5:1 threshold for normal\n * body text. Influenced by Infrographic's editorial palette with tweaks\n * for accessibility and colorblind distinguishability.\n */\nexport const CATEGORICAL_PALETTE = [\n '#1b7fa3', // teal-blue (primary)\n '#c44e52', // warm red (secondary)\n '#6a9f58', // softer green (tertiary)\n '#d47215', // orange\n '#507e79', // muted teal\n '#9a6a8d', // purple\n '#c4636b', // rose\n '#9c755f', // brown\n '#a88f22', // olive gold\n '#858078', // warm gray\n] as const;\n\nexport type CategoricalPalette = typeof CATEGORICAL_PALETTE;\n\n// ---------------------------------------------------------------------------\n// Sequential\n// ---------------------------------------------------------------------------\n\n/** Sequential palette definition: an array of color stops from light to dark. */\nexport interface SequentialPalette {\n readonly name: string;\n readonly stops: readonly string[];\n}\n\nexport const SEQUENTIAL_BLUE: SequentialPalette = {\n name: 'blue',\n stops: ['#deebf7', '#c6dbef', '#9ecae1', '#6baed6', '#3182bd', '#08519c'],\n} as const;\n\nexport const SEQUENTIAL_GREEN: SequentialPalette = {\n name: 'green',\n stops: ['#e5f5e0', '#c7e9c0', '#a1d99b', '#74c476', '#31a354', '#006d2c'],\n} as const;\n\nexport const SEQUENTIAL_ORANGE: SequentialPalette = {\n name: 'orange',\n stops: ['#fee6ce', '#fdd0a2', '#fdae6b', '#fd8d3c', '#e6550d', '#a63603'],\n} as const;\n\nexport const SEQUENTIAL_PURPLE: SequentialPalette = {\n name: 'purple',\n stops: ['#efedf5', '#dadaeb', '#bcbddc', '#9e9ac8', '#756bb1', '#54278f'],\n} as const;\n\n/** All sequential palettes keyed by name. */\nexport const SEQUENTIAL_PALETTES: Record<string, string[]> = {\n blue: [...SEQUENTIAL_BLUE.stops],\n green: [...SEQUENTIAL_GREEN.stops],\n orange: [...SEQUENTIAL_ORANGE.stops],\n purple: [...SEQUENTIAL_PURPLE.stops],\n};\n\n// ---------------------------------------------------------------------------\n// Diverging\n// ---------------------------------------------------------------------------\n\n/** Diverging palette definition: an array of color stops with a neutral midpoint. */\nexport interface DivergingPalette {\n readonly name: string;\n readonly stops: readonly string[];\n}\n\nexport const DIVERGING_RED_BLUE: DivergingPalette = {\n name: 'redBlue',\n stops: [\n '#b2182b', // strong red\n '#d6604d', // medium red\n '#f4a582', // light red\n '#f7f7f7', // neutral\n '#92c5de', // light blue\n '#4393c3', // medium blue\n '#2166ac', // strong blue\n ],\n} as const;\n\nexport const DIVERGING_BROWN_TEAL: DivergingPalette = {\n name: 'brownTeal',\n stops: [\n '#8c510a', // strong brown\n '#bf812d', // medium brown\n '#dfc27d', // light brown\n '#f6e8c3', // neutral\n '#80cdc1', // light teal\n '#35978f', // medium teal\n '#01665e', // strong teal\n ],\n} as const;\n\n/** All diverging palettes keyed by name. */\nexport const DIVERGING_PALETTES: Record<string, string[]> = {\n redBlue: [...DIVERGING_RED_BLUE.stops],\n brownTeal: [...DIVERGING_BROWN_TEAL.stops],\n};\n","/**\n * Dark mode theme adaptation.\n *\n * Preserves hue of colors while adjusting lightness and saturation\n * to maintain the same relative contrast ratios on a dark background.\n */\n\nimport { hsl, rgb } from 'd3-color';\nimport { contrastRatio } from '../colors/contrast';\nimport type { ResolvedTheme } from '../types/theme';\n\n// ---------------------------------------------------------------------------\n// Dark mode background\n// ---------------------------------------------------------------------------\n\n/** Default dark mode background color. */\nconst DARK_BG = '#1a1a2e';\n/** Default dark mode text color. */\nconst DARK_TEXT = '#e0e0e0';\n\n// ---------------------------------------------------------------------------\n// Color adaptation\n// ---------------------------------------------------------------------------\n\n/**\n * Adapt a single color for dark mode.\n *\n * Preserves the hue and adjusts lightness/saturation so the adapted\n * color has the same contrast ratio against darkBg as the original\n * had against lightBg.\n */\nexport function adaptColorForDarkMode(color: string, lightBg: string, darkBg: string): string {\n const originalRatio = contrastRatio(color, lightBg);\n const c = hsl(color);\n if (c == null || Number.isNaN(c.h)) {\n // Achromatic or invalid color: just adjust lightness\n const r = rgb(color);\n if (r == null) return color;\n const darkBgLum = _luminanceFromHex(darkBg);\n const isLight = darkBgLum < 0.5;\n if (isLight) return color;\n // Invert the lightness\n const inverted = hsl(color);\n if (inverted == null) return color;\n inverted.l = 1 - inverted.l;\n return inverted.formatHex();\n }\n\n // Binary search for lightness that gives equivalent contrast on dark bg\n let lo = 0.0;\n let hi = 1.0;\n let bestColor = color;\n let bestDiff = Infinity;\n\n for (let i = 0; i < 20; i++) {\n const mid = (lo + hi) / 2;\n const candidate = hsl(c.h, c.s, mid);\n const hex = candidate.formatHex();\n const ratio = contrastRatio(hex, darkBg);\n const diff = Math.abs(ratio - originalRatio);\n\n if (diff < bestDiff) {\n bestDiff = diff;\n bestColor = hex;\n }\n\n if (ratio < originalRatio) {\n // Need more contrast = more lightness on dark bg\n lo = mid;\n } else {\n hi = mid;\n }\n }\n\n return bestColor;\n}\n\n/** Quick luminance estimation from a hex color. */\nfunction _luminanceFromHex(color: string): number {\n const c = rgb(color);\n if (c == null) return 0;\n return (0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) / 255;\n}\n\n// ---------------------------------------------------------------------------\n// Full theme adaptation\n// ---------------------------------------------------------------------------\n\n/**\n * Adapt an entire resolved theme for dark mode.\n *\n * Swaps background/text, adapts categorical and annotation colors,\n * adjusts gridline and axis colors for the dark background.\n */\nexport function adaptTheme(theme: ResolvedTheme): ResolvedTheme {\n const inputBg = theme.colors.background;\n // Treat transparent as \"already dark\" to preserve user intent\n const alreadyDark = inputBg === 'transparent' || _luminanceFromHex(inputBg) < 0.2;\n\n // If the theme already has a dark background, preserve user-provided colors\n // instead of overwriting with library defaults.\n const darkBg = alreadyDark ? inputBg : DARK_BG;\n const darkText = alreadyDark ? theme.colors.text : DARK_TEXT;\n const darkGridline = alreadyDark ? theme.colors.gridline : '#333344';\n const darkAxis = alreadyDark ? theme.colors.axis : '#888899';\n\n // Only adapt categorical colors when switching from light to dark\n const categorical = alreadyDark\n ? theme.colors.categorical\n : theme.colors.categorical.map((c) => adaptColorForDarkMode(c, inputBg, darkBg));\n\n return {\n ...theme,\n isDark: true,\n colors: {\n ...theme.colors,\n background: darkBg,\n text: darkText,\n gridline: darkGridline,\n axis: darkAxis,\n annotationFill: 'rgba(255,255,255,0.08)',\n annotationText: '#bbbbcc',\n categorical,\n },\n chrome: {\n title: { ...theme.chrome.title, color: darkText },\n subtitle: { ...theme.chrome.subtitle, color: '#aaaaaa' },\n source: { ...theme.chrome.source, color: '#888888' },\n byline: { ...theme.chrome.byline, color: '#888888' },\n footer: { ...theme.chrome.footer, color: '#888888' },\n },\n };\n}\n","/**\n * Default theme definition.\n *\n * Tuned to match Infrographic's visual weight and editorial style.\n * Inter font family, typography hierarchy for chrome, and color\n * palettes from the colors module.\n */\n\nimport { CATEGORICAL_PALETTE, DIVERGING_PALETTES, SEQUENTIAL_PALETTES } from '../colors/palettes';\nimport type { Theme } from '../types/theme';\n\n/**\n * The default theme. All fields are required and fully specified.\n * resolveTheme() deep-merges user overrides onto this base.\n */\nexport const DEFAULT_THEME: Theme = {\n colors: {\n categorical: [...CATEGORICAL_PALETTE],\n sequential: SEQUENTIAL_PALETTES,\n diverging: DIVERGING_PALETTES,\n background: '#ffffff',\n text: '#1d1d1d',\n gridline: '#e8e8e8',\n axis: '#888888',\n annotationFill: 'rgba(0,0,0,0.04)',\n annotationText: '#555555',\n },\n fonts: {\n family: 'Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n mono: '\"JetBrains Mono\", \"Fira Code\", \"Cascadia Code\", monospace',\n sizes: {\n title: 22,\n subtitle: 15,\n body: 13,\n small: 11,\n axisTick: 11,\n },\n weights: {\n normal: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n },\n },\n spacing: {\n padding: 12,\n chromeGap: 4,\n chromeToChart: 8,\n chartToFooter: 8,\n axisMargin: 6,\n },\n borderRadius: 4,\n chrome: {\n title: {\n fontSize: 22,\n fontWeight: 700,\n color: '#333333',\n lineHeight: 1.3,\n },\n subtitle: {\n fontSize: 15,\n fontWeight: 400,\n color: '#666666',\n lineHeight: 1.4,\n },\n source: {\n fontSize: 12,\n fontWeight: 400,\n color: '#999999',\n lineHeight: 1.3,\n },\n byline: {\n fontSize: 12,\n fontWeight: 400,\n color: '#999999',\n lineHeight: 1.3,\n },\n footer: {\n fontSize: 12,\n fontWeight: 400,\n color: '#999999',\n lineHeight: 1.3,\n },\n },\n};\n","/**\n * Theme resolver: deep-merges user overrides onto default theme.\n *\n * Produces a ResolvedTheme where every property is guaranteed to have\n * a value. The engine uses ResolvedTheme internally so it never needs\n * null checks on theme properties.\n *\n * Auto-detects dark backgrounds and adapts chrome text colors so\n * custom themes with dark canvases are readable without explicitly\n * enabling darkMode.\n */\n\nimport type { ThemeConfig } from '../types/spec';\nimport type { ResolvedTheme, Theme } from '../types/theme';\nimport { DEFAULT_THEME } from './defaults';\n\n/**\n * Deep merge source into target, creating a new object.\n * Only merges plain objects; arrays and primitives replace directly.\n */\n// biome-ignore lint/suspicious/noExplicitAny: recursive object merge requires dynamic typing\nfunction deepMerge(target: any, source: any): any {\n const result = { ...target };\n\n for (const key of Object.keys(source)) {\n const sourceVal = source[key];\n const targetVal = target[key];\n\n if (\n sourceVal !== undefined &&\n sourceVal !== null &&\n typeof sourceVal === 'object' &&\n !Array.isArray(sourceVal) &&\n typeof targetVal === 'object' &&\n targetVal !== null &&\n !Array.isArray(targetVal)\n ) {\n result[key] = deepMerge(targetVal, sourceVal);\n } else if (sourceVal !== undefined) {\n result[key] = sourceVal;\n }\n }\n\n return result;\n}\n\n/**\n * Convert a user-facing ThemeConfig (partial) into the full Theme shape\n * that deepMerge can work with.\n */\nfunction themeConfigToPartial(config: ThemeConfig): Partial<Theme> {\n const partial: Partial<Theme> = {};\n\n if (config.colors) {\n const colors: Partial<Theme['colors']> = {};\n // Shorthand: flat string[] is treated as categorical palette\n if (Array.isArray(config.colors)) {\n colors.categorical = config.colors;\n } else {\n if (config.colors.categorical) colors.categorical = config.colors.categorical;\n if (config.colors.sequential) colors.sequential = config.colors.sequential;\n if (config.colors.diverging) colors.diverging = config.colors.diverging;\n if (config.colors.background) colors.background = config.colors.background;\n if (config.colors.text) colors.text = config.colors.text;\n if (config.colors.gridline) colors.gridline = config.colors.gridline;\n if (config.colors.axis) colors.axis = config.colors.axis;\n }\n partial.colors = colors as Theme['colors'];\n }\n\n if (config.fonts) {\n const fonts: Partial<Theme['fonts']> = {};\n if (config.fonts.family) fonts.family = config.fonts.family;\n if (config.fonts.mono) fonts.mono = config.fonts.mono;\n partial.fonts = fonts as Theme['fonts'];\n }\n\n if (config.spacing) {\n const spacing: Partial<Theme['spacing']> = {};\n if (config.spacing.padding !== undefined) spacing.padding = config.spacing.padding;\n if (config.spacing.chromeGap !== undefined) spacing.chromeGap = config.spacing.chromeGap;\n partial.spacing = spacing as Theme['spacing'];\n }\n\n if (config.borderRadius !== undefined) {\n partial.borderRadius = config.borderRadius;\n }\n\n return partial;\n}\n\n/**\n * Parse a hex color to sRGB relative luminance (WCAG 2.1).\n * Returns 0 for invalid/unparseable colors.\n */\nfunction relativeLuminance(hex: string): number {\n const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim());\n if (!m) return 0;\n const r = parseInt(m[1].slice(0, 2), 16) / 255;\n const g = parseInt(m[1].slice(2, 4), 16) / 255;\n const b = parseInt(m[1].slice(4, 6), 16) / 255;\n const toLinear = (c: number) => (c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4);\n return 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);\n}\n\n/** Returns true if the hex color is perceptually dark (luminance < 0.2). */\nfunction isDarkBackground(hex: string): boolean {\n return relativeLuminance(hex) < 0.2;\n}\n\n/**\n * Adapt chrome text colors for a dark background.\n * Only overrides values that still match the light-mode defaults,\n * so explicit user overrides are preserved.\n */\nfunction adaptChromeForDarkBg(theme: Theme, textColor: string): Theme {\n const light = DEFAULT_THEME.chrome;\n return {\n ...theme,\n chrome: {\n title: {\n ...theme.chrome.title,\n color:\n theme.chrome.title.color === light.title.color ? textColor : theme.chrome.title.color,\n },\n subtitle: {\n ...theme.chrome.subtitle,\n color:\n theme.chrome.subtitle.color === light.subtitle.color\n ? adjustOpacity(textColor, 0.7)\n : theme.chrome.subtitle.color,\n },\n source: {\n ...theme.chrome.source,\n color:\n theme.chrome.source.color === light.source.color\n ? adjustOpacity(textColor, 0.5)\n : theme.chrome.source.color,\n },\n byline: {\n ...theme.chrome.byline,\n color:\n theme.chrome.byline.color === light.byline.color\n ? adjustOpacity(textColor, 0.5)\n : theme.chrome.byline.color,\n },\n footer: {\n ...theme.chrome.footer,\n color:\n theme.chrome.footer.color === light.footer.color\n ? adjustOpacity(textColor, 0.5)\n : theme.chrome.footer.color,\n },\n },\n };\n}\n\n/** Blend a hex color toward white/black by a factor to simulate opacity. */\nfunction adjustOpacity(hex: string, opacity: number): string {\n const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim());\n if (!m) return hex;\n const r = parseInt(m[1].slice(0, 2), 16);\n const g = parseInt(m[1].slice(2, 4), 16);\n const b = parseInt(m[1].slice(4, 6), 16);\n // Blend toward mid-gray for muted secondary text\n const mix = (c: number) => Math.round(c * opacity + 128 * (1 - opacity));\n const toHex = (n: number) => n.toString(16).padStart(2, '0');\n return `#${toHex(mix(r))}${toHex(mix(g))}${toHex(mix(b))}`;\n}\n\n/**\n * Resolve a theme by deep-merging user overrides onto a base theme.\n *\n * Auto-detects dark backgrounds: if the resolved background color is\n * perceptually dark and chrome text colors are still the light-mode\n * defaults, they're adapted for readability.\n *\n * @param userTheme - Optional partial theme overrides from the spec.\n * @param base - Base theme to merge onto. Defaults to DEFAULT_THEME.\n * @returns A ResolvedTheme with all properties guaranteed.\n */\nexport function resolveTheme(userTheme?: ThemeConfig, base: Theme = DEFAULT_THEME): ResolvedTheme {\n let merged: Theme = userTheme ? deepMerge(base, themeConfigToPartial(userTheme)) : { ...base };\n\n // Auto-adapt chrome for dark backgrounds\n const dark = isDarkBackground(merged.colors.background);\n if (dark) {\n merged = adaptChromeForDarkBg(merged, merged.colors.text);\n }\n\n return {\n ...merged,\n isDark: dark,\n } as ResolvedTheme;\n}\n","/**\n * Heuristic text measurement for environments without a DOM.\n *\n * These are intentionally approximate. Adapters can provide a real\n * measureText function via CompileOptions for higher accuracy.\n * The engine uses the real function when available, falls back to\n * these heuristics when not.\n */\n\n/**\n * Average character width as a fraction of font size for Inter.\n * Inter is slightly wider than Helvetica, narrower than Courier.\n * This is a reasonable middle ground.\n */\nconst AVG_CHAR_WIDTH_RATIO = 0.55;\n\n/** Narrower characters (i, l, t, etc.) bring the average down. */\nconst WEIGHT_ADJUSTMENT: Record<number, number> = {\n 100: 0.9,\n 200: 0.92,\n 300: 0.95,\n 400: 1.0,\n 500: 1.02,\n 600: 1.05,\n 700: 1.08,\n 800: 1.1,\n 900: 1.12,\n};\n\n/**\n * Estimate the rendered width of a text string.\n *\n * Uses a per-character average width based on font size, adjusted\n * for font weight. Accurate to within ~20% for Latin text in Inter.\n *\n * @param text - The text string to measure.\n * @param fontSize - Font size in pixels.\n * @param fontWeight - Font weight (100-900). Defaults to 400.\n */\nexport function estimateTextWidth(text: string, fontSize: number, fontWeight = 400): number {\n const weightFactor = WEIGHT_ADJUSTMENT[fontWeight] ?? 1.0;\n return text.length * fontSize * AVG_CHAR_WIDTH_RATIO * weightFactor;\n}\n\n/**\n * Estimate the rendered height of a text block.\n *\n * @param fontSize - Font size in pixels.\n * @param lineCount - Number of lines. Defaults to 1.\n * @param lineHeight - Line height multiplier. Defaults to 1.3.\n */\nexport function estimateTextHeight(fontSize: number, lineCount = 1, lineHeight = 1.3): number {\n return fontSize * lineHeight * lineCount;\n}\n","/**\n * Chrome layout computation.\n *\n * Takes a Chrome spec + resolved theme and produces a ResolvedChrome\n * with computed text positions, styles, and total chrome heights.\n */\n\nimport type {\n MeasureTextFn,\n ResolvedChrome,\n ResolvedChromeElement,\n TextStyle,\n} from '../types/layout';\nimport type { Chrome, ChromeText } from '../types/spec';\nimport type { ChromeDefaults, ResolvedTheme } from '../types/theme';\nimport { estimateTextHeight, estimateTextWidth } from './text-measure';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Normalize a chrome field to text + optional style and offset overrides. */\nfunction normalizeChromeText(\n value: string | ChromeText | undefined,\n): { text: string; style?: ChromeText['style']; offset?: ChromeText['offset'] } | null {\n if (value === undefined) return null;\n if (typeof value === 'string') return { text: value };\n return { text: value.text, style: value.style, offset: value.offset };\n}\n\n/** Build a TextStyle from chrome defaults + optional overrides. */\nfunction buildTextStyle(\n defaults: ChromeDefaults,\n fontFamily: string,\n textColor: string,\n overrides?: ChromeText['style'],\n): TextStyle {\n return {\n fontFamily: overrides?.fontFamily ?? fontFamily,\n fontSize: overrides?.fontSize ?? defaults.fontSize,\n fontWeight: overrides?.fontWeight ?? defaults.fontWeight,\n fill: overrides?.color ?? textColor ?? defaults.color,\n lineHeight: defaults.lineHeight,\n textAnchor: 'start',\n dominantBaseline: 'hanging',\n };\n}\n\n/** Measure text width using the provided function or heuristic fallback. */\nfunction measureWidth(text: string, style: TextStyle, measureText?: MeasureTextFn): number {\n if (measureText) {\n return measureText(text, style.fontSize, style.fontWeight).width;\n }\n return estimateTextWidth(text, style.fontSize, style.fontWeight);\n}\n\n/**\n * Estimate how many lines text will wrap to, given a max width.\n * Returns at least 1.\n */\nfunction estimateLineCount(\n text: string,\n style: TextStyle,\n maxWidth: number,\n measureText?: MeasureTextFn,\n): number {\n const fullWidth = measureWidth(text, style, measureText);\n if (fullWidth <= maxWidth) return 1;\n return Math.ceil(fullWidth / maxWidth);\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute resolved chrome layout from a Chrome spec and resolved theme.\n *\n * Produces positioned text elements and total chrome heights (top and bottom).\n * Top chrome: title, subtitle. Bottom chrome: source, byline, footer.\n *\n * @param chrome - The Chrome spec from the user's VizSpec.\n * @param theme - The fully resolved theme.\n * @param width - Total available width in pixels.\n * @param measureText - Optional real text measurement function from the adapter.\n */\nexport function computeChrome(\n chrome: Chrome | undefined,\n theme: ResolvedTheme,\n width: number,\n measureText?: MeasureTextFn,\n): ResolvedChrome {\n if (!chrome) {\n return { topHeight: 0, bottomHeight: 0 };\n }\n\n const padding = theme.spacing.padding;\n const chromeGap = theme.spacing.chromeGap;\n const maxWidth = width - padding * 2;\n const fontFamily = theme.fonts.family;\n\n // Track vertical cursor for top elements\n let topY = padding;\n const topElements: Partial<Pick<ResolvedChrome, 'title' | 'subtitle'>> = {};\n\n // Title\n const titleNorm = normalizeChromeText(chrome.title);\n if (titleNorm) {\n const style = buildTextStyle(\n theme.chrome.title,\n fontFamily,\n theme.chrome.title.color,\n titleNorm.style,\n );\n const lineCount = estimateLineCount(titleNorm.text, style, maxWidth, measureText);\n const element: ResolvedChromeElement = {\n text: titleNorm.text,\n x: padding + (titleNorm.offset?.dx ?? 0),\n y: topY + (titleNorm.offset?.dy ?? 0),\n maxWidth,\n style,\n };\n topElements.title = element;\n topY += estimateTextHeight(style.fontSize, lineCount, style.lineHeight) + chromeGap;\n }\n\n // Subtitle\n const subtitleNorm = normalizeChromeText(chrome.subtitle);\n if (subtitleNorm) {\n const style = buildTextStyle(\n theme.chrome.subtitle,\n fontFamily,\n theme.chrome.subtitle.color,\n subtitleNorm.style,\n );\n const lineCount = estimateLineCount(subtitleNorm.text, style, maxWidth, measureText);\n const element: ResolvedChromeElement = {\n text: subtitleNorm.text,\n x: padding + (subtitleNorm.offset?.dx ?? 0),\n y: topY + (subtitleNorm.offset?.dy ?? 0),\n maxWidth,\n style,\n };\n topElements.subtitle = element;\n topY += estimateTextHeight(style.fontSize, lineCount, style.lineHeight) + chromeGap;\n }\n\n // Add chromeToChart gap if there are any top elements\n const hasTopChrome = titleNorm || subtitleNorm;\n const topHeight = hasTopChrome ? topY - padding + theme.spacing.chromeToChart - chromeGap : 0;\n\n // Bottom elements: source, byline, footer\n // We compute heights bottom-up but position them after knowing total\n const bottomElements: Partial<Pick<ResolvedChrome, 'source' | 'byline' | 'footer'>> = {};\n let bottomHeight = 0;\n\n const bottomItems: Array<{\n key: 'source' | 'byline' | 'footer';\n norm: { text: string; style?: ChromeText['style']; offset?: ChromeText['offset'] };\n defaults: ChromeDefaults;\n }> = [];\n\n const sourceNorm = normalizeChromeText(chrome.source);\n if (sourceNorm) {\n bottomItems.push({\n key: 'source',\n norm: sourceNorm,\n defaults: theme.chrome.source,\n });\n }\n\n const bylineNorm = normalizeChromeText(chrome.byline);\n if (bylineNorm) {\n bottomItems.push({\n key: 'byline',\n norm: bylineNorm,\n defaults: theme.chrome.byline,\n });\n }\n\n const footerNorm = normalizeChromeText(chrome.footer);\n if (footerNorm) {\n bottomItems.push({\n key: 'footer',\n norm: footerNorm,\n defaults: theme.chrome.footer,\n });\n }\n\n if (bottomItems.length > 0) {\n bottomHeight += theme.spacing.chartToFooter;\n\n for (const item of bottomItems) {\n const style = buildTextStyle(item.defaults, fontFamily, item.defaults.color, item.norm.style);\n const lineCount = estimateLineCount(item.norm.text, style, maxWidth, measureText);\n const height = estimateTextHeight(style.fontSize, lineCount, style.lineHeight);\n\n // y positions will be computed relative to the bottom of the\n // chart area by the engine. We store offsets from bottom start.\n bottomElements[item.key] = {\n text: item.norm.text,\n x: padding + (item.norm.offset?.dx ?? 0),\n y: bottomHeight + (item.norm.offset?.dy ?? 0), // offset from where bottom chrome starts\n maxWidth,\n style,\n };\n\n bottomHeight += height + chromeGap;\n }\n\n // Remove trailing gap\n bottomHeight -= chromeGap;\n // Add bottom padding\n bottomHeight += padding;\n }\n\n return {\n topHeight,\n bottomHeight,\n ...topElements,\n ...bottomElements,\n };\n}\n","/**\n * Responsive breakpoints and layout strategies.\n *\n * Three breakpoints based on container width:\n * - compact: < 400px (mobile, small embeds)\n * - medium: 400-700px (tablet, sidebars)\n * - full: > 700px (desktop, full-width)\n */\n\n// ---------------------------------------------------------------------------\n// Breakpoint type and detection\n// ---------------------------------------------------------------------------\n\n/** Responsive breakpoint based on container width. */\nexport type Breakpoint = 'compact' | 'medium' | 'full';\n\n/** Breakpoint thresholds in pixels. */\nexport const BREAKPOINT_COMPACT_MAX = 400;\nexport const BREAKPOINT_MEDIUM_MAX = 700;\n\n/**\n * Determine the breakpoint for a given container width.\n */\nexport function getBreakpoint(width: number): Breakpoint {\n if (width < BREAKPOINT_COMPACT_MAX) return 'compact';\n if (width <= BREAKPOINT_MEDIUM_MAX) return 'medium';\n return 'full';\n}\n\n// ---------------------------------------------------------------------------\n// Layout strategy\n// ---------------------------------------------------------------------------\n\n/** Label display mode at a given breakpoint. */\nexport type LabelMode = 'all' | 'important' | 'none';\n\n/** Legend position at a given breakpoint. */\nexport type LegendPosition = 'top' | 'right' | 'bottom' | 'bottom-right' | 'inline';\n\n/** Annotation position strategy. */\nexport type AnnotationPosition = 'inline' | 'tooltip-only';\n\n/** Axis label density (controls tick count reduction). */\nexport type AxisLabelDensity = 'full' | 'reduced' | 'minimal';\n\n/**\n * Layout strategy defining how the visualization adapts to available space.\n * Returned by getLayoutStrategy() based on the current breakpoint.\n */\nexport interface LayoutStrategy {\n /** How data labels are displayed. */\n labelMode: LabelMode;\n /** Where the legend is positioned. */\n legendPosition: LegendPosition;\n /** How annotations are displayed. */\n annotationPosition: AnnotationPosition;\n /** Axis tick density. */\n axisLabelDensity: AxisLabelDensity;\n}\n\n/**\n * Get the layout strategy for a given breakpoint.\n *\n * Compact: minimal chrome, no inline labels, legend on top, reduced axes.\n * Medium: moderate labels, legend on top, reduced axes.\n * Full: all labels, legend on right, full axes.\n */\nexport function getLayoutStrategy(breakpoint: Breakpoint): LayoutStrategy {\n switch (breakpoint) {\n case 'compact':\n return {\n labelMode: 'none',\n legendPosition: 'top',\n annotationPosition: 'tooltip-only',\n axisLabelDensity: 'minimal',\n };\n case 'medium':\n return {\n labelMode: 'important',\n legendPosition: 'top',\n annotationPosition: 'inline',\n axisLabelDensity: 'reduced',\n };\n case 'full':\n return {\n labelMode: 'all',\n legendPosition: 'right',\n annotationPosition: 'inline',\n axisLabelDensity: 'full',\n };\n }\n}\n","/**\n * Label collision detection and resolution.\n *\n * Greedy algorithm: sort by priority, place in order, try offset\n * positions for conflicts, demote to tooltip-only if no position works.\n * Targeting ~60% of Infrographic quality for Phase 0.\n */\n\nimport type { Rect, ResolvedLabel, TextStyle } from '../types/layout';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Priority levels for label placement. Data labels win over annotations which win over axes. */\nexport type LabelPriority = 'data' | 'annotation' | 'axis';\n\n/** Priority sort order (lower = higher priority). */\nconst PRIORITY_ORDER: Record<LabelPriority, number> = {\n data: 0,\n annotation: 1,\n axis: 2,\n};\n\n/**\n * A label candidate for collision resolution.\n * The collision engine decides its final position and visibility.\n */\nexport interface LabelCandidate {\n /** The label text. */\n text: string;\n /** Preferred anchor position (before collision resolution). */\n anchorX: number;\n /** Preferred anchor position (before collision resolution). */\n anchorY: number;\n /** Estimated width of the label text. */\n width: number;\n /** Estimated height of the label text. */\n height: number;\n /** Label priority for collision resolution. */\n priority: LabelPriority;\n /** Text style to apply. */\n style: TextStyle;\n}\n\n// ---------------------------------------------------------------------------\n// Collision detection\n// ---------------------------------------------------------------------------\n\n/**\n * Detect AABB (axis-aligned bounding box) overlap between two rectangles.\n */\nexport function detectCollision(a: Rect, b: Rect): boolean {\n return a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y;\n}\n\n// ---------------------------------------------------------------------------\n// Offset strategies\n// ---------------------------------------------------------------------------\n\n/** Offsets to try when a label collides with an existing placement. */\nconst OFFSET_STRATEGIES = [\n { dx: 0, dy: 0 }, // original position\n { dx: 0, dy: -1.2 }, // above (factor of height)\n { dx: 0, dy: 1.2 }, // below\n { dx: 1.1, dy: 0 }, // right\n { dx: -1.1, dy: 0 }, // left\n { dx: 1.1, dy: -1.2 }, // upper-right\n { dx: -1.1, dy: -1.2 }, // upper-left\n];\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve label collisions using a greedy placement algorithm.\n *\n * Sorts labels by priority (data > annotation > axis), then places\n * each label at its preferred position. If it collides with an already-placed\n * label, tries offset positions. If no position works, the label is\n * demoted to tooltip-only (visible: false).\n *\n * @param labels - Array of label candidates to position.\n * @returns Array of resolved labels with computed positions and visibility.\n */\nexport function resolveCollisions(labels: LabelCandidate[]): ResolvedLabel[] {\n // Sort by priority (highest first)\n const sorted = [...labels].sort(\n (a, b) => PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority],\n );\n\n const placed: Rect[] = [];\n const results: ResolvedLabel[] = [];\n\n for (const label of sorted) {\n let bestRect: Rect | null = null;\n let bestX = label.anchorX;\n let bestY = label.anchorY;\n\n // Try each offset strategy\n for (const offset of OFFSET_STRATEGIES) {\n const candidateX = label.anchorX + offset.dx * label.width;\n const candidateY = label.anchorY + offset.dy * label.height;\n const candidateRect: Rect = {\n x: candidateX,\n y: candidateY,\n width: label.width,\n height: label.height,\n };\n\n const hasCollision = placed.some((p) => detectCollision(candidateRect, p));\n\n if (!hasCollision) {\n bestRect = candidateRect;\n bestX = candidateX;\n bestY = candidateY;\n break;\n }\n }\n\n if (bestRect) {\n placed.push(bestRect);\n const nudgeDx = bestX - label.anchorX;\n const nudgeDy = bestY - label.anchorY;\n const nudgeDist = Math.sqrt(nudgeDx * nudgeDx + nudgeDy * nudgeDy);\n // Only show a connector when the label is nudged far enough that the\n // reader can't tell which data point it belongs to. Short nudges between\n // adjacent series labels produce visual noise without aiding comprehension.\n const MIN_CONNECTOR_DISTANCE = 20;\n const needsConnector = nudgeDist >= MIN_CONNECTOR_DISTANCE;\n\n results.push({\n text: label.text,\n x: bestX,\n y: bestY,\n style: label.style,\n visible: true,\n connector: needsConnector\n ? {\n from: { x: bestX, y: bestY },\n to: { x: label.anchorX, y: label.anchorY },\n stroke: label.style.fill,\n style: 'straight' as const,\n }\n : undefined,\n });\n } else {\n // No position works, demote to tooltip-only\n results.push({\n text: label.text,\n x: label.anchorX,\n y: label.anchorY,\n style: label.style,\n visible: false,\n });\n }\n }\n\n return results;\n}\n","/**\n * Locale-aware number and date formatting utilities.\n *\n * Uses d3-format and d3-time-format for formatting,\n * with convenience wrappers for common patterns.\n */\n\nimport { format as d3Format } from 'd3-format';\nimport { timeFormat, utcFormat } from 'd3-time-format';\n\n// ---------------------------------------------------------------------------\n// Number formatting\n// ---------------------------------------------------------------------------\n\n/**\n * Format a number with locale-appropriate separators.\n *\n * Uses d3-format under the hood. Default format: comma-separated\n * with auto-precision (e.g. 1500000 -> \"1,500,000\").\n *\n * @param value - The number to format.\n * @param locale - Locale string (currently unused, reserved for i18n).\n */\nexport function formatNumber(value: number, _locale?: string): string {\n if (!Number.isFinite(value)) return String(value);\n // Auto-detect: use integer format for whole numbers, 2dp for decimals\n if (Number.isInteger(value)) {\n return d3Format(',')(value);\n }\n return d3Format(',.2f')(value);\n}\n\n// ---------------------------------------------------------------------------\n// Number abbreviation\n// ---------------------------------------------------------------------------\n\n/** Suffixes for abbreviated numbers. */\nconst ABBREVIATIONS: Array<{ threshold: number; suffix: string; divisor: number }> = [\n { threshold: 1_000_000_000_000, suffix: 'T', divisor: 1_000_000_000_000 },\n { threshold: 1_000_000_000, suffix: 'B', divisor: 1_000_000_000 },\n { threshold: 1_000_000, suffix: 'M', divisor: 1_000_000 },\n { threshold: 1_000, suffix: 'K', divisor: 1_000 },\n];\n\n/**\n * Abbreviate a large number with a suffix.\n *\n * Examples:\n * - 1500000 -> \"1.5M\"\n * - 2300 -> \"2.3K\"\n * - 42 -> \"42\"\n * - 1000000000 -> \"1B\"\n */\nexport function abbreviateNumber(value: number): string {\n if (!Number.isFinite(value)) return String(value);\n\n const absValue = Math.abs(value);\n const sign = value < 0 ? '-' : '';\n\n for (const { threshold, suffix, divisor } of ABBREVIATIONS) {\n if (absValue >= threshold) {\n const abbreviated = absValue / divisor;\n // Use .1f precision, drop trailing .0\n const formatted = abbreviated % 1 === 0 ? String(abbreviated) : d3Format('.1f')(abbreviated);\n return `${sign}${formatted}${suffix}`;\n }\n }\n\n return formatNumber(value);\n}\n\n// ---------------------------------------------------------------------------\n// d3-format with suffix support\n// ---------------------------------------------------------------------------\n\n/**\n * Regex that matches a valid d3-format specifier (with optional ~ trim flag)\n * followed by a literal suffix. The first capture group is the d3 format part,\n * the second is the trailing literal suffix (e.g. \"T\", \"pp\", etc.).\n *\n * Examples:\n * - \"$,.2~fT\" -> [\"$,.2~f\", \"T\"]\n * - \".0f%\" -> [\".0f\", \"%\"] (% here is literal, not d3 percent type)\n * - \"$,.0f\" -> no match (valid d3 format, no suffix)\n */\nconst D3_FORMAT_SUFFIX_RE = /^(.*~?[efgsrdxXobcnp%])(.+)$/;\n\n/**\n * Build a number formatter from a d3-format string, with support for a\n * trailing literal suffix that d3-format itself would reject.\n *\n * Returns null if the format string is falsy or unparseable.\n */\nexport function buildD3Formatter(formatStr: string | undefined): ((v: number) => string) | null {\n if (!formatStr) return null;\n\n try {\n return d3Format(formatStr);\n } catch {\n // If d3-format rejects it, try stripping a trailing literal suffix\n const m = formatStr.match(D3_FORMAT_SUFFIX_RE);\n if (m) {\n try {\n const fmt = d3Format(m[1]);\n const suffix = m[2];\n return (v: number) => fmt(v) + suffix;\n } catch {\n // Unparseable even after suffix stripping\n }\n }\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Date formatting\n// ---------------------------------------------------------------------------\n\n/** Granularity levels for date formatting. */\nexport type DateGranularity = 'year' | 'quarter' | 'month' | 'week' | 'day' | 'hour' | 'minute';\n\n/** Format strings for each granularity level. */\nconst GRANULARITY_FORMATS: Record<DateGranularity, string> = {\n year: '%Y',\n quarter: '', // Quarter is always special-cased in formatDate() below\n month: '%b %Y',\n week: '%b %d',\n day: '%b %d, %Y',\n hour: '%b %d %H:%M',\n minute: '%H:%M',\n};\n\n/**\n * Format a date value for display.\n *\n * @param value - Date object, ISO string, or timestamp number.\n * @param locale - Locale string (currently unused, reserved for i18n).\n * @param granularity - Time granularity for format selection.\n */\nexport function formatDate(\n value: Date | string | number,\n _locale?: string,\n granularity?: DateGranularity,\n): string {\n const date = value instanceof Date ? value : new Date(value);\n if (Number.isNaN(date.getTime())) return String(value);\n\n const gran = granularity ?? inferGranularity(date);\n\n // Special handling for quarter (not a d3 format token)\n if (gran === 'quarter') {\n const q = Math.ceil((date.getMonth() + 1) / 3);\n return `Q${q} ${date.getFullYear()}`;\n }\n\n const formatStr = GRANULARITY_FORMATS[gran];\n // Use UTC format for year/month/day to avoid timezone shifts\n if (['year', 'month', 'day'].includes(gran)) {\n return utcFormat(formatStr)(date);\n }\n return timeFormat(formatStr)(date);\n}\n\n/**\n * Infer the appropriate granularity from a date value.\n * If time components are all zero, assume day or higher.\n */\nfunction inferGranularity(date: Date): DateGranularity {\n if (date.getHours() !== 0 || date.getMinutes() !== 0) {\n return date.getMinutes() !== 0 ? 'minute' : 'hour';\n }\n if (date.getDate() !== 1) return 'day';\n if (date.getMonth() !== 0) return 'month';\n return 'year';\n}\n","/**\n * Automatic alt text generation for chart accessibility.\n *\n * Produces human-readable descriptions of chart content for screen readers\n * and a tabular fallback for data access.\n */\n\nimport type { ChartSpec, DataRow } from '../types/spec';\n\n// ---------------------------------------------------------------------------\n// Alt text generation\n// ---------------------------------------------------------------------------\n\n/** Friendly display names for chart types. */\nconst CHART_TYPE_NAMES: Record<string, string> = {\n line: 'Line chart',\n area: 'Area chart',\n bar: 'Bar chart',\n column: 'Column chart',\n pie: 'Pie chart',\n donut: 'Donut chart',\n dot: 'Dot plot',\n scatter: 'Scatter plot',\n};\n\n/**\n * Generate alt text describing a chart's content.\n *\n * Produces a description like:\n * \"Line chart showing GDP Growth Rate from 2020 to 2024 with 2 series (US, UK)\"\n *\n * @param spec - The chart spec.\n * @param data - The data array.\n */\nexport function generateAltText(spec: ChartSpec, data: DataRow[]): string {\n const chartName = CHART_TYPE_NAMES[spec.type] ?? `${spec.type} chart`;\n const parts: string[] = [chartName];\n\n // Add title context if present\n const title = spec.chrome?.title;\n if (title) {\n const titleText = typeof title === 'string' ? title : title.text;\n parts.push(`showing ${titleText}`);\n }\n\n // Describe the data range\n if (spec.encoding.x && data.length > 0) {\n const field = spec.encoding.x.field;\n const values = data.map((d) => d[field]).filter((v) => v != null);\n\n if (values.length > 0) {\n if (spec.encoding.x.type === 'temporal') {\n const dates = values.map((v) => (v instanceof Date ? v : new Date(String(v))));\n const validDates = dates.filter((d) => !Number.isNaN(d.getTime()));\n if (validDates.length >= 2) {\n validDates.sort((a, b) => a.getTime() - b.getTime());\n const first = validDates[0].getUTCFullYear();\n const last = validDates[validDates.length - 1].getUTCFullYear();\n if (first !== last) {\n parts.push(`from ${first} to ${last}`);\n }\n }\n } else if (spec.encoding.x.type === 'nominal' || spec.encoding.x.type === 'ordinal') {\n const uniqueValues = [...new Set(values.map(String))];\n parts.push(`across ${uniqueValues.length} categories`);\n }\n }\n }\n\n // Describe series if color encoding is present\n if (spec.encoding.color && data.length > 0) {\n const colorField = spec.encoding.color.field;\n const uniqueSeries = [...new Set(data.map((d) => String(d[colorField])).filter(Boolean))];\n if (uniqueSeries.length > 0) {\n parts.push(`with ${uniqueSeries.length} series (${uniqueSeries.join(', ')})`);\n }\n }\n\n // Add data point count\n parts.push(`(${data.length} data points)`);\n\n return parts.join(' ');\n}\n\n// ---------------------------------------------------------------------------\n// Data table fallback\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a tabular data fallback for screen readers.\n *\n * Returns a 2D array where the first row is headers and subsequent\n * rows are data values. Only includes fields referenced in the encoding.\n *\n * @param spec - The chart spec.\n * @param data - The data array.\n */\nexport function generateDataTable(spec: ChartSpec, data: DataRow[]): unknown[][] {\n // Collect fields from encoding\n const fields: string[] = [];\n const encoding = spec.encoding;\n\n if (encoding.x) fields.push(encoding.x.field);\n if (encoding.y) fields.push(encoding.y.field);\n if (encoding.color) fields.push(encoding.color.field);\n if (encoding.size) fields.push(encoding.size.field);\n\n // Deduplicate\n const uniqueFields = [...new Set(fields)];\n\n if (uniqueFields.length === 0) return [];\n\n // Header row\n const headers = uniqueFields;\n\n // Data rows\n const rows = data.map((row) => uniqueFields.map((field) => row[field] ?? ''));\n\n return [headers, ...rows];\n}\n","/**\n * ARIA label generation for individual marks.\n *\n * Produces per-mark labels for screen reader navigation, enabling\n * users to explore data points individually.\n */\n\nimport type { Mark } from '../types/layout';\n\n/**\n * Generate ARIA labels for a set of marks.\n *\n * Returns a Map keyed by a mark identifier (index-based) with\n * descriptive labels like \"Data point: US GDP 42 in 2020-01\".\n *\n * @param marks - Array of mark objects from the compiled chart layout.\n */\nexport function generateAriaLabels(marks: Mark[]): Map<string, string> {\n const labels = new Map<string, string>();\n\n for (let i = 0; i < marks.length; i++) {\n const mark = marks[i];\n const key = `mark-${i}`;\n\n switch (mark.type) {\n case 'line': {\n const series = mark.seriesKey ?? 'Series';\n const pointCount = mark.points.length;\n labels.set(key, `Line series: ${series} with ${pointCount} points`);\n break;\n }\n\n case 'area': {\n const series = mark.seriesKey ?? 'Area';\n labels.set(key, `Area series: ${series}`);\n break;\n }\n\n case 'rect': {\n const dataEntries = Object.entries(mark.data).filter(([k]) => !k.startsWith('_'));\n const description = dataEntries.map(([k, v]) => `${k}: ${formatValue(v)}`).join(', ');\n labels.set(key, `Data point: ${description}`);\n break;\n }\n\n case 'arc': {\n const dataEntries = Object.entries(mark.data).filter(([k]) => !k.startsWith('_'));\n const description = dataEntries.map(([k, v]) => `${k}: ${formatValue(v)}`).join(', ');\n labels.set(key, `Slice: ${description}`);\n break;\n }\n\n case 'point': {\n const dataEntries = Object.entries(mark.data).filter(([k]) => !k.startsWith('_'));\n const description = dataEntries.map(([k, v]) => `${k}: ${formatValue(v)}`).join(', ');\n labels.set(key, `Data point: ${description}`);\n break;\n }\n }\n }\n\n return labels;\n}\n\n/** Format a data value for use in an ARIA label. */\nfunction formatValue(value: unknown): string {\n if (value == null) return 'N/A';\n if (value instanceof Date) return value.toISOString().slice(0, 10);\n if (typeof value === 'number') {\n return Number.isInteger(value) ? String(value) : value.toFixed(2);\n }\n return String(value);\n}\n","/**\n * Spec construction helpers: typed builder functions for common chart types.\n *\n * These builders reduce boilerplate when creating specs programmatically.\n * They accept field names as strings (simple case) or full EncodingChannel\n * objects (when you need to customize type, aggregate, axis, or scale).\n *\n * Type inference: when a string field name is provided, the builder samples\n * data values to infer the encoding type (quantitative, temporal, nominal).\n */\n\nimport type {\n Annotation,\n ChartSpec,\n ChartType,\n Chrome,\n DarkMode,\n DataRow,\n Encoding,\n EncodingChannel,\n FieldType,\n TableSpec,\n ThemeConfig,\n} from '../types/spec';\nimport type { ColumnConfig } from '../types/table';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** A field reference: either a plain string (field name) or a full EncodingChannel. */\nexport type FieldRef = string | EncodingChannel;\n\n/** Common options shared by all chart builder functions. */\nexport interface ChartBuilderOptions {\n /** Color encoding: field name or full channel config for series differentiation. */\n color?: FieldRef;\n /** Size encoding: field name or full channel config. */\n size?: FieldRef;\n /** Editorial chrome (title, subtitle, source, etc.). */\n chrome?: Chrome;\n /** Data annotations. */\n annotations?: Annotation[];\n /** Whether the chart adapts to container width. Defaults to true. */\n responsive?: boolean;\n /** Theme configuration overrides. */\n theme?: ThemeConfig;\n /** Dark mode behavior. */\n darkMode?: DarkMode;\n}\n\n/** Options for the dataTable builder. */\nexport interface TableBuilderOptions {\n /** Column definitions. Auto-generated from data keys if omitted. */\n columns?: ColumnConfig[];\n /** Field to use as a unique row identifier. */\n rowKey?: string;\n /** Editorial chrome. */\n chrome?: Chrome;\n /** Theme configuration overrides. */\n theme?: ThemeConfig;\n /** Dark mode behavior. */\n darkMode?: DarkMode;\n /** Enable client-side search/filter. */\n search?: boolean;\n /** Pagination configuration. */\n pagination?: boolean | { pageSize: number };\n /** Stick the first column during horizontal scroll. */\n stickyFirstColumn?: boolean;\n /** Compact mode. */\n compact?: boolean;\n /** Whether the table adapts to container width. */\n responsive?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Type inference\n// ---------------------------------------------------------------------------\n\n/** ISO 8601 date patterns we recognize for temporal inference. */\nconst ISO_DATE_RE = /^\\d{4}(-\\d{2}(-\\d{2}(T\\d{2}(:\\d{2}(:\\d{2})?)?)?)?)?$/;\n\n/**\n * Infer the encoding field type from data values.\n *\n * Samples up to 20 values from the data array for the given field.\n * - If all sampled values are numbers (or null/undefined), returns \"quantitative\".\n * - If all sampled string values match ISO date patterns, returns \"temporal\".\n * - Otherwise returns \"nominal\".\n */\nexport function inferFieldType(data: DataRow[], field: string): FieldType {\n const sampleSize = Math.min(data.length, 20);\n let hasNumber = false;\n let hasDateString = false;\n let hasOtherString = false;\n\n for (let i = 0; i < sampleSize; i++) {\n const value = data[i][field];\n\n // Skip null/undefined\n if (value == null) continue;\n\n if (typeof value === 'number') {\n hasNumber = true;\n } else if (typeof value === 'string') {\n if (ISO_DATE_RE.test(value) && !Number.isNaN(Date.parse(value))) {\n hasDateString = true;\n } else {\n hasOtherString = true;\n }\n } else if (value instanceof Date) {\n hasDateString = true;\n } else {\n hasOtherString = true;\n }\n }\n\n // Numbers-only: quantitative\n if (hasNumber && !hasDateString && !hasOtherString) return 'quantitative';\n // Date strings/Date objects only: temporal\n if (hasDateString && !hasNumber && !hasOtherString) return 'temporal';\n // Everything else: nominal\n return 'nominal';\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a FieldRef into a full EncodingChannel.\n * If the ref is a string, infer the type from data.\n */\nfunction resolveField(ref: FieldRef, data: DataRow[]): EncodingChannel {\n if (typeof ref === 'string') {\n return { field: ref, type: inferFieldType(data, ref) };\n }\n return ref;\n}\n\n/** Build the encoding object from resolved channels. */\nfunction buildEncoding(\n channels: { x?: EncodingChannel; y?: EncodingChannel },\n options?: ChartBuilderOptions,\n data?: DataRow[],\n): Encoding {\n const encoding: Encoding = { ...channels };\n if (options?.color && data) {\n encoding.color = resolveField(options.color, data);\n }\n if (options?.size && data) {\n encoding.size = resolveField(options.size, data);\n }\n return encoding;\n}\n\n/** Build a ChartSpec from the resolved pieces. */\nfunction buildChartSpec(\n type: ChartType,\n data: DataRow[],\n encoding: Encoding,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const spec: ChartSpec = { type, data, encoding };\n if (options?.chrome) spec.chrome = options.chrome;\n if (options?.annotations) spec.annotations = options.annotations;\n if (options?.responsive !== undefined) spec.responsive = options.responsive;\n if (options?.theme) spec.theme = options.theme;\n if (options?.darkMode) spec.darkMode = options.darkMode;\n return spec;\n}\n\n// ---------------------------------------------------------------------------\n// Builder functions\n// ---------------------------------------------------------------------------\n\n/**\n * Create a line chart spec.\n *\n * @param data - Array of data rows.\n * @param x - X-axis field (typically temporal or ordinal).\n * @param y - Y-axis field (typically quantitative).\n * @param options - Optional color, size, chrome, annotations, theme, etc.\n */\nexport function lineChart(\n data: DataRow[],\n x: FieldRef,\n y: FieldRef,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const xChannel = resolveField(x, data);\n const yChannel = resolveField(y, data);\n const encoding = buildEncoding({ x: xChannel, y: yChannel }, options, data);\n return buildChartSpec('line', data, encoding, options);\n}\n\n/**\n * Create a bar chart spec (horizontal bars).\n *\n * Convention: category goes on y-axis, value on x-axis.\n * The `category` param maps to y, `value` maps to x.\n *\n * @param data - Array of data rows.\n * @param category - Category field (y-axis, nominal/ordinal).\n * @param value - Value field (x-axis, quantitative).\n * @param options - Optional color, size, chrome, annotations, theme, etc.\n */\nexport function barChart(\n data: DataRow[],\n category: FieldRef,\n value: FieldRef,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const categoryChannel = resolveField(category, data);\n const valueChannel = resolveField(value, data);\n\n // Bar charts: category on y, value on x\n const encoding = buildEncoding({ x: valueChannel, y: categoryChannel }, options, data);\n return buildChartSpec('bar', data, encoding, options);\n}\n\n/**\n * Create a column chart spec (vertical columns).\n *\n * @param data - Array of data rows.\n * @param x - X-axis field (category or temporal).\n * @param y - Y-axis field (quantitative value).\n * @param options - Optional color, size, chrome, annotations, theme, etc.\n */\nexport function columnChart(\n data: DataRow[],\n x: FieldRef,\n y: FieldRef,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const xChannel = resolveField(x, data);\n const yChannel = resolveField(y, data);\n const encoding = buildEncoding({ x: xChannel, y: yChannel }, options, data);\n return buildChartSpec('column', data, encoding, options);\n}\n\n/**\n * Create a pie chart spec.\n *\n * Convention: category maps to the color channel, value maps to y.\n * Pie charts have no x-axis.\n *\n * @param data - Array of data rows.\n * @param category - Category field (color channel, nominal).\n * @param value - Value field (y channel, quantitative).\n * @param options - Optional chrome, annotations, theme, etc.\n * Note: color option is ignored since category is used for color.\n */\nexport function pieChart(\n data: DataRow[],\n category: FieldRef,\n value: FieldRef,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const categoryChannel = resolveField(category, data);\n const valueChannel = resolveField(value, data);\n\n // Pie charts: value on y, category on color (no x-axis)\n const encoding: Encoding = {\n y: valueChannel,\n color: categoryChannel,\n };\n if (options?.size && data) {\n encoding.size = resolveField(options.size, data);\n }\n\n return buildChartSpec('pie', data, encoding, options);\n}\n\n/**\n * Create an area chart spec.\n *\n * @param data - Array of data rows.\n * @param x - X-axis field (typically temporal or ordinal).\n * @param y - Y-axis field (typically quantitative).\n * @param options - Optional color, size, chrome, annotations, theme, etc.\n */\nexport function areaChart(\n data: DataRow[],\n x: FieldRef,\n y: FieldRef,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const xChannel = resolveField(x, data);\n const yChannel = resolveField(y, data);\n const encoding = buildEncoding({ x: xChannel, y: yChannel }, options, data);\n return buildChartSpec('area', data, encoding, options);\n}\n\n/**\n * Create a donut chart spec.\n *\n * Convention: category maps to the color channel, value maps to y.\n * Donut charts have no x-axis.\n *\n * @param data - Array of data rows.\n * @param category - Category field (color channel, nominal).\n * @param value - Value field (y channel, quantitative).\n * @param options - Optional chrome, annotations, theme, etc.\n * Note: color option is ignored since category is used for color.\n */\nexport function donutChart(\n data: DataRow[],\n category: FieldRef,\n value: FieldRef,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const categoryChannel = resolveField(category, data);\n const valueChannel = resolveField(value, data);\n\n const encoding: Encoding = {\n y: valueChannel,\n color: categoryChannel,\n };\n if (options?.size && data) {\n encoding.size = resolveField(options.size, data);\n }\n\n return buildChartSpec('donut', data, encoding, options);\n}\n\n/**\n * Create a dot chart spec (strip plot / dot plot).\n *\n * @param data - Array of data rows.\n * @param x - X-axis field (quantitative or temporal).\n * @param y - Y-axis field (nominal/categorical grouping).\n * @param options - Optional color, size, chrome, annotations, theme, etc.\n */\nexport function dotChart(\n data: DataRow[],\n x: FieldRef,\n y: FieldRef,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const xChannel = resolveField(x, data);\n const yChannel = resolveField(y, data);\n const encoding = buildEncoding({ x: xChannel, y: yChannel }, options, data);\n return buildChartSpec('dot', data, encoding, options);\n}\n\n/**\n * Create a scatter chart spec.\n *\n * @param data - Array of data rows.\n * @param x - X-axis field (quantitative).\n * @param y - Y-axis field (quantitative).\n * @param options - Optional color, size, chrome, annotations, theme, etc.\n */\nexport function scatterChart(\n data: DataRow[],\n x: FieldRef,\n y: FieldRef,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const xChannel = resolveField(x, data);\n const yChannel = resolveField(y, data);\n const encoding = buildEncoding({ x: xChannel, y: yChannel }, options, data);\n return buildChartSpec('scatter', data, encoding, options);\n}\n\n/**\n * Create a data table spec.\n *\n * If no columns are specified, auto-generates column configs from the\n * keys of the first data row.\n *\n * @param data - Array of data rows.\n * @param options - Column definitions, chrome, pagination, search, etc.\n */\nexport function dataTable(data: DataRow[], options?: TableBuilderOptions): TableSpec {\n // Auto-generate columns from data keys if not provided\n let columns = options?.columns;\n if (!columns && data.length > 0) {\n columns = Object.keys(data[0]).map((key): ColumnConfig => {\n // Infer alignment from data type\n const fieldType = inferFieldType(data, key);\n const align = fieldType === 'quantitative' ? ('right' as const) : ('left' as const);\n\n return {\n key,\n label: key,\n align,\n };\n });\n }\n\n const spec: TableSpec = {\n type: 'table',\n data,\n columns: columns ?? [],\n };\n\n if (options?.rowKey) spec.rowKey = options.rowKey;\n if (options?.chrome) spec.chrome = options.chrome;\n if (options?.theme) spec.theme = options.theme;\n if (options?.darkMode) spec.darkMode = options.darkMode;\n if (options?.search !== undefined) spec.search = options.search;\n if (options?.pagination !== undefined) spec.pagination = options.pagination;\n if (options?.stickyFirstColumn !== undefined) spec.stickyFirstColumn = options.stickyFirstColumn;\n if (options?.compact !== undefined) spec.compact = options.compact;\n if (options?.responsive !== undefined) spec.responsive = options.responsive;\n\n return spec;\n}\n"],"mappings":"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","names":["rgb","rgb","rgb","relativeLuminance"]}
|
|
1
|
+
{"version":3,"sources":["../src/types/encoding.ts","../src/types/spec.ts","../../../node_modules/.bun/d3-color@3.1.0/node_modules/d3-color/src/define.js","../../../node_modules/.bun/d3-color@3.1.0/node_modules/d3-color/src/color.js","../src/colors/colorblind.ts","../src/colors/contrast.ts","../src/colors/palettes.ts","../src/theme/dark-mode.ts","../src/theme/defaults.ts","../src/theme/resolve.ts","../src/layout/text-measure.ts","../src/layout/chrome.ts","../src/responsive/breakpoints.ts","../src/labels/collision.ts","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatDecimal.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/exponent.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatGroup.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatNumerals.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatSpecifier.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatTrim.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatPrefixAuto.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatRounded.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatTypes.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/identity.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/locale.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/defaultLocale.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/interval.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/duration.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/day.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/week.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/year.js","../../../node_modules/.bun/d3-time-format@4.1.0/node_modules/d3-time-format/src/locale.js","../../../node_modules/.bun/d3-time-format@4.1.0/node_modules/d3-time-format/src/defaultLocale.js","../src/locale/format.ts","../src/accessibility/alt-text.ts","../src/accessibility/aria.ts","../src/helpers/spec-builders.ts"],"sourcesContent":["/**\n * Per-chart-type encoding validation rules.\n *\n * Defines which encoding channels are required vs optional for each chart type.\n * The engine compiler uses these rules to validate specs at runtime (TypeScript\n * catches compile-time errors; these catch runtime JSON from Claude or APIs).\n */\n\nimport type { ChartType, FieldType } from './spec';\n\n// ---------------------------------------------------------------------------\n// Encoding rule types\n// ---------------------------------------------------------------------------\n\n/** Constraint on what field types are valid for an encoding channel. */\nexport interface ChannelRule {\n /** Whether this channel is required for the chart type. */\n required: boolean;\n /** Allowed field types. If empty, any field type is accepted. */\n allowedTypes: FieldType[];\n}\n\n/** Encoding rules for a single chart type: which channels are required/optional. */\nexport interface EncodingRule {\n x: ChannelRule;\n y: ChannelRule;\n color: ChannelRule;\n size: ChannelRule;\n detail: ChannelRule;\n}\n\n// ---------------------------------------------------------------------------\n// Chart encoding rules\n// ---------------------------------------------------------------------------\n\n/** Helper to create a required channel rule. */\nfunction required(...types: FieldType[]): ChannelRule {\n return { required: true, allowedTypes: types };\n}\n\n/** Helper to create an optional channel rule. */\nfunction optional(...types: FieldType[]): ChannelRule {\n return { required: false, allowedTypes: types };\n}\n\n/**\n * Encoding rules per chart type.\n *\n * Defines which channels are required and what field types they accept.\n * The compiler uses this map to validate user specs at runtime.\n *\n * Key design decisions:\n * - line/area: x is temporal/ordinal (the axis), y is quantitative (the value)\n * - bar: horizontal bars, so y is the category axis, x is the value\n * - column: vertical columns, so x is the category axis, y is the value\n * - pie/donut: no x axis; y is the value (quantitative), color is the category\n * - dot: y is the category, x is quantitative\n * - scatter: both axes are quantitative\n */\nexport const CHART_ENCODING_RULES: Record<ChartType, EncodingRule> = {\n line: {\n x: required('temporal', 'ordinal'),\n y: required('quantitative'),\n color: optional('nominal', 'ordinal'),\n size: optional('quantitative'),\n detail: optional('nominal'),\n },\n area: {\n x: required('temporal', 'ordinal'),\n y: required('quantitative'),\n color: optional('nominal', 'ordinal'),\n size: optional('quantitative'),\n detail: optional('nominal'),\n },\n bar: {\n x: required('quantitative'),\n y: required('nominal', 'ordinal'),\n color: optional('nominal', 'ordinal', 'quantitative'),\n size: optional('quantitative'),\n detail: optional('nominal'),\n },\n column: {\n x: required('nominal', 'ordinal', 'temporal'),\n y: required('quantitative'),\n color: optional('nominal', 'ordinal', 'quantitative'),\n size: optional('quantitative'),\n detail: optional('nominal'),\n },\n pie: {\n x: optional(),\n y: required('quantitative'),\n color: required('nominal', 'ordinal'),\n size: optional('quantitative'),\n detail: optional('nominal'),\n },\n donut: {\n x: optional(),\n y: required('quantitative'),\n color: required('nominal', 'ordinal'),\n size: optional('quantitative'),\n detail: optional('nominal'),\n },\n dot: {\n x: required('quantitative'),\n y: required('nominal', 'ordinal'),\n color: optional('nominal', 'ordinal'),\n size: optional('quantitative'),\n detail: optional('nominal'),\n },\n scatter: {\n x: required('quantitative'),\n y: required('quantitative'),\n color: optional('nominal', 'ordinal'),\n size: optional('quantitative'),\n detail: optional('nominal'),\n },\n};\n\n// ---------------------------------------------------------------------------\n// Graph encoding rules\n// ---------------------------------------------------------------------------\n\n/** Encoding rule for a single graph visual channel. */\nexport interface GraphChannelRule {\n /** Whether this channel is required. */\n required: boolean;\n /** Allowed field types. Empty means any type. */\n allowedTypes: FieldType[];\n}\n\n/**\n * Encoding rules for graph visualizations.\n *\n * All graph encoding channels are optional since a graph can be rendered\n * with just nodes and edges (uniform appearance). Encoding channels add\n * visual differentiation based on data fields.\n */\nexport const GRAPH_ENCODING_RULES: Record<string, GraphChannelRule> = {\n nodeColor: { required: false, allowedTypes: ['nominal', 'ordinal'] },\n nodeSize: { required: false, allowedTypes: ['quantitative'] },\n edgeColor: { required: false, allowedTypes: ['nominal', 'ordinal'] },\n edgeWidth: { required: false, allowedTypes: ['quantitative'] },\n nodeLabel: { required: false, allowedTypes: [] },\n};\n","/**\n * Spec types: the user-facing input contract.\n *\n * These types define what a user (or Claude) writes to describe a visualization.\n * The engine validates, normalizes, and compiles specs into layout objects.\n *\n * Encoding vocabulary follows Vega-Lite conventions (field/type/aggregate)\n * with editorial extensions for chrome, annotations, responsive, and dark mode.\n */\n\n// Re-import for use in LegendConfig and overrides (avoids circular by importing from sibling)\nimport type { Breakpoint, LegendPosition } from '../responsive/breakpoints';\nimport type { ColumnConfig } from './table';\n\n// ---------------------------------------------------------------------------\n// Chart type union\n// ---------------------------------------------------------------------------\n\n/** Supported chart types. Graph is separate since it uses nodes/edges, not data + encoding. */\nexport type ChartType = 'line' | 'area' | 'bar' | 'column' | 'pie' | 'donut' | 'dot' | 'scatter';\n\n// ---------------------------------------------------------------------------\n// Encoding\n// ---------------------------------------------------------------------------\n\n/** Data field type, following Vega-Lite conventions. */\nexport type FieldType = 'quantitative' | 'temporal' | 'nominal' | 'ordinal';\n\n/** Aggregate function applied to a field before encoding. */\nexport type AggregateOp = 'count' | 'sum' | 'mean' | 'median' | 'min' | 'max';\n\n/** Axis configuration for an encoding channel. */\nexport interface AxisConfig {\n /** Axis label text. If omitted, the field name is used. */\n label?: string;\n /** Number format string (d3-format). e.g. \",.0f\" for comma-separated integers. */\n format?: string;\n /** Override tick count. Engine picks a sensible default if omitted. */\n tickCount?: number;\n /** Whether to show gridlines for this axis. */\n grid?: boolean;\n /** Rotation angle in degrees for tick labels. Common values: -45, -90, 90. */\n tickAngle?: number;\n}\n\n/** Scale configuration for an encoding channel. */\nexport interface ScaleConfig {\n /** Explicit domain override. Auto-derived from data if omitted. */\n domain?: [number, number] | string[];\n /** Scale type override. Usually inferred from field type. */\n type?: 'linear' | 'log' | 'time' | 'band' | 'point' | 'ordinal';\n /** Whether to nice-ify the domain for clean tick values. Defaults to true. */\n nice?: boolean;\n /** Whether the domain should include zero. Defaults to true for quantitative. */\n zero?: boolean;\n /** When true and domain is set, filter out data rows with values outside the domain range. */\n clip?: boolean;\n}\n\n/**\n * A single encoding channel mapping a data field to a visual property.\n *\n * Follows the Vega-Lite encoding model: field identifies the column,\n * type determines how the engine interprets values, aggregate applies\n * a transformation before encoding.\n */\nexport interface EncodingChannel {\n /** Data field name (column in the data array). */\n field: string;\n /**\n * How to interpret the field values.\n * - quantitative: continuous numbers (scale: linear)\n * - temporal: dates/times (scale: time)\n * - nominal: unordered categories (scale: ordinal)\n * - ordinal: ordered categories (scale: ordinal)\n */\n type: FieldType;\n /** Optional aggregate to apply before encoding. */\n aggregate?: AggregateOp;\n /** Axis configuration. Only relevant for x and y channels. */\n axis?: AxisConfig;\n /** Scale configuration. */\n scale?: ScaleConfig;\n}\n\n/**\n * Encoding object mapping visual channels to data fields.\n * Which channels are required depends on the chart type.\n * See ChartEncodingRules in encoding.ts for per-type requirements.\n */\nexport interface Encoding {\n /** Horizontal position channel. */\n x?: EncodingChannel;\n /** Vertical position channel. */\n y?: EncodingChannel;\n /** Color channel (series differentiation or heatmap). */\n color?: EncodingChannel;\n /** Size channel (bubble charts, dot plots). */\n size?: EncodingChannel;\n /** Detail channel (group without encoding to a visual property). */\n detail?: EncodingChannel;\n}\n\n// ---------------------------------------------------------------------------\n// Graph-specific encoding\n// ---------------------------------------------------------------------------\n\n/** Encoding channel for graph nodes and edges. Same structure as EncodingChannel. */\nexport interface GraphEncodingChannel {\n /** Data field name on the node/edge object. */\n field: string;\n /** How to interpret the field values. */\n type?: FieldType;\n}\n\n/** Graph-specific encoding mapping visual properties to node/edge data fields. */\nexport interface GraphEncoding {\n /** Color mapping for nodes. */\n nodeColor?: GraphEncodingChannel;\n /** Size mapping for nodes. */\n nodeSize?: GraphEncodingChannel;\n /** Color mapping for edges. */\n edgeColor?: GraphEncodingChannel;\n /** Width mapping for edges. */\n edgeWidth?: GraphEncodingChannel;\n /** Style mapping for edges (solid, dashed, dotted). */\n edgeStyle?: GraphEncodingChannel;\n /** Label field for nodes. */\n nodeLabel?: GraphEncodingChannel;\n}\n\n/** Layout algorithm for graph visualization. */\nexport interface GraphLayoutConfig {\n /** Layout algorithm type. */\n type: 'force' | 'radial' | 'hierarchical';\n /** Optional clustering configuration. */\n clustering?: {\n /** Field to group nodes by for cluster forces. */\n field: string;\n };\n /** Charge strength for force layout. Negative values create repulsion. */\n chargeStrength?: number;\n /** Target distance between linked nodes. */\n linkDistance?: number;\n /** Extra px added to node radius for collision detection (default 2). */\n collisionPadding?: number;\n /** Link force strength override. */\n linkStrength?: number;\n /** Whether to apply center force (default true). */\n centerForce?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Chrome (editorial text elements)\n// ---------------------------------------------------------------------------\n\n/** Style overrides for a chrome text element. */\nexport interface ChromeTextStyle {\n /** Font size in pixels. */\n fontSize?: number;\n /** Font weight (400 = normal, 600 = semibold, 700 = bold). */\n fontWeight?: number;\n /** Font family override. */\n fontFamily?: string;\n /** Text color (CSS color string). */\n color?: string;\n}\n\n/** A chrome text element with optional style overrides. */\nexport interface ChromeText {\n /** The text content to display. */\n text: string;\n /** Optional style overrides. Theme defaults are used for any omitted property. */\n style?: ChromeTextStyle;\n /** Pixel offset for fine-tuning position. */\n offset?: AnnotationOffset;\n}\n\n/**\n * Editorial chrome elements: title, subtitle, source attribution, byline, footer.\n * These are first-class structural elements, not string-only afterthoughts.\n * Each element can be a simple string or a ChromeText object with style overrides.\n */\nexport interface Chrome {\n /** Main title displayed above the visualization. */\n title?: string | ChromeText;\n /** Subtitle displayed below the title, typically providing context. */\n subtitle?: string | ChromeText;\n /** Data source attribution, displayed below the chart area. */\n source?: string | ChromeText;\n /** Author or organization byline. */\n byline?: string | ChromeText;\n /** Footer text, displayed at the very bottom. */\n footer?: string | ChromeText;\n}\n\n// ---------------------------------------------------------------------------\n// Annotations\n// ---------------------------------------------------------------------------\n\n/** Pixel offset for fine-grained annotation positioning. */\nexport interface AnnotationOffset {\n /** Horizontal pixel offset. */\n dx?: number;\n /** Vertical pixel offset. */\n dy?: number;\n}\n\n/** Anchor direction for annotation label placement relative to the data point. */\nexport type AnnotationAnchor = 'top' | 'bottom' | 'left' | 'right' | 'auto';\n\n/** Base properties shared by all annotation types. */\ninterface AnnotationBase {\n /** Human-readable label for the annotation. */\n label?: string;\n /** Fill color for the annotation element. */\n fill?: string;\n /** Stroke color for the annotation element. */\n stroke?: string;\n /** Opacity from 0 to 1. */\n opacity?: number;\n /** Z-index for render ordering. Higher values render on top. */\n zIndex?: number;\n}\n\n/**\n * Text annotation positioned at a data coordinate.\n * Shows a callout label at a specific point in the chart.\n */\nexport interface TextAnnotation extends AnnotationBase {\n type: 'text';\n /** X-axis data value or position. */\n x: string | number;\n /** Y-axis data value or position. */\n y: string | number;\n /** The annotation text. Required for text annotations. */\n text: string;\n /** Font size override. */\n fontSize?: number;\n /** Font weight override. */\n fontWeight?: number;\n /** Pixel offset from the computed position. */\n offset?: AnnotationOffset;\n /** Anchor direction for label placement relative to the data point. */\n anchor?: AnnotationAnchor;\n /**\n * Connector from label to anchor point.\n * - `true` (default): straight line\n * - `'curve'`: curved arrow with arrowhead\n * - `false`: no connector\n */\n connector?: boolean | 'curve';\n /** Per-endpoint offsets for the connector line. Allows fine-tuning where the connector starts and ends. */\n connectorOffset?: {\n /** Offset for the label-end of the connector. */\n from?: AnnotationOffset;\n /** Offset for the data-point-end of the connector. */\n to?: AnnotationOffset;\n };\n /** Background color behind the text. Useful for readability over chart lines. */\n background?: string;\n}\n\n/**\n * Range annotation highlighting a region of the chart.\n * Defined by x1/x2 (vertical band) or y1/y2 (horizontal band) or both (rectangle).\n */\nexport interface RangeAnnotation extends AnnotationBase {\n type: 'range';\n /** Start of the range on the x-axis. */\n x1?: string | number;\n /** End of the range on the x-axis. */\n x2?: string | number;\n /** Start of the range on the y-axis. */\n y1?: string | number;\n /** End of the range on the y-axis. */\n y2?: string | number;\n /** Pixel offset for the range label. */\n labelOffset?: AnnotationOffset;\n /** Anchor direction for the range label. */\n labelAnchor?: AnnotationAnchor;\n}\n\n/**\n * Reference line annotation: a horizontal or vertical line at a data value.\n * Useful for baselines (zero), targets, or thresholds.\n */\nexport interface RefLineAnnotation extends AnnotationBase {\n type: 'refline';\n /** X-axis value for a vertical reference line. */\n x?: string | number;\n /** Y-axis value for a horizontal reference line. */\n y?: string | number;\n /** Line style. */\n style?: 'solid' | 'dashed' | 'dotted';\n /** Line width in pixels. */\n strokeWidth?: number;\n /** Pixel offset for the reference line label. */\n labelOffset?: AnnotationOffset;\n /** Anchor direction for the reference line label. */\n labelAnchor?: AnnotationAnchor;\n}\n\n/** Discriminated union of all annotation types. */\nexport type Annotation = TextAnnotation | RangeAnnotation | RefLineAnnotation;\n\n// ---------------------------------------------------------------------------\n// Theme + Dark Mode\n// ---------------------------------------------------------------------------\n\n/**\n * Dark mode behavior.\n * - \"auto\": respect system preference (prefers-color-scheme)\n * - \"force\": always render in dark mode\n * - \"off\": always render in light mode (default)\n */\nexport type DarkMode = 'auto' | 'force' | 'off';\n\n/**\n * User-facing theme configuration for overriding defaults.\n * All fields are optional. The engine deep-merges these onto the default theme.\n */\nexport interface ThemeConfig {\n /**\n * Color palette overrides.\n * Pass a flat string[] as shorthand for categorical colors,\n * or an object for full control over categorical, sequential, diverging, etc.\n */\n colors?:\n | string[]\n | {\n /** Categorical palette for nominal data (array of CSS color strings). */\n categorical?: string[];\n /** Sequential palettes keyed by name. Each is an array of color stops. */\n sequential?: Record<string, string[]>;\n /** Diverging palettes keyed by name. Each is an array of color stops with a neutral midpoint. */\n diverging?: Record<string, string[]>;\n /** Background color. */\n background?: string;\n /** Default text color. */\n text?: string;\n /** Gridline color. */\n gridline?: string;\n /** Axis line and tick color. */\n axis?: string;\n };\n /** Font overrides. */\n fonts?: {\n /** Primary font family. */\n family?: string;\n /** Monospace font family (for tabular numbers). */\n mono?: string;\n };\n /** Spacing overrides in pixels. */\n spacing?: {\n /** Padding inside the chart container. */\n padding?: number;\n /** Gap between chrome elements (title to subtitle, etc.). */\n chromeGap?: number;\n };\n /** Border radius for chart container and tooltips. */\n borderRadius?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Label configuration\n// ---------------------------------------------------------------------------\n\n/**\n * Label density mode controlling how many data labels are shown.\n * - 'all': show every label, skip collision detection\n * - 'auto': show labels with collision detection (default)\n * - 'endpoints': show only first and last per series (useful for line charts)\n * - 'none': hide all labels (rely on tooltips and legend)\n */\nexport type LabelDensity = 'all' | 'auto' | 'endpoints' | 'none';\n\n/** Label display configuration for chart data labels. */\nexport interface LabelConfig {\n /** How many labels to show. Defaults to 'auto'. */\n density?: LabelDensity;\n /** Number format override for label values (d3-format string, e.g. \",.0f\"). */\n format?: string;\n /** Per-series pixel offsets for fine-tuning label positions, keyed by series name. */\n offsets?: Record<string, AnnotationOffset>;\n}\n\n// ---------------------------------------------------------------------------\n// Legend configuration\n// ---------------------------------------------------------------------------\n\n/** Legend display configuration. Overrides the responsive-default position. */\nexport interface LegendConfig {\n /** Override the legend position. If omitted, the responsive strategy decides. */\n position?: LegendPosition;\n /** Pixel offset for fine-tuning legend position. */\n offset?: AnnotationOffset;\n /** Whether to show the legend. Defaults to true. Set to false to hide. */\n show?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Spec types (the top-level discriminated union)\n// ---------------------------------------------------------------------------\n\n/** Data row: a plain object with string keys. */\nexport type DataRow = Record<string, unknown>;\n\n/** Per-series visual style overrides for line/area charts. */\nexport interface SeriesStyle {\n /** Line dash style. Defaults to 'solid'. */\n lineStyle?: 'solid' | 'dashed' | 'dotted';\n /** Whether to show data point markers. Defaults to true. */\n showPoints?: boolean;\n /** Stroke width override. */\n strokeWidth?: number;\n /** Opacity override (0-1). */\n opacity?: number;\n}\n\n/**\n * Breakpoint-conditional overrides for chart specs.\n *\n * Allows specifying different chrome, labels, legend, or annotations\n * per breakpoint. Merged shallowly into the base spec at compile time\n * when the container matches the breakpoint.\n */\nexport interface ChartSpecOverride {\n /** Override editorial chrome at this breakpoint. */\n chrome?: Chrome;\n /** Override label configuration at this breakpoint. */\n labels?: LabelConfig;\n /** Override legend configuration at this breakpoint. */\n legend?: LegendConfig;\n /** Override annotations at this breakpoint. */\n annotations?: Annotation[];\n}\n\n/**\n * Chart specification: the primary input for standard chart types.\n *\n * Combines a chart type with data, encoding channels, editorial chrome,\n * annotations, and configuration. The engine validates, normalizes, and\n * compiles this into a ChartLayout.\n */\nexport interface ChartSpec {\n /** The chart type to render. */\n type: ChartType;\n /** Data array: each element is a row with field values. */\n data: DataRow[];\n /** Encoding mapping data fields to visual channels. */\n encoding: Encoding;\n /** Editorial chrome (title, subtitle, source, etc.). */\n chrome?: Chrome;\n /** Data annotations (text callouts, highlighted ranges, reference lines). */\n annotations?: Annotation[];\n /** Label display configuration (density, format). */\n labels?: LabelConfig;\n /** Legend display configuration (position override). */\n legend?: LegendConfig;\n /** Whether the chart adapts to container width. Defaults to true. */\n responsive?: boolean;\n /** Theme configuration overrides. */\n theme?: ThemeConfig;\n /** Dark mode behavior. Defaults to \"off\". */\n darkMode?: DarkMode;\n /** Series names to hide from rendering. Hidden series remain in the legend but are visually dimmed. */\n hiddenSeries?: string[];\n /** Per-series visual overrides, keyed by series name (the color field value). */\n seriesStyles?: Record<string, SeriesStyle>;\n /**\n * Breakpoint-conditional overrides. Keys are breakpoint names.\n * At compile time, if the container matches a breakpoint, its overrides\n * are shallow-merged into the spec before layout computation.\n */\n overrides?: Partial<Record<Breakpoint, ChartSpecOverride>>;\n}\n\n/**\n * Table specification: input for data table visualizations.\n *\n * Tables are a visualization type, not just an HTML grid. They support\n * heatmap coloring, inline sparklines, sorted columns, search, and pagination.\n */\nexport interface TableSpec {\n /** Discriminant: always \"table\". */\n type: 'table';\n /** Data array: each element is a row. */\n data: DataRow[];\n /** Column definitions controlling display, sorting, formatting, and mini-charts. */\n columns: ColumnConfig[];\n /** Optional field to use as a unique row identifier. */\n rowKey?: string;\n /** Editorial chrome. */\n chrome?: Chrome;\n /** Theme configuration overrides. */\n theme?: ThemeConfig;\n /** Dark mode behavior. */\n darkMode?: DarkMode;\n /** Enable client-side search/filter. */\n search?: boolean;\n /** Pagination configuration. True for defaults, or an object with pageSize. */\n pagination?: boolean | { pageSize: number };\n /** Whether to stick the first column during horizontal scroll. */\n stickyFirstColumn?: boolean;\n /** Compact mode: reduced padding and font sizes. */\n compact?: boolean;\n /** Whether the table adapts to container width. Defaults to true. */\n responsive?: boolean;\n}\n\n/** Graph node: must have an id, plus arbitrary data fields. */\nexport interface GraphNode {\n /** Unique identifier for the node. */\n id: string;\n /** Arbitrary data fields. */\n [key: string]: unknown;\n}\n\n/** Graph edge: connects two nodes by id. */\nexport interface GraphEdge {\n /** Source node id. */\n source: string;\n /** Target node id. */\n target: string;\n /** Arbitrary data fields (weight, type, confidence, etc.). */\n [key: string]: unknown;\n}\n\n/**\n * Graph specification: input for network/relationship visualizations.\n *\n * Uses a nodes + edges data model instead of the flat data + encoding model\n * used by chart types. The graph type is defined here for forward compatibility\n * but rendering is deferred to a future phase.\n */\n/** Per-node visual overrides, keyed by node id. */\nexport interface NodeOverride {\n /** Override fill color. */\n fill?: string;\n /** Override radius. */\n radius?: number;\n /** Override stroke width. */\n strokeWidth?: number;\n /** Override stroke color. */\n stroke?: string;\n /** Force label to always show regardless of zoom/priority. */\n alwaysShowLabel?: boolean;\n}\n\nexport interface GraphSpec {\n /** Discriminant: always \"graph\". */\n type: 'graph';\n /** Node array. Each node must have an id field. */\n nodes: GraphNode[];\n /** Edge array. Each edge connects source and target node ids. */\n edges: GraphEdge[];\n /** Graph-specific encoding mapping visual properties to node/edge fields. */\n encoding?: GraphEncoding;\n /** Layout algorithm configuration. */\n layout?: GraphLayoutConfig;\n /** Per-node visual overrides, keyed by node id. */\n nodeOverrides?: Record<string, NodeOverride>;\n /** Editorial chrome. */\n chrome?: Chrome;\n /** Annotations. */\n annotations?: Annotation[];\n /** Theme configuration overrides. */\n theme?: ThemeConfig;\n /** Dark mode behavior. */\n darkMode?: DarkMode;\n}\n\n/**\n * Top-level visualization spec: discriminated union on the `type` field.\n *\n * This is the primary API contract. Users (and Claude) write VizSpec objects,\n * the engine validates and compiles them into layout objects for rendering.\n */\nexport type VizSpec = ChartSpec | TableSpec | GraphSpec;\n\n/** Chart spec without runtime data, for persistence/storage. */\nexport type ChartSpecWithoutData = Omit<ChartSpec, 'data'>;\n/** Table spec without runtime data and columns, for persistence/storage. Columns can be auto-generated via dataTable(). */\nexport type TableSpecWithoutData = Omit<TableSpec, 'data' | 'columns'>;\n/** Graph spec without runtime data, for persistence/storage. */\nexport type GraphSpecWithoutData = Omit<GraphSpec, 'nodes' | 'edges'>;\n/** Union of data-stripped spec types for persistence/storage. */\nexport type StoredVizSpec = ChartSpecWithoutData | TableSpecWithoutData | GraphSpecWithoutData;\n\n// ---------------------------------------------------------------------------\n// Type guards\n// ---------------------------------------------------------------------------\n\n/** All valid chart type strings for runtime checking. */\nexport const CHART_TYPES: ReadonlySet<string> = new Set<ChartType>([\n 'line',\n 'area',\n 'bar',\n 'column',\n 'pie',\n 'donut',\n 'dot',\n 'scatter',\n]);\n\n/** Check if a spec is a ChartSpec (any standard chart type). */\nexport function isChartSpec(spec: VizSpec): spec is ChartSpec {\n return CHART_TYPES.has(spec.type);\n}\n\n/** Check if a spec is a TableSpec. */\nexport function isTableSpec(spec: VizSpec): spec is TableSpec {\n return spec.type === 'table';\n}\n\n/** Check if a spec is a GraphSpec. */\nexport function isGraphSpec(spec: VizSpec): spec is GraphSpec {\n return spec.type === 'graph';\n}\n\n// ---------------------------------------------------------------------------\n// Annotation type guards\n// ---------------------------------------------------------------------------\n\n/** Check if an annotation is a TextAnnotation. */\nexport function isTextAnnotation(annotation: Annotation): annotation is TextAnnotation {\n return annotation.type === 'text';\n}\n\n/** Check if an annotation is a RangeAnnotation. */\nexport function isRangeAnnotation(annotation: Annotation): annotation is RangeAnnotation {\n return annotation.type === 'range';\n}\n\n/** Check if an annotation is a RefLineAnnotation. */\nexport function isRefLineAnnotation(annotation: Annotation): annotation is RefLineAnnotation {\n return annotation.type === 'refline';\n}\n","export default function(constructor, factory, prototype) {\n constructor.prototype = factory.prototype = prototype;\n prototype.constructor = constructor;\n}\n\nexport function extend(parent, definition) {\n var prototype = Object.create(parent.prototype);\n for (var key in definition) prototype[key] = definition[key];\n return prototype;\n}\n","import define, {extend} from \"./define.js\";\n\nexport function Color() {}\n\nexport var darker = 0.7;\nexport var brighter = 1 / darker;\n\nvar reI = \"\\\\s*([+-]?\\\\d+)\\\\s*\",\n reN = \"\\\\s*([+-]?(?:\\\\d*\\\\.)?\\\\d+(?:[eE][+-]?\\\\d+)?)\\\\s*\",\n reP = \"\\\\s*([+-]?(?:\\\\d*\\\\.)?\\\\d+(?:[eE][+-]?\\\\d+)?)%\\\\s*\",\n reHex = /^#([0-9a-f]{3,8})$/,\n reRgbInteger = new RegExp(`^rgb\\\\(${reI},${reI},${reI}\\\\)$`),\n reRgbPercent = new RegExp(`^rgb\\\\(${reP},${reP},${reP}\\\\)$`),\n reRgbaInteger = new RegExp(`^rgba\\\\(${reI},${reI},${reI},${reN}\\\\)$`),\n reRgbaPercent = new RegExp(`^rgba\\\\(${reP},${reP},${reP},${reN}\\\\)$`),\n reHslPercent = new RegExp(`^hsl\\\\(${reN},${reP},${reP}\\\\)$`),\n reHslaPercent = new RegExp(`^hsla\\\\(${reN},${reP},${reP},${reN}\\\\)$`);\n\nvar named = {\n aliceblue: 0xf0f8ff,\n antiquewhite: 0xfaebd7,\n aqua: 0x00ffff,\n aquamarine: 0x7fffd4,\n azure: 0xf0ffff,\n beige: 0xf5f5dc,\n bisque: 0xffe4c4,\n black: 0x000000,\n blanchedalmond: 0xffebcd,\n blue: 0x0000ff,\n blueviolet: 0x8a2be2,\n brown: 0xa52a2a,\n burlywood: 0xdeb887,\n cadetblue: 0x5f9ea0,\n chartreuse: 0x7fff00,\n chocolate: 0xd2691e,\n coral: 0xff7f50,\n cornflowerblue: 0x6495ed,\n cornsilk: 0xfff8dc,\n crimson: 0xdc143c,\n cyan: 0x00ffff,\n darkblue: 0x00008b,\n darkcyan: 0x008b8b,\n darkgoldenrod: 0xb8860b,\n darkgray: 0xa9a9a9,\n darkgreen: 0x006400,\n darkgrey: 0xa9a9a9,\n darkkhaki: 0xbdb76b,\n darkmagenta: 0x8b008b,\n darkolivegreen: 0x556b2f,\n darkorange: 0xff8c00,\n darkorchid: 0x9932cc,\n darkred: 0x8b0000,\n darksalmon: 0xe9967a,\n darkseagreen: 0x8fbc8f,\n darkslateblue: 0x483d8b,\n darkslategray: 0x2f4f4f,\n darkslategrey: 0x2f4f4f,\n darkturquoise: 0x00ced1,\n darkviolet: 0x9400d3,\n deeppink: 0xff1493,\n deepskyblue: 0x00bfff,\n dimgray: 0x696969,\n dimgrey: 0x696969,\n dodgerblue: 0x1e90ff,\n firebrick: 0xb22222,\n floralwhite: 0xfffaf0,\n forestgreen: 0x228b22,\n fuchsia: 0xff00ff,\n gainsboro: 0xdcdcdc,\n ghostwhite: 0xf8f8ff,\n gold: 0xffd700,\n goldenrod: 0xdaa520,\n gray: 0x808080,\n green: 0x008000,\n greenyellow: 0xadff2f,\n grey: 0x808080,\n honeydew: 0xf0fff0,\n hotpink: 0xff69b4,\n indianred: 0xcd5c5c,\n indigo: 0x4b0082,\n ivory: 0xfffff0,\n khaki: 0xf0e68c,\n lavender: 0xe6e6fa,\n lavenderblush: 0xfff0f5,\n lawngreen: 0x7cfc00,\n lemonchiffon: 0xfffacd,\n lightblue: 0xadd8e6,\n lightcoral: 0xf08080,\n lightcyan: 0xe0ffff,\n lightgoldenrodyellow: 0xfafad2,\n lightgray: 0xd3d3d3,\n lightgreen: 0x90ee90,\n lightgrey: 0xd3d3d3,\n lightpink: 0xffb6c1,\n lightsalmon: 0xffa07a,\n lightseagreen: 0x20b2aa,\n lightskyblue: 0x87cefa,\n lightslategray: 0x778899,\n lightslategrey: 0x778899,\n lightsteelblue: 0xb0c4de,\n lightyellow: 0xffffe0,\n lime: 0x00ff00,\n limegreen: 0x32cd32,\n linen: 0xfaf0e6,\n magenta: 0xff00ff,\n maroon: 0x800000,\n mediumaquamarine: 0x66cdaa,\n mediumblue: 0x0000cd,\n mediumorchid: 0xba55d3,\n mediumpurple: 0x9370db,\n mediumseagreen: 0x3cb371,\n mediumslateblue: 0x7b68ee,\n mediumspringgreen: 0x00fa9a,\n mediumturquoise: 0x48d1cc,\n mediumvioletred: 0xc71585,\n midnightblue: 0x191970,\n mintcream: 0xf5fffa,\n mistyrose: 0xffe4e1,\n moccasin: 0xffe4b5,\n navajowhite: 0xffdead,\n navy: 0x000080,\n oldlace: 0xfdf5e6,\n olive: 0x808000,\n olivedrab: 0x6b8e23,\n orange: 0xffa500,\n orangered: 0xff4500,\n orchid: 0xda70d6,\n palegoldenrod: 0xeee8aa,\n palegreen: 0x98fb98,\n paleturquoise: 0xafeeee,\n palevioletred: 0xdb7093,\n papayawhip: 0xffefd5,\n peachpuff: 0xffdab9,\n peru: 0xcd853f,\n pink: 0xffc0cb,\n plum: 0xdda0dd,\n powderblue: 0xb0e0e6,\n purple: 0x800080,\n rebeccapurple: 0x663399,\n red: 0xff0000,\n rosybrown: 0xbc8f8f,\n royalblue: 0x4169e1,\n saddlebrown: 0x8b4513,\n salmon: 0xfa8072,\n sandybrown: 0xf4a460,\n seagreen: 0x2e8b57,\n seashell: 0xfff5ee,\n sienna: 0xa0522d,\n silver: 0xc0c0c0,\n skyblue: 0x87ceeb,\n slateblue: 0x6a5acd,\n slategray: 0x708090,\n slategrey: 0x708090,\n snow: 0xfffafa,\n springgreen: 0x00ff7f,\n steelblue: 0x4682b4,\n tan: 0xd2b48c,\n teal: 0x008080,\n thistle: 0xd8bfd8,\n tomato: 0xff6347,\n turquoise: 0x40e0d0,\n violet: 0xee82ee,\n wheat: 0xf5deb3,\n white: 0xffffff,\n whitesmoke: 0xf5f5f5,\n yellow: 0xffff00,\n yellowgreen: 0x9acd32\n};\n\ndefine(Color, color, {\n copy(channels) {\n return Object.assign(new this.constructor, this, channels);\n },\n displayable() {\n return this.rgb().displayable();\n },\n hex: color_formatHex, // Deprecated! Use color.formatHex.\n formatHex: color_formatHex,\n formatHex8: color_formatHex8,\n formatHsl: color_formatHsl,\n formatRgb: color_formatRgb,\n toString: color_formatRgb\n});\n\nfunction color_formatHex() {\n return this.rgb().formatHex();\n}\n\nfunction color_formatHex8() {\n return this.rgb().formatHex8();\n}\n\nfunction color_formatHsl() {\n return hslConvert(this).formatHsl();\n}\n\nfunction color_formatRgb() {\n return this.rgb().formatRgb();\n}\n\nexport default function color(format) {\n var m, l;\n format = (format + \"\").trim().toLowerCase();\n return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000\n : l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00\n : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000\n : l === 4 ? rgba((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000\n : null) // invalid hex\n : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)\n : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)\n : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)\n : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)\n : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)\n : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)\n : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins\n : format === \"transparent\" ? new Rgb(NaN, NaN, NaN, 0)\n : null;\n}\n\nfunction rgbn(n) {\n return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);\n}\n\nfunction rgba(r, g, b, a) {\n if (a <= 0) r = g = b = NaN;\n return new Rgb(r, g, b, a);\n}\n\nexport function rgbConvert(o) {\n if (!(o instanceof Color)) o = color(o);\n if (!o) return new Rgb;\n o = o.rgb();\n return new Rgb(o.r, o.g, o.b, o.opacity);\n}\n\nexport function rgb(r, g, b, opacity) {\n return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);\n}\n\nexport function Rgb(r, g, b, opacity) {\n this.r = +r;\n this.g = +g;\n this.b = +b;\n this.opacity = +opacity;\n}\n\ndefine(Rgb, rgb, extend(Color, {\n brighter(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n },\n darker(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n },\n rgb() {\n return this;\n },\n clamp() {\n return new Rgb(clampi(this.r), clampi(this.g), clampi(this.b), clampa(this.opacity));\n },\n displayable() {\n return (-0.5 <= this.r && this.r < 255.5)\n && (-0.5 <= this.g && this.g < 255.5)\n && (-0.5 <= this.b && this.b < 255.5)\n && (0 <= this.opacity && this.opacity <= 1);\n },\n hex: rgb_formatHex, // Deprecated! Use color.formatHex.\n formatHex: rgb_formatHex,\n formatHex8: rgb_formatHex8,\n formatRgb: rgb_formatRgb,\n toString: rgb_formatRgb\n}));\n\nfunction rgb_formatHex() {\n return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}`;\n}\n\nfunction rgb_formatHex8() {\n return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}${hex((isNaN(this.opacity) ? 1 : this.opacity) * 255)}`;\n}\n\nfunction rgb_formatRgb() {\n const a = clampa(this.opacity);\n return `${a === 1 ? \"rgb(\" : \"rgba(\"}${clampi(this.r)}, ${clampi(this.g)}, ${clampi(this.b)}${a === 1 ? \")\" : `, ${a})`}`;\n}\n\nfunction clampa(opacity) {\n return isNaN(opacity) ? 1 : Math.max(0, Math.min(1, opacity));\n}\n\nfunction clampi(value) {\n return Math.max(0, Math.min(255, Math.round(value) || 0));\n}\n\nfunction hex(value) {\n value = clampi(value);\n return (value < 16 ? \"0\" : \"\") + value.toString(16);\n}\n\nfunction hsla(h, s, l, a) {\n if (a <= 0) h = s = l = NaN;\n else if (l <= 0 || l >= 1) h = s = NaN;\n else if (s <= 0) h = NaN;\n return new Hsl(h, s, l, a);\n}\n\nexport function hslConvert(o) {\n if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);\n if (!(o instanceof Color)) o = color(o);\n if (!o) return new Hsl;\n if (o instanceof Hsl) return o;\n o = o.rgb();\n var r = o.r / 255,\n g = o.g / 255,\n b = o.b / 255,\n min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n h = NaN,\n s = max - min,\n l = (max + min) / 2;\n if (s) {\n if (r === max) h = (g - b) / s + (g < b) * 6;\n else if (g === max) h = (b - r) / s + 2;\n else h = (r - g) / s + 4;\n s /= l < 0.5 ? max + min : 2 - max - min;\n h *= 60;\n } else {\n s = l > 0 && l < 1 ? 0 : h;\n }\n return new Hsl(h, s, l, o.opacity);\n}\n\nexport function hsl(h, s, l, opacity) {\n return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);\n}\n\nfunction Hsl(h, s, l, opacity) {\n this.h = +h;\n this.s = +s;\n this.l = +l;\n this.opacity = +opacity;\n}\n\ndefine(Hsl, hsl, extend(Color, {\n brighter(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Hsl(this.h, this.s, this.l * k, this.opacity);\n },\n darker(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Hsl(this.h, this.s, this.l * k, this.opacity);\n },\n rgb() {\n var h = this.h % 360 + (this.h < 0) * 360,\n s = isNaN(h) || isNaN(this.s) ? 0 : this.s,\n l = this.l,\n m2 = l + (l < 0.5 ? l : 1 - l) * s,\n m1 = 2 * l - m2;\n return new Rgb(\n hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),\n hsl2rgb(h, m1, m2),\n hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),\n this.opacity\n );\n },\n clamp() {\n return new Hsl(clamph(this.h), clampt(this.s), clampt(this.l), clampa(this.opacity));\n },\n displayable() {\n return (0 <= this.s && this.s <= 1 || isNaN(this.s))\n && (0 <= this.l && this.l <= 1)\n && (0 <= this.opacity && this.opacity <= 1);\n },\n formatHsl() {\n const a = clampa(this.opacity);\n return `${a === 1 ? \"hsl(\" : \"hsla(\"}${clamph(this.h)}, ${clampt(this.s) * 100}%, ${clampt(this.l) * 100}%${a === 1 ? \")\" : `, ${a})`}`;\n }\n}));\n\nfunction clamph(value) {\n value = (value || 0) % 360;\n return value < 0 ? value + 360 : value;\n}\n\nfunction clampt(value) {\n return Math.max(0, Math.min(1, value || 0));\n}\n\n/* From FvD 13.37, CSS Color Module Level 3 */\nfunction hsl2rgb(h, m1, m2) {\n return (h < 60 ? m1 + (m2 - m1) * h / 60\n : h < 180 ? m2\n : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60\n : m1) * 255;\n}\n","/**\n * Color blindness simulation and palette distinguishability checks.\n *\n * Uses Brettel, Vienot, and Mollon (1997) simulation matrices for\n * protanopia, deuteranopia, and tritanopia.\n *\n * These are approximations suitable for checking palette accessibility,\n * not medical-grade simulations.\n */\n\nimport { rgb } from 'd3-color';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** The three common types of color vision deficiency. */\nexport type ColorBlindnessType = 'protanopia' | 'deuteranopia' | 'tritanopia';\n\n// ---------------------------------------------------------------------------\n// Simulation matrices\n// ---------------------------------------------------------------------------\n\n// 3x3 color transformation matrices for each deficiency type.\n// Applied in linear RGB space to simulate how colors appear.\n// Source: Brettel, Vienot & Mollon (1997), simplified.\n\ntype Matrix3x3 = readonly [\n readonly [number, number, number],\n readonly [number, number, number],\n readonly [number, number, number],\n];\n\nconst PROTAN_MATRIX: Matrix3x3 = [\n [0.567, 0.433, 0.0],\n [0.558, 0.442, 0.0],\n [0.0, 0.242, 0.758],\n];\n\nconst DEUTAN_MATRIX: Matrix3x3 = [\n [0.625, 0.375, 0.0],\n [0.7, 0.3, 0.0],\n [0.0, 0.3, 0.7],\n];\n\nconst TRITAN_MATRIX: Matrix3x3 = [\n [0.95, 0.05, 0.0],\n [0.0, 0.433, 0.567],\n [0.0, 0.475, 0.525],\n];\n\nconst MATRICES: Record<ColorBlindnessType, Matrix3x3> = {\n protanopia: PROTAN_MATRIX,\n deuteranopia: DEUTAN_MATRIX,\n tritanopia: TRITAN_MATRIX,\n};\n\n// ---------------------------------------------------------------------------\n// sRGB linearization helpers\n// ---------------------------------------------------------------------------\n\nfunction linearize(v: number): number {\n const s = v / 255;\n return s <= 0.04045 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n}\n\nfunction delinearize(v: number): number {\n const s = v <= 0.0031308 ? v * 12.92 : 1.055 * v ** (1 / 2.4) - 0.055;\n return Math.round(Math.max(0, Math.min(255, s * 255)));\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Simulate how a color appears under a given color blindness type.\n * Returns a hex color string.\n */\nexport function simulateColorBlindness(color: string, type: ColorBlindnessType): string {\n const c = rgb(color);\n if (c == null) return color;\n\n const lin = [linearize(c.r), linearize(c.g), linearize(c.b)];\n const m = MATRICES[type];\n\n const r = m[0][0] * lin[0] + m[0][1] * lin[1] + m[0][2] * lin[2];\n const g = m[1][0] * lin[0] + m[1][1] * lin[1] + m[1][2] * lin[2];\n const b = m[2][0] * lin[0] + m[2][1] * lin[1] + m[2][2] * lin[2];\n\n return rgb(delinearize(r), delinearize(g), delinearize(b)).formatHex();\n}\n\n/**\n * Check if colors in a palette are distinguishable under a given\n * color blindness type.\n *\n * Uses a minimum perceptual distance threshold in simulated space.\n * Returns true if all pairs of colors are sufficiently different.\n */\nexport function checkPaletteDistinguishability(\n colors: string[],\n type: ColorBlindnessType,\n minDistance = 30,\n): boolean {\n const simulated = colors.map((c) => {\n const s = rgb(simulateColorBlindness(c, type));\n return s ? [s.r, s.g, s.b] : [0, 0, 0];\n });\n\n for (let i = 0; i < simulated.length; i++) {\n for (let j = i + 1; j < simulated.length; j++) {\n const dr = simulated[i][0] - simulated[j][0];\n const dg = simulated[i][1] - simulated[j][1];\n const db = simulated[i][2] - simulated[j][2];\n const dist = Math.sqrt(dr * dr + dg * dg + db * db);\n if (dist < minDistance) return false;\n }\n }\n\n return true;\n}\n","/**\n * WCAG contrast ratio utilities.\n *\n * Uses d3-color for color space parsing and manipulation.\n * All functions accept CSS color strings (hex, rgb, hsl, named colors).\n */\n\nimport { rgb } from 'd3-color';\n\n// ---------------------------------------------------------------------------\n// Relative luminance (WCAG 2.1)\n// ---------------------------------------------------------------------------\n\n/**\n * Compute the relative luminance of a color per WCAG 2.1 definition.\n * https://www.w3.org/TR/WCAG21/#dfn-relative-luminance\n */\nfunction relativeLuminance(color: string): number {\n const c = rgb(color);\n if (c == null) return 0;\n\n const srgb = [c.r / 255, c.g / 255, c.b / 255];\n const linear = srgb.map((v) => (v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4));\n return 0.2126 * linear[0] + 0.7152 * linear[1] + 0.0722 * linear[2];\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute the WCAG contrast ratio between two colors.\n * Returns a value between 1 (identical) and 21 (black on white).\n */\nexport function contrastRatio(fg: string, bg: string): number {\n const l1 = relativeLuminance(fg);\n const l2 = relativeLuminance(bg);\n const lighter = Math.max(l1, l2);\n const darker = Math.min(l1, l2);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * Check if two colors meet WCAG AA contrast requirements.\n * Normal text: 4.5:1, large text (18px+ bold or 24px+): 3:1.\n */\nexport function meetsAA(fg: string, bg: string, largeText = false): boolean {\n const ratio = contrastRatio(fg, bg);\n return largeText ? ratio >= 3 : ratio >= 4.5;\n}\n\n/**\n * Find an accessible variant of `baseColor` against `bg`.\n *\n * Preserves the hue and saturation of baseColor but adjusts lightness\n * until the target contrast ratio is met. Returns the original color\n * if it already meets the target.\n */\nexport function findAccessibleColor(baseColor: string, bg: string, targetRatio = 4.5): string {\n if (contrastRatio(baseColor, bg) >= targetRatio) {\n return baseColor;\n }\n\n const c = rgb(baseColor);\n if (c == null) return baseColor;\n\n const bgLum = relativeLuminance(bg);\n // Determine direction: darken if bg is light, lighten if bg is dark.\n const bgIsLight = bgLum > 0.5;\n\n // Binary search for the lightness adjustment that hits the target ratio.\n let lo = 0;\n let hi = 1;\n let best = baseColor;\n\n for (let i = 0; i < 20; i++) {\n const mid = (lo + hi) / 2;\n const adjusted = bgIsLight\n ? rgb(c.r * (1 - mid), c.g * (1 - mid), c.b * (1 - mid))\n : rgb(c.r + (255 - c.r) * mid, c.g + (255 - c.g) * mid, c.b + (255 - c.b) * mid);\n\n const hex = adjusted.formatHex();\n const ratio = contrastRatio(hex, bg);\n\n if (ratio >= targetRatio) {\n best = hex;\n hi = mid; // try less adjustment\n } else {\n lo = mid; // need more adjustment\n }\n }\n\n return best;\n}\n","/**\n * Color palettes for @opendata-ai.\n *\n * Categorical palette is Infrographic-influenced with WCAG AA contrast\n * for large text (3:1 ratio) on both light (#ffffff) and dark (#1a1a2e)\n * backgrounds. Several colors do not meet the stricter 4.5:1 ratio\n * required for normal-sized body text. This is acceptable because chart\n * marks (bars, lines, areas, points) are large visual elements.\n *\n * Sequential palettes: 5-7 stops from light to dark.\n * Diverging palettes: 7 stops with a neutral midpoint.\n */\n\n// ---------------------------------------------------------------------------\n// Categorical\n// ---------------------------------------------------------------------------\n\n/**\n * Default categorical palette. 10 visually distinct colors that meet\n * WCAG AA contrast for large text (3:1) on both white and near-black\n * backgrounds. Some colors fall below the 4.5:1 threshold for normal\n * body text. Influenced by Infrographic's editorial palette with tweaks\n * for accessibility and colorblind distinguishability.\n */\nexport const CATEGORICAL_PALETTE = [\n '#1b7fa3', // teal-blue (primary)\n '#c44e52', // warm red (secondary)\n '#6a9f58', // softer green (tertiary)\n '#d47215', // orange\n '#507e79', // muted teal\n '#9a6a8d', // purple\n '#c4636b', // rose\n '#9c755f', // brown\n '#a88f22', // olive gold\n '#858078', // warm gray\n] as const;\n\nexport type CategoricalPalette = typeof CATEGORICAL_PALETTE;\n\n// ---------------------------------------------------------------------------\n// Sequential\n// ---------------------------------------------------------------------------\n\n/** Sequential palette definition: an array of color stops from light to dark. */\nexport interface SequentialPalette {\n readonly name: string;\n readonly stops: readonly string[];\n}\n\nexport const SEQUENTIAL_BLUE: SequentialPalette = {\n name: 'blue',\n stops: ['#deebf7', '#c6dbef', '#9ecae1', '#6baed6', '#3182bd', '#08519c'],\n} as const;\n\nexport const SEQUENTIAL_GREEN: SequentialPalette = {\n name: 'green',\n stops: ['#e5f5e0', '#c7e9c0', '#a1d99b', '#74c476', '#31a354', '#006d2c'],\n} as const;\n\nexport const SEQUENTIAL_ORANGE: SequentialPalette = {\n name: 'orange',\n stops: ['#fee6ce', '#fdd0a2', '#fdae6b', '#fd8d3c', '#e6550d', '#a63603'],\n} as const;\n\nexport const SEQUENTIAL_PURPLE: SequentialPalette = {\n name: 'purple',\n stops: ['#efedf5', '#dadaeb', '#bcbddc', '#9e9ac8', '#756bb1', '#54278f'],\n} as const;\n\n/** All sequential palettes keyed by name. */\nexport const SEQUENTIAL_PALETTES: Record<string, string[]> = {\n blue: [...SEQUENTIAL_BLUE.stops],\n green: [...SEQUENTIAL_GREEN.stops],\n orange: [...SEQUENTIAL_ORANGE.stops],\n purple: [...SEQUENTIAL_PURPLE.stops],\n};\n\n// ---------------------------------------------------------------------------\n// Diverging\n// ---------------------------------------------------------------------------\n\n/** Diverging palette definition: an array of color stops with a neutral midpoint. */\nexport interface DivergingPalette {\n readonly name: string;\n readonly stops: readonly string[];\n}\n\nexport const DIVERGING_RED_BLUE: DivergingPalette = {\n name: 'redBlue',\n stops: [\n '#b2182b', // strong red\n '#d6604d', // medium red\n '#f4a582', // light red\n '#f7f7f7', // neutral\n '#92c5de', // light blue\n '#4393c3', // medium blue\n '#2166ac', // strong blue\n ],\n} as const;\n\nexport const DIVERGING_BROWN_TEAL: DivergingPalette = {\n name: 'brownTeal',\n stops: [\n '#8c510a', // strong brown\n '#bf812d', // medium brown\n '#dfc27d', // light brown\n '#f6e8c3', // neutral\n '#80cdc1', // light teal\n '#35978f', // medium teal\n '#01665e', // strong teal\n ],\n} as const;\n\n/** All diverging palettes keyed by name. */\nexport const DIVERGING_PALETTES: Record<string, string[]> = {\n redBlue: [...DIVERGING_RED_BLUE.stops],\n brownTeal: [...DIVERGING_BROWN_TEAL.stops],\n};\n","/**\n * Dark mode theme adaptation.\n *\n * Preserves hue of colors while adjusting lightness and saturation\n * to maintain the same relative contrast ratios on a dark background.\n */\n\nimport { hsl, rgb } from 'd3-color';\nimport { contrastRatio } from '../colors/contrast';\nimport type { ResolvedTheme } from '../types/theme';\n\n// ---------------------------------------------------------------------------\n// Dark mode background\n// ---------------------------------------------------------------------------\n\n/** Default dark mode background color. */\nconst DARK_BG = '#1a1a2e';\n/** Default dark mode text color. */\nconst DARK_TEXT = '#e0e0e0';\n\n// ---------------------------------------------------------------------------\n// Color adaptation\n// ---------------------------------------------------------------------------\n\n/**\n * Adapt a single color for dark mode.\n *\n * Preserves the hue and adjusts lightness/saturation so the adapted\n * color has the same contrast ratio against darkBg as the original\n * had against lightBg.\n */\nexport function adaptColorForDarkMode(color: string, lightBg: string, darkBg: string): string {\n const originalRatio = contrastRatio(color, lightBg);\n const c = hsl(color);\n if (c == null || Number.isNaN(c.h)) {\n // Achromatic or invalid color: just adjust lightness\n const r = rgb(color);\n if (r == null) return color;\n const darkBgLum = _luminanceFromHex(darkBg);\n const isLight = darkBgLum < 0.5;\n if (isLight) return color;\n // Invert the lightness\n const inverted = hsl(color);\n if (inverted == null) return color;\n inverted.l = 1 - inverted.l;\n return inverted.formatHex();\n }\n\n // Binary search for lightness that gives equivalent contrast on dark bg\n let lo = 0.0;\n let hi = 1.0;\n let bestColor = color;\n let bestDiff = Infinity;\n\n for (let i = 0; i < 20; i++) {\n const mid = (lo + hi) / 2;\n const candidate = hsl(c.h, c.s, mid);\n const hex = candidate.formatHex();\n const ratio = contrastRatio(hex, darkBg);\n const diff = Math.abs(ratio - originalRatio);\n\n if (diff < bestDiff) {\n bestDiff = diff;\n bestColor = hex;\n }\n\n if (ratio < originalRatio) {\n // Need more contrast = more lightness on dark bg\n lo = mid;\n } else {\n hi = mid;\n }\n }\n\n return bestColor;\n}\n\n/** Quick luminance estimation from a hex color. */\nfunction _luminanceFromHex(color: string): number {\n const c = rgb(color);\n if (c == null) return 0;\n return (0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) / 255;\n}\n\n// ---------------------------------------------------------------------------\n// Full theme adaptation\n// ---------------------------------------------------------------------------\n\n/**\n * Adapt an entire resolved theme for dark mode.\n *\n * Swaps background/text, adapts categorical and annotation colors,\n * adjusts gridline and axis colors for the dark background.\n */\nexport function adaptTheme(theme: ResolvedTheme): ResolvedTheme {\n const inputBg = theme.colors.background;\n // Treat transparent as \"already dark\" to preserve user intent\n const alreadyDark = inputBg === 'transparent' || _luminanceFromHex(inputBg) < 0.2;\n\n // If the theme already has a dark background, preserve user-provided colors\n // instead of overwriting with library defaults.\n const darkBg = alreadyDark ? inputBg : DARK_BG;\n const darkText = alreadyDark ? theme.colors.text : DARK_TEXT;\n const darkGridline = alreadyDark ? theme.colors.gridline : '#333344';\n const darkAxis = alreadyDark ? theme.colors.axis : '#888899';\n\n // Only adapt categorical colors when switching from light to dark\n const categorical = alreadyDark\n ? theme.colors.categorical\n : theme.colors.categorical.map((c) => adaptColorForDarkMode(c, inputBg, darkBg));\n\n return {\n ...theme,\n isDark: true,\n colors: {\n ...theme.colors,\n background: darkBg,\n text: darkText,\n gridline: darkGridline,\n axis: darkAxis,\n annotationFill: 'rgba(255,255,255,0.08)',\n annotationText: '#bbbbcc',\n categorical,\n },\n chrome: {\n title: { ...theme.chrome.title, color: darkText },\n subtitle: { ...theme.chrome.subtitle, color: '#aaaaaa' },\n source: { ...theme.chrome.source, color: '#888888' },\n byline: { ...theme.chrome.byline, color: '#888888' },\n footer: { ...theme.chrome.footer, color: '#888888' },\n },\n };\n}\n","/**\n * Default theme definition.\n *\n * Tuned to match Infrographic's visual weight and editorial style.\n * Inter font family, typography hierarchy for chrome, and color\n * palettes from the colors module.\n */\n\nimport { CATEGORICAL_PALETTE, DIVERGING_PALETTES, SEQUENTIAL_PALETTES } from '../colors/palettes';\nimport type { Theme } from '../types/theme';\n\n/**\n * The default theme. All fields are required and fully specified.\n * resolveTheme() deep-merges user overrides onto this base.\n */\nexport const DEFAULT_THEME: Theme = {\n colors: {\n categorical: [...CATEGORICAL_PALETTE],\n sequential: SEQUENTIAL_PALETTES,\n diverging: DIVERGING_PALETTES,\n background: '#ffffff',\n text: '#1d1d1d',\n gridline: '#e8e8e8',\n axis: '#888888',\n annotationFill: 'rgba(0,0,0,0.04)',\n annotationText: '#555555',\n },\n fonts: {\n family: 'Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n mono: '\"JetBrains Mono\", \"Fira Code\", \"Cascadia Code\", monospace',\n sizes: {\n title: 22,\n subtitle: 15,\n body: 13,\n small: 11,\n axisTick: 11,\n },\n weights: {\n normal: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n },\n },\n spacing: {\n padding: 12,\n chromeGap: 4,\n chromeToChart: 8,\n chartToFooter: 8,\n axisMargin: 6,\n },\n borderRadius: 4,\n chrome: {\n title: {\n fontSize: 22,\n fontWeight: 700,\n color: '#333333',\n lineHeight: 1.3,\n },\n subtitle: {\n fontSize: 15,\n fontWeight: 400,\n color: '#666666',\n lineHeight: 1.4,\n },\n source: {\n fontSize: 12,\n fontWeight: 400,\n color: '#999999',\n lineHeight: 1.3,\n },\n byline: {\n fontSize: 12,\n fontWeight: 400,\n color: '#999999',\n lineHeight: 1.3,\n },\n footer: {\n fontSize: 12,\n fontWeight: 400,\n color: '#999999',\n lineHeight: 1.3,\n },\n },\n};\n","/**\n * Theme resolver: deep-merges user overrides onto default theme.\n *\n * Produces a ResolvedTheme where every property is guaranteed to have\n * a value. The engine uses ResolvedTheme internally so it never needs\n * null checks on theme properties.\n *\n * Auto-detects dark backgrounds and adapts chrome text colors so\n * custom themes with dark canvases are readable without explicitly\n * enabling darkMode.\n */\n\nimport type { ThemeConfig } from '../types/spec';\nimport type { ResolvedTheme, Theme } from '../types/theme';\nimport { DEFAULT_THEME } from './defaults';\n\n/**\n * Deep merge source into target, creating a new object.\n * Only merges plain objects; arrays and primitives replace directly.\n */\n// biome-ignore lint/suspicious/noExplicitAny: recursive object merge requires dynamic typing\nfunction deepMerge(target: any, source: any): any {\n const result = { ...target };\n\n for (const key of Object.keys(source)) {\n const sourceVal = source[key];\n const targetVal = target[key];\n\n if (\n sourceVal !== undefined &&\n sourceVal !== null &&\n typeof sourceVal === 'object' &&\n !Array.isArray(sourceVal) &&\n typeof targetVal === 'object' &&\n targetVal !== null &&\n !Array.isArray(targetVal)\n ) {\n result[key] = deepMerge(targetVal, sourceVal);\n } else if (sourceVal !== undefined) {\n result[key] = sourceVal;\n }\n }\n\n return result;\n}\n\n/**\n * Convert a user-facing ThemeConfig (partial) into the full Theme shape\n * that deepMerge can work with.\n */\nfunction themeConfigToPartial(config: ThemeConfig): Partial<Theme> {\n const partial: Partial<Theme> = {};\n\n if (config.colors) {\n const colors: Partial<Theme['colors']> = {};\n // Shorthand: flat string[] is treated as categorical palette\n if (Array.isArray(config.colors)) {\n colors.categorical = config.colors;\n } else {\n if (config.colors.categorical) colors.categorical = config.colors.categorical;\n if (config.colors.sequential) colors.sequential = config.colors.sequential;\n if (config.colors.diverging) colors.diverging = config.colors.diverging;\n if (config.colors.background) colors.background = config.colors.background;\n if (config.colors.text) colors.text = config.colors.text;\n if (config.colors.gridline) colors.gridline = config.colors.gridline;\n if (config.colors.axis) colors.axis = config.colors.axis;\n }\n partial.colors = colors as Theme['colors'];\n }\n\n if (config.fonts) {\n const fonts: Partial<Theme['fonts']> = {};\n if (config.fonts.family) fonts.family = config.fonts.family;\n if (config.fonts.mono) fonts.mono = config.fonts.mono;\n partial.fonts = fonts as Theme['fonts'];\n }\n\n if (config.spacing) {\n const spacing: Partial<Theme['spacing']> = {};\n if (config.spacing.padding !== undefined) spacing.padding = config.spacing.padding;\n if (config.spacing.chromeGap !== undefined) spacing.chromeGap = config.spacing.chromeGap;\n partial.spacing = spacing as Theme['spacing'];\n }\n\n if (config.borderRadius !== undefined) {\n partial.borderRadius = config.borderRadius;\n }\n\n return partial;\n}\n\n/**\n * Parse a hex color to sRGB relative luminance (WCAG 2.1).\n * Returns 0 for invalid/unparseable colors.\n */\nfunction relativeLuminance(hex: string): number {\n const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim());\n if (!m) return 0;\n const r = parseInt(m[1].slice(0, 2), 16) / 255;\n const g = parseInt(m[1].slice(2, 4), 16) / 255;\n const b = parseInt(m[1].slice(4, 6), 16) / 255;\n const toLinear = (c: number) => (c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4);\n return 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);\n}\n\n/** Returns true if the hex color is perceptually dark (luminance < 0.2). */\nfunction isDarkBackground(hex: string): boolean {\n return relativeLuminance(hex) < 0.2;\n}\n\n/**\n * Adapt chrome text colors for a dark background.\n * Only overrides values that still match the light-mode defaults,\n * so explicit user overrides are preserved.\n */\nfunction adaptChromeForDarkBg(theme: Theme, textColor: string): Theme {\n const light = DEFAULT_THEME.chrome;\n return {\n ...theme,\n chrome: {\n title: {\n ...theme.chrome.title,\n color:\n theme.chrome.title.color === light.title.color ? textColor : theme.chrome.title.color,\n },\n subtitle: {\n ...theme.chrome.subtitle,\n color:\n theme.chrome.subtitle.color === light.subtitle.color\n ? adjustOpacity(textColor, 0.7)\n : theme.chrome.subtitle.color,\n },\n source: {\n ...theme.chrome.source,\n color:\n theme.chrome.source.color === light.source.color\n ? adjustOpacity(textColor, 0.5)\n : theme.chrome.source.color,\n },\n byline: {\n ...theme.chrome.byline,\n color:\n theme.chrome.byline.color === light.byline.color\n ? adjustOpacity(textColor, 0.5)\n : theme.chrome.byline.color,\n },\n footer: {\n ...theme.chrome.footer,\n color:\n theme.chrome.footer.color === light.footer.color\n ? adjustOpacity(textColor, 0.5)\n : theme.chrome.footer.color,\n },\n },\n };\n}\n\n/** Blend a hex color toward white/black by a factor to simulate opacity. */\nfunction adjustOpacity(hex: string, opacity: number): string {\n const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim());\n if (!m) return hex;\n const r = parseInt(m[1].slice(0, 2), 16);\n const g = parseInt(m[1].slice(2, 4), 16);\n const b = parseInt(m[1].slice(4, 6), 16);\n // Blend toward mid-gray for muted secondary text\n const mix = (c: number) => Math.round(c * opacity + 128 * (1 - opacity));\n const toHex = (n: number) => n.toString(16).padStart(2, '0');\n return `#${toHex(mix(r))}${toHex(mix(g))}${toHex(mix(b))}`;\n}\n\n/**\n * Resolve a theme by deep-merging user overrides onto a base theme.\n *\n * Auto-detects dark backgrounds: if the resolved background color is\n * perceptually dark and chrome text colors are still the light-mode\n * defaults, they're adapted for readability.\n *\n * @param userTheme - Optional partial theme overrides from the spec.\n * @param base - Base theme to merge onto. Defaults to DEFAULT_THEME.\n * @returns A ResolvedTheme with all properties guaranteed.\n */\nexport function resolveTheme(userTheme?: ThemeConfig, base: Theme = DEFAULT_THEME): ResolvedTheme {\n let merged: Theme = userTheme ? deepMerge(base, themeConfigToPartial(userTheme)) : { ...base };\n\n // Auto-adapt chrome for dark backgrounds\n const dark = isDarkBackground(merged.colors.background);\n if (dark) {\n merged = adaptChromeForDarkBg(merged, merged.colors.text);\n }\n\n return {\n ...merged,\n isDark: dark,\n } as ResolvedTheme;\n}\n","/**\n * Heuristic text measurement for environments without a DOM.\n *\n * These are intentionally approximate. Adapters can provide a real\n * measureText function via CompileOptions for higher accuracy.\n * The engine uses the real function when available, falls back to\n * these heuristics when not.\n */\n\n/**\n * Average character width as a fraction of font size for Inter.\n * Inter is slightly wider than Helvetica, narrower than Courier.\n * This is a reasonable middle ground.\n */\nconst AVG_CHAR_WIDTH_RATIO = 0.55;\n\n/** Narrower characters (i, l, t, etc.) bring the average down. */\nconst WEIGHT_ADJUSTMENT: Record<number, number> = {\n 100: 0.9,\n 200: 0.92,\n 300: 0.95,\n 400: 1.0,\n 500: 1.02,\n 600: 1.05,\n 700: 1.08,\n 800: 1.1,\n 900: 1.12,\n};\n\n/**\n * Estimate the rendered width of a text string.\n *\n * Uses a per-character average width based on font size, adjusted\n * for font weight. Accurate to within ~20% for Latin text in Inter.\n *\n * @param text - The text string to measure.\n * @param fontSize - Font size in pixels.\n * @param fontWeight - Font weight (100-900). Defaults to 400.\n */\nexport function estimateTextWidth(text: string, fontSize: number, fontWeight = 400): number {\n const weightFactor = WEIGHT_ADJUSTMENT[fontWeight] ?? 1.0;\n return text.length * fontSize * AVG_CHAR_WIDTH_RATIO * weightFactor;\n}\n\n/**\n * Estimate the rendered height of a text block.\n *\n * @param fontSize - Font size in pixels.\n * @param lineCount - Number of lines. Defaults to 1.\n * @param lineHeight - Line height multiplier. Defaults to 1.3.\n */\nexport function estimateTextHeight(fontSize: number, lineCount = 1, lineHeight = 1.3): number {\n return fontSize * lineHeight * lineCount;\n}\n","/**\n * Chrome layout computation.\n *\n * Takes a Chrome spec + resolved theme and produces a ResolvedChrome\n * with computed text positions, styles, and total chrome heights.\n */\n\nimport type {\n MeasureTextFn,\n ResolvedChrome,\n ResolvedChromeElement,\n TextStyle,\n} from '../types/layout';\nimport type { Chrome, ChromeText } from '../types/spec';\nimport type { ChromeDefaults, ResolvedTheme } from '../types/theme';\nimport { estimateTextHeight, estimateTextWidth } from './text-measure';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Normalize a chrome field to text + optional style and offset overrides. */\nfunction normalizeChromeText(\n value: string | ChromeText | undefined,\n): { text: string; style?: ChromeText['style']; offset?: ChromeText['offset'] } | null {\n if (value === undefined) return null;\n if (typeof value === 'string') return { text: value };\n return { text: value.text, style: value.style, offset: value.offset };\n}\n\n/** Build a TextStyle from chrome defaults + optional overrides. */\nfunction buildTextStyle(\n defaults: ChromeDefaults,\n fontFamily: string,\n textColor: string,\n overrides?: ChromeText['style'],\n): TextStyle {\n return {\n fontFamily: overrides?.fontFamily ?? fontFamily,\n fontSize: overrides?.fontSize ?? defaults.fontSize,\n fontWeight: overrides?.fontWeight ?? defaults.fontWeight,\n fill: overrides?.color ?? textColor ?? defaults.color,\n lineHeight: defaults.lineHeight,\n textAnchor: 'start',\n dominantBaseline: 'hanging',\n };\n}\n\n/** Measure text width using the provided function or heuristic fallback. */\nfunction measureWidth(text: string, style: TextStyle, measureText?: MeasureTextFn): number {\n if (measureText) {\n return measureText(text, style.fontSize, style.fontWeight).width;\n }\n return estimateTextWidth(text, style.fontSize, style.fontWeight);\n}\n\n/**\n * Estimate how many lines text will wrap to, given a max width.\n * Returns at least 1.\n */\nfunction estimateLineCount(\n text: string,\n style: TextStyle,\n maxWidth: number,\n measureText?: MeasureTextFn,\n): number {\n const fullWidth = measureWidth(text, style, measureText);\n if (fullWidth <= maxWidth) return 1;\n return Math.ceil(fullWidth / maxWidth);\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute resolved chrome layout from a Chrome spec and resolved theme.\n *\n * Produces positioned text elements and total chrome heights (top and bottom).\n * Top chrome: title, subtitle. Bottom chrome: source, byline, footer.\n *\n * @param chrome - The Chrome spec from the user's VizSpec.\n * @param theme - The fully resolved theme.\n * @param width - Total available width in pixels.\n * @param measureText - Optional real text measurement function from the adapter.\n */\nexport function computeChrome(\n chrome: Chrome | undefined,\n theme: ResolvedTheme,\n width: number,\n measureText?: MeasureTextFn,\n): ResolvedChrome {\n if (!chrome) {\n return { topHeight: 0, bottomHeight: 0 };\n }\n\n const padding = theme.spacing.padding;\n const chromeGap = theme.spacing.chromeGap;\n const maxWidth = width - padding * 2;\n const fontFamily = theme.fonts.family;\n\n // Track vertical cursor for top elements\n let topY = padding;\n const topElements: Partial<Pick<ResolvedChrome, 'title' | 'subtitle'>> = {};\n\n // Title\n const titleNorm = normalizeChromeText(chrome.title);\n if (titleNorm) {\n const style = buildTextStyle(\n theme.chrome.title,\n fontFamily,\n theme.chrome.title.color,\n titleNorm.style,\n );\n const lineCount = estimateLineCount(titleNorm.text, style, maxWidth, measureText);\n const element: ResolvedChromeElement = {\n text: titleNorm.text,\n x: padding + (titleNorm.offset?.dx ?? 0),\n y: topY + (titleNorm.offset?.dy ?? 0),\n maxWidth,\n style,\n };\n topElements.title = element;\n topY += estimateTextHeight(style.fontSize, lineCount, style.lineHeight) + chromeGap;\n }\n\n // Subtitle\n const subtitleNorm = normalizeChromeText(chrome.subtitle);\n if (subtitleNorm) {\n const style = buildTextStyle(\n theme.chrome.subtitle,\n fontFamily,\n theme.chrome.subtitle.color,\n subtitleNorm.style,\n );\n const lineCount = estimateLineCount(subtitleNorm.text, style, maxWidth, measureText);\n const element: ResolvedChromeElement = {\n text: subtitleNorm.text,\n x: padding + (subtitleNorm.offset?.dx ?? 0),\n y: topY + (subtitleNorm.offset?.dy ?? 0),\n maxWidth,\n style,\n };\n topElements.subtitle = element;\n topY += estimateTextHeight(style.fontSize, lineCount, style.lineHeight) + chromeGap;\n }\n\n // Add chromeToChart gap if there are any top elements\n const hasTopChrome = titleNorm || subtitleNorm;\n const topHeight = hasTopChrome ? topY - padding + theme.spacing.chromeToChart - chromeGap : 0;\n\n // Bottom elements: source, byline, footer\n // We compute heights bottom-up but position them after knowing total\n const bottomElements: Partial<Pick<ResolvedChrome, 'source' | 'byline' | 'footer'>> = {};\n let bottomHeight = 0;\n\n const bottomItems: Array<{\n key: 'source' | 'byline' | 'footer';\n norm: { text: string; style?: ChromeText['style']; offset?: ChromeText['offset'] };\n defaults: ChromeDefaults;\n }> = [];\n\n const sourceNorm = normalizeChromeText(chrome.source);\n if (sourceNorm) {\n bottomItems.push({\n key: 'source',\n norm: sourceNorm,\n defaults: theme.chrome.source,\n });\n }\n\n const bylineNorm = normalizeChromeText(chrome.byline);\n if (bylineNorm) {\n bottomItems.push({\n key: 'byline',\n norm: bylineNorm,\n defaults: theme.chrome.byline,\n });\n }\n\n const footerNorm = normalizeChromeText(chrome.footer);\n if (footerNorm) {\n bottomItems.push({\n key: 'footer',\n norm: footerNorm,\n defaults: theme.chrome.footer,\n });\n }\n\n if (bottomItems.length > 0) {\n bottomHeight += theme.spacing.chartToFooter;\n\n for (const item of bottomItems) {\n const style = buildTextStyle(item.defaults, fontFamily, item.defaults.color, item.norm.style);\n const lineCount = estimateLineCount(item.norm.text, style, maxWidth, measureText);\n const height = estimateTextHeight(style.fontSize, lineCount, style.lineHeight);\n\n // y positions will be computed relative to the bottom of the\n // chart area by the engine. We store offsets from bottom start.\n bottomElements[item.key] = {\n text: item.norm.text,\n x: padding + (item.norm.offset?.dx ?? 0),\n y: bottomHeight + (item.norm.offset?.dy ?? 0), // offset from where bottom chrome starts\n maxWidth,\n style,\n };\n\n bottomHeight += height + chromeGap;\n }\n\n // Remove trailing gap\n bottomHeight -= chromeGap;\n // Add bottom padding\n bottomHeight += padding;\n }\n\n return {\n topHeight,\n bottomHeight,\n ...topElements,\n ...bottomElements,\n };\n}\n","/**\n * Responsive breakpoints and layout strategies.\n *\n * Three breakpoints based on container width:\n * - compact: < 400px (mobile, small embeds)\n * - medium: 400-700px (tablet, sidebars)\n * - full: > 700px (desktop, full-width)\n */\n\n// ---------------------------------------------------------------------------\n// Breakpoint type and detection\n// ---------------------------------------------------------------------------\n\n/** Responsive breakpoint based on container width. */\nexport type Breakpoint = 'compact' | 'medium' | 'full';\n\n/** Breakpoint thresholds in pixels. */\nexport const BREAKPOINT_COMPACT_MAX = 400;\nexport const BREAKPOINT_MEDIUM_MAX = 700;\n\n/**\n * Determine the breakpoint for a given container width.\n */\nexport function getBreakpoint(width: number): Breakpoint {\n if (width < BREAKPOINT_COMPACT_MAX) return 'compact';\n if (width <= BREAKPOINT_MEDIUM_MAX) return 'medium';\n return 'full';\n}\n\n// ---------------------------------------------------------------------------\n// Layout strategy\n// ---------------------------------------------------------------------------\n\n/** Label display mode at a given breakpoint. */\nexport type LabelMode = 'all' | 'important' | 'none';\n\n/** Legend position at a given breakpoint. */\nexport type LegendPosition = 'top' | 'right' | 'bottom' | 'bottom-right' | 'inline';\n\n/** Annotation position strategy. */\nexport type AnnotationPosition = 'inline' | 'tooltip-only';\n\n/** Axis label density (controls tick count reduction). */\nexport type AxisLabelDensity = 'full' | 'reduced' | 'minimal';\n\n/**\n * Layout strategy defining how the visualization adapts to available space.\n * Returned by getLayoutStrategy() based on the current breakpoint.\n */\nexport interface LayoutStrategy {\n /** How data labels are displayed. */\n labelMode: LabelMode;\n /** Where the legend is positioned. */\n legendPosition: LegendPosition;\n /** How annotations are displayed. */\n annotationPosition: AnnotationPosition;\n /** Axis tick density. */\n axisLabelDensity: AxisLabelDensity;\n}\n\n/**\n * Get the layout strategy for a given breakpoint.\n *\n * Compact: minimal chrome, no inline labels, legend on top, reduced axes.\n * Medium: moderate labels, legend on top, reduced axes.\n * Full: all labels, legend on right, full axes.\n */\nexport function getLayoutStrategy(breakpoint: Breakpoint): LayoutStrategy {\n switch (breakpoint) {\n case 'compact':\n return {\n labelMode: 'none',\n legendPosition: 'top',\n annotationPosition: 'tooltip-only',\n axisLabelDensity: 'minimal',\n };\n case 'medium':\n return {\n labelMode: 'important',\n legendPosition: 'top',\n annotationPosition: 'inline',\n axisLabelDensity: 'reduced',\n };\n case 'full':\n return {\n labelMode: 'all',\n legendPosition: 'right',\n annotationPosition: 'inline',\n axisLabelDensity: 'full',\n };\n }\n}\n","/**\n * Label collision detection and resolution.\n *\n * Greedy algorithm: sort by priority, place in order, try offset\n * positions for conflicts, demote to tooltip-only if no position works.\n * Targeting ~60% of Infrographic quality for Phase 0.\n */\n\nimport type { Rect, ResolvedLabel, TextStyle } from '../types/layout';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Priority levels for label placement. Data labels win over annotations which win over axes. */\nexport type LabelPriority = 'data' | 'annotation' | 'axis';\n\n/** Priority sort order (lower = higher priority). */\nconst PRIORITY_ORDER: Record<LabelPriority, number> = {\n data: 0,\n annotation: 1,\n axis: 2,\n};\n\n/**\n * A label candidate for collision resolution.\n * The collision engine decides its final position and visibility.\n */\nexport interface LabelCandidate {\n /** The label text. */\n text: string;\n /** Preferred anchor position (before collision resolution). */\n anchorX: number;\n /** Preferred anchor position (before collision resolution). */\n anchorY: number;\n /** Estimated width of the label text. */\n width: number;\n /** Estimated height of the label text. */\n height: number;\n /** Label priority for collision resolution. */\n priority: LabelPriority;\n /** Text style to apply. */\n style: TextStyle;\n}\n\n// ---------------------------------------------------------------------------\n// Collision detection\n// ---------------------------------------------------------------------------\n\n/**\n * Detect AABB (axis-aligned bounding box) overlap between two rectangles.\n */\nexport function detectCollision(a: Rect, b: Rect): boolean {\n return a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y;\n}\n\n// ---------------------------------------------------------------------------\n// Offset strategies\n// ---------------------------------------------------------------------------\n\n/** Offsets to try when a label collides with an existing placement. */\nconst OFFSET_STRATEGIES = [\n { dx: 0, dy: 0 }, // original position\n { dx: 0, dy: -1.2 }, // above (factor of height)\n { dx: 0, dy: 1.2 }, // below\n { dx: 1.1, dy: 0 }, // right\n { dx: -1.1, dy: 0 }, // left\n { dx: 1.1, dy: -1.2 }, // upper-right\n { dx: -1.1, dy: -1.2 }, // upper-left\n];\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve label collisions using a greedy placement algorithm.\n *\n * Sorts labels by priority (data > annotation > axis), then places\n * each label at its preferred position. If it collides with an already-placed\n * label, tries offset positions. If no position works, the label is\n * demoted to tooltip-only (visible: false).\n *\n * @param labels - Array of label candidates to position.\n * @returns Array of resolved labels with computed positions and visibility.\n */\nexport function resolveCollisions(labels: LabelCandidate[]): ResolvedLabel[] {\n // Sort by priority (highest first)\n const sorted = [...labels].sort(\n (a, b) => PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority],\n );\n\n const placed: Rect[] = [];\n const results: ResolvedLabel[] = [];\n\n for (const label of sorted) {\n let bestRect: Rect | null = null;\n let bestX = label.anchorX;\n let bestY = label.anchorY;\n\n // Try each offset strategy\n for (const offset of OFFSET_STRATEGIES) {\n const candidateX = label.anchorX + offset.dx * label.width;\n const candidateY = label.anchorY + offset.dy * label.height;\n const candidateRect: Rect = {\n x: candidateX,\n y: candidateY,\n width: label.width,\n height: label.height,\n };\n\n const hasCollision = placed.some((p) => detectCollision(candidateRect, p));\n\n if (!hasCollision) {\n bestRect = candidateRect;\n bestX = candidateX;\n bestY = candidateY;\n break;\n }\n }\n\n if (bestRect) {\n placed.push(bestRect);\n const nudgeDx = bestX - label.anchorX;\n const nudgeDy = bestY - label.anchorY;\n const nudgeDist = Math.sqrt(nudgeDx * nudgeDx + nudgeDy * nudgeDy);\n // Only show a connector when the label is nudged far enough that the\n // reader can't tell which data point it belongs to. Short nudges between\n // adjacent series labels produce visual noise without aiding comprehension.\n const MIN_CONNECTOR_DISTANCE = 20;\n const needsConnector = nudgeDist >= MIN_CONNECTOR_DISTANCE;\n\n results.push({\n text: label.text,\n x: bestX,\n y: bestY,\n style: label.style,\n visible: true,\n connector: needsConnector\n ? {\n from: { x: bestX, y: bestY },\n to: { x: label.anchorX, y: label.anchorY },\n stroke: label.style.fill,\n style: 'straight' as const,\n }\n : undefined,\n });\n } else {\n // No position works, demote to tooltip-only\n results.push({\n text: label.text,\n x: label.anchorX,\n y: label.anchorY,\n style: label.style,\n visible: false,\n });\n }\n }\n\n return results;\n}\n","export default function(x) {\n return Math.abs(x = Math.round(x)) >= 1e21\n ? x.toLocaleString(\"en\").replace(/,/g, \"\")\n : x.toString(10);\n}\n\n// Computes the decimal coefficient and exponent of the specified number x with\n// significant digits p, where x is positive and p is in [1, 21] or undefined.\n// For example, formatDecimalParts(1.23) returns [\"123\", 0].\nexport function formatDecimalParts(x, p) {\n if (!isFinite(x) || x === 0) return null; // NaN, ±Infinity, ±0\n var i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf(\"e\"), coefficient = x.slice(0, i);\n\n // The string returned by toExponential either has the form \\d\\.\\d+e[-+]\\d+\n // (e.g., 1.2e+3) or the form \\de[-+]\\d+ (e.g., 1e+3).\n return [\n coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,\n +x.slice(i + 1)\n ];\n}\n","import {formatDecimalParts} from \"./formatDecimal.js\";\n\nexport default function(x) {\n return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN;\n}\n","export default function(grouping, thousands) {\n return function(value, width) {\n var i = value.length,\n t = [],\n j = 0,\n g = grouping[0],\n length = 0;\n\n while (i > 0 && g > 0) {\n if (length + g + 1 > width) g = Math.max(1, width - length);\n t.push(value.substring(i -= g, i + g));\n if ((length += g + 1) > width) break;\n g = grouping[j = (j + 1) % grouping.length];\n }\n\n return t.reverse().join(thousands);\n };\n}\n","export default function(numerals) {\n return function(value) {\n return value.replace(/[0-9]/g, function(i) {\n return numerals[+i];\n });\n };\n}\n","// [[fill]align][sign][symbol][0][width][,][.precision][~][type]\nvar re = /^(?:(.)?([<>=^]))?([+\\-( ])?([$#])?(0)?(\\d+)?(,)?(\\.\\d+)?(~)?([a-z%])?$/i;\n\nexport default function formatSpecifier(specifier) {\n if (!(match = re.exec(specifier))) throw new Error(\"invalid format: \" + specifier);\n var match;\n return new FormatSpecifier({\n fill: match[1],\n align: match[2],\n sign: match[3],\n symbol: match[4],\n zero: match[5],\n width: match[6],\n comma: match[7],\n precision: match[8] && match[8].slice(1),\n trim: match[9],\n type: match[10]\n });\n}\n\nformatSpecifier.prototype = FormatSpecifier.prototype; // instanceof\n\nexport function FormatSpecifier(specifier) {\n this.fill = specifier.fill === undefined ? \" \" : specifier.fill + \"\";\n this.align = specifier.align === undefined ? \">\" : specifier.align + \"\";\n this.sign = specifier.sign === undefined ? \"-\" : specifier.sign + \"\";\n this.symbol = specifier.symbol === undefined ? \"\" : specifier.symbol + \"\";\n this.zero = !!specifier.zero;\n this.width = specifier.width === undefined ? undefined : +specifier.width;\n this.comma = !!specifier.comma;\n this.precision = specifier.precision === undefined ? undefined : +specifier.precision;\n this.trim = !!specifier.trim;\n this.type = specifier.type === undefined ? \"\" : specifier.type + \"\";\n}\n\nFormatSpecifier.prototype.toString = function() {\n return this.fill\n + this.align\n + this.sign\n + this.symbol\n + (this.zero ? \"0\" : \"\")\n + (this.width === undefined ? \"\" : Math.max(1, this.width | 0))\n + (this.comma ? \",\" : \"\")\n + (this.precision === undefined ? \"\" : \".\" + Math.max(0, this.precision | 0))\n + (this.trim ? \"~\" : \"\")\n + this.type;\n};\n","// Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k.\nexport default function(s) {\n out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) {\n switch (s[i]) {\n case \".\": i0 = i1 = i; break;\n case \"0\": if (i0 === 0) i0 = i; i1 = i; break;\n default: if (!+s[i]) break out; if (i0 > 0) i0 = 0; break;\n }\n }\n return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s;\n}\n","import {formatDecimalParts} from \"./formatDecimal.js\";\n\nexport var prefixExponent;\n\nexport default function(x, p) {\n var d = formatDecimalParts(x, p);\n if (!d) return prefixExponent = undefined, x.toPrecision(p);\n var coefficient = d[0],\n exponent = d[1],\n i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,\n n = coefficient.length;\n return i === n ? coefficient\n : i > n ? coefficient + new Array(i - n + 1).join(\"0\")\n : i > 0 ? coefficient.slice(0, i) + \".\" + coefficient.slice(i)\n : \"0.\" + new Array(1 - i).join(\"0\") + formatDecimalParts(x, Math.max(0, p + i - 1))[0]; // less than 1y!\n}\n","import {formatDecimalParts} from \"./formatDecimal.js\";\n\nexport default function(x, p) {\n var d = formatDecimalParts(x, p);\n if (!d) return x + \"\";\n var coefficient = d[0],\n exponent = d[1];\n return exponent < 0 ? \"0.\" + new Array(-exponent).join(\"0\") + coefficient\n : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + \".\" + coefficient.slice(exponent + 1)\n : coefficient + new Array(exponent - coefficient.length + 2).join(\"0\");\n}\n","import formatDecimal from \"./formatDecimal.js\";\nimport formatPrefixAuto from \"./formatPrefixAuto.js\";\nimport formatRounded from \"./formatRounded.js\";\n\nexport default {\n \"%\": (x, p) => (x * 100).toFixed(p),\n \"b\": (x) => Math.round(x).toString(2),\n \"c\": (x) => x + \"\",\n \"d\": formatDecimal,\n \"e\": (x, p) => x.toExponential(p),\n \"f\": (x, p) => x.toFixed(p),\n \"g\": (x, p) => x.toPrecision(p),\n \"o\": (x) => Math.round(x).toString(8),\n \"p\": (x, p) => formatRounded(x * 100, p),\n \"r\": formatRounded,\n \"s\": formatPrefixAuto,\n \"X\": (x) => Math.round(x).toString(16).toUpperCase(),\n \"x\": (x) => Math.round(x).toString(16)\n};\n","export default function(x) {\n return x;\n}\n","import exponent from \"./exponent.js\";\nimport formatGroup from \"./formatGroup.js\";\nimport formatNumerals from \"./formatNumerals.js\";\nimport formatSpecifier from \"./formatSpecifier.js\";\nimport formatTrim from \"./formatTrim.js\";\nimport formatTypes from \"./formatTypes.js\";\nimport {prefixExponent} from \"./formatPrefixAuto.js\";\nimport identity from \"./identity.js\";\n\nvar map = Array.prototype.map,\n prefixes = [\"y\",\"z\",\"a\",\"f\",\"p\",\"n\",\"µ\",\"m\",\"\",\"k\",\"M\",\"G\",\"T\",\"P\",\"E\",\"Z\",\"Y\"];\n\nexport default function(locale) {\n var group = locale.grouping === undefined || locale.thousands === undefined ? identity : formatGroup(map.call(locale.grouping, Number), locale.thousands + \"\"),\n currencyPrefix = locale.currency === undefined ? \"\" : locale.currency[0] + \"\",\n currencySuffix = locale.currency === undefined ? \"\" : locale.currency[1] + \"\",\n decimal = locale.decimal === undefined ? \".\" : locale.decimal + \"\",\n numerals = locale.numerals === undefined ? identity : formatNumerals(map.call(locale.numerals, String)),\n percent = locale.percent === undefined ? \"%\" : locale.percent + \"\",\n minus = locale.minus === undefined ? \"−\" : locale.minus + \"\",\n nan = locale.nan === undefined ? \"NaN\" : locale.nan + \"\";\n\n function newFormat(specifier, options) {\n specifier = formatSpecifier(specifier);\n\n var fill = specifier.fill,\n align = specifier.align,\n sign = specifier.sign,\n symbol = specifier.symbol,\n zero = specifier.zero,\n width = specifier.width,\n comma = specifier.comma,\n precision = specifier.precision,\n trim = specifier.trim,\n type = specifier.type;\n\n // The \"n\" type is an alias for \",g\".\n if (type === \"n\") comma = true, type = \"g\";\n\n // The \"\" type, and any invalid type, is an alias for \".12~g\".\n else if (!formatTypes[type]) precision === undefined && (precision = 12), trim = true, type = \"g\";\n\n // If zero fill is specified, padding goes after sign and before digits.\n if (zero || (fill === \"0\" && align === \"=\")) zero = true, fill = \"0\", align = \"=\";\n\n // Compute the prefix and suffix.\n // For SI-prefix, the suffix is lazily computed.\n var prefix = (options && options.prefix !== undefined ? options.prefix : \"\") + (symbol === \"$\" ? currencyPrefix : symbol === \"#\" && /[boxX]/.test(type) ? \"0\" + type.toLowerCase() : \"\"),\n suffix = (symbol === \"$\" ? currencySuffix : /[%p]/.test(type) ? percent : \"\") + (options && options.suffix !== undefined ? options.suffix : \"\");\n\n // What format function should we use?\n // Is this an integer type?\n // Can this type generate exponential notation?\n var formatType = formatTypes[type],\n maybeSuffix = /[defgprs%]/.test(type);\n\n // Set the default precision if not specified,\n // or clamp the specified precision to the supported range.\n // For significant precision, it must be in [1, 21].\n // For fixed precision, it must be in [0, 20].\n precision = precision === undefined ? 6\n : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))\n : Math.max(0, Math.min(20, precision));\n\n function format(value) {\n var valuePrefix = prefix,\n valueSuffix = suffix,\n i, n, c;\n\n if (type === \"c\") {\n valueSuffix = formatType(value) + valueSuffix;\n value = \"\";\n } else {\n value = +value;\n\n // Determine the sign. -0 is not less than 0, but 1 / -0 is!\n var valueNegative = value < 0 || 1 / value < 0;\n\n // Perform the initial formatting.\n value = isNaN(value) ? nan : formatType(Math.abs(value), precision);\n\n // Trim insignificant zeros.\n if (trim) value = formatTrim(value);\n\n // If a negative value rounds to zero after formatting, and no explicit positive sign is requested, hide the sign.\n if (valueNegative && +value === 0 && sign !== \"+\") valueNegative = false;\n\n // Compute the prefix and suffix.\n valuePrefix = (valueNegative ? (sign === \"(\" ? sign : minus) : sign === \"-\" || sign === \"(\" ? \"\" : sign) + valuePrefix;\n valueSuffix = (type === \"s\" && !isNaN(value) && prefixExponent !== undefined ? prefixes[8 + prefixExponent / 3] : \"\") + valueSuffix + (valueNegative && sign === \"(\" ? \")\" : \"\");\n\n // Break the formatted value into the integer “value” part that can be\n // grouped, and fractional or exponential “suffix” part that is not.\n if (maybeSuffix) {\n i = -1, n = value.length;\n while (++i < n) {\n if (c = value.charCodeAt(i), 48 > c || c > 57) {\n valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;\n value = value.slice(0, i);\n break;\n }\n }\n }\n }\n\n // If the fill character is not \"0\", grouping is applied before padding.\n if (comma && !zero) value = group(value, Infinity);\n\n // Compute the padding.\n var length = valuePrefix.length + value.length + valueSuffix.length,\n padding = length < width ? new Array(width - length + 1).join(fill) : \"\";\n\n // If the fill character is \"0\", grouping is applied after padding.\n if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = \"\";\n\n // Reconstruct the final output based on the desired alignment.\n switch (align) {\n case \"<\": value = valuePrefix + value + valueSuffix + padding; break;\n case \"=\": value = valuePrefix + padding + value + valueSuffix; break;\n case \"^\": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;\n default: value = padding + valuePrefix + value + valueSuffix; break;\n }\n\n return numerals(value);\n }\n\n format.toString = function() {\n return specifier + \"\";\n };\n\n return format;\n }\n\n function formatPrefix(specifier, value) {\n var e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3,\n k = Math.pow(10, -e),\n f = newFormat((specifier = formatSpecifier(specifier), specifier.type = \"f\", specifier), {suffix: prefixes[8 + e / 3]});\n return function(value) {\n return f(k * value);\n };\n }\n\n return {\n format: newFormat,\n formatPrefix: formatPrefix\n };\n}\n","import formatLocale from \"./locale.js\";\n\nvar locale;\nexport var format;\nexport var formatPrefix;\n\ndefaultLocale({\n thousands: \",\",\n grouping: [3],\n currency: [\"$\", \"\"]\n});\n\nexport default function defaultLocale(definition) {\n locale = formatLocale(definition);\n format = locale.format;\n formatPrefix = locale.formatPrefix;\n return locale;\n}\n","const t0 = new Date, t1 = new Date;\n\nexport function timeInterval(floori, offseti, count, field) {\n\n function interval(date) {\n return floori(date = arguments.length === 0 ? new Date : new Date(+date)), date;\n }\n\n interval.floor = (date) => {\n return floori(date = new Date(+date)), date;\n };\n\n interval.ceil = (date) => {\n return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;\n };\n\n interval.round = (date) => {\n const d0 = interval(date), d1 = interval.ceil(date);\n return date - d0 < d1 - date ? d0 : d1;\n };\n\n interval.offset = (date, step) => {\n return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;\n };\n\n interval.range = (start, stop, step) => {\n const range = [];\n start = interval.ceil(start);\n step = step == null ? 1 : Math.floor(step);\n if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date\n let previous;\n do range.push(previous = new Date(+start)), offseti(start, step), floori(start);\n while (previous < start && start < stop);\n return range;\n };\n\n interval.filter = (test) => {\n return timeInterval((date) => {\n if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);\n }, (date, step) => {\n if (date >= date) {\n if (step < 0) while (++step <= 0) {\n while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty\n } else while (--step >= 0) {\n while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty\n }\n }\n });\n };\n\n if (count) {\n interval.count = (start, end) => {\n t0.setTime(+start), t1.setTime(+end);\n floori(t0), floori(t1);\n return Math.floor(count(t0, t1));\n };\n\n interval.every = (step) => {\n step = Math.floor(step);\n return !isFinite(step) || !(step > 0) ? null\n : !(step > 1) ? interval\n : interval.filter(field\n ? (d) => field(d) % step === 0\n : (d) => interval.count(0, d) % step === 0);\n };\n }\n\n return interval;\n}\n","export const durationSecond = 1000;\nexport const durationMinute = durationSecond * 60;\nexport const durationHour = durationMinute * 60;\nexport const durationDay = durationHour * 24;\nexport const durationWeek = durationDay * 7;\nexport const durationMonth = durationDay * 30;\nexport const durationYear = durationDay * 365;\n","import {timeInterval} from \"./interval.js\";\nimport {durationDay, durationMinute} from \"./duration.js\";\n\nexport const timeDay = timeInterval(\n date => date.setHours(0, 0, 0, 0),\n (date, step) => date.setDate(date.getDate() + step),\n (start, end) => (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay,\n date => date.getDate() - 1\n);\n\nexport const timeDays = timeDay.range;\n\nexport const utcDay = timeInterval((date) => {\n date.setUTCHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setUTCDate(date.getUTCDate() + step);\n}, (start, end) => {\n return (end - start) / durationDay;\n}, (date) => {\n return date.getUTCDate() - 1;\n});\n\nexport const utcDays = utcDay.range;\n\nexport const unixDay = timeInterval((date) => {\n date.setUTCHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setUTCDate(date.getUTCDate() + step);\n}, (start, end) => {\n return (end - start) / durationDay;\n}, (date) => {\n return Math.floor(date / durationDay);\n});\n\nexport const unixDays = unixDay.range;\n","import {timeInterval} from \"./interval.js\";\nimport {durationMinute, durationWeek} from \"./duration.js\";\n\nfunction timeWeekday(i) {\n return timeInterval((date) => {\n date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);\n date.setHours(0, 0, 0, 0);\n }, (date, step) => {\n date.setDate(date.getDate() + step * 7);\n }, (start, end) => {\n return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek;\n });\n}\n\nexport const timeSunday = timeWeekday(0);\nexport const timeMonday = timeWeekday(1);\nexport const timeTuesday = timeWeekday(2);\nexport const timeWednesday = timeWeekday(3);\nexport const timeThursday = timeWeekday(4);\nexport const timeFriday = timeWeekday(5);\nexport const timeSaturday = timeWeekday(6);\n\nexport const timeSundays = timeSunday.range;\nexport const timeMondays = timeMonday.range;\nexport const timeTuesdays = timeTuesday.range;\nexport const timeWednesdays = timeWednesday.range;\nexport const timeThursdays = timeThursday.range;\nexport const timeFridays = timeFriday.range;\nexport const timeSaturdays = timeSaturday.range;\n\nfunction utcWeekday(i) {\n return timeInterval((date) => {\n date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);\n date.setUTCHours(0, 0, 0, 0);\n }, (date, step) => {\n date.setUTCDate(date.getUTCDate() + step * 7);\n }, (start, end) => {\n return (end - start) / durationWeek;\n });\n}\n\nexport const utcSunday = utcWeekday(0);\nexport const utcMonday = utcWeekday(1);\nexport const utcTuesday = utcWeekday(2);\nexport const utcWednesday = utcWeekday(3);\nexport const utcThursday = utcWeekday(4);\nexport const utcFriday = utcWeekday(5);\nexport const utcSaturday = utcWeekday(6);\n\nexport const utcSundays = utcSunday.range;\nexport const utcMondays = utcMonday.range;\nexport const utcTuesdays = utcTuesday.range;\nexport const utcWednesdays = utcWednesday.range;\nexport const utcThursdays = utcThursday.range;\nexport const utcFridays = utcFriday.range;\nexport const utcSaturdays = utcSaturday.range;\n","import {timeInterval} from \"./interval.js\";\n\nexport const timeYear = timeInterval((date) => {\n date.setMonth(0, 1);\n date.setHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setFullYear(date.getFullYear() + step);\n}, (start, end) => {\n return end.getFullYear() - start.getFullYear();\n}, (date) => {\n return date.getFullYear();\n});\n\n// An optimized implementation for this simple case.\ntimeYear.every = (k) => {\n return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : timeInterval((date) => {\n date.setFullYear(Math.floor(date.getFullYear() / k) * k);\n date.setMonth(0, 1);\n date.setHours(0, 0, 0, 0);\n }, (date, step) => {\n date.setFullYear(date.getFullYear() + step * k);\n });\n};\n\nexport const timeYears = timeYear.range;\n\nexport const utcYear = timeInterval((date) => {\n date.setUTCMonth(0, 1);\n date.setUTCHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setUTCFullYear(date.getUTCFullYear() + step);\n}, (start, end) => {\n return end.getUTCFullYear() - start.getUTCFullYear();\n}, (date) => {\n return date.getUTCFullYear();\n});\n\n// An optimized implementation for this simple case.\nutcYear.every = (k) => {\n return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : timeInterval((date) => {\n date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);\n date.setUTCMonth(0, 1);\n date.setUTCHours(0, 0, 0, 0);\n }, (date, step) => {\n date.setUTCFullYear(date.getUTCFullYear() + step * k);\n });\n};\n\nexport const utcYears = utcYear.range;\n","import {\n timeDay,\n timeSunday,\n timeMonday,\n timeThursday,\n timeYear,\n utcDay,\n utcSunday,\n utcMonday,\n utcThursday,\n utcYear\n} from \"d3-time\";\n\nfunction localDate(d) {\n if (0 <= d.y && d.y < 100) {\n var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);\n date.setFullYear(d.y);\n return date;\n }\n return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);\n}\n\nfunction utcDate(d) {\n if (0 <= d.y && d.y < 100) {\n var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));\n date.setUTCFullYear(d.y);\n return date;\n }\n return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));\n}\n\nfunction newDate(y, m, d) {\n return {y: y, m: m, d: d, H: 0, M: 0, S: 0, L: 0};\n}\n\nexport default function formatLocale(locale) {\n var locale_dateTime = locale.dateTime,\n locale_date = locale.date,\n locale_time = locale.time,\n locale_periods = locale.periods,\n locale_weekdays = locale.days,\n locale_shortWeekdays = locale.shortDays,\n locale_months = locale.months,\n locale_shortMonths = locale.shortMonths;\n\n var periodRe = formatRe(locale_periods),\n periodLookup = formatLookup(locale_periods),\n weekdayRe = formatRe(locale_weekdays),\n weekdayLookup = formatLookup(locale_weekdays),\n shortWeekdayRe = formatRe(locale_shortWeekdays),\n shortWeekdayLookup = formatLookup(locale_shortWeekdays),\n monthRe = formatRe(locale_months),\n monthLookup = formatLookup(locale_months),\n shortMonthRe = formatRe(locale_shortMonths),\n shortMonthLookup = formatLookup(locale_shortMonths);\n\n var formats = {\n \"a\": formatShortWeekday,\n \"A\": formatWeekday,\n \"b\": formatShortMonth,\n \"B\": formatMonth,\n \"c\": null,\n \"d\": formatDayOfMonth,\n \"e\": formatDayOfMonth,\n \"f\": formatMicroseconds,\n \"g\": formatYearISO,\n \"G\": formatFullYearISO,\n \"H\": formatHour24,\n \"I\": formatHour12,\n \"j\": formatDayOfYear,\n \"L\": formatMilliseconds,\n \"m\": formatMonthNumber,\n \"M\": formatMinutes,\n \"p\": formatPeriod,\n \"q\": formatQuarter,\n \"Q\": formatUnixTimestamp,\n \"s\": formatUnixTimestampSeconds,\n \"S\": formatSeconds,\n \"u\": formatWeekdayNumberMonday,\n \"U\": formatWeekNumberSunday,\n \"V\": formatWeekNumberISO,\n \"w\": formatWeekdayNumberSunday,\n \"W\": formatWeekNumberMonday,\n \"x\": null,\n \"X\": null,\n \"y\": formatYear,\n \"Y\": formatFullYear,\n \"Z\": formatZone,\n \"%\": formatLiteralPercent\n };\n\n var utcFormats = {\n \"a\": formatUTCShortWeekday,\n \"A\": formatUTCWeekday,\n \"b\": formatUTCShortMonth,\n \"B\": formatUTCMonth,\n \"c\": null,\n \"d\": formatUTCDayOfMonth,\n \"e\": formatUTCDayOfMonth,\n \"f\": formatUTCMicroseconds,\n \"g\": formatUTCYearISO,\n \"G\": formatUTCFullYearISO,\n \"H\": formatUTCHour24,\n \"I\": formatUTCHour12,\n \"j\": formatUTCDayOfYear,\n \"L\": formatUTCMilliseconds,\n \"m\": formatUTCMonthNumber,\n \"M\": formatUTCMinutes,\n \"p\": formatUTCPeriod,\n \"q\": formatUTCQuarter,\n \"Q\": formatUnixTimestamp,\n \"s\": formatUnixTimestampSeconds,\n \"S\": formatUTCSeconds,\n \"u\": formatUTCWeekdayNumberMonday,\n \"U\": formatUTCWeekNumberSunday,\n \"V\": formatUTCWeekNumberISO,\n \"w\": formatUTCWeekdayNumberSunday,\n \"W\": formatUTCWeekNumberMonday,\n \"x\": null,\n \"X\": null,\n \"y\": formatUTCYear,\n \"Y\": formatUTCFullYear,\n \"Z\": formatUTCZone,\n \"%\": formatLiteralPercent\n };\n\n var parses = {\n \"a\": parseShortWeekday,\n \"A\": parseWeekday,\n \"b\": parseShortMonth,\n \"B\": parseMonth,\n \"c\": parseLocaleDateTime,\n \"d\": parseDayOfMonth,\n \"e\": parseDayOfMonth,\n \"f\": parseMicroseconds,\n \"g\": parseYear,\n \"G\": parseFullYear,\n \"H\": parseHour24,\n \"I\": parseHour24,\n \"j\": parseDayOfYear,\n \"L\": parseMilliseconds,\n \"m\": parseMonthNumber,\n \"M\": parseMinutes,\n \"p\": parsePeriod,\n \"q\": parseQuarter,\n \"Q\": parseUnixTimestamp,\n \"s\": parseUnixTimestampSeconds,\n \"S\": parseSeconds,\n \"u\": parseWeekdayNumberMonday,\n \"U\": parseWeekNumberSunday,\n \"V\": parseWeekNumberISO,\n \"w\": parseWeekdayNumberSunday,\n \"W\": parseWeekNumberMonday,\n \"x\": parseLocaleDate,\n \"X\": parseLocaleTime,\n \"y\": parseYear,\n \"Y\": parseFullYear,\n \"Z\": parseZone,\n \"%\": parseLiteralPercent\n };\n\n // These recursive directive definitions must be deferred.\n formats.x = newFormat(locale_date, formats);\n formats.X = newFormat(locale_time, formats);\n formats.c = newFormat(locale_dateTime, formats);\n utcFormats.x = newFormat(locale_date, utcFormats);\n utcFormats.X = newFormat(locale_time, utcFormats);\n utcFormats.c = newFormat(locale_dateTime, utcFormats);\n\n function newFormat(specifier, formats) {\n return function(date) {\n var string = [],\n i = -1,\n j = 0,\n n = specifier.length,\n c,\n pad,\n format;\n\n if (!(date instanceof Date)) date = new Date(+date);\n\n while (++i < n) {\n if (specifier.charCodeAt(i) === 37) {\n string.push(specifier.slice(j, i));\n if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);\n else pad = c === \"e\" ? \" \" : \"0\";\n if (format = formats[c]) c = format(date, pad);\n string.push(c);\n j = i + 1;\n }\n }\n\n string.push(specifier.slice(j, i));\n return string.join(\"\");\n };\n }\n\n function newParse(specifier, Z) {\n return function(string) {\n var d = newDate(1900, undefined, 1),\n i = parseSpecifier(d, specifier, string += \"\", 0),\n week, day;\n if (i != string.length) return null;\n\n // If a UNIX timestamp is specified, return it.\n if (\"Q\" in d) return new Date(d.Q);\n if (\"s\" in d) return new Date(d.s * 1000 + (\"L\" in d ? d.L : 0));\n\n // If this is utcParse, never use the local timezone.\n if (Z && !(\"Z\" in d)) d.Z = 0;\n\n // The am-pm flag is 0 for AM, and 1 for PM.\n if (\"p\" in d) d.H = d.H % 12 + d.p * 12;\n\n // If the month was not specified, inherit from the quarter.\n if (d.m === undefined) d.m = \"q\" in d ? d.q : 0;\n\n // Convert day-of-week and week-of-year to day-of-year.\n if (\"V\" in d) {\n if (d.V < 1 || d.V > 53) return null;\n if (!(\"w\" in d)) d.w = 1;\n if (\"Z\" in d) {\n week = utcDate(newDate(d.y, 0, 1)), day = week.getUTCDay();\n week = day > 4 || day === 0 ? utcMonday.ceil(week) : utcMonday(week);\n week = utcDay.offset(week, (d.V - 1) * 7);\n d.y = week.getUTCFullYear();\n d.m = week.getUTCMonth();\n d.d = week.getUTCDate() + (d.w + 6) % 7;\n } else {\n week = localDate(newDate(d.y, 0, 1)), day = week.getDay();\n week = day > 4 || day === 0 ? timeMonday.ceil(week) : timeMonday(week);\n week = timeDay.offset(week, (d.V - 1) * 7);\n d.y = week.getFullYear();\n d.m = week.getMonth();\n d.d = week.getDate() + (d.w + 6) % 7;\n }\n } else if (\"W\" in d || \"U\" in d) {\n if (!(\"w\" in d)) d.w = \"u\" in d ? d.u % 7 : \"W\" in d ? 1 : 0;\n day = \"Z\" in d ? utcDate(newDate(d.y, 0, 1)).getUTCDay() : localDate(newDate(d.y, 0, 1)).getDay();\n d.m = 0;\n d.d = \"W\" in d ? (d.w + 6) % 7 + d.W * 7 - (day + 5) % 7 : d.w + d.U * 7 - (day + 6) % 7;\n }\n\n // If a time zone is specified, all fields are interpreted as UTC and then\n // offset according to the specified time zone.\n if (\"Z\" in d) {\n d.H += d.Z / 100 | 0;\n d.M += d.Z % 100;\n return utcDate(d);\n }\n\n // Otherwise, all fields are in local time.\n return localDate(d);\n };\n }\n\n function parseSpecifier(d, specifier, string, j) {\n var i = 0,\n n = specifier.length,\n m = string.length,\n c,\n parse;\n\n while (i < n) {\n if (j >= m) return -1;\n c = specifier.charCodeAt(i++);\n if (c === 37) {\n c = specifier.charAt(i++);\n parse = parses[c in pads ? specifier.charAt(i++) : c];\n if (!parse || ((j = parse(d, string, j)) < 0)) return -1;\n } else if (c != string.charCodeAt(j++)) {\n return -1;\n }\n }\n\n return j;\n }\n\n function parsePeriod(d, string, i) {\n var n = periodRe.exec(string.slice(i));\n return n ? (d.p = periodLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseShortWeekday(d, string, i) {\n var n = shortWeekdayRe.exec(string.slice(i));\n return n ? (d.w = shortWeekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseWeekday(d, string, i) {\n var n = weekdayRe.exec(string.slice(i));\n return n ? (d.w = weekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseShortMonth(d, string, i) {\n var n = shortMonthRe.exec(string.slice(i));\n return n ? (d.m = shortMonthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseMonth(d, string, i) {\n var n = monthRe.exec(string.slice(i));\n return n ? (d.m = monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseLocaleDateTime(d, string, i) {\n return parseSpecifier(d, locale_dateTime, string, i);\n }\n\n function parseLocaleDate(d, string, i) {\n return parseSpecifier(d, locale_date, string, i);\n }\n\n function parseLocaleTime(d, string, i) {\n return parseSpecifier(d, locale_time, string, i);\n }\n\n function formatShortWeekday(d) {\n return locale_shortWeekdays[d.getDay()];\n }\n\n function formatWeekday(d) {\n return locale_weekdays[d.getDay()];\n }\n\n function formatShortMonth(d) {\n return locale_shortMonths[d.getMonth()];\n }\n\n function formatMonth(d) {\n return locale_months[d.getMonth()];\n }\n\n function formatPeriod(d) {\n return locale_periods[+(d.getHours() >= 12)];\n }\n\n function formatQuarter(d) {\n return 1 + ~~(d.getMonth() / 3);\n }\n\n function formatUTCShortWeekday(d) {\n return locale_shortWeekdays[d.getUTCDay()];\n }\n\n function formatUTCWeekday(d) {\n return locale_weekdays[d.getUTCDay()];\n }\n\n function formatUTCShortMonth(d) {\n return locale_shortMonths[d.getUTCMonth()];\n }\n\n function formatUTCMonth(d) {\n return locale_months[d.getUTCMonth()];\n }\n\n function formatUTCPeriod(d) {\n return locale_periods[+(d.getUTCHours() >= 12)];\n }\n\n function formatUTCQuarter(d) {\n return 1 + ~~(d.getUTCMonth() / 3);\n }\n\n return {\n format: function(specifier) {\n var f = newFormat(specifier += \"\", formats);\n f.toString = function() { return specifier; };\n return f;\n },\n parse: function(specifier) {\n var p = newParse(specifier += \"\", false);\n p.toString = function() { return specifier; };\n return p;\n },\n utcFormat: function(specifier) {\n var f = newFormat(specifier += \"\", utcFormats);\n f.toString = function() { return specifier; };\n return f;\n },\n utcParse: function(specifier) {\n var p = newParse(specifier += \"\", true);\n p.toString = function() { return specifier; };\n return p;\n }\n };\n}\n\nvar pads = {\"-\": \"\", \"_\": \" \", \"0\": \"0\"},\n numberRe = /^\\s*\\d+/, // note: ignores next directive\n percentRe = /^%/,\n requoteRe = /[\\\\^$*+?|[\\]().{}]/g;\n\nfunction pad(value, fill, width) {\n var sign = value < 0 ? \"-\" : \"\",\n string = (sign ? -value : value) + \"\",\n length = string.length;\n return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);\n}\n\nfunction requote(s) {\n return s.replace(requoteRe, \"\\\\$&\");\n}\n\nfunction formatRe(names) {\n return new RegExp(\"^(?:\" + names.map(requote).join(\"|\") + \")\", \"i\");\n}\n\nfunction formatLookup(names) {\n return new Map(names.map((name, i) => [name.toLowerCase(), i]));\n}\n\nfunction parseWeekdayNumberSunday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.w = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekdayNumberMonday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.u = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberSunday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.U = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberISO(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.V = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberMonday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.W = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseFullYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 4));\n return n ? (d.y = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;\n}\n\nfunction parseZone(d, string, i) {\n var n = /^(Z)|([+-]\\d\\d)(?::?(\\d\\d))?/.exec(string.slice(i, i + 6));\n return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || \"00\")), i + n[0].length) : -1;\n}\n\nfunction parseQuarter(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.q = n[0] * 3 - 3, i + n[0].length) : -1;\n}\n\nfunction parseMonthNumber(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.m = n[0] - 1, i + n[0].length) : -1;\n}\n\nfunction parseDayOfMonth(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseDayOfYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 3));\n return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseHour24(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.H = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMinutes(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.M = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseSeconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.S = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMilliseconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 3));\n return n ? (d.L = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMicroseconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 6));\n return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1;\n}\n\nfunction parseLiteralPercent(d, string, i) {\n var n = percentRe.exec(string.slice(i, i + 1));\n return n ? i + n[0].length : -1;\n}\n\nfunction parseUnixTimestamp(d, string, i) {\n var n = numberRe.exec(string.slice(i));\n return n ? (d.Q = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseUnixTimestampSeconds(d, string, i) {\n var n = numberRe.exec(string.slice(i));\n return n ? (d.s = +n[0], i + n[0].length) : -1;\n}\n\nfunction formatDayOfMonth(d, p) {\n return pad(d.getDate(), p, 2);\n}\n\nfunction formatHour24(d, p) {\n return pad(d.getHours(), p, 2);\n}\n\nfunction formatHour12(d, p) {\n return pad(d.getHours() % 12 || 12, p, 2);\n}\n\nfunction formatDayOfYear(d, p) {\n return pad(1 + timeDay.count(timeYear(d), d), p, 3);\n}\n\nfunction formatMilliseconds(d, p) {\n return pad(d.getMilliseconds(), p, 3);\n}\n\nfunction formatMicroseconds(d, p) {\n return formatMilliseconds(d, p) + \"000\";\n}\n\nfunction formatMonthNumber(d, p) {\n return pad(d.getMonth() + 1, p, 2);\n}\n\nfunction formatMinutes(d, p) {\n return pad(d.getMinutes(), p, 2);\n}\n\nfunction formatSeconds(d, p) {\n return pad(d.getSeconds(), p, 2);\n}\n\nfunction formatWeekdayNumberMonday(d) {\n var day = d.getDay();\n return day === 0 ? 7 : day;\n}\n\nfunction formatWeekNumberSunday(d, p) {\n return pad(timeSunday.count(timeYear(d) - 1, d), p, 2);\n}\n\nfunction dISO(d) {\n var day = d.getDay();\n return (day >= 4 || day === 0) ? timeThursday(d) : timeThursday.ceil(d);\n}\n\nfunction formatWeekNumberISO(d, p) {\n d = dISO(d);\n return pad(timeThursday.count(timeYear(d), d) + (timeYear(d).getDay() === 4), p, 2);\n}\n\nfunction formatWeekdayNumberSunday(d) {\n return d.getDay();\n}\n\nfunction formatWeekNumberMonday(d, p) {\n return pad(timeMonday.count(timeYear(d) - 1, d), p, 2);\n}\n\nfunction formatYear(d, p) {\n return pad(d.getFullYear() % 100, p, 2);\n}\n\nfunction formatYearISO(d, p) {\n d = dISO(d);\n return pad(d.getFullYear() % 100, p, 2);\n}\n\nfunction formatFullYear(d, p) {\n return pad(d.getFullYear() % 10000, p, 4);\n}\n\nfunction formatFullYearISO(d, p) {\n var day = d.getDay();\n d = (day >= 4 || day === 0) ? timeThursday(d) : timeThursday.ceil(d);\n return pad(d.getFullYear() % 10000, p, 4);\n}\n\nfunction formatZone(d) {\n var z = d.getTimezoneOffset();\n return (z > 0 ? \"-\" : (z *= -1, \"+\"))\n + pad(z / 60 | 0, \"0\", 2)\n + pad(z % 60, \"0\", 2);\n}\n\nfunction formatUTCDayOfMonth(d, p) {\n return pad(d.getUTCDate(), p, 2);\n}\n\nfunction formatUTCHour24(d, p) {\n return pad(d.getUTCHours(), p, 2);\n}\n\nfunction formatUTCHour12(d, p) {\n return pad(d.getUTCHours() % 12 || 12, p, 2);\n}\n\nfunction formatUTCDayOfYear(d, p) {\n return pad(1 + utcDay.count(utcYear(d), d), p, 3);\n}\n\nfunction formatUTCMilliseconds(d, p) {\n return pad(d.getUTCMilliseconds(), p, 3);\n}\n\nfunction formatUTCMicroseconds(d, p) {\n return formatUTCMilliseconds(d, p) + \"000\";\n}\n\nfunction formatUTCMonthNumber(d, p) {\n return pad(d.getUTCMonth() + 1, p, 2);\n}\n\nfunction formatUTCMinutes(d, p) {\n return pad(d.getUTCMinutes(), p, 2);\n}\n\nfunction formatUTCSeconds(d, p) {\n return pad(d.getUTCSeconds(), p, 2);\n}\n\nfunction formatUTCWeekdayNumberMonday(d) {\n var dow = d.getUTCDay();\n return dow === 0 ? 7 : dow;\n}\n\nfunction formatUTCWeekNumberSunday(d, p) {\n return pad(utcSunday.count(utcYear(d) - 1, d), p, 2);\n}\n\nfunction UTCdISO(d) {\n var day = d.getUTCDay();\n return (day >= 4 || day === 0) ? utcThursday(d) : utcThursday.ceil(d);\n}\n\nfunction formatUTCWeekNumberISO(d, p) {\n d = UTCdISO(d);\n return pad(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2);\n}\n\nfunction formatUTCWeekdayNumberSunday(d) {\n return d.getUTCDay();\n}\n\nfunction formatUTCWeekNumberMonday(d, p) {\n return pad(utcMonday.count(utcYear(d) - 1, d), p, 2);\n}\n\nfunction formatUTCYear(d, p) {\n return pad(d.getUTCFullYear() % 100, p, 2);\n}\n\nfunction formatUTCYearISO(d, p) {\n d = UTCdISO(d);\n return pad(d.getUTCFullYear() % 100, p, 2);\n}\n\nfunction formatUTCFullYear(d, p) {\n return pad(d.getUTCFullYear() % 10000, p, 4);\n}\n\nfunction formatUTCFullYearISO(d, p) {\n var day = d.getUTCDay();\n d = (day >= 4 || day === 0) ? utcThursday(d) : utcThursday.ceil(d);\n return pad(d.getUTCFullYear() % 10000, p, 4);\n}\n\nfunction formatUTCZone() {\n return \"+0000\";\n}\n\nfunction formatLiteralPercent() {\n return \"%\";\n}\n\nfunction formatUnixTimestamp(d) {\n return +d;\n}\n\nfunction formatUnixTimestampSeconds(d) {\n return Math.floor(+d / 1000);\n}\n","import formatLocale from \"./locale.js\";\n\nvar locale;\nexport var timeFormat;\nexport var timeParse;\nexport var utcFormat;\nexport var utcParse;\n\ndefaultLocale({\n dateTime: \"%x, %X\",\n date: \"%-m/%-d/%Y\",\n time: \"%-I:%M:%S %p\",\n periods: [\"AM\", \"PM\"],\n days: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n shortDays: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n months: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"],\n shortMonths: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\n});\n\nexport default function defaultLocale(definition) {\n locale = formatLocale(definition);\n timeFormat = locale.format;\n timeParse = locale.parse;\n utcFormat = locale.utcFormat;\n utcParse = locale.utcParse;\n return locale;\n}\n","/**\n * Locale-aware number and date formatting utilities.\n *\n * Uses d3-format and d3-time-format for formatting,\n * with convenience wrappers for common patterns.\n */\n\nimport { format as d3Format } from 'd3-format';\nimport { timeFormat, utcFormat } from 'd3-time-format';\n\n// ---------------------------------------------------------------------------\n// Number formatting\n// ---------------------------------------------------------------------------\n\n/**\n * Format a number with locale-appropriate separators.\n *\n * Uses d3-format under the hood. Default format: comma-separated\n * with auto-precision (e.g. 1500000 -> \"1,500,000\").\n *\n * @param value - The number to format.\n * @param locale - Locale string (currently unused, reserved for i18n).\n */\nexport function formatNumber(value: number, _locale?: string): string {\n if (!Number.isFinite(value)) return String(value);\n // Auto-detect: use integer format for whole numbers, 2dp for decimals\n if (Number.isInteger(value)) {\n return d3Format(',')(value);\n }\n return d3Format(',.2f')(value);\n}\n\n// ---------------------------------------------------------------------------\n// Number abbreviation\n// ---------------------------------------------------------------------------\n\n/** Suffixes for abbreviated numbers. */\nconst ABBREVIATIONS: Array<{ threshold: number; suffix: string; divisor: number }> = [\n { threshold: 1_000_000_000_000, suffix: 'T', divisor: 1_000_000_000_000 },\n { threshold: 1_000_000_000, suffix: 'B', divisor: 1_000_000_000 },\n { threshold: 1_000_000, suffix: 'M', divisor: 1_000_000 },\n { threshold: 1_000, suffix: 'K', divisor: 1_000 },\n];\n\n/**\n * Abbreviate a large number with a suffix.\n *\n * Examples:\n * - 1500000 -> \"1.5M\"\n * - 2300 -> \"2.3K\"\n * - 42 -> \"42\"\n * - 1000000000 -> \"1B\"\n */\nexport function abbreviateNumber(value: number): string {\n if (!Number.isFinite(value)) return String(value);\n\n const absValue = Math.abs(value);\n const sign = value < 0 ? '-' : '';\n\n for (const { threshold, suffix, divisor } of ABBREVIATIONS) {\n if (absValue >= threshold) {\n const abbreviated = absValue / divisor;\n // Use .1f precision, drop trailing .0\n const formatted = abbreviated % 1 === 0 ? String(abbreviated) : d3Format('.1f')(abbreviated);\n return `${sign}${formatted}${suffix}`;\n }\n }\n\n return formatNumber(value);\n}\n\n// ---------------------------------------------------------------------------\n// d3-format with suffix support\n// ---------------------------------------------------------------------------\n\n/**\n * Regex that matches a valid d3-format specifier (with optional ~ trim flag)\n * followed by a literal suffix. The first capture group is the d3 format part,\n * the second is the trailing literal suffix (e.g. \"T\", \"pp\", etc.).\n *\n * Examples:\n * - \"$,.2~fT\" -> [\"$,.2~f\", \"T\"]\n * - \".0f%\" -> [\".0f\", \"%\"] (% here is literal, not d3 percent type)\n * - \"$,.0f\" -> no match (valid d3 format, no suffix)\n */\nconst D3_FORMAT_SUFFIX_RE = /^(.*~?[efgsrdxXobcnp%])(.+)$/;\n\n/**\n * Build a number formatter from a d3-format string, with support for a\n * trailing literal suffix that d3-format itself would reject.\n *\n * Returns null if the format string is falsy or unparseable.\n */\nexport function buildD3Formatter(formatStr: string | undefined): ((v: number) => string) | null {\n if (!formatStr) return null;\n\n try {\n return d3Format(formatStr);\n } catch {\n // If d3-format rejects it, try stripping a trailing literal suffix\n const m = formatStr.match(D3_FORMAT_SUFFIX_RE);\n if (m) {\n try {\n const fmt = d3Format(m[1]);\n const suffix = m[2];\n return (v: number) => fmt(v) + suffix;\n } catch {\n // Unparseable even after suffix stripping\n }\n }\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Date formatting\n// ---------------------------------------------------------------------------\n\n/** Granularity levels for date formatting. */\nexport type DateGranularity = 'year' | 'quarter' | 'month' | 'week' | 'day' | 'hour' | 'minute';\n\n/** Format strings for each granularity level. */\nconst GRANULARITY_FORMATS: Record<DateGranularity, string> = {\n year: '%Y',\n quarter: '', // Quarter is always special-cased in formatDate() below\n month: '%b %Y',\n week: '%b %d',\n day: '%b %d, %Y',\n hour: '%b %d %H:%M',\n minute: '%H:%M',\n};\n\n/**\n * Format a date value for display.\n *\n * @param value - Date object, ISO string, or timestamp number.\n * @param locale - Locale string (currently unused, reserved for i18n).\n * @param granularity - Time granularity for format selection.\n */\nexport function formatDate(\n value: Date | string | number,\n _locale?: string,\n granularity?: DateGranularity,\n): string {\n const date = value instanceof Date ? value : new Date(value);\n if (Number.isNaN(date.getTime())) return String(value);\n\n const gran = granularity ?? inferGranularity(date);\n\n // Special handling for quarter (not a d3 format token)\n if (gran === 'quarter') {\n const q = Math.ceil((date.getMonth() + 1) / 3);\n return `Q${q} ${date.getFullYear()}`;\n }\n\n const formatStr = GRANULARITY_FORMATS[gran];\n // Use UTC format for year/month/day to avoid timezone shifts\n if (['year', 'month', 'day'].includes(gran)) {\n return utcFormat(formatStr)(date);\n }\n return timeFormat(formatStr)(date);\n}\n\n/**\n * Infer the appropriate granularity from a date value.\n * If time components are all zero, assume day or higher.\n */\nfunction inferGranularity(date: Date): DateGranularity {\n if (date.getHours() !== 0 || date.getMinutes() !== 0) {\n return date.getMinutes() !== 0 ? 'minute' : 'hour';\n }\n if (date.getDate() !== 1) return 'day';\n if (date.getMonth() !== 0) return 'month';\n return 'year';\n}\n","/**\n * Automatic alt text generation for chart accessibility.\n *\n * Produces human-readable descriptions of chart content for screen readers\n * and a tabular fallback for data access.\n */\n\nimport type { ChartSpec, DataRow } from '../types/spec';\n\n// ---------------------------------------------------------------------------\n// Alt text generation\n// ---------------------------------------------------------------------------\n\n/** Friendly display names for chart types. */\nconst CHART_TYPE_NAMES: Record<string, string> = {\n line: 'Line chart',\n area: 'Area chart',\n bar: 'Bar chart',\n column: 'Column chart',\n pie: 'Pie chart',\n donut: 'Donut chart',\n dot: 'Dot plot',\n scatter: 'Scatter plot',\n};\n\n/**\n * Generate alt text describing a chart's content.\n *\n * Produces a description like:\n * \"Line chart showing GDP Growth Rate from 2020 to 2024 with 2 series (US, UK)\"\n *\n * @param spec - The chart spec.\n * @param data - The data array.\n */\nexport function generateAltText(spec: ChartSpec, data: DataRow[]): string {\n const chartName = CHART_TYPE_NAMES[spec.type] ?? `${spec.type} chart`;\n const parts: string[] = [chartName];\n\n // Add title context if present\n const title = spec.chrome?.title;\n if (title) {\n const titleText = typeof title === 'string' ? title : title.text;\n parts.push(`showing ${titleText}`);\n }\n\n // Describe the data range\n if (spec.encoding.x && data.length > 0) {\n const field = spec.encoding.x.field;\n const values = data.map((d) => d[field]).filter((v) => v != null);\n\n if (values.length > 0) {\n if (spec.encoding.x.type === 'temporal') {\n const dates = values.map((v) => (v instanceof Date ? v : new Date(String(v))));\n const validDates = dates.filter((d) => !Number.isNaN(d.getTime()));\n if (validDates.length >= 2) {\n validDates.sort((a, b) => a.getTime() - b.getTime());\n const first = validDates[0].getUTCFullYear();\n const last = validDates[validDates.length - 1].getUTCFullYear();\n if (first !== last) {\n parts.push(`from ${first} to ${last}`);\n }\n }\n } else if (spec.encoding.x.type === 'nominal' || spec.encoding.x.type === 'ordinal') {\n const uniqueValues = [...new Set(values.map(String))];\n parts.push(`across ${uniqueValues.length} categories`);\n }\n }\n }\n\n // Describe series if color encoding is present\n if (spec.encoding.color && data.length > 0) {\n const colorField = spec.encoding.color.field;\n const uniqueSeries = [...new Set(data.map((d) => String(d[colorField])).filter(Boolean))];\n if (uniqueSeries.length > 0) {\n parts.push(`with ${uniqueSeries.length} series (${uniqueSeries.join(', ')})`);\n }\n }\n\n // Add data point count\n parts.push(`(${data.length} data points)`);\n\n return parts.join(' ');\n}\n\n// ---------------------------------------------------------------------------\n// Data table fallback\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a tabular data fallback for screen readers.\n *\n * Returns a 2D array where the first row is headers and subsequent\n * rows are data values. Only includes fields referenced in the encoding.\n *\n * @param spec - The chart spec.\n * @param data - The data array.\n */\nexport function generateDataTable(spec: ChartSpec, data: DataRow[]): unknown[][] {\n // Collect fields from encoding\n const fields: string[] = [];\n const encoding = spec.encoding;\n\n if (encoding.x) fields.push(encoding.x.field);\n if (encoding.y) fields.push(encoding.y.field);\n if (encoding.color) fields.push(encoding.color.field);\n if (encoding.size) fields.push(encoding.size.field);\n\n // Deduplicate\n const uniqueFields = [...new Set(fields)];\n\n if (uniqueFields.length === 0) return [];\n\n // Header row\n const headers = uniqueFields;\n\n // Data rows\n const rows = data.map((row) => uniqueFields.map((field) => row[field] ?? ''));\n\n return [headers, ...rows];\n}\n","/**\n * ARIA label generation for individual marks.\n *\n * Produces per-mark labels for screen reader navigation, enabling\n * users to explore data points individually.\n */\n\nimport type { Mark } from '../types/layout';\n\n/**\n * Generate ARIA labels for a set of marks.\n *\n * Returns a Map keyed by a mark identifier (index-based) with\n * descriptive labels like \"Data point: US GDP 42 in 2020-01\".\n *\n * @param marks - Array of mark objects from the compiled chart layout.\n */\nexport function generateAriaLabels(marks: Mark[]): Map<string, string> {\n const labels = new Map<string, string>();\n\n for (let i = 0; i < marks.length; i++) {\n const mark = marks[i];\n const key = `mark-${i}`;\n\n switch (mark.type) {\n case 'line': {\n const series = mark.seriesKey ?? 'Series';\n const pointCount = mark.points.length;\n labels.set(key, `Line series: ${series} with ${pointCount} points`);\n break;\n }\n\n case 'area': {\n const series = mark.seriesKey ?? 'Area';\n labels.set(key, `Area series: ${series}`);\n break;\n }\n\n case 'rect': {\n const dataEntries = Object.entries(mark.data).filter(([k]) => !k.startsWith('_'));\n const description = dataEntries.map(([k, v]) => `${k}: ${formatValue(v)}`).join(', ');\n labels.set(key, `Data point: ${description}`);\n break;\n }\n\n case 'arc': {\n const dataEntries = Object.entries(mark.data).filter(([k]) => !k.startsWith('_'));\n const description = dataEntries.map(([k, v]) => `${k}: ${formatValue(v)}`).join(', ');\n labels.set(key, `Slice: ${description}`);\n break;\n }\n\n case 'point': {\n const dataEntries = Object.entries(mark.data).filter(([k]) => !k.startsWith('_'));\n const description = dataEntries.map(([k, v]) => `${k}: ${formatValue(v)}`).join(', ');\n labels.set(key, `Data point: ${description}`);\n break;\n }\n }\n }\n\n return labels;\n}\n\n/** Format a data value for use in an ARIA label. */\nfunction formatValue(value: unknown): string {\n if (value == null) return 'N/A';\n if (value instanceof Date) return value.toISOString().slice(0, 10);\n if (typeof value === 'number') {\n return Number.isInteger(value) ? String(value) : value.toFixed(2);\n }\n return String(value);\n}\n","/**\n * Spec construction helpers: typed builder functions for common chart types.\n *\n * These builders reduce boilerplate when creating specs programmatically.\n * They accept field names as strings (simple case) or full EncodingChannel\n * objects (when you need to customize type, aggregate, axis, or scale).\n *\n * Type inference: when a string field name is provided, the builder samples\n * data values to infer the encoding type (quantitative, temporal, nominal).\n */\n\nimport type {\n Annotation,\n ChartSpec,\n ChartType,\n Chrome,\n DarkMode,\n DataRow,\n Encoding,\n EncodingChannel,\n FieldType,\n TableSpec,\n ThemeConfig,\n} from '../types/spec';\nimport type { ColumnConfig } from '../types/table';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** A field reference: either a plain string (field name) or a full EncodingChannel. */\nexport type FieldRef = string | EncodingChannel;\n\n/** Common options shared by all chart builder functions. */\nexport interface ChartBuilderOptions {\n /** Color encoding: field name or full channel config for series differentiation. */\n color?: FieldRef;\n /** Size encoding: field name or full channel config. */\n size?: FieldRef;\n /** Editorial chrome (title, subtitle, source, etc.). */\n chrome?: Chrome;\n /** Data annotations. */\n annotations?: Annotation[];\n /** Whether the chart adapts to container width. Defaults to true. */\n responsive?: boolean;\n /** Theme configuration overrides. */\n theme?: ThemeConfig;\n /** Dark mode behavior. */\n darkMode?: DarkMode;\n}\n\n/** Options for the dataTable builder. */\nexport interface TableBuilderOptions {\n /** Column definitions. Auto-generated from data keys if omitted. */\n columns?: ColumnConfig[];\n /** Field to use as a unique row identifier. */\n rowKey?: string;\n /** Editorial chrome. */\n chrome?: Chrome;\n /** Theme configuration overrides. */\n theme?: ThemeConfig;\n /** Dark mode behavior. */\n darkMode?: DarkMode;\n /** Enable client-side search/filter. */\n search?: boolean;\n /** Pagination configuration. */\n pagination?: boolean | { pageSize: number };\n /** Stick the first column during horizontal scroll. */\n stickyFirstColumn?: boolean;\n /** Compact mode. */\n compact?: boolean;\n /** Whether the table adapts to container width. */\n responsive?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Type inference\n// ---------------------------------------------------------------------------\n\n/** ISO 8601 date patterns we recognize for temporal inference. */\nconst ISO_DATE_RE = /^\\d{4}(-\\d{2}(-\\d{2}(T\\d{2}(:\\d{2}(:\\d{2})?)?)?)?)?$/;\n\n/**\n * Infer the encoding field type from data values.\n *\n * Samples up to 20 values from the data array for the given field.\n * - If all sampled values are numbers (or null/undefined), returns \"quantitative\".\n * - If all sampled string values match ISO date patterns, returns \"temporal\".\n * - Otherwise returns \"nominal\".\n */\nexport function inferFieldType(data: DataRow[], field: string): FieldType {\n const sampleSize = Math.min(data.length, 20);\n let hasNumber = false;\n let hasDateString = false;\n let hasOtherString = false;\n\n for (let i = 0; i < sampleSize; i++) {\n const value = data[i][field];\n\n // Skip null/undefined\n if (value == null) continue;\n\n if (typeof value === 'number') {\n hasNumber = true;\n } else if (typeof value === 'string') {\n if (ISO_DATE_RE.test(value) && !Number.isNaN(Date.parse(value))) {\n hasDateString = true;\n } else {\n hasOtherString = true;\n }\n } else if (value instanceof Date) {\n hasDateString = true;\n } else {\n hasOtherString = true;\n }\n }\n\n // Numbers-only: quantitative\n if (hasNumber && !hasDateString && !hasOtherString) return 'quantitative';\n // Date strings/Date objects only: temporal\n if (hasDateString && !hasNumber && !hasOtherString) return 'temporal';\n // Everything else: nominal\n return 'nominal';\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a FieldRef into a full EncodingChannel.\n * If the ref is a string, infer the type from data.\n */\nfunction resolveField(ref: FieldRef, data: DataRow[]): EncodingChannel {\n if (typeof ref === 'string') {\n return { field: ref, type: inferFieldType(data, ref) };\n }\n return ref;\n}\n\n/** Build the encoding object from resolved channels. */\nfunction buildEncoding(\n channels: { x?: EncodingChannel; y?: EncodingChannel },\n options?: ChartBuilderOptions,\n data?: DataRow[],\n): Encoding {\n const encoding: Encoding = { ...channels };\n if (options?.color && data) {\n encoding.color = resolveField(options.color, data);\n }\n if (options?.size && data) {\n encoding.size = resolveField(options.size, data);\n }\n return encoding;\n}\n\n/** Build a ChartSpec from the resolved pieces. */\nfunction buildChartSpec(\n type: ChartType,\n data: DataRow[],\n encoding: Encoding,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const spec: ChartSpec = { type, data, encoding };\n if (options?.chrome) spec.chrome = options.chrome;\n if (options?.annotations) spec.annotations = options.annotations;\n if (options?.responsive !== undefined) spec.responsive = options.responsive;\n if (options?.theme) spec.theme = options.theme;\n if (options?.darkMode) spec.darkMode = options.darkMode;\n return spec;\n}\n\n// ---------------------------------------------------------------------------\n// Builder functions\n// ---------------------------------------------------------------------------\n\n/**\n * Create a line chart spec.\n *\n * @param data - Array of data rows.\n * @param x - X-axis field (typically temporal or ordinal).\n * @param y - Y-axis field (typically quantitative).\n * @param options - Optional color, size, chrome, annotations, theme, etc.\n */\nexport function lineChart(\n data: DataRow[],\n x: FieldRef,\n y: FieldRef,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const xChannel = resolveField(x, data);\n const yChannel = resolveField(y, data);\n const encoding = buildEncoding({ x: xChannel, y: yChannel }, options, data);\n return buildChartSpec('line', data, encoding, options);\n}\n\n/**\n * Create a bar chart spec (horizontal bars).\n *\n * Convention: category goes on y-axis, value on x-axis.\n * The `category` param maps to y, `value` maps to x.\n *\n * @param data - Array of data rows.\n * @param category - Category field (y-axis, nominal/ordinal).\n * @param value - Value field (x-axis, quantitative).\n * @param options - Optional color, size, chrome, annotations, theme, etc.\n */\nexport function barChart(\n data: DataRow[],\n category: FieldRef,\n value: FieldRef,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const categoryChannel = resolveField(category, data);\n const valueChannel = resolveField(value, data);\n\n // Bar charts: category on y, value on x\n const encoding = buildEncoding({ x: valueChannel, y: categoryChannel }, options, data);\n return buildChartSpec('bar', data, encoding, options);\n}\n\n/**\n * Create a column chart spec (vertical columns).\n *\n * @param data - Array of data rows.\n * @param x - X-axis field (category or temporal).\n * @param y - Y-axis field (quantitative value).\n * @param options - Optional color, size, chrome, annotations, theme, etc.\n */\nexport function columnChart(\n data: DataRow[],\n x: FieldRef,\n y: FieldRef,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const xChannel = resolveField(x, data);\n const yChannel = resolveField(y, data);\n const encoding = buildEncoding({ x: xChannel, y: yChannel }, options, data);\n return buildChartSpec('column', data, encoding, options);\n}\n\n/**\n * Create a pie chart spec.\n *\n * Convention: category maps to the color channel, value maps to y.\n * Pie charts have no x-axis.\n *\n * @param data - Array of data rows.\n * @param category - Category field (color channel, nominal).\n * @param value - Value field (y channel, quantitative).\n * @param options - Optional chrome, annotations, theme, etc.\n * Note: color option is ignored since category is used for color.\n */\nexport function pieChart(\n data: DataRow[],\n category: FieldRef,\n value: FieldRef,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const categoryChannel = resolveField(category, data);\n const valueChannel = resolveField(value, data);\n\n // Pie charts: value on y, category on color (no x-axis)\n const encoding: Encoding = {\n y: valueChannel,\n color: categoryChannel,\n };\n if (options?.size && data) {\n encoding.size = resolveField(options.size, data);\n }\n\n return buildChartSpec('pie', data, encoding, options);\n}\n\n/**\n * Create an area chart spec.\n *\n * @param data - Array of data rows.\n * @param x - X-axis field (typically temporal or ordinal).\n * @param y - Y-axis field (typically quantitative).\n * @param options - Optional color, size, chrome, annotations, theme, etc.\n */\nexport function areaChart(\n data: DataRow[],\n x: FieldRef,\n y: FieldRef,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const xChannel = resolveField(x, data);\n const yChannel = resolveField(y, data);\n const encoding = buildEncoding({ x: xChannel, y: yChannel }, options, data);\n return buildChartSpec('area', data, encoding, options);\n}\n\n/**\n * Create a donut chart spec.\n *\n * Convention: category maps to the color channel, value maps to y.\n * Donut charts have no x-axis.\n *\n * @param data - Array of data rows.\n * @param category - Category field (color channel, nominal).\n * @param value - Value field (y channel, quantitative).\n * @param options - Optional chrome, annotations, theme, etc.\n * Note: color option is ignored since category is used for color.\n */\nexport function donutChart(\n data: DataRow[],\n category: FieldRef,\n value: FieldRef,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const categoryChannel = resolveField(category, data);\n const valueChannel = resolveField(value, data);\n\n const encoding: Encoding = {\n y: valueChannel,\n color: categoryChannel,\n };\n if (options?.size && data) {\n encoding.size = resolveField(options.size, data);\n }\n\n return buildChartSpec('donut', data, encoding, options);\n}\n\n/**\n * Create a dot chart spec (strip plot / dot plot).\n *\n * @param data - Array of data rows.\n * @param x - X-axis field (quantitative or temporal).\n * @param y - Y-axis field (nominal/categorical grouping).\n * @param options - Optional color, size, chrome, annotations, theme, etc.\n */\nexport function dotChart(\n data: DataRow[],\n x: FieldRef,\n y: FieldRef,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const xChannel = resolveField(x, data);\n const yChannel = resolveField(y, data);\n const encoding = buildEncoding({ x: xChannel, y: yChannel }, options, data);\n return buildChartSpec('dot', data, encoding, options);\n}\n\n/**\n * Create a scatter chart spec.\n *\n * @param data - Array of data rows.\n * @param x - X-axis field (quantitative).\n * @param y - Y-axis field (quantitative).\n * @param options - Optional color, size, chrome, annotations, theme, etc.\n */\nexport function scatterChart(\n data: DataRow[],\n x: FieldRef,\n y: FieldRef,\n options?: ChartBuilderOptions,\n): ChartSpec {\n const xChannel = resolveField(x, data);\n const yChannel = resolveField(y, data);\n const encoding = buildEncoding({ x: xChannel, y: yChannel }, options, data);\n return buildChartSpec('scatter', data, encoding, options);\n}\n\n/**\n * Create a data table spec.\n *\n * If no columns are specified, auto-generates column configs from the\n * keys of the first data row.\n *\n * @param data - Array of data rows.\n * @param options - Column definitions, chrome, pagination, search, etc.\n */\nexport function dataTable(data: DataRow[], options?: TableBuilderOptions): TableSpec {\n // Auto-generate columns from data keys if not provided\n let columns = options?.columns;\n if (!columns && data.length > 0) {\n columns = Object.keys(data[0]).map((key): ColumnConfig => {\n // Infer alignment from data type\n const fieldType = inferFieldType(data, key);\n const align = fieldType === 'quantitative' ? ('right' as const) : ('left' as const);\n\n return {\n key,\n label: key,\n align,\n };\n });\n }\n\n const spec: TableSpec = {\n type: 'table',\n data,\n columns: columns ?? [],\n };\n\n if (options?.rowKey) spec.rowKey = options.rowKey;\n if (options?.chrome) spec.chrome = options.chrome;\n if (options?.theme) spec.theme = options.theme;\n if (options?.darkMode) spec.darkMode = options.darkMode;\n if (options?.search !== undefined) spec.search = options.search;\n if (options?.pagination !== undefined) spec.pagination = options.pagination;\n if (options?.stickyFirstColumn !== undefined) spec.stickyFirstColumn = options.stickyFirstColumn;\n if (options?.compact !== undefined) spec.compact = options.compact;\n if (options?.responsive !== undefined) spec.responsive = options.responsive;\n\n return spec;\n}\n"],"mappings":"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","names":["format","color","color","darker","hex","color","hex","relativeLuminance","hex","locale","format","formatPrefix","value","locale","formats","pad","format","locale","defaultLocale"]}
|