{"version":3,"sources":["../../src/core/encoding-overrides.ts","../../src/core/aggregate.ts","../../src/core/chart-transitions.ts","../../src/core/pivot.ts","../../src/chartjs/colormap.ts","../../src/chartjs/templates/utils.ts","../../src/chartjs/templates/scatter.ts","../../src/chartjs/templates/connected-scatter.ts","../../src/chartjs/templates/bubble.ts","../../src/chartjs/templates/jitter.ts","../../src/core/axis-detection.ts","../../src/core/band-dodge.ts","../../src/core/encoding-actions.ts","../../src/chartjs/templates/bar.ts","../../src/chartjs/templates/combo.ts","../../src/chartjs/templates/line.ts","../../src/core/type-registry.ts","../../src/core/semantic-types.ts","../../src/core/field-semantics.ts","../../src/chartjs/templates/bump.ts","../../src/chartjs/templates/slope.ts","../../src/chartjs/templates/area.ts","../../src/chartjs/templates/range-area.ts","../../src/chartjs/templates/pie.ts","../../src/chartjs/templates/doughnut.ts","../../src/chartjs/templates/histogram.ts","../../src/chartjs/templates/ecdf.ts","../../src/chartjs/templates/radar.ts","../../src/chartjs/templates/rose.ts","../../src/chart-types/gantt.ts","../../src/chartjs/templates/gantt.ts","../../src/chart-types/waterfall.ts","../../src/chartjs/templates/waterfall.ts","../../src/chartjs/templates/index.ts","../../src/core/decisions.ts","../../src/core/resolve-semantics.ts","../../src/core/filter-overflow.ts","../../src/core/compute-layout.ts","../../src/core/color-decisions.ts","../../src/chartjs/instantiate-spec.ts","../../src/core/static-series.ts","../../src/core/normalize-properties.ts","../../src/chartjs/assemble.ts","../../src/core/recommendation.ts","../../src/core/chart-type-recommendation.ts","../../src/chartjs/recommendation.ts"],"names":["fallback","isDiscrete","t","hexToRgb","uniqueValues","isTemporal","groupAxis","ar","nRows","semType","distinct","schemeType","channel","chosen"],"mappings":"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","file":"index.cjs","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { ChartEncoding, ChartTemplateDef } from './types';\n\n/**\n * Compose a template's encoding-action overrides onto the base encodings.\n *\n * Category-B quick options (sort, color scheme, aggregate, orientation, …) are\n * stored by the host as *configuration overrides* keyed by the action's `key`\n * inside `chartProperties` — exactly like a chart property. They are NOT written\n * into the encoding map. This function is where the compiler composes them:\n * for each `encodingAction` whose override is present, it applies the action's\n * `set(encodings, value)` to produce the transformed encodings that feed the\n * rest of assembly.\n *\n * Backends call this once, at the very top of `assemble`, so every downstream\n * phase (semantic resolution → overflow → layout → instantiate) — and the\n * `InstantiateContext.encodings` handed to templates — sees the transformed\n * encodings. The base `encodings` argument is never mutated.\n *\n * An absent override (`undefined`) means \"no override\" and is skipped, so the\n * base encoding value (whatever the encoding shelf set, if anything) stands.\n * Because the override key matches the action key, charts saved before this\n * mechanism — which stored e.g. `chartProperties.colorScheme` directly — are\n * picked up automatically with no separate legacy fallback.\n */\nexport function applyEncodingOverrides(\n    template: ChartTemplateDef,\n    encodings: Record<string, ChartEncoding>,\n    chartProperties?: Record<string, any>,\n): Record<string, ChartEncoding> {\n    const actions = template.encodingActions;\n    if (!actions || actions.length === 0 || !chartProperties) return encodings;\n\n    let result = encodings;\n    for (const action of actions) {\n        const override = chartProperties[action.key];\n        if (override !== undefined) {\n            result = action.set(result, override);\n        }\n    }\n    return result;\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Optional data aggregation transform.\n *\n * Flint's default contract is \"callers own the data\" — the host passes in rows\n * that are already shaped for the chart. As a convenience, an encoding may set\n * `aggregate` to ask Flint to collapse the rows itself, mirroring the way\n * Vega-Lite derives an aggregated field:\n *\n *   - Rows are grouped by every channel that has a `field` and no `aggregate`\n *     (the dimensions).\n *   - For each group, each aggregated channel produces a derived column named\n *     `${field}_${op}` (`count` produces `_count`), which the backend assemblers\n *     already reference once `aggregate` is set.\n *\n * The derived column name IS the contract: if a caller has already\n * pre-aggregated, they simply reference that column by name (e.g. `revenue_sum`)\n * and omit `aggregate`, and this transform is a no-op. `average` and `mean` are\n * synonyms (both arithmetic mean) and keep distinct suffixes by design.\n *\n * This is a deliberate, opt-in exception to the no-transform principle — most\n * callers should still aggregate upstream.\n */\n\nimport { ChartEncoding } from './types';\n\ninterface AggSpec {\n    field?: string;\n    op: string;\n    /** Derived column name the assemblers expect (`${field}_${op}` or `_count`). */\n    target: string;\n}\n\n/**\n * Apply requested `aggregate` operations to the data, returning grouped rows.\n *\n * Returns the input unchanged when no encoding requests aggregation, or when the\n * derived columns are already present (caller pre-aggregated).\n */\nexport function applyAggregation(\n    encodings: Record<string, ChartEncoding>,\n    data: any[],\n): any[] {\n    if (!data || data.length === 0) return data;\n\n    // Collect aggregate requests from the input encodings.\n    const specs: AggSpec[] = [];\n    for (const enc of Object.values(encodings)) {\n        if (!enc || !enc.aggregate) continue;\n        const op = enc.aggregate;\n        if (op !== 'count' && !enc.field) continue; // nothing to reduce\n        const target = op === 'count' ? '_count' : `${enc.field}_${op}`;\n        specs.push({ field: enc.field, op, target });\n    }\n    if (specs.length === 0) return data;\n\n    // If every derived column already exists, the caller pre-aggregated — trust\n    // the supplied data and do nothing.\n    const firstRow = data[0];\n    const allPresent = specs.every(s =>\n        Object.prototype.hasOwnProperty.call(firstRow, s.target),\n    );\n    if (allPresent) return data;\n\n    // Group-by dimensions: every channel with a field and no aggregate.\n    const groupFields: string[] = [];\n    const seen = new Set<string>();\n    for (const enc of Object.values(encodings)) {\n        if (!enc || enc.aggregate || !enc.field) continue;\n        if (seen.has(enc.field)) continue;\n        seen.add(enc.field);\n        groupFields.push(enc.field);\n    }\n\n    // Bucket rows by the tuple of group-field values (insertion order preserved).\n    const groups = new Map<string, any[]>();\n    for (const row of data) {\n        const key = JSON.stringify(groupFields.map(f => row[f] ?? null));\n        let bucket = groups.get(key);\n        if (!bucket) {\n            bucket = [];\n            groups.set(key, bucket);\n        }\n        bucket.push(row);\n    }\n\n    const toNum = (v: any): number => (typeof v === 'number' ? v : Number(v));\n    const reduceOp = (rows: any[], spec: AggSpec): number => {\n        if (spec.op === 'count') return rows.length;\n        const nums = rows\n            .map(r => toNum(r[spec.field as string]))\n            .filter(v => Number.isFinite(v));\n        if (nums.length === 0) return 0;\n        const sum = nums.reduce((a, b) => a + b, 0);\n        // 'average' and 'mean' are synonyms (arithmetic mean); 'sum' totals.\n        return spec.op === 'sum' ? sum : sum / nums.length;\n    };\n\n    const out: any[] = [];\n    for (const rows of groups.values()) {\n        const head = rows[0];\n        const aggregated: Record<string, any> = {};\n        for (const f of groupFields) aggregated[f] = head[f];\n        for (const spec of specs) {\n            const val = reduceOp(rows, spec);\n            aggregated[spec.target] = val;\n            // Keep the source column populated so semantic/format inference for\n            // the measure channel still sees representative numeric values.\n            if (spec.op !== 'count' && spec.field) aggregated[spec.field] = val;\n        }\n        out.push(aggregated);\n    }\n    return out;\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Central chart-type **transition registry** — the θ graph.\n *\n * This is the single source of truth for which sibling chart types a given chart\n * can re-render as (Control B / `θ` in the two-control transform model). It\n * replaces the per-template, per-backend inline `transitions` arrays: a chart\n * template no longer declares what it can turn into — the compiler looks the\n * edges up here by chart-type display name.\n *\n * Design notes (design-docs/chart-transform-two-axes.md §4, and the \"registry\"\n * discussion):\n *   - Edges are keyed by the *authored* chart type's display name.\n *   - Each edge is a CANDIDATE. It is still gated at runtime against the live\n *     encoding + data (route feasibility + the declarative gates on\n *     `PivotTransition`: requireOrderedAxis / requireNonNegative /\n *     maxCategoryCardinality / requireNoSeries / requireDiscreteSource /\n *     maxSourceCardinality) AND against backend availability (an edge is hidden\n *     when the target template does not exist in the active backend's registry).\n *   - So \"not all mappings make sense\" is handled twice: only sensible edges are\n *     declared here (the §4 catalog), and even a declared edge is withheld when\n *     the data / backend does not support it.\n *   - Edges should be *reversible*: if A → B is declared, B → A generally should\n *     be too (verified by tests), so a transform round-trips home.\n *\n * Grouped by data-signature family (design doc §4).\n */\n\nimport { PivotTransition } from './types';\n\nexport const CHART_TRANSITIONS: Record<string, PivotTransition[]> = {\n    // ── Categorical comparison — D × M (§4.1) ──────────────────────────────\n    'Bar Chart': [\n        // Ordered-axis bridge into the trend family (§4.9). Only when the domain\n        // axis is temporal/ordinal — an unordered nominal bar never sprouts a line.\n        // orientDomainAxis:'x' re-orients a horizontal bar so time stays horizontal.\n        { to: 'Line Chart', label: 'Line', requireOrderedAxis: true, orientDomainAxis: 'x' },\n        { to: 'Area Chart', label: 'Area', requireOrderedAxis: true, requireNonNegative: true, orientDomainAxis: 'x' },\n        // Same D×M signature, lighter ink.\n        { to: 'Lollipop Chart', label: 'Lollipop' },\n    ],\n    'Lollipop Chart': [\n        { to: 'Bar Chart', label: 'Bar' },\n    ],\n    'Grouped Bar Chart': [\n        {\n            to: 'Stacked Bar Chart',\n            label: 'Stacked',\n            route: { from: 'group', to: 'color', mode: 'move' },\n            requireDiscreteSource: true,\n        },\n        // A 2-sided grouped bar reads as a population pyramid (mirrored).\n        {\n            to: 'Pyramid Chart',\n            label: 'Pyramid',\n            route: { from: 'group', to: 'color', mode: 'move' },\n            requireDiscreteSource: true,\n            maxSourceCardinality: 2,\n        },\n    ],\n    'Stacked Bar Chart': [\n        {\n            to: 'Grouped Bar Chart',\n            label: 'Grouped',\n            route: { from: 'color', to: 'group', mode: 'move' },\n            requireDiscreteSource: true,\n            maxSourceCardinality: 12,\n        },\n    ],\n    // Population pyramid = a 2-sided category × measure; its complement is the\n    // side-by-side grouped bar (the 2 sides dodged instead of mirrored).\n    'Pyramid Chart': [\n        {\n            to: 'Grouped Bar Chart',\n            label: 'Grouped',\n            route: { from: 'color', to: 'group', mode: 'move' },\n            requireDiscreteSource: true,\n        },\n    ],\n\n    // ── Trend over an ordered domain — T × M (§4.2) ────────────────────────\n    'Line Chart': [\n        { to: 'Area Chart', label: 'Area', requireNonNegative: true },\n        // Back to discrete-period comparison; only readable with few ticks.\n        { to: 'Bar Chart', label: 'Bar', maxCategoryCardinality: 30 },\n        // Small-multiple trend strips (one per series) — needs a series. Route\n        // the series onto `color` (from wherever it sits — color OR a column/row\n        // facet) so the Sparkline template picks it up as its row series.\n        { to: 'Sparkline', label: 'Sparklines', requireSeries: true, route: { from: 'series', to: 'color', mode: 'move' } },\n    ],\n    'Area Chart': [\n        { to: 'Line Chart', label: 'Line' },\n        { to: 'Bar Chart', label: 'Bar', maxCategoryCardinality: 30 },\n        { to: 'Streamgraph', label: 'Stream', requireSeries: true, requireNonNegative: true, route: { from: 'series', to: 'color', mode: 'move' } },\n    ],\n    // Small-multiple trend table → a single overlaid multi-series line.\n    'Sparkline': [\n        { to: 'Line Chart', label: 'Line' },\n    ],\n    // Flowing composition → back to baseline-anchored trend / area. Both reads\n    // are safe; note Streamgraph → Line is intentionally *one-directional* (there\n    // is no Line → Streamgraph — see the note above).\n    'Streamgraph': [\n        { to: 'Area Chart', label: 'Area' },\n        { to: 'Line Chart', label: 'Line' },\n    ],\n\n    // ── Two-measure relationship — M₁ × M₂ (§4.3) ──────────────────────────\n    'Scatter Plot': [\n        {\n            to: 'Strip Plot',\n            label: 'Jitter',\n            route: { from: 'series', to: 'x', mode: 'swap', spill: 'color' },\n        },\n        // Add a fitted trend layer over the same cloud — only a clean\n        // two-measure scatter (both axes quantitative, no size bubble).\n        { to: 'Regression', label: 'Trend', requireBiaxialMeasure: true, requireNoSize: true },\n    ],\n    'Regression': [\n        { to: 'Scatter Plot', label: 'Scatter' },\n    ],\n    'Strip Plot': [\n        {\n            to: 'Scatter Plot',\n            label: 'Scatter',\n            route: { from: 'color', to: 'x', mode: 'swap', spill: 'color' },\n        },\n        // A strip plot is a per-category distribution: box (summary) + violin\n        // (density) are the same {x:category, y:measure} layout, no route.\n        { to: 'Boxplot', label: 'Box' },\n        { to: 'Violin Plot', label: 'Violin' },\n    ],\n\n    // ── Univariate distribution — M (§4.4) ─────────────────────────────────\n    'Histogram': [\n        { to: 'Density Plot', label: 'Density' },\n        { to: 'ECDF Plot', label: 'ECDF' },\n    ],\n    'Density Plot': [\n        { to: 'Histogram', label: 'Histogram' },\n        { to: 'ECDF Plot', label: 'ECDF' },\n    ],\n    'ECDF Plot': [\n        { to: 'Histogram', label: 'Histogram' },\n        { to: 'Density Plot', label: 'Density' },\n    ],\n    'Boxplot': [\n        { to: 'Violin Plot', label: 'Violin' },\n        { to: 'Strip Plot', label: 'Strip' },\n    ],\n    'Violin Plot': [\n        { to: 'Boxplot', label: 'Box' },\n        { to: 'Strip Plot', label: 'Strip' },\n    ],\n};\n\n/**\n * Look up the candidate θ transitions for a chart type (by display name).\n * Returns an empty array when the chart declares none.\n */\nexport function getChartTransitions(chart: string | undefined): PivotTransition[] {\n    if (!chart) return [];\n    return CHART_TRANSITIONS[chart] ?? [];\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart pivot — a derived Category-B operator that re-routes encoding *fields*\n * across position/legend/facet *channels* to surface alternative views of the\n * same semantic spec (orientation swap, series↔axis role swap, facet split).\n *\n * The host stores the chosen pivot *state id* as a single override keyed by\n * `PivotDef.key` (default `'pivot'`) inside `chart_spec.chartProperties`, exactly\n * like any other encoding action. The compiler — not the host — owns the channel\n * permutation: at assemble time it enumerates the valid states for the current\n * encodings + data, picks the stored id (falling back to the identity state when\n * the id is stale or absent), and composes the resulting encoding map BEFORE the\n * rest of the pipeline runs (so sort/overflow/layout all resolve post-pivot).\n *\n * This module is intentionally backend-agnostic: it operates purely on the\n * abstract `ChartEncoding` map + the raw data table, so the same enumeration\n * drives Vega-Lite, ECharts and Chart.js.\n *\n * MVP linearization. The full design models the pivot states as the orbit of a\n * channel-permutation group, linearized by a Gray code so adjacent steps differ\n * by one generator. This first increment exposes a curated *star* of single-\n * generator views around the authored identity (identity → orientation → role →\n * facet), which is a valid finite cycle (Z/n over the ordered list) that always\n * returns to the authored view. Richer products land later.\n *\n * Role-swap has two type-preserving flavors: discrete↔color-hue (a category\n * moves between a banded axis and the legend — bars/lines) and, on position\n * marks only, measure↔(color-gradient | size) (a quantitative field moves\n * between a precise position axis and a demoted auxiliary channel — scatter).\n *\n * Two distinct group actions drive the channel moves, matching the design doc:\n *   - τ (transpose): flip two axis *slots* wholesale (`x↔y` orientation). Profile-\n *     agnostic, always occupancy-preserving — declared via `PivotDef.transpose`.\n *   - σ (permute): reassign a *field* to a same-profile channel (axis ↔ color/size)\n *     — declared via `PivotDef.permute`, admitted by the Young-block profile rule.\n * Keeping them separate is what lets the must-present guard drop out entirely.\n */\n\nimport { ChartEncoding, ChartTemplateDef, PivotDef, PivotTransition } from './types';\nimport { getChartTransitions } from './chart-transitions';\n\n/** Resolved pivot surface attached to the assembled spec as `_pivot`. */\nexport interface PivotSurface {\n    key: string;\n    label: string;\n    /** Number of states in the cycle (>= 2 when a control should show). */\n    length: number;\n    /** Index of the active state within `ids`. */\n    index: number;\n    /** Ordered state ids; `ids[0]` is always the identity (authored) view. */\n    ids: string[];\n    /** Parallel human labels for each state. */\n    labels: string[];\n}\n\n/** A redundant identity encoding added by a local Arrange operator. */\nexport interface EncodingAugmentation {\n    kind: 'facet-identity';\n    sourceChannel: 'color' | 'group';\n    facetChannel: 'column' | 'row';\n    colorEncoding: ChartEncoding;\n}\n\n/** Internal: a fully enumerated pivot for a given encoding map + data. */\nexport interface PivotComputation {\n    key: string;\n    label: string;\n    ids: string[];\n    labels: string[];\n    statesById: Record<string, Record<string, ChartEncoding>>;\n    augmentationById: Record<string, EncodingAugmentation | undefined>;\n    /**\n     * Chart-type override per state id, set only for chart-type *transition*\n     * states (§4.6). Absent/undefined entries render with the authored template.\n     */\n    chartTypeById: Record<string, string | undefined>;\n}\n\nconst DISCRETE_TYPES = new Set(['nominal', 'ordinal']);\n\nfunction isDiscrete(enc: ChartEncoding | undefined): boolean {\n    return !!enc?.field && !!enc.type && DISCRETE_TYPES.has(enc.type);\n}\n\nfunction isMeasure(enc: ChartEncoding | undefined): boolean {\n    return !!enc?.field && (enc.type === 'quantitative' || !!enc.aggregate);\n}\n\nfunction isTemporal(enc: ChartEncoding | undefined): boolean {\n    return enc?.type === 'temporal';\n}\n\n/**\n * Whether a temporal position axis is rendered as discrete *bands* (so it acts\n * as a category for pivot purposes) rather than a continuous time scale. Length\n * marks (bars/histograms) and color marks (heatmaps) band their categorical\n * axis; only position marks (line/area/scatter) lay time out continuously, where\n * \"time stays horizontal\" is the convention we preserve.\n */\nfunction temporalActsDiscrete(template: ChartTemplateDef): boolean {\n    return template.markCognitiveChannel !== 'position';\n}\n\nfunction clone(encodings: Record<string, ChartEncoding>): Record<string, ChartEncoding> {\n    const out: Record<string, ChartEncoding> = {};\n    for (const [ch, enc] of Object.entries(encodings)) {\n        out[ch] = { ...enc };\n    }\n    return out;\n}\n\nfunction distinctCount(data: any[], field: string | undefined): number {\n    if (!field || !Array.isArray(data)) return 0;\n    const seen = new Set<unknown>();\n    for (const row of data) {\n        if (row && row[field] != null) seen.add(row[field]);\n    }\n    return seen.size;\n}\n\n/** Build the standard cartesian pivot declaration from its permissible domains. */\nexport function makeCartesianPivot(opts: Partial<PivotDef> = {}): PivotDef {\n    return {\n        key: opts.key ?? 'pivot',\n        label: opts.label ?? 'View',\n        transpose: opts.transpose ?? [],\n        permute: opts.permute ?? [],\n        shift: opts.shift ?? [],\n        facetBudget: opts.facetBudget ?? 12,\n        transitions: opts.transitions,\n    };\n}\n\n/**\n * Canonical channel order so a swap pair has a stable id/label regardless of the\n * order it was declared in (e.g. `['color','x']` is normalized to `x ↔ color`).\n */\nconst CHANNEL_ORDER = ['x', 'y', 'color', 'size', 'group', 'column', 'row'];\nfunction orderPair(a: string, b: string): [string, string] {\n    const ia = CHANNEL_ORDER.indexOf(a);\n    const ib = CHANNEL_ORDER.indexOf(b);\n    return (ia <= ib ? [a, b] : [b, a]) as [string, string];\n}\n\n/**\n * Human-friendly channel names for the arrange labels shown in the UI (the\n * dropdown/switcher). Keeps the stored *ids* untouched — only the display text.\n */\nconst CHANNEL_DISPLAY: Record<string, string> = {\n    x: 'X',\n    y: 'Y',\n    color: 'Color',\n    size: 'Size',\n    group: 'Groups',\n    column: 'Columns',\n    row: 'Rows',\n    detail: 'Detail',\n    opacity: 'Opacity',\n};\nfunction chDisplay(ch: string): string {\n    return CHANNEL_DISPLAY[ch] ?? ch.charAt(0).toUpperCase() + ch.slice(1);\n}\n\n/** The set of channels whose bound field differs between two encodings. */\nfunction changedChannels(\n    a: Record<string, ChartEncoding>,\n    b: Record<string, ChartEncoding>,\n): Set<string> {\n    const out = new Set<string>();\n    for (const ch of new Set([...Object.keys(a), ...Object.keys(b)])) {\n        if (a[ch]?.field !== b[ch]?.field) out.add(ch);\n    }\n    return out;\n}\n\n/**\n * Transpose generator (τ): exchange two axis *slots* wholesale (`x↔y`). This is\n * the orientation/flip — it carries each channel's full encoding to the other,\n * so it is profile-agnostic (category↔measure on a bar, measure↔measure on a\n * scatter, dimension↔dimension on a heatmap). It is suppressed only when a\n * continuous-temporal position axis must stay horizontal (line/area keep time on\n * `x`). Because both slots stay occupied it can never drop a required channel.\n * Returns `null` when either slot is unbound or the temporal-horizontal rule\n * blocks the flip.\n */\nfunction transposeState(\n    base: Record<string, ChartEncoding>,\n    template: ChartTemplateDef,\n    pair: [string, string],\n): { id: string; label: string; enc: Record<string, ChartEncoding> } | null {\n    const [a, b] = orderPair(pair[0], pair[1]);\n    const ea = base[a];\n    const eb = base[b];\n    if (!ea?.field || !eb?.field) return null; // both slots must be bound\n    // Keep a continuous-temporal axis horizontal (no vertical time on position marks).\n    if (!temporalActsDiscrete(template) && (isTemporal(ea) || isTemporal(eb))) return null;\n    const next = clone(base);\n    next[a] = { ...eb };\n    next[b] = { ...ea };\n    return { id: `flip:${a}-${b}`, label: `${chDisplay(a)} ⇄ ${chDisplay(b)}`, enc: next };\n}\n\ntype ChannelProfile = 'measure' | 'category' | 'time';\n\n/**\n * The profile a bound field presents on a channel: `measure` (quantitative or\n * aggregated), `category` (discrete, or a temporal axis the chart bands), or\n * `time` (continuous temporal). Two channels may exchange fields under {@link\n * permuteSwapState} only when their profiles match — the Young-block rule.\n */\nfunction channelProfile(enc: ChartEncoding | undefined, template: ChartTemplateDef): ChannelProfile | null {\n    if (!enc?.field) return null;\n    if (isMeasure(enc)) return 'measure';\n    if (isDiscrete(enc) || (isTemporal(enc) && temporalActsDiscrete(template))) return 'category';\n    return 'time';\n}\n\n/**\n * Permute generator (σ): reassign a field between a position *axis* and an\n * *auxiliary* channel (`color`/`size`), admitting the swap only when both ends\n * share a {@link channelProfile} — the Young-block rule. This single predicate\n * subsumes the old measure↔measure and category↔color cases:\n *   - `measure` profile: position marks only (a bar's length-measure is privileged\n *     and never demotes to color/size); the peer quantities trade the precise axis.\n *   - `category` profile: the auxiliary must be `color` (only it carries a discrete\n *     series); the banded axis dimension and the legend series exchange places.\n * `x↔y` is handled by {@link transposeState}, not here, and pure auxiliary pairs\n * (`color↔size`) are never offered. No must-present guard is needed: both ends are\n * already bound, so the swap preserves occupancy by construction.\n * Returns `null` when no profile-preserving interpretation admits the pair.\n */\nfunction permuteSwapState(\n    base: Record<string, ChartEncoding>,\n    template: ChartTemplateDef,\n    pair: [string, string],\n): { id: string; label: string; enc: Record<string, ChartEncoding> } | null {\n    const [a, b] = orderPair(pair[0], pair[1]);\n    // Canonical ordering keeps a position axis as `a`; the auxiliary is `b`.\n    const posCh = a === 'x' || a === 'y' ? a : null;\n    const auxCh = b;\n    if (!posCh || (auxCh !== 'color' && auxCh !== 'size')) return null;\n    const posEnc = base[posCh];\n    const auxEnc = base[auxCh];\n    if (!posEnc?.field || !auxEnc?.field) return null; // both ends must be bound\n    if (posEnc.field === auxEnc.field) return null;\n\n    const profile = channelProfile(posEnc, template);\n    if (!profile || profile !== channelProfile(auxEnc, template)) return null; // different profile\n\n    const id = `swap:${a}-${b}`;\n    const label = `${chDisplay(a)} ⇄ ${chDisplay(b)}`;\n\n    if (profile === 'measure') {\n        // Demoting a measure to an aux channel only reads on position marks; on a\n        // length mark (bar) the value axis is privileged. Carry only the semantic\n        // core so downstream assembly re-derives scales/schemes per channel.\n        if (template.markCognitiveChannel !== 'position') return null;\n        const next = clone(base);\n        next[posCh] = measureCore(auxEnc);\n        next[auxCh] = measureCore(posEnc);\n        return { id, label, enc: next };\n    }\n\n    if (profile === 'category') {\n        // Only `color` carries a discrete series to exchange with a banded axis.\n        if (auxCh !== 'color') return null;\n        const next = clone(base);\n        next[posCh] = { ...auxEnc };\n        next.color = { ...posEnc };\n        return { id, label, enc: next };\n    }\n\n    return null; // continuous time does not demote to an auxiliary channel\n}\nfunction measureCore(enc: ChartEncoding): ChartEncoding {\n    const core: ChartEncoding = { field: enc.field, type: enc.type };\n    if (enc.aggregate) core.aggregate = enc.aggregate;\n    return core;\n}\n\n/**\n * Default grouping channels a discrete *series* field can occupy, used to locate\n * the current series when a transition references the `'series'` sentinel. The\n * shiftable domain offered to the user is the template's declared `shift` list\n * (filtered against these semantics); this constant is the resolution fallback.\n */\nconst GROUPING_CHANNELS = ['color', 'group', 'column', 'row'];\n\n/** Per-target budgets: facets allow more panels than a color/dodge legend. */\nfunction routeBudget(target: string, facetBudget: number): number {\n    if (target === 'column' || target === 'row') return facetBudget;\n    if (target === 'group') return 12; // dodged sub-bars get cramped past ~12\n    return 20; // color legend\n}\n\n/** Operator label for routing the series from its current channel onto another. */\nfunction routeLabel(from: string, to: string): string {\n    return `${chDisplay(from)} ⇄ ${chDisplay(to)}`;\n}\n\n/** Locate a discrete series for chart-type transition routing. */\nfunction findTransitionSeries(\n    base: Record<string, ChartEncoding>,\n    candidates: string[],\n    channels: string[],\n): { channel: string; enc: ChartEncoding } | null {\n    for (const channel of candidates) {\n        if (channels.includes(channel) && isDiscrete(base[channel])) {\n            return { channel, enc: base[channel]! };\n        }\n    }\n    return null;\n}\n\n/**\n * Identity channels augment onto empty facets; facet channels shift normally.\n * Keeping the sources independent avoids destructive color-to-facet moves and\n * lets a chart with both color and column offer two distinct row alternatives.\n */\nfunction seriesRoutingStates(\n    base: Record<string, ChartEncoding>,\n    template: ChartTemplateDef,\n    data: any[],\n    shiftChannels: string[],\n    facetBudget: number,\n    preferredFacet?: 'column' | 'row',\n): { id: string; enc: Record<string, ChartEncoding>; label: string; augmentation?: EncodingAugmentation }[] {\n    const channels = template.channels ?? [];\n    const out: { id: string; enc: Record<string, ChartEncoding>; label: string; augmentation?: EncodingAugmentation }[] = [];\n\n    const identitySource: 'color' | 'group' | undefined = isDiscrete(base.color)\n        ? 'color'\n        : (!base.color?.field && isDiscrete(base.group) ? 'group' : undefined);\n    if (identitySource && shiftChannels.includes(identitySource) && channels.includes(identitySource)) {\n        const identityEncoding = base[identitySource]!;\n        const card = distinctCount(data, identityEncoding.field);\n        const facetTargets = preferredFacet ? [preferredFacet] : ['column', 'row'] as const;\n        for (const target of facetTargets) {\n            if (!shiftChannels.includes(target) || !channels.includes(target)) continue;\n            if (base[target]?.field || card > routeBudget(target, facetBudget)) continue;\n            const next = clone(base);\n            delete next[identitySource];\n            next[target] = { ...identityEncoding };\n            out.push({\n                id: `augment:${target}`,\n                enc: next,\n                label: `Color + ${chDisplay(target)}`,\n                augmentation: {\n                    kind: 'facet-identity',\n                    sourceChannel: identitySource,\n                    facetChannel: target,\n                    colorEncoding: { ...identityEncoding },\n                },\n            });\n        }\n    }\n\n    const facetSource = (['column', 'row'] as const).find(channel =>\n        shiftChannels.includes(channel) && channels.includes(channel) && isDiscrete(base[channel]),\n    );\n    if (facetSource) {\n        const facetEncoding = base[facetSource]!;\n        const card = distinctCount(data, facetEncoding.field);\n        for (const target of shiftChannels) {\n            if (target === facetSource || target === 'group') continue;\n            if ((target === 'column' || target === 'row') && preferredFacet && target !== preferredFacet) continue;\n            if (!channels.includes(target) || base[target]?.field) continue;\n            if (card > routeBudget(target, facetBudget)) continue;\n            const next = clone(base);\n            delete next[facetSource];\n            next[target] = { ...facetEncoding };\n            out.push({ id: `series:${target}`, enc: next, label: routeLabel(facetSource, target) });\n        }\n    }\n    return out;\n}\n\n/** Preferred small-multiple direction for the compact dynamic Arrange surface. */\nfunction preferredFacetTarget(base: Record<string, ChartEncoding>): 'column' | 'row' {\n    const domain = domainAxisEnc(base);\n    return domain === base.y ? 'row' : 'column';\n}\n\n/** Facet channel newly targeted by a composed transformation, if any. */\nfunction changedFacetTarget(\n    authored: Record<string, ChartEncoding>,\n    transformed: Record<string, ChartEncoding>,\n): 'column' | 'row' | undefined {\n    for (const channel of ['column', 'row'] as const) {\n        if (transformed[channel]?.field && transformed[channel]?.field !== authored[channel]?.field) {\n            return channel;\n        }\n    }\n    return undefined;\n}\n\n/**\n * The *domain* position axis encoding — the non-measure x/y (a category/time\n * axis). Prefers whichever position channel is not a measure.\n */\nfunction domainAxisEnc(base: Record<string, ChartEncoding>): ChartEncoding | undefined {\n    if (base.x?.field && !isMeasure(base.x)) return base.x;\n    if (base.y?.field && !isMeasure(base.y)) return base.y;\n    return undefined;\n}\n\n/** The *measure* position axis encoding — the quantitative/aggregated x/y. */\nfunction measureAxisEnc(base: Record<string, ChartEncoding>): ChartEncoding | undefined {\n    if (base.x?.field && isMeasure(base.x)) return base.x;\n    if (base.y?.field && isMeasure(base.y)) return base.y;\n    return undefined;\n}\n\n/**\n * Evaluate a transition's declarative *data-characteristic* gates against the\n * authored encoding + data (design-docs/chart-transform-two-axes.md §4.9.3).\n * These are the \"not all mappings make sense\" guards: a candidate edge is only\n * offered when the shared fields actually support the sibling's reading.\n */\nfunction transitionGatesPass(\n    base: Record<string, ChartEncoding>,\n    data: any[],\n    t: PivotTransition,\n): boolean {\n    if (t.requireOrderedAxis) {\n        const domain = domainAxisEnc(base);\n        // Ordered = temporal or ordinal; plain nominal never qualifies.\n        if (!domain || !(domain.type === 'temporal' || domain.type === 'ordinal')) return false;\n    }\n    if (t.requireNonNegative) {\n        const measure = measureAxisEnc(base);\n        if (measure?.field) {\n            for (const row of data) {\n                const v = row?.[measure.field];\n                if (typeof v === 'number' && v < 0) return false;\n            }\n        }\n    }\n    if (t.maxCategoryCardinality != null) {\n        const domain = domainAxisEnc(base);\n        if (domain?.field && distinctCount(data, domain.field) > t.maxCategoryCardinality) return false;\n    }\n    if (t.requireNoSeries) {\n        for (const ch of GROUPING_CHANNELS) {\n            if (isDiscrete(base[ch])) return false;\n        }\n    }\n    if (t.requireSeries) {\n        const seriesChannels = ['color', 'group', 'detail', 'column', 'row'];\n        if (!seriesChannels.some((ch) => isDiscrete(base[ch]))) return false;\n    }\n    if (t.requireBiaxialMeasure) {\n        if (!isMeasure(base.x) || !isMeasure(base.y)) return false;\n    }\n    if (t.requireNoSize) {\n        if (base.size?.field) return false;\n    }\n    return true;\n}\n\n/**\n * Build the encoding map for a chart-type *transition* (§4.6). A transition\n * re-views the same data as a sibling chart type, optionally re-routing one\n * field across channels first. Returns `null` when the transition's constraints\n * (source presence, discreteness, cardinality budget, target occupancy) are not\n * met. The `chartType` it returns tells the compiler to re-select the sibling\n * template for rendering while the authored chartType / encodings stay intact.\n */\nfunction transitionState(\n    base: Record<string, ChartEncoding>,\n    data: any[],\n    template: ChartTemplateDef,\n    t: PivotTransition,\n): { enc: Record<string, ChartEncoding>; chartType: string; label: string } | null {\n    if (!transitionGatesPass(base, data, t)) return null;\n    const enc = clone(base);\n    const route = t.route;\n    if (route) {\n        // Resolve the source channel. `'series'` finds the discrete grouping\n        // field wherever it sits (color/column/row); a literal name is used as-is.\n        const fromCh = route.from === 'series'\n            ? findTransitionSeries(base, GROUPING_CHANNELS, template.channels ?? [])?.channel\n            : route.from;\n        if (!fromCh) return null;\n        const srcEnc = base[fromCh];\n        if (!srcEnc?.field) return null; // nothing to re-route\n        if (t.requireDiscreteSource && !isDiscrete(srcEnc)) return null;\n        if (t.maxSourceCardinality != null &&\n            distinctCount(data, srcEnc.field) > t.maxSourceCardinality) return null;\n        const mode = route.mode ?? 'move';\n        const dstEnc = base[route.to];\n        if (mode === 'swap') {\n            // The source field takes the target channel; the field displaced from\n            // the target spills to `spill` (default: the vacated source channel).\n            const spillCh = route.spill ?? fromCh;\n            // Don't clobber an unrelated field already sitting on the spill slot.\n            if (spillCh !== fromCh && base[spillCh]?.field) return null;\n            enc[route.to] = { ...srcEnc };\n            delete enc[fromCh];\n            if (dstEnc?.field) enc[spillCh] = { ...dstEnc };\n            else delete enc[spillCh];\n        } else {\n            // move: bring the source field onto the target channel. If it is\n            // already there (from === to, e.g. `series` resolved to the target),\n            // it's a no-op; otherwise the target must be empty so we don't clobber.\n            if (fromCh !== route.to) {\n                if (dstEnc?.field) return null;\n                delete enc[fromCh];\n                enc[route.to] = { ...srcEnc };\n            }\n        }\n    }\n    // Re-orient the domain axis for the sibling if requested (bar → line/area):\n    // a horizontal bar carries the ordered/temporal domain on `y`, but a line\n    // pins it to the horizontal — swap x/y wholesale so we never render a\n    // vertical line chart.\n    if (t.orientDomainAxis) {\n        const target = t.orientDomainAxis;\n        const other = target === 'x' ? 'y' : 'x';\n        const domainOnOther = !!enc[other]?.field && !isMeasure(enc[other]);\n        const targetFreeForDomain = !enc[target]?.field || isMeasure(enc[target]);\n        if (domainOnOther && targetFreeForDomain) {\n            const a = enc[target];\n            const b = enc[other];\n            if (b) enc[target] = { ...b }; else delete enc[target];\n            if (a) enc[other] = { ...a }; else delete enc[other];\n        }\n    }\n    return { enc, chartType: t.to, label: t.label };\n}\n\n/**\n * A single applied generator (one step / one \"delta\"): the abstract operator\n * δ ∈ {σ, γ, θ} re-expressed as a concrete neighbor of a given encoding under a\n * given template. `id` is the step token used to build composite path ids,\n * `label` is its operator notation, and `chartType` is set only for θ steps.\n */\ninterface PivotStep {\n    id: string;\n    label: string;\n    enc: Record<string, ChartEncoding>;\n    chartType?: string;\n    augmentation?: EncodingAugmentation;\n}\n\n/**\n * Enumerate the *one-step* neighbors of an encoding under a template's pivot\n * def — the generators δ applicable to `enc` right now. This is the building\n * block of the runtime orbit walk: the same enumerator runs on every reachable\n * state, so composing transforms is just \"apply one more δ\". The generators are\n * pure functions of the passed encoding (not the authored base), which is what\n * lets γ∘σ, σ∘θ, … fall out without any special-casing.\n */\nfunction pivotSteps(\n    template: ChartTemplateDef,\n    enc: Record<string, ChartEncoding>,\n    data: any[],\n    opts?: { local?: boolean; transitions?: boolean; preferFacetTarget?: boolean },\n    resolveTemplate?: (chartType: string) => ChartTemplateDef | undefined,\n): PivotStep[] {\n    const def = template.pivot;\n    if (!def) return [];\n    const includeLocal = opts?.local !== false;\n    const includeTransitions = opts?.transitions !== false;\n    const steps: PivotStep[] = [];\n    // τ: each declared axis-slot pair contributes its wholesale flip (orientation).\n    if (includeLocal) for (const pair of def.transpose ?? []) {\n        if (pair.length !== 2) continue;\n        const s = transposeState(enc, template, [pair[0], pair[1]]);\n        if (s) steps.push({ id: s.id, label: s.label, enc: s.enc });\n    }\n    // σ: each permutable block contributes its within-block axis↔aux field swaps as\n    // candidate one-step moves; the orbit BFS composes them to close the block's\n    // symmetric group. Profile-mismatched pairs return null and are dropped.\n    if (includeLocal) for (const block of def.permute ?? []) {\n        for (let i = 0; i < block.length; i++) {\n            for (let j = i + 1; j < block.length; j++) {\n                const s = permuteSwapState(enc, template, [block[i], block[j]]);\n                if (s) steps.push({ id: s.id, label: s.label, enc: s.enc });\n            }\n        }\n    }\n    if (includeLocal && def.shift && def.shift.length) {\n        const preferredFacet = opts?.preferFacetTarget ? preferredFacetTarget(enc) : undefined;\n        for (const s of seriesRoutingStates(enc, template, data, def.shift, def.facetBudget ?? 12, preferredFacet)) {\n            steps.push({ id: s.id, label: s.label, enc: s.enc, augmentation: s.augmentation });\n        }\n    }\n    // θ: chart-type transitions are sourced from the CENTRAL registry (keyed by\n    // the template's chart name), not the template itself — a template no longer\n    // declares what it can turn into. A candidate edge is emitted only when its\n    // target template exists in the active backend (via `resolveTemplate`, when\n    // supplied); the per-edge data gates run inside transitionState.\n    if (includeTransitions) {\n        for (const t of getChartTransitions(template.chart)) {\n            if (resolveTemplate && !resolveTemplate(t.to)) continue; // backend can't render it\n            const st = transitionState(enc, data, template, t);\n            // Operator notation: θ = chart-type transition, subscripted by the target view.\n            if (st) steps.push({ id: `type:${t.to}`, label: `θ_→${t.label.toLowerCase()}`, enc: st.enc, chartType: st.chartType });\n        }\n    }\n    return steps;\n}\n\n/**\n * Canonical fingerprint of an encoding map (+ effective chart type) used to\n * dedup orbit states. Two paths that land on the same channel→field assignment\n * collapse to one state — this is the group *stabilizer* quotient (e.g. σ∘σ = id\n * folds back onto `default`; faceting then jittering reaches the same strip plot\n * as jittering directly). Only the semantic core (field/type/aggregate) and the\n * occupied channel set matter; cosmetic encoding props are ignored.\n */\nfunction encodingKey(enc: Record<string, ChartEncoding>, chartType: string | undefined): string {\n    const cells = Object.keys(enc)\n        .filter((ch) => enc[ch]?.field)\n        .sort()\n        .map((ch) => {\n            const e = enc[ch];\n            return `${ch}=${e.field}/${e.type ?? ''}/${e.aggregate ?? ''}`;\n        });\n    return `${chartType ?? ''}::${cells.join(',')}`;\n}\n\n/**\n * Reject orbit states that would be structurally invalid for their (effective)\n * template — primarily the cartesian invariant that a chart with both `x` and\n * `y` channels must keep *both* position axes bound (a scatter/line/bar with a\n * missing x or y is not a renderable view). This guards composed paths from\n * walking into degenerate encodings even if an individual generator is locally\n * type-preserving.\n */\nfunction isRenderableState(template: ChartTemplateDef, enc: Record<string, ChartEncoding>): boolean {\n    const channels = template.channels ?? [];\n    if (channels.includes('x') && channels.includes('y')) {\n        if (!enc.x?.field || !enc.y?.field) return false;\n    }\n    return true;\n}\n\n/** Hard cap on orbit size so a rich generator set can't produce an unwieldy control. */\nconst MAX_PIVOT_STATES = 12;\n\n/**\n * Enumerate the pivot states for an encoding map + data under a template's\n * `PivotDef` by walking the *orbit* of the generators at runtime: start from the\n * authored identity and repeatedly apply one more δ (breadth-first), deduping by\n * {@link encodingKey} (the stabilizer quotient) and rejecting non-renderable\n * states (see {@link isRenderableState}). State ids are operator *paths* (e.g.\n * `orient|series:row`, `type:Strip Plot`); labels compose the per-step operator\n * notation with `·`. Returns `null` when no template pivot is declared. The\n * identity (authored) view is always state 0; a control should only render when\n * `ids.length > 1`.\n *\n * `resolveTemplate` lets the walk cross θ (chart-type) edges: after a transition\n * switches `chartType`, subsequent generators come from the *target* template's\n * pivot def. Backends that omit it leave θ states as leaves (no composition past\n * a chart-type change).\n */\nexport function computePivot(\n    template: ChartTemplateDef,\n    base: Record<string, ChartEncoding>,\n    data: any[],\n    resolveTemplate?: (chartType: string) => ChartTemplateDef | undefined,\n    opts?: { includeTransitions?: boolean; key?: string; label?: string; preferFacetTarget?: boolean },\n): PivotComputation | null {\n    const def = template.pivot;\n    if (!def) return null;\n    const key = opts?.key ?? def.key ?? 'pivot';\n    const label = opts?.label ?? def.label ?? 'View';\n    const includeTransitions = opts?.includeTransitions !== false;\n\n    const ids: string[] = ['default'];\n    const labels: string[] = ['Default'];\n    const statesById: Record<string, Record<string, ChartEncoding>> = {\n        default: clone(base),\n    };\n    const augmentationById: Record<string, EncodingAugmentation | undefined> = {\n        default: undefined,\n    };\n    const chartTypeById: Record<string, string | undefined> = {\n        default: undefined,\n    };\n\n    interface OrbitNode {\n        id: string;\n        label: string;\n        enc: Record<string, ChartEncoding>;\n        chartType: string | undefined;\n        template: ChartTemplateDef;\n        augmentation: EncodingAugmentation | undefined;\n    }\n\n    const seen = new Set<string>([encodingKey(base, undefined)]);\n    const queue: OrbitNode[] = [{ id: 'default', label: 'Default', enc: clone(base), chartType: undefined, template, augmentation: undefined }];\n    // The authored chart type *is* home: a θ path that lands back on it (e.g.\n    // Stacked → Grouped → Stacked) is not a new view, so we normalize its\n    // effective chartType to `undefined`. This lets the stabilizer dedup fold\n    // such round-trips onto the identity instead of showing them as extra states.\n    const authoredChart = template.chart;\n\n    while (queue.length > 0 && ids.length < MAX_PIVOT_STATES) {\n        const cur = queue.shift()!;\n        for (const step of pivotSteps(cur.template, cur.enc, data, {\n            local: true,\n            transitions: includeTransitions,\n            preferFacetTarget: opts?.preferFacetTarget,\n        }, resolveTemplate)) {\n            // A θ step switches the effective chart type (and thus the template\n            // whose generators apply next); σ/γ steps stay on the current one.\n            let nextChartType = step.chartType ?? cur.chartType;\n            if (nextChartType === authoredChart) nextChartType = undefined; // back home\n            // A θ step switches the effective template (and thus the generators\n            // that apply next). When no resolver is supplied — or it can't resolve\n            // the target — the θ state becomes a *leaf*: we strip its pivot so no\n            // further (wrong-template) generators compose past the chart-type\n            // change. σ/γ/τ steps stay on the current template.\n            const resolved = step.chartType ? resolveTemplate?.(step.chartType) : undefined;\n            const nextTemplate: ChartTemplateDef = step.chartType\n                ? (resolved ?? { ...cur.template, pivot: undefined })\n                : cur.template;\n            if (!isRenderableState(nextTemplate, step.enc)) continue; // avoid invalid combos\n            if (opts?.preferFacetTarget) {\n                const facetTarget = changedFacetTarget(base, step.enc);\n                if (facetTarget && facetTarget !== preferredFacetTarget(step.enc)) continue;\n            }\n            // Drop OVERLAPPING arrangement compositions. Composing two generators\n            // that touch a shared channel yields a confusing 3-cycle (flip X⇄Y then\n            // swap Y⇄Color rotates all three axes, not a clean pairwise swap). We\n            // only compose steps whose moved channels are DISJOINT from what the\n            // path already moved — so every state is a single generator or an\n            // INDEPENDENT combo. The generators themselves are unchanged (the\n            // overlapping states still exist in theory), we just don't enumerate them.\n            if (step.chartType === undefined && cur.id !== 'default') {\n                const already = changedChannels(base, cur.enc);\n                const now = changedChannels(cur.enc, step.enc);\n                let overlaps = false;\n                for (const ch of now) {\n                    if (already.has(ch)) { overlaps = true; break; }\n                }\n                if (overlaps) continue;\n            }\n            const fp = encodingKey(step.enc, nextChartType);\n            if (seen.has(fp)) continue; // dedup (stabilizer)\n            seen.add(fp);\n            const id = cur.id === 'default' ? step.id : `${cur.id}|${step.id}`;\n            // Compositions are now always DISJOINT (see the overlap guard above),\n            // so a plain operator join reads cleanly with no double-counted channel\n            // (e.g. `X ⇄ Y · Color ⇄ Columns`). θ states join the same way.\n            const stepLabel = cur.id === 'default' ? step.label : `${cur.label} · ${step.label}`;\n            ids.push(id);\n            labels.push(stepLabel);\n            statesById[id] = step.enc;\n            chartTypeById[id] = nextChartType;\n            const augmentation = step.chartType\n                ? undefined\n                : (step.augmentation ?? cur.augmentation);\n            augmentationById[id] = augmentation;\n            queue.push({ id, label: stepLabel, enc: step.enc, chartType: nextChartType, template: nextTemplate, augmentation });\n            if (ids.length >= MAX_PIVOT_STATES) break;\n        }\n    }\n\n    return { key, label, ids, labels, statesById, augmentationById, chartTypeById };\n}\n\n/**\n * Resolve the active pivot state for the stored override and return both the\n * transformed encodings and the serializable surface (or the untouched base\n * encodings + `undefined` surface when no multi-state pivot applies).\n */\nexport function applyPivot(\n    template: ChartTemplateDef,\n    base: Record<string, ChartEncoding>,\n    data: any[],\n    chartProperties: Record<string, any> | undefined,\n    resolveTemplate?: (chartType: string) => ChartTemplateDef | undefined,\n): { encodings: Record<string, ChartEncoding>; augmentation: EncodingAugmentation | undefined; chartType: string | undefined; surface: PivotSurface | undefined } {\n    const comp = computePivot(template, base, data, resolveTemplate);\n    if (!comp || comp.ids.length <= 1) {\n        return { encodings: base, augmentation: undefined, chartType: undefined, surface: undefined };\n    }\n    const stored = chartProperties?.[comp.key];\n    const id = typeof stored === 'string' && comp.ids.includes(stored) ? stored : comp.ids[0];\n    const index = comp.ids.indexOf(id);\n    return {\n        encodings: comp.statesById[id],\n        augmentation: comp.augmentationById[id],\n        chartType: comp.chartTypeById[id],\n        surface: {\n            key: comp.key,\n            label: comp.label,\n            length: comp.ids.length,\n            index,\n            ids: comp.ids,\n            labels: comp.labels,\n        },\n    };\n}\n\n// ─── Factored two-control model (design-docs/chart-transform-two-axes.md) ─────\n//\n// The single composed orbit above is re-exposed as TWO independent controls:\n//   - Control B (chart type, θ): a one-hop transition menu enumerated from the\n//     object's *identity* — no composition, independent of Control A.\n//   - Control A (arrange, τ/σ/γ): the local group of the *effective* chart type\n//     (authored, or the θ-selected sibling), BFS-composed and deduped.\n// The two are stored as separate override keys (`chartType`, `arrange`). A θ\n// switch resets `arrange` to identity and rebuilds Control A on the new object.\n\n/** Both control surfaces resolved for the current input. */\nexport interface TransformSurface {\n    /** Control B — chart-type transitions (dropdown). Absent when no siblings. */\n    chartType?: PivotSurface;\n    /** Control A — local rearrangement group (stepper). Absent when trivial. */\n    arrange?: PivotSurface;\n}\n\n/** Override keys the two controls read/write under `chartProperties`. */\nexport const TRANSFORM_CHART_TYPE_KEY = 'chartType';\nexport const TRANSFORM_ARRANGE_KEY = 'arrange';\n\n/** Build a PivotSurface for a chosen state id within a computation. */\nfunction buildSurface(comp: PivotComputation, id: string): PivotSurface {\n    const index = Math.max(0, comp.ids.indexOf(id));\n    return {\n        key: comp.key,\n        label: comp.label,\n        length: comp.ids.length,\n        index,\n        ids: comp.ids,\n        labels: comp.labels,\n    };\n}\n\n/**\n * Control A enumeration: the local rearrangement group (τ/σ/γ only, no θ) of a\n * template, BFS-composed and deduped exactly like {@link computePivot} but with\n * chart-type transitions excluded. Runs on the *effective* object's identity\n * encoding (post-θ), so it offers exactly the moves that make sense there.\n */\nexport function computeArrangeStates(\n    template: ChartTemplateDef,\n    base: Record<string, ChartEncoding>,\n    data: any[],\n): PivotComputation | null {\n    return computePivot(template, base, data, undefined, {\n        includeTransitions: false,\n        key: TRANSFORM_ARRANGE_KEY,\n        label: 'Arrange',\n        preferFacetTarget: true,\n    });\n}\n\n/**\n * Control B enumeration: the one-hop chart-type transitions (θ only) of a\n * template, enumerated from the object's *identity* encoding — no composition,\n * no τ/σ/γ. Each state re-routes fields for a sibling chart type and carries a\n * `chartType` override the compiler re-dispatches on. State 0 is the authored\n * type (`default`, no override); labels are the sibling chart-type display\n * names so the dropdown reads \"Bar Chart · Line Chart · …\". Returns `null` when\n * the template declares no transitions.\n */\nexport function computeChartTypeStates(\n    template: ChartTemplateDef,\n    base: Record<string, ChartEncoding>,\n    data: any[],\n    resolveTemplate?: (chartType: string) => ChartTemplateDef | undefined,\n): PivotComputation | null {\n    // Transitions come from the central registry (keyed by chart name), NOT from\n    // the template's pivot def — so a template with no local τ/σ/γ group (e.g. a\n    // Pyramid) can still offer chart-type siblings.\n    const transitions = getChartTransitions(template.chart);\n    if (transitions.length === 0) return null;\n\n    const ids: string[] = ['default'];\n    const labels: string[] = [template.chart];\n    const statesById: Record<string, Record<string, ChartEncoding>> = { default: clone(base) };\n    const augmentationById: Record<string, EncodingAugmentation | undefined> = { default: undefined };\n    const chartTypeById: Record<string, string | undefined> = { default: undefined };\n    const seenChartTypes = new Set<string>([template.chart]);\n\n    for (const t of transitions) {\n        // Backend gate: skip a target the active backend can't render.\n        if (resolveTemplate && !resolveTemplate(t.to)) continue;\n        const st = transitionState(base, data, template, t);\n        if (!st) continue;\n        // One sibling per target chart type; skip a hop back to the authored type.\n        if (seenChartTypes.has(st.chartType)) continue;\n        seenChartTypes.add(st.chartType);\n        const id = `type:${t.to}`;\n        ids.push(id);\n        labels.push(st.chartType);\n        statesById[id] = st.enc;\n        chartTypeById[id] = st.chartType;\n    }\n\n    if (ids.length <= 1) return null;\n    return { key: TRANSFORM_CHART_TYPE_KEY, label: 'Chart type', ids, labels, statesById, augmentationById, chartTypeById };\n}\n\n/**\n * Resolve the two transform override ids from `chartProperties`, with a\n * backward-compatible shim for the legacy single composed `pivot` id: a\n * `type:*` token routes to the chart-type override and the remaining τ/σ/γ\n * tokens (before it) route to arrange. Because a θ resets arrange in the new\n * model, tokens *after* a `type:*` token are dropped (best-effort migration).\n */\nfunction resolveTransformOverrides(\n    chartProperties: Record<string, any> | undefined,\n): { chartTypeId: string | undefined; arrangeId: string | undefined } {\n    let chartTypeId = chartProperties?.[TRANSFORM_CHART_TYPE_KEY];\n    let arrangeId = chartProperties?.[TRANSFORM_ARRANGE_KEY];\n    if (typeof chartTypeId !== 'string') chartTypeId = undefined;\n    if (typeof arrangeId !== 'string') arrangeId = undefined;\n\n    if (chartTypeId === undefined && arrangeId === undefined) {\n        const legacy = chartProperties?.pivot;\n        if (typeof legacy === 'string' && legacy.length > 0 && legacy !== 'default') {\n            const tokens = legacy.split('|');\n            const typeIdx = tokens.findIndex((t) => t.startsWith('type:'));\n            if (typeIdx >= 0) {\n                chartTypeId = tokens[typeIdx];\n                const local = tokens.slice(0, typeIdx);\n                arrangeId = local.length ? local.join('|') : undefined;\n            } else {\n                arrangeId = legacy;\n            }\n        }\n    }\n    return { chartTypeId, arrangeId };\n}\n\n/**\n * Resolve the active state for the two independent controls and return the\n * transformed encodings + both surfaces. Order (design §4.10.1): apply the\n * chart-type transition (Control B) from the authored identity FIRST, re-select\n * the sibling template, THEN enumerate + apply that object's local arrange group\n * (Control A). A stale/absent `arrange` id falls back to identity — which is the\n * reset-on-θ behavior for free (design §4.10.2).\n */\nexport function applyTransform(\n    template: ChartTemplateDef,\n    base: Record<string, ChartEncoding>,\n    data: any[],\n    chartProperties: Record<string, any> | undefined,\n    resolveTemplate?: (chartType: string) => ChartTemplateDef | undefined,\n): {\n    encodings: Record<string, ChartEncoding>;\n    augmentation: EncodingAugmentation | undefined;\n    chartType: string | undefined;\n    surface: TransformSurface;\n} {\n    const { chartTypeId, arrangeId } = resolveTransformOverrides(chartProperties);\n\n    // Control B — chart type (θ), from the authored identity.\n    let effectiveTemplate = template;\n    let effectiveEnc = base;\n    let chartType: string | undefined;\n    let chartTypeSurface: PivotSurface | undefined;\n    const ctComp = computeChartTypeStates(template, base, data, resolveTemplate);\n    if (ctComp && ctComp.ids.length > 1) {\n        const id = chartTypeId && ctComp.ids.includes(chartTypeId) ? chartTypeId : 'default';\n        effectiveEnc = ctComp.statesById[id];\n        chartType = ctComp.chartTypeById[id];\n        if (chartType) {\n            const resolved = resolveTemplate?.(chartType);\n            if (resolved) effectiveTemplate = resolved;\n        }\n        chartTypeSurface = buildSurface(ctComp, id);\n    }\n\n    // Control A — arrange (τ/σ/γ), on the effective object.\n    let encodings = effectiveEnc;\n    let augmentation: EncodingAugmentation | undefined;\n    let arrangeSurface: PivotSurface | undefined;\n    const arrComp = computeArrangeStates(effectiveTemplate, effectiveEnc, data);\n    if (arrComp && arrComp.ids.length > 1) {\n        const id = arrangeId && arrComp.ids.includes(arrangeId) ? arrangeId : arrComp.ids[0];\n        encodings = arrComp.statesById[id];\n        augmentation = arrComp.augmentationById[id];\n        arrangeSurface = buildSurface(arrComp, id);\n    }\n\n    return {\n        encodings,\n        augmentation,\n        chartType,\n        surface: { chartType: chartTypeSurface, arrange: arrangeSurface },\n    };\n}\n","// Chart.js 专用调色板定义。\n// 承接 core/color-decisions.ts 中的抽象 colormap 信息（schemeType / schemeId / categoryCount），\n// 但真正的颜色数组与选盘策略完全在 Chart.js backend 本地实现，并尽量贴近 Chart.js 默认配色。\n\nimport type { ColorDecision, ColorMapType } from '../core/color-decisions';\n\nexport type ChartJsPaletteId = 'cat10' | 'cat20' | 'viridis' | 'RdBu' | string;\n\nexport interface ChartJsColorMapDef {\n    id: ChartJsPaletteId;\n    type: ColorMapType;\n    supportsDiscrete: boolean;\n    supportsContinuous: boolean;\n    background: 'light' | 'dark' | 'any';\n    colorblindSafe?: boolean;\n    maxCategories?: number;\n    diverging?: boolean;\n    preferredMidpoint?: number;\n    colors: string[]; // 使用 Chart.js 推荐的基础色（不含 alpha）\n}\n\n/**\n * Chart.js 常用的基础配色，基于官方文档中推荐的默认颜色集合：\n * https://www.chartjs.org/docs/latest/general/colors.html\n */\nconst CHARTJS_COLOR_MAPS: ChartJsColorMapDef[] = [\n    {\n        id: 'cat10',\n        type: 'categorical',\n        supportsDiscrete: true,\n        supportsContinuous: false,\n        background: 'any',\n        maxCategories: 10,\n        colorblindSafe: false,\n        colors: [\n            '#36a2eb', // blue\n            '#ff6384', // red\n            '#ffcd56', // yellow\n            '#4bc0c0', // teal\n            '#9966ff', // purple\n            '#ff9f40', // orange\n            '#2ecc71', // green\n            '#34495e', // dark blue-grey\n            '#e74c3c', // red-orange\n            '#95a5a6', // grey\n        ],\n    },\n    {\n        id: 'cat20',\n        type: 'categorical',\n        supportsDiscrete: true,\n        supportsContinuous: false,\n        background: 'any',\n        maxCategories: 20,\n        colorblindSafe: false,\n        colors: [\n            '#36a2eb', '#9ad0f5',\n            '#ff6384', '#ff99aa',\n            '#ffcd56', '#ffe39f',\n            '#4bc0c0', '#8fdede',\n            '#9966ff', '#c3a3ff',\n            '#ff9f40', '#ffc078',\n            '#2ecc71', '#7ee2a8',\n            '#34495e', '#5d6d7e',\n            '#e74c3c', '#f1948a',\n            '#95a5a6', '#cfd4d6',\n        ],\n    },\n    {\n        id: 'viridis',\n        type: 'sequential',\n        supportsDiscrete: true,\n        supportsContinuous: true,\n        background: 'any',\n        colorblindSafe: true,\n        colors: [\n            '#440154', '#46327e', '#365c8d', '#277f8e',\n            '#1fa187', '#4ac16d', '#a0da39', '#fde725',\n        ],\n    },\n    {\n        id: 'RdBu',\n        type: 'diverging',\n        supportsDiscrete: true,\n        supportsContinuous: true,\n        background: 'any',\n        diverging: true,\n        preferredMidpoint: 0,\n        colors: [\n            '#b2182b', '#d6604d', '#f4a582', '#fddbc7',\n            '#f7f7f7',\n            '#d1e5f0', '#92c5de', '#4393c3', '#2166ac',\n        ],\n    },\n];\n\nfunction getMapById(id: ChartJsPaletteId | undefined): ChartJsColorMapDef | undefined {\n    if (!id) return undefined;\n    const key = String(id).toLowerCase();\n    return CHARTJS_COLOR_MAPS.find(m => m.id.toLowerCase() === key);\n}\n\nexport function getPaletteForScheme(id: ChartJsPaletteId): string[] | undefined {\n    const entry = getMapById(id);\n    return entry?.colors;\n}\n\n/**\n * Chart.js 侧的「选盘」函数：等价于 backend 版 pickColorMap。\n *\n * 输入：\n *   - ColorDecision：来自 core/color-decisions（已算好 schemeType / categoryCount / schemeId）。\n *\n * 策略：\n *   1）若用户显式指定了 schemeId，则优先按该 id 取 palette。\n *   2）否则根据 schemeType + categoryCount 自动挑选合适的盘：\n *        - categorical：按类别数量在 cat10 / cat20 之间选；\n *        - sequential：优先 viridis；\n *        - diverging ：优先 RdBu。\n *   3）若都无法命中，回退到符合 Chart.js 习惯的默认 categorical palette（cat10）。\n */\nexport function pickChartJsPalette(decision: ColorDecision | undefined): string[] {\n    if (!decision) {\n        const fallback = getPaletteForScheme('cat10');\n        return fallback && fallback.length ? fallback : [];\n    }\n\n    const { schemeType, schemeId, categoryCount } = decision;\n\n    // 1. 显式 schemeId 优先。\n    if (schemeId) {\n        const fromId = getPaletteForScheme(schemeId);\n        if (fromId && fromId.length > 0) {\n            return fromId;\n        }\n    }\n\n    // 2. 自动路径：根据类型 / 类别数挑选本 backend 推荐盘。\n    const mapsOfType = CHARTJS_COLOR_MAPS.filter(m => m.type === schemeType);\n\n    if (schemeType === 'categorical') {\n        const k = categoryCount ?? 0;\n        if (mapsOfType.length) {\n            const candidates = mapsOfType.filter(m => m.supportsDiscrete);\n            if (candidates.length) {\n                const byCapacity = candidates\n                    .filter(m => m.maxCategories == null || m.maxCategories >= k)\n                    .sort((a, b) => (a.maxCategories ?? Infinity) - (b.maxCategories ?? Infinity));\n                const picked = byCapacity[0] ?? candidates[0];\n                if (picked.colors.length) {\n                    return picked.colors;\n                }\n            }\n        }\n        const fallback = getPaletteForScheme('cat10');\n        if (fallback && fallback.length) {\n            return fallback;\n        }\n    } else if (schemeType === 'sequential') {\n        const seq = mapsOfType.find(m => m.supportsContinuous) ?? getMapById('viridis');\n        if (seq && seq.colors.length) {\n            return seq.colors;\n        }\n    } else if (schemeType === 'diverging') {\n        const divergingFirst = mapsOfType.find(m => m.diverging) ?? getMapById('RdBu');\n        if (divergingFirst && divergingFirst.colors.length) {\n            return divergingFirst.colors;\n        }\n    }\n\n    // 3. 兜底：Chart.js 默认 categorical palette（cat10）。\n    const fallback = getPaletteForScheme('cat10');\n    return fallback && fallback.length ? fallback : [];\n}\n\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Shared helper functions for Chart.js template hooks.\n * Pure logic — no UI dependencies.\n */\n\nimport type { ChannelSemantics, InstantiateContext } from '../../core/types';\nimport { pickChartJsPalette } from '../colormap';\n\n// ---------------------------------------------------------------------------\n// Discrete-dimension helpers\n// ---------------------------------------------------------------------------\n\nconst isDiscrete = (type: string | undefined) => type === 'nominal' || type === 'ordinal';\n\n/**\n * Get the number of unique non-null values for a field in the data table.\n */\nexport function getFieldCardinality(field: string, table: any[]): number {\n    return new Set(table.map((r: any) => r[field]).filter((v: any) => v != null)).size;\n}\n\n// ---------------------------------------------------------------------------\n// Chart.js-specific helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Extract unique category values from data for a given field, preserving order.\n * If `ordinalSortOrder` is provided, returns values sorted in that canonical order.\n */\nexport function extractCategories(data: any[], field: string, ordinalSortOrder?: string[]): string[] {\n    const seen = new Set<string>();\n    const result: string[] = [];\n    for (const row of data) {\n        const val = row[field];\n        if (val != null) {\n            const key = String(val);\n            if (!seen.has(key)) {\n                seen.add(key);\n                result.push(key);\n            }\n        }\n    }\n\n    if (ordinalSortOrder && ordinalSortOrder.length > 0) {\n        const orderMap = new Map(ordinalSortOrder.map((v, i) => [v, i]));\n        result.sort((a, b) => {\n            const ia = orderMap.get(a);\n            const ib = orderMap.get(b);\n            if (ia !== undefined && ib !== undefined) return ia - ib;\n            if (ia !== undefined) return -1;\n            if (ib !== undefined) return 1;\n            return 0;\n        });\n    }\n\n    return result;\n}\n\n/**\n * Resolve the display order of a categorical axis, honoring either a canonical\n * `ordinalSortOrder` or a sort-by-measure request (`sortBy` + `sortOrder` from\n * the shared Sort encoding action).\n */\nexport function resolveCategoryOrder(\n    data: any[],\n    catField: string,\n    opts?: { ordinalSortOrder?: string[]; sortBy?: string; sortOrder?: 'ascending' | 'descending' },\n): string[] {\n    const base = extractCategories(data, catField, opts?.ordinalSortOrder);\n    if (!opts?.sortBy) return base;\n    const agg = new Map<string, number>();\n    for (const row of data) {\n        const cat = String(row[catField] ?? '');\n        const v = Number(row[opts.sortBy]);\n        if (Number.isFinite(v)) agg.set(cat, (agg.get(cat) ?? 0) + v);\n    }\n    const dir = opts.sortOrder === 'ascending' ? 1 : -1;\n    return [...base].sort((a, b) => dir * ((agg.get(a) ?? 0) - (agg.get(b) ?? 0)));\n}\n\n/**\n * Group data by a categorical field.\n * Returns a map: seriesName → rows[].\n */\nexport function groupBy(data: any[], field: string): Map<string, any[]> {\n    const groups = new Map<string, any[]>();\n    for (const row of data) {\n        const key = String(row[field] ?? '');\n        if (!groups.has(key)) groups.set(key, []);\n        groups.get(key)!.push(row);\n    }\n    return groups;\n}\n\n/**\n * Chart.js `linear` scale requires numeric `x` in `{x,y}` points. ISO strings\n * (from temporal conversion) become NaN and nothing renders. Map to Unix ms.\n * Seconds (e.g. ≤1e12) are treated as Unix seconds and multiplied by 1000.\n */\nexport function coerceUnixMsForChartJs(raw: unknown): number {\n    if (raw == null) return NaN;\n    if (typeof raw === 'number' && Number.isFinite(raw)) {\n        return raw < 1e12 ? Math.round(raw * 1000) : raw;\n    }\n    if (raw instanceof Date) {\n        const t = raw.getTime();\n        return Number.isFinite(t) ? t : NaN;\n    }\n    const t = new Date(String(raw)).getTime();\n    return Number.isFinite(t) ? t : NaN;\n}\n\n/**\n * Default Chart.js color palette (RGBA with alpha for fill).\n */\nexport const DEFAULT_COLORS = [\n    'rgba(54, 162, 235, 1)',    // blue\n    'rgba(255, 99, 132, 1)',    // red\n    'rgba(255, 206, 86, 1)',    // yellow\n    'rgba(75, 192, 192, 1)',    // teal\n    'rgba(153, 102, 255, 1)',   // purple\n    'rgba(255, 159, 64, 1)',    // orange\n    'rgba(46, 204, 113, 1)',    // green\n    'rgba(52, 73, 94, 1)',      // dark blue-grey\n    'rgba(231, 76, 60, 1)',     // red-orange\n    'rgba(149, 165, 166, 1)',   // grey\n];\n\nexport const DEFAULT_BG_COLORS = [\n    'rgba(54, 162, 235, 0.6)',\n    'rgba(255, 99, 132, 0.6)',\n    'rgba(255, 206, 86, 0.6)',\n    'rgba(75, 192, 192, 0.6)',\n    'rgba(153, 102, 255, 0.6)',\n    'rgba(255, 159, 64, 0.6)',\n    'rgba(46, 204, 113, 0.6)',\n    'rgba(52, 73, 94, 0.6)',\n    'rgba(231, 76, 60, 0.6)',\n    'rgba(149, 165, 166, 0.6)',\n];\n\n// ---------------------------------------------------------------------------\n// Color-decisions integration\n// ---------------------------------------------------------------------------\n\nfunction hexToRgb(hex: string): { r: number; g: number; b: number } | null {\n    const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim());\n    if (!m) return null;\n    const intVal = parseInt(m[1], 16);\n    return {\n        r: (intVal >> 16) & 255,\n        g: (intVal >> 8) & 255,\n        b: intVal & 255,\n    };\n}\n\nfunction rgbaFromHex(hex: string, alpha: number): string {\n    const rgb = hexToRgb(hex);\n    if (!rgb) return hex;\n    const a = Math.max(0, Math.min(1, alpha));\n    return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${a})`;\n}\n\nfunction applyAlphaToColor(color: string, alpha: number): string {\n    const a = Math.max(0, Math.min(1, alpha));\n    if (color.startsWith('#')) {\n        return rgbaFromHex(color, a);\n    }\n    if (color.startsWith('rgba')) {\n        return color.replace(\n            /rgba\\((\\d+),\\s*(\\d+),\\s*(\\d+),\\s*([\\d.]+)\\)/,\n            (_m, r, g, b) => `rgba(${r}, ${g}, ${b}, ${a})`,\n        );\n    }\n    if (color.startsWith('rgb(')) {\n        return color.replace(\n            /rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)/,\n            (_m, r, g, b) => `rgba(${r}, ${g}, ${b}, ${a})`,\n        );\n    }\n    return color;\n}\n\n/**\n * 从 color-decisions 解析调色板；若没有决策则回退到 Chart.js 默认 cat10。\n */\nexport function getChartJsPalette(ctx: InstantiateContext, preferred: 'color' | 'group' = 'color'): string[] {\n    const decisions = ctx.colorDecisions;\n    const decision =\n        preferred === 'color'\n            ? decisions?.color ?? decisions?.group\n            : decisions?.group ?? decisions?.color;\n\n    const palette = pickChartJsPalette(decision);\n    if (palette.length > 0) {\n        return palette;\n    }\n    return DEFAULT_COLORS;\n}\n\n/**\n * 取得第 i 个系列的描边色（优先使用统一调色板）。\n */\nexport function getSeriesBorderColor(palette: string[], index: number): string {\n    if (!palette.length) {\n        return DEFAULT_COLORS[index % DEFAULT_COLORS.length];\n    }\n    return palette[index % palette.length];\n}\n\n/**\n * 取得第 i 个系列的填充色，自动按需要设置透明度。\n */\nexport function getSeriesBackgroundColor(palette: string[], index: number, alpha = 0.6): string {\n    const border = getSeriesBorderColor(palette, index);\n    return applyAlphaToColor(border, alpha);\n}\n\n/**\n * Detect which axis is the category (banded) axis and which is the value axis.\n */\nexport function detectAxes(\n    channelSemantics: Record<string, ChannelSemantics>,\n): { categoryAxis: 'x' | 'y'; valueAxis: 'x' | 'y' } {\n    const xCS = channelSemantics.x;\n    const yCS = channelSemantics.y;\n\n    if (xCS && isDiscrete(xCS.type)) {\n        return { categoryAxis: 'x', valueAxis: 'y' };\n    }\n    if (yCS && isDiscrete(yCS.type)) {\n        return { categoryAxis: 'y', valueAxis: 'x' };\n    }\n    return { categoryAxis: 'x', valueAxis: 'y' };\n}\n\n/**\n * Build category-aligned data array for a subset of rows.\n * Returns values indexed by category position (null for missing).\n */\nexport function buildCategoryAlignedData(\n    rows: any[],\n    xField: string,\n    yField: string,\n    categories: string[],\n): (number | null)[] {\n    const map = new Map<string, number>();\n    for (const row of rows) {\n        const key = String(row[xField] ?? '');\n        const val = row[yField];\n        if (val != null && !isNaN(val)) {\n            map.set(key, (map.get(key) ?? 0) + Number(val));\n        }\n    }\n    return categories.map(cat => map.get(cat) ?? null);\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Scatter Plot template.\n *\n * Maps scatter semantics to Chart.js config:\n *   VL: encoding.x.field + encoding.y.field → positional channels\n *   CJS: datasets[].data = [{x, y}, ...] with type: 'scatter'\n */\n\nimport { ChartTemplateDef } from '../../core/types';\nimport {\n    getChartJsPalette,\n    getSeriesBorderColor,\n    getSeriesBackgroundColor,\n} from './utils';\nimport { makeCartesianPivot } from '../../core/pivot';\n\n/** Compute a reasonable point radius based on canvas area and point count. */\nfunction computePointRadius(width: number, height: number, pointCount: number): number {\n    const canvasArea = width * height;\n    const areaPerPoint = canvasArea / Math.max(1, pointCount);\n    const idealRadius = Math.sqrt(areaPerPoint * 0.05) / 2;\n    return Math.max(2, Math.min(6, Math.round(idealRadius)));\n}\n\nexport const cjsScatterPlotDef: ChartTemplateDef = {\n    chart: 'Scatter Plot',\n    template: { mark: 'circle', encoding: {} },\n    channels: ['x', 'y', 'color', 'size', 'opacity', 'column', 'row'],\n    markCognitiveChannel: 'position',\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, chartProperties } = ctx;\n        const xField = channelSemantics.x?.field;\n        const yField = channelSemantics.y?.field;\n        const colorField = channelSemantics.color?.field;\n\n        if (!xField || !yField) return;\n\n        const opacity = chartProperties?.opacity ?? 1;\n\n        const palette = getChartJsPalette(ctx, 'color');\n\n        const config: any = {\n            type: 'scatter',\n            data: { datasets: [] },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: {\n                    x: {\n                        type: 'linear',\n                        title: { display: true, text: xField },\n                    },\n                    y: {\n                        type: 'linear',\n                        title: { display: true, text: yField },\n                    },\n                },\n                plugins: {\n                    tooltip: { enabled: true },\n                },\n            },\n        };\n\n        // Apply zero-baseline decisions\n        // Chart.js linear scales default beginAtZero to false, so we must\n        // explicitly set true when the semantic decision includes zero.\n        if (channelSemantics.x?.zero) {\n            config.options.scales.x.beginAtZero = channelSemantics.x.zero.zero !== false;\n        }\n        if (channelSemantics.y?.zero) {\n            config.options.scales.y.beginAtZero = channelSemantics.y.zero.zero !== false;\n        }\n\n        if (colorField) {\n            // Multi-series: group by color field\n            const groups = new Map<string, { x: number; y: number }[]>();\n            for (const row of table) {\n                const key = String(row[colorField] ?? '');\n                if (!groups.has(key)) groups.set(key, []);\n                groups.get(key)!.push({ x: row[xField], y: row[yField] });\n            }\n\n            let colorIdx = 0;\n            for (const [name, data] of groups) {\n                config.data.datasets.push({\n                    label: name,\n                    data,\n                    backgroundColor: getSeriesBackgroundColor(palette, colorIdx, opacity),\n                    borderColor: getSeriesBorderColor(palette, colorIdx),\n                    borderWidth: 1,\n                    pointRadius: 4,\n                });\n                colorIdx++;\n            }\n            config.options.plugins.legend = { display: true };\n        } else {\n            const data = table.map(row => ({ x: row[xField], y: row[yField] }));\n            config.data.datasets.push({\n                data,\n                backgroundColor: getSeriesBackgroundColor(palette, 0, opacity),\n                borderColor: getSeriesBorderColor(palette, 0),\n                borderWidth: 1,\n                pointRadius: 4,\n            });\n            config.options.plugins.legend = { display: false };\n        }\n\n        // Write Chart.js config into spec\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n    properties: [\n        { key: 'opacity', label: 'Opacity', type: 'continuous', min: 0.1, max: 1, step: 0.05, defaultValue: 1 },\n    ],\n    pivot: makeCartesianPivot({\n        transpose: [['x', 'y']],\n        permute: [['x', 'y', 'color', 'size']],\n        shift: ['color', 'group', 'column', 'row'],\n        // θ transitions declared centrally in core/chart-transitions.ts.\n    }),\n    postProcess: (option, ctx) => {\n        if (!option.data?.datasets) return;\n        const w = option._width || ctx.canvasSize.width;\n        const h = option._height || ctx.canvasSize.height;\n        const pointCount = ctx.table.length;\n        const radius = computePointRadius(w, h, pointCount);\n        for (const ds of option.data.datasets) {\n            if (ds.pointRadius == null || ds.pointRadius === 4) {\n                ds.pointRadius = radius;\n            }\n        }\n    },\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Connected Scatter Plot template.\n *\n * Points plotted in 2-D (x, y both quantitative) and **connected by a straight\n * line in a defined order** (usually time / sequence), tracing a trajectory.\n * Shows the x↔y correlation AND the ordered path at once — distinct from a\n * plain scatter (no order, no line) and from a regression (a fitted trend).\n *\n * Mirrors cjsScatterPlotDef (points) and cjsLineChartDef (connecting line).\n *\n * Contract:\n *   x      — quantitative (linear axis).\n *   y      — quantitative (linear axis).\n *   order  — the sequence field; each dataset's points are **pre-sorted by this\n *            field** so the line follows the trajectory, NOT the x value. With\n *            `tension:0` the segments stay straight, so a looping path crosses\n *            itself.\n *   color  — optional series → one dataset (trajectory) per value (legend).\n *   detail — optional series → one trajectory per value (used when color absent).\n *\n * Each dataset is a `scatter` with `showLine:true` so both the points and the\n * connecting line are drawn.\n */\n\nimport { ChartTemplateDef } from '../../core/types';\nimport {\n    groupBy,\n    getChartJsPalette,\n    getSeriesBorderColor,\n    getSeriesBackgroundColor,\n} from './utils';\n\n/**\n * Stable sort of `rows` by the sequence `field`. Detection is value-based so it\n * works for any order field type: numeric (years / step indices) sort\n * numerically, date-parseable values sort chronologically, everything else\n * sorts lexically. Ties keep their original row order.\n */\nfunction sortByOrder(rows: any[], field: string | undefined): any[] {\n    if (!field) return rows;\n    const tagged = rows.map((row, idx) => ({ row, idx, key: row[field] }));\n    const present = tagged.filter(t => t.key != null && t.key !== '');\n    const allNumeric = present.length > 0 &&\n        present.every(t => typeof t.key === 'number' ||\n            (typeof t.key === 'string' && t.key.trim() !== '' && !isNaN(Number(t.key))));\n    const allDates = !allNumeric && present.length > 0 &&\n        present.every(t => !isNaN(Date.parse(String(t.key))));\n    const rank = (k: any): number | string => {\n        if (allNumeric) return Number(k);\n        if (allDates) return Date.parse(String(k));\n        return String(k);\n    };\n    return [...tagged].sort((a, b) => {\n        const ra = rank(a.key);\n        const rb = rank(b.key);\n        if (ra < rb) return -1;\n        if (ra > rb) return 1;\n        return a.idx - b.idx; // stable\n    }).map(t => t.row);\n}\n\n/** Build the {x, y} point list for a (sorted) set of rows. */\nfunction toPoints(rows: any[], xField: string, yField: string): { x: number; y: number }[] {\n    return rows.map(r => ({ x: Number(r[xField]), y: Number(r[yField]) }));\n}\n\nexport const cjsConnectedScatterDef: ChartTemplateDef = {\n    chart: 'Connected Scatter Plot',\n    template: { mark: 'line', encoding: {} },\n    channels: ['x', 'y', 'order', 'color', 'detail', 'column', 'row'],\n    markCognitiveChannel: 'position',\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table } = ctx;\n        const xCS = channelSemantics.x;\n        const yCS = channelSemantics.y;\n        const orderField = channelSemantics.order?.field;\n        // One trajectory per dataset: prefer color, fall back to detail.\n        const groupField = channelSemantics.color?.field ?? channelSemantics.detail?.field;\n\n        if (!xCS?.field || !yCS?.field) return;\n        const xField = xCS.field;\n        const yField = yCS.field;\n\n        const palette = getChartJsPalette(ctx, 'color');\n\n        const config: any = {\n            type: 'scatter',\n            data: { datasets: [] },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: {\n                    x: {\n                        type: 'linear',\n                        title: { display: true, text: xField },\n                        ticks: { font: { size: 10 } },\n                    },\n                    y: {\n                        type: 'linear',\n                        title: { display: true, text: yField },\n                        ticks: { font: { size: 10 } },\n                    },\n                },\n                plugins: {\n                    tooltip: { enabled: true },\n                    legend: { display: false },\n                },\n            },\n        };\n\n        // A trajectory reads its shape, not the distance from zero — fit the\n        // data unless the zero decision forces a zero baseline.\n        if (channelSemantics.x?.zero) {\n            config.options.scales.x.beginAtZero = channelSemantics.x.zero.zero !== false;\n        }\n        if (channelSemantics.y?.zero) {\n            config.options.scales.y.beginAtZero = channelSemantics.y.zero.zero !== false;\n        }\n\n        const baseDataset = {\n            // Straight segments + visible points connecting the trajectory.\n            showLine: true,\n            tension: 0,\n            borderWidth: 2,\n            pointRadius: 4,\n            fill: false,\n            // Don't clip points at the chart-area edge: a point that lands\n            // exactly on an axis bound would otherwise have its marker cut off.\n            clip: false,\n        };\n\n        if (groupField) {\n            const groups = groupBy(table, groupField);\n            config.options.plugins.legend = { display: true };\n            let colorIdx = 0;\n            for (const [name, rows] of groups) {\n                const sorted = sortByOrder(rows, orderField);\n                config.data.datasets.push({\n                    label: name,\n                    data: toPoints(sorted, xField, yField),\n                    borderColor: getSeriesBorderColor(palette, colorIdx),\n                    backgroundColor: getSeriesBackgroundColor(palette, colorIdx, 1),\n                    ...baseDataset,\n                });\n                colorIdx++;\n            }\n        } else {\n            const sorted = sortByOrder(table, orderField);\n            config.data.datasets.push({\n                label: yField,\n                data: toPoints(sorted, xField, yField),\n                borderColor: getSeriesBorderColor(palette, 0),\n                backgroundColor: getSeriesBackgroundColor(palette, 0, 1),\n                ...baseDataset,\n            });\n        }\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Bubble Chart template.\n *\n * Contrast with VL / Scatter:\n *   VL: encoding.x + encoding.y + encoding.size (quantitative) → point area\n *   CJS: native type 'bubble' with data = [{x, y, r}, ...] where `r` is a\n *        per-point pixel radius derived (area-proportionally) from the size\n *        channel. Optional color channel groups points into datasets.\n */\n\nimport { ChartTemplateDef } from '../../core/types';\nimport {\n    getChartJsPalette,\n    getSeriesBorderColor,\n    getSeriesBackgroundColor,\n} from './utils';\n\n/**\n * Build an area-proportional value → pixel-radius mapper for the size channel.\n * Returns a constant-radius mapper when there is no usable size field.\n */\nfunction makeRadiusScale(\n    values: number[],\n    rMin: number,\n    rMax: number,\n): (v: number) => number {\n    const finite = values.filter((v) => typeof v === 'number' && isFinite(v));\n    if (finite.length === 0) {\n        const mid = Math.round((rMin + rMax) / 2);\n        return () => mid;\n    }\n    const min = Math.min(...finite);\n    const max = Math.max(...finite);\n    if (min === max) {\n        const mid = Math.round((rMin + rMax) / 2);\n        return () => mid;\n    }\n    // Area-proportional: interpolate area (r^2) linearly, then take sqrt.\n    const aMin = rMin * rMin;\n    const aMax = rMax * rMax;\n    return (v: number) => {\n        if (typeof v !== 'number' || !isFinite(v)) return rMin;\n        const t = (v - min) / (max - min);\n        const area = aMin + t * (aMax - aMin);\n        return Math.max(rMin, Math.sqrt(area));\n    };\n}\n\nexport const cjsBubbleChartDef: ChartTemplateDef = {\n    chart: 'Bubble Chart',\n    template: { mark: 'circle', encoding: {} },\n    channels: ['x', 'y', 'size', 'color', 'opacity', 'column', 'row'],\n    markCognitiveChannel: 'position',\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, chartProperties } = ctx;\n        const xField = channelSemantics.x?.field;\n        const yField = channelSemantics.y?.field;\n        const sizeField = channelSemantics.size?.field;\n        const colorField = channelSemantics.color?.field;\n\n        if (!xField || !yField) return;\n\n        const opacity = chartProperties?.opacity ?? 0.6;\n        const palette = getChartJsPalette(ctx, 'color');\n\n        // Radius scale spans the whole dataset so groups stay comparable.\n        const sizeValues = sizeField\n            ? table.map((row) => Number(row[sizeField]))\n            : [];\n        // Provisional radius range; postProcess refines rMax to canvas size.\n        const radiusScale = makeRadiusScale(sizeValues, 5, 24);\n\n        const toPoint = (row: any) => {\n            const v = sizeField ? Number(row[sizeField]) : NaN;\n            return {\n                x: Number(row[xField]),\n                y: Number(row[yField]),\n                r: sizeField ? radiusScale(v) : 8,\n                // Raw size value retained so postProcess can rescale to canvas.\n                _v: v,\n            };\n        };\n\n        const config: any = {\n            type: 'bubble',\n            data: { datasets: [] },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: {\n                    // Bubble charts scale to the data extent (not a zero\n                    // baseline) and pad both ends with `grace` so large bubbles\n                    // sitting at the min/max aren't clipped by the plot edge.\n                    x: { type: 'linear', grace: '10%', title: { display: true, text: xField } },\n                    y: { type: 'linear', grace: '10%', title: { display: true, text: yField } },\n                },\n                plugins: {\n                    tooltip: { enabled: true },\n                },\n            },\n        };\n\n        if (colorField) {\n            const groups = new Map<string, any[]>();\n            for (const row of table) {\n                const key = String(row[colorField] ?? '');\n                if (!groups.has(key)) groups.set(key, []);\n                groups.get(key)!.push(toPoint(row));\n            }\n            let colorIdx = 0;\n            for (const [name, data] of groups) {\n                config.data.datasets.push({\n                    label: name,\n                    data,\n                    backgroundColor: getSeriesBackgroundColor(palette, colorIdx, opacity),\n                    borderColor: getSeriesBorderColor(palette, colorIdx),\n                    borderWidth: 1,\n                });\n                colorIdx++;\n            }\n            config.options.plugins.legend = { display: true };\n        } else {\n            config.data.datasets.push({\n                data: table.map(toPoint),\n                backgroundColor: getSeriesBackgroundColor(palette, 0, opacity),\n                borderColor: getSeriesBorderColor(palette, 0),\n                borderWidth: 1,\n            });\n            config.options.plugins.legend = { display: false };\n        }\n\n        // Stash size metadata so postProcess can rescale radii to the final canvas.\n        config._sizeField = sizeField ?? null;\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n    properties: [\n        { key: 'opacity', label: 'Opacity', type: 'continuous', min: 0.1, max: 1, step: 0.05, defaultValue: 0.6 },\n    ],\n    postProcess: (option, ctx) => {\n        if (!option.data?.datasets) return;\n        const sizeField: string | null = option._sizeField ?? null;\n        delete option._sizeField;\n        if (!sizeField) {\n            // Strip helper field even when no size channel is present.\n            for (const ds of option.data.datasets) for (const pt of ds.data) delete pt._v;\n            return;\n        }\n\n        // Collect all raw size values to build a dataset-wide radius scale.\n        const allValues: number[] = [];\n        for (const ds of option.data.datasets) {\n            for (const pt of ds.data) allValues.push(pt._v);\n        }\n\n        // Scale the max bubble radius to the canvas AND point density so dense\n        // plots don't turn into a blob.\n        const w = option._width || ctx.canvasSize.width;\n        const h = option._height || ctx.canvasSize.height;\n        const minDim = Math.min(w, h);\n        const count = Math.max(1, allValues.length);\n        const rMaxByDensity = Math.sqrt((w * h) / count * 0.08);\n        const rMax = Math.max(8, Math.min(34, Math.round(Math.min(minDim * 0.09, rMaxByDensity))));\n        const rMin = Math.max(3, Math.round(rMax * 0.22));\n        const radiusScale = makeRadiusScale(allValues, rMin, rMax);\n\n        for (const ds of option.data.datasets) {\n            for (const pt of ds.data) {\n                const v = pt._v;\n                if (typeof v === 'number' && isFinite(v)) pt.r = radiusScale(v);\n                delete pt._v;\n            }\n        }\n    },\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Strip Plot — scatter points jittered along a categorical axis.\n */\n\nimport { ChartTemplateDef, ChartPropertyDef } from '../../core/types';\nimport { makeCartesianPivot } from '../../core/pivot';\nimport {\n    extractCategories,\n    groupBy,\n    getChartJsPalette,\n    getSeriesBorderColor,\n    getSeriesBackgroundColor,\n} from './utils';\n\nconst isDiscrete = (type: string | undefined) => type === 'nominal' || type === 'ordinal';\n\nfunction clamp01(value: number): number {\n    return Math.max(0, Math.min(1, value));\n}\n\nfunction hexToRgb(color: string): [number, number, number] | undefined {\n    const hex = color.trim().replace(/^#/, '');\n    if (!/^[0-9a-fA-F]{6}$/.test(hex)) return undefined;\n    return [\n        parseInt(hex.slice(0, 2), 16),\n        parseInt(hex.slice(2, 4), 16),\n        parseInt(hex.slice(4, 6), 16),\n    ];\n}\n\nfunction continuousColor(palette: string[], value: number, min: number, max: number, alpha: number): string {\n    const colors = palette.length > 0 ? palette : ['#440154', '#fde725'];\n    const span = max > min ? max - min : 1;\n    const scaled = clamp01((value - min) / span) * (colors.length - 1);\n    const lo = Math.floor(scaled);\n    const hi = Math.min(colors.length - 1, Math.ceil(scaled));\n    const t = scaled - lo;\n    const left = hexToRgb(colors[lo]);\n    const right = hexToRgb(colors[hi]);\n    if (!left || !right) return colors[lo];\n    const mix = (a: number, b: number) => Math.round(a + (b - a) * t);\n    return `rgba(${mix(left[0], right[0])}, ${mix(left[1], right[1])}, ${mix(left[2], right[2])}, ${alpha})`;\n}\n\nfunction jitter(seed: number): () => number {\n    let state = seed;\n    return () => {\n        state = (state * 1103515245 + 12345) & 0x7fffffff;\n        return (state / 0x7fffffff) * 2 - 1;\n    };\n}\n\nexport const cjsStripPlotDef: ChartTemplateDef = {\n    chart: 'Strip Plot',\n    template: { mark: 'circle', encoding: {} },\n    channels: ['x', 'y', 'color', 'size', 'column', 'row'],\n    markCognitiveChannel: 'position',\n    declareLayoutMode: () => ({\n        paramOverrides: { defaultBandSize: 50, minStep: 16 },\n    }),\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, chartProperties } = ctx;\n        const xCS = channelSemantics.x;\n        const yCS = channelSemantics.y;\n        const xField = xCS?.field;\n        const yField = yCS?.field;\n        const colorField = channelSemantics.color?.field;\n        const colorType = channelSemantics.color?.type;\n        const isContinuousColor = !!colorField && (colorType === 'quantitative' || colorType === 'temporal');\n        const isTemporalColor = colorType === 'temporal';\n        if (!xField || !yField) return;\n\n        const xIsDiscrete = isDiscrete(xCS?.type);\n        const yIsDiscrete = isDiscrete(yCS?.type);\n        const catAxis: 'x' | 'y' = xIsDiscrete ? 'x' : yIsDiscrete ? 'y' : 'x';\n        const contAxis: 'x' | 'y' = catAxis === 'x' ? 'y' : 'x';\n        const catField = catAxis === 'x' ? xField : yField;\n        const contField = contAxis === 'x' ? xField : yField;\n        const catSemantics = catAxis === 'x' ? xCS : yCS;\n        const categories = extractCategories(table, catField, catSemantics?.ordinalSortOrder);\n        const categoryIndex = new Map(categories.map((category, index) => [String(category), index]));\n        const nextJitter = jitter(42);\n        const jitterHalfWidth = 0.3;\n        const palette = getChartJsPalette(ctx, isDiscrete(colorType) ? 'color' : 'group');\n        const opacity = chartProperties?.opacity ?? 0.7;\n        const explicitPointSize = Number(chartProperties?.pointSize ?? 0);\n        const pointRadius = explicitPointSize > 0\n            ? Math.max(1, Math.min(10, Math.round(explicitPointSize / 12)))\n            : 3;\n        const toColorValue = (value: any) => {\n            if (value == null) return NaN;\n            return isTemporalColor ? new Date(value).getTime() : Number(value);\n        };\n        const continuousColorValues = isContinuousColor && colorField\n            ? table.map((row: any) => toColorValue(row[colorField])).filter((value: number) => Number.isFinite(value))\n            : [];\n        const colorMin = continuousColorValues.length ? Math.min(...continuousColorValues) : 0;\n        const colorMax = continuousColorValues.length ? Math.max(...continuousColorValues) : 1;\n        const pointColors = isContinuousColor && colorField\n            ? table.map((row: any) => continuousColor(palette, toColorValue(row[colorField]), colorMin, colorMax, opacity))\n            : undefined;\n\n        const buildPoint = (row: any) => {\n            const category = String(row[catField] ?? '');\n            const index = categoryIndex.get(category) ?? 0;\n            const categoryValue = index + nextJitter() * jitterHalfWidth;\n            const continuousValue = row[contField];\n            return catAxis === 'x'\n                ? { x: categoryValue, y: continuousValue }\n                : { x: continuousValue, y: categoryValue };\n        };\n\n        const categoryScale = {\n            type: 'linear' as const,\n            min: -0.5,\n            max: Math.max(0.5, categories.length - 0.5),\n            title: { display: true, text: catField },\n            ticks: {\n                stepSize: 1,\n                callback(value: number | string) {\n                    const index = Math.round(Number(value));\n                    return categories[index] ?? '';\n                },\n            },\n        };\n        const continuousScale = {\n            type: 'linear' as const,\n            title: { display: true, text: contField },\n            ticks: { font: { size: 10 } },\n        };\n\n        const config: any = {\n            type: 'scatter',\n            data: { datasets: [] },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: catAxis === 'x'\n                    ? { x: categoryScale, y: continuousScale }\n                    : { x: continuousScale, y: categoryScale },\n                plugins: {\n                    tooltip: { enabled: true },\n                    legend: { display: !!colorField && isDiscrete(colorType) },\n                },\n            },\n        };\n\n        if (colorField && isDiscrete(colorType)) {\n            let colorIndex = 0;\n            for (const [name, rows] of groupBy(table, colorField)) {\n                config.data.datasets.push({\n                    label: name,\n                    data: rows.map(buildPoint),\n                    backgroundColor: getSeriesBackgroundColor(palette, colorIndex, opacity),\n                    borderColor: getSeriesBorderColor(palette, colorIndex),\n                    borderWidth: 1,\n                    pointRadius,\n                });\n                colorIndex++;\n            }\n        } else {\n            config.data.datasets.push({\n                data: table.map(buildPoint),\n                backgroundColor: pointColors ?? getSeriesBackgroundColor(palette, 0, opacity),\n                borderColor: pointColors ?? getSeriesBorderColor(palette, 0),\n                borderWidth: 1,\n                pointRadius,\n            });\n        }\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n    properties: [\n        { key: 'stepWidth', label: 'Jitter', type: 'continuous', min: 10, max: 100, step: 5, defaultValue: 20 },\n        { key: 'pointSize', label: 'Size', type: 'continuous', min: 0, max: 150, step: 5, defaultValue: 0 },\n        { key: 'opacity', label: 'Opacity', type: 'continuous', min: 0, max: 1, step: 0.05, defaultValue: 0 },\n    ] as ChartPropertyDef[],\n    pivot: makeCartesianPivot({\n        // θ (Strip → Scatter) declared centrally in core/chart-transitions.ts.\n    }),\n};","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { ChannelSemantics } from './types';\n\ntype EncodingType = 'nominal' | 'ordinal' | 'quantitative' | 'temporal';\n\ntype BandedAxisResult = {\n    axis: 'x' | 'y';\n    resolvedTypes?: Record<string, EncodingType>;\n};\n\nconst isDiscrete = (type: string | undefined): boolean =>\n    type === 'nominal' || type === 'ordinal';\n\nconst getFieldCardinality = (field: string, table: any[]): number =>\n    new Set(table.map((row: any) => row[field]).filter((value: any) => value != null)).size;\n\n/** Resolve a backend-neutral discrete encoding type for a field. */\nexport function resolveDiscreteType(\n    currentType: string,\n    field: string | undefined,\n    table: any[],\n): 'nominal' | 'ordinal' {\n    if (currentType === 'nominal') return 'nominal';\n    if (currentType === 'ordinal') return 'ordinal';\n    if (currentType === 'temporal') return 'ordinal';\n    if (currentType === 'quantitative' && field && table.length > 0) {\n        return getFieldCardinality(field, table) <= 20 ? 'ordinal' : 'nominal';\n    }\n    return 'nominal';\n}\n\n/** Choose the position axis that should use banded layout. */\nexport function detectBandedAxisFromSemantics(\n    channelSemantics: Record<string, ChannelSemantics>,\n    table: any[],\n    options: { preferAxis?: 'x' | 'y' } = {},\n): BandedAxisResult | null {\n    const xType = channelSemantics.x?.type;\n    const yType = channelSemantics.y?.type;\n\n    if (xType && isDiscrete(xType)) return { axis: 'x' };\n    if (yType && isDiscrete(yType)) return { axis: 'y' };\n\n    if (xType && yType) {\n        if (xType === 'quantitative' && yType !== 'quantitative') {\n            return { axis: 'y' };\n        }\n        if (yType === 'quantitative' && xType !== 'quantitative') {\n            return { axis: 'x' };\n        }\n        return { axis: options.preferAxis || 'x' };\n    }\n\n    if (xType) {\n        const newType = resolveDiscreteType(xType, channelSemantics.x?.field, table);\n        return { axis: 'x', resolvedTypes: { x: newType } };\n    }\n    if (yType) {\n        const newType = resolveDiscreteType(yType, channelSemantics.y?.field, table);\n        return { axis: 'y', resolvedTypes: { y: newType } };\n    }\n\n    return null;\n}\n\n/** Choose a banded axis and force its encoding type to be discrete. */\nexport function detectBandedAxisForceDiscrete(\n    channelSemantics: Record<string, ChannelSemantics>,\n    table: any[],\n    options: { preferAxis?: 'x' | 'y' } = {},\n): BandedAxisResult | null {\n    const result = detectBandedAxisFromSemantics(channelSemantics, table, options);\n    if (!result) return null;\n\n    const axis = result.axis;\n    const semantics = channelSemantics[axis];\n    if (!semantics) return result;\n\n    if (!isDiscrete(semantics.type)) {\n        const newType = resolveDiscreteType(semantics.type, semantics.field, table);\n        return {\n            axis,\n            resolvedTypes: { ...result.resolvedTypes, [axis]: newType },\n        };\n    }\n\n    return result;\n}","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Band-dodge decision: does a secondary discrete channel (`color`, or an explicit\n * `group` field) subdivide a categorical axis band into side-by-side sub-lanes\n * (\"dodge\"), or is it redundant/nested with the axis (render one full-width glyph\n * per band, \"nested\")?\n *\n * This is the single source of truth shared by the layout engine\n * (`compute-layout.ts`) and every backend template that dodges by color/group\n * (VL boxplot/violin/grouped-bar, ECharts, Chart.js). Keeping the decision here\n * prevents the layout and the templates from drifting apart (the class of bug\n * where the band is budgeted for a different lane count than the glyph is sized\n * for). See `design-docs/boxplot-color-dodge-heuristic.md`.\n *\n * Two independent quantities, deliberately NOT the same number:\n *   - the **gate** (`dodge`): keyed off the max per-band sub-cardinality — \"does\n *     any single band actually contain more than one sub-value?\"\n *   - the **lane count** (`laneCount`): the *global* distinct sub-value count,\n *     because that is what a global band-offset scale (VL `xOffset`, an ECharts\n *     series-per-group, a Chart.js dataset-per-group) physically reserves per\n *     band. Sizing a glyph by the max-per-band instead would overlap in sparse\n *     cross-products.\n */\n\n/** Default fraction of single-valued bands above which `auto` snaps to `none`\n *  (mostly-1:1 / dirty near-1:1 data). Tunable via `planBandDodge` options. */\nexport const DEFAULT_NESTED_SNAP_THRESHOLD = 0.9;\n\n/** Resolved dodge mode (what actually renders). */\nexport type DodgeMode = 'none' | 'local' | 'global';\n\n/** User-facing `dodge` chart-property values (`auto` defers to the compiler). */\nexport type DodgeOption = 'auto' | DodgeMode;\n\nexport interface BandDodgePlan {\n    /** Compiler's recommended default mode. */\n    mode: DodgeMode;\n    /** Back-compat: does the recommendation subdivide the band? (`mode !== 'none'`). */\n    dodge: boolean;\n    /** Lanes a *global* offset scale reserves per band = global distinct\n     *  sub-values (the `global` mode lane count). */\n    laneCount: number;\n    /** True when local and global dodge can produce different layouts. */\n    ambiguous: boolean;\n    /** Most distinct sub-values co-occurring within any single band. */\n    maxPerBand: number;\n    /** Global distinct sub-values. */\n    global: number;\n    /** Number of distinct axis bands. */\n    bandCount: number;\n}\n\nexport interface PlanBandDodgeOptions {\n    /** Fraction of single-valued bands above which `auto` snaps to `none`.\n     *  Defaults to {@link DEFAULT_NESTED_SNAP_THRESHOLD}. */\n    nestedSnapThreshold?: number;\n}\n\n/** Pure recommendation from the per-band statistics. */\nfunction recommendMode(\n    maxPerBand: number,\n    globalCount: number,\n    nestedFraction: number,\n    threshold: number,\n): DodgeMode {\n    // Nothing subdivides any band → full-width.\n    if (maxPerBand <= 1) return 'none';\n    // Mostly single-valued (a few dirty/outlier multi-color bands) → snap to\n    // full-width rather than dodge the whole chart for a couple of rows.\n    if (nestedFraction >= threshold) return 'none';\n    // Every occupied band spans the full sub-domain → uniform global grid.\n    if (maxPerBand >= globalCount) return 'global';\n    // Sparse / spiky → compact, centered per-band lanes.\n    return 'local';\n}\n\n/**\n * Decide whether `subField` dodges `axisField` for the given data.\n *\n * Confident zones (never ambiguous):\n *   - `maxPerBand <= 1`  → nested (redundant/nested with the axis; `color == x`\n *     or a 1:1 different-field pair).\n *   - `maxPerBand === global` → dodge (clean full cross-product).\n * Ambiguous zone (`1 < maxPerBand < global`, e.g. sparse cross-products or dirty\n * near-1:1 data): the `auto` lean is resolved by a configurable threshold on the\n * fraction of single-valued bands, and `ambiguous` is set so a host can surface\n * the toggle.\n */\nexport function planBandDodge(\n    table: ReadonlyArray<Record<string, unknown>>,\n    axisField: string,\n    subField: string,\n    options?: PlanBandDodgeOptions,\n): BandDodgePlan {\n    const perBand = new Map<unknown, Set<unknown>>();\n    const global = new Set<unknown>();\n    for (const row of table) {\n        global.add(row[subField]);\n        const key = row[axisField];\n        let bandSet = perBand.get(key);\n        if (!bandSet) perBand.set(key, (bandSet = new Set()));\n        bandSet.add(row[subField]);\n    }\n\n    const globalCount = Math.max(1, global.size);\n    const bandCount = perBand.size;\n    let maxPerBand = 0;\n    let singleValuedBands = 0;\n    let completeBands = 0;\n    for (const bandSet of perBand.values()) {\n        if (bandSet.size > maxPerBand) maxPerBand = bandSet.size;\n        if (bandSet.size <= 1) singleValuedBands++;\n        if (bandSet.size === globalCount) completeBands++;\n    }\n\n    const threshold = options?.nestedSnapThreshold ?? DEFAULT_NESTED_SNAP_THRESHOLD;\n    const nestedFraction = bandCount > 0 ? singleValuedBands / bandCount : 1;\n    const mode = recommendMode(maxPerBand, globalCount, nestedFraction, threshold);\n\n    return {\n        mode,\n        dodge: mode !== 'none',\n        laneCount: globalCount,\n        ambiguous: maxPerBand > 1 && completeBands < bandCount,\n        maxPerBand,\n        global: globalCount,\n        bandCount,\n    };\n}\n\n/** Number of sub-lanes a resolved mode reserves per band. */\nexport function laneCountForMode(plan: BandDodgePlan, mode: DodgeMode): number {\n    if (mode === 'global') return plan.global;\n    if (mode === 'local') return Math.max(1, plan.maxPerBand);\n    return 1;\n}\n\n/**\n * Apply a user `dodge` override on top of a plan. `none`/`local`/`global` are\n * hard overrides; `auto` (or unset) follows the compiler recommendation. A dodge\n * mode is downgraded to `none` when nothing actually subdivides a band\n * (`maxPerBand <= 1`), so forcing dodge on redundant color can't collapse it.\n */\nexport function resolveDodge(\n    plan: BandDodgePlan,\n    override?: string,\n): { mode: DodgeMode; laneCount: number } {\n    let mode: DodgeMode =\n        override === 'none' || override === 'local' || override === 'global'\n            ? override\n            : plan.mode;\n    if (mode !== 'none' && plan.maxPerBand <= 1) mode = 'none';\n    return { mode, laneCount: laneCountForMode(plan, mode) };\n}\n\n// ---------------------------------------------------------------------------\n// Back-compat shim (pre-`local` callers that only need a dodge boolean).\n// `local` currently renders via the global offset path, so its lane count is\n// the global one until the per-backend `local` renderer lands (Stage 2).\n// ---------------------------------------------------------------------------\n\n/** @deprecated user-facing values; prefer {@link DodgeOption}. */\nexport type ColorLayoutMode = DodgeOption;\n\n/** @deprecated prefer {@link resolveDodge}. Maps the mode to a dodge boolean and\n *  the global lane count (the only lane count the current renderers support). */\nexport function resolveBandDodge(\n    plan: BandDodgePlan,\n    override?: string,\n): { dodge: boolean; laneCount: number } {\n    // Legacy override spellings → new modes.\n    const normalized = override === 'dodge' ? 'global' : override === 'nested' ? 'none' : override;\n    const { mode } = resolveDodge(plan, normalized);\n    return { dodge: mode !== 'none', laneCount: plan.laneCount };\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { ChartEncoding, EncodingActionDef } from './types';\n\n/**\n * Reusable factories for Category-B encoding actions (see EncodingActionDef).\n *\n * These are authored once and attached to many templates, so the per-chart\n * knowledge (which channel is the category axis, which carries the measure)\n * lives in one place instead of being re-implemented per template.\n */\n\n/** The semantic sort choices the Sort control exposes. */\nexport type SortChoice = 'value-asc' | 'value-desc';\n\n// A measure is a quantitative channel or any aggregated channel.\nconst isMeasureEnc = (e?: ChartEncoding): boolean =>\n    !!e?.field && (!!e.aggregate || e.type === 'quantitative');\n\n// A sortable category axis is discrete (nominal/ordinal). Temporal axes are\n// deliberately excluded: reordering a time axis by value scrambles the\n// chronology, so Sort should not apply to them.\nconst isDiscreteCategoryEnc = (e?: ChartEncoding): boolean =>\n    !!e?.field && !e.aggregate && e.type !== 'quantitative' && e.type !== 'temporal';\n\n/**\n * Identify the discrete category axis and the measure axis among a pair of\n * position channels, so Sort works under either orientation (vertical or\n * horizontal) and only when a discrete axis actually exists.\n *\n * Returns `null` when there is no discrete category + measure pair to sort —\n * e.g. a temporal-x time series, or two quantitative axes (scatter). Callers\n * use this both to gate visibility and to no-op safely.\n */\nfunction resolveSortChannels(\n    encodings: Record<string, ChartEncoding>,\n    candidates: [string, string],\n): { category: string; measure: string } | null {\n    const category = candidates.find(c => isDiscreteCategoryEnc(encodings[c]));\n    const measure = candidates.find(c => isMeasureEnc(encodings[c]));\n    if (!category || !measure || category === measure) return null;\n    return { category, measure };\n}\n\n/**\n * Sort the category axis of a bar-like chart by the measure value.\n *\n * Encoding model: a value sort writes `sortBy = <measure channel>` (one of\n * 'x' | 'y', which the assembler understands) on the category channel.\n * \"Default\" clears the sort so the field's canonical ordering wins — the\n * natural order for ordinal/temporal-like categories, or alphabetic otherwise,\n * as decided by semantic resolution. The action is only applicable — and only\n * visible — when one position channel is a discrete category and the other is\n * a measure.\n *\n * @param channels Position-channel pair (default ['x', 'y']); the orientation\n *                 (which one is the category) is resolved per-encoding at runtime.\n */\nexport function makeSortAction(options?: {\n    key?: string;\n    label?: string;\n    channels?: [string, string];\n}): EncodingActionDef {\n    const candidates = options?.channels ?? ['x', 'y'];\n    return {\n        key: options?.key ?? 'sort',\n        label: options?.label ?? 'Sort',\n        dependencies: candidates,\n        isApplicable: (ctx) => resolveSortChannels(ctx.encodings, candidates) !== null,\n        control: {\n            type: 'discrete',\n            options: [\n                { value: undefined, label: 'Default' },\n                { value: 'value-desc', label: 'Value ↓' },\n                { value: 'value-asc', label: 'Value ↑' },\n            ],\n        },\n        get: (encodings) => {\n            const resolved = resolveSortChannels(encodings, candidates);\n            if (!resolved) return undefined;\n            const { category, measure } = resolved;\n            const enc = encodings[category];\n            if (enc.sortBy === measure) {\n                return enc.sortOrder === 'descending' ? 'value-desc' : 'value-asc';\n            }\n            // Any other sort (label order, custom value order, sort-by-color)\n            // isn't representable by this control → show as Default.\n            return undefined;\n        },\n        set: (encodings, value: SortChoice | undefined) => {\n            const resolved = resolveSortChannels(encodings, candidates);\n            if (!resolved) return encodings;\n            const { category, measure } = resolved;\n            const base = encodings[category];\n            let next: ChartEncoding;\n            switch (value) {\n                case 'value-asc':\n                    next = { ...base, sortBy: measure, sortOrder: 'ascending' };\n                    break;\n                case 'value-desc':\n                    next = { ...base, sortBy: measure, sortOrder: 'descending' };\n                    break;\n                default:\n                    next = { ...base, sortBy: undefined, sortOrder: undefined };\n            }\n            return { ...encodings, [category]: next };\n        },\n    };\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Bar Chart templates: Bar, Stacked Bar, Grouped Bar.\n *\n * Key contrast with Vega-Lite:\n *   VL: encoding channels determine stacking/grouping implicitly\n *   CJS: explicit datasets[] with stacked option on scales\n */\n\nimport { ChartTemplateDef, ChartPropertyDef, EncodingActionDef } from '../../core/types';\nimport {\n  resolveCategoryOrder,\n  groupBy,\n  detectAxes,\n  buildCategoryAlignedData,\n  getChartJsPalette,\n  getSeriesBorderColor,\n  getSeriesBackgroundColor,\n} from './utils';\nimport {\n    detectBandedAxisFromSemantics, detectBandedAxisForceDiscrete,\n} from '../../core/axis-detection';\nimport { planBandDodge, resolveDodge } from '../../core/band-dodge';\nimport { makeCartesianPivot } from '../../core/pivot';\nimport { makeSortAction } from '../../core/encoding-actions';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst isDiscrete = (type: string | undefined) => type === 'nominal' || type === 'ordinal';\n\n// ─── Bar Chart ──────────────────────────────────────────────────────────────\n\nexport const cjsBarChartDef: ChartTemplateDef = {\n    chart: 'Bar Chart',\n    template: { mark: 'bar', encoding: {} },\n    channels: ['x', 'y', 'color', 'opacity', 'column', 'row'],\n    markCognitiveChannel: 'length',\n    declareLayoutMode: (cs, table) => {\n        const result = detectBandedAxisFromSemantics(cs, table, { preferAxis: 'x' });\n        return {\n            axisFlags: result ? { [result.axis]: { banded: true } } : { x: { banded: true } },\n            resolvedTypes: result?.resolvedTypes,\n        };\n    },\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, chartProperties } = ctx;\n        const { categoryAxis, valueAxis } = detectAxes(channelSemantics);\n\n        const catField = channelSemantics[categoryAxis]?.field;\n        const valField = channelSemantics[valueAxis]?.field;\n        if (!catField || !valField) return;\n\n        const catCS = channelSemantics[categoryAxis];\n        const catEnc = ctx.encodings?.[categoryAxis];\n        const sortByField = catEnc?.sortBy ? channelSemantics[catEnc.sortBy]?.field : undefined;\n        const categories = resolveCategoryOrder(table, catField, {\n            ordinalSortOrder: catCS?.ordinalSortOrder,\n            sortBy: sortByField,\n            sortOrder: catEnc?.sortOrder,\n        });\n        const values = buildCategoryAlignedData(table, catField, valField, categories);\n\n        const isHorizontal = categoryAxis === 'y';\n\n        const palette = getChartJsPalette(ctx);\n\n        const config: any = {\n            type: 'bar',\n            data: {\n                labels: categories,\n                datasets: [{\n                    label: valField,\n                    data: values,\n                    backgroundColor: getSeriesBackgroundColor(palette, 0),\n                    borderColor: getSeriesBorderColor(palette, 0),\n                    borderWidth: 1,\n                    borderRadius: chartProperties?.cornerRadius ?? 0,\n                }],\n            },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                indexAxis: isHorizontal ? 'y' as const : 'x' as const,\n                scales: {\n                    x: {\n                        title: { display: true, text: isHorizontal ? valField : catField },\n                        ...(isHorizontal ? {} : {}),\n                    },\n                    y: {\n                        title: { display: true, text: isHorizontal ? catField : valField },\n                    },\n                },\n                plugins: {\n                    legend: { display: false },\n                    tooltip: { enabled: true },\n                },\n            },\n        };\n\n        // Apply zero-baseline from semantic decision\n        const valScale = isHorizontal ? 'x' : 'y';\n        const valCS = channelSemantics[valueAxis];\n        if (valCS?.zero) {\n            config.options.scales[valScale].beginAtZero = valCS.zero.zero !== false;\n        } else {\n            // Default: bars should include zero for length integrity\n            config.options.scales[valScale].beginAtZero = true;\n        }\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n    properties: [\n        { key: 'cornerRadius', label: 'Corners', type: 'continuous', min: 0, max: 15, step: 1, defaultValue: 0 },\n    ] as ChartPropertyDef[],\n    encodingActions: [makeSortAction()] as EncodingActionDef[],\n    pivot: makeCartesianPivot({\n        transpose: [['x', 'y']],\n        permute: [['x', 'y', 'color']],\n        shift: ['color', 'column', 'row'],\n    }),\n};\n\n// ─── Stacked Bar Chart ──────────────────────────────────────────────────────\n\nexport const cjsStackedBarChartDef: ChartTemplateDef = {\n    chart: 'Stacked Bar Chart',\n    template: { mark: 'bar', encoding: {} },\n    channels: ['x', 'y', 'color', 'column', 'row'],\n    markCognitiveChannel: 'length',\n    declareLayoutMode: (cs, table) => {\n        const result = detectBandedAxisFromSemantics(cs, table, { preferAxis: 'x' });\n        return {\n            axisFlags: result ? { [result.axis]: { banded: true } } : { x: { banded: true } },\n            resolvedTypes: result?.resolvedTypes,\n            paramOverrides: { continuousMarkCrossSection: { x: 20, y: 20, seriesCountAxis: 'auto' } },\n        };\n    },\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, chartProperties } = ctx;\n        const { categoryAxis, valueAxis } = detectAxes(channelSemantics);\n        const colorField = channelSemantics.color?.field;\n        const hasStackSeries = !!colorField;\n\n        const catField = channelSemantics[categoryAxis]?.field;\n        const valField = channelSemantics[valueAxis]?.field;\n        if (!catField || !valField) return;\n\n        const catCS = channelSemantics[categoryAxis];\n        const catEnc = ctx.encodings?.[categoryAxis];\n        const sortByField = catEnc?.sortBy ? channelSemantics[catEnc.sortBy]?.field : undefined;\n        const categories = resolveCategoryOrder(table, catField, {\n            ordinalSortOrder: catCS?.ordinalSortOrder,\n            sortBy: sortByField,\n            sortOrder: catEnc?.sortOrder,\n        });\n        const isHorizontal = categoryAxis === 'y';\n\n        const palette = getChartJsPalette(ctx, 'color');\n\n        const config: any = {\n            type: 'bar',\n            data: {\n                labels: categories,\n                datasets: [],\n            },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                indexAxis: isHorizontal ? 'y' as const : 'x' as const,\n                scales: {\n                    x: {\n                        stacked: hasStackSeries,\n                        title: { display: true, text: isHorizontal ? valField : catField },\n                    },\n                    y: {\n                        stacked: hasStackSeries,\n                        title: { display: true, text: isHorizontal ? catField : valField },\n                    },\n                },\n                plugins: {\n                    legend: { display: !!colorField },\n                    tooltip: { enabled: true },\n                },\n            },\n        };\n\n        if (colorField) {\n            const groups = groupBy(table, colorField);\n            let colorIdx = 0;\n            for (const [name, rows] of groups) {\n                const values = buildCategoryAlignedData(rows, catField, valField, categories);\n                config.data.datasets.push({\n                    label: name,\n                    data: values,\n                    backgroundColor: getSeriesBackgroundColor(palette, colorIdx),\n                    borderColor: getSeriesBorderColor(palette, colorIdx),\n                    borderWidth: 1,\n                });\n                colorIdx++;\n            }\n        } else {\n            const values = buildCategoryAlignedData(table, catField, valField, categories);\n            config.data.datasets.push({\n                label: valField,\n                data: values,\n                backgroundColor: getSeriesBackgroundColor(palette, 0),\n                borderColor: getSeriesBorderColor(palette, 0),\n                borderWidth: 1,\n            });\n        }\n\n        // Apply zero-baseline from semantic decision\n        const valScaleS = isHorizontal ? 'x' : 'y';\n        const valCSs = channelSemantics[valueAxis];\n        if (valCSs?.zero) {\n            config.options.scales[valScaleS].beginAtZero = valCSs.zero.zero !== false;\n        } else {\n            config.options.scales[valScaleS].beginAtZero = true;\n        }\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n    encodingActions: [makeSortAction()] as EncodingActionDef[],\n    pivot: makeCartesianPivot({\n        transpose: [['x', 'y']],\n        permute: [['x', 'y', 'color']],\n        shift: ['color', 'group', 'column', 'row'],\n        // θ (→ Grouped Bar) declared centrally in core/chart-transitions.ts.\n    }),\n};\n\n// ─── Grouped Bar Chart ──────────────────────────────────────────────────────\n\nexport const cjsGroupedBarChartDef: ChartTemplateDef = {\n    chart: 'Grouped Bar Chart',\n    template: { mark: 'bar', encoding: {} },\n    channels: ['x', 'y', 'group', 'color', 'column', 'row'],\n    markCognitiveChannel: 'length',\n    declareLayoutMode: (cs, table, chartProperties) => {\n        const result = detectBandedAxisForceDiscrete(cs, table, { preferAxis: 'x' });\n        const decl: any = {\n            axisFlags: result ? { [result.axis]: { banded: true } } : { x: { banded: true } },\n            resolvedTypes: result?.resolvedTypes,\n            paramOverrides: { continuousMarkCrossSection: { x: 20, y: 20, seriesCountAxis: 'auto' } },\n        };\n        const groupField = cs.group?.field || cs.color?.field;\n        const axisField = result?.axis ? cs[result.axis]?.field : (isDiscrete(cs.x?.type) ? cs.x?.field : cs.y?.field);\n        if (groupField && axisField) {\n            const plan = planBandDodge(table, axisField, groupField);\n            const { mode } = resolveDodge(plan, chartProperties?.dodge);\n            if (mode === 'local') decl.groupLaneCount = Math.max(1, plan.maxPerBand);\n        }\n        return decl;\n    },\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, chartProperties } = ctx;\n        const { categoryAxis, valueAxis } = detectAxes(channelSemantics);\n        const groupField = channelSemantics.group?.field || channelSemantics.color?.field;\n\n        const catField = channelSemantics[categoryAxis]?.field;\n        const valField = channelSemantics[valueAxis]?.field;\n        if (!catField || !valField) return;\n\n        const catCS = channelSemantics[categoryAxis];\n        const catEnc = ctx.encodings?.[categoryAxis];\n        const sortByField = catEnc?.sortBy ? channelSemantics[catEnc.sortBy]?.field : undefined;\n        const categories = resolveCategoryOrder(table, catField, {\n            ordinalSortOrder: catCS?.ordinalSortOrder,\n            sortBy: sortByField,\n            sortOrder: catEnc?.sortOrder,\n        });\n        const isHorizontal = categoryAxis === 'y';\n\n        const palette = getChartJsPalette(ctx, 'group');\n\n        // Decide compact (local) vs fixed-lane (global) dodge.\n        const dodgePlan = groupField ? planBandDodge(table, catField, groupField) : null;\n        const dodgeMode = dodgePlan ? resolveDodge(dodgePlan, chartProperties?.dodge).mode : 'none';\n\n        const config: any = {\n            type: 'bar',\n            data: {\n                labels: categories,\n                datasets: [],\n            },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                indexAxis: isHorizontal ? 'y' as const : 'x' as const,\n                scales: {\n                    x: {\n                        title: { display: true, text: isHorizontal ? valField : catField },\n                    },\n                    y: {\n                        title: { display: true, text: isHorizontal ? catField : valField },\n                    },\n                },\n                plugins: {\n                    legend: { display: !!groupField },\n                    tooltip: { enabled: true },\n                },\n            },\n        };\n\n        if (groupField && dodgeMode === 'local') {\n            // Local (compact) dodge: pack only `maxPerBand` lanes per band,\n            // left-aligned. Each lane is a dataset; a band with fewer present\n            // groups leaves trailing lanes null. Bars are colored per-datum by\n            // their group value, and a custom legend maps group → swatch (lane\n            // dataset labels are synthetic).\n            const globalGroups: string[] = [...new Set(table.map((r) => String(r[groupField] ?? '')))].filter(Boolean).sort();\n            const colorFor = (g: string) => getSeriesBackgroundColor(palette, Math.max(0, globalGroups.indexOf(g)));\n            const borderFor = (g: string) => getSeriesBorderColor(palette, Math.max(0, globalGroups.indexOf(g)));\n\n            // Per-band ordered present groups → lane index.\n            const perBand = new Map<string, string[]>();\n            for (const cat of categories) perBand.set(cat, []);\n            for (const r of table) {\n                const cat = String(r[catField] ?? '');\n                const g = String(r[groupField] ?? '');\n                if (!perBand.has(cat) || !g) continue;\n                const arr = perBand.get(cat)!;\n                if (!arr.includes(g)) arr.push(g);\n            }\n            for (const arr of perBand.values()) arr.sort();\n            const maxPerBand = Math.max(1, ...[...perBand.values()].map((a) => a.length));\n\n            const valAt = new Map<string, number>();\n            for (const r of table) {\n                const v = Number(r[valField]);\n                if (isFinite(v)) valAt.set(`${r[catField]}\\u0000${r[groupField]}`, v);\n            }\n\n            for (let lane = 0; lane < maxPerBand; lane++) {\n                const data: (number | null)[] = [];\n                const bg: string[] = [];\n                const bd: string[] = [];\n                for (const cat of categories) {\n                    const g = perBand.get(cat)?.[lane];\n                    if (g === undefined) { data.push(null); bg.push('transparent'); bd.push('transparent'); continue; }\n                    const v = valAt.get(`${cat}\\u0000${g}`);\n                    data.push(v === undefined ? null : v);\n                    bg.push(colorFor(g));\n                    bd.push(borderFor(g));\n                }\n                config.data.datasets.push({\n                    label: `__lane${lane}`,\n                    data,\n                    backgroundColor: bg,\n                    borderColor: bd,\n                    borderWidth: 1,\n                });\n            }\n\n            // Custom legend: one swatch per group value (not per lane).\n            config.options.plugins.legend = {\n                display: true,\n                labels: {\n                    generateLabels: () => globalGroups.map((g) => ({\n                        text: g,\n                        fillStyle: colorFor(g),\n                        strokeStyle: borderFor(g),\n                        lineWidth: 1,\n                    })),\n                },\n            };\n        } else if (groupField) {\n            const groups = groupBy(table, groupField);\n            let colorIdx = 0;\n            for (const [name, rows] of groups) {\n                const values = buildCategoryAlignedData(rows, catField, valField, categories);\n                config.data.datasets.push({\n                    label: name,\n                    data: values,\n                    backgroundColor: getSeriesBackgroundColor(palette, colorIdx),\n                    borderColor: getSeriesBorderColor(palette, colorIdx),\n                    borderWidth: 1,\n                });\n                colorIdx++;\n            }\n        } else {\n            const values = buildCategoryAlignedData(table, catField, valField, categories);\n            config.data.datasets.push({\n                label: valField,\n                data: values,\n                backgroundColor: getSeriesBackgroundColor(palette, 0),\n                borderColor: getSeriesBorderColor(palette, 0),\n                borderWidth: 1,\n            });\n        }\n\n        // Apply zero-baseline from semantic decision\n        const valScaleG = isHorizontal ? 'x' : 'y';\n        const valCSg = channelSemantics[valueAxis];\n        if (valCSg?.zero) {\n            config.options.scales[valScaleG].beginAtZero = valCSg.zero.zero !== false;\n        } else {\n            config.options.scales[valScaleG].beginAtZero = true;\n        }\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n    properties: [\n        {\n            key: 'dodge', label: 'Dodge', type: 'discrete',\n            options: [\n                { value: 'auto',   label: 'Auto' },\n                { value: 'local',  label: 'Local (compact)' },\n                { value: 'global', label: 'Global (aligned)' },\n            ],\n            defaultValue: 'auto',\n            check: (ctx) => {\n                const isDisc = (t: string | undefined) => t === 'nominal' || t === 'ordinal';\n                const groupField = ctx.channelSemantics?.group?.field\n                    ?? ctx.channelSemantics?.color?.field\n                    ?? ctx.encodings?.group?.field\n                    ?? ctx.encodings?.color?.field;\n                const axisField = isDisc(ctx.channelSemantics?.x?.type)\n                    ? ctx.channelSemantics?.x?.field\n                    : ctx.channelSemantics?.y?.field;\n                const rows = ctx.data;\n                if (!groupField || !axisField || !rows) return { applicable: false };\n                const plan = planBandDodge(rows, axisField, groupField);\n                return { applicable: plan.ambiguous, recommendedValue: plan.mode === 'none' ? 'auto' : plan.mode };\n            },\n        },\n    ] as ChartPropertyDef[],\n    encodingActions: [makeSortAction()] as EncodingActionDef[],\n    pivot: makeCartesianPivot({\n        transpose: [['x', 'y']],\n        permute: [['x', 'y', 'color']],\n        shift: ['color', 'group', 'column', 'row'],\n        // θ (→ Stacked Bar) declared centrally in core/chart-transitions.ts.\n    }),\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Combo (Bar + Line) template.\n *\n * A dual-measure chart: bars for a primary measure and a line for a secondary\n * measure plotted on its own right-hand axis. This is one of the most common\n * dashboard idioms (e.g. revenue bars + growth-rate line).\n *\n * Data model:\n *   x  (nominal)      → shared category axis\n *   y  (quantitative) → the BAR measure (left axis)\n *   line measure      → the LINE measure (right axis); chosen from\n *                       `chartProperties.lineField`, else the first other\n *                       numeric field in the data.\n *   color is intentionally not used — the two series ARE the legend.\n *\n * Chart.js renders this as a base `type: 'bar'` chart with one dataset\n * overridden to `type: 'line'` and bound to a secondary `y1` scale.\n */\n\nimport { ChartTemplateDef } from '../../core/types';\nimport {\n    extractCategories,\n    buildCategoryAlignedData,\n    getChartJsPalette,\n    getSeriesBorderColor,\n    getSeriesBackgroundColor,\n} from './utils';\nimport { detectBandedAxisFromSemantics } from '../../core/axis-detection';\n\n/** A field is numeric if (nearly) all of its non-null values parse as numbers. */\nfunction isNumericField(table: any[], field: string): boolean {\n    let total = 0;\n    let numeric = 0;\n    for (const row of table) {\n        const v = row[field];\n        if (v == null || v === '') continue;\n        total++;\n        if (typeof v === 'number' ? isFinite(v) : !isNaN(Number(v))) numeric++;\n    }\n    return total > 0 && numeric / total >= 0.9;\n}\n\nexport const cjsComboChartDef: ChartTemplateDef = {\n    chart: 'Combo Chart',\n    template: { mark: 'bar', encoding: {} },\n    channels: ['x', 'y', 'column', 'row'],\n    markCognitiveChannel: 'length',\n    declareLayoutMode: (cs, table) => {\n        const result = detectBandedAxisFromSemantics(cs, table, { preferAxis: 'x' });\n        return {\n            axisFlags: result ? { [result.axis]: { banded: true } } : { x: { banded: true } },\n            resolvedTypes: result?.resolvedTypes,\n        };\n    },\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, chartProperties } = ctx;\n        const catField = channelSemantics.x?.field;\n        const barField = channelSemantics.y?.field;\n        if (!catField || !barField || table.length === 0) return;\n\n        // Resolve the line measure: explicit override, else first other numeric field.\n        const lineField: string | undefined =\n            (chartProperties?.lineField && chartProperties.lineField in table[0])\n                ? chartProperties.lineField\n                : Object.keys(table[0]).find(\n                    (k) => k !== catField && k !== barField && isNumericField(table, k),\n                );\n\n        const categories = extractCategories(table, catField, channelSemantics.x?.ordinalSortOrder);\n        const barData = buildCategoryAlignedData(table, catField, barField, categories);\n\n        const palette = getChartJsPalette(ctx, 'color');\n\n        const datasets: any[] = [{\n            type: 'bar' as const,\n            label: barField,\n            data: barData,\n            yAxisID: 'y',\n            order: 2,\n            backgroundColor: getSeriesBackgroundColor(palette, 0),\n            borderColor: getSeriesBorderColor(palette, 0),\n            borderWidth: 1,\n            borderRadius: chartProperties?.cornerRadius ?? 0,\n        }];\n\n        if (lineField) {\n            const lineData = buildCategoryAlignedData(table, catField, lineField, categories);\n            datasets.push({\n                type: 'line' as const,\n                label: lineField,\n                data: lineData,\n                yAxisID: 'y1',\n                order: 1,\n                borderColor: getSeriesBorderColor(palette, 1),\n                backgroundColor: 'transparent',\n                borderWidth: 2,\n                pointRadius: 3,\n                tension: 0.3,\n                fill: false,\n            });\n        }\n\n        const config: any = {\n            type: 'bar',\n            data: { labels: categories, datasets },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: {\n                    x: {\n                        title: { display: true, text: catField },\n                    },\n                    y: {\n                        type: 'linear' as const,\n                        position: 'left' as const,\n                        beginAtZero: channelSemantics.y?.zero ? channelSemantics.y.zero.zero !== false : true,\n                        title: { display: true, text: barField },\n                    },\n                    ...(lineField ? {\n                        y1: {\n                            type: 'linear' as const,\n                            position: 'right' as const,\n                            title: { display: true, text: lineField },\n                            // Don't draw the right axis grid over the bars.\n                            grid: { drawOnChartArea: false },\n                        },\n                    } : {}),\n                },\n                plugins: {\n                    legend: { display: true },\n                    tooltip: { enabled: true },\n                },\n            },\n        };\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n    properties: [\n        { key: 'cornerRadius', label: 'Corners', type: 'continuous', min: 0, max: 15, step: 1, defaultValue: 0 },\n    ],\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Line Chart template (single + multi-series).\n *\n * Contrast with VL:\n *   VL: encoding.x + encoding.y + encoding.color → auto-groups into lines\n *   CJS: explicit datasets[] — each dataset is one line\n */\n\nimport { ChartTemplateDef, ChartPropertyDef } from '../../core/types';\nimport {\n    extractCategories,\n    groupBy,\n    buildCategoryAlignedData,\n    getChartJsPalette,\n    getSeriesBorderColor,\n    coerceUnixMsForChartJs,\n} from './utils';\nimport { makeCartesianPivot } from '../../core/pivot';\n\nconst isDiscrete = (type: string | undefined) => type === 'nominal' || type === 'ordinal';\n\nexport const cjsLineChartDef: ChartTemplateDef = {\n    chart: 'Line Chart',\n    template: { mark: 'line', encoding: {} },\n    channels: ['x', 'y', 'color', 'opacity', 'column', 'row'],\n    markCognitiveChannel: 'position',\n    declareLayoutMode: () => ({\n        paramOverrides: { continuousMarkCrossSection: { x: 100, y: 20, seriesCountAxis: 'auto' }, facetAspectRatioResistance: 0.5 },\n    }),\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, fullTable, chartProperties } = ctx;\n        const xCS = channelSemantics.x;\n        const yCS = channelSemantics.y;\n        const colorField = channelSemantics.color?.field;\n\n        if (!xCS?.field || !yCS?.field) return;\n        const xField = xCS.field;\n        const yField = yCS.field;\n\n        const xIsDiscrete = isDiscrete(xCS.type);\n        const xIsTemporal = xCS.type === 'temporal';\n\n        const mapContinuousX = (raw: unknown) =>\n            (xIsTemporal ? coerceUnixMsForChartJs(raw) : raw);\n\n        // For a continuous (linear) x-scale, Chart.js auto-computes a \"nice\"\n        // range that, on large Unix-ms timestamps, balloons far beyond the\n        // data extent and squeezes the plotted line into a narrow band. Pin\n        // the scale to the actual data extent — computed from the full table\n        // so faceted small multiples share one aligned x-domain (matching the\n        // Vega-Lite output).\n        let continuousXExtent: { min: number; max: number } | undefined;\n        if (!xIsDiscrete) {\n            const xNums = (fullTable ?? table)\n                .map((r: any) => mapContinuousX(r[xField]))\n                .filter((v: any): v is number => typeof v === 'number' && Number.isFinite(v));\n            if (xNums.length > 0) {\n                continuousXExtent = { min: Math.min(...xNums), max: Math.max(...xNums) };\n            }\n        }\n\n        const categories = xIsDiscrete\n            ? extractCategories(table, xField, xCS.ordinalSortOrder)\n            : undefined;\n\n        // Determine tension for interpolation\n        const interpolate = chartProperties?.interpolate;\n        const tension = (interpolate === 'monotone' || interpolate === 'basis' ||\n                         interpolate === 'cardinal' || interpolate === 'catmull-rom')\n            ? 0.4 : 0;\n        const stepped = interpolate === 'step' ? 'middle' as const\n                      : interpolate === 'step-before' ? 'before' as const\n                      : interpolate === 'step-after' ? 'after' as const\n                      : false as const;\n\n        const palette = getChartJsPalette(ctx, 'color');\n\n        const config: any = {\n            type: 'line',\n            data: {\n                labels: categories || [],\n                datasets: [],\n            },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: {\n                    x: {\n                        type: xIsDiscrete ? 'category' : 'linear',\n                        title: { display: true, text: xField },\n                        ...(continuousXExtent\n                            ? { min: continuousXExtent.min, max: continuousXExtent.max }\n                            : {}),\n                        ticks: {\n                            font: { size: 10 },\n                            ...(xIsTemporal\n                                ? {\n                                    maxTicksLimit: 4,\n                                    autoSkip: true,\n                                    maxRotation: 0,\n                                    callback(v: number | string) {\n                                        const n = typeof v === 'number' ? v : Number(v);\n                                        if (!Number.isFinite(n)) return String(v);\n                                        // Drop the day for spans longer than ~2\n                                        // months so faceted (narrow) panels don't\n                                        // collide long \"Apr 18, 2025\" labels.\n                                        const spanDays = continuousXExtent\n                                            ? (continuousXExtent.max - continuousXExtent.min) / 86_400_000\n                                            : 0;\n                                        const opts: Intl.DateTimeFormatOptions = spanDays > 60\n                                            ? { month: 'short', year: 'numeric' }\n                                            : { month: 'short', day: 'numeric', year: 'numeric' };\n                                        return new Date(n).toLocaleDateString(undefined, opts);\n                                    },\n                                }\n                                : {}),\n                        },\n                    },\n                    y: {\n                        type: 'linear',\n                        title: { display: true, text: yField },\n                        ticks: { font: { size: 10 } },\n                    },\n                },\n                plugins: {\n                    tooltip: { enabled: true },\n                },\n            },\n        };\n\n        // Zero-baseline: Chart.js defaults beginAtZero to false, so\n        // explicitly set true when the semantic decision includes zero.\n        if (channelSemantics.y?.zero) {\n            config.options.scales.y.beginAtZero = channelSemantics.y.zero.zero !== false;\n        }\n\n        if (colorField) {\n            const groups = groupBy(table, colorField);\n            config.options.plugins.legend = { display: true };\n\n            let colorIdx = 0;\n            for (const [name, rows] of groups) {\n                const data = xIsDiscrete\n                    ? buildCategoryAlignedData(rows, xField, yField, categories!)\n                    : rows\n                        .map(r => ({ x: mapContinuousX(r[xField]), y: r[yField] }))\n                        .filter(p => p.y != null && (xIsTemporal ? Number.isFinite(p.x as number) : true));\n\n                config.data.datasets.push({\n                    label: name,\n                    data,\n                    borderColor: getSeriesBorderColor(palette, colorIdx),\n                    backgroundColor: 'transparent',\n                    tension,\n                    stepped,\n                    pointRadius: 3,\n                    fill: false,\n                });\n                colorIdx++;\n            }\n        } else {\n            const data = xIsDiscrete\n                ? categories!.map(cat => {\n                    const row = table.find(r => String(r[xField]) === cat);\n                    return row ? row[yField] : null;\n                })\n                : table\n                    .map(r => ({ x: mapContinuousX(r[xField]), y: r[yField] }))\n                    .filter(p => p.y != null && (xIsTemporal ? Number.isFinite(p.x as number) : true));\n\n            config.data.datasets.push({\n                label: yField,\n                data,\n                borderColor: getSeriesBorderColor(palette, 0),\n                backgroundColor: 'transparent',\n                tension,\n                stepped,\n                pointRadius: 3,\n                fill: false,\n            });\n            config.options.plugins.legend = { display: false };\n        }\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n    properties: [\n        {\n            key: 'interpolate', label: 'Curve', type: 'discrete', options: [\n                { value: undefined, label: 'Default (linear)' },\n                { value: 'linear', label: 'Linear' },\n                { value: 'monotone', label: 'Monotone (smooth)' },\n                { value: 'step', label: 'Step' },\n                { value: 'step-before', label: 'Step Before' },\n                { value: 'step-after', label: 'Step After' },\n                { value: 'basis', label: 'Basis (smooth)' },\n                { value: 'cardinal', label: 'Cardinal' },\n                { value: 'catmull-rom', label: 'Catmull-Rom' },\n            ],\n        } as ChartPropertyDef,\n    ],\n    pivot: makeCartesianPivot({\n        permute: [['y', 'color']],\n        shift: ['color', 'group', 'column', 'row'],\n    }),\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * =============================================================================\n * TYPE REGISTRY — Single Source of Truth\n * =============================================================================\n *\n * Every recognized semantic type is registered here with its orthogonal\n * compilation dimensions. This is the ONLY place where per-type properties\n * are defined. All other files (field-semantics.ts, semantic-types.ts)\n * derive helper functions by querying this registry.\n *\n * To add a new semantic type: add an entry here.\n * To query a type's properties: use `getRegistryEntry()`.\n * =============================================================================\n */\n\n// ---------------------------------------------------------------------------\n// Visualization Categories\n// ---------------------------------------------------------------------------\n\nexport type VisCategory = 'quantitative' | 'ordinal' | 'nominal' | 'temporal' | 'geographic';\n\n// ---------------------------------------------------------------------------\n// Registry Dimension Types\n// ---------------------------------------------------------------------------\n\n/** Top-level type family */\nexport type T0Family = 'Temporal' | 'Measure' | 'Discrete' | 'Geographic' | 'Categorical' | 'Identifier';\n\n/** Mid-level category within a family */\nexport type T1Category =\n    | 'DateTime' | 'DateGranule' | 'Duration'\n    | 'Amount' | 'Physical' | 'Proportion' | 'SignedMeasure' | 'GenericMeasure'\n    | 'Rank' | 'Score'\n    | 'GeoCoordinate' | 'GeoPlace'\n    | 'Entity' | 'Coded' | 'Binned'\n    | 'ID';\n\nexport type DomainShape = 'open' | 'bounded' | 'fixed' | 'cyclic';\nexport type AggRole = 'additive' | 'intensive' | 'signed-additive' | 'dimension' | 'identifier';\nexport type DivergingClass = 'none' | 'inherent' | 'conditional';\nexport type FormatClass = 'currency' | 'percent'\n    | 'unit-suffix' | 'integer' | 'decimal' | 'plain';\n\n/**\n * Zero-baseline classification for quantitative axes.\n *\n * - `meaningful`: 0 = absence of the measured thing; axis should include 0 (Count, Revenue).\n * - `arbitrary`:  0 is arbitrary or nonexistent; data-fit the axis (Temperature, Year, Rank).\n * - `contextual`: 0 is meaningful but data-fitting may be better when data is far from 0 (Percentage, Score).\n * - `none`:       Not a quantitative type; zero question is irrelevant (all categorical/temporal types).\n */\nexport type ZeroBaseline = 'meaningful' | 'arbitrary' | 'contextual' | 'none';\n\nexport interface TypeRegistryEntry {\n    t0: T0Family;\n    t1: T1Category;\n    visEncodings: VisCategory[];\n    aggRole: AggRole;\n    domainShape: DomainShape;\n    diverging: DivergingClass;\n    formatClass: FormatClass;\n    /** Zero-baseline classification for quantitative axes */\n    zeroBaseline: ZeroBaseline;\n    /** Domain padding fraction for non-zero axes (0 = no padding) */\n    zeroPad: number;\n}\n\n// ---------------------------------------------------------------------------\n// The Registry\n// ---------------------------------------------------------------------------\n\n/**\n * Static registry mapping every recognized semantic type to its\n * tier membership and orthogonal compilation dimensions.\n *\n * Types not in this registry are treated as 'Unknown' → nominal/plain.\n */\nconst TYPE_REGISTRY: Record<string, TypeRegistryEntry> = {\n    // --- Temporal: DateTime ---\n    DateTime:      { t0: 'Temporal', t1: 'DateTime', visEncodings: ['temporal'],           aggRole: 'dimension',  domainShape: 'open',    diverging: 'none', formatClass: 'plain',           zeroBaseline: 'none', zeroPad: 0 },\n    Date:          { t0: 'Temporal', t1: 'DateTime', visEncodings: ['temporal'],           aggRole: 'dimension',  domainShape: 'open',    diverging: 'none', formatClass: 'plain',           zeroBaseline: 'none', zeroPad: 0 },\n    Time:          { t0: 'Temporal', t1: 'DateTime', visEncodings: ['temporal'],           aggRole: 'dimension',  domainShape: 'open',    diverging: 'none', formatClass: 'plain',           zeroBaseline: 'none', zeroPad: 0 },\n    Timestamp:     { t0: 'Temporal', t1: 'DateTime', visEncodings: ['temporal'],           aggRole: 'dimension',  domainShape: 'open',    diverging: 'none', formatClass: 'plain',           zeroBaseline: 'none', zeroPad: 0 },\n\n    // --- Temporal: DateGranule ---\n    Year:          { t0: 'Temporal', t1: 'DateGranule', visEncodings: ['temporal', 'ordinal'], aggRole: 'dimension', domainShape: 'open',    diverging: 'none', formatClass: 'integer',        zeroBaseline: 'arbitrary', zeroPad: 0.03 },\n    Quarter:       { t0: 'Temporal', t1: 'DateGranule', visEncodings: ['ordinal'],            aggRole: 'dimension', domainShape: 'cyclic',  diverging: 'none', formatClass: 'plain',          zeroBaseline: 'none', zeroPad: 0 },\n    Month:         { t0: 'Temporal', t1: 'DateGranule', visEncodings: ['ordinal'],            aggRole: 'dimension', domainShape: 'cyclic',  diverging: 'none', formatClass: 'plain',          zeroBaseline: 'none', zeroPad: 0 },\n    Week:          { t0: 'Temporal', t1: 'DateGranule', visEncodings: ['ordinal'],            aggRole: 'dimension', domainShape: 'cyclic',  diverging: 'none', formatClass: 'plain',          zeroBaseline: 'none', zeroPad: 0 },\n    Day:           { t0: 'Temporal', t1: 'DateGranule', visEncodings: ['ordinal'],            aggRole: 'dimension', domainShape: 'cyclic',  diverging: 'none', formatClass: 'plain',          zeroBaseline: 'none', zeroPad: 0 },\n    Hour:          { t0: 'Temporal', t1: 'DateGranule', visEncodings: ['ordinal'],            aggRole: 'dimension', domainShape: 'cyclic',  diverging: 'none', formatClass: 'integer',        zeroBaseline: 'arbitrary', zeroPad: 0 },\n    YearMonth:     { t0: 'Temporal', t1: 'DateGranule', visEncodings: ['temporal', 'ordinal'], aggRole: 'dimension', domainShape: 'open',   diverging: 'none', formatClass: 'plain',          zeroBaseline: 'none', zeroPad: 0 },\n    YearQuarter:   { t0: 'Temporal', t1: 'DateGranule', visEncodings: ['temporal', 'ordinal'], aggRole: 'dimension', domainShape: 'open',   diverging: 'none', formatClass: 'plain',          zeroBaseline: 'none', zeroPad: 0 },\n    YearWeek:      { t0: 'Temporal', t1: 'DateGranule', visEncodings: ['temporal', 'ordinal'], aggRole: 'dimension', domainShape: 'open',   diverging: 'none', formatClass: 'plain',          zeroBaseline: 'none', zeroPad: 0 },\n    Decade:        { t0: 'Temporal', t1: 'DateGranule', visEncodings: ['temporal', 'ordinal'], aggRole: 'dimension', domainShape: 'open',   diverging: 'none', formatClass: 'integer',        zeroBaseline: 'arbitrary', zeroPad: 0.03 },\n\n    // --- Temporal: Duration ---\n    Duration:      { t0: 'Temporal', t1: 'Duration', visEncodings: ['quantitative'],       aggRole: 'additive',   domainShape: 'open',    diverging: 'none', formatClass: 'unit-suffix',     zeroBaseline: 'meaningful', zeroPad: 0 },\n\n    // --- Measure: Amount ---\n    Amount:        { t0: 'Measure', t1: 'Amount', visEncodings: ['quantitative'],          aggRole: 'additive',   domainShape: 'open',    diverging: 'none',        formatClass: 'currency',   zeroBaseline: 'meaningful', zeroPad: 0 },\n    Price:         { t0: 'Measure', t1: 'Amount', visEncodings: ['quantitative'],          aggRole: 'intensive',  domainShape: 'open',    diverging: 'none',        formatClass: 'currency',   zeroBaseline: 'meaningful', zeroPad: 0 },\n\n    // --- Measure: Physical ---\n    Quantity:      { t0: 'Measure', t1: 'Physical', visEncodings: ['quantitative'],        aggRole: 'additive',   domainShape: 'open',    diverging: 'none',        formatClass: 'unit-suffix', zeroBaseline: 'meaningful', zeroPad: 0 },\n    Temperature:   { t0: 'Measure', t1: 'Physical', visEncodings: ['quantitative'],        aggRole: 'intensive',  domainShape: 'open',    diverging: 'conditional', formatClass: 'unit-suffix', zeroBaseline: 'arbitrary', zeroPad: 0.05 },\n\n    // --- Measure: Proportion ---\n    Percentage:    { t0: 'Measure', t1: 'Proportion', visEncodings: ['quantitative'],      aggRole: 'intensive',  domainShape: 'bounded', diverging: 'none',        formatClass: 'percent',    zeroBaseline: 'contextual', zeroPad: 0 },\n\n    // --- Measure: SignedMeasure ---\n    Profit:             { t0: 'Measure', t1: 'SignedMeasure', visEncodings: ['quantitative'], aggRole: 'signed-additive', domainShape: 'open', diverging: 'conditional', formatClass: 'decimal',          zeroBaseline: 'meaningful', zeroPad: 0 },\n    PercentageChange:   { t0: 'Measure', t1: 'SignedMeasure', visEncodings: ['quantitative'], aggRole: 'intensive',       domainShape: 'open', diverging: 'conditional', formatClass: 'percent',          zeroBaseline: 'contextual', zeroPad: 0.05 },\n    Sentiment:          { t0: 'Measure', t1: 'SignedMeasure', visEncodings: ['quantitative'], aggRole: 'intensive',       domainShape: 'open', diverging: 'inherent',    formatClass: 'decimal',          zeroBaseline: 'meaningful', zeroPad: 0 },\n    Correlation:        { t0: 'Measure', t1: 'SignedMeasure', visEncodings: ['quantitative'], aggRole: 'intensive',       domainShape: 'bounded', diverging: 'inherent', formatClass: 'decimal',          zeroBaseline: 'meaningful', zeroPad: 0 },\n\n    // --- Measure: GenericMeasure ---\n    Count:         { t0: 'Measure', t1: 'GenericMeasure', visEncodings: ['quantitative'],  aggRole: 'additive',   domainShape: 'open',    diverging: 'none',        formatClass: 'integer',    zeroBaseline: 'meaningful', zeroPad: 0 },\n    Number:        { t0: 'Measure', t1: 'GenericMeasure', visEncodings: ['quantitative'],  aggRole: 'additive',   domainShape: 'open',    diverging: 'none',        formatClass: 'decimal',    zeroBaseline: 'meaningful', zeroPad: 0 },\n\n    // --- Discrete ---\n    Rank:          { t0: 'Discrete', t1: 'Rank',  visEncodings: ['ordinal'],               aggRole: 'dimension',  domainShape: 'open',    diverging: 'none',        formatClass: 'integer',    zeroBaseline: 'arbitrary', zeroPad: 0.08 },\n    Score:         { t0: 'Discrete', t1: 'Score', visEncodings: ['quantitative', 'ordinal'], aggRole: 'intensive', domainShape: 'bounded', diverging: 'conditional', formatClass: 'decimal',    zeroBaseline: 'contextual', zeroPad: 0.05 },\n    ID:            { t0: 'Identifier', t1: 'ID',  visEncodings: ['nominal'],               aggRole: 'identifier', domainShape: 'open',    diverging: 'none',        formatClass: 'plain',      zeroBaseline: 'arbitrary', zeroPad: 0 },\n\n    // --- Geographic ---\n    Latitude:      { t0: 'Geographic', t1: 'GeoCoordinate', visEncodings: ['quantitative', 'geographic'], aggRole: 'dimension', domainShape: 'fixed', diverging: 'none', formatClass: 'decimal',    zeroBaseline: 'arbitrary', zeroPad: 0.02 },\n    Longitude:     { t0: 'Geographic', t1: 'GeoCoordinate', visEncodings: ['quantitative', 'geographic'], aggRole: 'dimension', domainShape: 'fixed', diverging: 'none', formatClass: 'decimal',    zeroBaseline: 'arbitrary', zeroPad: 0.02 },\n    Country:       { t0: 'Geographic', t1: 'GeoPlace', visEncodings: ['nominal'],         aggRole: 'dimension',  domainShape: 'open',    diverging: 'none',        formatClass: 'plain',      zeroBaseline: 'none', zeroPad: 0 },\n    State:         { t0: 'Geographic', t1: 'GeoPlace', visEncodings: ['nominal'],         aggRole: 'dimension',  domainShape: 'open',    diverging: 'none',        formatClass: 'plain',      zeroBaseline: 'none', zeroPad: 0 },\n    City:          { t0: 'Geographic', t1: 'GeoPlace', visEncodings: ['nominal'],         aggRole: 'dimension',  domainShape: 'open',    diverging: 'none',        formatClass: 'plain',      zeroBaseline: 'none', zeroPad: 0 },\n    Region:        { t0: 'Geographic', t1: 'GeoPlace', visEncodings: ['nominal'],         aggRole: 'dimension',  domainShape: 'open',    diverging: 'none',        formatClass: 'plain',      zeroBaseline: 'none', zeroPad: 0 },\n    Address:       { t0: 'Geographic', t1: 'GeoPlace', visEncodings: ['nominal'],         aggRole: 'dimension',  domainShape: 'open',    diverging: 'none',        formatClass: 'plain',      zeroBaseline: 'none', zeroPad: 0 },\n    ZipCode:       { t0: 'Geographic', t1: 'GeoPlace', visEncodings: ['nominal'],         aggRole: 'identifier', domainShape: 'open',    diverging: 'none',        formatClass: 'plain',      zeroBaseline: 'none', zeroPad: 0 },\n    // --- Categorical: Entity ---\n    Category:      { t0: 'Categorical', t1: 'Entity', visEncodings: ['nominal'],           aggRole: 'dimension',  domainShape: 'open',    diverging: 'none',        formatClass: 'plain',      zeroBaseline: 'none', zeroPad: 0 },\n    Name:          { t0: 'Categorical', t1: 'Entity', visEncodings: ['nominal'],           aggRole: 'dimension',  domainShape: 'open',    diverging: 'none',        formatClass: 'plain',      zeroBaseline: 'none', zeroPad: 0 },\n\n    // --- Categorical: Coded ---\n    Status:        { t0: 'Categorical', t1: 'Coded', visEncodings: ['nominal'],            aggRole: 'dimension',  domainShape: 'open',    diverging: 'none',        formatClass: 'plain',      zeroBaseline: 'none', zeroPad: 0 },\n    Boolean:       { t0: 'Categorical', t1: 'Coded', visEncodings: ['nominal'],            aggRole: 'dimension',  domainShape: 'fixed',   diverging: 'none',        formatClass: 'plain',      zeroBaseline: 'none', zeroPad: 0 },\n    Direction:     { t0: 'Categorical', t1: 'Coded', visEncodings: ['ordinal', 'nominal'], aggRole: 'dimension',  domainShape: 'cyclic',  diverging: 'none',        formatClass: 'plain',      zeroBaseline: 'none', zeroPad: 0 },\n\n    // --- Categorical: Binned ---\n    Range:         { t0: 'Categorical', t1: 'Binned', visEncodings: ['ordinal'],           aggRole: 'dimension',  domainShape: 'open',    diverging: 'none',        formatClass: 'plain',      zeroBaseline: 'none', zeroPad: 0 },\n\n    // --- Fallbacks ---\n    Unknown:       { t0: 'Categorical', t1: 'Entity', visEncodings: ['nominal'],           aggRole: 'dimension',  domainShape: 'open',    diverging: 'none',        formatClass: 'plain',      zeroBaseline: 'none', zeroPad: 0 },\n};\n\n/** Default entry for unrecognized types */\nconst UNKNOWN_ENTRY: TypeRegistryEntry = {\n    t0: 'Categorical', t1: 'Entity',\n    visEncodings: ['nominal'],\n    aggRole: 'dimension',\n    domainShape: 'open',\n    diverging: 'none',\n    formatClass: 'plain',\n    zeroBaseline: 'none',\n    zeroPad: 0,\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/** Look up a semantic type in the registry. Falls back to UNKNOWN_ENTRY. */\nexport function getRegistryEntry(semanticType: string): TypeRegistryEntry {\n    return TYPE_REGISTRY[semanticType] ?? UNKNOWN_ENTRY;\n}\n\n/** Check whether a semantic type string is explicitly registered. */\nexport function isRegistered(semanticType: string): boolean {\n    return semanticType in TYPE_REGISTRY;\n}\n\n/**\n * Get all registered type names.\n * Useful for validation or iterating over the type system.\n */\nexport function getRegisteredTypes(): string[] {\n    return Object.keys(TYPE_REGISTRY);\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { getRegistryEntry, getRegisteredTypes, isRegistered, type VisCategory } from './type-registry';\nexport type { VisCategory } from './type-registry';\n\n/**\n * =============================================================================\n * SEMANTIC TYPE SYSTEM\n * =============================================================================\n * \n * Semantic types classify data fields for intelligent chart recommendations.\n * Uses strings for flexibility and easy JSON serialization.\n * \n * DESIGN GOALS:\n * 1. Comprehensive: Cover common data types seen in real-world datasets\n * 2. Visualization-aware: Map to Vega-Lite encoding types (Q, O, N, T)\n * 3. Hierarchical: Support generalization via lattice structure\n * 4. Simple: Use strings with helper functions, no complex enums\n * \n * =============================================================================\n * SEMANTIC TYPE LATTICE\n * =============================================================================\n * \n *                           ┌─────────────┐\n *                           │   AnyType   │\n *                           └──────┬──────┘\n *            ┌────────────────────┼────────────────────┐\n *            ▼                    ▼                    ▼\n *     ┌──────────┐         ┌──────────┐         ┌───────-───┐\n *     │ Temporal │         │ Numeric  │         │Categorical│\n *     └────┬─────┘         └────┬─────┘         └─────┬────┘\n *          │                    │                     │\n *    ┌─────┴─────┐        ┌─────┴─────┐         ┌─────┴─────┐\n *    │           │        │           │         │           │\n *  DateTime     Granule    Measure   Discrete    Entity     Coded\n *    │           │        │           │         │           │\n * DateTime    Year     Quantity    Rank      Category   Status\n * Date        Month    Count       Score     Name       Boolean\n * Time        Day      Price       ID                   Direction\n *             Quarter  Percentage\n *             Decade   Amount\n *                      Temperature\n * \n * =============================================================================\n */\n\n// ---------------------------------------------------------------------------\n// All Semantic Types (as string constants)\n// ---------------------------------------------------------------------------\n\n/**\n * All recognized semantic types.\n * Use these constants when comparing or assigning types.\n */\nexport const SemanticTypes = {\n    // =========================================================================\n    // TEMPORAL TYPES - Time-related concepts\n    // =========================================================================\n    \n    // Point-in-time (full timestamp precision)\n    DateTime: 'DateTime',       // Full date and time: \"2024-01-15T14:30:00\"\n    Date: 'Date',               // Date only: \"2024-01-15\"\n    Time: 'Time',               // Time only: \"14:30:00\"\n    Timestamp: 'Timestamp',     // Unix timestamp (seconds or milliseconds since epoch)\n    \n    // Temporal granules (discrete time units, inherently ordered)\n    Year: 'Year',               // \"2024\" (as a time unit, not a measure)\n    Quarter: 'Quarter',         // \"Q1\", \"Q2\", \"2024-Q1\"\n    Month: 'Month',             // \"January\", \"Jan\", 1-12\n    Week: 'Week',               // \"Week 1\", 1-52\n    Day: 'Day',                 // \"Monday\", \"Mon\", 1-31\n    Hour: 'Hour',               // 0-23\n    \n    // Combined temporal\n    YearMonth: 'YearMonth',     // \"2024-01\", \"Jan 2024\"\n    YearQuarter: 'YearQuarter', // \"2024-Q1\"\n    YearWeek: 'YearWeek',       // \"2024-W01\"\n    Decade: 'Decade',           // \"1990s\", \"2000s\"\n    \n    // Temporal duration/span\n    Duration: 'Duration',       // Time span: \"2 hours\", \"3 days\", milliseconds\n    \n    // =========================================================================\n    // NUMERIC MEASURE TYPES - Continuous values for aggregation\n    // =========================================================================\n    \n    Quantity: 'Quantity',       // Generic continuous measure\n    Count: 'Count',             // Discrete count of items\n    Amount: 'Amount',           // Monetary or general amounts\n    Price: 'Price',             // Unit price\n    Percentage: 'Percentage',   // 0-100% or 0-1 ratio\n    Temperature: 'Temperature', // Degrees\n    \n    // Signed measures (can be positive or negative, zero has meaning)\n    Profit: 'Profit',             // Gain/loss, profit/deficit\n    PercentageChange: 'PercentageChange', // Growth rate, change %\n    Sentiment: 'Sentiment',       // Positive/negative sentiment score\n    Correlation: 'Correlation',   // Positive/negative correlation coefficient\n    \n    // =========================================================================\n    // NUMERIC DISCRETE TYPES - Numbers with ordinal/identifier meaning\n    // =========================================================================\n    \n    Rank: 'Rank',               // Position in ordered list: 1st, 2nd, 3rd\n    ID: 'ID',                   // Unique identifier (not for aggregation!)\n    Score: 'Score',             // Rating score: 1-5, 1-10, 0-100\n    \n    // =========================================================================\n    // GEOGRAPHIC TYPES - Location-based data\n    // =========================================================================\n    \n    Latitude: 'Latitude',       // -90 to 90\n    Longitude: 'Longitude',     // -180 to 180\n    Country: 'Country',         // Country name or code\n    State: 'State',             // State/Province\n    City: 'City',               // City name\n    Region: 'Region',           // Geographic region\n    Address: 'Address',         // Street address (geo lookup)\n    ZipCode: 'ZipCode',         // Postal code (geo lookup)\n    \n    // =========================================================================\n    // CATEGORICAL ENTITY TYPES - Named entities\n    // =========================================================================\n    \n    Category: 'Category',       // Discrete category / product / entity class\n    Name: 'Name',               // Generic named entity (person, company, product, etc.)\n    \n    // =========================================================================\n    // CATEGORICAL CODED TYPES - Discrete categories/statuses\n    // =========================================================================\n    \n    Status: 'Status',           // State: \"Active\", \"Pending\", \"Closed\"\n    Boolean: 'Boolean',         // True/False, Yes/No\n    Direction: 'Direction',     // Compass direction: \"N\", \"NE\", \"East\", etc.\n    \n    // =========================================================================\n    // BINNED/RANGE TYPES - Discretized continuous values\n    // =========================================================================\n    \n    Range: 'Range',             // Numeric range, age group, binned values\n    \n    // =========================================================================\n    // FALLBACK TYPES\n    // =========================================================================\n    \n    Number: 'Number',           // Generic number (measure fallback)\n    Unknown: 'Unknown',         // Cannot determine type\n} as const;\n\n// Type for any semantic type string\nexport type SemanticType = typeof SemanticTypes[keyof typeof SemanticTypes];\n\n// ---------------------------------------------------------------------------\n// Visualization Categories  →  defined in type-registry.ts (single source of truth)\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Type Sets for Classification — derived from type-registry.ts\n// ---------------------------------------------------------------------------\n\n// timeseriesXTypes: REMOVED — derived from type-registry.ts via isTimeSeriesType()\n\n/**\n * Types suitable for quantitative encoding (true continuous measures).\n *\n * Derived from the registry: aggRole ∈ {additive, intensive, signed-additive},\n * excluding Score/Rating (t1='Score') which behave as bounded ordinal scales\n * for vis purposes (e.g., 1–5 star rating). This is an intentional vis-level\n * distinction, not a mathematical one.\n */\nexport const measureTypes = new Set<string>(\n    getRegisteredTypes().filter(t => {\n        const e = getRegistryEntry(t);\n        return ['additive', 'intensive', 'signed-additive'].includes(e.aggRole) && e.t1 !== 'Score';\n    })\n);\n\n/** Numeric types that should NOT be used as measures (don't aggregate) */\nexport const nonMeasureNumericTypes = new Set<string>([\n    'Rank', 'ID', 'Score',\n    'Year', 'Month', 'Day', 'Hour',\n    'Latitude', 'Longitude',\n]);\n\n/**\n * Types suitable for categorical color/grouping encoding.\n *\n * Derived from the registry: types that include 'nominal' in visEncodings\n * (at any position — Direction has ['ordinal','nominal']),\n * plus binned types (Range, AgeGroup) which also work as categorical for\n * color/grouping despite having 'ordinal' as their primary encoding.\n * Excludes identifiers (ID) which are nominal but not useful for grouping.\n */\nexport const categoricalTypes = new Set<string>(\n    getRegisteredTypes().filter(t => {\n        const e = getRegistryEntry(t);\n        return (e.visEncodings.includes('nominal') && e.aggRole !== 'identifier') || e.t1 === 'Binned';\n    })\n);\n\n/**\n * Types suitable for ordinal encoding (have inherent order).\n *\n * Derived from the registry: types whose visEncodings include 'ordinal'.\n */\nexport const ordinalTypes = new Set<string>(\n    getRegisteredTypes().filter(t => {\n        const e = getRegistryEntry(t);\n        return e.visEncodings.includes('ordinal');\n    })\n);\n\n// geoTypes, geoCoordinateTypes, geoLocationTypes: REMOVED — derived from type-registry.ts\n// via isGeoType(), isGeoCoordinateType(), isGeoLocationString()\n\n// ---------------------------------------------------------------------------\n// Type Hierarchy — REMOVED\n// ---------------------------------------------------------------------------\n// The typeHierarchy map and its helper functions (getParentType,\n// getAncestorTypes, isSubtypeOf) have been removed. They were unused\n// externally — no consumer ever imported them.\n//\n// The registry's t0/t1 dimensions capture family grouping (e.g., all\n// Amount types share t1='Amount'). If fine-grained parent-child lattice\n// traversal is ever needed in the future, it can be rebuilt from\n// type-registry.ts with an explicit `parent` field per entry.\n// ---------------------------------------------------------------------------\n\n// visCategoryMap: REMOVED — derived from type-registry.ts via getRegistryEntry().visEncodings[0]\n\n// ---------------------------------------------------------------------------\n// Helper Functions\n// ---------------------------------------------------------------------------\n\n/**\n * Get the Vega-Lite visualization category for a semantic type.\n * Derived from the registry's visEncodings[0] (primary encoding).\n * Returns null for unrecognised types so callers can fall back\n * to data-driven inference.\n */\nexport function getVisCategory(semanticType: string): VisCategory | null {\n    // Return null for empty, 'Unknown', or any unregistered type string\n    // so callers fall back to data-driven inference (inferVisCategory).\n    if (!semanticType || !isRegistered(semanticType)) return null;\n    return getRegistryEntry(semanticType).visEncodings[0] ?? null;\n}\n\n\n/**\n * Infer a VisCategory from raw data values when no semantic type is available.\n * Mirrors the DataType → VL encoding type mapping:\n *   number/integer → quantitative, boolean → nominal, date → temporal, string → nominal.\n */\nexport function inferVisCategory(values: any[]): VisCategory {\n    if (values.length === 0) return 'nominal';\n    const isBoolean = (v: any) => v === true || v === false || Object.prototype.toString.call(v) === '[object Boolean]';\n    const isNumber = (v: any) => !isNaN(+v) && !(Object.prototype.toString.call(v) === '[object Date]');\n    // Date.parse is too permissive in V8 — \"FY 2018\", \"hello world 2018\" all parse.\n    // Require the string to start with a digit or a known month-name prefix.\n    const looksLikeDate = (s: string) => /^\\d|^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i.test(s.trim());\n    const isDate = (v: any) => {\n        if (v instanceof Date) return !isNaN(v.getTime());\n        if (typeof v === 'string') return looksLikeDate(v) && !isNaN(Date.parse(v));\n        return !isNaN(Date.parse(v));\n    };\n    const nonNull = values.filter(v => v != null);\n    if (nonNull.length === 0) return 'nominal';\n    if (nonNull.every(isBoolean)) return 'nominal';\n    if (nonNull.every(isNumber)) return 'quantitative';\n    if (nonNull.every(isDate)) return 'temporal';\n    return 'nominal';\n}\n\n/**\n * Check if a semantic type is a true measure (suitable for quantitative encoding).\n */\nexport function isMeasureType(semanticType: string): boolean {\n    return measureTypes.has(semanticType);\n}\n\n/**\n * Check if a semantic type is suitable for time-series X axis.\n * Derived from type-registry: t0 === 'Temporal' but not Duration.\n */\nexport function isTimeSeriesType(semanticType: string): boolean {\n    const entry = getRegistryEntry(semanticType);\n    return entry.t0 === 'Temporal' && entry.t1 !== 'Duration';\n}\n\n/**\n * Check if a semantic type is categorical (suitable for color/grouping).\n */\nexport function isCategoricalType(semanticType: string): boolean {\n    return categoricalTypes.has(semanticType);\n}\n\n/**\n * Check if a semantic type is ordinal (has inherent order).\n */\nexport function isOrdinalType(semanticType: string): boolean {\n    return ordinalTypes.has(semanticType);\n}\n\n/**\n * Check if a semantic type is geographic.\n * Derived from type-registry: t0 === 'Geographic'.\n */\nexport function isGeoType(semanticType: string): boolean {\n    return getRegistryEntry(semanticType).t0 === 'Geographic';\n}\n\n/**\n * Check if a semantic type is a geographic coordinate (lat/lon).\n * Derived from type-registry: t1 === 'GeoCoordinate'.\n */\nexport function isGeoCoordinateType(semanticType: string): boolean {\n    return getRegistryEntry(semanticType).t1 === 'GeoCoordinate';\n}\n\n/**\n * Check if a semantic type is a named geographic location.\n * Derived from type-registry: t1 === 'GeoPlace'.\n */\nexport function isGeoLocationString(semanticType: string): boolean {\n    return getRegistryEntry(semanticType).t1 === 'GeoPlace';\n}\n\n/**\n * Check if a semantic type is numeric but should not be aggregated.\n */\nexport function isNonMeasureNumeric(semanticType: string): boolean {\n    return nonMeasureNumericTypes.has(semanticType);\n}\n\n// ---------------------------------------------------------------------------\n// Zero-Baseline Classification  →  data lives in type-registry.ts (zeroBaseline, zeroPad)\n// ---------------------------------------------------------------------------\n\n/**\n * Classification of whether zero is a meaningful baseline for a semantic type.\n *\n * - `meaningful`: 0 has a real-world interpretation (absence of the measured thing).\n *   Comparisons to zero and ratios between values are meaningful.\n *   Examples: Count, Revenue, Distance, Weight.\n *\n * - `arbitrary`: 0 is either meaningless, doesn't exist, or is an arbitrary\n *   reference point. The data's range is what matters.\n *   Examples: Temperature (0°F is arbitrary), Year (year 0 doesn't exist),\n *   Rank (0th place doesn't exist).\n *\n * - `contextual`: 0 is meaningful but data-fitting may be better when data\n *   is concentrated far from zero and the mark is not bar/area.\n *   Examples: Percentage (0–100% natural, but 48–52% benefits from zoom),\n *   Score (1–5 scale, but 4.2–4.8 benefits from zoom).\n */\nexport type ZeroClass = 'meaningful' | 'arbitrary' | 'contextual';\n\n/**\n * Result of the zero-baseline decision.\n * Encapsulates both the boolean decision and domain padding for non-zero axes.\n */\nexport interface ZeroDecision {\n    /** Whether the axis should include zero */\n    zero: boolean;\n    /**\n     * For non-zero axes: fraction of data range to pad on each side\n     * so edge values aren't crushed against the axis boundary.\n     * e.g. 0.05 = 5% padding on each side.\n     */\n    domainPadFraction: number;\n    /** The zero class that drove this decision */\n    zeroClass: ZeroClass | 'unknown';\n    /**\n     * Whether this is a *forced* (non-debatable) decision:\n     *   - `true`  → mandatory: a length/area mark, data that crosses zero, or a\n     *     zero-meaningful type on a length mark. Including zero is structural.\n     *   - `false` → the engine still has a recommended `zero`, but anchoring at\n     *     zero is at least conceptually a choice.\n     * `forced` records the structural side of the decision; it is NOT the gate\n     * for the UI toggle — see `uncertain` below.\n     */\n    forced: boolean;\n    /**\n     * Whether the zero-vs-fit choice is a *genuine toss-up worth surfacing* to\n     * the user. Hosts read this (via the property `check`) to decide whether to\n     * show the \"Zero X/Y\" toggle at all.\n     *\n     * We deliberately keep this narrow to avoid UI clutter: it is `true` ONLY\n     * for a zero-meaningful field on a position mark whose data sits far enough\n     * from zero that anchoring at zero would noticeably compress the view (a\n     * real zoom-in-vs-anchor tradeoff). Every other case — arbitrary types\n     * (zero is meaningless, just fit the data), contextual types (the engine's\n     * data-range call is confident enough), meaningful types whose data already\n     * spans most of the way to zero (the choice barely changes anything), and\n     * all forced/unknown cases — is `false`, so no toggle is shown and the\n     * engine's `zero` value simply applies. The engine's `zero` remains the\n     * recommended default when the toggle is shown.\n     */\n    uncertain: boolean;\n}\n\n// zeroMeaningfulTypes, zeroArbitraryTypes, zeroContextualTypes, zeroPadMap:\n// REMOVED — now stored as zeroBaseline/zeroPad in type-registry.ts\n\n/**\n * Classify a semantic type's relationship to zero.\n * Derived from the registry's zeroBaseline dimension.\n */\nexport function getZeroClass(semanticType: string): ZeroClass | 'unknown' {\n    const baseline = getRegistryEntry(semanticType).zeroBaseline;\n    if (baseline === 'none') return 'unknown';\n    return baseline;\n}\n\n/**\n * Compute whether a quantitative axis should start at zero, based on\n * semantic type, mark type, channel, and data values.\n *\n * Priority: semantic type > mark type > data range > VL default.\n *\n * This is a pure decision function — it returns a ZeroDecision object\n * without modifying any spec. The caller applies the decision to VL.\n *\n * @param semanticType  The semantic type of the field (e.g. 'Amount', 'Temperature')\n * @param channel       The VL channel ('x', 'y', 'size', etc.)\n * @param markType      The mark type ('bar', 'line', 'point', etc.)\n * @param values        Optional numeric data values for data-range analysis\n */\n/**\n * Above this ratio of dataMin/dataMax, the data band sits far enough above\n * zero that anchoring the axis at zero would leave at least half the axis\n * empty — a big enough gap that \"zoom into the data\" vs \"keep the zero\n * reference\" is a genuine toss-up worth offering as a toggle. Below it, the\n * data already spans most of the way to zero, so including zero barely changes\n * the view and we keep it on silently.\n */\nconst ZERO_BASELINE_GAP_THRESHOLD = 0.5;\n\n/**\n * True when strictly-positive data sits far enough from zero that anchoring at\n * zero would noticeably compress the view (see ZERO_BASELINE_GAP_THRESHOLD).\n * Returns false for empty data or any data that touches/crosses zero (there the\n * baseline is inside the data range, so it is not a debatable gap).\n */\nfunction dataFarFromZero(values?: number[]): boolean {\n    if (!values || values.length === 0) return false;\n    const dataMin = Math.min(...values);\n    const dataMax = Math.max(...values);\n    if (dataMin <= 0 || dataMax <= 0) return false;\n    return dataMin / dataMax >= ZERO_BASELINE_GAP_THRESHOLD;\n}\n\nexport function computeZeroDecision(\n    semanticType: string,\n    channel: string,\n    markType: string,\n    values?: number[],\n): ZeroDecision {\n    const isBarLike = ['bar', 'area', 'rect'].includes(markType);\n    const isScatterMark = markType === 'circle' || markType === 'point';\n    const isPositional = ['x', 'y'].includes(channel);\n    const entry = getRegistryEntry(semanticType);\n    const zeroClass = getZeroClass(semanticType);\n\n    // --- Zero-meaningful types: zero is the conventional baseline ---\n    if (zeroClass === 'meaningful') {\n        // Length marks (bar/area/rect): the baseline is structurally required —\n        // a bar's length is meaningless without zero. Not debatable.\n        if (isBarLike) {\n            return { zero: true, domainPadFraction: 0, zeroClass, forced: true, uncertain: false };\n        }\n        // Scatter (circle/point position): the read is correlation / cloud shape,\n        // not distance from zero — data-fit is the conventional default. Offer\n        // Zero X/Y as an opt-in toggle when the user wants a zero reference.\n        if (isPositional && isScatterMark) {\n            if (values && values.length > 0 && Math.min(...values) <= 0) {\n                return { zero: true, domainPadFraction: 0, zeroClass, forced: true, uncertain: false };\n            }\n            return {\n                zero: false,\n                domainPadFraction: entry.zeroPad || 0.05,\n                zeroClass,\n                forced: false,\n                uncertain: true,\n            };\n        }\n        // Position marks (line/strip): zero is the conventional reference,\n        // so the recommended default is ON. We only *offer* the toggle when the\n        // data sits far enough from zero that anchoring at zero would noticeably\n        // compress the view — a genuine zoom-in-vs-keep-the-reference toss-up.\n        // When the data already spans most of the way to zero, the choice barely\n        // changes anything, so we keep zero on silently and hide the toggle.\n        return {\n            zero: true,\n            domainPadFraction: 0,\n            zeroClass,\n            forced: false,\n            uncertain: dataFarFromZero(values),\n        };\n    }\n\n    // --- Zero-arbitrary types: never zero, apply padding ---\n    if (zeroClass === 'arbitrary') {\n        // Exception: bar/area marks with data that touches/crosses zero —\n        // the baseline is structurally required, so this is forced.\n        if (isBarLike && values && values.length > 0) {\n            const dataMin = Math.min(...values);\n            if (dataMin <= 0) {\n                return { zero: true, domainPadFraction: 0, zeroClass, forced: true, uncertain: false };\n            }\n        }\n        // Strictly away from zero on an arbitrary scale: zero is meaningless\n        // here, so data-fit is simply the right answer — there is nothing to\n        // debate and no toggle is offered.\n        return {\n            zero: false,\n            domainPadFraction: entry.zeroPad || 0.05,\n            zeroClass,\n            forced: false,\n            uncertain: false,\n        };\n    }\n\n    // --- Contextual types: use data range + mark to decide ---\n    if (zeroClass === 'contextual' && values && values.length > 0) {\n        const dataMin = Math.min(...values);\n        const dataMax = Math.max(...values);\n\n        // Data touches/crosses zero → include it (forced: the baseline is\n        // inside the data range).\n        if (dataMin <= 0) {\n            return { zero: true, domainPadFraction: 0, zeroClass, forced: true, uncertain: false };\n        }\n\n        // How far is data from zero?\n        const proximity = dataMax > 0 ? dataMin / dataMax : 0;\n\n        // Close to zero → include it. The engine's data-range call is confident\n        // enough here, so no toggle is offered.\n        if (proximity < 0.3) {\n            return { zero: true, domainPadFraction: 0, zeroClass, forced: false, uncertain: false };\n        }\n\n        // Far from zero + bar/area → still include (bar length integrity, forced).\n        if (isBarLike) {\n            return { zero: true, domainPadFraction: 0, zeroClass, forced: true, uncertain: false };\n        }\n\n        // Far from zero + non-bar → data-fit with padding (engine's call, no toggle).\n        return { zero: false, domainPadFraction: 0.05, zeroClass, forced: false, uncertain: false };\n    }\n\n    // --- No semantic type or unrecognized → no opinion, let VL decide ---\n    // Unknown class is never debatable: we have no basis for a toggle.\n    if (isBarLike && isPositional) {\n        return { zero: true, domainPadFraction: 0, zeroClass: 'unknown', forced: true, uncertain: false };\n    }\n    return { zero: false, domainPadFraction: 0.05, zeroClass: 'unknown', forced: true, uncertain: false };\n}\n\n/**\n * Compute padded domain bounds for a non-zero axis.\n * Pure computation — returns [paddedMin, paddedMax] without modifying any spec.\n *\n * @param values         Numeric data values\n * @param padFraction    Fraction of data range to pad on each side\n * @returns              [paddedMin, paddedMax] or null if padding is not applicable\n */\nexport function computePaddedDomain(\n    values: number[],\n    padFraction: number,\n): [number, number] | null {\n    if (padFraction <= 0 || values.length < 2) return null;\n\n    const dataMin = Math.min(...values);\n    const dataMax = Math.max(...values);\n    const span = dataMax - dataMin;\n    if (span <= 0) return null;\n\n    const padding = span * padFraction;\n    return [dataMin - padding, dataMax + padding];\n}\n\n// ---------------------------------------------------------------------------\n// Color Scheme Recommendations\n// ---------------------------------------------------------------------------\n\nexport type ColorSchemeType = 'categorical' | 'sequential' | 'diverging';\n\nexport interface ColorSchemeRecommendation {\n    scheme: string;\n    type: ColorSchemeType;\n    reason: string;\n    /** For diverging schemes, the recommended midpoint value */\n    domainMid?: number;\n}\n\n// getDivergingMidpoint: REMOVED — superseded by resolveDivergingInfo() in field-semantics.ts\n// which uses a priority chain (unit → type-intrinsic → domain → data) and\n// distinguishes inherent vs conditional diverging.\n\n/**\n * Vega-Lite color schemes organized by use case\n * See: https://vega.github.io/vega/docs/schemes/\n */\nconst colorSchemes = {\n    // Categorical (nominal) - good for distinct categories\n    categorical: {\n        default: 'category10',\n        large: 'category20',\n        pastel: 'pastel1',\n        accent: 'accent',\n        paired: 'paired',      // Good for paired comparisons\n        set1: 'set1',          // Distinct, saturated\n        set2: 'set2',          // Pastel\n        set3: 'set3',          // Larger set\n        tableau10: 'tableau10',\n        tableau20: 'tableau20',\n    },\n    // Sequential - good for ordered/quantitative data\n    sequential: {\n        blues: 'blues',\n        greens: 'greens',\n        oranges: 'oranges',\n        reds: 'reds',\n        purples: 'purples',\n        greys: 'greys',\n        // Multi-hue sequential\n        viridis: 'viridis',\n        inferno: 'inferno',\n        magma: 'magma',\n        plasma: 'plasma',\n        turbo: 'turbo',\n        // Domain-specific\n        yellowGreen: 'yellowgreen',\n        yellowOrangeBrown: 'yelloworangebrown',\n        goldGreen: 'goldgreen',\n        goldOrange: 'goldorange',\n        goldRed: 'goldred',\n    },\n    // Diverging - good for data with meaningful center point\n    diverging: {\n        redBlue: 'redblue',\n        redGrey: 'redgrey',\n        redYellowBlue: 'redyellowblue',\n        redYellowGreen: 'redyellowgreen',\n        pinkYellowGreen: 'pinkyellowgreen',\n        purpleGreen: 'purplegreen',\n        purpleOrange: 'purpleorange',\n        brownBlueGreen: 'brownbluegreen',\n    },\n};\n\n/**\n * Get recommended color scheme based on semantic type and encoding context.\n * \n * @param semanticType - The semantic type of the field\n * @param encodingType - The Vega-Lite encoding type ('nominal', 'ordinal', 'quantitative')\n * @param uniqueValueCount - Number of unique values (for categorical sizing)\n * @param fieldName - Field name (for consistent hashing)\n * @param values - Optional actual data values (for inspecting data range)\n * @param colorHint - Optional classification from resolveColorSchemeHint().\n *        When provided, the hint's type ('diverging'|'sequential'|'categorical')\n *        overrides inline detection, avoiding duplicate diverging logic.\n */\nexport function getRecommendedColorScheme(\n    semanticType: string | undefined,\n    encodingType: 'nominal' | 'ordinal' | 'quantitative' | 'temporal',\n    uniqueValueCount: number = 10,\n    fieldName: string = '',\n    values: any[] = [],\n    colorHint?: { type: 'categorical' | 'sequential' | 'diverging' },\n): ColorSchemeRecommendation {\n    \n    // Helper for consistent scheme selection from array\n    const pickScheme = (schemes: string[], name: string): string => {\n        let hash = 0;\n        for (let i = 0; i < name.length; i++) {\n            hash = ((hash << 5) - hash) + name.charCodeAt(i);\n            hash = hash & hash;\n        }\n        return schemes[Math.abs(hash) % schemes.length];\n    };\n\n    // If no semantic type, use defaults based on encoding type\n    if (!semanticType) {\n        if (encodingType === 'quantitative') {\n            return { scheme: 'viridis', type: 'sequential', reason: 'default for quantitative' };\n        }\n        if (encodingType === 'ordinal') {\n            return { scheme: 'blues', type: 'sequential', reason: 'default for ordinal' };\n        }\n        // nominal/temporal default to categorical — use saturated schemes for readability\n        return { \n            scheme: uniqueValueCount > 10 ? 'tableau20' : 'tableau10', \n            type: 'categorical', \n            reason: 'default for categorical' \n        };\n    }\n\n    // --- Diverging-capable types ---\n    // When a colorHint is provided (from resolveColorSchemeHint), it drives the\n    // diverging/sequential decision. Without a hint, fall back to sequential.\n    // This avoids duplicating the diverging detection logic from field-semantics.ts.\n\n    // Temperature\n    if (semanticType === 'Temperature') {\n        if (colorHint?.type === 'diverging') {\n            return { scheme: 'redblue', type: 'diverging', reason: 'temperature diverging around freezing point' };\n        }\n        return { scheme: 'reds', type: 'sequential', reason: 'temperature single-direction uses sequential' };\n    }\n\n    // Percentage\n    if (semanticType === 'Percentage') {\n        if (colorHint?.type === 'diverging') {\n            return { scheme: 'redblue', type: 'diverging', reason: 'percentage spans positive and negative' };\n        }\n        return { scheme: 'oranges', type: 'sequential', reason: 'percentage all same sign uses sequential' };\n    }\n\n    // Price/Amount\n    if (['Price', 'Amount'].includes(semanticType)) {\n        if (colorHint?.type === 'diverging') {\n            return { scheme: 'redblue', type: 'diverging', reason: 'financial data spans positive and negative' };\n        }\n        return { scheme: 'goldgreen', type: 'sequential', reason: 'financial data uses gold-green' };\n    }\n\n    // Score - evaluation metrics; diverging when hint says so (e.g., domain midpoint)\n    if (semanticType === 'Score') {\n        if (colorHint?.type === 'diverging') {\n            return { scheme: 'redblue', type: 'diverging', reason: 'score/rating diverging around midpoint' };\n        }\n        return { scheme: 'yelloworangebrown', type: 'sequential', reason: 'scores use warm sequential' };\n    }\n\n    // Rank - use single-hue sequential\n    if (semanticType === 'Rank') {\n        return { scheme: 'purples', type: 'sequential', reason: 'ranks use single-hue sequential' };\n    }\n\n    // Ranges - use sequential\n    if (semanticType === 'Range') {\n        return { scheme: 'blues', type: 'sequential', reason: 'range groups use sequential' };\n    }\n\n    // Temporal granules (Year, Month, Quarter, etc.) - sequential for continuity\n    if (ordinalTypes.has(semanticType) && ['Year', 'Quarter', 'Month', 'Week', 'Day', 'Hour', 'Decade'].includes(semanticType)) {\n        return { scheme: 'viridis', type: 'sequential', reason: 'temporal granules use perceptually uniform' };\n    }\n\n    // Geographic locations - use geographic-friendly palettes\n    if (getRegistryEntry(semanticType ?? '').t1 === 'GeoPlace') {\n        if (uniqueValueCount <= 10) {\n            return { scheme: 'set2', type: 'categorical', reason: 'geographic regions use distinct pastels' };\n        }\n        return { scheme: 'tableau20', type: 'categorical', reason: 'many regions use large categorical' };\n    }\n\n    // Status/Boolean - use accent colors for clear distinction\n    if (['Status', 'Boolean'].includes(semanticType)) {\n        return { scheme: 'set1', type: 'categorical', reason: 'status uses high-contrast categorical' };\n    }\n\n    // Categories - use standard categorical\n    if (semanticType === 'Category') {\n        return { \n            scheme: uniqueValueCount > 10 ? 'tableau20' : 'tableau10', \n            type: 'categorical', \n            reason: 'categories use standard categorical' \n        };\n    }\n\n    // Names (persons, companies, products) - use saturated schemes for readability\n    if (semanticType === 'Name') {\n        return { \n            scheme: uniqueValueCount > 8 ? 'tableau20' : 'set2', \n            type: 'categorical', \n            reason: 'names use readable categorical' \n        };\n    }\n\n    // Duration - use sequential (longer = more intense)\n    if (semanticType === 'Duration') {\n        return { scheme: 'oranges', type: 'sequential', reason: 'duration uses intensity-based sequential' };\n    }\n\n    // Quantity/Count/Distance/etc. - general measures\n    // Check colorHint first — signed measures (Profit, Sentiment, Correlation,\n    // PercentageChange) pass through here and should honor their diverging hint.\n    if (measureTypes.has(semanticType)) {\n        if (colorHint?.type === 'diverging') {\n            return { scheme: 'redblue', type: 'diverging', reason: 'measure with diverging nature' };\n        }\n        const sequentialSchemes = ['viridis', 'blues', 'greens', 'reds', 'yelloworangebrown', 'goldgreen'];\n        return { \n            scheme: pickScheme(sequentialSchemes, fieldName), \n            type: 'sequential', \n            reason: 'measures use perceptually uniform sequential' \n        };\n    }\n\n    // Ordinal types not already handled\n    if (ordinalTypes.has(semanticType) || encodingType === 'ordinal') {\n        const ordinalSchemes = ['blues', 'greens', 'purples', 'oranges'];\n        return { \n            scheme: pickScheme(ordinalSchemes, fieldName), \n            type: 'sequential', \n            reason: 'ordinal data uses sequential scheme' \n        };\n    }\n\n    // Default categorical for nominal\n    if (encodingType === 'nominal' || encodingType === 'temporal') {\n        return { \n            scheme: uniqueValueCount > 10 ? 'tableau20' : 'tableau10', \n            type: 'categorical', \n            reason: 'default categorical palette' \n        };\n    }\n\n    // Fallback\n    return { scheme: 'viridis', type: 'sequential', reason: 'universal fallback' };\n}\n\n// getRecommendedColorSchemeWithMidpoint: REMOVED — diverging midpoint is now\n// resolved via resolveDivergingInfo() in field-semantics.ts and applied directly\n// by the caller in resolve-semantics.ts. See resolveChannelSemantics().\n\n// ===========================================================================\n// Canonical Ordinal Sort Orders\n// ===========================================================================\n\n/**\n * Well-known canonical ordinal sequences.\n *\n * Used to detect when data values belong to a known ordinal domain\n * (months, days of the week, quarters, etc.) and sort them in their\n * natural order instead of alphabetically or by a quantitative axis.\n */\n\n/** Full and abbreviated English month names (case-insensitive lookup). */\nconst MONTH_FULL = ['January','February','March','April','May','June','July','August','September','October','November','December'];\nconst MONTH_ABBR3 = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];\nconst MONTH_NUM = ['1','2','3','4','5','6','7','8','9','10','11','12'];\n\n/** Full and abbreviated English day-of-week names. */\nconst DOW_FULL = ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'];\nconst DOW_ABBR3 = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'];\nconst DOW_ABBR2 = ['Mo','Tu','We','Th','Fr','Sa','Su'];\n\n/** Sunday-first variant (US convention). */\nconst DOW_FULL_SUN = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];\nconst DOW_ABBR3_SUN = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];\n\n/** Quarter labels. */\nconst QUARTER_LABELS = ['Q1','Q2','Q3','Q4'];\n\n/** Compass directions — clockwise from North (top of chart). */\nconst COMPASS_8 = ['N','NE','E','SE','S','SW','W','NW'];\nconst COMPASS_8_FULL = ['North','Northeast','East','Southeast','South','Southwest','West','Northwest'];\nconst COMPASS_4 = ['N','E','S','W'];\nconst COMPASS_4_FULL = ['North','East','South','West'];\n\ninterface OrdinalSequence {\n    /** Canonical labels in order */\n    labels: string[];\n    /** Case-insensitive matching */\n    caseInsensitive: boolean;\n}\n\n/** All known ordinal sequences, keyed by semantic type. */\nconst ORDINAL_SEQUENCES: Record<string, OrdinalSequence[]> = {\n    Month: [\n        { labels: MONTH_FULL, caseInsensitive: true },\n        { labels: MONTH_ABBR3, caseInsensitive: true },\n        { labels: MONTH_NUM, caseInsensitive: false },\n    ],\n    Day: [\n        { labels: DOW_FULL, caseInsensitive: true },\n        { labels: DOW_ABBR3, caseInsensitive: true },\n        { labels: DOW_ABBR2, caseInsensitive: true },\n        { labels: DOW_FULL_SUN, caseInsensitive: true },\n        { labels: DOW_ABBR3_SUN, caseInsensitive: true },\n    ],\n    Quarter: [\n        { labels: QUARTER_LABELS, caseInsensitive: true },\n    ],\n    Direction: [\n        { labels: COMPASS_8, caseInsensitive: true },\n        { labels: COMPASS_8_FULL, caseInsensitive: true },\n        { labels: COMPASS_4, caseInsensitive: true },\n        { labels: COMPASS_4_FULL, caseInsensitive: true },\n    ],\n};\n\n/**\n * Build a case-insensitive lookup map from a sequence's labels.\n * Returns map: lowercased label → index.\n */\nfunction buildLookup(seq: OrdinalSequence): Map<string, number> {\n    const m = new Map<string, number>();\n    for (let i = 0; i < seq.labels.length; i++) {\n        const key = seq.caseInsensitive ? seq.labels[i].toLowerCase() : seq.labels[i];\n        m.set(key, i);\n    }\n    return m;\n}\n\n/**\n * Try to match a set of data values against a well-known ordinal sequence.\n *\n * Returns the canonical sort order (subset of the sequence, in order) if\n * enough values match, or `undefined` if no match.\n *\n * Matching rules:\n * - At least 60% of unique data values must be found in the sequence\n * - All matched values are returned in canonical order\n * - Unmatched values are appended at the end (preserving data order)\n *\n * @param values     The data values (strings or numbers) on this channel\n * @param sequences  The candidate sequences for the semantic type\n */\nfunction matchSequence(values: any[], sequences: OrdinalSequence[]): string[] | undefined {\n    const uniqueValues = [...new Set(values.map(v => v != null ? String(v) : ''))].filter(v => v !== '');\n    if (uniqueValues.length === 0) return undefined;\n\n    for (const seq of sequences) {\n        const lookup = buildLookup(seq);\n        const matched: { value: string; index: number }[] = [];\n        const unmatched: string[] = [];\n\n        for (const val of uniqueValues) {\n            const key = seq.caseInsensitive ? val.toLowerCase() : val;\n            const idx = lookup.get(key);\n            if (idx !== undefined) {\n                matched.push({ value: val, index: idx });\n            } else {\n                unmatched.push(val);\n            }\n        }\n\n        // Require at least 60% match rate\n        if (matched.length >= uniqueValues.length * 0.6 && matched.length >= 2) {\n            // Sort matched values by canonical index\n            matched.sort((a, b) => a.index - b.index);\n            const result = matched.map(m => m.value);\n            // Append unmatched at the end\n            result.push(...unmatched);\n            return result;\n        }\n    }\n    return undefined;\n}\n\n/**\n * Infer a canonical ordinal sort order for a field based on its semantic type\n * and data values.\n *\n * Works for:\n * - Month names (full/abbreviated/numeric): Jan, Feb, ... or January, February, ...\n * - Day-of-week names (full/abbreviated): Mon, Tue, ... or Monday, Tuesday, ...\n * - Quarter labels: Q1, Q2, Q3, Q4\n *\n * Falls back to `undefined` if no known sequence is detected, letting the\n * caller use its own default sort logic.\n *\n * @param semanticType  The semantic type of the field (e.g. 'Month', 'Day')\n * @param values        The data values on this channel\n * @returns Sorted unique values in canonical order, or undefined\n */\nexport function inferOrdinalSortOrder(\n    semanticType: string,\n    values: any[],\n): string[] | undefined {\n    // 1. Check by explicit semantic type\n    const sequences = ORDINAL_SEQUENCES[semanticType];\n    if (sequences) {\n        return matchSequence(values, sequences);\n    }\n\n    // 2. Auto-detect: try all sequences if semantic type is generic\n    if (!semanticType || semanticType === 'Category' || semanticType === 'Unknown') {\n        for (const seqs of Object.values(ORDINAL_SEQUENCES)) {\n            const result = matchSequence(values, seqs);\n            if (result) return result;\n        }\n    }\n\n    return undefined;\n}\n\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * =============================================================================\n * FIELD SEMANTICS\n * =============================================================================\n *\n * Resolves what a data field *is* by combining its semantic annotation\n * (from LLM or user) with the actual data values. This resolves the\n * one-to-many ambiguities in the type registry (e.g., Score can be\n * quantitative or ordinal depending on cardinality).\n *\n * The entry point is `resolveFieldSemantics()`. It produces a\n * `FieldSemantics` object that captures the field's identity, format,\n * aggregation role, domain, scale hint, and ordering — everything\n * about *what the data represents*, independent of how it will be\n * visualized on any particular channel.\n *\n * Design doc: docs/design-compilation-context.md\n *\n * VL dependency: **None** — pure TypeScript, no rendering library imports.\n * =============================================================================\n */\n\nimport {\n    type VisCategory,\n    getRegistryEntry,\n    isRegistered,\n} from './type-registry';\n\nimport {\n    getZeroClass,\n    inferOrdinalSortOrder,\n    inferVisCategory,\n    type ZeroClass,\n} from './semantic-types';\n\n// Re-export for backward compatibility — consumers can import from here or type-registry\nexport { getRegistryEntry } from './type-registry';\nexport type { TypeRegistryEntry } from './type-registry';\n\n// =============================================================================\n// §1  PUBLIC TYPES\n// =============================================================================\n\n/**\n * Enriched semantic annotation from LLM or user.\n */\nexport interface SemanticAnnotation {\n    /** The T2 semantic type string (e.g., \"Amount\", \"Score\", \"Month\") */\n    semanticType: string;\n\n    /**\n     * Intrinsic domain (value range) of this field's scale.\n     * Only for bounded/scaled types — NOT for open-ended measures.\n     * E.g., [1, 5] for 5-star rating, [0, 100] for score, [-90, 90] for latitude.\n     */\n    intrinsicDomain?: [number, number];\n\n    /** Unit or currency code. E.g., \"USD\", \"°C\", \"kg\" */\n    unit?: string;\n\n    /** Explicit ordinal ordering. E.g., [\"Low\", \"Medium\", \"High\"] */\n    sortOrder?: string[];\n}\n\n/** d3-compatible format specification */\nexport interface FormatSpec {\n    /** d3-format pattern: \",.2f\", \".1%\", \"+.2f\", etc. */\n    pattern?: string;\n    /** Prefix before the number: \"$\", \"€\", \"£\" */\n    prefix?: string;\n    /** Suffix after the number: \"°C\", \"%\", \" kg\" */\n    suffix?: string;\n    /** Whether large values should be abbreviated (1K, 1M, 1B) */\n    abbreviate?: boolean;\n}\n\n/** Domain bounds constraint */\nexport interface DomainConstraint {\n    min?: number;\n    max?: number;\n    /** Whether to hard-clamp values outside the domain */\n    clamp?: boolean;\n}\n\n/** Tick mark constraint */\nexport interface TickConstraint {\n    /** Only show integer tick values */\n    integersOnly?: boolean;\n    /** Exact tick values to show (for small domains like 1–5 rating) */\n    exactTicks?: number[];\n    /** Minimum step between ticks */\n    minStep?: number;\n}\n\n/** Color scheme recommendation from semantic analysis */\nexport interface ColorSchemeHint {\n    /** Whether the field is best shown with sequential, diverging, or categorical colors */\n    type: 'sequential' | 'diverging' | 'categorical';\n    /** For diverging: the midpoint value */\n    divergingMidpoint?: number;\n    /** Whether the field is inherently diverging (always show diverging) vs conditional */\n    inherentlyDiverging?: boolean;\n}\n\n/** Result of diverging midpoint analysis */\nexport interface DivergingInfo {\n    /** The midpoint value where the diverging center sits */\n    midpoint: number;\n    /** Whether this type is always diverging or only when data spans both sides */\n    inherent: boolean;\n    /** Source of the midpoint determination */\n    source: 'unit' | 'type-intrinsic' | 'domain' | 'data';\n}\n\n/**\n * Resolved field semantics — what the data field *is*.\n *\n * Derived from a `SemanticAnnotation` (semantic type + optional metadata)\n * plus actual data values. Resolves the one-to-many ambiguities in the\n * type registry by inspecting the concrete data representation.\n *\n * This is purely about the field’s identity and intrinsic properties —\n * NOT about how it will be visualized on a particular channel.\n * Channel-specific decisions (color scheme, axis reversal, interpolation,\n * tick strategy, stacking, etc.) belong in `ChannelSemantics`.\n *\n * Built once per field per dataset by `resolveFieldSemantics()`.\n */\nexport interface FieldSemantics {\n    // --- Identity ---\n    /** The semantic annotation (normalized from string or object input) */\n    semanticAnnotation: SemanticAnnotation;\n\n    // --- Encoding ---\n    /** Preferred encoding type, disambiguated from registry using data */\n    defaultVisType: VisCategory;\n\n    // --- Formatting ---\n    /** Number format derived from data type and unit (only set when confident) */\n    format?: FormatSpec;\n    /** Tooltip format (typically higher precision than axis format) */\n    tooltipFormat?: FormatSpec;\n\n    // --- Aggregation ---\n    /** Default aggregate function — intrinsic to the field (additive vs intensive) */\n    aggregationDefault?: 'sum' | 'average';\n\n    // --- Scale ---\n    /** Zero-baseline classification (meaningful / arbitrary / bipolar) */\n    zeroClass: ZeroClass | 'unknown';\n    /** Recommended scale type based on data distribution */\n    scaleType?: 'linear' | 'log' | 'sqrt' | 'symlog';\n\n    // --- Domain ---\n    /** Intrinsic domain bounds (from annotation, type-intrinsic, or data-inferred) */\n    domainConstraint?: DomainConstraint;\n\n    // --- Ordering ---\n    /** Canonical ordinal sort order (months, days, etc.) */\n    canonicalOrder?: string[];\n    /** Whether the canonical order is cyclic (wraps around) */\n    cyclic: boolean;\n    /** Default sort direction */\n    sortDirection: 'ascending' | 'descending';\n\n    // --- Histogram ---\n    /** Whether this field’s data distribution benefits from binning */\n    binningSuggested: boolean;\n}\n\n// =============================================================================\n// §2  TYPE REGISTRY  →  see ./type-registry.ts (single source of truth)\n// =============================================================================\n\n/**\n * Extract the semantic type string from a bare string or annotation object.\n * Used when downstream code only needs the type string, not the full annotation.\n */\nexport function toTypeString(input: string | SemanticAnnotation | undefined): string {\n    if (!input) return '';\n    if (typeof input === 'string') return input;\n    return input.semanticType || '';\n}\n\n// =============================================================================\n// §3  ANNOTATION NORMALIZATION\n// =============================================================================\n\n/**\n * Normalize a bare string or enriched annotation object into a\n * consistent SemanticAnnotation.\n *\n * Accepts:\n *   \"Amount\"                                          → { semanticType: \"Amount\" }\n *   { semanticType: \"Score\", intrinsicDomain: [1,5] }  → as-is\n *   undefined / \"\"                                     → { semanticType: \"Unknown\" }\n */\nexport function normalizeAnnotation(\n    input: string | SemanticAnnotation | undefined,\n): SemanticAnnotation {\n    if (!input) return { semanticType: 'Unknown' };\n    if (typeof input === 'string') return { semanticType: input || 'Unknown' };\n    return { ...input, semanticType: input.semanticType || 'Unknown' };\n}\n\n// =============================================================================\n// §4  FORMAT RESOLUTION\n// =============================================================================\n\n/** Map currency codes to display symbols */\nconst CURRENCY_MAP: Record<string, string> = {\n    USD: '$', EUR: '€', GBP: '£', JPY: '¥', CNY: '¥',\n    KRW: '₩', INR: '₹', BRL: 'R$', CAD: 'CA$', AUD: 'A$',\n    CHF: 'CHF', SEK: 'kr', NOK: 'kr', DKK: 'kr',\n};\n\n/**\n * Map common unit strings to suffix display.\n *\n * Limited to a small set of well-known, universally understood units.\n * Unknown/arbitrary annotation.unit values are intentionally excluded\n * to keep axis labels clean and avoid displaying obscure or verbose\n * unit strings on tick marks.\n */\nconst UNIT_SUFFIX_MAP: Record<string, string> = {\n    // Temperature\n    '°C': '°C', '°F': '°F', C: '°C', F: '°F',\n    // Mass\n    kg: ' kg', lb: ' lb',\n    // Distance\n    km: ' km', mi: ' mi', m: ' m', ft: ' ft',\n    // Speed\n    'km/h': ' km/h', mph: ' mph',\n    // Time\n    sec: ' s', min: ' min', hr: ' hr',\n    seconds: ' s', minutes: ' min', hours: ' hr',\n    // Percentage (handled by formatClass, but allow explicit suffix)\n    '%': '%',\n};\n\n/**\n * Detect whether percentage data uses 0–1 (fractional) or 0–100 (whole-number)\n * representation.\n *\n * Values can exceed the intrinsic range (e.g., 155 % growth), so we look at\n * the *majority* of absolute values rather than just the max.\n */\nfunction detectPercentageRepresentation(values: number[]): '0-1' | '0-100' {\n    if (values.length === 0) return '0-100';\n    const abs = values.map(Math.abs);\n    // If the majority of values are ≤ 1, treat as fractional 0–1 representation\n    const countBelow1 = abs.filter(v => v <= 1).length;\n    if (countBelow1 / abs.length >= 0.8) return '0-1';\n    return '0-100';\n}\n\n/**\n * Detect the maximum number of meaningful decimal places in a set of values.\n *\n * Returns 0 for all-integer data, 1 for data like [3.7, 4.2], 2 for [1.25, 3.50], etc.\n * Caps at 4 to avoid floating-point noise (e.g., 0.1 + 0.2 = 0.30000000000000004).\n */\nfunction detectPrecision(values: number[]): number {\n    let maxDecimals = 0;\n    for (const v of values) {\n        if (!Number.isFinite(v)) continue;\n        // Convert to string, trim trailing zeros, count decimal places\n        const s = v.toFixed(10);  // enough digits to detect real precision\n        const dot = s.indexOf('.');\n        if (dot === -1) continue;\n        // Trim trailing zeros\n        let end = s.length - 1;\n        while (end > dot && s[end] === '0') end--;\n        const decimals = end > dot ? end - dot : 0;\n        if (decimals > maxDecimals) maxDecimals = decimals;\n    }\n    return Math.min(maxDecimals, 4);\n}\n\n/**\n * Build a d3-format pattern that matches the detected data precision.\n *\n * @param values  Numeric data values\n * @param useGrouping  Whether to include thousands separator (,)\n * @param signMode  '' = default, '+' = always show sign\n * @returns  Format pattern string like ',d', ',.1f', ',.2f'\n */\nfunction precisionFormat(values: number[], useGrouping = true, signMode: '' | '+' = ''): string {\n    const p = detectPrecision(values);\n    const group = useGrouping ? ',' : '';\n    if (p === 0) return `${signMode}${group}d`;\n    return `${signMode}${group}.${p}f`;\n}\n\n/**\n * Resolve the format specification for a field based on its semantic type,\n * annotation metadata, and data values.\n *\n * Priority: annotation.unit > type-specific defaults\n */\nexport function resolveFormat(\n    semanticType: string,\n    annotation: SemanticAnnotation,\n    values: any[],\n): { format?: FormatSpec; tooltipFormat?: FormatSpec } {\n    const entry = getRegistryEntry(semanticType);\n    const unit = annotation.unit;\n\n    // Resolve currency prefix from annotation.unit\n    const currencyPrefix = unit ? CURRENCY_MAP[unit.toUpperCase()] ?? CURRENCY_MAP[unit] : undefined;\n    // Resolve unit suffix from annotation.unit — only use known units;\n    // unknown units are dropped to avoid polluting tick labels with\n    // obscure or verbose strings.\n    const unitSuffix = unit ? UNIT_SUFFIX_MAP[unit] : undefined;\n\n    const nums = values.filter((v: any) => typeof v === 'number' && !isNaN(v));\n\n    // ─── Policy: only override axis format when the raw number would be\n    // genuinely misleading.  Two cases qualify:\n    //   1. Percent with 0–1 data + intrinsicDomain → representation transform\n    //   2. Currency with a known unit → add currency symbol\n    // Everything else: let VL handle axis formatting natively.\n    // Tooltip format is lower-stakes (transient hover) so we're more liberal.\n\n    switch (entry.formatClass) {\n        case 'currency': {\n            const pfx = currencyPrefix;\n            // Only override axis when we have a known currency symbol;\n            // without it the axis is better left to VL defaults.\n            if (pfx) {\n                const axisPattern = semanticType === 'Price' ? ',.2f' : precisionFormat(nums);\n                return {\n                    format: { pattern: axisPattern, prefix: pfx },\n                    tooltipFormat: { pattern: ',.2f', prefix: pfx },\n                };\n            }\n            return { tooltipFormat: { pattern: ',.2f' } };\n        }\n\n        case 'percent': {\n            // Without intrinsicDomain we can't reliably distinguish 0–1\n            // from 0–100, so defer to VL.\n            if (!annotation.intrinsicDomain) {\n                return { tooltipFormat: { pattern: precisionFormat(nums) } };\n            }\n            const rep = detectPercentageRepresentation(nums);\n            if (rep === '0-1') {\n                // 0–1 fractional → axis must transform (0.45 → \"45%\")\n                const p = detectPrecision(nums);\n                const axisP = Math.max(0, p - 2);\n                const tipP  = Math.min(axisP + 1, 4);\n                return {\n                    format: { pattern: `.${axisP}~%` },\n                    tooltipFormat: { pattern: `.${tipP}%` },\n                };\n            }\n            // Whole-number 0–100: raw numbers are readable as-is.\n            // Axis title conveys \"percentage\"; tooltip adds suffix for clarity.\n            return {\n                tooltipFormat: { pattern: precisionFormat(nums, false), suffix: '%' },\n            };\n        }\n\n        case 'unit-suffix':\n            return {\n                tooltipFormat: unitSuffix\n                    ? { pattern: precisionFormat(nums), suffix: unitSuffix }\n                    : { pattern: precisionFormat(nums) },\n            };\n\n        case 'integer':\n            // Year/Decade: no comma — '2,024' is wrong for a year.\n            // Other integers (Count, Rank, Hour): comma separator aids readability.\n            if (semanticType === 'Year' || semanticType === 'Decade') {\n                return {};\n            }\n            return { tooltipFormat: { pattern: ',d' } };\n\n        case 'decimal':\n            return { tooltipFormat: { pattern: precisionFormat(nums) } };\n\n        case 'plain':\n        default:\n            return {};\n    }\n}\n\n// =============================================================================\n// §5  DEFAULT VIS TYPE\n// =============================================================================\n\n/**\n * Resolve the default Vega-Lite encoding type for a field.\n *\n * When the registry lists multiple candidates (e.g., Score → ['quantitative', 'ordinal']),\n * disambiguate using data statistics (distinct value count).\n */\nexport function resolveDefaultVisType(\n    semanticType: string,\n    values: any[],\n): VisCategory {\n    // For unregistered types, defer entirely to data characteristics\n    if (!isRegistered(semanticType)) {\n        return inferVisCategory(values);\n    }\n\n    const entry = getRegistryEntry(semanticType);\n    const candidates = entry.visEncodings;\n    if (candidates.length === 1) {\n        // Guard: if registry says quantitative but actual values are\n        // strings (e.g. binned ranges like \"91-95\"), defer to data inference.\n        if (candidates[0] === 'quantitative') {\n            const nonNull = values.filter(v => v != null);\n            const allNumeric = nonNull.length > 0 &&\n                nonNull.every(v => typeof v === 'number' || (typeof v === 'string' && !isNaN(+v) && v.trim() !== ''));\n            if (!allNumeric) {\n                return inferVisCategory(values);\n            }\n        }\n        return candidates[0];\n    }\n\n    // Disambiguate between quantitative and ordinal based on distinct count\n    if (candidates.includes('quantitative') && candidates.includes('ordinal')) {\n        const distinct = new Set(values.filter(v => v != null)).size;\n        // Small number of distinct values → ordinal feels more natural\n        return distinct <= 12 ? 'ordinal' : 'quantitative';\n    }\n\n    // Disambiguate between temporal and ordinal\n    if (candidates.includes('temporal') && candidates.includes('ordinal')) {\n        const distinct = new Set(values.filter(v => v != null)).size;\n        // Few values → ordinal (e.g., only 3 years: 2022, 2023, 2024)\n        return distinct <= 6 ? 'ordinal' : 'temporal';\n    }\n\n    // If geographic + quantitative (lat/lon), prefer quantitative for standard charts\n    if (candidates.includes('geographic') && candidates.includes('quantitative')) {\n        return 'quantitative';\n    }\n\n    return candidates[0];\n}\n\n// =============================================================================\n// §6  AGGREGATION DEFAULT\n// =============================================================================\n\n/**\n * Resolve the default aggregation function based on the field's role.\n *\n * - Additive measures → sum (parts sum to a meaningful total)\n * - Intensive measures → average (rates/averages shouldn't be summed)\n * - Signed-additive    → sum (preserves sign semantics)\n * - Dimensions/IDs     → undefined (aggregation not meaningful)\n */\nexport function resolveAggregationDefault(\n    semanticType: string,\n): 'sum' | 'average' | undefined {\n    const entry = getRegistryEntry(semanticType);\n    switch (entry.aggRole) {\n        case 'additive':        return 'sum';\n        case 'signed-additive': return 'sum';\n        case 'intensive':       return 'average';\n        case 'dimension':       return undefined;\n        case 'identifier':      return undefined;\n        default:                return undefined;\n    }\n}\n\n// =============================================================================\n// §7  ZERO-BASELINE CLASSIFICATION\n// =============================================================================\n\n/**\n * Resolve zero-baseline class, enhanced with annotation domain.\n *\n * If annotation provides a domain starting above 0 (e.g., Rating [1, 5]),\n * zero is arbitrary regardless of what the base type says.\n */\nexport function resolveZeroClassFromAnnotation(\n    semanticType: string,\n    domain?: [number, number],\n): ZeroClass | 'unknown' {\n    // If domain starts above zero (e.g., Rating [1,5]), zero is arbitrary\n    if (domain && domain[0] > 0) return 'arbitrary';\n\n    // Delegate to existing classification\n    return getZeroClass(semanticType);\n}\n\n// =============================================================================\n// §8  SCALE TYPE\n// =============================================================================\n\n/**\n * Recommend a scale type based on semantic type and data distribution.\n *\n * Conservative policy — only triggers when ALL of these hold:\n *   1. The semantic type is an additive measure with an open domain and is\n *      not a generic fallback (i.e. Amount, Quantity, Duration — types whose\n *      magnitude is meaningful and can legitimately span many decades).\n *   2. Data spans ≥ 6 orders of magnitude (1,000,000×).\n *   3. At least 10 data points, all non-negative.\n *\n * This intentionally almost never fires on everyday data; it only helps with\n * genuinely wide-range additive measures. When it does not fire the axis stays\n * linear, and the user can still opt into log via the per-axis quick control.\n */\nexport function resolveScaleType(\n    semanticType: string,\n    values: number[],\n): 'linear' | 'log' | 'sqrt' | 'symlog' | undefined {\n    // Only consider log for additive measures with open domains —\n    // these are the types that can legitimately span many orders of magnitude.\n    // (E.g., revenue, population, quantities across different scales.)\n    // Exclude generic fallback types (Number, Unknown) — they just mean\n    // \"we know it's numeric but not what it measures\", so applying\n    // log/symlog would be presumptuous.\n    const entry = getRegistryEntry(semanticType);\n    const eligible = entry.aggRole === 'additive' && entry.domainShape === 'open'\n        && entry.t1 !== 'GenericMeasure';\n    if (!eligible) return undefined;\n\n    if (values.length < 10) return undefined;\n\n    const filtered = values.filter(v => typeof v === 'number' && !isNaN(v) && isFinite(v));\n    if (filtered.length < 10) return undefined;\n\n    const min = Math.min(...filtered);\n    const max = Math.max(...filtered);\n    if (max <= 0 || min === max) return undefined;\n\n    // Only all-positive data — don't auto-log mixed-sign\n    if (min < 0) return undefined;\n\n    // Require ≥ 6 orders of magnitude (1000 000×) — very conservative\n    const positiveMin = Math.min(...filtered.filter(v => v > 0));\n    if (positiveMin > 0 && max / positiveMin >= 1000000) {\n        // If data contains zeros, log(0) = -∞ breaks the scale.\n        // Use symlog (linear near zero, logarithmic for large values)\n        // so zeros remain representable.\n        const hasZeros = filtered.some(v => v === 0);\n        return hasZeros ? 'symlog' : 'log';\n    }\n\n    return undefined;\n}\n\n// =============================================================================\n// §9  DOMAIN CONSTRAINTS\n// =============================================================================\n\n/**\n * Merge an intrinsic (semantic) domain with the actual data range.\n *\n * For **hard** domains (Latitude, Correlation) the intrinsic bounds are\n * physically absolute — data cannot exceed them, so we clamp.\n *\n * For **soft** domains (Percentage, Score, Rating, annotation-supplied)\n * the intrinsic bounds describe the *typical* range but real data can\n * legitimately exceed them (e.g., 155 % growth).  The effective domain\n * is the union: min(intrinsic[0], dataMin) … max(intrinsic[1], dataMax).\n */\nfunction mergeIntrinsicWithData(\n    intrinsic: [number, number],\n    values: any[],\n    hard: boolean,\n): DomainConstraint {\n    if (hard) {\n        return { min: intrinsic[0], max: intrinsic[1], clamp: true };\n    }\n    const nums = values.filter((v: any) => typeof v === 'number' && !isNaN(v));\n    if (nums.length === 0) {\n        return { min: intrinsic[0], max: intrinsic[1], clamp: false };\n    }\n    const dataMin = Math.min(...nums);\n    const dataMax = Math.max(...nums);\n    return {\n        min: Math.min(intrinsic[0], dataMin),\n        max: Math.max(intrinsic[1], dataMax),\n        clamp: false,\n    };\n}\n\n/**\n * Snap-to-bound heuristic for bounded types like Percentage / PercentageChange.\n *\n * Each bound is snapped independently:\n * - If data approaches the intrinsic lower bound → snap min\n * - If data approaches the intrinsic upper bound → snap max\n * - If data exceeds a bound → don't snap that side (let VL auto-extend)\n *\n * Threshold: 25% of the *effective side range*.\n *\n * We err on the side of snapping, because:\n * - Semantic types are opt-in — the bound carries meaning by definition.\n * - A wrong snap (extra white space) is less harmful than a wrong\n *   no-snap (viewer loses semantic reference, differences are\n *   exaggerated and proximity to the bound is hidden).\n * - Only when data is clearly in the interior (> 25% away from each\n *   bound) does the bound stop being a useful reference.\n *\n * When the intrinsic domain straddles zero (lo < 0 < hi), zero acts as a\n * visual baseline (bar charts, contextual zero).  Each bound's threshold\n * is computed relative to its distance from zero — not the full range —\n * so that snapping one side doesn't make values on the other side of zero\n * invisible (e.g., snapping to -100% when data has a tiny +0.2% bar).\n *\n * When the domain doesn't straddle zero (e.g., [0, 100]), the full range\n * is used as the reference.\n *\n * Examples for Percentage [0, 100] (threshold = 25, full range):\n *   20–45%   → snap min=0 only     (20 within 25 of 0; 45 far from 100)\n *   35–65%   → no snap             (both far from edges, in interior)\n *   55–82%   → snap max=100 only   (82 within 25 of 100; 55 far from 0)\n *   15–80%   → snap both [0, 100]  (15 near 0, 80 near 100)\n *   30–130%  → no snap             (130 exceeds 100 → no snap; 30 far from 0)\n *\n * Examples for PercentageChange [-1, 1] (threshold = 0.25 per side):\n *   -0.03 to +0.05 → no snap       (both far from ±0.75)\n *   -0.70 to +0.30 → no snap       (-0.70 > -0.75, not close enough)\n *   -0.80 to +0.30 → snap min=-1   (-0.80 ≤ -0.75; +0.30 < 0.75)\n *   -0.80 to +0.78 → snap both     (both within 0.25 of edges)\n */\nexport function snapToBoundHeuristic(\n    intrinsic: [number, number],\n    values: any[],\n): DomainConstraint | undefined {\n    const nums = values.filter((v: any) => typeof v === 'number' && !isNaN(v));\n    if (nums.length === 0) return undefined;\n\n    const [lo, hi] = intrinsic;\n    const range = hi - lo;\n    if (range <= 0) return undefined;\n\n    const dataMin = Math.min(...nums);\n    const dataMax = Math.max(...nums);\n\n    // When the domain straddles zero, compute each side's threshold relative\n    // to its distance from zero.  This prevents snapping one side from\n    // stretching the axis so wide that values near zero on the other side\n    // become invisible (sub-pixel bars).\n    const zeroInside = lo < 0 && hi > 0;\n    const thresholdLo = 0.25 * (zeroInside ? (0 - lo) : range);\n    const thresholdHi = 0.25 * (zeroInside ? hi       : range);\n\n    let snapMin: number | undefined;\n    let snapMax: number | undefined;\n\n    // Snap lower bound: data min is close to intrinsic lower bound\n    // AND data doesn't go below it (if it does, VL auto-extends)\n    if (dataMin >= lo && dataMin <= lo + thresholdLo) {\n        snapMin = lo;\n    }\n\n    // Snap upper bound: data max is close to intrinsic upper bound\n    // AND data doesn't exceed it\n    if (dataMax <= hi && dataMax >= hi - thresholdHi) {\n        snapMax = hi;\n    }\n\n    if (snapMin === undefined && snapMax === undefined) return undefined;\n\n    return { min: snapMin, max: snapMax, clamp: false };\n}\n\n/**\n * Resolve domain constraints from annotation, type-intrinsic rules, or data.\n *\n * Only truly fixed physical domains (Latitude, Longitude, Correlation)\n * use hard clamping. Bounded types like Percentage use a snap-to-bound\n * heuristic: the axis extends to the theoretical endpoint (e.g., 100%)\n * only when data is close to it, avoiding wasted space when data is\n * concentrated in a small region.\n *\n * Priority: annotation.intrinsicDomain > type-intrinsic > data-inferred\n */\nexport function resolveDomainConstraint(\n    semanticType: string,\n    annotation: SemanticAnnotation,\n    values: any[],\n): DomainConstraint | undefined {\n    const entry = getRegistryEntry(semanticType);\n\n    // 1. Explicit annotation intrinsicDomain\n    if (annotation.intrinsicDomain) {\n        // Proportion (Percentage) and SignedMeasure (PercentageChange, Profit):\n        // use snap-to-bound heuristic on both ends independently.\n        // Don't force the full theoretical range — only snap to a bound\n        // when data approaches it (e.g., 97% → snap to 100%, -0.95 → snap to -1).\n        if (entry.t1 === 'Proportion' || entry.t1 === 'SignedMeasure') {\n            return snapToBoundHeuristic(annotation.intrinsicDomain, values);\n        }\n        // All other types: soft merge (union of intrinsic + data)\n        return mergeIntrinsicWithData(annotation.intrinsicDomain, values, false);\n    }\n\n    // 2. Type-intrinsic hard domains (physically impossible to exceed)\n    if (semanticType === 'Latitude')    return mergeIntrinsicWithData([-90, 90], values, true);\n    if (semanticType === 'Longitude')   return mergeIntrinsicWithData([-180, 180], values, true);\n    if (semanticType === 'Correlation') return mergeIntrinsicWithData([-1, 1], values, true);\n\n    // 3. Percentage without explicit annotation — detect scale and apply snap\n    if (semanticType === 'Percentage') {\n        const nums = values.filter((v: any) => typeof v === 'number' && !isNaN(v));\n        if (nums.length > 0) {\n            const rep = detectPercentageRepresentation(nums);\n            const M = rep === '0-1' ? 1 : 100;\n            return snapToBoundHeuristic([0, M], values);\n        }\n    }\n\n    return undefined;\n}\n\n// =============================================================================\n// §10  TICK CONSTRAINTS\n// =============================================================================\n\n/**\n * Resolve tick constraints based on semantic type and domain.\n *\n * For bounded integer domains (e.g., Rating [1, 5]), generates exact ticks.\n * For integer types (Count, Rank, Year), enforces integer-only ticks.\n */\nexport function resolveTickConstraint(\n    semanticType: string,\n    domain?: [number, number],\n): TickConstraint | undefined {\n    const entry = getRegistryEntry(semanticType);\n\n    if (entry.formatClass === 'integer') {\n        const tc: TickConstraint = { integersOnly: true, minStep: 1 };\n        // If domain provided and span is small, generate exact ticks\n        if (domain) {\n            const span = domain[1] - domain[0];\n            if (span <= 20 && span > 0) {\n                tc.exactTicks = [];\n                for (let i = domain[0]; i <= domain[1]; i++) {\n                    tc.exactTicks.push(i);\n                }\n            }\n        }\n        return tc;\n    }\n\n    // Score with bounded domain → integer ticks ONLY when domain span\n    // indicates meaningful integer steps.  For small spans like [0, 1],\n    // the values are continuous (e.g., outlier_score 0–1) and forcing\n    // integer ticks would remove all intermediate tick marks.\n    if (semanticType === 'Score' && domain) {\n        const span = domain[1] - domain[0];\n        if (span >= 2) {\n            const tc: TickConstraint = { integersOnly: true, minStep: 1 };\n            if (span <= 20) {\n                tc.exactTicks = [];\n                for (let i = domain[0]; i <= domain[1]; i++) {\n                    tc.exactTicks.push(i);\n                }\n            }\n            return tc;\n        }\n    }\n\n    return undefined;\n}\n\n// =============================================================================\n// §11  CANONICAL ORDERING & CYCLIC\n// =============================================================================\n\n/**\n * Resolve the canonical sort order for a field.\n *\n * Priority: annotation.sortOrder > well-known type sequence > auto-detect from data\n */\nexport function resolveCanonicalOrder(\n    semanticType: string,\n    annotation: SemanticAnnotation,\n    values: any[],\n): string[] | undefined {\n    // 1. Explicit annotation sortOrder\n    if (annotation.sortOrder && annotation.sortOrder.length > 0) {\n        return annotation.sortOrder;\n    }\n\n    // 2. Delegate to existing well-known sequence detection\n    return inferOrdinalSortOrder(semanticType, values);\n}\n\n/**\n * Determine whether a field's values form a cyclic (wrap-around) sequence.\n *\n * Derived purely from semantic type — NOT an LLM annotation.\n * Types with domainShape='cyclic' in the registry are cyclic.\n */\nexport function resolveCyclic(semanticType: string): boolean {\n    const entry = getRegistryEntry(semanticType);\n    return entry.domainShape === 'cyclic';\n}\n\n// =============================================================================\n// §12  REVERSED AXIS\n// =============================================================================\n\n/**\n * Whether the axis should be reversed for this field.\n *\n * Rank is the primary case: 1st place should appear at the top of the\n * y-axis.  On the x-axis, rank 1 should stay on the left (no reversal).\n */\nexport function resolveReversed(semanticType: string, channel?: string): boolean {\n    if (semanticType === 'Rank') {\n        // Only reverse on the y-axis (rank 1 at top).\n        // On x-axis, natural left-to-right order is correct.\n        return channel !== 'x';\n    }\n    return false;\n}\n\n// =============================================================================\n// §13  NICE (domain rounding)\n// =============================================================================\n\n/**\n * Whether to apply \"nice\" rounding to scale domain endpoints.\n *\n * Nice is false when:\n * - There's a fixed domain constraint (Rating [1, 5] → axis should show exactly 1–5)\n * - The type has a fixed domain shape (Latitude, Correlation)\n */\nexport function resolveNice(\n    semanticType: string,\n    domainConstraint?: DomainConstraint,\n): boolean {\n    if (domainConstraint?.clamp) return false;\n    if (domainConstraint && domainConstraint.min !== undefined && domainConstraint.max !== undefined) {\n        return false;\n    }\n    const entry = getRegistryEntry(semanticType);\n    if (entry.domainShape === 'fixed') return false;\n    return true;\n}\n\n// =============================================================================\n// §14  DIVERGING & COLOR SCHEME HINT\n// =============================================================================\n\n/**\n * Resolve diverging midpoint information for a field.\n *\n * Priority chain:\n *   1. annotation.unit → type lookup (°C → 0, °F → 32)\n *   2. type-intrinsic midpoint (Sentiment → 0, Correlation → 0)\n *   3. annotation.intrinsicDomain midpoint (Rating [1,5] → 3)\n *   4. data-driven: data spans 0 → midpoint 0\n *\n * Returns undefined if no diverging treatment applies.\n */\nexport function resolveDivergingInfo(\n    semanticType: string,\n    annotation: SemanticAnnotation,\n    values: number[],\n): DivergingInfo | undefined {\n    const entry = getRegistryEntry(semanticType);\n    // Types with diverging='none' don't get diverging treatment\n\n    // 1. Unit-derived (Temperature)\n    if (semanticType === 'Temperature' && annotation.unit) {\n        const unitMidpoints: Record<string, number> = {\n            '°C': 0, '°F': 32, 'K': 273.15, C: 0, F: 32,\n        };\n        const mid = unitMidpoints[annotation.unit];\n        if (mid !== undefined) {\n            return { midpoint: mid, inherent: false, source: 'unit' };\n        }\n    }\n\n    // 3. Type-intrinsic\n    if (entry.diverging === 'inherent') {\n        return { midpoint: 0, inherent: true, source: 'type-intrinsic' };\n    }\n    if (entry.diverging === 'conditional') {\n        return { midpoint: 0, inherent: false, source: 'type-intrinsic' };\n    }\n\n    // 3. Domain-derived midpoint (e.g., Rating [1,5] → 3)\n    if (annotation.intrinsicDomain) {\n        return {\n            midpoint: (annotation.intrinsicDomain[0] + annotation.intrinsicDomain[1]) / 2,\n            inherent: false,\n            source: 'domain',\n        };\n    }\n\n    // 4. Data-driven: if data spans 0, use 0 as midpoint\n    if (values.length > 0) {\n        const min = Math.min(...values);\n        const max = Math.max(...values);\n        if (min < 0 && max > 0) {\n            return { midpoint: 0, inherent: false, source: 'data' };\n        }\n    }\n\n    return undefined;\n}\n\n/**\n * Resolve color scheme hint based on semantic type, diverging analysis,\n * and data values.\n */\nexport function resolveColorSchemeHint(\n    semanticType: string,\n    annotation: SemanticAnnotation,\n    values: any[],\n): ColorSchemeHint {\n    const entry = getRegistryEntry(semanticType);\n    const nums = values.filter((v: any) => typeof v === 'number' && !isNaN(v));\n\n    // Try diverging analysis\n    const divInfo = resolveDivergingInfo(semanticType, annotation, nums);\n    if (divInfo) {\n        const min = nums.length > 0 ? Math.min(...nums) : 0;\n        const max = nums.length > 0 ? Math.max(...nums) : 0;\n        const spansBothSides = min < divInfo.midpoint && max > divInfo.midpoint;\n\n        if (divInfo.inherent || spansBothSides) {\n            return {\n                type: 'diverging',\n                divergingMidpoint: divInfo.midpoint,\n                inherentlyDiverging: divInfo.inherent,\n            };\n        }\n    }\n\n    // Sequential for quantitative, categorical for nominal/ordinal\n    if (entry.visEncodings.includes('quantitative')) {\n        return { type: 'sequential' };\n    }\n    return { type: 'categorical' };\n}\n\n// =============================================================================\n// §15  BINNING SUITABILITY\n// =============================================================================\n\n/**\n * Whether this field benefits from histogram-style binning.\n *\n * False for small bounded domains (Rating 1–5), non-numeric types,\n * and identifiers.\n */\nexport function resolveBinningSuggested(\n    semanticType: string,\n    domain?: [number, number],\n): boolean {\n    const entry = getRegistryEntry(semanticType);\n\n    // Non-quantitative types don't get binned\n    if (!entry.visEncodings.includes('quantitative')) return false;\n\n    // Identifiers/dimensions don't get binned\n    if (entry.aggRole === 'identifier' || entry.aggRole === 'dimension') return false;\n\n    // Year should use temporal axis, not bins\n    if (semanticType === 'Year' || semanticType === 'Decade') return false;\n\n    // Small bounded domains have too few values to bin\n    if (domain && (domain[1] - domain[0]) <= 20) return false;\n\n    // Score with known small range\n    if (semanticType === 'Score' && !domain) return false;\n\n    return true;\n}\n\n// =============================================================================\n// §17  STACKING COMPATIBILITY\n// =============================================================================\n\n/**\n * Whether values of this type can be stacked in a bar/area chart, and how.\n *\n * - 'sum':       Additive measures (parts sum to whole)\n * - 'normalize': Proportions (show 100% breakdown)\n * - false:       Stacking is meaningless (rates, scores, identifiers)\n */\nexport function resolveStackable(\n    semanticType: string,\n): 'sum' | 'normalize' | false {\n    const entry = getRegistryEntry(semanticType);\n\n    switch (entry.aggRole) {\n        case 'additive':        return 'sum';\n        case 'signed-additive': return 'sum';\n        case 'intensive':\n            // Percentage is the exception — normalizable\n            if (semanticType === 'Percentage') return 'normalize';\n            return false;\n        case 'dimension':       return false;\n        case 'identifier':      return false;\n        default:                return false;\n    }\n}\n\n// =============================================================================\n// §18  SORT DIRECTION\n// =============================================================================\n\n/**\n * Default sort direction for this field when used on an axis.\n */\nexport function resolveSortDirection(\n    semanticType: string,\n): 'ascending' | 'descending' {\n    // Rank: show best first\n    if (semanticType === 'Rank') return 'descending';\n    return 'ascending';\n}\n\n// =============================================================================\n// §19  BUILDER: resolveFieldSemantics()\n// =============================================================================\n\n/**\n * Resolve field semantics from annotation + data.\n *\n * This is the sole entry point for data-identity decisions. It resolves\n * the one-to-many ambiguities in the type registry by inspecting the\n * concrete data representation.\n *\n * Visualization-specific decisions (color scheme, axis reversal,\n * interpolation, tick strategy, nice rounding, stacking) are NOT\n * computed here — those belong in `resolveChannelSemantics()`.\n *\n * @param input       The semantic type annotation (string or enriched object)\n * @param fieldName   Column name (used for unit detection heuristics)\n * @param values      Sampled data values from this field\n * @returns           Resolved field semantics\n */\nexport function resolveFieldSemantics(\n    input: string | SemanticAnnotation | undefined,\n    fieldName: string,\n    values: any[],\n): FieldSemantics {\n    // 1. Normalize annotation\n    const annotation = normalizeAnnotation(input);\n    const semanticType = annotation.semanticType;\n\n    // 2. Numeric values (filtered once, reused across resolvers)\n    const numericValues = values\n        .filter((v: any) => typeof v === 'number' && !isNaN(v) && isFinite(v));\n\n    // 3. Resolve field-intrinsic properties\n    const defaultVisType = resolveDefaultVisType(semanticType, values);\n    const { format, tooltipFormat } = resolveFormat(semanticType, annotation, values);\n    let aggregationDefault = resolveAggregationDefault(semanticType);\n    let zeroClass = resolveZeroClassFromAnnotation(semanticType, annotation.intrinsicDomain);\n    const scaleType = resolveScaleType(semanticType, numericValues);\n    const domainConstraint = resolveDomainConstraint(semanticType, annotation, values);\n    const canonicalOrder = resolveCanonicalOrder(semanticType, annotation, values);\n    const cyclic = resolveCyclic(semanticType);\n    let binningSuggested = resolveBinningSuggested(semanticType, annotation.intrinsicDomain);\n    const sortDirection = resolveSortDirection(semanticType);\n\n    // 4. For unregistered types, provide data-driven fallbacks.\n    //    The registry treats unknown types as categorical, but if the data\n    //    is actually numeric, we should behave like a generic measure.\n    if (!isRegistered(semanticType) && defaultVisType === 'quantitative') {\n        // Data looks numeric → treat like Number (GenericMeasure)\n        if (!aggregationDefault) aggregationDefault = 'sum';\n        if (zeroClass === 'unknown') zeroClass = 'meaningful';\n        binningSuggested = true;\n    }\n\n    return {\n        semanticAnnotation: annotation,\n        defaultVisType,\n        format,\n        tooltipFormat,\n        aggregationDefault,\n        zeroClass,\n        scaleType: scaleType ?? undefined,\n        domainConstraint,\n        canonicalOrder,\n        cyclic,\n        sortDirection,\n        binningSuggested,\n    };\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Bump Chart — line with points, rank axis reversed so rank 1 sits on\n * top (mirror of ecBumpChartDef in echarts/templates/line.ts and\n * vegalite/templates/bump.ts).\n *\n * Unlike ECharts — where a value-axis `inverse` moves the x-axis to the top,\n * forcing a category-index workaround — Chart.js reverses a linear scale in\n * place (`reverse: true`), so series keep their real rank values and the\n * config stays pure JSON with no tooltip formatter.\n */\n\nimport { ChartTemplateDef } from '../../core/types';\nimport {\n    extractCategories,\n    groupBy,\n    buildCategoryAlignedData,\n    getChartJsPalette,\n    getSeriesBorderColor,\n    coerceUnixMsForChartJs,\n} from './utils';\nimport { toTypeString } from '../../core/field-semantics';\n\n/** Semantic types that indicate a rank-like field (mirror vegalite/templates/bump.ts). */\nconst RANK_SEMANTIC_TYPES = new Set(['Rank', 'Score', 'Level']);\n\nconst isDiscrete = (type: string | undefined) => type === 'nominal' || type === 'ordinal';\n\nexport const cjsBumpChartDef: ChartTemplateDef = {\n    chart: 'Bump Chart',\n    template: { mark: 'line', encoding: {} },\n    channels: ['x', 'y', 'color', 'detail', 'column', 'row'],\n    markCognitiveChannel: 'position',\n    declareLayoutMode: () => ({\n        paramOverrides: { continuousMarkCrossSection: { x: 80, y: 20, seriesCountAxis: 'auto' } },\n    }),\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, fullTable, semanticTypes } = ctx;\n        const xCS = channelSemantics.x;\n        const yCS = channelSemantics.y;\n        const colorField = channelSemantics.color?.field;\n\n        if (!xCS?.field || !yCS?.field) return;\n        const xField = xCS.field;\n        const yField = yCS.field;\n\n        const ySemType = toTypeString(semanticTypes?.[yField]);\n        const xSemType = toTypeString(semanticTypes?.[xField]);\n        const yIsRank = RANK_SEMANTIC_TYPES.has(ySemType);\n        const xIsRank = RANK_SEMANTIC_TYPES.has(xSemType);\n        const rankOnY = yIsRank && !xIsRank;\n\n        const xIsDiscrete = isDiscrete(xCS.type);\n        const xIsTemporal = xCS.type === 'temporal';\n\n        const mapContinuousX = (raw: unknown) =>\n            (xIsTemporal ? coerceUnixMsForChartJs(raw) : raw);\n\n        // Pin continuous x to the data extent (same reasoning as line.ts:\n        // Chart.js \"nice\" ranges balloon on Unix-ms timestamps).\n        let continuousXExtent: { min: number; max: number } | undefined;\n        if (!xIsDiscrete) {\n            const xNums = (fullTable ?? table)\n                .map((r: any) => mapContinuousX(r[xField]))\n                .filter((v: any): v is number => typeof v === 'number' && Number.isFinite(v));\n            if (xNums.length > 0) {\n                continuousXExtent = { min: Math.min(...xNums), max: Math.max(...xNums) };\n            }\n        }\n\n        const categories = xIsDiscrete\n            ? extractCategories(table, xField, xCS.ordinalSortOrder)\n            : undefined;\n\n        const sortRowsByX = (rows: any[]) =>\n            [...rows].sort((a, b) => {\n                const ax = mapContinuousX(a[xField]);\n                const bx = mapContinuousX(b[xField]);\n                if (typeof ax === 'number' && typeof bx === 'number') return ax - bx;\n                return String(ax).localeCompare(String(bx));\n            });\n\n        const rankValues = table\n            .map((r: any) => Number(r[yField]))\n            .filter((v: number) => !isNaN(v) && isFinite(v));\n        const maxRank = rankValues.length ? Math.max(...rankValues) : 1;\n\n        const palette = getChartJsPalette(ctx, 'color');\n\n        const config: any = {\n            type: 'line',\n            data: { labels: categories || [], datasets: [] },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: {\n                    x: {\n                        type: xIsDiscrete ? 'category' : 'linear',\n                        title: { display: true, text: xField },\n                        ...(continuousXExtent\n                            ? { min: continuousXExtent.min, max: continuousXExtent.max }\n                            : {}),\n                        ticks: {\n                            font: { size: 10 },\n                            ...(xIsTemporal\n                                ? {\n                                    maxTicksLimit: 4,\n                                    autoSkip: true,\n                                    maxRotation: 0,\n                                    callback(v: number | string) {\n                                        const n = typeof v === 'number' ? v : Number(v);\n                                        if (!Number.isFinite(n)) return String(v);\n                                        const spanDays = continuousXExtent\n                                            ? (continuousXExtent.max - continuousXExtent.min) / 86_400_000\n                                            : 0;\n                                        const opts: Intl.DateTimeFormatOptions = spanDays > 60\n                                            ? { month: 'short', year: 'numeric' }\n                                            : { month: 'short', day: 'numeric', year: 'numeric' };\n                                        return new Date(n).toLocaleDateString(undefined, opts);\n                                    },\n                                }\n                                : {}),\n                        },\n                    },\n                    y: rankOnY\n                        ? {\n                            type: 'linear',\n                            reverse: true,\n                            min: 1,\n                            max: maxRank,\n                            title: { display: true, text: yField },\n                            ticks: { font: { size: 10 }, stepSize: 1, precision: 0 },\n                        }\n                        : {\n                            type: 'linear',\n                            title: { display: true, text: yField },\n                            ticks: { font: { size: 10 } },\n                        },\n                },\n                plugins: {\n                    tooltip: { enabled: true },\n                },\n            },\n        };\n\n        // Zero-baseline only applies to the non-rank value axis; a reversed\n        // rank axis is pinned to [1, maxRank] instead.\n        if (!rankOnY && channelSemantics.y?.zero) {\n            config.options.scales.y.beginAtZero = channelSemantics.y.zero.zero !== false;\n        }\n\n        const baseDataset = {\n            tension: 0.4,\n            pointRadius: 3,\n            fill: false,\n            backgroundColor: 'transparent',\n        };\n\n        if (colorField) {\n            const groups = groupBy(table, colorField);\n            config.options.plugins.legend = { display: true };\n\n            let colorIdx = 0;\n            for (const [name, rows] of groups) {\n                const data = xIsDiscrete\n                    ? buildCategoryAlignedData(rows, xField, yField, categories!)\n                    : sortRowsByX(rows)\n                        .map(r => ({ x: mapContinuousX(r[xField]), y: r[yField] }))\n                        .filter(p => p.y != null && (xIsTemporal ? Number.isFinite(p.x as number) : true));\n\n                config.data.datasets.push({\n                    label: name,\n                    data,\n                    borderColor: getSeriesBorderColor(palette, colorIdx),\n                    ...baseDataset,\n                });\n                colorIdx++;\n            }\n        } else {\n            const data = xIsDiscrete\n                ? categories!.map(cat => {\n                    const row = table.find(r => String(r[xField]) === cat);\n                    return row ? row[yField] : null;\n                })\n                : sortRowsByX(table)\n                    .map(r => ({ x: mapContinuousX(r[xField]), y: r[yField] }))\n                    .filter(p => p.y != null && (xIsTemporal ? Number.isFinite(p.x as number) : true));\n\n            config.data.datasets.push({\n                label: yField,\n                data,\n                borderColor: getSeriesBorderColor(palette, 0),\n                ...baseDataset,\n            });\n            config.options.plugins.legend = { display: false };\n        }\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Slope Chart (slopegraph) template.\n *\n * One straight line **per category** connecting that category's value at exactly\n * **two periods**, with a point marker at each end. The read is the slope /\n * direction of change and the crossovers between categories — the 2-point\n * value-change cousin of the Bump Chart. Mirrors cjsLineChartDef where\n * practical.\n *\n * Contract:\n *   x      — period, rendered as a *category* axis with exactly two labels.\n *   y      — value (linear).\n *   color  — category → one line (dataset) per value (legend).\n *   detail — category → one line per value (used when color is absent).\n *\n * Each dataset uses tension 0 (straight) and a visible point at each end.\n */\n\nimport { ChartTemplateDef } from '../../core/types';\nimport {\n    extractCategories,\n    groupBy,\n    buildCategoryAlignedData,\n    getChartJsPalette,\n    getSeriesBorderColor,\n} from './utils';\n\n/**\n * Order the period categories naturally: numerically when every label parses as\n * a number, chronologically when every label parses as a date, else preserve\n * the extracted order.\n */\nfunction orderPeriods(categories: string[]): string[] {\n    if (categories.length <= 1) return categories;\n    const allNumeric = categories.every(c => c.trim() !== '' && !isNaN(Number(c)));\n    if (allNumeric) return [...categories].sort((a, b) => Number(a) - Number(b));\n    const allDates = categories.every(c => !isNaN(Date.parse(c)));\n    if (allDates) return [...categories].sort((a, b) => Date.parse(a) - Date.parse(b));\n    return categories;\n}\n\nexport const cjsSlopeChartDef: ChartTemplateDef = {\n    chart: 'Slope Chart',\n    template: { mark: 'line', encoding: {} },\n    channels: ['x', 'y', 'color', 'detail', 'column', 'row'],\n    markCognitiveChannel: 'position',\n    declareLayoutMode: () => ({\n        axisFlags: { x: { banded: true } },\n        paramOverrides: {\n            defaultBandSize: 120,\n            continuousMarkCrossSection: { x: 0, y: 0, seriesCountAxis: 'auto' },\n        },\n    }),\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table } = ctx;\n        const xCS = channelSemantics.x;\n        const yCS = channelSemantics.y;\n        // One line per category: prefer color, fall back to detail.\n        const groupField = channelSemantics.color?.field ?? channelSemantics.detail?.field;\n\n        if (!xCS?.field || !yCS?.field) return;\n        const xField = xCS.field;\n        const yField = yCS.field;\n\n        // Period axis is always a two-label category axis (slopegraph).\n        const categories = orderPeriods(\n            extractCategories(table, xField, xCS.ordinalSortOrder),\n        );\n\n        const palette = getChartJsPalette(ctx, 'color');\n\n        const config: any = {\n            type: 'line',\n            data: { labels: categories, datasets: [] },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: {\n                    x: {\n                        type: 'category',\n                        // Inset the two period bands so the end points/labels\n                        // are not clipped against the plot edges.\n                        offset: true,\n                        title: { display: true, text: xField },\n                        ticks: { font: { size: 10 } },\n                    },\n                    y: {\n                        type: 'linear',\n                        title: { display: true, text: yField },\n                        ticks: { font: { size: 10 } },\n                    },\n                },\n                plugins: {\n                    tooltip: { enabled: true },\n                    legend: { display: false },\n                },\n            },\n        };\n\n        // Slope charts emphasize the change, not the absolute level — let the\n        // value axis fit the data unless the zero decision forces zero.\n        if (channelSemantics.y?.zero) {\n            config.options.scales.y.beginAtZero = channelSemantics.y.zero.zero !== false;\n        }\n\n        const baseDataset = {\n            // Straight segments + visible end points.\n            tension: 0,\n            pointRadius: 4,\n            backgroundColor: 'transparent',\n            fill: false,\n        };\n\n        if (groupField) {\n            const groups = groupBy(table, groupField);\n            config.options.plugins.legend = { display: true };\n            let colorIdx = 0;\n            for (const [name, rows] of groups) {\n                config.data.datasets.push({\n                    label: name,\n                    data: buildCategoryAlignedData(rows, xField, yField, categories),\n                    borderColor: getSeriesBorderColor(palette, colorIdx),\n                    ...baseDataset,\n                });\n                colorIdx++;\n            }\n        } else {\n            config.data.datasets.push({\n                label: yField,\n                data: buildCategoryAlignedData(table, xField, yField, categories),\n                borderColor: getSeriesBorderColor(palette, 0),\n                ...baseDataset,\n            });\n        }\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Area Chart template (single + multi-series).\n *\n * Chart.js renders area charts as line charts with `fill: true`.\n */\n\nimport { ChartTemplateDef, ChartPropertyDef } from '../../core/types';\nimport {\n    extractCategories,\n    groupBy,\n    buildCategoryAlignedData,\n    getChartJsPalette,\n    getSeriesBorderColor,\n    getSeriesBackgroundColor,\n    coerceUnixMsForChartJs,\n} from './utils';\n\nconst isDiscrete = (type: string | undefined) => type === 'nominal' || type === 'ordinal';\n\nexport const cjsAreaChartDef: ChartTemplateDef = {\n    chart: 'Area Chart',\n    template: { mark: 'area', encoding: {} },\n    channels: ['x', 'y', 'color', 'opacity', 'column', 'row'],\n    markCognitiveChannel: 'area',\n    declareLayoutMode: () => ({\n        paramOverrides: { continuousMarkCrossSection: { x: 100, y: 20, seriesCountAxis: 'auto' }, facetAspectRatioResistance: 0.5 },\n    }),\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, chartProperties } = ctx;\n        const xCS = channelSemantics.x;\n        const yCS = channelSemantics.y;\n        const colorField = channelSemantics.color?.field;\n\n        if (!xCS?.field || !yCS?.field) return;\n        const xField = xCS.field;\n        const yField = yCS.field;\n\n        const xIsDiscrete = isDiscrete(xCS.type);\n        const xIsTemporal = xCS.type === 'temporal';\n        const mapContinuousX = (raw: unknown) =>\n            (xIsTemporal ? coerceUnixMsForChartJs(raw) : raw);\n\n        const categories = xIsDiscrete\n            ? extractCategories(table, xField, xCS.ordinalSortOrder)\n            : undefined;\n\n        const opacity = chartProperties?.opacity ?? 0.4;\n\n        // Stacking\n        const stackMode = chartProperties?.stackMode;\n        const stacked = stackMode !== 'layered';\n\n        // Interpolation\n        const interpolate = chartProperties?.interpolate;\n        const tension = (interpolate === 'monotone' || interpolate === 'basis' ||\n                         interpolate === 'cardinal' || interpolate === 'catmull-rom')\n            ? 0.4 : 0;\n        const stepped = interpolate === 'step' ? 'middle' as const\n                      : interpolate === 'step-before' ? 'before' as const\n                      : interpolate === 'step-after' ? 'after' as const\n                      : false;\n\n        const palette = getChartJsPalette(ctx, 'color');\n\n        const config: any = {\n            type: 'line',\n            data: {\n                labels: categories || [],\n                datasets: [],\n            },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: {\n                    x: {\n                        type: xIsDiscrete ? 'category' : 'linear',\n                        title: { display: true, text: xField },\n                        ticks: {\n                            font: { size: 10 },\n                            ...(xIsTemporal\n                                ? {\n                                    maxTicksLimit: 8,\n                                    callback(v: number | string) {\n                                        const n = typeof v === 'number' ? v : Number(v);\n                                        if (!Number.isFinite(n)) return String(v);\n                                        return new Date(n).toLocaleDateString(undefined, {\n                                            month: 'short',\n                                            day: 'numeric',\n                                            year: 'numeric',\n                                        });\n                                    },\n                                }\n                                : {}),\n                        },\n                    },\n                    y: {\n                        type: 'linear',\n                        title: { display: true, text: yField },\n                        stacked,\n                        ticks: { font: { size: 10 } },\n                    },\n                },\n                plugins: {\n                    tooltip: { enabled: true },\n                    filler: { propagate: true },\n                },\n            },\n        };\n\n        // Zero-baseline: Chart.js defaults beginAtZero to false, so\n        // explicitly set true when the semantic decision includes zero.\n        if (channelSemantics.y?.zero) {\n            config.options.scales.y.beginAtZero = channelSemantics.y.zero.zero !== false;\n        }\n\n        if (colorField) {\n            const groups = groupBy(table, colorField);\n            config.options.plugins.legend = { display: true };\n\n            let colorIdx = 0;\n            for (const [name, rows] of groups) {\n                const data = xIsDiscrete\n                    ? buildCategoryAlignedData(rows, xField, yField, categories!)\n                    : rows\n                        .map(r => ({ x: mapContinuousX(r[xField]), y: r[yField] }))\n                        .filter(p => p.y != null && (xIsTemporal ? Number.isFinite(p.x as number) : true));\n\n                const borderColor = getSeriesBorderColor(palette, colorIdx);\n                const bgColor = getSeriesBackgroundColor(palette, colorIdx, opacity);\n\n                config.data.datasets.push({\n                    label: name,\n                    data,\n                    borderColor,\n                    backgroundColor: bgColor,\n                    tension,\n                    stepped,\n                    fill: stacked ? 'stack' : 'origin',\n                    pointRadius: 2,\n                });\n                colorIdx++;\n            }\n        } else {\n            const data = xIsDiscrete\n                ? categories!.map(cat => {\n                    const row = table.find(r => String(r[xField]) === cat);\n                    return row ? row[yField] : null;\n                })\n                : table\n                    .map(r => ({ x: mapContinuousX(r[xField]), y: r[yField] }))\n                    .filter(p => p.y != null && (xIsTemporal ? Number.isFinite(p.x as number) : true));\n\n            config.data.datasets.push({\n                label: yField,\n                data,\n                borderColor: getSeriesBorderColor(palette, 0),\n                backgroundColor: getSeriesBackgroundColor(palette, 0, opacity),\n                tension,\n                stepped,\n                fill: 'origin',\n                pointRadius: 2,\n            });\n            config.options.plugins.legend = { display: false };\n        }\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n    properties: [\n        {\n            key: 'interpolate', label: 'Curve', type: 'discrete', options: [\n                { value: undefined, label: 'Default (linear)' },\n                { value: 'linear', label: 'Linear' },\n                { value: 'monotone', label: 'Monotone (smooth)' },\n                { value: 'step', label: 'Step' },\n                { value: 'step-before', label: 'Step Before' },\n                { value: 'step-after', label: 'Step After' },\n                { value: 'basis', label: 'Basis (smooth)' },\n                { value: 'cardinal', label: 'Cardinal' },\n                { value: 'catmull-rom', label: 'Catmull-Rom' },\n            ],\n        } as ChartPropertyDef,\n        {\n            key: 'opacity', label: 'Opacity', type: 'continuous', min: 0.1, max: 1, step: 0.05, defaultValue: 0.4,\n            check: (ctx) => ({\n                applicable: !!ctx.encodings.color?.field && ctx.chartProperties?.stackMode === 'layered',\n            }),\n        } as ChartPropertyDef,\n        {\n            key: 'stackMode', label: 'Stack', type: 'discrete', options: [\n                { value: undefined, label: 'Stacked (default)' },\n                { value: 'layered', label: 'Layered (overlap)' },\n            ],\n        } as ChartPropertyDef,\n    ],\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Range Area Chart (band / high–low / area-range) template.\n *\n * A filled band showing a **low–high range** at each x. Chart.js has no native\n * ranged-area type, so a band is two line datasets per group:\n *\n *   - a LOWER-bound line dataset (`fill: false`);\n *   - an UPPER-bound line dataset that FILLS down to the lower dataset via\n *     `fill: { target: <lowerDatasetIndex> }` with a translucent\n *     `backgroundColor`.\n *\n * Because the upper fills to the lower (not to the origin), the band is a\n * translucent ribbon between the two bounds — it is never drawn down to zero.\n *\n * Contract:\n *   x      — position (category axis for discrete x; linear axis for numeric x;\n *            linear axis with unix-ms points for temporal x).\n *   y      — lower bound (linear).\n *   y2     — upper bound (linear).\n *   color  — optional series → one band (lower+upper pair) per value. The legend\n *            shows one entry per band (the lower datasets are filtered out).\n *\n * Core Chart.js only — no plugins.\n */\n\nimport { ChartTemplateDef } from '../../core/types';\nimport {\n    extractCategories,\n    groupBy,\n    buildCategoryAlignedData,\n    getChartJsPalette,\n    getSeriesBorderColor,\n    getSeriesBackgroundColor,\n    coerceUnixMsForChartJs,\n} from './utils';\n\nconst isDiscrete = (type: string | undefined) => type === 'nominal' || type === 'ordinal';\n\nexport const cjsRangeAreaChartDef: ChartTemplateDef = {\n    chart: 'Range Area Chart',\n    template: { mark: 'area', encoding: {} },\n    channels: ['x', 'y', 'y2', 'color', 'column', 'row'],\n    markCognitiveChannel: 'area',\n    declareLayoutMode: () => ({\n        paramOverrides: {\n            continuousMarkCrossSection: { x: 100, y: 20, seriesCountAxis: 'auto' },\n            facetAspectRatioResistance: 0.5,\n        },\n    }),\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, chartProperties } = ctx;\n        const xCS = channelSemantics.x;\n        const yCS = channelSemantics.y;\n        const y2CS = channelSemantics.y2;\n        const colorField = channelSemantics.color?.field;\n\n        if (!xCS?.field || !yCS?.field || !y2CS?.field) return;\n        const xField = xCS.field;\n        const lowField = yCS.field;\n        const highField = y2CS.field;\n\n        const xIsDiscrete = isDiscrete(xCS.type);\n        const xIsTemporal = xCS.type === 'temporal';\n        const mapContinuousX = (raw: unknown) => (xIsTemporal ? coerceUnixMsForChartJs(raw) : Number(raw));\n\n        // Title the value axis with BOTH bound fields (matching Vega-Lite's\n        // native \"low, high\" axis title), falling back to the single name.\n        const valueTitle = lowField === highField ? lowField : `${lowField}, ${highField}`;\n\n        const categories = xIsDiscrete\n            ? extractCategories(table, xField, xCS.ordinalSortOrder)\n            : undefined;\n\n        const opacity = chartProperties?.opacity ?? 0.3;\n        const palette = getChartJsPalette(ctx, 'color');\n\n        const config: any = {\n            type: 'line',\n            data: { labels: categories ?? [], datasets: [] },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: {\n                    x: {\n                        type: xIsDiscrete ? 'category' : 'linear',\n                        title: { display: true, text: xField },\n                        ticks: {\n                            font: { size: 10 },\n                            ...(xIsTemporal\n                                ? {\n                                    maxTicksLimit: 8,\n                                    callback(v: number | string) {\n                                        const n = typeof v === 'number' ? v : Number(v);\n                                        if (!Number.isFinite(n)) return String(v);\n                                        return new Date(n).toLocaleDateString(undefined, {\n                                            month: 'short', day: 'numeric', year: 'numeric',\n                                        });\n                                    },\n                                }\n                                : {}),\n                        },\n                    },\n                    y: {\n                        type: 'linear',\n                        // A ranged area reads its extent, not its distance from\n                        // zero — fit the band rather than forcing a zero baseline.\n                        title: { display: true, text: valueTitle },\n                        ticks: { font: { size: 10 } },\n                    },\n                },\n                plugins: {\n                    tooltip: { enabled: true },\n                    legend: { display: false },\n                },\n            },\n        };\n\n        /** Build the lower / upper data arrays for a group of rows. */\n        const buildBoundData = (rows: any[], field: string): any => {\n            if (xIsDiscrete) return buildCategoryAlignedData(rows, xField, field, categories!);\n            return rows\n                .map(r => ({ x: mapContinuousX(r[xField]), y: Number(r[field]) }))\n                .filter(p => Number.isFinite(p.x) && Number.isFinite(p.y))\n                .sort((a, b) => a.x - b.x);\n        };\n\n        const pushBand = (rows: any[], name: string, colorIdx: number) => {\n            const lowerData = buildBoundData(rows, lowField);\n            const upperData = buildBoundData(rows, highField);\n            const border = getSeriesBorderColor(palette, colorIdx);\n            const lowerIndex = config.data.datasets.length;\n            // Lower bound — a thin line, no fill.\n            config.data.datasets.push({\n                label: name,\n                data: lowerData,\n                borderColor: border,\n                backgroundColor: 'transparent',\n                borderWidth: 1,\n                pointRadius: 0,\n                fill: false,\n                tension: 0,\n                _rangeBound: 'lower',\n            });\n            // Upper bound — fills DOWN to the lower dataset (the band ribbon).\n            config.data.datasets.push({\n                label: name,\n                data: upperData,\n                borderColor: border,\n                backgroundColor: getSeriesBackgroundColor(palette, colorIdx, opacity),\n                borderWidth: 1,\n                pointRadius: 0,\n                fill: { target: lowerIndex },\n                tension: 0,\n                _rangeBound: 'upper',\n            });\n        };\n\n        if (colorField) {\n            const groups = groupBy(table, colorField);\n            let idx = 0;\n            for (const [name, rows] of groups) {\n                pushBand(rows, String(name), idx);\n                idx++;\n            }\n            // One legend entry per band: hide the lower-bound datasets.\n            config.options.plugins.legend = {\n                display: true,\n                labels: {\n                    filter: (item: any, data: any) =>\n                        data.datasets[item.datasetIndex]?._rangeBound !== 'lower',\n                },\n            };\n        } else {\n            pushBand(table, lowField, 0);\n        }\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Pie Chart template.\n *\n * Contrast with VL:\n *   VL: mark = \"arc\" with theta + color\n *   CJS: type = 'pie' or 'doughnut' with data = { labels, datasets[{data}] }\n */\n\nimport { ChartTemplateDef, ChartPropertyDef } from '../../core/types';\nimport {\n    extractCategories,\n    getChartJsPalette,\n    getSeriesBorderColor,\n    getSeriesBackgroundColor,\n} from './utils';\n\n/**\n * Reorder parallel label/value arrays in place by slice value. 'descending'\n * leads with the largest slice, 'ascending' the smallest; anything else keeps\n * the incoming data/category order.\n */\nexport function sortSlicesInPlace(\n    labels: string[],\n    values: number[],\n    sortSlices: unknown,\n): void {\n    if (sortSlices !== 'descending' && sortSlices !== 'ascending') return;\n    const idx = values.map((_, i) => i);\n    idx.sort((a, b) => (sortSlices === 'descending' ? values[b] - values[a] : values[a] - values[b]));\n    const sortedLabels = idx.map((i) => labels[i]);\n    const sortedValues = idx.map((i) => values[i]);\n    labels.splice(0, labels.length, ...sortedLabels);\n    values.splice(0, values.length, ...sortedValues);\n}\n\nconst SORT_SLICES_PROPERTY: ChartPropertyDef = {\n    key: 'sortSlices', label: 'Sort slices', type: 'discrete',\n    options: [\n        { value: 'none', label: 'Data order' },\n        { value: 'descending', label: 'Largest first' },\n        { value: 'ascending', label: 'Smallest first' },\n    ],\n    defaultValue: 'none',\n};\n\nexport const cjsPieChartDef: ChartTemplateDef = {\n    chart: 'Pie Chart',\n    template: { mark: 'arc', encoding: {} },\n    channels: ['size', 'color', 'column', 'row'],\n    markCognitiveChannel: 'area',\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, chartProperties } = ctx;\n        const colorField = channelSemantics.color?.field;\n        const sizeField = channelSemantics.size?.field;\n\n        const labels: string[] = [];\n        const values: number[] = [];\n\n        const palette = getChartJsPalette(ctx, 'color');\n\n        if (colorField && sizeField) {\n            // color = category (slice label), size = measure (slice value)\n            const agg = new Map<string, number>();\n            for (const row of table) {\n                const cat = String(row[colorField] ?? '');\n                const val = Number(row[sizeField]) || 0;\n                agg.set(cat, (agg.get(cat) ?? 0) + val);\n            }\n            const categories = extractCategories(table, colorField, channelSemantics.color?.ordinalSortOrder);\n            for (const cat of categories) {\n                labels.push(cat);\n                values.push(agg.get(cat) ?? 0);\n            }\n        } else if (colorField) {\n            // No size field → count occurrences per category\n            const counts = new Map<string, number>();\n            for (const row of table) {\n                const cat = String(row[colorField] ?? '');\n                counts.set(cat, (counts.get(cat) ?? 0) + 1);\n            }\n            const categories = extractCategories(table, colorField, channelSemantics.color?.ordinalSortOrder);\n            for (const cat of categories) {\n                labels.push(cat);\n                values.push(counts.get(cat) ?? 0);\n            }\n        } else if (sizeField) {\n            for (const row of table) {\n                const val = Number(row[sizeField]) || 0;\n                labels.push(String(val));\n                values.push(val);\n            }\n        }\n\n        const innerRadius = chartProperties?.innerRadius ?? 0;\n        const isDoughnut = innerRadius > 0;\n\n        sortSlicesInPlace(labels, values, chartProperties?.sortSlices);\n\n        const config: any = {\n            type: isDoughnut ? 'doughnut' : 'pie',\n            data: {\n                labels,\n                datasets: [{\n                    data: values,\n                    backgroundColor: labels.map((_, i) => getSeriesBackgroundColor(palette, i, 0.6)),\n                    borderColor: labels.map((_, i) => getSeriesBorderColor(palette, i)),\n                    borderWidth: 1,\n                }],\n            },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                plugins: {\n                    legend: { display: true, position: 'right' as const },\n                    tooltip: { enabled: true },\n                },\n                ...(isDoughnut ? { cutout: `${innerRadius}%` } : {}),\n            },\n            // Canvas size from context (no axes)\n            _width: Math.max(ctx.canvasSize.width, 300),\n            _height: Math.max(ctx.canvasSize.height, 250),\n        };\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n    properties: [\n        { key: 'innerRadius', label: 'Donut', type: 'continuous', min: 0, max: 60, step: 5, defaultValue: 0 } as ChartPropertyDef,\n        SORT_SLICES_PROPERTY,\n    ],\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Doughnut Chart template.\n *\n * Contrast with Pie:\n *   Pie: type = 'pie' (full disc, area encodes value)\n *   Doughnut: type = 'doughnut' with a `cutout` — the hollow centre trades a\n *             little area-judgement accuracy for a cleaner look and room for a\n *             centre label. Same data model as Pie (color = slice, size = value).\n */\n\nimport { ChartTemplateDef, ChartPropertyDef } from '../../core/types';\nimport {\n    extractCategories,\n    getChartJsPalette,\n    getSeriesBorderColor,\n    getSeriesBackgroundColor,\n} from './utils';\nimport { sortSlicesInPlace } from './pie';\n\nexport const cjsDoughnutChartDef: ChartTemplateDef = {\n    chart: 'Doughnut Chart',\n    template: { mark: 'arc', encoding: {} },\n    channels: ['size', 'color', 'column', 'row'],\n    markCognitiveChannel: 'area',\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, chartProperties } = ctx;\n        const colorField = channelSemantics.color?.field;\n        const sizeField = channelSemantics.size?.field;\n\n        const labels: string[] = [];\n        const values: number[] = [];\n\n        const palette = getChartJsPalette(ctx, 'color');\n\n        if (colorField && sizeField) {\n            const agg = new Map<string, number>();\n            for (const row of table) {\n                const cat = String(row[colorField] ?? '');\n                const val = Number(row[sizeField]) || 0;\n                agg.set(cat, (agg.get(cat) ?? 0) + val);\n            }\n            const categories = extractCategories(table, colorField, channelSemantics.color?.ordinalSortOrder);\n            for (const cat of categories) {\n                labels.push(cat);\n                values.push(agg.get(cat) ?? 0);\n            }\n        } else if (colorField) {\n            const counts = new Map<string, number>();\n            for (const row of table) {\n                const cat = String(row[colorField] ?? '');\n                counts.set(cat, (counts.get(cat) ?? 0) + 1);\n            }\n            const categories = extractCategories(table, colorField, channelSemantics.color?.ordinalSortOrder);\n            for (const cat of categories) {\n                labels.push(cat);\n                values.push(counts.get(cat) ?? 0);\n            }\n        } else if (sizeField) {\n            for (const row of table) {\n                const val = Number(row[sizeField]) || 0;\n                labels.push(String(val));\n                values.push(val);\n            }\n        }\n\n        // Default to a 55% hollow centre; let callers tune it.\n        const cutout = chartProperties?.innerRadius ?? 55;\n\n        sortSlicesInPlace(labels, values, chartProperties?.sortSlices);\n\n        const config: any = {\n            type: 'doughnut',\n            data: {\n                labels,\n                datasets: [{\n                    data: values,\n                    backgroundColor: labels.map((_, i) => getSeriesBackgroundColor(palette, i, 0.6)),\n                    borderColor: labels.map((_, i) => getSeriesBorderColor(palette, i)),\n                    borderWidth: 1,\n                }],\n            },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                cutout: `${cutout}%`,\n                plugins: {\n                    legend: { display: true, position: 'right' as const },\n                    tooltip: { enabled: true },\n                },\n            },\n            _width: Math.max(ctx.canvasSize.width, 300),\n            _height: Math.max(ctx.canvasSize.height, 250),\n        };\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n    properties: [\n        { key: 'innerRadius', label: 'Hole', type: 'continuous', min: 20, max: 80, step: 5, defaultValue: 55 } as ChartPropertyDef,\n        {\n            key: 'sortSlices', label: 'Sort slices', type: 'discrete',\n            options: [\n                { value: 'none', label: 'Data order' },\n                { value: 'descending', label: 'Largest first' },\n                { value: 'ascending', label: 'Smallest first' },\n            ],\n            defaultValue: 'none',\n        } as ChartPropertyDef,\n    ],\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Histogram template.\n *\n * Chart.js has no built-in binning — we compute bins client-side\n * and render as a bar chart.\n */\n\nimport { ChartTemplateDef, ChartPropertyDef } from '../../core/types';\nimport {\n    getChartJsPalette,\n    getSeriesBorderColor,\n    getSeriesBackgroundColor,\n} from './utils';\nexport const cjsHistogramDef: ChartTemplateDef = {\n    chart: 'Histogram',\n    template: { mark: 'bar', encoding: {} },\n    channels: ['x', 'color', 'column', 'row'],\n    markCognitiveChannel: 'length',\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, chartProperties } = ctx;\n        const xField = channelSemantics.x?.field;\n        const colorField = channelSemantics.color?.field;\n        if (!xField) return;\n\n        const palette = getChartJsPalette(ctx, 'color');\n\n        // Extract numeric values\n        const numValues = table\n            .map(r => Number(r[xField]))\n            .filter(v => isFinite(v));\n\n        if (numValues.length === 0) return;\n\n        // `binCount` is the bin count; 0 (auto) falls back to 10.\n        const binCount = chartProperties?.binCount || 10;\n\n        const minVal = Math.min(...numValues);\n        const maxVal = Math.max(...numValues);\n        const range = maxVal - minVal;\n        const binWidth = range > 0 ? range / binCount : 1;\n\n        const categories = Array.from({ length: binCount }, (_, i) => {\n            const lo = (minVal + i * binWidth).toFixed(1);\n            const hi = (minVal + (i + 1) * binWidth).toFixed(1);\n            return `${lo}–${hi}`;\n        });\n\n        const config: any = {\n            type: 'bar',\n            data: {\n                labels: categories,\n                datasets: [],\n            },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: {\n                    x: {\n                        title: { display: true, text: xField },\n                    },\n                    y: {\n                        title: { display: true, text: 'Count' },\n                        beginAtZero: true,\n                    },\n                },\n                plugins: {\n                    tooltip: { enabled: true },\n                },\n            },\n        };\n\n        if (!colorField) {\n            // Simple histogram\n            const counts = new Array(binCount).fill(0);\n            for (const v of numValues) {\n                let idx = Math.floor((v - minVal) / binWidth);\n                if (idx >= binCount) idx = binCount - 1;\n                counts[idx]++;\n            }\n\n            config.data.datasets.push({\n                label: 'Count',\n                data: counts,\n                backgroundColor: getSeriesBackgroundColor(palette, 0),\n                borderColor: getSeriesBorderColor(palette, 0),\n                borderWidth: 1,\n                barPercentage: 1.0,\n                categoryPercentage: 1.0,\n            });\n            config.options.plugins.legend = { display: false };\n        } else {\n            // Stacked histogram\n            const groupValues = new Map<string, number[]>();\n            for (const row of table) {\n                const v = Number(row[xField]);\n                if (!isFinite(v)) continue;\n                const g = String(row[colorField] ?? '');\n                if (!groupValues.has(g)) groupValues.set(g, []);\n                groupValues.get(g)!.push(v);\n            }\n\n            config.options.scales.x.stacked = true;\n            config.options.scales.y.stacked = true;\n\n            let colorIdx = 0;\n            for (const [name, vals] of groupValues) {\n                const counts = new Array(binCount).fill(0);\n                for (const v of vals) {\n                    let idx = Math.floor((v - minVal) / binWidth);\n                    if (idx >= binCount) idx = binCount - 1;\n                    counts[idx]++;\n                }\n                config.data.datasets.push({\n                    label: name,\n                    data: counts,\n                    backgroundColor: getSeriesBackgroundColor(palette, colorIdx),\n                    borderColor: getSeriesBorderColor(palette, colorIdx),\n                    borderWidth: 1,\n                    barPercentage: 1.0,\n                    categoryPercentage: 1.0,\n                });\n                colorIdx++;\n            }\n            config.options.plugins.legend = { display: true };\n        }\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n    properties: [\n        { key: 'binCount', label: 'Max Bins', type: 'continuous', min: 5, max: 50, step: 1, defaultValue: 0 } as ChartPropertyDef,\n    ],\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js ECDF Plot (Empirical Cumulative Distribution Function) template.\n *\n * Align with vegalite/templates/ecdf.ts and echarts/templates/ecdf.ts. Chart.js\n * has no transform pipeline, so we precompute the same sorted cumulative arrays:\n * for each color/detail group, sort the numeric values ascending and emit\n * {x, y} points using the \"≤ x\" convention (ties collapse to the proportion at\n * the value's last occurrence). Each group is one `line` dataset with\n * `stepped: 'after'` (= step-after, matching VL's `step-after` and ECharts'\n * `step: 'end'`), drawn on a `linear` x-axis; the y-axis is pinned to [0, 1].\n *\n * Core Chart.js only — no plugins. A measure is always quantitative, so a linear\n * x-axis is correct (never temporal).\n */\n\nimport { ChartTemplateDef, ChartPropertyDef } from '../../core/types';\nimport { groupBy, getChartJsPalette, getSeriesBorderColor } from './utils';\n\n/**\n * Sorted distinct {x, y} ECDF points using the \"≤ x\" convention. Ties collapse\n * to the proportion at the value's last occurrence, so the curve is\n * non-decreasing and ends at y = 1.0.\n */\nfunction ecdfPoints(values: number[]): { x: number; y: number }[] {\n    const sorted = values.filter(v => Number.isFinite(v)).sort((a, b) => a - b);\n    const n = sorted.length;\n    const out: { x: number; y: number }[] = [];\n    if (n === 0) return out;\n    let i = 0;\n    while (i < n) {\n        let j = i;\n        while (j + 1 < n && sorted[j + 1] === sorted[i]) j++;\n        out.push({ x: sorted[i], y: (j + 1) / n });\n        i = j + 1;\n    }\n    return out;\n}\n\nexport const cjsEcdfPlotDef: ChartTemplateDef = {\n    chart: 'ECDF Plot',\n    template: { mark: 'line', encoding: {} },\n    channels: ['x', 'color', 'detail', 'column', 'row'],\n    markCognitiveChannel: 'position',\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, chartProperties } = ctx;\n        const xField = channelSemantics.x?.field;\n        // One ECDF per dataset: prefer color, fall back to detail.\n        const groupField = channelSemantics.color?.field ?? channelSemantics.detail?.field;\n        if (!xField) return;\n\n        const showPoints = !!chartProperties?.showPoints;\n        const palette = getChartJsPalette(ctx, 'color');\n\n        const config: any = {\n            type: 'line',\n            data: { datasets: [] },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: {\n                    x: {\n                        type: 'linear',\n                        title: { display: true, text: xField },\n                        ticks: { font: { size: 10 } },\n                    },\n                    y: {\n                        type: 'linear',\n                        min: 0,\n                        max: 1,\n                        title: { display: true, text: 'Cumulative proportion' },\n                        ticks: { font: { size: 10 } },\n                    },\n                },\n                plugins: {\n                    tooltip: { enabled: true },\n                    legend: { display: false },\n                },\n            },\n        };\n\n        const pushDataset = (name: string, values: number[], idx: number) => {\n            config.data.datasets.push({\n                label: name,\n                data: ecdfPoints(values),\n                borderColor: getSeriesBorderColor(palette, idx),\n                backgroundColor: 'transparent',\n                // step-after: hold the proportion until the next value, then jump.\n                stepped: 'after',\n                pointRadius: showPoints ? 3 : 0,\n                borderWidth: 2,\n                fill: false,\n                tension: 0,\n            });\n        };\n\n        if (groupField) {\n            const groups = groupBy(table, groupField);\n            config.options.plugins.legend = { display: true };\n            let idx = 0;\n            for (const [name, rows] of groups) {\n                const values = rows.map((r: any) => Number(r[xField])).filter((v: number) => !isNaN(v));\n                pushDataset(String(name), values, idx);\n                idx++;\n            }\n        } else {\n            const values = table.map((r: any) => Number(r[xField])).filter((v: number) => !isNaN(v));\n            pushDataset(xField, values, 0);\n        }\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n    properties: [\n        { key: 'showPoints', label: 'Points', type: 'binary', defaultValue: false } as ChartPropertyDef,\n    ],\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Radar Chart template.\n *\n * Chart.js has native radar chart support via type: 'radar'.\n *\n * Data model (long format):\n *   x (nominal): metric / axis name\n *   y (quantitative): value for that metric\n *   color (nominal): entity / group\n */\n\nimport { ChartTemplateDef, ChartPropertyDef } from '../../core/types';\nimport {\n    extractCategories,\n    groupBy,\n    getChartJsPalette,\n    getSeriesBorderColor,\n    getSeriesBackgroundColor,\n} from './utils';\n\nexport const cjsRadarChartDef: ChartTemplateDef = {\n    chart: 'Radar Chart',\n    template: { mark: 'point', encoding: {} },\n    channels: ['x', 'y', 'color', 'column', 'row'],\n    markCognitiveChannel: 'position',\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, chartProperties } = ctx;\n        const axisField = channelSemantics.x?.field;   // metric names\n        const valueField = channelSemantics.y?.field;   // metric values\n        const groupField = channelSemantics.color?.field; // entities\n\n        if (!axisField || !valueField) return;\n\n        // Extract unique metrics (radar axes)\n        const metrics = extractCategories(table, axisField, channelSemantics.x?.ordinalSortOrder);\n        if (metrics.length < 2) return;\n\n        const filled = chartProperties?.filled !== false;\n        const fillOpacity = chartProperties?.fillOpacity ?? 0.3;\n\n        const palette = getChartJsPalette(ctx, 'color');\n\n        const config: any = {\n            type: 'radar',\n            data: {\n                labels: metrics,\n                datasets: [],\n            },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: {\n                    r: {\n                        beginAtZero: true,\n                        ticks: { display: true },\n                        pointLabels: { display: true },\n                    },\n                },\n                plugins: {\n                    tooltip: { enabled: true },\n                },\n            },\n            // Canvas size from context (no axes)\n            _width: Math.max(ctx.canvasSize.width, 350),\n            _height: Math.max(ctx.canvasSize.height, 300),\n        };\n\n        if (groupField) {\n            const groups = groupBy(table, groupField);\n            config.options.plugins.legend = { display: true };\n\n            let colorIdx = 0;\n            for (const [name, rows] of groups) {\n                // Aggregate: mean per metric\n                const metricVals = new Map<string, { sum: number; count: number }>();\n                for (const row of rows) {\n                    const m = String(row[axisField]);\n                    const v = Number(row[valueField]) || 0;\n                    if (!metricVals.has(m)) metricVals.set(m, { sum: 0, count: 0 });\n                    const entry = metricVals.get(m)!;\n                    entry.sum += v;\n                    entry.count++;\n                }\n\n                const values = metrics.map(m => {\n                    const entry = metricVals.get(m);\n                    return entry ? Math.round((entry.sum / entry.count) * 100) / 100 : 0;\n                });\n\n                const borderColor = getSeriesBorderColor(palette, colorIdx);\n                const bgColor = getSeriesBackgroundColor(palette, colorIdx, fillOpacity);\n\n                config.data.datasets.push({\n                    label: name,\n                    data: values,\n                    borderColor,\n                    backgroundColor: filled ? bgColor : 'transparent',\n                    pointBackgroundColor: borderColor,\n                    fill: filled,\n                });\n                colorIdx++;\n            }\n        } else {\n            // Single group\n            const metricVals = new Map<string, { sum: number; count: number }>();\n            for (const row of table) {\n                const m = String(row[axisField]);\n                const v = Number(row[valueField]) || 0;\n                if (!metricVals.has(m)) metricVals.set(m, { sum: 0, count: 0 });\n                const entry = metricVals.get(m)!;\n                entry.sum += v;\n                entry.count++;\n            }\n\n            const values = metrics.map(m => {\n                const entry = metricVals.get(m);\n                return entry ? Math.round((entry.sum / entry.count) * 100) / 100 : 0;\n            });\n\n            config.data.datasets.push({\n                label: valueField,\n                data: values,\n                borderColor: getSeriesBorderColor(palette, 0),\n                backgroundColor: filled\n                    ? getSeriesBackgroundColor(palette, 0, fillOpacity)\n                    : 'transparent',\n                pointBackgroundColor: getSeriesBorderColor(palette, 0),\n                fill: filled,\n            });\n            config.options.plugins.legend = { display: false };\n        }\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n    properties: [\n        {\n            key: 'filled', label: 'Fill', type: 'discrete', options: [\n                { value: true, label: 'Filled (default)' },\n                { value: false, label: 'Outline only' },\n            ],\n        } as ChartPropertyDef,\n        { key: 'fillOpacity', label: 'Opacity', type: 'continuous', min: 0.05, max: 0.8, step: 0.05, defaultValue: 0.3 } as ChartPropertyDef,\n    ],\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Rose Chart (Nightingale / Coxcomb) template.\n *\n * Contrast with VL:\n *   VL: mark = \"arc\" with theta (angular extent fixed per slice) + radius (value)\n *   CJS: type = 'polarArea' — each wedge spans an equal angle, radius encodes value.\n *\n * Data model (long format):\n *   x (nominal): angular category (direction, month, etc.)\n *   y (quantitative): value mapped to wedge radius\n *   color (nominal, optional): stack / group variable\n *\n * Note: Chart.js polarArea doesn't support native stacking. When a color\n * field is present we aggregate per category (sum across groups) and show\n * the total, with the legend listing the color groups for reference.\n */\n\nimport { ChartTemplateDef, ChartPropertyDef } from '../../core/types';\nimport {\n    extractCategories,\n    groupBy,\n    getChartJsPalette,\n    getSeriesBorderColor,\n    getSeriesBackgroundColor,\n} from './utils';\nimport { sortSlicesInPlace } from './pie';\n\nexport const cjsRoseChartDef: ChartTemplateDef = {\n    chart: 'Rose Chart',\n    template: { mark: 'arc', encoding: {} },\n    channels: ['x', 'y', 'color', 'column', 'row'],\n    markCognitiveChannel: 'area',\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table } = ctx;\n        const catField = channelSemantics.x?.field;   // angular categories\n        const valField = channelSemantics.y?.field;    // wedge radius value\n        const colorField = channelSemantics.color?.field; // optional grouping\n\n        if (!catField || !valField) return;\n\n        const palette = getChartJsPalette(ctx, 'color');\n\n        // Extract unique angular categories\n        const categories = extractCategories(table, catField, channelSemantics.x?.ordinalSortOrder);\n        if (categories.length === 0) return;\n\n        let labels: string[];\n        let values: number[];\n        let bgColors: string[];\n        let borderColors: string[];\n\n        if (colorField) {\n            // Stacked: aggregate per (category × group), then sum across groups per category\n            const groups = groupBy(table, colorField);\n            const groupNames = [...groups.keys()];\n\n            // Build per-category totals\n            const catTotals = new Map<string, number>();\n            for (const cat of categories) catTotals.set(cat, 0);\n\n            for (const [, rows] of groups) {\n                for (const row of rows) {\n                    const cat = String(row[catField] ?? '');\n                    const val = Number(row[valField]) || 0;\n                    if (catTotals.has(cat)) {\n                        catTotals.set(cat, catTotals.get(cat)! + val);\n                    }\n                }\n            }\n\n            labels = categories;\n            values = categories.map(c => catTotals.get(c) ?? 0);\n\n            // Assign distinct colors per wedge (category)\n            bgColors = categories.map((_, i) => getSeriesBackgroundColor(palette, i, 0.6));\n            borderColors = categories.map((_, i) => getSeriesBorderColor(palette, i));\n        } else {\n            // Simple: one value per category\n            const catAgg = new Map<string, number>();\n            for (const row of table) {\n                const cat = String(row[catField] ?? '');\n                const val = Number(row[valField]) || 0;\n                catAgg.set(cat, (catAgg.get(cat) ?? 0) + val);\n            }\n\n            labels = categories;\n            values = categories.map(c => catAgg.get(c) ?? 0);\n            bgColors = categories.map((_, i) => getSeriesBackgroundColor(palette, i, 0.6));\n            borderColors = categories.map((_, i) => getSeriesBorderColor(palette, i));\n        }\n\n        // Alignment: 'center' puts wedge center at 12 o'clock,\n        // 'left' puts wedge left edge at 12 o'clock.\n        sortSlicesInPlace(labels, values, ctx.chartProperties?.sortSlices);\n\n        // Area-truth: Chart.js `polarArea` maps the datum linearly to the wedge\n        // radius, so raw values make AREA ∝ value² (a 4:1 value reads as 16:1\n        // area). Vega-Lite instead uses a sqrt radius scale. Chart.js' radial `r`\n        // scale has no sqrt type, so we plot sqrt(value) as the radius (making\n        // AREA ∝ value) and keep the true value for the tooltip/label. Guard\n        // against negatives (sqrt(NaN)).\n        const rawValues = values.slice();\n        const radii = values.map(v => Math.sqrt(Math.max(0, v)));\n\n        const alignment = ctx.chartProperties?.alignment ?? 'left';\n        const n = categories.length;\n        // Chart.js polarArea rotation lives on the RADIAL SCALE\n        // (`scales.r.startAngle`, in degrees, 0 = 12 o'clock, CW) — the\n        // top-level `options.startAngle` is NOT read for polarArea and has no\n        // effect. Default (0) is left alignment (first wedge's left edge at 12\n        // o'clock); center rotates back by half a slice so the first wedge is\n        // centred on 12 o'clock.\n        const startAngle = alignment === 'center' && n > 0\n            ? -(180 / n)\n            : 0;\n\n        const config: any = {\n            type: 'polarArea',\n            data: {\n                labels,\n                datasets: [{\n                    data: radii,\n                    backgroundColor: bgColors,\n                    borderColor: borderColors,\n                    borderWidth: 1,\n                }],\n            },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: {\n                    r: {\n                        beginAtZero: true,\n                        startAngle,\n                        // Radii are sqrt(value); the raw tick numbers would\n                        // misrepresent the scale, so hide them (true values are\n                        // surfaced in the tooltip).\n                        ticks: { display: false },\n                    },\n                },\n                plugins: {\n                    legend: { display: true, position: 'right' as const },\n                    tooltip: {\n                        enabled: true,\n                        callbacks: {\n                            // Radius is sqrt-transformed; report the true value.\n                            label: (item: any) => {\n                                const raw = rawValues[item.dataIndex];\n                                const shown = raw != null ? raw : item.raw;\n                                const name = item.label != null ? item.label : '';\n                                return `${name}: ${shown}`;\n                            },\n                        },\n                    },\n                },\n            },\n            _width: Math.max(ctx.canvasSize.width, 350),\n            _height: Math.max(ctx.canvasSize.height, 300),\n        };\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n    properties: [\n        {\n            key: 'alignment', label: 'Alignment', type: 'discrete', options: [\n                { value: 'left', label: 'Left (default)' },\n                { value: 'center', label: 'Center' },\n            ],\n        } as ChartPropertyDef,\n        {\n            key: 'sortSlices', label: 'Sort slices', type: 'discrete',\n            options: [\n                { value: 'none', label: 'Data order' },\n                { value: 'descending', label: 'Largest first' },\n                { value: 'ascending', label: 'Smallest first' },\n            ],\n            defaultValue: 'none',\n        } as ChartPropertyDef,\n    ],\n};\n","import { SemanticAnnotation, toTypeString } from '../core/field-semantics';\nimport { isTimeSeriesType } from '../core/semantic-types';\nimport { ChartPropertyDef } from '../core/types';\n\nexport interface GanttRow {\n    task: string;\n    start: number;\n    end: number;\n    inputIndex: number;\n}\n\nexport const GANTT_PROPERTIES: ChartPropertyDef[] = [\n    { key: 'taskHeight', label: 'Task height', type: 'continuous', min: 40, max: 90, step: 5, defaultValue: 70 },\n    { key: 'cornerRadius', label: 'Corners', type: 'continuous', min: 0, max: 8, step: 1, defaultValue: 2 },\n    { key: 'intervalLabels', label: 'Labels', type: 'binary', defaultValue: false },\n];\n\nexport function sortGanttRows<T extends GanttRow>(rows: T[]): T[] {\n    return [...rows].sort((a, b) => (a.start - b.start) || (a.inputIndex - b.inputIndex));\n}\n\nexport function coerceGanttEndpoint(value: unknown, temporal: boolean): number {\n    if (value == null) return NaN;\n    if (!temporal) return Number(value);\n    if (value instanceof Date) return value.getTime();\n    if (typeof value === 'number') return Math.abs(value) < 1e11 ? value * 1000 : value;\n    return Date.parse(String(value));\n}\n\nexport function isGanttTemporal(\n    resolvedType: unknown,\n    semanticType: string | SemanticAnnotation | undefined,\n): boolean {\n    if (resolvedType === 'temporal') return true;\n    const typeName = toTypeString(semanticType);\n    return typeName ? isTimeSeriesType(typeName) : false;\n}\n\nfunction compactNumber(value: number): string {\n    return Number.isInteger(value) ? String(value) : String(Number(value.toFixed(2)));\n}\n\nconst GANTT_DURATION_UNITS = [\n    { minimumMs: 86_400_000, divisorMs: 86_400_000, suffix: 'd' },\n    { minimumMs: 3_600_000, divisorMs: 3_600_000, suffix: 'h' },\n    { minimumMs: 60_000, divisorMs: 60_000, suffix: 'min' },\n    { minimumMs: 1_000, divisorMs: 1_000, suffix: 's' },\n    { minimumMs: 0, divisorMs: 1, suffix: 'ms' },\n] as const;\n\nexport function formatGanttDuration(durationMs: number): string {\n    const unit = GANTT_DURATION_UNITS.find(({ minimumMs }) => Math.abs(durationMs) >= minimumMs)!;\n    return `${compactNumber(durationMs / unit.divisorMs)}${unit.suffix}`;\n}\n\nexport function ganttDurationLabelExpression(start: string, end: string, temporal: boolean): string {\n    const startValue = `datum[${JSON.stringify(start)}]`;\n    const endValue = `datum[${JSON.stringify(end)}]`;\n    if (!temporal) return `format(${endValue} - ${startValue}, ',.2~f')`;\n\n    const duration = `(toDate(${endValue}) - toDate(${startValue}))`;\n    return GANTT_DURATION_UNITS.reduceRight((fallback, unit, index) => {\n        const label = `format(${duration} / ${unit.divisorMs}, '.2~f') + '${unit.suffix}'`;\n        return index === GANTT_DURATION_UNITS.length - 1\n            ? label\n            : `(abs(${duration}) >= ${unit.minimumMs} ? ${label} : ${fallback})`;\n    }, '');\n}\n\nexport function formatGanttLabel(\n    start: number,\n    end: number,\n    temporal: boolean,\n): string {\n    const duration = end - start;\n    if (!temporal) return compactNumber(duration);\n    return formatGanttDuration(duration);\n}\n\nexport function ganttLabelReservePx(rows: Pick<GanttRow, 'start' | 'end'>[], temporal: boolean): number {\n    const maxCharacters = rows.reduce((max, row) => (\n        Math.max(max, formatGanttLabel(row.start, row.end, temporal).length)\n    ), 0);\n    return Math.max(40, maxCharacters * 7 + 10);\n}","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Gantt Chart — one horizontal floating bar per task, spanning\n * [start, end] (mirror vegalite/templates/gantt.ts).\n *\n * Channels:\n *   - y      task / activity label (the category axis)\n *   - x      start of the interval (temporal or quantitative)\n *   - x2     end of the interval (shares x's scale)\n *   - color  optional grouping (phase, owner, resource)\n *\n * Chart.js bars accept a `[start, end]` tuple natively (floating bars), so a\n * Gantt is a horizontal bar (`indexAxis: 'y'`) whose data are the intervals.\n * Tasks are sorted by start so the timeline reads chronologically top-to-bottom\n * (Chart.js draws category index 0 at the top of a horizontal bar). Temporal\n * intervals are positioned on a linear epoch-ms axis with a date tick callback,\n * avoiding a date-adapter dependency.\n */\n\nimport { ChartTemplateDef } from '../../core/types';\nimport {\n    coerceGanttEndpoint,\n    formatGanttLabel,\n    ganttLabelReservePx,\n    GANTT_PROPERTIES,\n    isGanttTemporal,\n    sortGanttRows,\n} from '../../chart-types/gantt';\nimport { DEFAULT_COLORS, DEFAULT_BG_COLORS } from './utils';\n\nfunction fmtDate(ms: number): string {\n    if (!Number.isFinite(ms)) return '';\n    return new Date(ms).toISOString().slice(0, 10);\n}\n\nexport const cjsGanttChartDef: ChartTemplateDef = {\n    chart: 'Gantt Chart',\n    template: { mark: 'bar', encoding: {} },\n    channels: ['y', 'x', 'x2', 'color', 'column', 'row'],\n    markCognitiveChannel: 'position',\n    declareLayoutMode: () => ({ axisFlags: { y: { banded: true } } }),\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table, chartProperties, semanticTypes } = ctx;\n        const taskField = channelSemantics.y?.field;\n        const startField = channelSemantics.x?.field;\n        const endField = channelSemantics.x2?.field;\n        const colorField = channelSemantics.color?.field;\n        if (!taskField || !startField || !endField || table.length === 0) return;\n\n        const temporal = isGanttTemporal(channelSemantics.x?.type, semanticTypes[startField]);\n        const num = (v: unknown) => coerceGanttEndpoint(v, temporal);\n\n        const rows = sortGanttRows(table\n            .map((r: any, inputIndex: number) => ({\n                task: String(r[taskField] ?? ''),\n                start: num(r[startField]),\n                end: num(r[endField]),\n                group: colorField != null ? String(r[colorField] ?? '') : undefined,\n                inputIndex,\n            }))\n            .filter((r) => r.task && Number.isFinite(r.start) && Number.isFinite(r.end)));\n        const taskHeight = chartProperties?.taskHeight ?? 70;\n        const cornerRadius = chartProperties?.cornerRadius ?? 2;\n        const intervalLabels = chartProperties?.intervalLabels === true;\n        const labelReserve = ganttLabelReservePx(rows, temporal);\n\n        const groups = colorField\n            ? Array.from(new Set(rows.map((r) => r.group ?? '')))\n            : [];\n        const groupIndex = new Map<string, number>();\n        groups.forEach((g, i) => groupIndex.set(g, i));\n\n        const colorFor = (group: string | undefined): { bg: string; border: string } => {\n            const i = group != null ? (groupIndex.get(group) ?? 0) : 0;\n            return {\n                bg: DEFAULT_BG_COLORS[i % DEFAULT_BG_COLORS.length],\n                border: DEFAULT_COLORS[i % DEFAULT_COLORS.length],\n            };\n        };\n\n        const labels = rows.map((r) => r.task);\n        const data = rows.map((r) => [r.start, r.end] as [number, number]);\n        const bg = rows.map((r) => colorFor(r.group).bg);\n        const border = rows.map((r) => colorFor(r.group).border);\n\n        const config: any = {\n            type: 'bar',\n            data: {\n                labels,\n                datasets: [{\n                    label: taskField,\n                    data,\n                    backgroundColor: bg,\n                    borderColor: border,\n                    borderWidth: 1,\n                    borderRadius: cornerRadius,\n                    borderSkipped: false,\n                    barPercentage: taskHeight / 100,\n                }],\n            },\n            options: {\n                indexAxis: 'y',\n                responsive: true,\n                maintainAspectRatio: false,\n                ...(intervalLabels\n                    ? { layout: { padding: { right: labelReserve } } }\n                    : {}),\n                scales: {\n                    x: {\n                        beginAtZero: false,\n                        title: { display: !temporal, text: startField },\n                        ...(temporal\n                            ? { ticks: { callback: (v: number) => fmtDate(Number(v)) } }\n                            : {}),\n                    },\n                    y: { title: { display: false } },\n                },\n                plugins: {\n                    legend: colorField && groups.length > 1\n                        ? {\n                            display: true,\n                            labels: {\n                                generateLabels: () => groups.map((g) => {\n                                    const c = colorFor(g);\n                                    return {\n                                        text: g,\n                                        fillStyle: c.bg,\n                                        strokeStyle: c.border,\n                                        lineWidth: 1,\n                                    };\n                                }),\n                            },\n                        }\n                        : { display: false },\n                    tooltip: {\n                        callbacks: {\n                            label: (item: any) => {\n                                const [s, e] = item.raw as [number, number];\n                                const fs = temporal ? fmtDate(s) : s;\n                                const fe = temporal ? fmtDate(e) : e;\n                                return `${fs} → ${fe}`;\n                            },\n                        },\n                    },\n                },\n            },\n        };\n\n        if (intervalLabels) {\n            config.plugins = [{\n                id: 'ganttLabels',\n                afterDatasetsDraw: (chart: any) => {\n                    const { ctx: canvasContext } = chart;\n                    canvasContext.save();\n                    canvasContext.fillStyle = '#333333';\n                    canvasContext.font = '10px sans-serif';\n                    canvasContext.textAlign = 'left';\n                    canvasContext.textBaseline = 'middle';\n                    chart.getDatasetMeta(0).data.forEach((bar: any, index: number) => {\n                        const row = rows[index];\n                        if (!row) return;\n                        canvasContext.fillText(\n                            formatGanttLabel(row.start, row.end, temporal),\n                            bar.x + 4,\n                            bar.y,\n                        );\n                    });\n                    canvasContext.restore();\n                },\n            }];\n        }\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n    properties: GANTT_PROPERTIES,\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Shared waterfall \"totals\" semantics, used by every backend template\n * (Vega-Lite / ECharts / Chart.js) and by the `totals` property `check` so the\n * options UI and the rendered chart never disagree on the default.\n *\n * A waterfall bar is either a *delta* (floats off the running cumulative) or a\n * *total* (anchored at zero, \"touches down\" to the running cumulative). When\n * the data has no explicit type column, Flint infers which ends are totals.\n * The user's `totals` property is purely an *override* of that inference.\n */\n\nexport type WaterfallTotalsMode = 'none' | 'first' | 'last' | 'both';\n\n/**\n * True when the final value reconciles with the running cumulative of every\n * prior row — i.e. the last row reads like a genuine grand-total restatement\n * (`last ≈ Σ prior`). Tolerance is relative (0.5% of the cumulative) with a\n * tiny absolute floor for near-zero totals. Non-finite values never reconcile.\n */\nexport function waterfallLastReconciles(values: number[]): boolean {\n    if (values.length < 2) return false;\n    let cumPrev = 0;\n    for (let i = 0; i < values.length - 1; i++) {\n        if (!Number.isFinite(values[i])) return false;\n        cumPrev += values[i];\n    }\n    const last = values[values.length - 1];\n    if (!Number.isFinite(last)) return false;\n    const tol = Math.max(1e-6, 0.005 * Math.abs(cumPrev));\n    return Math.abs(last - cumPrev) <= tol;\n}\n\n/**\n * The compiler's inferred default when the user hasn't set `totals` and there\n * is no explicit type column. The first bar is always a reasonable start total;\n * the last bar is only treated as a total when it reconciles with the prior\n * cumulative — otherwise it stays a floating delta.\n */\nexport function recommendedTotalsMode(values: number[]): 'first' | 'both' {\n    return waterfallLastReconciles(values) ? 'both' : 'first';\n}\n\n/**\n * Resolve the effective totals mode: a valid explicit user value wins;\n * anything else (undefined, or the UI default 'auto') falls back to the\n * data-aware recommendation.\n */\nexport function resolveTotalsMode(values: number[], explicit?: unknown): WaterfallTotalsMode {\n    if (explicit === 'none' || explicit === 'first' || explicit === 'last' || explicit === 'both') {\n        return explicit;\n    }\n    return recommendedTotalsMode(values);\n}","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js Waterfall Chart — cumulative bars with start / delta / end\n * (mirror vegalite/templates/waterfall.ts and echarts/templates/waterfall.ts).\n *\n * Channels:\n *   - x      category / step label (the banded axis)\n *   - y      signed amount for the step\n *   - color  optional explicit type column (start / increase / decrease / end)\n *\n * Each bar floats between the running total before and after its step, which\n * Chart.js expresses natively as a `[base, top]` bar value. The first and last\n * bars are anchored at zero (totals); the middle bars float from the previous\n * cumulative value. Bars are colored start/end blue, increase green, decrease\n * red.\n */\n\nimport { ChartTemplateDef } from '../../core/types';\nimport { resolveTotalsMode } from '../../chart-types/waterfall';\nimport { extractCategories } from './utils';\n\nconst COLOR = {\n    startEnd: { bg: 'rgba(84, 112, 198, 0.65)', border: 'rgba(84, 112, 198, 1)' },\n    increase: { bg: 'rgba(145, 204, 117, 0.65)', border: 'rgba(145, 204, 117, 1)' },\n    decrease: { bg: 'rgba(238, 102, 102, 0.65)', border: 'rgba(238, 102, 102, 1)' },\n};\n\nexport const cjsWaterfallChartDef: ChartTemplateDef = {\n    chart: 'Waterfall Chart',\n    template: { mark: 'bar', encoding: {} },\n    channels: ['x', 'y', 'color', 'column', 'row'],\n    markCognitiveChannel: 'length',\n    declareLayoutMode: () => ({ axisFlags: { x: { banded: true } } }),\n    instantiate: (spec, ctx) => {\n        const { channelSemantics, table } = ctx;\n        const catField = channelSemantics.x?.field;\n        const valField = channelSemantics.y?.field;\n        const colorField = channelSemantics.color?.field;\n        if (!catField || !valField || table.length === 0) return;\n\n        const categories = extractCategories(table, catField, channelSemantics.x?.ordinalSortOrder);\n        const rows = categories\n            .map((cat) => table.find((r: any) => String(r[catField]) === cat))\n            .filter(Boolean) as any[];\n        const values = rows.map((r) => Number(r[valField]) || 0);\n\n        // Data-aware totals default (see chart-types/waterfall.ts): first is a start\n        // total, last is a total only when it reconciles with the prior\n        // cumulative. The user's `totals` property overrides this; an explicit\n        // color/type column is authoritative. Mirror vegalite/echarts templates.\n        const totalsMode = resolveTotalsMode(values, ctx.chartProperties?.totals);\n        const wantFirst = totalsMode === 'first' || totalsMode === 'both';\n        const wantLast = totalsMode === 'last' || totalsMode === 'both';\n        const types: string[] = colorField\n            ? rows.map((r) => String(r[colorField] ?? 'delta'))\n            : values.map((_, i) =>\n                wantFirst && i === 0 ? 'start'\n                    : wantLast && i === values.length - 1 ? 'end'\n                        : 'delta');\n\n        // Cumulative running total including the current row.\n        const cumulative: number[] = [];\n        let acc = 0;\n        for (const v of values) { acc += v; cumulative.push(acc); }\n\n        const data: Array<[number, number]> = [];\n        const bg: string[] = [];\n        const border: string[] = [];\n        for (let i = 0; i < values.length; i++) {\n            const v = values[i];\n            const t = types[i];\n            const isTotal = t === 'start' || t === 'end';\n            const top = t === 'end' ? cumulative[i] - v : cumulative[i];\n            const prev = isTotal ? 0 : cumulative[i] - v;\n            const lo = Math.min(prev, top);\n            const hi = Math.max(prev, top);\n            data.push([lo, hi]);\n            const c = isTotal ? COLOR.startEnd : top >= prev ? COLOR.increase : COLOR.decrease;\n            bg.push(c.bg);\n            border.push(c.border);\n        }\n\n        const legendItems = [\n            { text: 'Start/End', color: COLOR.startEnd },\n            { text: 'Increase', color: COLOR.increase },\n            { text: 'Decrease', color: COLOR.decrease },\n        ];\n\n        const config: any = {\n            type: 'bar',\n            data: {\n                labels: categories,\n                datasets: [{\n                    label: valField,\n                    data,\n                    backgroundColor: bg,\n                    borderColor: border,\n                    borderWidth: 1,\n                    borderSkipped: false,\n                }],\n            },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: {\n                    x: { title: { display: true, text: catField } },\n                    y: { beginAtZero: true, title: { display: true, text: valField } },\n                },\n                plugins: {\n                    legend: {\n                        display: true,\n                        labels: {\n                            generateLabels: () => legendItems.map((it) => ({\n                                text: it.text,\n                                fillStyle: it.color.bg,\n                                strokeStyle: it.color.border,\n                                lineWidth: 1,\n                            })),\n                        },\n                    },\n                    tooltip: {\n                        callbacks: {\n                            label: (item: any) => {\n                                const [lo, hi] = item.raw as [number, number];\n                                return `${valField}: ${Math.round((hi - lo) * 100) / 100}`;\n                            },\n                        },\n                    },\n                },\n            },\n        };\n\n        Object.assign(spec, config);\n        delete spec.mark;\n        delete spec.encoding;\n    },\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js template registry.\n *\n * Mirrors the structure of echarts/templates/index.ts and\n * vegalite/templates/index.ts but with Chart.js template definitions.\n */\n\nimport { ChartTemplateDef } from '../../core/types';\nimport { cjsScatterPlotDef } from './scatter';\nimport { cjsConnectedScatterDef } from './connected-scatter';\nimport { cjsBubbleChartDef } from './bubble';\nimport { cjsStripPlotDef } from './jitter';\nimport { cjsBarChartDef, cjsStackedBarChartDef, cjsGroupedBarChartDef } from './bar';\nimport { cjsComboChartDef } from './combo';\nimport { cjsLineChartDef } from './line';\nimport { cjsBumpChartDef } from './bump';\nimport { cjsSlopeChartDef } from './slope';\nimport { cjsAreaChartDef } from './area';\nimport { cjsRangeAreaChartDef } from './range-area';\nimport { cjsPieChartDef } from './pie';\nimport { cjsDoughnutChartDef } from './doughnut';\nimport { cjsHistogramDef } from './histogram';\nimport { cjsEcdfPlotDef } from './ecdf';\nimport { cjsRadarChartDef } from './radar';\nimport { cjsRoseChartDef } from './rose';\nimport { cjsGanttChartDef } from './gantt';\nimport { cjsWaterfallChartDef } from './waterfall';\n\n/**\n * Chart.js chart template definitions, grouped by category.\n */\nexport const cjsTemplateDefs: { [key: string]: ChartTemplateDef[] } = {\n    'Scatter & Point': [cjsScatterPlotDef, cjsConnectedScatterDef, cjsBubbleChartDef, cjsStripPlotDef],\n    'Bar':             [cjsBarChartDef, cjsGroupedBarChartDef, cjsStackedBarChartDef, cjsComboChartDef, cjsHistogramDef, cjsWaterfallChartDef, cjsGanttChartDef],\n    'Line & Area':     [cjsLineChartDef, cjsBumpChartDef, cjsSlopeChartDef, cjsAreaChartDef, cjsRangeAreaChartDef, cjsEcdfPlotDef],\n    'Part-to-Whole':   [cjsPieChartDef, cjsDoughnutChartDef],\n    'Polar':           [cjsRadarChartDef, cjsRoseChartDef],\n};\n\n/**\n * Flat list of all Chart.js chart template definitions.\n */\nexport const cjsAllTemplateDefs: ChartTemplateDef[] = Object.values(cjsTemplateDefs).flat();\n\n/**\n * Look up a Chart.js chart template definition by chart type name.\n */\nexport function cjsGetTemplateDef(chartType: string): ChartTemplateDef | undefined {\n    return cjsAllTemplateDefs.find(t => t.chart === chartType);\n}\n\n/**\n * Get the available channels for a Chart.js chart type.\n */\nexport function cjsGetTemplateChannels(chartType: string): string[] {\n    return cjsGetTemplateDef(chartType)?.channels || [];\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * =============================================================================\n * REUSABLE DECISION LOGIC\n * =============================================================================\n *\n * Pure decision functions that determine chart layout behavior.\n * These functions take data/config inputs and return decision objects —\n * NO Vega-Lite spec mutation happens here.\n *\n * The separation ensures:\n * 1. Decision logic is testable in isolation\n * 2. Same decisions can drive different output formats (VL, SVG, etc.)\n * 3. Templates can call decision functions without coupling to VL\n *\n * Naming conventions:\n *   - `compute*()` — returns a decision/value from inputs\n *   - `resolve*()` — picks from alternatives (type resolution, etc.)\n *   - `classify*()` — categorizes an input\n * =============================================================================\n */\n\nimport {\n    inferVisCategory,\n    type VisCategory,\n} from './semantic-types';\nimport { getRegistryEntry, isRegistered } from './type-registry';\n\n// ---------------------------------------------------------------------------\n// Encoding Type Resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Result of encoding type resolution.\n * Separates the decision from what gets written into VL.\n */\nexport interface EncodingTypeDecision {\n    /** The resolved VL encoding type */\n    vlType: 'quantitative' | 'ordinal' | 'nominal' | 'temporal';\n    /** The VisCategory that drove the decision */\n    visCategory: VisCategory;\n    /** Whether the type was overridden by channel rules */\n    channelOverride: boolean;\n    /** Whether the type was overridden by cardinality/fraction guard */\n    cardinalityGuard: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers for encoding type resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Map a VisCategory to the corresponding VL encoding type string.\n * Geographic maps to quantitative since VL uses quantitative for coordinates.\n */\nfunction visCategoryToVLType(vc: VisCategory): 'quantitative' | 'ordinal' | 'nominal' | 'temporal' {\n    switch (vc) {\n        case 'quantitative': return 'quantitative';\n        case 'ordinal': return 'ordinal';\n        case 'temporal': return 'temporal';\n        case 'geographic': return 'quantitative';\n        case 'nominal':\n        default: return 'nominal';\n    }\n}\n\n/**\n * Validate that field values actually parse as dates.\n *\n * @param fromRegistry  If true, uses a looser threshold (≥30%) since the\n *                      semantic type explicitly identified the field as temporal.\n *                      If false (data-inferred), requires ≥50%.\n */\nfunction validateTemporalParsing(\n    data: any[],\n    fieldName: string,\n    fromRegistry: boolean,\n): boolean {\n    const sampleValues = data.map(r => r[fieldName]).slice(0, 15).filter((v: any) => v != null);\n    if (sampleValues.length === 0) return false;\n\n    // Single unique value → not useful as temporal axis (would show a single point)\n    const uniqueValues = new Set(sampleValues.map(String));\n    if (uniqueValues.size <= 1) return false;\n\n    const looksTemporalValue = (val: any): boolean => {\n        if (val instanceof Date) return true;\n        if (typeof val === 'number') {\n            // Year-like integers (1500–2200)\n            if (val >= 1500 && val <= 2200 && val % 1 === 0) return true;\n            // Unix-ms timestamps: 86_400_000 (Jan 2, 1970) to ~year 2103\n            if (val > 86400000 && val < 4200000000000) return true;\n            return false;\n        }\n        if (typeof val === 'string') {\n            const trimmed = val.trim();\n            if (!trimmed) return false;\n            if (/^\\d{4}$/.test(trimmed)) return true;\n            return !Number.isNaN(Date.parse(trimmed));\n        }\n        return false;\n    };\n\n    const passingCount = sampleValues.filter(looksTemporalValue).length;\n    const minFraction = fromRegistry ? 0.3 : 0.5;\n    return passingCount / sampleValues.length >= minFraction;\n}\n\n/**\n * Apply temporal channel-compatibility adjustments, shared by both\n * registry-driven and data-inferred temporal paths.\n */\nfunction resolveTemporalEncoding(\n    visCategory: VisCategory,\n    channel: string,\n    data: any[],\n    fieldName: string,\n    fromRegistry: boolean,\n): EncodingTypeDecision {\n    // Temporal on facet/size channels → ordinal (VL limitation)\n    if (['size', 'column', 'row'].includes(channel)) {\n        return { vlType: 'ordinal', visCategory, channelOverride: true, cardinalityGuard: false };\n    }\n    // Temporal on color with low cardinality → ordinal for distinct colors\n    if (channel === 'color') {\n        const uniqueCount = new Set(data.map(r => r[fieldName])).size;\n        if (uniqueCount <= 12) {\n            return { vlType: 'ordinal', visCategory, channelOverride: true, cardinalityGuard: false };\n        }\n    }\n    // Validate temporal parsing\n    if (!validateTemporalParsing(data, fieldName, fromRegistry)) {\n        return { vlType: 'ordinal', visCategory, channelOverride: false, cardinalityGuard: false };\n    }\n    return { vlType: 'temporal', visCategory, channelOverride: false, cardinalityGuard: false };\n}\n\n/**\n * Apply channel-context guards to an ordinal encoding.\n *\n * Even when the registry says a field is ordinal, channel context may\n * require promoting to quantitative:\n *   - High cardinality on color/group → unreadable legend\n *   - High cardinality on x/y        → bars/lollipops need proportional\n *     spacing and baseline anchoring (y2/x2)\n *   - Fractional values + high cardinality → mis-classified continuous measure\n *\n * @param fromRegistry  Whether the ordinal type came from the registry\n *        (true) or was data-inferred (false). Data-inferred additionally\n *        checks for fractional values (Guard 1).\n */\nfunction applyOrdinalGuards(\n    visCategory: VisCategory,\n    channel: string,\n    data: any[],\n    fieldName: string,\n    fieldValues: any[],\n    fromRegistry: boolean,\n): EncodingTypeDecision {\n    const numericVals = fieldValues.filter(v => v != null && !isNaN(+v)).map(Number);\n    if (numericVals.length > 0) {\n        const uniqueCount = new Set(numericVals).size;\n        const hasFractions = numericVals.some(v => v % 1 !== 0);\n\n        // Guard 1 (data-inferred only): fractional + high-cardinality →\n        // mis-classified continuous measure. Registry types are explicit,\n        // so this guard only applies when the type was inferred from data.\n        if (!fromRegistry && hasFractions && uniqueCount > 20) {\n            return { vlType: 'quantitative', visCategory, channelOverride: false, cardinalityGuard: true };\n        }\n\n        // Guard 2: integer ordinal with high cardinality on color/group →\n        // a discrete legend with 12+ entries is unreadable; promote to\n        // quantitative so VL renders a continuous gradient instead.\n        if (!hasFractions && uniqueCount > 12 && ['color', 'group'].includes(channel)) {\n            return { vlType: 'quantitative', visCategory, channelOverride: true, cardinalityGuard: true };\n        }\n\n        // Guard 3: integer ordinal with high cardinality on position\n        // axes (x, y) → charts like bar/lollipop need a quantitative\n        // axis for proportional length; treating 12+ unique integers\n        // as discrete categories produces an unreadable axis and\n        // prevents baseline anchoring (y2/x2).\n        if (!hasFractions && uniqueCount > 12 && ['x', 'y'].includes(channel)) {\n            return { vlType: 'quantitative', visCategory, channelOverride: true, cardinalityGuard: true };\n        }\n    }\n    return { vlType: 'ordinal', visCategory, channelOverride: false, cardinalityGuard: false };\n}\n\n/**\n * Disambiguate when the registry lists multiple visEncodings for a type.\n *\n * Uses channel context and data characteristics to select the most\n * appropriate encoding from the candidates. Each combination of\n * candidate encodings has dedicated logic:\n *\n *   temporal + ordinal  (Year, YearMonth, Decade, …)\n *   quantitative + ordinal  (Score, Rating)\n *   quantitative + geographic  (Latitude, Longitude)\n *   ordinal + nominal  (Direction)\n */\nfunction disambiguateMultiEncoding(\n    candidates: VisCategory[],\n    channel: string,\n    data: any[],\n    fieldName: string,\n    fieldValues: any[],\n): EncodingTypeDecision {\n    const has = (vc: VisCategory) => candidates.includes(vc);\n\n    // ── Temporal + Ordinal (Year, YearMonth, Decade, etc.) ────────\n    // Time-unit granules. Temporal for continuous time axes (x/y);\n    // ordinal for grouping channels (color, facet, size).\n    if (has('temporal') && has('ordinal')) {\n        return resolveTemporalEncoding('temporal', channel, data, fieldName, true);\n    }\n\n    // ── Quantitative + Ordinal (Score, Rating) ────────────────────\n    // Bounded discrete numerics. Use ordinal for grouping channels\n    // with low cardinality (distinct colors/symbols); quantitative\n    // for position axes (proportional spacing, zero-baseline).\n    if (has('quantitative') && has('ordinal')) {\n        if (['color', 'group'].includes(channel)) {\n            const uniqueCount = new Set(data.map(r => r[fieldName])).size;\n            if (uniqueCount <= 12) {\n                return { vlType: 'ordinal', visCategory: 'ordinal', channelOverride: false, cardinalityGuard: false };\n            }\n            // High-cardinality Score/Rating on color → quantitative gradient\n            return { vlType: 'quantitative', visCategory: 'quantitative', channelOverride: false, cardinalityGuard: true };\n        }\n        if (['column', 'row'].includes(channel)) {\n            return { vlType: 'ordinal', visCategory: 'ordinal', channelOverride: false, cardinalityGuard: false };\n        }\n        // x, y, size → quantitative (proportional axis)\n        return { vlType: 'quantitative', visCategory: 'quantitative', channelOverride: false, cardinalityGuard: false };\n    }\n\n    // ── Quantitative + Geographic (Latitude, Longitude) ───────────\n    // Geographic is for map projections; standard encodings use quantitative.\n    if (has('quantitative') && has('geographic')) {\n        return { vlType: 'quantitative', visCategory: 'quantitative', channelOverride: false, cardinalityGuard: false };\n    }\n\n    // ── Ordinal + Nominal (Direction) ─────────────────────────────\n    // Inherently ordered, but nominal for grouping channels to get\n    // distinct (unordered) colors rather than a sequential scale.\n    if (has('ordinal') && has('nominal')) {\n        if (['color', 'group'].includes(channel)) {\n            return { vlType: 'nominal', visCategory: 'nominal', channelOverride: false, cardinalityGuard: false };\n        }\n        return { vlType: 'ordinal', visCategory: 'ordinal', channelOverride: false, cardinalityGuard: false };\n    }\n\n    // ── Fallback: first candidate ─────────────────────────────────\n    const fallback = candidates[0];\n    return { vlType: visCategoryToVLType(fallback), visCategory: fallback, channelOverride: false, cardinalityGuard: false };\n}\n\n// ---------------------------------------------------------------------------\n// Main API\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the VL encoding type for a field.\n *\n * Two-stage pipeline:\n *\n * **Stage 1 — Registry-driven** (when semanticType is registered):\n *   - Single visEncoding  → use it directly (with channel adjustments)\n *   - Multiple visEncodings → `disambiguateMultiEncoding()` selects best\n *     option using channel context + data characteristics\n *\n * **Stage 2 — Data-inferred fallback** (no registered semantic type):\n *   - `inferVisCategory()` inspects raw values → VisCategory\n *   - Heuristic guards catch common mis-classifications (e.g., dense\n *     fractional data inferred as ordinal)\n *\n * This is a pure decision — it does NOT mutate any spec.\n *\n * @param semanticType   Semantic type string (e.g. 'Quantity', 'Country')\n * @param fieldValues    Sampled values from the field\n * @param channel        VL channel name (e.g. 'x', 'y', 'color')\n * @param data           Full data table (for computing unique value counts)\n * @param fieldName      Field name (for data lookups)\n */\nexport function resolveEncodingType(\n    semanticType: string,\n    fieldValues: any[],\n    channel: string,\n    data: any[],\n    fieldName: string,\n): EncodingTypeDecision {\n    // ═══════════════════════════════════════════════════════════════════\n    // Stage 1: Registry-driven resolution\n    // ═══════════════════════════════════════════════════════════════════\n    // The registry's visEncodings array is the source of truth.\n    //   - Single encoding  → resolved directly\n    //   - Multiple encodings → disambiguated by channel + data\n    if (semanticType && isRegistered(semanticType)) {\n        const entry = getRegistryEntry(semanticType);\n        const candidates = entry.visEncodings;\n\n        if (candidates.length > 1) {\n            // Multiple encodings listed — disambiguate semantically\n            return disambiguateMultiEncoding(candidates, channel, data, fieldName, fieldValues);\n        }\n\n        // Single encoding — use it directly with channel adjustments\n        const baseType = candidates[0];\n\n        // Guard: if the registry says quantitative but the actual values\n        // are strings (e.g. semantic \"Quantity\" on a binned field like\n        // \"91-95\"), fall back to data-inferred type.  Numeric strings\n        // that parse as numbers (e.g. \"42\") still count as numeric.\n        if (baseType === 'quantitative') {\n            const nonNull = fieldValues.filter(v => v != null);\n            const allNumeric = nonNull.length > 0 &&\n                nonNull.every(v => typeof v === 'number' || (typeof v === 'string' && !isNaN(+v) && v.trim() !== ''));\n            if (!allNumeric) {\n                // Values aren't actually numeric — infer from data instead\n                const inferred = inferVisCategory(fieldValues);\n                return {\n                    vlType: visCategoryToVLType(inferred),\n                    visCategory: inferred,\n                    channelOverride: false,\n                    cardinalityGuard: false,\n                };\n            }\n        }\n\n        if (baseType === 'temporal') {\n            return resolveTemporalEncoding(baseType, channel, data, fieldName, true);\n        }\n        if (baseType === 'ordinal') {\n            return applyOrdinalGuards(baseType, channel, data, fieldName, fieldValues, true);\n        }\n        return {\n            vlType: visCategoryToVLType(baseType),\n            visCategory: baseType,\n            channelOverride: false,\n            cardinalityGuard: false,\n        };\n    }\n\n    // ═══════════════════════════════════════════════════════════════════\n    // Stage 2: Data-inferred fallback\n    // ═══════════════════════════════════════════════════════════════════\n    // No registered semantic type — infer from raw data values, then\n    // apply heuristic guards for common data-inference mis-classifications.\n    const visCategory: VisCategory = inferVisCategory(fieldValues);\n    const channelOverride = false;\n    const cardinalityGuard = false;\n\n    switch (visCategory) {\n        case 'temporal':\n            return resolveTemporalEncoding(visCategory, channel, data, fieldName, false);\n\n        case 'ordinal':\n            return applyOrdinalGuards(visCategory, channel, data, fieldName, fieldValues, false);\n\n        case 'quantitative':\n            return { vlType: 'quantitative', visCategory, channelOverride, cardinalityGuard };\n\n        case 'geographic':\n            return { vlType: 'quantitative', visCategory, channelOverride, cardinalityGuard };\n\n        case 'nominal':\n        default:\n            return { vlType: 'nominal', visCategory, channelOverride, cardinalityGuard };\n    }\n}\n\n// ---------------------------------------------------------------------------\n// Continuous Axis Gas Pressure Model (docs/design-stretch-model.md §2)\n// ---------------------------------------------------------------------------\n\n/**\n * Parameters for the per-axis stretch model (docs/design-stretch-model.md §2).\n *\n * Each axis is stretched independently based on how many distinguishable\n * positions (or series) compete for pixel space along that axis.\n */\nexport interface GasPressureParams {\n    /** Mark cross-section in px² — used as default σ for both axes (default: 30) */\n    markCrossSection: number;\n    /** Per-axis cross-section overrides. When set, the per-axis stretch\n     *  uses these instead of `markCrossSection`.\n     *  Useful for line charts where X needs more stretch than Y. */\n    markCrossSectionX?: number;\n    markCrossSectionY?: number;\n    /** Override X item count for stretch.\n     *  When set, X stretch uses this count (e.g. number of series)\n     *  instead of counting unique X pixel positions. */\n    xItemCountOverride?: number;\n    /** Override Y item count for stretch.\n     *  When set, Y stretch uses this count (e.g. number of series)\n     *  instead of counting unique Y pixel positions. */\n    yItemCountOverride?: number;\n    /** Power-law exponent for continuous stretch (default: 0.3) */\n    elasticity: number;\n    /** Maximum stretch multiplier cap (default: 1.5) */\n    maxStretch: number;\n}\n\n/** Default gas pressure parameters (§2 recommendations). */\nexport const DEFAULT_GAS_PRESSURE_PARAMS: GasPressureParams = {\n    markCrossSection: 30,\n    elasticity: 0.3,\n    maxStretch: 1.5,\n};\n\n/**\n * Result of the per-axis stretch decision.\n */\nexport interface GasPressureDecision {\n    /** Per-axis stretch: X axis (1 = no stretch, capped by maxStretch) */\n    stretchX: number;\n    /** Per-axis stretch: Y axis (1 = no stretch, capped by maxStretch) */\n    stretchY: number;\n    /** Uncapped stretch for X (raw pressure^elasticity, not clipped to maxStretch).\n     *  Used by the layout engine to compute ideal aspect ratio before squeezing. */\n    rawStretchX: number;\n    /** Uncapped stretch for Y (raw pressure^elasticity, not clipped to maxStretch). */\n    rawStretchY: number;\n}\n\n/**\n * Compute per-axis stretch for a continuous 2D axis region.\n *\n * Implements docs/design-stretch-model.md §2: each axis is stretched independently based\n * on how many distinguishable positions (or series) compete for pixel\n * space along that axis.\n *\n * Two modes per axis:\n *   - Positional: count unique pixel positions, σ_1d = √σ.\n *   - Series-count: when xItemCountOverride / yItemCountOverride is set,\n *     use that count directly with σ (not sqrt'd) since it's already 1D.\n *\n * @param xValues      Numeric x-coordinates of data points\n * @param yValues      Numeric y-coordinates of data points\n * @param xDomain      Scale domain [min, max] for x-axis\n * @param yDomain      Scale domain [min, max] for y-axis\n * @param canvasWidth  Base canvas width W₀\n * @param canvasHeight Base canvas height H₀\n * @param params       Gas pressure parameters (optional, uses defaults)\n */\nexport function computeGasPressure(\n    xValues: number[],\n    yValues: number[],\n    xDomain: [number, number],\n    yDomain: [number, number],\n    canvasWidth: number,\n    canvasHeight: number,\n    params: GasPressureParams = DEFAULT_GAS_PRESSURE_PARAMS,\n): GasPressureDecision {\n    const N = xValues.length;\n\n    if (N <= 1 || canvasWidth <= 0 || canvasHeight <= 0) {\n        return { stretchX: 1, stretchY: 1, rawStretchX: 1, rawStretchY: 1 };\n    }\n\n    // Per-axis stretch via unique-position linear packing.\n    // The question for each axis is: \"how many distinguishable positions\n    // compete for pixel space along this axis?\"\n    //\n    // Count unique positions (bucketed to ~1px resolution) along each\n    // axis. Each unique position needs σ_1d ≈ √σ pixels of space.\n    // 1D pressure = uniquePositions × σ_1d / axisDimension.\n    const sigma1dDefault = Math.sqrt(params.markCrossSection); // ~5 px\n\n    /** Returns [cappedStretch, rawStretch] for one axis. */\n    const computeAxisStretch = (values: number[], domain: [number, number], baseDim: number, sigma1d: number): [number, number] => {\n        if (baseDim <= 0 || values.length <= 1) return [1, 1];\n\n        const range = domain[1] - domain[0];\n        if (range <= 0) return [1, 1];\n\n        // Bucket values to ~1px resolution in pixel space\n        const pxPerUnit = baseDim / range;\n        const seen = new Set<number>();\n        for (const v of values) {\n            seen.add(Math.round((v - domain[0]) * pxPerUnit));\n        }\n        const uniquePositions = seen.size;\n\n        // 1D pressure: how many sigma-sized marks fight for baseDim pixels\n        const pressure = (uniquePositions * sigma1d) / baseDim;\n        if (pressure <= 1) return [1, 1];\n        const raw = Math.pow(pressure, params.elasticity);\n        return [Math.min(params.maxStretch, raw), raw];\n    };\n\n    const sigma1dX = params.markCrossSectionX != null ? Math.sqrt(params.markCrossSectionX) : sigma1dDefault;\n    const sigma1dY = params.markCrossSectionY != null ? Math.sqrt(params.markCrossSectionY) : sigma1dDefault;\n\n    // Helper: compute stretch for one axis, using series-count override if set.\n    // When a series override is provided, σ is used directly (not sqrt'd)\n    // because series count is already a 1D concept.\n    /** Returns [cappedStretch, rawStretch] for one axis, with series-count override support. */\n    const computeStretchForAxis = (\n        values: number[], domain: [number, number], baseDim: number,\n        sigma1d: number, sigmaRaw: number, itemCountOverride?: number,\n    ): [number, number] => {\n        if (itemCountOverride != null && sigmaRaw > 0) {\n            const pressure = (itemCountOverride * sigmaRaw) / baseDim;\n            if (pressure <= 1) return [1, 1];\n            const raw = Math.pow(pressure, params.elasticity);\n            return [Math.min(params.maxStretch, raw), raw];\n        }\n        return sigma1d > 0 ? computeAxisStretch(values, domain, baseDim, sigma1d) : [1, 1];\n    };\n\n    const sigmaRawX = params.markCrossSectionX ?? params.markCrossSection;\n    const sigmaRawY = params.markCrossSectionY ?? params.markCrossSection;\n    const [stretchX, rawStretchX] = computeStretchForAxis(xValues, xDomain, canvasWidth, sigma1dX, sigmaRawX, params.xItemCountOverride);\n    const [stretchY, rawStretchY] = computeStretchForAxis(yValues, yDomain, canvasHeight, sigma1dY, sigmaRawY, params.yItemCountOverride);\n\n    return { stretchX, stretchY, rawStretchX, rawStretchY };\n}\n\n// ---------------------------------------------------------------------------\n// Elastic Stretch Computation\n// ---------------------------------------------------------------------------\n\n/**\n * Parameters for elastic axis stretch computation.\n * These control the spring-model behavior from docs/design-stretch-model.md §1.\n */\nexport interface ElasticStretchParams {\n    /** Power-law exponent for stretch (default: 0.5) */\n    elasticity: number;\n    /** Maximum stretch multiplier cap (default: 2) */\n    maxStretch: number;\n    /** Default step size in px per discrete item */\n    defaultStepSize: number;\n    /** Minimum pixels per discrete item (default: 6) */\n    minStep: number;\n}\n\n/**\n * Result of elastic budget computation for a single axis.\n */\nexport interface ElasticBudget {\n    /** Elastic-stretched canvas budget in px */\n    budget: number;\n    /** Stretch multiplier applied (1 = no stretch) */\n    stretchFactor: number;\n}\n\n/**\n * Compute the elastic canvas budget for an axis with N discrete items.\n *\n * When N items at defaultStepSize exceed the base dimension, the axis\n * stretches using a power-law: stretch = min(maxStretch, pressure^elasticity).\n *\n * @param itemCount       Number of discrete items on the axis\n * @param baseDimension   Base canvas size (width or height) in px\n * @param params          Elastic stretch parameters\n */\nexport function computeElasticBudget(\n    itemCount: number,\n    baseDimension: number,\n    params: ElasticStretchParams,\n): ElasticBudget {\n    if (itemCount <= 0) {\n        return { budget: baseDimension, stretchFactor: 1 };\n    }\n    const pressure = (itemCount * params.defaultStepSize) / baseDimension;\n    if (pressure <= 1) {\n        return { budget: baseDimension, stretchFactor: 1 };\n    }\n    const stretchFactor = Math.min(params.maxStretch, Math.pow(pressure, params.elasticity));\n    return {\n        budget: baseDimension * stretchFactor,\n        stretchFactor,\n    };\n}\n\n/**\n * Result of per-axis step computation.\n */\nexport interface AxisStepDecision {\n    /** Computed step size in px per item */\n    step: number;\n    /** Total canvas budget in px */\n    budget: number;\n    /** Number of items this step was computed for */\n    itemCount: number;\n}\n\n/**\n * Compute the step size for a single axis, covering both discrete\n * and continuous-as-discrete (banded) cases.\n *\n * @param nominalCount       Number of discrete (nominal/ordinal) items\n * @param continuousCount    Number of continuous-as-discrete items (banded Q/T)\n * @param baseDimension      Base canvas size (width or height) in px\n * @param params             Elastic stretch parameters\n */\nexport function computeAxisStep(\n    nominalCount: number,\n    continuousCount: number,\n    baseDimension: number,\n    params: ElasticStretchParams,\n): AxisStepDecision {\n    if (nominalCount > 0) {\n        const { budget } = computeElasticBudget(nominalCount, baseDimension, params);\n        return { step: Math.floor(budget / nominalCount), budget, itemCount: nominalCount };\n    }\n    if (continuousCount > 0) {\n        const { budget } = computeElasticBudget(continuousCount, baseDimension, params);\n        return { step: Math.floor(budget / continuousCount), budget, itemCount: continuousCount };\n    }\n    return { step: params.defaultStepSize, budget: baseDimension, itemCount: 0 };\n}\n\n// ---------------------------------------------------------------------------\n// Facet Layout Decisions\n// ---------------------------------------------------------------------------\n\n/**\n * Result of facet layout computation.\n */\nexport interface FacetLayoutDecision {\n    /** Number of facet columns */\n    columns: number;\n    /** Number of facet rows */\n    rows: number;\n    /** Per-subplot width in px */\n    subplotWidth: number;\n    /** Per-subplot height in px */\n    subplotHeight: number;\n}\n\n/**\n * Parameters for facet layout computation.\n */\nexport interface FacetLayoutParams {\n    /** Power-law exponent for facet stretch (default: 0.3) */\n    facetElasticity: number;\n    /** Maximum total stretch multiplier cap (default: 2) */\n    maxStretch: number;\n    /** Minimum subplot size in px (default: 60) */\n    minSubplotSize: number;\n}\n\n/**\n * Compute facet subplot dimensions.\n *\n * @param facetCols       Number of facet columns\n * @param facetRows       Number of facet rows\n * @param baseWidth       Base canvas width in px\n * @param baseHeight      Base canvas height in px\n * @param params          Facet layout parameters\n */\nexport function computeFacetLayout(\n    facetCols: number,\n    facetRows: number,\n    baseWidth: number,\n    baseHeight: number,\n    params: FacetLayoutParams,\n): FacetLayoutDecision {\n    // Minimum subplot dimension — use the caller-supplied parameter\n    // (default 60px) so subplots remain readable.\n    const minContinuousSize = params.minSubplotSize;\n\n    let subplotWidth: number;\n    if (facetCols > 1) {\n        const stretch = Math.min(params.maxStretch, Math.pow(facetCols, params.facetElasticity));\n        subplotWidth = Math.round(Math.max(minContinuousSize, baseWidth * stretch / facetCols));\n    } else {\n        subplotWidth = baseWidth;\n    }\n\n    let subplotHeight: number;\n    if (facetRows > 1) {\n        const stretch = Math.min(params.maxStretch, Math.pow(facetRows, params.facetElasticity));\n        subplotHeight = Math.round(Math.max(minContinuousSize, baseHeight * stretch / facetRows));\n    } else {\n        subplotHeight = baseHeight;\n    }\n\n    return { columns: facetCols, rows: facetRows, subplotWidth, subplotHeight };\n}\n\n// ---------------------------------------------------------------------------\n// Label Sizing Decisions\n// ---------------------------------------------------------------------------\n\n/**\n * Result of label sizing computation for a discrete axis.\n */\nexport interface LabelSizingDecision {\n    /** Font size in px */\n    fontSize: number;\n    /** Max label width in px */\n    labelLimit: number;\n    /** Label rotation angle (undefined = no rotation) */\n    labelAngle?: number;\n    /** Label alignment (for rotated labels) */\n    labelAlign?: string;\n    /** Label baseline (for rotated labels) */\n    labelBaseline?: string;\n}\n\n/**\n * Compute label sizing for a discrete axis based on the effective step size.\n * Pure decision — returns sizing params without modifying any spec.\n *\n * The font descends the **shrink → rotate → cap** ladder from a backend-native\n * base font (`baseFont`), never exceeding it and never dropping below `minFont`:\n *   1. Wide band  → horizontal label at (up to) `baseFont`.\n *   2. Medium band → shrink a little and rotate -45°.\n *   3. Narrow band → shrink more and rotate -90°.\n * `labelLimit` caps the label width so long text is truncated (…) rather than\n * overflowing arbitrarily.\n *\n * @param effectiveStep      Pixels per discrete item\n * @param hasDiscreteItems   Whether the axis has discrete items\n * @param opts               `baseFont` (native ceiling) and `minFont` (floor)\n */\nexport function computeLabelSizing(\n    effectiveStep: number,\n    hasDiscreteItems: boolean,\n    opts?: { baseFont?: number; minFont?: number },\n): LabelSizingDecision {\n    const baseFont = opts?.baseFont ?? 10;\n    const minFont = opts?.minFont ?? 6;\n    const defaultLimit = 100;\n\n    if (!hasDiscreteItems) {\n        return { fontSize: baseFont, labelLimit: defaultLimit };\n    }\n\n    // Shrink lever: font tracks the band step but is bounded by [minFont, baseFont].\n    let fontSize = Math.max(minFont, Math.min(baseFont, effectiveStep - 1));\n    let labelLimit = Math.max(30, Math.min(100, effectiveStep * 8));\n    let labelAngle: number | undefined;\n    let labelAlign: string | undefined;\n    let labelBaseline: string | undefined;\n\n    if (effectiveStep < 10) {\n        // Narrow band → rotate vertical, shrink harder (but keep the ceiling\n        // one notch below base so a 12-native backend still reads ~10 here).\n        labelAngle = -90;\n        fontSize = Math.max(minFont, Math.min(baseFont - 2, effectiveStep));\n        labelLimit = 40;\n        labelAlign = 'right';\n        labelBaseline = 'middle';\n    } else if (effectiveStep < 16) {\n        // Medium band → rotate 45°, shrink slightly.\n        labelAngle = -45;\n        fontSize = Math.max(minFont, Math.min(baseFont - 1, effectiveStep));\n        labelLimit = 60;\n        labelAlign = 'right';\n        labelBaseline = 'top';\n    }\n\n    return { fontSize, labelLimit, labelAngle, labelAlign, labelBaseline };\n}\n\n/**\n * Canvas-adaptive font sizes for headers (axis titles, legend, chart title) and\n * the base for axis tick labels.\n *\n * The per-backend base fonts are the preferred (native) sizes. Fonts render at\n * that base and only **shrink** for genuinely small small-multiple subplots\n * (so dense facets don't overflow); they are never grown above native, matching\n * how the underlying renderers keep fonts constant across canvas sizes.\n *\n * @param minPlotDimension  The smaller of the (sub)plot width/height in px\n * @param opts              Backend-native base font sizes\n */\nexport interface FontSizingDecision {\n    /** Ceiling for axis tick labels (feeds computeLabelSizing `baseFont`). */\n    tickBase: number;\n    /** Header font for axis titles and chart title. */\n    titleFontSize: number;\n    /** Legend entry font (one notch below the title). */\n    legendFontSize: number;\n}\n\nexport function computeFontSizing(\n    minPlotDimension: number,\n    opts?: { baseLabelFontSize?: number; baseTitleFontSize?: number },\n): FontSizingDecision {\n    const baseLabel = opts?.baseLabelFontSize ?? 10;\n    const baseTitle = opts?.baseTitleFontSize ?? 11;\n    // The per-backend base fonts ARE the preferred (native) sizes: native\n    // renderers (Plotly/VL/ECharts) keep tick/title/legend fonts CONSTANT at\n    // every canvas size. So we do NOT grow above base — growth made large\n    // charts render heavy, oversized text. Fonts only SHRINK for genuinely\n    // small small-multiple subplots (minDim < 220) so dense facets don't\n    // overflow; otherwise they render at native base.\n    const minDim = minPlotDimension || 320;\n    const ratio = minDim >= 220 ? 1 : Math.max(0.7, minDim / 220);\n    const atMostNative = (base: number) =>\n        Math.round(Math.max(base - 2, Math.min(base, base * ratio)));\n    const tickBase = atMostNative(baseLabel);\n    const titleFontSize = atMostNative(baseTitle);\n    const legendFontSize = Math.max(baseTitle - 2, titleFontSize - 1);\n    return { tickBase, titleFontSize, legendFontSize };\n}\n\n// ---------------------------------------------------------------------------\n// Overflow Decision\n// ---------------------------------------------------------------------------\n\n/**\n * Result of overflow analysis for a discrete axis.\n */\nexport interface OverflowDecision {\n    /** Whether overflow occurred (more items than can fit) */\n    overflowed: boolean;\n    /** Maximum items to keep */\n    maxToKeep: number;\n    /** Number of items omitted */\n    omittedCount: number;\n}\n\n/**\n * Compute whether a discrete axis overflows and how many items to keep.\n *\n * @param uniqueCount    Number of unique values on the axis\n * @param maxDimension   Maximum canvas dimension (with stretch) in px\n * @param minStepSize    Minimum px per item\n */\nexport function computeOverflow(\n    uniqueCount: number,\n    maxDimension: number,\n    minStepSize: number,\n): OverflowDecision {\n    const maxToKeep = Math.floor(maxDimension / minStepSize);\n    const overflowed = uniqueCount > maxToKeep;\n    return {\n        overflowed,\n        maxToKeep,\n        omittedCount: overflowed ? uniqueCount - maxToKeep : 0,\n    };\n}\n\n// ---------------------------------------------------------------------------\n// Circumference-pressure model for radial charts (§3)\n// ---------------------------------------------------------------------------\n\n/**\n * Parameters for circumference-pressure scaling (spring model on polar axis).\n */\nexport interface CircumferencePressureParams {\n    /** Minimum arc-length (px) each \"effective bar\" needs on the\n     *  circumference — analogous to defaultStepSize in the spring model.\n     *  Default: 45 */\n    minArcPx?: number;\n    /** Minimum chart radius in px. Default: 60 */\n    minRadius?: number;\n    /** Maximum chart radius in px. Caps runaway growth. Default: 400 */\n    maxRadius?: number;\n    /** Power-law exponent for pressure → stretch (same as spring model).\n     *  0.5 = square-root growth. Default: 0.5 */\n    elasticity?: number;\n    /** Per-dimension maximum stretch multiplier cap (matches bar-chart\n     *  default of 2.0).  The effective max stretch on the radius is\n     *  derived from min(baseW, baseH) × maxStretch so that the chart\n     *  never exceeds the cap in either dimension.  Default: 2.0 */\n    maxStretch?: number;\n    /** Per-dimension cap for the width axis. Defaults to `maxStretch`.\n     *  Lets the radius ceiling honor an asymmetric canvas (canvasW/baseW). */\n    maxStretchX?: number;\n    /** Per-dimension cap for the height axis. Defaults to `maxStretch`.\n     *  Lets the radius ceiling honor an asymmetric canvas (canvasH/baseH). */\n    maxStretchY?: number;\n    /** Extra margin outside the chart circle (px) for labels, legend, etc.\n     *  Added to each side when computing canvas dimensions. Default: 20 */\n    margin?: number;\n}\n\n/**\n * Result of circumference pressure computation.\n */\nexport interface CircumferencePressureResult {\n    /** Computed chart radius in px */\n    radius: number;\n    /** Recommended canvas width (px) */\n    canvasW: number;\n    /** Recommended canvas height (px) */\n    canvasH: number;\n}\n\n/**\n * Compute radial chart sizing using the spring model mapped to a polar axis.\n *\n * Treats the circumference as a linear \"bar axis\":\n *   baseCircumference = 2π × baseRadius\n *   pressure = effectiveItemCount × minArcPx / baseCircumference\n *   if pressure > 1:  stretch = min(maxStretch, pressure ^ elasticity)\n *   radius = baseRadius × stretch\n *\n * **effectiveItemCount** varies by chart type:\n *   - Rose / Radar: N categories (uniform slices/spokes)\n *   - Pie: total / minValue — how many of the smallest slice fit in the\n *     full circle.  This captures the worst-case thin slice that needs\n *     minimum arc width.\n *   - Sunburst: same as pie but computed on the outer ring leaves only.\n *\n * Both canvas dimensions grow equally (maintains 1:1 circular aspect).\n *\n * @param effectiveItemCount  Effective number of uniform \"bars\" around\n *                            the circle (see above)\n * @param canvasSize          Base canvas dimensions (from context)\n * @param params              Optional tuning parameters\n */\nexport function computeCircumferencePressure(\n    effectiveItemCount: number,\n    canvasSize: { width: number; height: number },\n    params: CircumferencePressureParams = {},\n): CircumferencePressureResult {\n    const {\n        minArcPx = 45,\n        minRadius = 60,\n        maxRadius = 400,\n        elasticity = 0.5,\n        maxStretch = 2.0,\n        margin = 20,\n    } = params;\n\n    // Per-dimension caps default to the scalar maxStretch (symmetric canvas).\n    const maxStretchX = Math.max(1, params.maxStretchX ?? maxStretch);\n    const maxStretchY = Math.max(1, params.maxStretchY ?? maxStretch);\n\n    const baseW = canvasSize.width;\n    const baseH = canvasSize.height;\n\n    // Base radius: largest circle that fits in the base canvas\n    const baseRadius = Math.max(minRadius,\n        (Math.min(baseW, baseH) / 2) - margin);\n\n    // ── Effective max-stretch on the radius ──────────────────────────\n    // The radius stretch expands the canvas in BOTH x and y equally.\n    // Cap so that neither dimension exceeds its per-dimension budget.\n    const maxCanvasW = baseW * maxStretchX;\n    const maxCanvasH = baseH * maxStretchY;\n    const maxDiameter = Math.min(maxCanvasW, maxCanvasH);\n    const effectiveMaxRadius = Math.min(maxRadius,\n        (maxDiameter - 2 * margin) / 2);\n    const effectiveMaxStretch = Math.max(1, effectiveMaxRadius / baseRadius);\n\n    // Spring model: pressure = items × step / baseDimension\n    const baseCircumference = 2 * Math.PI * baseRadius;\n    const pressure = (effectiveItemCount * minArcPx) / baseCircumference;\n\n    let radius: number;\n    if (pressure <= 1) {\n        // No pressure — base radius is sufficient\n        radius = baseRadius;\n    } else {\n        // Elastic stretch (same power law as bar-chart spring model)\n        const stretch = Math.min(effectiveMaxStretch, Math.pow(pressure, elasticity));\n        radius = Math.round(baseRadius * stretch);\n    }\n\n    // Clamp\n    radius = Math.min(maxRadius, Math.max(minRadius, radius));\n\n    // Canvas = diameter + margins\n    const diameter = 2 * radius + 2 * margin;\n    const canvasW = Math.max(baseW, diameter);\n    const canvasH = Math.max(baseH, diameter);\n\n    return { radius, canvasW, canvasH };\n}\n\n/**\n * Compute effective bar count for variable-width slices (pie / sunburst).\n *\n * If all slices are equal, this returns N (number of slices).\n * If slices vary, this returns `total / minValue` — i.e., how many of the\n * thinnest slice would fill the whole circle.  This is the worst-case\n * pressure that determines whether the chart needs to grow.\n *\n * Capped at 100 to prevent degenerate cases (near-zero slices) from\n * blowing up the radius.\n *\n * @param values  Array of slice values (must be > 0)\n */\nexport function computeEffectiveBarCount(values: number[]): number {\n    if (values.length === 0) return 0;\n    const positiveValues = values.filter(v => v > 0);\n    if (positiveValues.length === 0) return values.length;\n\n    const total = positiveValues.reduce((s, v) => s + v, 0);\n    const minVal = Math.min(...positiveValues);\n\n    // effectiveCount = total / minVal → how many of the smallest slice fill the circle\n    const effective = total / minVal;\n\n    // Cap at 100 to prevent degenerate cases\n    return Math.min(100, effective);\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * =============================================================================\n * CHANNEL SEMANTICS RESOLVER\n * =============================================================================\n *\n * Stage 2 of the semantic pipeline:\n *   SemanticAnnotation + data → FieldSemantics → **ChannelSemantics**\n *\n * Takes each channel’s field, builds FieldSemantics (stage 1), then adds\n * channel-specific visualization decisions: encoding type, color scheme,\n * temporal format, ordinal sort, tick constraints, axis reversal, nice\n * rounding, interpolation, and stacking.\n *\n * Zero-baseline is NOT resolved here — it requires template mark knowledge\n * and is finalized by the assembler after this function returns.\n *\n * VL dependency: **None**\n * =============================================================================\n */\n\nimport type {\n    ChartEncoding,\n    ChannelSemantics,\n    SemanticResult,\n} from './types';\nimport {\n    getVisCategory,\n    inferVisCategory,\n    getRecommendedColorScheme,\n    inferOrdinalSortOrder,\n} from './semantic-types';\nimport {\n    resolveEncodingType as resolveEncodingTypeDecision,\n} from './decisions';\nimport {\n    resolveFieldSemantics,\n    toTypeString,\n    resolveNice,\n    resolveTickConstraint,\n    resolveReversed,\n    resolveStackable,\n    resolveColorSchemeHint,\n    resolveDivergingInfo,\n    type SemanticAnnotation,\n} from './field-semantics';\n\n// ---------------------------------------------------------------------------\n// Internal helpers (moved from assemble.ts)\n// ---------------------------------------------------------------------------\n\n/** Upper bounds for plausible timestamps (~2099-12-31). */\nconst MAX_TIMESTAMP_SEC = 4102444800;\nconst MAX_TIMESTAMP_MS = 4102444800000;\n\nfunction isLikelyTimestamp(val: number): boolean {\n    if (val >= 1e9 && val <= MAX_TIMESTAMP_SEC) return true;\n    if (val > MAX_TIMESTAMP_SEC && val <= MAX_TIMESTAMP_MS) return true;\n    return false;\n}\n\nfunction timestampToMs(val: number): number {\n    return val <= MAX_TIMESTAMP_SEC ? val * 1000 : val;\n}\n\nfunction looksLikeDateString(s: string): boolean {\n    const t = s.trim();\n    return /^\\d|^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i.test(t);\n}\n\n// ---------------------------------------------------------------------------\n// Temporal field analysis\n// ---------------------------------------------------------------------------\n\ninterface TemporalAnalysis {\n    dates: Date[];\n    same: {\n        month: boolean;\n        day: boolean;\n        hour: boolean;\n        minute: boolean;\n        second: boolean;\n    };\n    sameYear: boolean;\n    sameMonth: boolean;\n    sameDay: boolean;\n}\n\nfunction analyzeTemporalField(fieldValues: any[]): TemporalAnalysis | null {\n    const dates: Date[] = [];\n    let nonNull = 0;\n    for (const v of fieldValues.slice(0, 100)) {\n        if (v == null) continue;\n        nonNull++;\n        const d = v instanceof Date ? v : new Date(v);\n        if (!isNaN(d.getTime())) dates.push(d);\n    }\n    if (dates.length < 2 || dates.length < nonNull * 0.5) return null;\n\n    const monthSet  = new Set(dates.map(d => d.getUTCMonth()));\n    const daySet    = new Set(dates.map(d => d.getUTCDate()));\n    const hourSet   = new Set(dates.map(d => d.getUTCHours()));\n    const minuteSet = new Set(dates.map(d => d.getUTCMinutes()));\n    const secondSet = new Set(dates.map(d => d.getUTCSeconds()));\n    const yearSet   = new Set(dates.map(d => d.getUTCFullYear()));\n\n    const isSmallSpread = (s: Set<number>, maxSpread: number = 1) => {\n        if (s.size <= 1) return true;\n        const arr = [...s];\n        return Math.max(...arr) - Math.min(...arr) <= maxSpread;\n    };\n\n    const same = {\n        month:  monthSet.size  === 1,\n        day:    daySet.size    === 1,\n        hour:   isSmallSpread(hourSet, 1),\n        minute: minuteSet.size === 1,\n        second: secondSet.size === 1,\n    };\n\n    const sameYear  = yearSet.size === 1;\n    const sameMonth = sameYear && same.month;\n    const sameDay   = sameMonth && same.day;\n\n    return { dates, same, sameYear, sameMonth, sameDay };\n}\n\nfunction computeDataVotes(same: TemporalAnalysis['same']): number[] {\n    const votes = [0, 0, 0, 0, 0, 0];\n\n    if (same.second)                                                           votes[5] += 1;\n    if (same.minute && same.second)                                            votes[5] += 1;\n    if (same.hour   && same.minute && same.second)                             votes[5] += 1;\n    if (same.day    && same.hour   && same.minute && same.second)              votes[5] += 2;\n    if (same.month  && same.day    && same.hour   && same.minute && same.second) votes[5] += 3;\n\n    if (same.second)                                                           votes[4] += 1;\n    if (same.minute && same.second)                                            votes[4] += 1;\n    if (same.hour   && same.minute && same.second)                             votes[4] += 1;\n    if (same.day    && same.hour   && same.minute && same.second)              votes[4] += 2;\n    if (!same.month && same.day && same.hour && same.minute && same.second)    votes[4] += 3;\n\n    if (same.second)                                                           votes[3] += 1;\n    if (same.minute && same.second)                                            votes[3] += 1;\n    if (same.hour   && same.minute && same.second)                             votes[3] += 1;\n    if (!same.day && same.hour && same.minute && same.second)                  votes[3] += 3;\n\n    if (same.second)                               votes[2] += 1;\n    if (same.minute && same.second)                votes[2] += 1;\n    if (!same.hour && same.minute && same.second)  votes[2] += 3;\n\n    if (same.second)                    votes[1] += 1;\n    if (!same.minute && same.second)    votes[1] += 3;\n\n    if (!same.second) votes[0] += 4;\n\n    return votes;\n}\n\nconst SEMANTIC_LEVEL: Record<string, number> = {\n    Year:        5, Decade:      5,\n    YearMonth:   4, Month:       4, YearQuarter: 4, Quarter: 4,\n    Date:        3, Day:         3,\n    Hour:        2,\n    DateTime:    1,\n    Timestamp:   0,\n};\n\nfunction pickBestLevel(votes: number[]): { level: number; score: number } {\n    let bestLevel = 0;\n    let bestScore = votes[0];\n    for (let i = 1; i <= 5; i++) {\n        if (votes[i] >= bestScore) {\n            bestScore = votes[i];\n            bestLevel = i;\n        }\n    }\n    return { level: bestLevel, score: bestScore };\n}\n\nfunction levelToFormat(level: number, analysis: TemporalAnalysis): string | null {\n    switch (level) {\n        case 5: return '%Y';\n        case 4: return analysis.sameYear ? '%b' : '%b %Y';\n        case 3: return analysis.sameYear ? '%b %d' : '%b %d, %Y';\n        case 2: return analysis.sameDay  ? '%H:00' : '%b %d %H:00';\n        case 1: return analysis.sameDay  ? '%H:%M' : '%b %d %H:%M';\n        case 0: return analysis.sameDay  ? '%H:%M:%S' : '%b %d %H:%M:%S';\n        default: return null;\n    }\n}\n\n/**\n * Resolve temporal format for a field.\n * Used for both temporal and ordinal-temporal fields.\n */\nfunction resolveTemporalFormat(\n    fieldValues: any[],\n    semanticType: string,\n): string | null {\n    const analysis = analyzeTemporalField(fieldValues);\n    if (!analysis) return null;\n\n    const votes = computeDataVotes(analysis.same);\n    const semLevel = SEMANTIC_LEVEL[semanticType];\n    if (semLevel !== undefined) votes[semLevel] += 3;\n    const { level } = pickBestLevel(votes);\n    return levelToFormat(level, analysis);\n}\n\n// ---------------------------------------------------------------------------\n// Temporal data conversion\n// ---------------------------------------------------------------------------\n\n/**\n * Expand a year string to an unambiguous 4-digit representation.\n *\n * - \"98\" → \"1998\",  \"07\" → \"2007\",  \"00\" → \"2000\"\n * - \"1998\" → \"1998\" (already 4+ digits, pass through)\n * - \"FY 2018\" → \"FY 2018\" (non-numeric, pass through)\n *\n * Two-digit cutoff: 0–49 → 2000s, 50–99 → 1900s (same heuristic JS Date uses).\n */\nfunction expandToFullYear(val: string): string {\n    const trimmed = val.trim();\n    if (/^\\d{2}$/.test(trimmed)) {\n        const n = parseInt(trimmed, 10);\n        return String(n <= 49 ? 2000 + n : 1900 + n);\n    }\n    return val;\n}\n\n/**\n * Convert temporal field values in the data table to canonical string\n * representations for Vega-Lite consumption.\n *\n * This is a data-level concern (not VL-specific) — it ensures consistent\n * date parsing across backends.\n */\nexport function convertTemporalData(\n    data: any[],\n    semanticTypes: Record<string, string | SemanticAnnotation>,\n): any[] {\n    if (data.length === 0) return data;\n\n    const keys = Object.keys(data[0]);\n    const temporalKeys = keys.filter((k: string) => {\n        const st = toTypeString(semanticTypes[k]);\n        const vc = inferVisCategory(data.map(r => r[k]));\n        const stCategory = st ? getVisCategory(st) : null;\n        return vc === 'temporal' || stCategory === 'temporal' || st === 'Decade';\n    });\n\n    if (temporalKeys.length === 0) return data;\n\n    const values = structuredClone(data);\n    return values.map((r: any) => {\n        for (const temporalKey of temporalKeys) {\n            const val = r[temporalKey];\n            const st = toTypeString(semanticTypes[temporalKey]);\n\n            if (typeof val === 'number') {\n                if (st === 'Year' || st === 'Decade') {\n                    r[temporalKey] = `${Math.floor(val)}`;\n                } else if (isLikelyTimestamp(val)) {\n                    r[temporalKey] = new Date(timestampToMs(val)).toISOString();\n                } else {\n                    r[temporalKey] = String(val);\n                }\n            } else if (val instanceof Date) {\n                r[temporalKey] = val.toISOString();\n            } else {\n                // For Year/Decade strings, normalise to 4-digit years so\n                // Vega-Lite parses them unambiguously and doesn't auto-tick\n                // at sub-year intervals (e.g. \"98\" → \"1998\").\n                if ((st === 'Year' || st === 'Decade') && typeof val === 'string') {\n                    r[temporalKey] = expandToFullYear(val);\n                } else {\n                    r[temporalKey] = String(val);\n                }\n            }\n        }\n        return r;\n    });\n}\n\n// ---------------------------------------------------------------------------\n// Public API: resolveChannelSemantics\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve all channel-level semantic decisions.\n *\n * For each channel, builds FieldSemantics (data identity) then layers on\n * channel-specific visualization decisions (color scheme, temporal format,\n * tick constraints, axis reversal, interpolation, etc.).\n *\n * Zero-baseline (cs.zero) is NOT resolved here -- it requires template\n * mark knowledge (bar vs point) that belongs to the assembler.\n * The assembler finalizes zero after calling this function.\n *\n * @param encodings       Channel -> ChartEncoding from user / AI agent\n * @param data            Array of data rows (original, unconverted)\n * @param semanticTypes   Field name -> semantic type string\n * @param convertedData   Pre-converted temporal data (from convertTemporalData).\n *                        If omitted, falls back to data for temporal format detection.\n */\nexport function resolveChannelSemantics(\n    encodings: Record<string, ChartEncoding>,\n    data: any[],\n    semanticTypes: Record<string, string | SemanticAnnotation>,\n    convertedData?: any[],\n): SemanticResult {\n    const result: SemanticResult = {};\n\n    // Use pre-converted temporal data for format detection, or fall back to raw data\n    const temporalData = convertedData ?? data;\n\n    for (const [channel, encoding] of Object.entries(encodings)) {\n        const fieldName = encoding.field;\n        if (!fieldName && encoding.aggregate !== 'count') continue;\n\n        // Handle count aggregate without a field\n        if (!fieldName && encoding.aggregate === 'count') {\n            result[channel] = {\n                field: '_count',\n                semanticAnnotation: { semanticType: 'Count' },\n                type: 'quantitative',\n                aggregationDefault: 'sum',\n            };\n            continue;\n        }\n\n        if (!fieldName) continue;\n\n        const rawAnnotation = semanticTypes[fieldName];\n        const semanticType = typeof rawAnnotation === 'string'\n            ? (rawAnnotation || '')\n            : (rawAnnotation?.semanticType ?? '');\n        const fieldValues = data.map(r => r[fieldName]);\n\n        // Resolve encoding type\n        const typeDecision = resolveEncodingTypeDecision(\n            semanticType, fieldValues, channel, data, fieldName,\n        );\n\n        // Apply explicit type override\n        let resolvedType = typeDecision.vlType;\n        if (encoding.type) {\n            resolvedType = encoding.type;\n        } else if (channel === 'column' || channel === 'row') {\n            if (resolvedType !== 'nominal' && resolvedType !== 'ordinal') {\n                resolvedType = 'nominal';\n            }\n        }\n\n        // ISO date hack\n        if (resolvedType === 'quantitative') {\n            const sampleValues = data.slice(0, 15).filter(r => r[fieldName] != undefined).map(r => r[fieldName]);\n            const isoDateRegex = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})?$/;\n            if (sampleValues.length > 0 && sampleValues.every((val: any) => isoDateRegex.test(`${val}`.trim()))) {\n                resolvedType = 'temporal';\n            }\n        }\n\n        // Build ChannelSemantics entry\n        // Stage 1: resolve field-level semantics (data identity)\n        const fc = resolveFieldSemantics(rawAnnotation, fieldName, fieldValues);\n        const annotation = fc.semanticAnnotation;\n\n        // Stage 2: layer on channel-specific visualization decisions\n        const tickConstraint = resolveTickConstraint(annotation.semanticType, annotation.intrinsicDomain);\n        const reversed = resolveReversed(annotation.semanticType, channel);\n        const nice = resolveNice(annotation.semanticType, fc.domainConstraint);\n        const stackable = resolveStackable(annotation.semanticType);\n\n        const cs: ChannelSemantics = {\n            field: fieldName,\n            semanticAnnotation: annotation,\n            type: resolvedType,\n\n            // From FieldSemantics (data identity)\n            format: fc.format,\n            tooltipFormat: fc.tooltipFormat,\n            aggregationDefault: fc.aggregationDefault,\n            scaleType: fc.scaleType,\n            domainConstraint: fc.domainConstraint,\n            cyclic: fc.cyclic || undefined,\n            sortDirection: fc.sortDirection,\n            binningSuggested: fc.binningSuggested || undefined,\n\n            // Channel-specific visualization decisions\n            nice,\n            tickConstraint,\n            reversed: reversed || undefined,\n            stackable,\n        };\n\n        // Adjust field name for aggregated fields (the derived column is either\n        // computed by applyAggregation or supplied pre-aggregated by the caller)\n        if (encoding.aggregate) {\n            if (encoding.aggregate === 'count') {\n                cs.field = '_count';\n                cs.type = 'quantitative';\n            } else {\n                cs.field = `${fieldName}_${encoding.aggregate}`;\n                cs.type = 'quantitative';\n            }\n        }\n\n        // --- Channel-specific semantic decisions ---\n\n        // Color scheme (color and group channels)\n        if ((channel === 'color' || channel === 'group') && fieldName) {\n            if (encoding.scheme && encoding.scheme !== 'default') {\n                cs.colorScheme = {\n                    scheme: encoding.scheme,\n                    type: 'categorical',\n                    reason: 'explicit user scheme',\n                };\n            } else {\n                const encodingVLType = cs.type as 'nominal' | 'ordinal' | 'quantitative' | 'temporal';\n                // Use design-aligned classification from field-semantics.ts\n                const colorHint = resolveColorSchemeHint(semanticType, annotation, fieldValues);\n                const uniqueValues = [...new Set(fieldValues)];\n                cs.colorScheme = getRecommendedColorScheme(\n                    semanticType, encodingVLType, uniqueValues.length, fieldName,\n                    fieldValues, { type: colorHint.type },\n                );\n                // Apply midpoint from design-aligned diverging analysis\n                if (cs.colorScheme.type === 'diverging' && encodingVLType === 'quantitative') {\n                    const nums = fieldValues.filter((v: any) => typeof v === 'number' && !isNaN(v));\n                    const divInfo = resolveDivergingInfo(semanticType, annotation, nums);\n                    if (divInfo) {\n                        cs.colorScheme.domainMid = divInfo.midpoint;\n                    }\n                }\n            }\n        }\n\n        // Temporal format\n        if (cs.type === 'temporal' || (semanticType && getVisCategory(semanticType) === 'temporal')) {\n            const convertedFieldValues = temporalData.map(r => r[fieldName]);\n            const fmt = resolveTemporalFormat(convertedFieldValues, semanticType);\n            if (fmt) cs.temporalFormat = fmt;\n        }\n\n        // Ordinal sort order (canonical ordering for months, days, quarters, etc.)\n        if (cs.type === 'ordinal' || cs.type === 'nominal') {\n            if (!encoding.sortOrder && !encoding.sortBy) {\n                const ordinalSort = inferOrdinalSortOrder(semanticType, fieldValues);\n                if (ordinalSort) {\n                    cs.ordinalSortOrder = ordinalSort;\n                }\n            }\n        }\n\n        result[channel] = cs;\n    }\n\n    return result;\n}\n\n// Re-export helpers needed by other modules\nexport {\n    analyzeTemporalField,\n    computeDataVotes,\n    pickBestLevel,\n    levelToFormat,\n    looksLikeDateString,\n    SEMANTIC_LEVEL,\n    type TemporalAnalysis,\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * =============================================================================\n * OVERFLOW FILTERING\n * =============================================================================\n *\n * Decides *which* discrete values to keep when there are too many for\n * the available canvas space, then filters the data accordingly.\n *\n * This module does **no layout math**.  Per-channel capacity budgets\n * are computed upstream by `computeChannelBudgets` and passed in as\n * a `ChannelBudgets` object.  This module focuses on:\n *   1. Iterating each discrete channel\n *   2. Applying the overflow strategy (which values to keep)\n *   3. Filtering data rows\n *   4. Producing truncation warnings\n *\n * Runs AFTER computeChannelBudgets and BEFORE computeLayout.\n *\n * VL dependency: **None**\n * =============================================================================\n */\n\nimport type {\n    ChannelSemantics,\n    ChartEncoding,\n    LayoutDeclaration,\n    TruncationWarning,\n    OverflowResult,\n    OverflowStrategy,\n    OverflowStrategyContext,\n    ChannelBudgets,\n} from './types';\nimport type { ChartWarning } from './types';\nimport { inferVisCategory } from './semantic-types';\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Filter data to keep only the values that fit within the canvas.\n *\n * @param channelSemantics  Phase 0 output (field, type per channel)\n * @param declaration       Template layout declaration (resolvedTypes, overflowStrategy)\n * @param encodings         Original user-level encodings (for sort info)\n * @param data              Full data table\n * @param budgets           Per-channel capacity budgets from computeChannelBudgets\n * @param allMarkTypes      Set of all mark types in the template (for connected-mark detection)\n * @returns                 OverflowResult with filtered data, nominal counts, truncations, and warnings\n */\nexport function filterOverflow(\n    channelSemantics: Record<string, ChannelSemantics>,\n    declaration: LayoutDeclaration,\n    encodings: Record<string, ChartEncoding>,\n    data: any[],\n    budgets: ChannelBudgets,\n    allMarkTypes: Set<string>,\n): OverflowResult {\n\n    // --- Build effective channel info from semantics + declaration ---\n\n    const effectiveType = (ch: string): string | undefined =>\n        declaration.resolvedTypes?.[ch] ?? channelSemantics[ch]?.type;\n\n    const effectiveField = (ch: string): string | undefined => {\n        if (channelSemantics[ch]?.field) return channelSemantics[ch].field;\n        return undefined;\n    };\n\n    const isDiscreteType = (t: string | undefined) => t === 'nominal' || t === 'ordinal';\n\n    // --- Filter data ---\n\n    const nominalCounts: Record<string, number> = {\n        x: 0, y: 0, column: 0, row: 0, group: 0,\n    };\n    const truncations: TruncationWarning[] = [];\n    const warnings: ChartWarning[] = [];\n    let filteredData = data;\n\n    // Compute group nominal count\n    const groupField = channelSemantics.group?.field;\n    if (groupField) {\n        nominalCounts.group = new Set(data.map(r => r[groupField])).size;\n    }\n\n    // Strategy context for custom or default overflow\n    const strategyContext: OverflowStrategyContext = {\n        data,\n        channelSemantics,\n        encodings,\n        allMarkTypes,\n    };\n\n    const strategy = declaration.overflowStrategy ?? defaultOverflowStrategy;\n\n    for (const channel of ['x', 'y', 'column', 'row', 'color'] as const) {\n        const fieldName = effectiveField(channel);\n        const type = effectiveType(channel);\n        if (!fieldName) continue;\n\n        // Budget for this channel (Infinity if uncapped)\n        const maxToKeep = budgets.maxValues[channel] ?? Infinity;\n\n        // For non-discrete types on column/row, apply overflow cap —\n        // every unique value becomes a facet panel.\n        if (!isDiscreteType(type)) {\n            if (channel === 'column' || channel === 'row') {\n                const uniqueValues = [...new Set(filteredData.map(r => r[fieldName]))];\n                nominalCounts[channel] = Math.min(uniqueValues.length, maxToKeep);\n\n                if (uniqueValues.length > maxToKeep) {\n                    // For non-discrete facets, keep the first N values (sorted)\n                    const sorted = [...uniqueValues].sort();\n                    const valuesToKeep = sorted.slice(0, maxToKeep);\n\n                    const omittedCount = uniqueValues.length - valuesToKeep.length;\n                    warnings.push({\n                        severity: 'warning',\n                        code: 'overflow',\n                        message: `${omittedCount} of ${uniqueValues.length} values in '${fieldName}' were omitted (showing first ${valuesToKeep.length}).`,\n                        channel,\n                        field: fieldName,\n                    });\n\n                    const keepSet = new Set(valuesToKeep);\n                    filteredData = filteredData.filter(row => keepSet.has(row[fieldName]));\n                }\n            }\n            continue;\n        }\n\n        const uniqueValues = [...new Set(filteredData.map(r => r[fieldName]))];\n        nominalCounts[channel] = Math.min(uniqueValues.length, maxToKeep);\n\n        if (uniqueValues.length > maxToKeep) {\n            const valuesToKeep = strategy(channel, fieldName, uniqueValues, maxToKeep, strategyContext);\n\n            const omittedCount = uniqueValues.length - valuesToKeep.length;\n            const placeholder = `...${omittedCount} items omitted`;\n\n            warnings.push({\n                severity: 'warning',\n                code: 'overflow',\n                message: `${omittedCount} of ${uniqueValues.length} values in '${fieldName}' were omitted (showing first ${valuesToKeep.length} in sort order).`,\n                channel,\n                field: fieldName,\n            });\n\n            truncations.push({\n                severity: 'warning',\n                code: 'overflow',\n                message: `${omittedCount} of ${uniqueValues.length} values in '${fieldName}' were omitted (showing first ${valuesToKeep.length} in sort order).`,\n                channel,\n                field: fieldName,\n                keptValues: valuesToKeep,\n                omittedCount,\n                placeholder,\n            });\n\n            // Filter data rows (except for color — we keep all rows but style the legend)\n            if (channel !== 'color') {\n                filteredData = filteredData.filter(row => valuesToKeep.includes(row[fieldName]));\n            }\n        }\n    }\n\n    return { filteredData, nominalCounts, truncations, warnings };\n}\n\n// ---------------------------------------------------------------------------\n// Default overflow strategy\n// ---------------------------------------------------------------------------\n\n/**\n * Default overflow strategy: decides which discrete values to keep.\n *\n * - User-specified sort: respect it\n * - Canonical semantic order (months, ranks, etc.): keep the first N\n * - Numeric categories: keep the first N numerically\n * - Otherwise preserve data encounter order\n */\nconst defaultOverflowStrategy: OverflowStrategy = (\n    channel, fieldName, uniqueValues, maxToKeep, context,\n) => {\n    const { data, channelSemantics, encodings, allMarkTypes } = context;\n\n    // Determine sort intent from user encodings\n    const encoding = encodings[channel];\n    const sortBy = encoding?.sortBy;\n    const sortOrder = encoding?.sortOrder;\n\n    // Infer sort field and direction\n    let sortField: string | undefined;\n    let sortFieldType: string | undefined;\n    let isDescending = false;\n\n    if (sortBy) {\n        // User explicitly specified sort\n        if (sortBy === 'x' || sortBy === 'y' || sortBy === 'color') {\n            const sortCS = channelSemantics[sortBy];\n            sortField = sortCS?.field;\n            sortFieldType = sortCS?.type;\n            isDescending = sortOrder === 'descending' || (sortOrder !== 'ascending' && sortBy !== channel);\n        } else {\n            // Custom sort list — respect insertion order\n            try {\n                const sortedList = JSON.parse(sortBy);\n                if (Array.isArray(sortedList)) {\n                    const orderedValues = (sortOrder === 'descending') ? sortedList.reverse() : sortedList;\n                    return orderedValues.filter((v: any) => uniqueValues.includes(v)).slice(0, maxToKeep);\n                }\n            } catch {\n                // not a JSON list, fall through\n            }\n            isDescending = sortOrder === 'descending';\n        }\n    }\n\n    // Explicit value sort takes precedence over the category field's own type.\n    if (sortField && sortFieldType === 'quantitative') {\n        let aggregateOp = Math.max;\n        let initialValue = -Infinity;\n        if (allMarkTypes.has('bar') && sortField !== channelSemantics.color?.field) {\n            aggregateOp = (x: number, y: number) => x + y;\n            initialValue = 0;\n        }\n\n        const valueAggregates = new Map<any, number>();\n        for (const row of data) {\n            const fieldValue = row[fieldName];\n            const sortValue = Number(row[sortField] ?? 0);\n            if (valueAggregates.has(fieldValue)) {\n                valueAggregates.set(fieldValue, aggregateOp(valueAggregates.get(fieldValue)!, sortValue));\n            } else {\n                valueAggregates.set(fieldValue, aggregateOp(initialValue, sortValue));\n            }\n        }\n\n        return Array.from(valueAggregates.entries())\n            .map(([value, agg]) => ({ value, agg }))\n            .sort((a, b) => isDescending ? b.agg - a.agg : a.agg - b.agg)\n            .slice(0, maxToKeep)\n            .map(v => v.value);\n    }\n\n    const canonicalOrder = channelSemantics[channel]?.ordinalSortOrder;\n    if (!sortBy && !sortOrder && canonicalOrder?.length) {\n        const present = new Set(uniqueValues);\n        const ordered = canonicalOrder.filter(value => present.has(value));\n        const canonicalValues = new Set(ordered);\n        ordered.push(...uniqueValues.filter(value => !canonicalValues.has(value)));\n        return ordered.slice(0, maxToKeep);\n    }\n\n    // Match the display default for quantitative values treated as discrete.\n    const fieldOriginalType = inferVisCategory(data.map(r => r[fieldName]));\n    if (fieldOriginalType === 'quantitative' || channel === 'color') {\n        return [...uniqueValues].sort((a, b) => Number(a) - Number(b))\n            .slice(0, maxToKeep);\n    }\n\n    // Facet channels: first N\n    if (channel === 'column' || channel === 'row') {\n        return uniqueValues.slice(0, maxToKeep);\n    }\n\n    // Explicit field-order sort follows the displayed label order.\n    if (sortOrder === 'descending') {\n        return [...uniqueValues].sort((a, b) => String(b).localeCompare(String(a), undefined, { numeric: true })).slice(0, maxToKeep);\n    }\n    if (sortOrder === 'ascending') {\n        return [...uniqueValues].sort((a, b) => String(a).localeCompare(String(b), undefined, { numeric: true })).slice(0, maxToKeep);\n    }\n\n    // Default: first N values\n    return uniqueValues.slice(0, maxToKeep);\n};\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * =============================================================================\n * PHASE 1: COMPUTE LAYOUT\n * =============================================================================\n *\n * Determine how big things should be — axis lengths, step sizes,\n * subplot dimensions, label sizing, and overflow truncation — from data\n * density, axis classification, and template-provided tuning knobs.\n *\n * VL dependency: **None**\n *\n * This module reads abstract axis descriptors (AxisLayoutInput) and\n * produces abstract layout numbers (LayoutResult). The same layout\n * engine works regardless of output format.\n *\n * ── Backend Responsibility ──────────────────────────────────────────\n * The LayoutResult is a target-agnostic description of \"how big things\n * should be\".  Each rendering backend (Vega-Lite, ECharts, etc.) MUST:\n *\n *   1. Call computeLayout() once per chart (facet-aware — it already\n *      divides subplot sizes for the facet grid).\n *\n *   2. Translate the LayoutResult into its own rendering format:\n *      - subplotWidth / subplotHeight → plot area size (before margins)\n *      - xStep / yStep → bar widths, band sizes, category spacing\n *      - stepPadding → inter-category gap (barCategoryGap, paddingInner)\n *      - label sizing → font size, rotation, truncation\n *\n *   3. Add its own margins, padding, and chrome (axis labels, titles,\n *      legends, CANVAS_BUFFER) around the subplot area.\n *\n *   4. Handle facet-specific concerns itself:\n *      - Column wrapping (when user specifies column-only, the backend\n *        decides how many columns per visual row and restructures the\n *        panel grid accordingly).\n *      - Per-panel vs shared axis titles.\n *      - Panel positioning and header labels.\n *\n * The layout engine does NOT know about VL encodings, ECharts grid\n * objects, or any rendering-specific structure.\n * =============================================================================\n */\n\nimport type {\n    ChannelSemantics,\n    LayoutDeclaration,\n    LayoutResult,\n    AssembleOptions,\n    ChannelBudgets,\n} from './types';\nimport {\n    computeAxisStep,\n    computeGasPressure,\n    computeLabelSizing,\n    computeFontSizing,\n    DEFAULT_GAS_PRESSURE_PARAMS,\n    type ElasticStretchParams,\n    type GasPressureParams,\n} from './decisions';\nimport { planBandDodge } from './band-dodge';\n\n// ---------------------------------------------------------------------------\n// Short discrete axis labels (align with echarts/templates/bar.ts)\n// ---------------------------------------------------------------------------\n\nconst VL_SHORT_DISCRETE_CATEGORY_COUNT = 4;\nconst VL_SHORT_DISCRETE_LABEL_MAX_LEN = 8;\n\n/** Approximate width (px) of one label character at the given font size. */\nconst APPROX_CHAR_WIDTH_RATIO = 0.62;\n\n/** Distinct label strings for a discrete axis field, plus derived stats. */\ninterface DiscreteLabelStats {\n    count: number;\n    maxLen: number;\n    /** True when every label parses as a finite number (e.g. years, bins, IDs). */\n    allNumeric: boolean;\n}\n\nfunction computeDiscreteLabelStats(\n    field: string | undefined,\n    table: any[],\n): DiscreteLabelStats | null {\n    if (!field) return null;\n    const uniques = new Set<string>();\n    for (const row of table) {\n        const v = row[field];\n        if (v == null || v === '') continue;\n        uniques.add(String(v));\n    }\n    if (uniques.size === 0) return null;\n    const labels = [...uniques];\n    return {\n        count: labels.length,\n        maxLen: Math.max(...labels.map(s => s.length)),\n        allNumeric: labels.every(s => s.trim() !== '' && isFinite(Number(s))),\n    };\n}\n\n/**\n * Few, short category strings → keep axis labels horizontal in Vega-Lite. Used\n * for the Y axis, where banded labels read horizontally in the left margin\n * regardless of band height (so quantitative/numeric labels stay horizontal).\n */\nfunction discreteYAxisShouldUseHorizontalLabels(\n    field: string | undefined,\n    channelType: string | undefined,\n    table: any[],\n): boolean {\n    if (!field) return false;\n    if (channelType === 'quantitative') return true;\n    const stats = computeDiscreteLabelStats(field, table);\n    if (!stats) return false;\n    if (stats.count > VL_SHORT_DISCRETE_CATEGORY_COUNT) return false;\n    return stats.maxLen <= VL_SHORT_DISCRETE_LABEL_MAX_LEN;\n}\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ninterface AxisLayoutInput {\n    /** Spring model (banded) or gas pressure (non-banded) */\n    mode: 'banded' | 'non-banded';\n    /** Number of discrete positions (for banded) */\n    itemCount: number;\n    /** Number of sub-items per group (for grouped bars) */\n    subItemsPerGroup?: number;\n    /** Numeric values along this axis (for gas pressure) */\n    values?: number[];\n    /** Data extent [min, max] */\n    domain?: [number, number];\n    /** Number of distinct series (for series-based pressure) */\n    seriesCount?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Stretch caps\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the per-dimension maximum stretch caps (βx, βy) from options.\n *\n * The assembler derives `maxStretchX`/`maxStretchY` from the spec's\n * `canvasSize / baseSize` ratio (the hard ceiling). When neither is set,\n * both fall back to the scalar `maxStretch` (default {@link DEFAULT_MAX_STRETCH})\n * — the symmetric budget used when the spec pins no `canvasSize`. Each cap is\n * clamped to ≥ 1 (a chart never shrinks below its base under \"stretch\").\n */\nexport function resolveStretchCaps(options: AssembleOptions): { x: number; y: number } {\n    const def = options.maxStretch ?? DEFAULT_MAX_STRETCH;\n    return {\n        x: Math.max(1, options.maxStretchX ?? def),\n        y: Math.max(1, options.maxStretchY ?? def),\n    };\n}\n\n/** Default base (target) chart size in pixels when the spec omits `baseSize`. */\nexport const DEFAULT_BASE_SIZE = { width: 400, height: 320 } as const;\n\n/**\n * Default axis stretch cap used when the spec pins no `canvasSize` ceiling.\n *\n * Bounds how far a chart may grow past its base size (per dimension) under\n * layout pressure. 1.5 keeps growth modest; 2× was found to over-stretch\n * charts in the general (no-ceiling) case.\n */\nexport const DEFAULT_MAX_STRETCH = 1.5;\n\n/**\n * Resolve the effective base (target) size the layout pipeline aims for.\n *\n * Defaults to {@link DEFAULT_BASE_SIZE} when the spec omits `baseSize`, then\n * clamps each dimension to the optional `canvasSize` ceiling. This guarantees\n * the target never exceeds the hard maximum: when a user sets only a (small)\n * `canvasSize` and leaves `baseSize` defaulted — or sets a `baseSize` larger\n * than the ceiling — the chart shrinks to fit the box instead of overflowing\n * it. After clamping, `deriveStretchCaps` yields βx/βy = 1 in any clamped\n * dimension (pure fit-to-box, no growth past the ceiling).\n */\nexport function resolveBaseSize(\n    specBaseSize: { width: number; height: number } | undefined,\n    ceiling: { width: number; height: number } | undefined,\n): { width: number; height: number } {\n    const base = specBaseSize ?? { ...DEFAULT_BASE_SIZE };\n    if (!ceiling) return { width: base.width, height: base.height };\n    return {\n        width: Math.min(base.width, ceiling.width),\n        height: Math.min(base.height, ceiling.height),\n    };\n}\n\n/**\n * Read the user's `facetColumns` chart property (the interactive facet-wrap\n * control) off the RAW chart_spec.chartProperties, returning a clamped integer\n * column count or undefined for auto. Read raw (pre-normalization) because\n * `facetColumns` is a layout-level option, not a per-template mark property, so\n * `normalizeChartProperties` would otherwise drop it as an unknown key.\n */\nexport function resolveFacetColumnsOption(\n    chartProperties: Record<string, any> | undefined,\n): number | undefined {\n    const raw = chartProperties?.facetColumns;\n    if (raw == null) return undefined;\n    const n = Number(raw);\n    return Number.isFinite(n) && n >= 1 ? Math.floor(n) : undefined;\n}\n\n/**\n * Derive per-dimension stretch ceilings (βx, βy) for an assembler.\n *\n * When the spec supplies a hard `canvasSize` ceiling, the caps are the ratio\n * of ceiling to base in each dimension (clamped to ≥ 1). The base passed here\n * is expected to already be clamped to the ceiling (see {@link resolveBaseSize}),\n * so a ceiling smaller than the spec's base resolves to β = 1 (fit-to-box)\n * rather than an overflow. When no ceiling is given, both caps fall back to\n * `options.maxStretch` (or {@link DEFAULT_MAX_STRETCH} when that is unset too),\n * which already reflects any template `paramOverrides`.\n *\n * Assemblers inject the result into `effectiveOptions.maxStretchX/Y` so the\n * whole layout pipeline shares one budget — including faceted grids, whose\n * total size is bounded by the same ceiling.\n */\nexport function deriveStretchCaps(\n    baseSize: { width: number; height: number },\n    ceiling: { width: number; height: number } | undefined,\n    options: AssembleOptions,\n): { maxStretchX: number; maxStretchY: number } {\n    const def = options.maxStretch ?? DEFAULT_MAX_STRETCH;\n    return {\n        maxStretchX: ceiling ? Math.max(1, ceiling.width / baseSize.width) : def,\n        maxStretchY: ceiling ? Math.max(1, ceiling.height / baseSize.height) : def,\n    };\n}\n\n// ---------------------------------------------------------------------------\n// Public API: computeLayout\n// ---------------------------------------------------------------------------\n\n/**\n * Phase 1: Compute layout decisions.\n *\n * Takes channel semantics, template layout declaration, data, canvas size,\n * and assembly options to produce a LayoutResult with step sizes, subplot\n * dimensions, label sizing, and truncation warnings.\n *\n * VL dependency: **None**\n *\n * @param channelSemantics   Phase 0 output\n * @param declaration        Template's layout declaration (axisFlags, resolvedTypes,\n *                           grouping, binnedAxes)\n * @param table              Data rows (post-overflow filtered)\n * @param canvasSize         Target canvas dimensions\n * @param options            Assembly options (merged with template overrides)\n * @param facetGrid          Optional pre-decided facet grid from computeFacetGrid.\n *                           When provided, computeLayout uses these column/row\n *                           counts instead of counting from data — this\n *                           eliminates the circularity between wrapping and\n *                           banded axis sizing.\n */\nexport function computeLayout(\n    channelSemantics: Record<string, ChannelSemantics>,\n    declaration: LayoutDeclaration,\n    table: any[],\n    canvasSize: { width: number; height: number },\n    options: AssembleOptions = {},\n    facetGrid?: { columns: number; rows: number },\n): LayoutResult {\n    const {\n        elasticity: elasticityVal = 0.5,\n        facetElasticity: facetElasticityVal = 0.3,\n        minStep: minStepVal = 6,\n        minSubplotSize: minSubplotVal = 60,\n        stepPadding: stepPaddingVal = 0.1,\n        maintainContinuousAxisRatio = false,\n        continuousMarkCrossSection,\n        facetAspectRatioResistance = 0,\n    } = options;\n\n    // Per-dimension stretch ceilings: βx bounds width-related growth,\n    // βy bounds height-related growth. Both reduce to `maxStretch`\n    // (default 1.5) when the spec sets no explicit `canvasSize` ceiling.\n    const { x: maxStretchX, y: maxStretchY } = resolveStretchCaps(options);\n\n    const defaultChartWidth = canvasSize.width;\n    const defaultChartHeight = canvasSize.height;\n\n    // Facet overhead: fixed (axis labels, titles) + per-panel gap (spacing).\n    const fixW = options.facetFixedPadding?.width ?? 0;\n    const fixH = options.facetFixedPadding?.height ?? 0;\n    const gap = options.facetGap ?? 0;\n\n    const baseRefSize = 300;\n    const sizeRatio = Math.max(defaultChartWidth, defaultChartHeight) / baseRefSize;\n    const baseBandSize = options.defaultBandSize ?? 20;\n    const defaultStepSize = Math.round(baseBandSize * Math.max(1, sizeRatio));\n    // Sparse-expansion ceiling: a band may grow past its base size to fill a\n    // wide plot, but never past maxStepSize. Defaults to the base band, so a\n    // backend that doesn't opt in keeps the old \"cap at base\" behavior.\n    const maxBandSize = Math.max(baseBandSize, options.maxBandSize ?? baseBandSize);\n    const maxStepSize = Math.round(maxBandSize * Math.max(1, sizeRatio));\n\n    const isDiscreteType = (t: string | undefined) => t === 'nominal' || t === 'ordinal';\n\n    // Apply resolved types from template declaration\n    const effectiveTypes: Record<string, string> = {};\n    for (const [ch, cs] of Object.entries(channelSemantics)) {\n        effectiveTypes[ch] = declaration.resolvedTypes?.[ch] || cs.type;\n    }\n\n    // --- Classify axes and count items ---\n    const axisFlags = declaration.axisFlags || {};\n    const xBanded = axisFlags.x?.banded ?? false;\n    const yBanded = axisFlags.y?.banded ?? false;\n\n    const nominalCount: Record<string, number> = {\n        x: 0, y: 0, column: 0, row: 0, group: 0,\n    };\n\n    // Count discrete values per channel\n    for (const channel of ['x', 'y', 'column', 'row', 'color'] as const) {\n        const cs = channelSemantics[channel];\n        if (!cs?.field) continue;\n        const effectiveType = effectiveTypes[channel] || cs.type;\n        if (!isDiscreteType(effectiveType)) continue;\n        const uniqueValues = [...new Set(table.map((r: any) => r[cs.field]))];\n        nominalCount[channel] = uniqueValues.length;\n    }\n\n    // Detect grouping from 'group' channel + discrete axis\n    let groupField: string | undefined = channelSemantics.group?.field;\n    // Some templates (e.g. boxplot) subdivide a band by the COLOR field via an\n    // explicit offset rather than a dedicated 'group' channel. When they opt in,\n    // size the band as a group so total width is budgeted across categories and\n    // each sub-lane shrinks as the subgroup count grows.\n    if (!groupField && declaration.colorActsAsGroup) {\n        const colorCS = channelSemantics.color;\n        const colorType = effectiveTypes.color ?? colorCS?.type;\n        const axisField = isDiscreteType(effectiveTypes.x ?? channelSemantics.x?.type)\n            ? channelSemantics.x?.field\n            : channelSemantics.y?.field;\n        if (colorCS?.field && isDiscreteType(colorType) && colorCS.field !== axisField) {\n            groupField = colorCS.field;\n        }\n    }\n    // Guard: a grouping field that is redundant/nested with the categorical axis\n    // (group == x, or a 1:1 field pair) doesn't actually subdivide any band, so\n    // grouping it would collapse each bar/box to ~1/N of its band. When no band\n    // holds more than one distinct group value (confident-nested; threshold-\n    // independent), suppress grouping so glyphs fill their whole band. Genuine\n    // grouped charts (any band with >1 group value) are untouched.\n    if (groupField) {\n        const groupAxisField = isDiscreteType(effectiveTypes.x ?? channelSemantics.x?.type)\n            ? channelSemantics.x?.field\n            : channelSemantics.y?.field;\n        if (groupAxisField === groupField) {\n            groupField = undefined;  // group == axis: nothing to dodge\n        } else if (groupAxisField && planBandDodge(table, groupAxisField, groupField).maxPerBand <= 1) {\n            groupField = undefined;  // 1:1 / nested with the axis\n        }\n    }\n    let groupAxis: 'x' | 'y' | undefined;\n    if (groupField) {\n        // `local` dodge budgets only `maxPerBand` lanes (declaration.groupLaneCount);\n        // otherwise reserve one lane per global distinct group value.\n        nominalCount.group = declaration.groupLaneCount\n            ?? new Set(table.map((r: any) => r[groupField])).size;\n        if (isDiscreteType(effectiveTypes.x ?? channelSemantics.x?.type)) groupAxis = 'x';\n        else if (isDiscreteType(effectiveTypes.y ?? channelSemantics.y?.type)) groupAxis = 'y';\n    }\n\n    // Total discrete items per axis (grouping multiplies the grouped axis)\n    const xGroupMultiplier = (groupAxis === 'x' && nominalCount.group > 1) ? nominalCount.group : 1;\n    const yGroupMultiplier = (groupAxis === 'y' && nominalCount.group > 1) ? nominalCount.group : 1;\n    const xTotalNominalCount = nominalCount.x * xGroupMultiplier;\n    const yTotalNominalCount = nominalCount.y * yGroupMultiplier;\n\n    // --- Step size hints ---\n    // Minimum group step: the inter-group gap (stepPadding × step) must be\n    // at least MIN_GROUP_GAP_PX pixels so groups are visually separated.\n    const MIN_GROUP_GAP_PX = 3;\n    const xMinGroupStep = xGroupMultiplier > 1 ? Math.max(Math.ceil(MIN_GROUP_GAP_PX / stepPaddingVal), 2 * xGroupMultiplier) : minStepVal;\n    const yMinGroupStep = yGroupMultiplier > 1 ? Math.max(Math.ceil(MIN_GROUP_GAP_PX / stepPaddingVal), 2 * yGroupMultiplier) : minStepVal;\n\n    // (Overflow filtering is now handled by filterOverflow() before\n    //  computeLayout is called. The data passed here is already filtered.)\n\n    // --- Count banded continuous axes ---\n    let xContinuousAsDiscrete = 0;\n    let yContinuousAsDiscrete = 0;\n    for (const axis of ['x', 'y'] as const) {\n        const cs = channelSemantics[axis];\n        if (!cs?.field) continue;\n        const effectiveType = effectiveTypes[axis] || cs.type;\n        if (isDiscreteType(effectiveType)) continue;\n\n        const isBanded = (axis === 'x' ? xBanded : yBanded);\n        // Check for binned from declaration\n        const isBinned = declaration.binnedAxes?.[axis];\n        if (!isBanded && !isBinned) continue;\n\n        let count: number;\n        if (isBinned) {\n            const binDef = declaration.binnedAxes![axis];\n            // Default to 10 bins (Vega-Lite's default maxbins)\n            count = typeof binDef === 'object' && binDef.maxbins\n                ? binDef.maxbins : 10;\n        } else {\n            count = new Set(table.map((r: any) => r[cs.field])).size;\n        }\n        if (count <= 1) continue;\n\n        if (axis === 'x') {\n            xContinuousAsDiscrete = count;\n        } else {\n            yContinuousAsDiscrete = count;\n        }\n    }\n\n    // --- Facet layout ---\n    // Use pre-decided grid from filterOverflow when available.\n    // This avoids the circularity where wrapping depends on subplot\n    // width which depends on facet count which depends on wrapping.\n    let facetCols = 1;\n    let facetRows = 1;\n    if (facetGrid) {\n        facetCols = facetGrid.columns;\n        facetRows = facetGrid.rows;\n    } else {\n        if (nominalCount.column > 0) facetCols = nominalCount.column;\n        if (nominalCount.row > 0) facetRows = nominalCount.row;\n    }\n\n    // --- Facet subplot sizing ---\n    // Log-scale axes need more room so the minor grid lines (1,2,3…9 per\n    // decade) remain legible and act as the visual cue that it's log scale.\n    // Compute the number of orders of magnitude each axis spans; each\n    // decade needs ~40px minimum to avoid a dense wall of grid lines.\n    const LOG_PX_PER_DECADE = 40;\n    let logBoostX = 0;\n    let logBoostY = 0;\n    for (const axis of ['x', 'y'] as const) {\n        const cs = channelSemantics[axis];\n        if (!cs?.field || !cs.scaleType) continue;\n        if (cs.scaleType !== 'log' && cs.scaleType !== 'symlog') continue;\n        const vals = table\n            .map((r: any) => r[cs.field])\n            .filter((v: any) => typeof v === 'number' && v > 0 && isFinite(v));\n        if (vals.length < 2) continue;\n        const decades = Math.log10(Math.max(...vals)) - Math.log10(Math.min(...vals));\n        const needed = Math.ceil(Math.max(1, decades)) * LOG_PX_PER_DECADE;\n        if (axis === 'x') logBoostX = needed;\n        else logBoostY = needed;\n    }\n    const minContinuousSize = Math.max(10, minStepVal);\n    const minContinuousSizeX = Math.max(minContinuousSize, logBoostX);\n    const minContinuousSizeY = Math.max(minContinuousSize, logBoostY);\n\n    let subplotWidth: number;\n    if (facetCols > 1) {\n        const stretch = Math.min(maxStretchX, Math.pow(facetCols, facetElasticityVal));\n        subplotWidth = Math.round(Math.max(minContinuousSizeX,\n            (defaultChartWidth * stretch - fixW) / facetCols - gap));\n    } else {\n        subplotWidth = defaultChartWidth;\n    }\n\n    let subplotHeight: number;\n    if (facetRows > 1) {\n        const stretch = Math.min(maxStretchY, Math.pow(facetRows, facetElasticityVal));\n        subplotHeight = Math.round(Math.max(minContinuousSizeY,\n            (defaultChartHeight * stretch - fixH) / facetRows - gap));\n    } else {\n        subplotHeight = defaultChartHeight;\n    }\n\n    // --- Facet aspect-ratio resistance (non-gas-pressure charts) ---\n    // When faceting compresses one dimension (e.g. width ÷ columns), the\n    // aspect ratio drifts.  Line/area charts are very sensitive to this.\n    // For charts entering the 2D gas pressure path, AR resistance is\n    // handled inside the ideal-then-squeeze logic below. This block\n    // only applies when both axes are NOT continuous-non-banded.\n    const xIsContinuousNonBanded = xTotalNominalCount === 0 && xContinuousAsDiscrete === 0;\n    const yIsContinuousNonBanded = yTotalNominalCount === 0 && yContinuousAsDiscrete === 0;\n    const bothContinuousNonBanded = xIsContinuousNonBanded && yIsContinuousNonBanded;\n\n    if (facetAspectRatioResistance > 0 && !bothContinuousNonBanded\n        && (facetCols > 1 || facetRows > 1)) {\n        const baseAR = defaultChartWidth / defaultChartHeight;\n        const facetAR = subplotWidth / subplotHeight;\n        const arDrift = facetAR / baseAR; // <1 when panel got relatively narrower\n\n        if (arDrift < 1) {\n            // Panel is narrower than base → shrink height to compensate\n            subplotHeight = Math.round(\n                Math.max(minContinuousSizeY, subplotHeight * Math.pow(arDrift, facetAspectRatioResistance)),\n            );\n        } else if (arDrift > 1) {\n            // Panel is wider than base → shrink width to compensate\n            subplotWidth = Math.round(\n                Math.max(minContinuousSizeX, subplotWidth * Math.pow(1 / arDrift, facetAspectRatioResistance)),\n            );\n        }\n    }\n\n    // --- Gas pressure stretch for continuous non-banded axes ---\n    //\n    // Design: per-subplot baseline → pressure → AR blend → fit.\n    //\n    //   Baseline: each subplot gets a fair share of the canvas with\n    //             facet elasticity applied (cols^e / cols).\n    //   Step 1 — Gas pressure measures crowding against the per-subplot\n    //            baseline and produces per-axis raw stretches.\n    //   Step 2 — Decide AR: blend gas-pressure AR (density asymmetry)\n    //            with banking AR (perceptual slope optimization) in\n    //            log space.  Distribute gas-pressure area into the\n    //            blended AR.\n    //   Step 3 — Fit into budget: uniform scale-down so neither axis\n    //            exceeds maxStretch, preserving the AR.\n\n    if (bothContinuousNonBanded) {\n        const xCS = channelSemantics.x;\n        const yCS = channelSemantics.y;\n\n        if (xCS?.field && yCS?.field) {\n            const isTempX = (effectiveTypes.x || xCS.type) === 'temporal';\n            const isTempY = (effectiveTypes.y || yCS.type) === 'temporal';\n\n            const xNumeric: number[] = [];\n            const yNumeric: number[] = [];\n            for (const row of table) {\n                let xv = row[xCS.field];\n                let yv = row[yCS.field];\n                if (xv == null || yv == null) continue;\n                if (isTempX) xv = +new Date(xv);\n                else xv = +xv;\n                if (isTempY) yv = +new Date(yv);\n                else yv = +yv;\n                if (isNaN(xv) || isNaN(yv)) continue;\n                xNumeric.push(xv);\n                yNumeric.push(yv);\n            }\n\n            if (xNumeric.length > 1) {\n                const xMin = Math.min(...xNumeric);\n                const xMax = Math.max(...xNumeric);\n                const yMin = Math.min(...yNumeric);\n                const yMax = Math.max(...yNumeric);\n\n                // Expand to visual domain (include zero when axis starts at zero).\n                const xDomain: [number, number] = [xMin, xMax];\n                const yDomain: [number, number] = [yMin, yMax];\n                if (xCS.zero?.zero) {\n                    if (xDomain[0] > 0) xDomain[0] = 0;\n                    if (xDomain[1] < 0) xDomain[1] = 0;\n                }\n                if (yCS.zero?.zero) {\n                    if (yDomain[0] > 0) yDomain[0] = 0;\n                    if (yDomain[1] < 0) yDomain[1] = 0;\n                }\n\n                // Data-coverage guard: skip banking when zero dominates.\n                const xDataCoverage = (xDomain[1] - xDomain[0]) > 0\n                    ? (xMax - xMin) / (xDomain[1] - xDomain[0]) : 1;\n                const yDataCoverage = (yDomain[1] - yDomain[0]) > 0\n                    ? (yMax - yMin) / (yDomain[1] - yDomain[0]) : 1;\n                const BANKING_COVERAGE_THRESHOLD = 0.2;\n\n                // --- Gas pressure params ---\n                let gasPressureParams: GasPressureParams = DEFAULT_GAS_PRESSURE_PARAMS;\n                if (continuousMarkCrossSection != null) {\n                    if (typeof continuousMarkCrossSection === 'number') {\n                        gasPressureParams = { ...DEFAULT_GAS_PRESSURE_PARAMS, markCrossSection: continuousMarkCrossSection };\n                    } else {\n                        const maxCS = Math.max(continuousMarkCrossSection.x, continuousMarkCrossSection.y);\n                        gasPressureParams = {\n                            ...DEFAULT_GAS_PRESSURE_PARAMS,\n                            markCrossSection: maxCS,\n                            markCrossSectionX: continuousMarkCrossSection.x,\n                            markCrossSectionY: continuousMarkCrossSection.y,\n                            ...(continuousMarkCrossSection.elasticity != null && { elasticity: continuousMarkCrossSection.elasticity }),\n                            ...(continuousMarkCrossSection.maxStretch != null && { maxStretch: continuousMarkCrossSection.maxStretch }),\n                        };\n\n                        if (continuousMarkCrossSection.seriesCountAxis) {\n                            const resolvedAxis = continuousMarkCrossSection.seriesCountAxis === 'auto'\n                                ? 'y' : continuousMarkCrossSection.seriesCountAxis;\n                            const nSeries = countDistinctSeries(channelSemantics, table);\n                            if (resolvedAxis === 'y') {\n                                gasPressureParams.yItemCountOverride = nSeries;\n                            } else {\n                                gasPressureParams.xItemCountOverride = nSeries;\n                            }\n                        }\n                    }\n                }\n\n                // --- Per-subplot baseline canvas ---\n                // Gas pressure must measure crowding against the actual\n                // per-subplot space, not the full canvas.  When faceted,\n                // each subplot gets a share of the canvas that includes\n                // facet elasticity (the same formula used for discrete\n                // axes): `canvas × cols^elasticity / cols`.  This way\n                // 2 columns don't naively halve the space — some stretch\n                // is assumed before gas pressure even kicks in.\n                const perSubplotCanvasW = facetCols > 1\n                    ? Math.max(minContinuousSizeX,\n                        (defaultChartWidth * Math.min(maxStretchX, Math.pow(facetCols, facetElasticityVal)) - fixW)\n                        / facetCols - gap)\n                    : defaultChartWidth;\n                const perSubplotCanvasH = facetRows > 1\n                    ? Math.max(minContinuousSizeY,\n                        (defaultChartHeight * Math.min(maxStretchY, Math.pow(facetRows, facetElasticityVal)) - fixH)\n                        / facetRows - gap)\n                    : defaultChartHeight;\n\n                // --- Gas pressure: per-axis raw stretches ---\n                const idealResult = computeGasPressure(\n                    xNumeric, yNumeric, xDomain, yDomain,\n                    perSubplotCanvasW, perSubplotCanvasH, gasPressureParams,\n                );\n\n                const isConnected = typeof continuousMarkCrossSection === 'object'\n                    && !!continuousMarkCrossSection.seriesCountAxis;\n                const useBanking = xDataCoverage >= BANKING_COVERAGE_THRESHOLD\n                    && yDataCoverage >= BANKING_COVERAGE_THRESHOLD;\n\n                let idealW: number;\n                let idealH: number;\n\n                // Gas pressure's native per-axis dimensions (uncapped).\n                const rawW = perSubplotCanvasW * idealResult.rawStretchX;\n                const rawH = perSubplotCanvasH * idealResult.rawStretchY;\n\n                if (useBanking) {\n                    // ── Step 1: Decide AR ──────────────────────────────\n                    // Blend gas-pressure AR (which axis is more crowded)\n                    // with banking AR (perceptual slope optimization).\n                    const seriesFields: string[] = [];\n                    const colorField = channelSemantics.color?.field;\n                    const detailField = channelSemantics.detail?.field;\n                    if (colorField) seriesFields.push(colorField);\n                    if (detailField && detailField !== colorField) seriesFields.push(detailField);\n\n                    const perPointSeriesKeys: string[] = new Array(xNumeric.length);\n                    if (seriesFields.length === 0) {\n                        perPointSeriesKeys.fill('');\n                    } else {\n                        let idx = 0;\n                        for (const row of table) {\n                            const xv = xCS?.field ? row[xCS.field] : undefined;\n                            const yv = yCS?.field ? row[yCS.field] : undefined;\n                            if (xv == null || yv == null) continue;\n                            const xn = isTempX ? +new Date(xv) : +xv;\n                            const yn = isTempY ? +new Date(yv) : +yv;\n                            if (isNaN(xn) || isNaN(yn)) continue;\n                            perPointSeriesKeys[idx++] = seriesFields\n                                .map(f => String(row[f] ?? '')).join('\\x00');\n                        }\n                    }\n\n                    const bankingAR = computeBankingAR(\n                        xNumeric, yNumeric, xDomain, yDomain,\n                        perPointSeriesKeys, isConnected,\n                    );\n\n                    // ── Step 2: Blend AR + distribute area ────────────\n                    // Gas pressure knows which axis is crowded (per-axis\n                    // stretch).  Banking knows the perceptual ideal AR.\n                    // Blend in log space so both signals contribute:\n                    //   gasAR reflects density asymmetry (X crowded → landscape)\n                    //   bankingAR reflects slope perception\n                    const BANKING_BLEND = 0.5;\n                    const gasAR = rawW / rawH;\n                    const blendedAR = gasAR > 0 && bankingAR > 0\n                        ? Math.exp((1 - BANKING_BLEND) * Math.log(gasAR)\n                            + BANKING_BLEND * Math.log(bankingAR))\n                        : bankingAR;\n\n                    // Total area from gas pressure (capped so subplot\n                    // doesn't blow past per-subplot budget before fit).\n                    const rawArea = rawW * rawH;\n                    const maxArea = perSubplotCanvasW * perSubplotCanvasH * Math.max(maxStretchX, maxStretchY);\n                    const area = Math.min(rawArea, maxArea);\n\n                    idealW = Math.sqrt(area * blendedAR);\n                    idealH = Math.sqrt(area / blendedAR);\n                } else {\n                    // Banking skipped (zero dominates): gas pressure shape.\n                    idealW = rawW;\n                    idealH = rawH;\n                }\n\n                // ── Step 3: Fit into budget, preserving AR ───────────\n                // Hard ceiling per subplot: canvas × maxStretch shared\n                // across facet panels.\n                const availW = facetCols > 1\n                    ? Math.max(minContinuousSizeX, (defaultChartWidth * maxStretchX - fixW) / facetCols - gap)\n                    : defaultChartWidth * maxStretchX;\n                const availH = facetRows > 1\n                    ? Math.max(minContinuousSizeY, (defaultChartHeight * maxStretchY - fixH) / facetRows - gap)\n                    : defaultChartHeight * maxStretchY;\n\n                // Scale down to fit: if either axis exceeds its budget,\n                // shrink both axes by the tighter ratio so neither\n                // exceeds AND the AR is preserved.\n                const scaleX = idealW > availW ? availW / idealW : 1;\n                const scaleY = idealH > availH ? availH / idealH : 1;\n                const fitScale = Math.min(scaleX, scaleY);\n\n                let finalW = idealW * fitScale;\n                let finalH = idealH * fitScale;\n\n                // Enforce minimums (may slightly distort AR at extremes).\n                finalW = Math.max(finalW, minContinuousSizeX);\n                finalH = Math.max(finalH, minContinuousSizeY);\n\n                subplotWidth = Math.round(finalW);\n                subplotHeight = Math.round(finalH);\n            }\n        }\n    } else if (xIsContinuousNonBanded || yIsContinuousNonBanded) {\n        const contAxis = xIsContinuousNonBanded ? 'x' : 'y';\n        const otherAxisHasDiscreteItems = contAxis === 'x'\n            ? (yTotalNominalCount > 0 || yContinuousAsDiscrete > 0)\n            : (xTotalNominalCount > 0 || xContinuousAsDiscrete > 0);\n\n        let seriesStretchApplied = false;\n        if (typeof continuousMarkCrossSection === 'object' && continuousMarkCrossSection.seriesCountAxis) {\n            const resolvedAxis = continuousMarkCrossSection.seriesCountAxis === 'auto'\n                ? contAxis : continuousMarkCrossSection.seriesCountAxis;\n\n            if (resolvedAxis === contAxis) {\n                const sigmaPerSeries = contAxis === 'x'\n                    ? continuousMarkCrossSection.x\n                    : continuousMarkCrossSection.y;\n                const baseDim = contAxis === 'x' ? subplotWidth : subplotHeight;\n                const nSeries = countDistinctSeries(channelSemantics, table);\n                const pressure = (nSeries * sigmaPerSeries) / baseDim;\n\n                const elast = continuousMarkCrossSection.elasticity ?? DEFAULT_GAS_PRESSURE_PARAMS.elasticity;\n                const maxS = continuousMarkCrossSection.maxStretch ?? DEFAULT_GAS_PRESSURE_PARAMS.maxStretch;\n\n                if (pressure > 1) {\n                    const stretch = Math.min(maxS, Math.pow(pressure, elast));\n                    if (contAxis === 'x') {\n                        subplotWidth = Math.round(subplotWidth * stretch);\n                    } else {\n                        subplotHeight = Math.round(subplotHeight * stretch);\n                    }\n                }\n                seriesStretchApplied = true;\n            }\n        }\n\n        if (!seriesStretchApplied && !otherAxisHasDiscreteItems) {\n            const contCS = channelSemantics[contAxis];\n            if (contCS?.field) {\n                const isTemporal = (effectiveTypes[contAxis] || contCS.type) === 'temporal';\n                const contValues: number[] = [];\n                for (const row of table) {\n                    let v = row[contCS.field];\n                    if (v == null) continue;\n                    if (isTemporal) v = +new Date(v);\n                    else v = +v;\n                    if (!isNaN(v)) contValues.push(v);\n                }\n                const sigma1d = Math.sqrt(DEFAULT_GAS_PRESSURE_PARAMS.markCrossSection);\n                const baseDim = contAxis === 'x' ? subplotWidth : subplotHeight;\n                const pressure1d = (contValues.length * sigma1d) / baseDim;\n                if (pressure1d > 1) {\n                    const stretch1d = Math.min(\n                        DEFAULT_GAS_PRESSURE_PARAMS.maxStretch,\n                        Math.pow(pressure1d, DEFAULT_GAS_PRESSURE_PARAMS.elasticity),\n                    );\n                    if (contAxis === 'x') {\n                        subplotWidth = Math.round(subplotWidth * stretch1d);\n                    } else {\n                        subplotHeight = Math.round(subplotHeight * stretch1d);\n                    }\n                }\n            }\n        }\n    }\n\n    // --- Elastic stretch for discrete axes ---\n    // X axis grows under its width budget (βx); Y under its height budget (βy).\n    const elasticParamsX: ElasticStretchParams = {\n        elasticity: elasticityVal,\n        maxStretch: maxStretchX,\n        defaultStepSize,\n        minStep: minStepVal,\n    };\n    const elasticParamsY: ElasticStretchParams = {\n        elasticity: elasticityVal,\n        maxStretch: maxStretchY,\n        defaultStepSize,\n        minStep: minStepVal,\n    };\n\n    const xAxis = computeAxisStep(xTotalNominalCount, xContinuousAsDiscrete, subplotWidth, elasticParamsX);\n    const yAxis = computeAxisStep(yTotalNominalCount, yContinuousAsDiscrete, subplotHeight, elasticParamsY);\n\n    const xIsDiscrete = xTotalNominalCount > 0;\n    const yIsDiscrete = yTotalNominalCount > 0;\n\n    const xHasGrouping = groupAxis === 'x' && nominalCount.group > 0;\n    const yHasGrouping = groupAxis === 'y' && nominalCount.group > 0;\n\n    let xStepSize: number;\n    let yStepSize: number;\n    let xStepUnit: 'item' | 'group' | undefined;\n    let yStepUnit: 'item' | 'group' | undefined;\n\n    if (xIsDiscrete && xHasGrouping) {\n        const itemsPerGroup = nominalCount.group;\n        const defaultGroupStep = itemsPerGroup * maxStepSize;\n        const minGroupStep = Math.max(Math.ceil(MIN_GROUP_GAP_PX / stepPaddingVal), 2 * itemsPerGroup);\n        const groupAxis = computeAxisStep(nominalCount.x, 0, subplotWidth, elasticParamsX);\n        const groupStep = Math.max(minGroupStep, Math.min(defaultGroupStep, groupAxis.step));\n        xStepSize = groupStep;\n        xStepUnit = 'group';\n    } else if (xIsDiscrete) {\n        xStepSize = Math.max(minStepVal, Math.min(maxStepSize, xAxis.step));\n    } else if (xContinuousAsDiscrete > 0) {\n        xStepSize = Math.max(minStepVal, Math.min(maxStepSize, xAxis.step));\n    } else {\n        xStepSize = defaultStepSize;\n    }\n\n    if (yIsDiscrete && yHasGrouping) {\n        const itemsPerGroup = nominalCount.group;\n        const defaultGroupStep = itemsPerGroup * maxStepSize;\n        const minGroupStep = Math.max(Math.ceil(MIN_GROUP_GAP_PX / stepPaddingVal), 2 * itemsPerGroup);\n        const groupAxis = computeAxisStep(nominalCount.y, 0, subplotHeight, elasticParamsY);\n        const groupStep = Math.max(minGroupStep, Math.min(defaultGroupStep, groupAxis.step));\n        yStepSize = groupStep;\n        yStepUnit = 'group';\n    } else if (yIsDiscrete) {\n        yStepSize = Math.max(minStepVal, Math.min(maxStepSize, yAxis.step));\n    } else if (yContinuousAsDiscrete > 0) {\n        yStepSize = Math.max(minStepVal, Math.min(maxStepSize, yAxis.step));\n    } else {\n        yStepSize = defaultStepSize;\n    }\n\n    // --- Banded continuous canvas size ---\n    for (const axis of ['x', 'y'] as const) {\n        const count = axis === 'x' ? xContinuousAsDiscrete : yContinuousAsDiscrete;\n        if (count <= 0) continue;\n        const stepSize = axis === 'x' ? xStepSize : yStepSize;\n        const continuousSize = Math.round(stepSize * (count + 1));\n        if (axis === 'x') {\n            subplotWidth = continuousSize;\n        } else {\n            subplotHeight = continuousSize;\n        }\n    }\n\n    // --- Unified stretch budget ------------------------------------------------\n    // Cap the per-subplot dimensions so total canvas never exceeds\n    // canvasWidth × maxStretch (and canvasHeight × maxStretch).\n    // Formula: effectiveW = W × maxStretch − fixedPad; each panel costs subplot + gap.\n    const maxSubplotW = (defaultChartWidth * maxStretchX - fixW) / facetCols - gap;\n    const maxSubplotH = (defaultChartHeight * maxStretchY - fixH) / facetRows - gap;\n\n    // Clamp step sizes for discrete/banded axes so VL step-based\n    // sizing respects the same budget.\n    // When step unit is 'group', divide by the number of groups (nominalCount)\n    // rather than the total item count (groups × items-per-group).\n    if (xTotalNominalCount > 0) {\n        const divisor = xStepUnit === 'group' ? nominalCount.x : xTotalNominalCount;\n        const cap = Math.max(minStepVal, Math.floor(maxSubplotW / divisor));\n        if (xStepSize > cap) xStepSize = cap;\n    }\n    if (xContinuousAsDiscrete > 0) {\n        const cap = Math.max(minStepVal, Math.floor(maxSubplotW / (xContinuousAsDiscrete + 1)));\n        if (xStepSize > cap) xStepSize = cap;\n    }\n    if (yTotalNominalCount > 0) {\n        const divisor = yStepUnit === 'group' ? nominalCount.y : yTotalNominalCount;\n        const cap = Math.max(minStepVal, Math.floor(maxSubplotH / divisor));\n        if (yStepSize > cap) yStepSize = cap;\n    }\n    if (yContinuousAsDiscrete > 0) {\n        const cap = Math.max(minStepVal, Math.floor(maxSubplotH / (yContinuousAsDiscrete + 1)));\n        if (yStepSize > cap) yStepSize = cap;\n    }\n\n    // Recompute banded subplot size after step clamping.\n    for (const axis of ['x', 'y'] as const) {\n        const count = axis === 'x' ? xContinuousAsDiscrete : yContinuousAsDiscrete;\n        if (count <= 0) continue;\n        const stepSize = axis === 'x' ? xStepSize : yStepSize;\n        if (axis === 'x') subplotWidth = Math.round(stepSize * (count + 1));\n        else subplotHeight = Math.round(stepSize * (count + 1));\n    }\n\n    // --- Nominal discrete subplot sizing ---\n    // For nominal discrete axes, one backend (VL) overrides subplotWidth\n    // with step-based sizing (width:{step:N}), so the subplot dimension\n    // doesn't matter.  Other backends (Chart.js, ECharts) fill the canvas\n    // and divide evenly among categories — for them, the subplot dimension\n    // IS the canvas width.\n    //\n    // Ensure the subplot is at least as wide as canvasSize (the user's\n    // requested chart size) so backends that fill the canvas get generous\n    // bars when there are few categories.  The subplot only exceeds\n    // canvasSize when faceting shrinks it, which is already handled above.\n\n    // Clamp continuous subplot dimensions.\n    subplotWidth = Math.min(subplotWidth, Math.round(maxSubplotW));\n    subplotHeight = Math.min(subplotHeight, Math.round(maxSubplotH));\n\n    // --- Band AR blending ---\n    // When one axis is banded (discrete) and the other is continuous,\n    // each band has a natural AR = continuousSize / stepSize.  If the\n    // actual band AR exceeds the target, blend the subplot AR toward\n    // the target (in log space) to avoid excessively tall/wide bands.\n    const targetBandAR = options.targetBandAR;\n    if (targetBandAR && targetBandAR > 0) {\n        const xIsBanded = xTotalNominalCount > 0 || xContinuousAsDiscrete > 0;\n        const yIsBanded = yTotalNominalCount > 0 || yContinuousAsDiscrete > 0;\n\n        if (xIsBanded && !yIsBanded) {\n            // X is banded, Y is continuous → band AR = subplotHeight / xStepSize\n            const actualBandAR = subplotHeight / xStepSize;\n            if (actualBandAR > targetBandAR) {\n                const idealH = xStepSize * targetBandAR;\n                // Blend: 50/50 between actual and target in log space.\n                const blendedH = Math.exp(\n                    0.5 * Math.log(subplotHeight) + 0.5 * Math.log(idealH));\n                subplotHeight = Math.round(\n                    Math.max(minContinuousSizeY, Math.min(blendedH, subplotHeight)));\n            }\n        } else if (yIsBanded && !xIsBanded) {\n            // Y is banded, X is continuous → band AR = subplotWidth / yStepSize\n            const actualBandAR = subplotWidth / yStepSize;\n            if (actualBandAR > targetBandAR) {\n                const idealW = yStepSize * targetBandAR;\n                const blendedW = Math.exp(\n                    0.5 * Math.log(subplotWidth) + 0.5 * Math.log(idealW));\n                subplotWidth = Math.round(\n                    Math.max(minContinuousSizeX, Math.min(blendedW, subplotWidth)));\n            }\n        }\n    }\n\n    // --- Label sizing ---\n    // A temporal/numeric field used as a BANDED axis (one bar per value) is\n    // \"continuous-as-discrete\": its tick labels sit one-per-band exactly like a\n    // nominal axis, so they must follow the same discrete sizing ladder (shrink\n    // — and rotate when bands are narrow) rather than staying at the full\n    // continuous base font. Otherwise dense date/number bands render oversized\n    // labels that feel too large for their band and crowd together.\n    const xHasDiscreteItems = xTotalNominalCount > 0 || xContinuousAsDiscrete > 0;\n    const yHasDiscreteItems = yTotalNominalCount > 0 || yContinuousAsDiscrete > 0;\n    // Canvas-adaptive fonts: descend the tick ladder from the backend's native\n    // base, and derive header/legend sizes. Scaled by the (sub)plot's smaller\n    // dimension so small multiples shrink and large single views grow subtly.\n    const fontSizing = computeFontSizing(Math.min(subplotWidth, subplotHeight), {\n        baseLabelFontSize: options.baseLabelFontSize,\n        baseTitleFontSize: options.baseTitleFontSize,\n    });\n    const labelOpts = { baseFont: fontSizing.tickBase, minFont: 6 };\n    let xLabel = computeLabelSizing(xStepSize, xHasDiscreteItems, labelOpts);\n    let yLabel = computeLabelSizing(yStepSize, yHasDiscreteItems, labelOpts);\n\n    if (xHasDiscreteItems) {\n        const xf = channelSemantics.x?.field;\n        const xt = effectiveTypes.x || channelSemantics.x?.type;\n        const stats = computeDiscreteLabelStats(xf, table);\n        if (stats) {\n            // Numeric-like labels (declared quantitative, or all values parse as\n            // numbers — years, bins, IDs) compete for the band's width when laid\n            // out horizontally. A continuous field split into many narrow bands\n            // yields many/wide numbers that crowd. Decide horizontal vs. angled\n            // by whether the widest label fits within one band.\n            const numericLike = xt === 'quantitative' || stats.allNumeric;\n            let labelPx = stats.maxLen * xLabel.fontSize * APPROX_CHAR_WIDTH_RATIO;\n            const fewShortStrings = !numericLike\n                && stats.count <= VL_SHORT_DISCRETE_CATEGORY_COUNT\n                && stats.maxLen <= VL_SHORT_DISCRETE_LABEL_MAX_LEN;\n\n            if (fewShortStrings || (numericLike && labelPx <= xStepSize)) {\n                // We want horizontal labels here. But a small number of short\n                // string categories can still collide when the band step is\n                // narrower than the widest label (e.g. box marks declare a tiny\n                // defaultBandSize). Before committing to horizontal, make sure\n                // the label actually fits — widen the band within the stretch\n                // budget if it can, otherwise angle the labels instead of\n                // letting them overlap. (xStepSize is the per-label band width:\n                // the item step when ungrouped, the group step when grouped.)\n                if (labelPx > xStepSize) {\n                    const desiredStep = Math.ceil(labelPx) + 6; // label width + inter-label gap\n                    const cap = Math.max(minStepVal, Math.floor(maxSubplotW / stats.count));\n                    if (desiredStep <= cap) {\n                        xStepSize = Math.max(xStepSize, desiredStep);\n                        xLabel = computeLabelSizing(xStepSize, xHasDiscreteItems, labelOpts);\n                        labelPx = stats.maxLen * xLabel.fontSize * APPROX_CHAR_WIDTH_RATIO;\n                    }\n                }\n\n                if (labelPx <= xStepSize) {\n                    // Fits horizontally (already, or after widening the band).\n                    // Must be explicit: omitting labelAngle leaves VL defaults (e.g. -45° on ordinal).\n                    xLabel = {\n                        ...xLabel,\n                        labelAngle: 0,\n                        labelAlign: 'center',\n                        labelBaseline: 'top',\n                    };\n                } else {\n                    // Even the stretch budget can't fit a wide-enough band →\n                    // angle the labels rather than let them run together.\n                    xLabel = {\n                        ...xLabel,\n                        labelAngle: -45,\n                        labelAlign: 'right',\n                        labelBaseline: 'top',\n                    };\n                }\n            } else if (numericLike && labelPx > xStepSize && xLabel.labelAngle === undefined) {\n                // Numeric labels that don't fit horizontally and weren't already\n                // rotated by step-based sizing (which only rotates at narrow\n                // steps). Without this, VL keeps them horizontal and the numbers\n                // overlap. Rotate to -45°.\n                xLabel = {\n                    ...xLabel,\n                    labelAngle: -45,\n                    labelAlign: 'right',\n                    labelBaseline: 'top',\n                };\n            }\n        }\n    }\n    if (yHasDiscreteItems) {\n        const yf = channelSemantics.y?.field;\n        const yt = effectiveTypes.y || channelSemantics.y?.type;\n        if (discreteYAxisShouldUseHorizontalLabels(yf, yt, table)) {\n            yLabel = {\n                ...yLabel,\n                labelAngle: 0,\n                labelAlign: 'right',\n                labelBaseline: 'middle',\n            };\n        }\n    }\n\n    // Keep tick labels consistent across axes. A continuous value axis stays at\n    // the base font, but a banded axis shrinks its labels as bands tighten — so\n    // the value \"numbers\" can end up visibly larger than the category \"text\".\n    // Unify both tick fonts to the smaller of the two so they read as one size.\n    const unifiedTickFont = Math.min(xLabel.fontSize, yLabel.fontSize);\n    if (xLabel.fontSize !== unifiedTickFont) xLabel = { ...xLabel, fontSize: unifiedTickFont };\n    if (yLabel.fontSize !== unifiedTickFont) yLabel = { ...yLabel, fontSize: unifiedTickFont };\n\n    return {\n        subplotWidth,\n        subplotHeight,\n        xStep: xStepSize,\n        yStep: yStepSize,\n        xStepUnit,\n        yStepUnit,\n        xContinuousAsDiscrete,\n        yContinuousAsDiscrete,\n        xNominalCount: xTotalNominalCount,\n        yNominalCount: yTotalNominalCount,\n        xLabel,\n        yLabel,\n        titleFontSize: fontSizing.titleFontSize,\n        legendFontSize: fontSizing.legendFontSize,\n        stepPadding: stepPaddingVal,\n        facet: (facetCols > 1 || facetRows > 1) ? {\n            columns: facetCols,\n            rows: facetRows,\n            subplotWidth,\n            subplotHeight,\n        } : undefined,\n        effectiveFacetGap: gap,\n        truncations: [],  // Overflow truncations are handled by filterOverflow\n    };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Count distinct series (color/detail categories) from channel semantics.\n */\nfunction countDistinctSeries(\n    channelSemantics: Record<string, ChannelSemantics>,\n    data: any[],\n): number {\n    const seriesFields: string[] = [];\n    const colorField = channelSemantics.color?.field;\n    const detailField = channelSemantics.detail?.field;\n    if (colorField) seriesFields.push(colorField);\n    if (detailField && detailField !== colorField) seriesFields.push(detailField);\n\n    if (seriesFields.length === 0) return 1;\n\n    const seriesKeys = new Set<string>();\n    for (const row of data) {\n        const key = seriesFields.map(f => String(row[f] ?? '')).join('\\x00');\n        seriesKeys.add(key);\n    }\n    return seriesKeys.size;\n}\n\n/**\n * Compute the ideal aspect ratio for a both-continuous chart.\n *\n * Dispatches to two strategies depending on mark type:\n *\n * - **Scatter / point** (`isConnected = false`): Uses the normalized\n *   standard-deviation ratio of the point cloud — a unit-independent\n *   shape measure.  Dampened 0.3× toward 1.0 so scatter stays near\n *   square.\n *\n * - **Connected marks** (line/area/bump, `isConnected = true`): Uses\n *   multi-scale banking to 45° (Heer & Agrawala 2006).  Slopes are\n *   computed at multiple octave-band smoothing levels and combined via\n *   geometric mean so that trend, periodicity, and noise each\n *   contribute proportionally — avoiding the dense-data failure mode\n *   of Cleveland's single-scale median.\n *\n * @param xValues     Numeric X values\n * @param yValues     Numeric Y values (parallel array)\n * @param xDomain     [min, max] of the visual X axis\n * @param yDomain     [min, max] of the visual Y axis\n * @param seriesKeys  Per-point series key ('' if no series)\n * @param isConnected Whether the mark connects points (line/area vs scatter)\n * @returns Ideal AR (width/height). Clamped to [0.5, 3.0].\n */\nfunction computeBankingAR(\n    xValues: number[],\n    yValues: number[],\n    xDomain: [number, number],\n    yDomain: [number, number],\n    seriesKeys: string[],\n    isConnected: boolean,\n): number {\n    const MIN_AR = 0.5;\n    const MAX_AR = 3.0;\n\n    const xRange = xDomain[1] - xDomain[0];\n    const yRange = yDomain[1] - yDomain[0];\n    if (xRange <= 0 || yRange <= 0) return 1;\n\n    // ── Scatter: σ-ratio ──────────────────────────────────────────────\n    if (!isConnected) {\n        const n = xValues.length;\n        let sumX = 0, sumY = 0;\n        for (let i = 0; i < n; i++) {\n            sumX += (xValues[i] - xDomain[0]) / xRange;\n            sumY += (yValues[i] - yDomain[0]) / yRange;\n        }\n        const meanX = sumX / n;\n        const meanY = sumY / n;\n        let varX = 0, varY = 0;\n        for (let i = 0; i < n; i++) {\n            const dx = (xValues[i] - xDomain[0]) / xRange - meanX;\n            const dy = (yValues[i] - yDomain[0]) / yRange - meanY;\n            varX += dx * dx;\n            varY += dy * dy;\n        }\n        const sdX = Math.sqrt(varX / n);\n        const sdY = Math.sqrt(varY / n);\n        if (sdY <= 0) return MAX_AR;\n        if (sdX <= 0) return MIN_AR;\n\n        const sdRatio = sdX / sdY;\n        const ar = sdRatio > 1\n            ? 1 + (sdRatio - 1) * 0.3\n            : 1 - (1 - sdRatio) * 0.3;\n        return Math.min(MAX_AR, Math.max(MIN_AR, ar));\n    }\n\n    // ── Connected marks: multi-scale banking (Heer & Agrawala 2006) ──\n\n    // Group by series and sort by X.\n    const seriesMap = new Map<string, { x: number; y: number }[]>();\n    for (let i = 0; i < xValues.length; i++) {\n        const key = seriesKeys[i];\n        let arr = seriesMap.get(key);\n        if (!arr) { arr = []; seriesMap.set(key, arr); }\n        arr.push({ x: xValues[i], y: yValues[i] });\n    }\n    for (const pts of seriesMap.values()) {\n        pts.sort((a, b) => a.x - b.x);\n    }\n\n    // Collect per-scale median absolute slopes, then combine with\n    // geometric mean across scales.  Each scale is a box-filter\n    // smoothing at window width 2^k (k = 0, 1, 2, …).\n    // Scale 0 = raw data (Cleveland's original).\n    const scaleMedians: number[] = [];\n\n    // Determine max scale: largest power of 2 that still leaves ≥ 3\n    // points in the longest series after smoothing.\n    let maxSeriesLen = 0;\n    for (const pts of seriesMap.values()) {\n        if (pts.length > maxSeriesLen) maxSeriesLen = pts.length;\n    }\n    const maxScale = Math.max(0, Math.floor(Math.log2(maxSeriesLen)) - 1);\n\n    for (let scale = 0; scale <= maxScale; scale++) {\n        const windowSize = 1 << scale;  // 1, 2, 4, 8, …\n        const absSlopes: number[] = [];\n\n        for (const pts of seriesMap.values()) {\n            // Smooth: non-overlapping bucket averages of `windowSize` points.\n            // The last bucket may be smaller — included as-is.\n            const n = pts.length;\n            if (n < 2) continue;\n\n            const smoothed: { x: number; y: number }[] = [];\n            for (let i = 0; i < n; i += windowSize) {\n                const end = Math.min(i + windowSize, n);\n                let sx = 0, sy = 0;\n                for (let j = i; j < end; j++) {\n                    sx += pts[j].x;\n                    sy += pts[j].y;\n                }\n                const cnt = end - i;\n                smoothed.push({ x: sx / cnt, y: sy / cnt });\n            }\n\n            // Compute slopes between consecutive smoothed points.\n            for (let i = 1; i < smoothed.length; i++) {\n                const dx = (smoothed[i].x - smoothed[i - 1].x) / xRange;\n                const dy = (smoothed[i].y - smoothed[i - 1].y) / yRange;\n                if (dx === 0) continue;\n                absSlopes.push(Math.abs(dy / dx));\n            }\n        }\n\n        if (absSlopes.length === 0) continue;\n\n        // Median absolute slope at this scale.\n        absSlopes.sort((a, b) => a - b);\n        const mid = absSlopes.length >> 1;\n        const median = absSlopes.length % 2 === 1\n            ? absSlopes[mid]\n            : (absSlopes[mid - 1] + absSlopes[mid]) / 2;\n        if (median > 0) {\n            scaleMedians.push(median);\n        }\n    }\n\n    if (scaleMedians.length === 0) return 1;\n\n    // Geometric mean of per-scale median slopes.\n    // This gives equal weight to each octave band: trend (coarse),\n    // periodicity (middle), and noise (fine) all contribute.\n    let logSum = 0;\n    for (const m of scaleMedians) {\n        logSum += Math.log(m);\n    }\n    const combinedSlope = Math.exp(logSum / scaleMedians.length);\n\n    if (combinedSlope <= 0) return MAX_AR;\n\n    // Banking to 45°: display_slope = s_norm × (H/W).\n    // For median |display_slope| = 1:  H/W = 1/median(|s_norm|),\n    // so W/H = median(|s_norm|) = combinedSlope.\n    //\n    // No dampening here — the caller (computeLayout) blends banking AR\n    // with gas-pressure AR at 50/50, which already moderates it.\n    // Applying dampening on top of the blend would double-moderate.\n\n    // Landscape floor for connected marks: time series, line charts,\n    // and area charts are conventionally landscape.  Banking can push\n    // wider (when slopes are steep) but never portrait — the gentle-\n    // slope majority in typical time series would otherwise dominate\n    // the median and produce portrait, compressing the time axis.\n    const ar = Math.max(1.0, combinedSlope);\n    return Math.min(MAX_AR, Math.max(MIN_AR, ar));\n}\n\n// ---------------------------------------------------------------------------\n// Public: computeChannelBudgets\n// ---------------------------------------------------------------------------\n\n/**\n * Compute per-channel maximum values that can fit on the canvas.\n *\n * Uses the **most conservative** assumptions:\n *   - minStep  (smallest px per discrete item)\n *   - minSubplotSize (smallest subplot for continuous axes)\n *   - maxStretch (maximum canvas stretching)\n *\n * This is Step 0c-a in the pipeline — it runs before filterOverflow\n * and produces the budgets that filterOverflow consumes.\n *\n * Pipeline:  computeChannelBudgets → filterOverflow → computeLayout\n *\n * @param channelSemantics  Phase 0 output (field, type per channel)\n * @param declaration       Template layout declaration\n * @param data              Full data table (pre-overflow)\n * @param canvasSize        Target canvas dimensions\n * @param options           Assembly options\n * @returns                 ChannelBudgets with per-channel max-to-keep\n */\nexport function computeChannelBudgets(\n    channelSemantics: Record<string, ChannelSemantics>,\n    declaration: LayoutDeclaration,\n    data: any[],\n    canvasSize: { width: number; height: number },\n    options: AssembleOptions,\n): ChannelBudgets {\n    const {\n        minStep: minStepVal = 6,\n        stepPadding: stepPaddingVal = 0.1,\n        maxColorValues: maxColorVal = 24,\n    } = options;\n\n    const { x: maxStretchX, y: maxStretchY } = resolveStretchCaps(options);\n\n    const fixW = options.facetFixedPadding?.width ?? 0;\n    const fixH = options.facetFixedPadding?.height ?? 0;\n    const gap = options.facetGap ?? 0;\n\n    const isDiscreteType = (t: string | undefined) => t === 'nominal' || t === 'ordinal';\n    const effectiveType = (ch: string): string | undefined =>\n        declaration.resolvedTypes?.[ch] ?? channelSemantics[ch]?.type;\n\n    // --- 1. Facet grid (delegates to computeFacetGrid) ---\n    const facetGrid = computeFacetGrid(\n        channelSemantics, declaration, data, canvasSize, options,\n    );\n    const facetCols = facetGrid?.columns ?? 1;\n    const facetRows = facetGrid?.rows ?? 1;\n\n    // --- 2. Per-subplot budget at maximum stretch ---\n    const maxSubplotW = Math.max(\n        options.minSubplotSize ?? 60,\n        (canvasSize.width * maxStretchX - fixW) / facetCols - gap,\n    );\n    const maxSubplotH = Math.max(\n        options.minSubplotSize ?? 60,\n        (canvasSize.height * maxStretchY - fixH) / facetRows - gap,\n    );\n\n    // --- 3. Grouping detection ---\n    const groupField = channelSemantics.group?.field;\n    let groupCount = 0;\n    let groupAxis: 'x' | 'y' | undefined;\n    if (groupField) {\n        groupCount = new Set(data.map(r => r[groupField])).size;\n        if (isDiscreteType(effectiveType('x'))) groupAxis = 'x';\n        else if (isDiscreteType(effectiveType('y'))) groupAxis = 'y';\n    }\n\n    const xGroupMultiplier = (groupAxis === 'x' && groupCount > 1) ? groupCount : 1;\n    const yGroupMultiplier = (groupAxis === 'y' && groupCount > 1) ? groupCount : 1;\n\n    const MIN_GROUP_GAP_PX = 3;\n    const xMinGroupStep = xGroupMultiplier > 1\n        ? Math.max(Math.ceil(MIN_GROUP_GAP_PX / stepPaddingVal), 2 * xGroupMultiplier)\n        : minStepVal;\n    const yMinGroupStep = yGroupMultiplier > 1\n        ? Math.max(Math.ceil(MIN_GROUP_GAP_PX / stepPaddingVal), 2 * yGroupMultiplier)\n        : minStepVal;\n\n    // --- 4. Per-channel budgets ---\n    let maxXToKeep = Math.floor(maxSubplotW / xMinGroupStep);\n    let maxYToKeep = Math.floor(maxSubplotH / yMinGroupStep);\n\n    // --- 5. Faceted-chart canvas cap ---\n    // When a busy discrete axis makes each subplot wider than the\n    // un-stretched canvas, cap axis items to fit within one canvas\n    // width/height.  This lets subplots be narrower, potentially fitting\n    // more facet columns — reducing overall chart height.\n    //\n    // Example: 70 counties on X × 20 states on column.  Without the cap,\n    // minSubplotWidth = 70 × 6 = 420 → only 1 facet column fits → each\n    // state stacks vertically → excessively tall chart.  With the cap,\n    // X is truncated to floor(400/6) = 66 items, and the facet grid is\n    // re-derived with narrower subplots so more columns fit.\n    if (facetGrid) {\n        const canvasXCap = Math.max(1, Math.floor(canvasSize.width / xMinGroupStep));\n        const canvasYCap = Math.max(1, Math.floor(canvasSize.height / yMinGroupStep));\n\n        if (maxXToKeep > canvasXCap || maxYToKeep > canvasYCap) {\n            maxXToKeep = Math.min(maxXToKeep, canvasXCap);\n            maxYToKeep = Math.min(maxYToKeep, canvasYCap);\n\n            // With tighter axis items, subplots can be narrower, so more\n            // facet columns may fit.  Re-derive the grid for column-only\n            // wrapping (the most affected case).\n            const colField = channelSemantics.column?.field;\n            const rowField = channelSemantics.row?.field;\n            const colCount = colField\n                ? new Set(data.map(r => r[colField])).size : 0;\n\n            if (colCount > 1 && !rowField) {\n                const tighterW = Math.max(\n                    options.minSubplotSize ?? 60,\n                    maxXToKeep * xMinGroupStep,\n                );\n                const totalW = canvasSize.width * maxStretchX - fixW;\n                const totalH = canvasSize.height * maxStretchY - fixH;\n                const revisedMaxCols = Math.max(1, Math.floor(\n                    totalW / (tighterW + gap),\n                ));\n                const revisedMaxRows = Math.max(1, Math.floor(\n                    totalH / ((options.minSubplotSize ?? 60) + gap),\n                ));\n                const maxTotal = revisedMaxCols * revisedMaxRows;\n                const effectiveCount = Math.min(colCount, maxTotal);\n                const visRows = Math.ceil(effectiveCount / revisedMaxCols);\n                const visCols = Math.ceil(effectiveCount / visRows);\n\n                facetGrid.columns = visCols;\n                facetGrid.rows = visRows;\n                facetGrid.maxColumnValues = maxTotal;\n            }\n        }\n    }\n\n    // maxColumnValues already carries the correct semantics for both\n    // column+row (per-dimension cap) and column-only wrapping (total\n    // panel count = grid cols × grid rows).  No multiplication needed.\n    const maxValues: Record<string, number> = {\n        x: maxXToKeep,\n        y: maxYToKeep,\n        column: facetGrid?.maxColumnValues ?? Infinity,\n        row: facetGrid?.maxRowValues ?? Infinity,\n        color: maxColorVal,\n    };\n\n    return { maxValues, facetGrid };\n}\n\n// ---------------------------------------------------------------------------\n// Public: computeFacetGrid\n// ---------------------------------------------------------------------------\n\n/**\n * Decide the facet grid layout (including column-only wrapping).\n *\n * This runs BEFORE filterOverflow and computeLayout.  It:\n *   1. Counts unique column/row values from data.\n *   2. Computes banded-aware minimum subplot dimensions.\n *   3. Computes max columns/rows that fit in the canvas budget.\n *   4. For column-only: wraps into a 2D grid (total panels = cols × rows).\n *   5. For column+row: caps each dimension independently.\n *\n * Returns `undefined` when there are no facet channels.\n *\n * @param channelSemantics  Phase 0 output\n * @param declaration       Template layout declaration\n * @param data              Data rows (pre-overflow — possibly after temporal conversion)\n * @param canvasSize        Target canvas dimensions\n * @param options           Assembly options\n */\nexport function computeFacetGrid(\n    channelSemantics: Record<string, ChannelSemantics>,\n    declaration: LayoutDeclaration,\n    data: any[],\n    canvasSize: { width: number; height: number },\n    options: AssembleOptions,\n): import('./types').FacetGridResult | undefined {\n    const { x: msX, y: msY } = resolveStretchCaps(options);\n    const fixW = options.facetFixedPadding?.width ?? 0;\n    const fixH = options.facetFixedPadding?.height ?? 0;\n    const gap = options.facetGap ?? 0;\n    const minStep = options.minStep ?? 6;\n    const stepPadding = options.stepPadding ?? 0.1;\n    const baseMinSubplot = options.minSubplotSize ?? 60;\n\n    const isDiscreteType = (t: string | undefined) => t === 'nominal' || t === 'ordinal';\n\n    // --- Compute min subplot size per axis ---\n    //\n    // Continuous:  baseMinSubplot (e.g. 60px).\n    //\n    // Discrete (not grouped):\n    //   min(minStep × valueCount, maxDim)\n    //\n    // Discrete (grouped):\n    //   perCategoryStep = max(minStep × groupCount, minGroupStep)\n    //   min(perCategoryStep × valueCount, maxDim)\n    //\n    //   where minGroupStep accounts for the inter-group gap:\n    //     the gap = stepPadding × step, which must be ≥ MIN_GROUP_GAP_PX.\n    //\n    // Always capped at maxDim (full stretched canvas minus fixed overhead)\n    // to guarantee at least 1 facet column/row.\n\n    const maxW = canvasSize.width * msX - fixW;\n    const maxH = canvasSize.height * msY - fixH;\n    const MIN_GROUP_GAP_PX = 3;\n\n    // Grouping detection\n    const groupField = channelSemantics.group?.field;\n    let groupCount = 0;\n    let groupAxis: 'x' | 'y' | undefined;\n    if (groupField) {\n        groupCount = new Set(data.map((r: any) => r[groupField])).size;\n        const xType = declaration.resolvedTypes?.x ?? channelSemantics.x?.type;\n        const yType = declaration.resolvedTypes?.y ?? channelSemantics.y?.type;\n        if (isDiscreteType(xType)) groupAxis = 'x';\n        else if (isDiscreteType(yType)) groupAxis = 'y';\n    }\n\n    let minSubplotWidth = baseMinSubplot;\n    let minSubplotHeight = baseMinSubplot;\n\n    // Log-scale axes need more space for minor grid lines to be legible.\n    const LOG_PX_PER_DECADE_FACET = 40;\n    for (const axis of ['x', 'y'] as const) {\n        const cs = channelSemantics[axis];\n        if (!cs?.field || !cs.scaleType) continue;\n        if (cs.scaleType !== 'log' && cs.scaleType !== 'symlog') continue;\n        const vals = data\n            .map((r: any) => r[cs.field])\n            .filter((v: any) => typeof v === 'number' && v > 0 && isFinite(v));\n        if (vals.length < 2) continue;\n        const decades = Math.log10(Math.max(...vals)) - Math.log10(Math.min(...vals));\n        const needed = Math.ceil(Math.max(1, decades)) * LOG_PX_PER_DECADE_FACET;\n        if (axis === 'x') minSubplotWidth = Math.max(minSubplotWidth, needed);\n        else minSubplotHeight = Math.max(minSubplotHeight, needed);\n    }\n\n    for (const axis of ['x', 'y'] as const) {\n        const cs = channelSemantics[axis];\n        if (!cs?.field) continue;\n\n        const effectiveType = declaration.resolvedTypes?.[axis] ?? cs.type;\n        const isBanded = declaration.axisFlags?.[axis]?.banded === true;\n        if (!isDiscreteType(effectiveType) && !isBanded) continue;\n\n        const valueCount = new Set(data.map((r: any) => r[cs.field])).size;\n        const axisGroupCount = (groupAxis === axis && groupCount > 1) ? groupCount : 1;\n        const maxDim = axis === 'x' ? maxW : maxH;\n\n        let perCategoryStep: number;\n        if (axisGroupCount > 1) {\n            // Grouped: each category needs room for groupCount sub-items\n            // PLUS enough inter-group gap (stepPadding × step ≥ MIN_GROUP_GAP_PX).\n            const minGroupStep = Math.max(\n                Math.ceil(MIN_GROUP_GAP_PX / stepPadding),\n                2 * axisGroupCount,\n            );\n            perCategoryStep = Math.max(minStep * axisGroupCount, minGroupStep);\n        } else {\n            // Ungrouped: one item per category\n            perCategoryStep = minStep;\n        }\n\n        const dataDrivenMin = Math.min(perCategoryStep * valueCount, maxDim);\n        const minDim = Math.max(baseMinSubplot, dataDrivenMin);\n\n        if (axis === 'x') {\n            minSubplotWidth = minDim;\n        } else {\n            minSubplotHeight = minDim;\n        }\n    }\n\n    // --- Continuous axes: AR-based min subplot size ---\n    // When both axes are continuous (non-banded), the expected aspect\n    // ratio tells us which axis needs more room.  The shorter dimension\n    // stays at baseMinSubplot; the longer gets up to ms× (maxStretch)\n    // of the base.  This ensures line charts (landscape AR) get wider\n    // min subplots, so maxFacetColumns is lower → fewer, wider panels.\n    const xIsCont = (() => {\n        const cs = channelSemantics.x;\n        if (!cs?.field) return false;\n        const t = declaration.resolvedTypes?.x ?? cs.type;\n        return !isDiscreteType(t) && !(declaration.axisFlags?.x?.banded === true);\n    })();\n    const yIsCont = (() => {\n        const cs = channelSemantics.y;\n        if (!cs?.field) return false;\n        const t = declaration.resolvedTypes?.y ?? cs.type;\n        return !isDiscreteType(t) && !(declaration.axisFlags?.y?.banded === true);\n    })();\n\n    if (xIsCont && yIsCont) {\n        const xCS = channelSemantics.x;\n        const yCS = channelSemantics.y;\n        if (xCS?.field && yCS?.field) {\n            const isTempX = (declaration.resolvedTypes?.x ?? xCS.type) === 'temporal';\n            const isTempY = (declaration.resolvedTypes?.y ?? yCS.type) === 'temporal';\n            const cmcs = options.continuousMarkCrossSection;\n            const isConn = typeof cmcs === 'object' && !!cmcs.seriesCountAxis;\n\n            const xNum: number[] = [];\n            const yNum: number[] = [];\n            const sKeys: string[] = [];\n            const sFields: string[] = [];\n            // Include facet fields in series keys so banking computes\n            // slopes within each panel, not across panel boundaries.\n            const colF = channelSemantics.column?.field;\n            const rowF = channelSemantics.row?.field;\n            if (colF) sFields.push(colF);\n            if (rowF) sFields.push(rowF);\n            const cf = channelSemantics.color?.field;\n            const df = channelSemantics.detail?.field;\n            if (cf) sFields.push(cf);\n            if (df && df !== cf) sFields.push(df);\n\n            for (const row of data) {\n                const xv = row[xCS.field];\n                const yv = row[yCS.field];\n                if (xv == null || yv == null) continue;\n                const xn = isTempX ? +new Date(xv) : +xv;\n                const yn = isTempY ? +new Date(yv) : +yv;\n                if (isNaN(xn) || isNaN(yn)) continue;\n                xNum.push(xn);\n                yNum.push(yn);\n                sKeys.push(sFields.length > 0\n                    ? sFields.map(f => String(row[f] ?? '')).join('\\x00')\n                    : '');\n            }\n\n            if (xNum.length > 1) {\n                const xMin = Math.min(...xNum);\n                const xMax = Math.max(...xNum);\n                const yMin = Math.min(...yNum);\n                const yMax = Math.max(...yNum);\n                const xDom: [number, number] = [xMin, xMax];\n                const yDom: [number, number] = [yMin, yMax];\n                if (xCS.zero?.zero) {\n                    if (xDom[0] > 0) xDom[0] = 0;\n                    if (xDom[1] < 0) xDom[1] = 0;\n                }\n                if (yCS.zero?.zero) {\n                    if (yDom[0] > 0) yDom[0] = 0;\n                    if (yDom[1] < 0) yDom[1] = 0;\n                }\n\n                const ar = computeBankingAR(xNum, yNum, xDom, yDom, sKeys, isConn);\n\n                // Distribute: shorter side = base, longer side = base × min(ar, ms).\n                if (ar >= 1) {\n                    minSubplotWidth = Math.max(minSubplotWidth,\n                        Math.round(baseMinSubplot * Math.min(ar, msX)));\n                    minSubplotHeight = Math.max(minSubplotHeight, baseMinSubplot);\n                } else {\n                    minSubplotWidth = Math.max(minSubplotWidth, baseMinSubplot);\n                    minSubplotHeight = Math.max(minSubplotHeight,\n                        Math.round(baseMinSubplot * Math.min(1 / ar, msY)));\n                }\n            }\n        }\n    }\n\n    // effectiveW = totalBudget - fixedOverhead; each panel costs (subplot + gap).\n    const effectiveW = maxW;\n    const effectiveH = maxH;\n    const maxFacetColumns = Math.max(1, Math.floor(\n        effectiveW / (minSubplotWidth + gap),\n    ));\n    const maxFacetRows = Math.max(1, Math.floor(\n        effectiveH / (minSubplotHeight + gap),\n    ));\n\n    // Identify column/row fields\n    const colField = channelSemantics.column?.field;\n    const rowField = channelSemantics.row?.field;\n    if (!colField && !rowField) return undefined;\n\n    const colCount = colField\n        ? new Set(data.map((r: any) => r[colField])).size : 0;\n    const rowCount = rowField\n        ? new Set(data.map((r: any) => r[rowField])).size : 0;\n\n    if (colCount === 0 && rowCount === 0) return undefined;\n\n    // Explicit user override: force a specific column count for a column-wrapped\n    // facet (the `facetColumns` chart property). Clamped to [1, colCount]; the\n    // remaining panels wrap into as many rows as needed (all kept, canvas grows).\n    const forcedCols = options.facetColumns != null && options.facetColumns >= 1\n        ? Math.min(Math.max(1, Math.floor(options.facetColumns)), Math.max(1, colCount))\n        : undefined;\n\n    if (colCount > 0 && rowCount === 0) {\n        if (forcedCols != null) {\n            const nRows = Math.ceil(colCount / forcedCols);\n            return {\n                columns: forcedCols,\n                rows: nRows,\n                maxColumnValues: forcedCols * nRows,\n                maxRowValues: Math.max(maxFacetRows, nRows),\n            };\n        }\n        // Column-only.  If all panels fit in one row, use a single row.\n        // Otherwise wrap into a balanced grid: pick the number of rows\n        // that makes the grid as square as possible (cols ≈ rows) while\n        // staying within the max budget per dimension.\n        if (colCount <= maxFacetColumns) {\n            return {\n                columns: colCount,\n                rows: 1,\n                maxColumnValues: colCount,\n                maxRowValues: maxFacetRows,\n            };\n        }\n\n        // Need to wrap.  Use maxFacetColumns as the column count\n        // (fill the width), but reduce columns slightly if it would\n        // produce a widow row (a single orphan panel on the last row).\n        let nCols = maxFacetColumns;\n        let nRows = Math.ceil(colCount / nCols);\n\n        // Check for widow: if last row has only 1 panel, try nCols-1\n        // to redistribute more evenly.  Keep reducing while widow\n        // exists and nCols > 2.\n        while (nCols > 2 && (colCount % nCols) === 1) {\n            nCols--;\n            nRows = Math.ceil(colCount / nCols);\n        }\n\n        const visRows = Math.min(nRows, maxFacetRows);\n        const maxTotal = nCols * visRows;\n\n        return {\n            columns: nCols,\n            rows: visRows,\n            maxColumnValues: maxTotal,\n            maxRowValues: maxFacetRows,\n        };\n    }\n\n    // Column+row or row-only: cap each dimension independently.\n    return {\n        columns: Math.max(1, Math.min(colCount, maxFacetColumns)),\n        rows: Math.max(1, Math.min(rowCount, maxFacetRows)),\n        maxColumnValues: maxFacetColumns,\n        maxRowValues: maxFacetRows,\n    };\n}\n\n// ---------------------------------------------------------------------------\n// Public: computeMinSubplotDimensions\n// ---------------------------------------------------------------------------\n\n/**\n * Compute minimum subplot dimensions considering banded and discrete axes.\n *\n * For banded axes (e.g. temporal x on candlestick), each data point needs\n * `minStep` px, so the subplot minimum can be much larger than the generic\n * `minSubplotSize` (60px).  For discrete axes, the count of unique values\n * drives the minimum similarly.\n *\n * This is used by both filterOverflow (pre-layout) and the assemblers\n * (post-layout) to consistently compute facet column/row caps.\n *\n * @param channelSemantics  Phase 0 output (field, type per channel)\n * @param declaration       Template layout declaration (axisFlags, resolvedTypes)\n * @param data              Data rows\n * @param options           Assembly options ({ minStep, minSubplotSize })\n * @returns                 { minSubplotWidth, minSubplotHeight }\n */\nexport function computeMinSubplotDimensions(\n    channelSemantics: Record<string, ChannelSemantics>,\n    declaration: LayoutDeclaration,\n    data: any[],\n    options: { minStep?: number; minSubplotSize?: number },\n): { minSubplotWidth: number; minSubplotHeight: number } {\n    const minStep = options.minStep ?? 6;\n    const minSubplot = options.minSubplotSize ?? 60;\n\n    let minSubplotWidth = minSubplot;\n    let minSubplotHeight = minSubplot;\n\n    // Log-scale axes need more space so minor grid lines stay legible.\n    const LOG_PX_PER_DECADE_MIN = 40;\n    for (const axis of ['x', 'y'] as const) {\n        const cs = channelSemantics[axis];\n        if (!cs?.field || !cs.scaleType) continue;\n        if (cs.scaleType !== 'log' && cs.scaleType !== 'symlog') continue;\n        const vals = data\n            .map((r: any) => r[cs.field])\n            .filter((v: any) => typeof v === 'number' && v > 0 && isFinite(v));\n        if (vals.length < 2) continue;\n        const decades = Math.log10(Math.max(...vals)) - Math.log10(Math.min(...vals));\n        const needed = Math.ceil(Math.max(1, decades)) * LOG_PX_PER_DECADE_MIN;\n        if (axis === 'x') minSubplotWidth = Math.max(minSubplotWidth, needed);\n        else minSubplotHeight = Math.max(minSubplotHeight, needed);\n    }\n\n    const isDiscreteType = (t: string | undefined) =>\n        t === 'nominal' || t === 'ordinal';\n\n    for (const axis of ['x', 'y'] as const) {\n        const cs = channelSemantics[axis];\n        if (!cs?.field) continue;\n\n        const effectiveType = declaration.resolvedTypes?.[axis] ?? cs.type;\n        const isBanded = declaration.axisFlags?.[axis]?.banded === true;\n        const isDiscrete = isDiscreteType(effectiveType);\n\n        let itemCount = 0;\n        if (isBanded || isDiscrete) {\n            itemCount = new Set(data.map((r: any) => r[cs.field])).size;\n        }\n\n        if (itemCount > 0) {\n            const minDim = Math.max(minSubplot, itemCount * minStep);\n            if (axis === 'x') {\n                minSubplotWidth = Math.max(minSubplotWidth, minDim);\n            } else {\n                minSubplotHeight = Math.max(minSubplotHeight, minDim);\n            }\n        }\n    }\n\n    return { minSubplotWidth, minSubplotHeight };\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n+ * =============================================================================\n+ * COLOR DECISIONS (backend-agnostic)\n+ * =============================================================================\n+ *\n+ * Pure decision layer for choosing colormaps based on:\n+ *   - Field semantics (FieldSemantics / ColorSchemeHint)\n+ *   - Channel semantics (ChannelSemantics)\n+ *   - Chart type & encodings\n+ *   - Data statistics (distinct count, numeric range)\n+ *\n+ * This module does NOT know about Vega-Lite / ECharts syntax.\n+ * It only returns abstract colormap identifiers and palette needs.\n+ * Backends translate these decisions into concrete scale/option config.\n+ * =============================================================================\n+ */\n\nimport type { ChartEncoding, ChannelSemantics } from './types';\n\n// -----------------------------------------------------------------------------\n// 公共类型\n// -----------------------------------------------------------------------------\n\nexport type ColorMapType = 'categorical' | 'sequential' | 'diverging';\n\nexport type ColorChannel = 'color' | 'group' | 'fill' | 'stroke';\n\nexport interface ColorDecision {\n    channel: ColorChannel;\n    schemeType: ColorMapType;\n    /**\n     * 具体 colormap 标识：\n     *   - 当用户在 encoding.scheme 中显式指定时，这里会带上该 id（如 'viridis'）。\n     *   - 自动决策路径下，core 不再选择具体 id，schemeId 留空，由各后端的 colormap\n     *     模块根据 schemeType / categoryCount / backend 主题自行挑选合适的 palette。\n     */\n    schemeId?: string;\n    divergingMidpoint?: number;\n    categoryCount?: number;\n    /** 是否是主编码（影响后续主题/对比度策略） */\n    primary: boolean;\n    /** 是否是数据驱动的颜色（而非常量色） */\n    dataDriven: boolean;\n}\n\n/**\n * 一个后端无关的颜色决策结果：按 channel 存一份。\n */\nexport interface ColorDecisionResult {\n    color?: ColorDecision;\n    group?: ColorDecision;\n    fill?: ColorDecision;\n    stroke?: ColorDecision;\n}\n\n// -----------------------------------------------------------------------------\n// 通道级颜色决策\n// -----------------------------------------------------------------------------\n\ninterface DecideColorMapsContext {\n    chartType: string;\n    encodings: Record<string, ChartEncoding>;\n    channelSemantics: Record<string, ChannelSemantics>;\n    table: any[];\n    // backend: 'vegalite' | 'echarts' | 'chartjs';\n    background?: 'light' | 'dark';\n}\n\nfunction inferColorChannelPrimary(channel: ColorChannel, chartType: string): boolean {\n    // 目前简单：color / group 视为主色通道\n    if (channel === 'color' || channel === 'group') return true;\n    return false;\n}\n\n/**\n * 从 ChannelSemantics 推断需要的 scheme 类型（categorical / sequential / diverging）。\n */\nfunction decideSchemeTypeFromChannel(\n    channel: ColorChannel,\n    cs: ChannelSemantics | undefined,\n): { schemeType: ColorMapType; divergingMidpoint?: number } {\n    const hint = cs?.colorScheme;\n    if (hint) {\n        // 若语义推荐是 diverging，则直接按发散处理。\n        if (hint.type === 'diverging') {\n            return {\n                schemeType: 'diverging',\n                // resolve-semantics 里用 domainMid 表示 diverging 中点\n                divergingMidpoint: (hint as any).domainMid,\n            };\n        }\n        // 若推荐为 sequential，则直接按顺序色带处理。\n        if (hint.type === 'sequential') {\n            return { schemeType: 'sequential' };\n        }\n        // 语义推荐为 categorical，但编码类型实际是 temporal 时，\n        // 对 color 通道优先按连续时间轴处理，使用 sequential colormap，\n        // 而不是一条一条离散颜色（防止 Date/Time 被当成类别色盘）。\n        if (hint.type === 'categorical') {\n            // 若语义为 Rank，则更适合作为连续数轴上的等级映射，\n            // 使用 continuous colormap（sequential），否则按普通类别处理。\n            const semType = cs?.semanticAnnotation?.semanticType;\n            const isRankLike = semType === 'Rank';\n            if (isRankLike) {\n                return { schemeType: 'sequential' };\n            }\n\n            if (cs?.type === 'temporal' && channel === 'color') {\n                return { schemeType: 'sequential' };\n            }\n            return { schemeType: 'categorical' };\n        }\n    }\n\n    // 没 hint 时，用语义 + encoding type 兜底\n    const encType = cs?.type;\n    const semType = cs?.semanticAnnotation?.semanticType;\n\n    // 相关系数 [-1,1] 等「双向度量」优先使用发散色带，以 0 为中点。\n    if (semType === 'Correlation') {\n        return { schemeType: 'diverging', divergingMidpoint: 0 };\n    }\n\n    if (encType === 'quantitative' || encType === 'temporal') {\n        return { schemeType: 'sequential' };\n    }\n\n    return { schemeType: 'categorical' };\n}\n\nfunction countDistinctValues(table: any[], field: string | undefined): number | undefined {\n    if (!field) return undefined;\n    const set = new Set<any>();\n    for (const row of table) {\n        if (row == null) continue;\n        set.add(row[field]);\n    }\n    return set.size;\n}\n\nfunction decideColorForChannel(\n    channel: ColorChannel,\n    ctx: DecideColorMapsContext,\n): ColorDecision | undefined {\n    const encoding = ctx.encodings[channel as string];\n    const cs = ctx.channelSemantics[channel as string];\n\n    // 没字段就不是数据驱动色，不做决策\n    if (!encoding || !cs?.field) return undefined;\n\n    const dataDriven = true;\n    const primary = inferColorChannelPrimary(channel, ctx.chartType);\n\n    // 1. 显式 scheme 优先\n    if (encoding.scheme && encoding.scheme !== 'default') {\n        const distinct = countDistinctValues(ctx.table, cs.field);\n        // 用户显式指定 scheme 时，core 只透传 id，并根据 ChannelSemantics 推断类型；\n        // 真正选择调色板由各后端的 colormap 模块完成。\n        const { schemeType } = decideSchemeTypeFromChannel(channel, cs);\n        return {\n            channel,\n            schemeType,\n            schemeId: encoding.scheme,\n            categoryCount: distinct,\n            primary,\n            dataDriven,\n        };\n    }\n\n    // 2. 基于 ChannelSemantics.colorScheme 的 family 决策\n    const { schemeType, divergingMidpoint } = decideSchemeTypeFromChannel(channel, cs);\n    const distinct = countDistinctValues(ctx.table, cs.field);\n\n    return {\n        channel,\n        schemeType,\n        divergingMidpoint,\n        categoryCount: distinct,\n        primary,\n        dataDriven,\n    };\n}\n\n/**\n * 主入口：根据 chart / encodings / channelSemantics / data 计算颜色决策。\n */\nexport function decideColorMaps(ctx: DecideColorMapsContext): ColorDecisionResult {\n    const result: ColorDecisionResult = {\n        color: undefined,\n        group: undefined,\n        fill: undefined,\n        stroke: undefined,\n    };\n\n    // 目前只对 color / group 做决策，fill / stroke 预留\n    const channels: ColorChannel[] = ['color', 'group'];\n    for (const ch of channels) {\n        const decision = decideColorForChannel(ch, ctx);\n        if (decision) {\n            result[ch] = decision;\n        }\n    }\n\n    return result;\n}","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * =============================================================================\n * PHASE 2: INSTANTIATE SPEC — Chart.js backend\n * =============================================================================\n *\n * Translates semantic decisions (Phase 0) and layout dimensions (Phase 1)\n * into Chart.js-specific config properties.\n *\n * Key differences from ECharts/Vega-Lite instantiation:\n *   - CJS uses { type, data: { labels, datasets[] }, options: { scales } }\n *   - CJS scales use 'x'/'y' keys (not xAxis/yAxis)\n *   - CJS sizing via canvas element dimensions + responsive: false\n *   - CJS label rotation via scales[axis].ticks.maxRotation\n *   - CJS stacking via stacked property on scales\n *   - CJS bar sizing via barPercentage and categoryPercentage\n *\n * CJS dependency: **Yes — this is where Chart.js-specific syntax lives**\n * =============================================================================\n */\n\nimport type {\n    InstantiateContext,\n    ChartWarning,\n} from '../core/types';\n\n/**\n * Phase 2: Apply layout and semantic decisions to the Chart.js config object.\n *\n * Handles common Chart.js plumbing across all templates:\n *   - Canvas sizing (_width, _height)\n *   - Axis label rotation and font sizing\n *   - Bar sizing (barPercentage, categoryPercentage)\n *   - Overflow truncation warnings\n */\nexport function cjsApplyLayoutToSpec(\n    config: any,\n    context: InstantiateContext,\n    warnings: ChartWarning[],\n): void {\n    const { channelSemantics, layout, canvasSize } = context;\n\n    // ── Axis-less chart types (pie, radar, doughnut) ─────────────────────\n    const hasAxes = !!(config.options?.scales?.x || config.options?.scales?.y);\n    const isRadar = config.type === 'radar';\n\n    // ── Canvas dimensions ────────────────────────────────────────────────\n    // Chart.js uses the canvas element dimensions.\n    // For non-axis charts (pie, radar), templates set their own _width/_height.\n    if (hasAxes && !config._width) {\n        // Axes + optional right legend column (see legend block below for extra gutter).\n        const PADDING = 80; // approximate space for axes, labels\n\n        const xIsDiscrete = layout.xNominalCount > 0 || layout.xContinuousAsDiscrete > 0;\n        const yIsDiscrete = layout.yNominalCount > 0 || layout.yContinuousAsDiscrete > 0;\n\n        let plotWidth: number;\n        let plotHeight: number;\n\n        if (xIsDiscrete && layout.xStepUnit !== 'group') {\n            const xItemCount = layout.xNominalCount || layout.xContinuousAsDiscrete || 0;\n            plotWidth = xItemCount > 0 ? layout.xStep * xItemCount : (layout.subplotWidth || canvasSize.width);\n        } else {\n            plotWidth = layout.subplotWidth || canvasSize.width;\n        }\n\n        if (yIsDiscrete && layout.yStepUnit !== 'group') {\n            const yItemCount = layout.yNominalCount || layout.yContinuousAsDiscrete || 0;\n            plotHeight = yItemCount > 0 ? layout.yStep * yItemCount : (layout.subplotHeight || canvasSize.height);\n        } else {\n            plotHeight = layout.subplotHeight || canvasSize.height;\n        }\n\n        const legendGutter = cjsLegendLikelyVisible(config) ? 96 : 0;\n        config._width = plotWidth + PADDING + legendGutter;\n        config._height = plotHeight + PADDING;\n    }\n\n    // ── Bar sizing ───────────────────────────────────────────────────────\n    if (config.data?.datasets) {\n        const barDatasets = config.data.datasets.filter(\n            (ds: any) => config.type === 'bar' || ds.type === 'bar'\n        );\n        if (barDatasets.length > 0 && hasAxes) {\n            const bandPadding = layout.stepPadding;\n            // Chart.js uses:\n            //   categoryPercentage: fraction of available space per category (default 0.8)\n            //   barPercentage: fraction of category space per bar (default 0.9)\n            // Total bar space = categoryPercentage × barPercentage\n            const categoryPct = 1 - bandPadding;\n            for (const ds of barDatasets) {\n                if (ds.categoryPercentage == null) {\n                    ds.categoryPercentage = categoryPct;\n                }\n            }\n        }\n    }\n\n    // ── X-axis label sizing ──────────────────────────────────────────────\n    if (hasAxes && config.options?.scales?.x && layout.xLabel) {\n        if (!config.options.scales.x.ticks) config.options.scales.x.ticks = {};\n\n        if (layout.xLabel.labelAngle && layout.xLabel.labelAngle !== 0) {\n            config.options.scales.x.ticks.maxRotation = Math.abs(layout.xLabel.labelAngle);\n            config.options.scales.x.ticks.minRotation = Math.abs(layout.xLabel.labelAngle);\n        }\n\n        if (layout.xLabel.fontSize) {\n            config.options.scales.x.ticks.font = {\n                ...(config.options.scales.x.ticks.font || {}),\n                size: layout.xLabel.fontSize,\n            };\n        }\n        // Axis title (scale title) font — canvas-adaptive header size.\n        if (config.options.scales.x.title?.display) {\n            config.options.scales.x.title.font = {\n                ...(config.options.scales.x.title.font || {}),\n                size: layout.titleFontSize,\n            };\n        }\n    }\n\n    // ── Y-axis label sizing ──────────────────────────────────────────────\n    if (hasAxes && config.options?.scales?.y && layout.yLabel) {\n        if (!config.options.scales.y.ticks) config.options.scales.y.ticks = {};\n\n        if (layout.yLabel.fontSize) {\n            config.options.scales.y.ticks.font = {\n                ...(config.options.scales.y.ticks.font || {}),\n                size: layout.yLabel.fontSize,\n            };\n        }\n        if (config.options.scales.y.title?.display) {\n            config.options.scales.y.title.font = {\n                ...(config.options.scales.y.title.font || {}),\n                size: layout.titleFontSize,\n            };\n        }\n    }\n\n    // ── Legend / chart title font — canvas-adaptive header sizes ──────────\n    if (config.options?.plugins?.legend) {\n        const legend = config.options.plugins.legend;\n        if (!legend.labels) legend.labels = {};\n        legend.labels.font = { ...(legend.labels.font || {}), size: layout.legendFontSize };\n    }\n    if (config.options?.plugins?.title?.display) {\n        config.options.plugins.title.font = {\n            ...(config.options.plugins.title.font || {}),\n            size: layout.titleFontSize,\n        };\n    }\n\n    // ── Overflow truncation warnings ─────────────────────────────────────\n    if (layout.truncations && layout.truncations.length > 0) {\n        for (const trunc of layout.truncations) {\n            warnings.push({\n                severity: 'warning',\n                code: 'overflow',\n                message: trunc.message,\n                channel: trunc.channel,\n                field: trunc.field,\n            });\n            // Chart.js: append placeholder to labels\n            if (config.data?.labels && Array.isArray(config.data.labels)) {\n                config.data.labels.push(trunc.placeholder);\n            }\n        }\n    }\n\n    // ── Legend: right side (Chart.js stacks items vertically for position 'right') ──\n    cjsApplyLegendRightColumn(config);\n}\n\n/** Whether the Chart.js legend is expected to show (respects display:false; default is show when multiple datasets). */\nfunction cjsLegendLikelyVisible(config: any): boolean {\n    const legend = config.options?.plugins?.legend;\n    if (legend?.display === false) return false;\n    if (legend?.display === true) return true;\n    const n = config.data?.datasets?.length ?? 0;\n    return n > 1;\n}\n\n/** How many legend rows we expect (pie/doughnut: slice labels; else: one per dataset). */\nfunction cjsLegendEntryCount(config: any): number {\n    const t = config.type;\n    if (t === 'pie' || t === 'doughnut') {\n        return config.data?.labels?.length ?? 0;\n    }\n    return config.data?.datasets?.length ?? 0;\n}\n\n/**\n * Place legend on the right in a vertical column; match EC/VL legend text size so labels fit the canvas.\n * (Chart.js defaults ~12px; VL labelFontSize 8, EC textStyle 11 or 8 when high-cardinality.)\n */\nfunction cjsApplyLegendRightColumn(config: any): void {\n    if (!cjsLegendLikelyVisible(config)) return;\n    if (!config.options) config.options = {};\n    if (!config.options.plugins) config.options.plugins = {};\n    const prev = config.options.plugins.legend ?? {};\n    const prevLabels = prev.labels ?? {};\n    const prevFont = prevLabels.font ?? {};\n    const entryCount = cjsLegendEntryCount(config);\n    const highCardinality = entryCount >= 16;\n    const fontSize = prevFont.size ?? (highCardinality ? 8 : 10);\n    const boxW = prevLabels.boxWidth ?? (highCardinality ? 8 : 10);\n    const boxH = prevLabels.boxHeight ?? (highCardinality ? 8 : 10);\n    config.options.plugins.legend = {\n        ...prev,\n        position: 'right' as const,\n        labels: {\n            ...prevLabels,\n            font: {\n                ...prevFont,\n                size: fontSize,\n            },\n            boxWidth: boxW,\n            boxHeight: boxH,\n        },\n    };\n}\n\n/**\n * Apply tooltips to a Chart.js config.\n * Chart.js tooltips are configured under options.plugins.tooltip.\n */\nexport function cjsApplyTooltips(config: any): void {\n    if (!config.options) config.options = {};\n    if (!config.options.plugins) config.options.plugins = {};\n    if (!config.options.plugins.tooltip) {\n        config.options.plugins.tooltip = { enabled: true };\n    }\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Static Series Normalization\n *\n * Detects array-valued encodings (static series) in the input spec,\n * validates them, and folds (unpivots) the data into long form so\n * the rest of the pipeline can process it as a standard single-field\n * encoding with a color discriminator.\n *\n * This runs BEFORE Phase 0 (resolveChannelSemantics).\n */\n\nimport type { ChartEncoding, EncodingValue, RawEncodingValue, StaticSeriesMetadata } from './types';\nimport type { SemanticAnnotation } from './field-semantics';\nimport { getVisCategory, inferVisCategory } from './semantic-types';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Synthetic column names injected by the fold transform */\nexport const STATIC_SERIES_KEY_COLUMN = '__flint_series_key';\nexport const STATIC_SERIES_VALUE_COLUMN = '__flint_series_value';\n\n/** Channels that may accept array-valued (multi-field) encodings */\nconst MEASURE_CHANNELS = new Set(['x', 'y']);\n\n// ---------------------------------------------------------------------------\n// Shorthand normalization\n// ---------------------------------------------------------------------------\n\n/**\n * Expand the bare-string channel shorthand into a full encoding object.\n *\n * `\"weight\"` → `{ field: \"weight\" }`. Array entries (static series) are\n * expanded element-by-element, so `[\"a\", \"b\"]` → `[{ field: \"a\" }, { field: \"b\" }]`.\n * Non-string values pass through unchanged.\n */\nexport function coerceEncodingValue(value: RawEncodingValue): EncodingValue {\n    if (typeof value === 'string') {\n        return { field: value };\n    }\n    if (Array.isArray(value)) {\n        return value.map((entry) => (typeof entry === 'string' ? { field: entry } : entry));\n    }\n    return value;\n}\n\n/** Normalize a raw channel→value map, expanding any bare-string shorthands. */\nexport function normalizeEncodingShorthand(\n    encodings: Record<string, RawEncodingValue>,\n): Record<string, EncodingValue> {\n    const out: Record<string, EncodingValue> = {};\n    for (const [channel, value] of Object.entries(encodings)) {\n        out[channel] = coerceEncodingValue(value);\n    }\n    return out;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Result of normalizing static series from the input spec.\n */\nexport interface NormalizeStaticSeriesResult {\n    /** Normalized encodings (all single-valued) */\n    encodings: Record<string, ChartEncoding>;\n    /** Folded data (or original if no static series detected) */\n    data: any[];\n    /** Static series metadata (present only when fold was applied) */\n    staticSeries?: StaticSeriesMetadata;\n}\n\n/**\n * Detect, validate, and normalize static series (array-valued encodings).\n *\n * If no array-valued encodings are present, returns the input unchanged.\n * If one is found, validates constraints and returns folded data +\n * rewritten encodings.\n *\n * @throws Error if validation fails (non-quantitative field, conflicting\n *         color binding, multiple array channels, etc.)\n */\nexport function normalizeStaticSeries(\n    rawEncodings: Record<string, RawEncodingValue>,\n    data: any[],\n    semanticTypes: Record<string, string | SemanticAnnotation>,\n): NormalizeStaticSeriesResult {\n    // Expand bare-string channel shorthands (e.g. `{ x: \"weight\" }`) first so\n    // the rest of the pipeline only ever sees full encoding objects.\n    const encodings = normalizeEncodingShorthand(rawEncodings);\n\n    // Find array-valued channels\n    const arrayChannels: { channel: string; entries: ChartEncoding[] }[] = [];\n    for (const [channel, enc] of Object.entries(encodings)) {\n        if (Array.isArray(enc)) {\n            arrayChannels.push({ channel, entries: enc });\n        }\n    }\n\n    // No static series — pass through unchanged\n    if (arrayChannels.length === 0) {\n        return {\n            encodings: encodings as Record<string, ChartEncoding>,\n            data,\n        };\n    }\n\n    // --- Validation ---\n\n    // Only one channel may have an array encoding\n    if (arrayChannels.length > 1) {\n        const channelNames = arrayChannels.map(c => c.channel).join(', ');\n        throw new Error(\n            `Static series (array encoding) found on multiple channels: ${channelNames}. ` +\n            `Only one channel may use array encoding at a time.`\n        );\n    }\n\n    const { channel, entries } = arrayChannels[0];\n\n    // Must be a measure channel\n    if (!MEASURE_CHANNELS.has(channel)) {\n        throw new Error(\n            `Static series (array encoding) is only allowed on measure channels (${[...MEASURE_CHANNELS].join(', ')}), ` +\n            `not \"${channel}\".`\n        );\n    }\n\n    // Must have at least 2 entries\n    if (entries.length < 2) {\n        throw new Error(\n            `Static series requires at least 2 fields, got ${entries.length} on channel \"${channel}\".`\n        );\n    }\n\n    // Each entry must specify a field\n    const fields: string[] = [];\n    for (const entry of entries) {\n        if (!entry.field) {\n            throw new Error(\n                `Each static series entry must have a \"field\" property.`\n            );\n        }\n        fields.push(entry.field);\n    }\n\n    // Duplicate field check\n    const fieldSet = new Set(fields);\n    if (fieldSet.size !== fields.length) {\n        throw new Error(\n            `Static series contains duplicate fields. Each field must be unique.`\n        );\n    }\n\n    // Fields must exist in data columns (if data is available)\n    if (data.length > 0) {\n        const dataColumns = new Set(Object.keys(data[0]));\n        for (const field of fields) {\n            if (!dataColumns.has(field)) {\n                throw new Error(\n                    `Static series field \"${field}\" not found in data columns. ` +\n                    `Available columns: ${[...dataColumns].join(', ')}`\n                );\n            }\n        }\n    }\n\n    // Fields must resolve to quantitative (not nominal/ordinal)\n    for (const entry of entries) {\n        const field = entry.field!;\n        const explicitType = entry.type;\n        if (explicitType === 'nominal' || explicitType === 'ordinal') {\n            throw new Error(\n                `Static series field \"${field}\" has type \"${explicitType}\" — ` +\n                `only quantitative or temporal fields are allowed in static series.`\n            );\n        }\n        // Infer if no explicit type\n        if (!explicitType && data.length > 0) {\n            const semType = semanticTypes[field];\n            const semTypeStr = typeof semType === 'string' ? semType : semType?.semanticType || '';\n            // Try semantic type registry first, then infer from data values\n            const fromRegistry = semTypeStr ? getVisCategory(semTypeStr) : null;\n            const inferred = fromRegistry ?? inferVisCategory(data.map(r => r[field]));\n            if (inferred === 'nominal' || inferred === 'ordinal') {\n                throw new Error(\n                    `Static series field \"${field}\" infers as \"${inferred}\" from data — ` +\n                    `only quantitative or temporal fields are allowed in static series.`\n                );\n            }\n        }\n    }\n\n    // Cannot combine with explicit color field binding\n    const colorEnc = encodings.color;\n    if (colorEnc && !Array.isArray(colorEnc) && colorEnc.field) {\n        throw new Error(\n            `Cannot use static series on \"${channel}\" when the color channel is already bound to ` +\n            `field \"${colorEnc.field}\". Static series implicitly uses the color channel for ` +\n            `series discrimination.`\n        );\n    }\n\n    // --- Fold (unpivot) the data ---\n    const foldedData = foldData(data, fields);\n\n    // --- Rewrite encodings ---\n    const normalizedEncodings: Record<string, ChartEncoding> = {};\n    for (const [ch, enc] of Object.entries(encodings)) {\n        if (ch === channel) {\n            // Replace array with single encoding on the synthetic value column\n            normalizedEncodings[ch] = { field: STATIC_SERIES_VALUE_COLUMN, type: 'quantitative' };\n        } else if (Array.isArray(enc)) {\n            // Shouldn't reach here (validated above), but handle gracefully\n            normalizedEncodings[ch] = enc[0];\n        } else {\n            normalizedEncodings[ch] = enc;\n        }\n    }\n\n    // Add color encoding for the synthetic key column (preserving any user-specified scheme)\n    const colorScheme = (!Array.isArray(colorEnc) && colorEnc?.scheme) ? colorEnc.scheme : undefined;\n    normalizedEncodings.color = {\n        field: STATIC_SERIES_KEY_COLUMN,\n        type: 'nominal',\n        ...(colorScheme ? { scheme: colorScheme } : {}),\n    };\n\n    const metadata: StaticSeriesMetadata = {\n        channel,\n        fields,\n        keyColumn: STATIC_SERIES_KEY_COLUMN,\n        valueColumn: STATIC_SERIES_VALUE_COLUMN,\n    };\n\n    return {\n        encodings: normalizedEncodings,\n        data: foldedData,\n        staticSeries: metadata,\n    };\n}\n\n// ---------------------------------------------------------------------------\n// Internal: fold/unpivot\n// ---------------------------------------------------------------------------\n\n/**\n * Unpivot (fold) wide-format data into long form.\n *\n * Each input row produces N output rows (one per field in `fields`).\n * Non-measure columns are preserved. Two synthetic columns are added:\n * - `__flint_series_key`: the field name (series identifier)\n * - `__flint_series_value`: the value from that field\n *\n * Rows where all fold values are null/undefined are skipped.\n */\nfunction foldData(data: any[], fields: string[]): any[] {\n    const fieldSet = new Set(fields);\n    const result: any[] = [];\n\n    for (const row of data) {\n        // Collect non-fold columns\n        const baseRow: Record<string, any> = {};\n        for (const [key, value] of Object.entries(row)) {\n            if (!fieldSet.has(key)) {\n                baseRow[key] = value;\n            }\n        }\n\n        // Create one row per fold field\n        for (const field of fields) {\n            const value = row[field];\n            // Skip null/undefined values to avoid phantom data points\n            if (value == null) continue;\n            result.push({\n                ...baseRow,\n                [STATIC_SERIES_KEY_COLUMN]: field,\n                [STATIC_SERIES_VALUE_COLUMN]: value,\n            });\n        }\n    }\n\n    return result;\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Normalize user-supplied `chart_spec.chartProperties` against a template's\n * declared `properties`, so an invalid *value* never reaches the backend spec.\n *\n * The reference docs (see `scripts/gen-chart-reference.ts`) list the accepted\n * `value` for each discrete property, but a caller may still pass a human label\n * (e.g. `\"Logarithmic\"` instead of `\"log\"`) or an outright unknown value. Left\n * unchecked, the template's `instantiate` copies that string verbatim into the\n * backend transform (e.g. Vega-Lite's `regression` `method`), which the renderer\n * silently rejects — producing a blank chart with no error.\n *\n * For every discrete property present in `chartProperties` this helper:\n *   - keeps the value untouched when it already matches an option `value`;\n *   - maps a known option `label` (case-insensitive) to its `value`, emitting an\n *     `info` warning so the caller learns the canonical value;\n *   - drops an unrecognized value (falling back to the property default) and\n *     emits a `warning`, keeping the \"safe to pass\" contract that a bad input\n *     degrades gracefully rather than rendering nothing.\n *\n * Non-discrete properties and keys not declared by the template (pivot state,\n * axis overrides, encoding overrides, …) are passed through unchanged.\n */\n\nimport type { ChartPropertyDef, ChartWarning } from './types';\n\nexport interface NormalizePropertiesResult {\n    chartProperties: Record<string, any> | undefined;\n    warnings: ChartWarning[];\n}\n\nexport function normalizeChartProperties(\n    properties: ChartPropertyDef[] | undefined,\n    chartProperties: Record<string, any> | undefined,\n): NormalizePropertiesResult {\n    const warnings: ChartWarning[] = [];\n    if (!properties || !chartProperties) {\n        return { chartProperties, warnings };\n    }\n\n    let result: Record<string, any> | undefined;\n    const ensureCopy = (): Record<string, any> => {\n        if (!result) result = { ...chartProperties };\n        return result;\n    };\n\n    for (const def of properties) {\n        if (def.type !== 'discrete') continue;\n        if (!(def.key in chartProperties)) continue;\n        const value = chartProperties[def.key];\n        if (value == null) continue;\n\n        // Already a valid accepted value — nothing to do.\n        if (def.options.some((o) => o.value === value)) continue;\n\n        // Known label (case-insensitive) → coerce to the canonical value.\n        const byLabel =\n            typeof value === 'string'\n                ? def.options.find(\n                      (o) =>\n                          o.label != null &&\n                          o.label.toLowerCase() === value.trim().toLowerCase(),\n                  )\n                : undefined;\n        if (byLabel) {\n            ensureCopy()[def.key] = byLabel.value;\n            warnings.push({\n                severity: 'info',\n                code: 'coerced-option-label',\n                message: `chartProperties.${def.key}: '${value}' is a display label; using the accepted value '${byLabel.value}' instead.`,\n            });\n            continue;\n        }\n\n        // Unrecognized value → drop it so the property falls back to its default,\n        // instead of emitting an invalid backend spec that renders blank.\n        const accepted = def.options\n            .map((o) => (o.value == null ? '(default)' : `'${o.value}'`))\n            .join(', ');\n        const copy = ensureCopy();\n        delete copy[def.key];\n        warnings.push({\n            severity: 'warning',\n            code: 'invalid-option-value',\n            message: `chartProperties.${def.key}: '${value}' is not a valid option (accepted: ${accepted}). Falling back to the default.`,\n        });\n    }\n\n    return { chartProperties: result ?? chartProperties, warnings };\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js chart assembly — Two-Stage Pipeline Coordinator.\n *\n * Reuses the **same core analysis pipeline** as Vega-Lite and ECharts:\n *   Phase 0:  resolveChannelSemantics  → ChannelSemantics\n *   Step 0a:  declareLayoutMode    → LayoutDeclaration\n *   Step 0b:  convertTemporalData  → converted data\n *   Step 0c:  filterOverflow       → filtered data, nominalCounts\n *   Phase 1:  computeLayout        → LayoutResult\n *\n * Then diverges for Phase 2 (Chart.js-specific):\n *   template.instantiate → builds Chart.js config structure\n *   cjsApplyLayoutToSpec → applies layout decisions to config\n *\n * Key structural differences from ECharts / VL output:\n *   VL: { mark, encoding, data: {values}, width, height }\n *   EC: { xAxis, yAxis, series: [{type, data}], tooltip, legend, grid }\n *   CJS: { type, data: { labels, datasets[] }, options: { scales, plugins } }\n *\n * This module has NO React, Redux, or UI framework dependencies.\n */\n\nimport {\n    ChartEncoding,\n    ChartTemplateDef,\n    ChartAssemblyInput,\n    AssembleOptions,\n    LayoutDeclaration,\n    InstantiateContext,\n} from '../core/types';\nimport type { ChartWarning } from '../core/types';\nimport { applyEncodingOverrides } from '../core/encoding-overrides';\nimport { applyAggregation } from '../core/aggregate';\nimport { applyPivot, applyTransform, type PivotSurface, type TransformSurface } from '../core/pivot';\nimport { cjsGetTemplateDef } from './templates';\nimport { resolveChannelSemantics, convertTemporalData } from '../core/resolve-semantics';\nimport { computeZeroDecision } from '../core/semantic-types';\nimport { filterOverflow } from '../core/filter-overflow';\nimport { computeLayout, computeChannelBudgets, deriveStretchCaps, resolveBaseSize, resolveFacetColumnsOption } from '../core/compute-layout';\nimport { decideColorMaps } from '../core/color-decisions';\nimport { cjsApplyLayoutToSpec, cjsApplyTooltips } from './instantiate-spec';\nimport { normalizeStaticSeries } from '../core/static-series';\nimport { normalizeChartProperties } from '../core/normalize-properties';\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n/**\n * Assemble a Chart.js config object.\n *\n * ```ts\n * const config = assembleChartjs({\n *   data: { values: myRows },\n *   semantic_types: { weight: 'Quantity' },\n *   chart_spec: { chartType: 'Bar Chart', encodings: { x: { field: 'category' }, y: { field: 'value' } } },\n *   options: { addTooltips: true },\n * });\n * ```\n *\n * @returns A Chart.js config object with optional `_warnings` and `_width`/`_height` hints\n */\nexport function assembleChartjs(input: ChartAssemblyInput): any {\n    const chartType = input.chart_spec.chartType;\n    const semanticTypes = input.semantic_types ?? {};\n    // Internal layout targets the base (target) size; the optional canvasSize\n    // ceiling is applied as per-dimension stretch caps once options resolve.\n    // The base is clamped to the ceiling so a smaller canvasSize shrinks the\n    // chart to fit rather than overflowing it.\n    const sizeCeiling = input.chart_spec.canvasSize;\n    const baseSize = resolveBaseSize(input.chart_spec.baseSize, sizeCeiling);\n    const canvasSize = baseSize;\n    const options = input.options ?? {};\n    let chartTemplate = cjsGetTemplateDef(chartType) as ChartTemplateDef;\n    if (!chartTemplate) {\n        throw new Error(`Unknown Chart.js chart type: ${chartType}. Use cjsAllTemplateDefs to see available types.`);\n    }\n\n    const warnings: ChartWarning[] = [];\n\n    // Validate discrete property values against the template's options before\n    // they reach `instantiate` (map known labels → values, drop unknowns).\n    const normalizedProps = normalizeChartProperties(\n        chartTemplate.properties, input.chart_spec.chartProperties,\n    );\n    const chartProperties = normalizedProps.chartProperties;\n    warnings.push(...normalizedProps.warnings);\n\n    // ═══════════════════════════════════════════════════════════════════════\n    // PRE-PHASE: Static Series Normalization\n    // ═══════════════════════════════════════════════════════════════════════\n    const rawData = input.data.values ?? [];\n    const normalized = normalizeStaticSeries(\n        input.chart_spec.encodings, rawData, semanticTypes,\n    );\n    let data = normalized.data;\n    const staticSeries = normalized.staticSeries;\n\n    const prelimConvertedData = convertTemporalData(data, semanticTypes);\n    const prelimSemantics = resolveChannelSemantics(\n        normalized.encodings, data, semanticTypes, prelimConvertedData,\n    );\n    const typedRawEncodings: Record<string, ChartEncoding> = {};\n    for (const [ch, enc] of Object.entries(normalized.encodings)) {\n        typedRawEncodings[ch] = enc.type\n            ? enc\n            : { ...enc, type: prelimSemantics[ch]?.type };\n    }\n\n    // Transform (derived Category-B operator): same two-control model as VL —\n    // chartProperties.chartType (θ) + chartProperties.arrange (τ/σ/γ). Legacy\n    // composed `pivot` ids are migrated inside applyTransform. See\n    // design-docs/chart-transform-two-axes.md.\n    const authoredTemplate = chartTemplate;\n    const transformed = applyTransform(chartTemplate, typedRawEncodings, data, chartProperties, cjsGetTemplateDef);\n    if (transformed.chartType && transformed.chartType !== chartType) {\n        const swapped = cjsGetTemplateDef(transformed.chartType) as ChartTemplateDef | undefined;\n        if (swapped) chartTemplate = swapped;\n    }\n\n    // Compose Category-B encoding-action overrides (stored by the host in\n    // chartProperties, keyed by action key) onto the post-transform encodings\n    // before any pipeline phase runs. Flint owns the transform; the host only\n    // stores the override value. See applyEncodingOverrides / EncodingActionDef.\n    const encodings = applyEncodingOverrides(chartTemplate, transformed.encodings, chartProperties);\n\n    // Optional aggregation transform — see vegalite/assemble for rationale.\n    data = applyAggregation(encodings, data);\n\n    // ═══════════════════════════════════════════════════════════════════════\n    // PHASE 0: Resolve Semantics (shared with VL + EC — completely target-agnostic)\n    // ═══════════════════════════════════════════════════════════════════════\n\n    const tplMark = chartTemplate.template?.mark;\n    const templateMarkType = typeof tplMark === 'string' ? tplMark : tplMark?.type;\n\n    // Convert temporal data once — feeds semantic resolution and all downstream stages\n    const convertedData = convertTemporalData(data, semanticTypes);\n\n    const channelSemantics = resolveChannelSemantics(\n        encodings, data, semanticTypes, convertedData,\n    );\n\n    // Finalize zero-baseline (requires template mark knowledge)\n    const effectiveMarkType = templateMarkType || 'point';\n    for (const [channel, cs] of Object.entries(channelSemantics)) {\n        if ((channel === 'x' || channel === 'y') && cs.type === 'quantitative') {\n            const numericValues = data\n                .map(r => r[cs.field])\n                .filter((v: any) => v != null && typeof v === 'number' && !isNaN(v));\n            cs.zero = computeZeroDecision(\n                cs.semanticAnnotation.semanticType, channel, effectiveMarkType, numericValues,\n            );\n        }\n    }\n\n    // ═══════════════════════════════════════════════════════════════════════\n    // STEP 0a: declareLayoutMode (shared hook)\n    // ═══════════════════════════════════════════════════════════════════════\n\n    const declaration: LayoutDeclaration = chartTemplate.declareLayoutMode\n        ? chartTemplate.declareLayoutMode(channelSemantics, data, chartProperties)\n        : {};\n\n    const effectiveOptions: AssembleOptions = {\n        // Chart.js fills its canvas natively — a wider default band size\n        // matches its generous category spacing behavior.\n        defaultBandSize: 30,\n        // Chart.js has no default maxBarThickness, so sparse bars fill the\n        // canvas. Allow bands to expand past the base to match, capped so a\n        // couple of bars don't span the whole canvas.\n        maxBandSize: 100,\n        // Chart.js native font default (12 for ticks, legend, and title).\n        baseLabelFontSize: 12,\n        baseTitleFontSize: 12,\n        ...options,\n        ...(declaration.paramOverrides || {}),\n    };\n\n    // Resolve the optional canvasSize ceiling into per-dimension stretch caps\n    // (βx, βy). Falls back to maxStretch when no ceiling is set.\n    Object.assign(effectiveOptions, deriveStretchCaps(baseSize, sizeCeiling, effectiveOptions));\n    effectiveOptions.facetColumns = resolveFacetColumnsOption(input.chart_spec.chartProperties);\n\n    const {\n        addTooltips: addTooltipsOpt = false,\n    } = effectiveOptions;\n\n    // ═══════════════════════════════════════════════════════════════════════\n    // STEP 0b: filterOverflow (shared)\n    // ═══════════════════════════════════════════════════════════════════════\n\n    const allMarkTypes = new Set<string>();\n    if (templateMarkType) allMarkTypes.add(templateMarkType);\n\n    // ── Channel budgets (shared, in layout module) ─────────────────────\n    const budgets = computeChannelBudgets(\n        channelSemantics, declaration, convertedData, canvasSize, effectiveOptions,\n    );\n    const facetGridResult = budgets.facetGrid;\n\n    const overflowResult = filterOverflow(\n        channelSemantics, declaration, encodings, convertedData,\n        budgets, allMarkTypes,\n    );\n\n    const values = overflowResult.filteredData;\n    warnings.push(...overflowResult.warnings);\n\n    // ═══════════════════════════════════════════════════════════════════════\n    // PHASE 1: Compute Layout (shared — completely target-agnostic)\n    // ═══════════════════════════════════════════════════════════════════════\n\n    const layoutResult = computeLayout(\n        channelSemantics,\n        declaration,\n        values,\n        canvasSize,\n        effectiveOptions,\n        facetGridResult,\n    );\n\n    layoutResult.truncations = overflowResult.truncations;\n\n    // ═══════════════════════════════════════════════════════════════════════\n    // PHASE 2: Instantiate Chart.js Config (CJS-specific)\n    // ═══════════════════════════════════════════════════════════════════════\n\n    // Build resolved encodings for interface compatibility\n    const resolvedEncodings: Record<string, any> = {};\n    for (const [channel, encoding] of Object.entries(encodings)) {\n        const cs = channelSemantics[channel];\n        if (cs) {\n            resolvedEncodings[channel] = {\n                field: cs.field,\n                type: cs.type,\n                aggregate: encoding.aggregate,\n            };\n        }\n    }\n\n    // Template instantiate\n    const instantiateContext: InstantiateContext = {\n        channelSemantics,\n        layout: layoutResult,\n        table: values,\n        fullTable: convertedData,\n        resolvedEncodings,\n        encodings,\n        chartProperties,\n        staticSeries,\n        canvasSize,\n        semanticTypes,\n        chartType,\n        assembleOptions: effectiveOptions,\n        colorDecisions: decideColorMaps({\n            chartType,\n            encodings,\n            channelSemantics,\n            table: values,\n            background: 'light',\n        }),\n    };\n\n    const colField = channelSemantics.column?.field;\n    const rowField = channelSemantics.row?.field;\n    const hasFacet = !!(colField || rowField);\n    const hasAxes = chartTemplate.channels.includes('x') || chartTemplate.channels.includes('y');\n\n    let cjsConfig: any;\n    if (hasFacet && hasAxes) {\n        const colValues = colField ? [...new Set(values.map((r: any) => String(r[colField])))] : [''];\n        const rowValues = rowField ? [...new Set(values.map((r: any) => String(r[rowField])))] : [''];\n        const facetLegend: Array<{ label: string; color: string }> = [];\n\n        const yField = channelSemantics.y?.field;\n        const colorField = channelSemantics.color?.field;\n        let sharedYDomain: { min: number; max: number } | undefined;\n        if (yField) {\n            const nums = values\n                .map((r: any) => r[yField])\n                .filter((v: any) => typeof v === 'number' && Number.isFinite(v)) as number[];\n            if (nums.length > 0) {\n                const rawMin = Math.min(...nums);\n                const rawMax = Math.max(...nums);\n                const forceZero = !!channelSemantics.y?.zero?.zero;\n                const min = forceZero ? Math.min(0, rawMin) : rawMin;\n                const max = forceZero ? Math.max(0, rawMax) : rawMax;\n                // Round to \"nice\" bounds so the shared top/bottom land on round\n                // tick values. Otherwise Chart.js draws an extra tick at the\n                // exact data extreme (e.g. 517 or 169,877) that overlaps the\n                // adjacent round tick — Vega-Lite always uses nice bounds here.\n                sharedYDomain = niceBounds(min, max);\n            }\n        }\n\n        // Only the leftmost column reserves room for the shared y-axis; inner\n        // columns drop it and reclaim that width (see estimateYAxisGutter).\n        const axisGutter = sharedYDomain ? estimateYAxisGutter(sharedYDomain) : 0;\n\n        // Column wrapping: a column-only facet with more categories than fit in\n        // one row wraps into a 2D grid (matching Vega-Lite / ECharts). The wrap\n        // width comes from the shared facet-grid budget. computeLayout already\n        // sized the panels for this column count, so we only need to restructure\n        // the flat column list into rows. (2D col+row facets never wrap.)\n        const maxColsPerRow = (colField && !rowField)\n            ? (facetGridResult?.columns ?? colValues.length)\n            : colValues.length;\n        const wrapColumnOnly = !!colField && !rowField && maxColsPerRow < colValues.length;\n\n        const gridRows: Array<Array<{ colVal: string; rowVal: string }>> = [];\n        if (wrapColumnOnly) {\n            for (let i = 0; i < colValues.length; i += maxColsPerRow) {\n                gridRows.push(\n                    colValues.slice(i, i + maxColsPerRow).map((cv) => ({ colVal: cv, rowVal: '' })),\n                );\n            }\n        } else {\n            for (let ri = 0; ri < rowValues.length; ri++) {\n                gridRows.push(colValues.map((cv) => ({ colVal: cv, rowVal: rowValues[ri] })));\n            }\n        }\n\n        const panelRows: any[][] = [];\n        for (let ri = 0; ri < gridRows.length; ri++) {\n            const rowPanels: any[] = [];\n            const cells = gridRows[ri];\n            for (let ci = 0; ci < cells.length; ci++) {\n                const { colVal, rowVal } = cells[ci];\n                const panelData = values.filter((r: any) => {\n                    if (colField && String(r[colField]) !== colVal) return false;\n                    if (rowField && String(r[rowField]) !== rowVal) return false;\n                    return true;\n                });\n\n                const panelConfig: any = structuredClone(chartTemplate.template);\n                const panelContext: InstantiateContext = {\n                    ...instantiateContext,\n                    table: panelData,\n                    layout: layoutResult,\n                };\n                chartTemplate.instantiate(panelConfig, panelContext);\n                // Keep all facet panels the same plot size: disable per-panel built-in legend.\n                // A shared legend is rendered by the gallery host.\n                if (!panelConfig.options) panelConfig.options = {};\n                if (!panelConfig.options.plugins) panelConfig.options.plugins = {};\n                panelConfig.options.plugins.legend = {\n                    ...(panelConfig.options.plugins.legend || {}),\n                    display: false,\n                    position: 'right',\n                };\n                cjsApplyLayoutToSpec(panelConfig, panelContext, []);\n                if (addTooltipsOpt) cjsApplyTooltips(panelConfig);\n                if (chartTemplate.postProcess) chartTemplate.postProcess(panelConfig, panelContext);\n\n                // Shared y-axis across a facet row: only the leftmost column\n                // draws the y tick labels and axis title. Inner columns hide\n                // them entirely (display:false) and shrink their panel width by\n                // the reclaimed gutter, so panels pack tightly and the layout\n                // scales with the canvas. The renderer pins the leftmost axis\n                // width to `axisGutter` so every panel's plot area stays equal\n                // and the lines line up across the row.\n                if (ci > 0 && panelConfig.options?.scales?.y) {\n                    const yScale = panelConfig.options.scales.y;\n                    yScale.ticks = { ...(yScale.ticks || {}), display: false };\n                    yScale.title = { ...(yScale.title || {}), display: false };\n                    yScale.border = { ...(yScale.border || {}), display: false };\n                    if (typeof panelConfig._width === 'number') {\n                        panelConfig._width = Math.max(40, panelConfig._width - axisGutter);\n                    }\n                }\n\n                // Consistent x-axis labels across facet columns. Faceted small\n                // multiples are narrow, and a continuous/temporal x-axis places\n                // its first tick at the panel's left edge. On the leftmost panel\n                // the y-axis gutter gives the leading label room, but inner\n                // panels (no left gutter) clip it, so Chart.js drops it — leaving\n                // each facet with a different set of date labels. `align: 'inner'`\n                // pulls the first/last tick labels inside the chart area so they\n                // render on every panel, keeping the labels consistent across the\n                // row. Detect a continuous x-axis via the template's tick callback.\n                const xScale = panelConfig.options?.scales?.x;\n                if (xScale && typeof xScale.ticks?.callback === 'function') {\n                    xScale.ticks = { ...(xScale.ticks || {}), align: 'inner' };\n                }\n\n                if (facetLegend.length === 0 && colorField && Array.isArray(panelConfig.data?.datasets)) {\n                    for (const ds of panelConfig.data.datasets) {\n                        const label = String(ds?.label ?? '').trim();\n                        if (!label) continue;\n                        const color = String(ds?.borderColor ?? ds?.backgroundColor ?? '#666');\n                        facetLegend.push({ label, color });\n                    }\n                }\n\n                rowPanels.push({\n                    key: `${ri}:${ci}`,\n                    rowIndex: ri,\n                    colIndex: ci,\n                    rowHeader: rowField ? rowVal : undefined,\n                    colHeader: colField ? colVal : undefined,\n                    config: panelConfig,\n                });\n            }\n            panelRows.push(rowPanels);\n        }\n\n        cjsConfig = cjsCombineFacetPanels(\n            panelRows,\n            !!colField,\n            !!rowField,\n            sharedYDomain,\n            axisGutter,\n            wrapColumnOnly,\n        );\n        cjsConfig._facetLegend = facetLegend;\n    } else {\n        cjsConfig = structuredClone(chartTemplate.template);\n        chartTemplate.instantiate(cjsConfig, instantiateContext);\n        cjsApplyLayoutToSpec(cjsConfig, instantiateContext, warnings);\n        if (addTooltipsOpt) cjsApplyTooltips(cjsConfig);\n        if (chartTemplate.postProcess) chartTemplate.postProcess(cjsConfig, instantiateContext);\n    }\n\n    // ═══════════════════════════════════════════════════════════════════════\n    // RESULT\n    // ═══════════════════════════════════════════════════════════════════════\n\n    if (warnings.length > 0) {\n        cjsConfig._warnings = warnings;\n    }\n\n    cjsConfig._dataLength = values.length;\n\n    if (transformed.surface) {\n        cjsConfig._transform = transformed.surface;\n    }\n    // Legacy single-control surface for getChartjsPivot — enumerated from the\n    // authored template so ids/labels match the pre-split contract.\n    const legacyPivot = applyPivot(authoredTemplate, typedRawEncodings, data, chartProperties, cjsGetTemplateDef);\n    if (legacyPivot.surface) {\n        cjsConfig._pivot = legacyPivot.surface;\n    }\n\n    return cjsConfig;\n}\n\n/** Inspect the Chart.js legacy (composed) view transformation surface for an input. */\nexport function getChartjsPivot(input: ChartAssemblyInput): PivotSurface | undefined {\n    const spec = assembleChartjs(input);\n    return spec && spec._pivot ? (spec._pivot as PivotSurface) : undefined;\n}\n\n/** Inspect the Chart.js two-control transform surface for an input. */\nexport function getChartjsTransform(input: ChartAssemblyInput): TransformSurface | undefined {\n    const spec = assembleChartjs(input);\n    return spec && spec._transform ? (spec._transform as TransformSurface) : undefined;\n}\n\n/**\n * Round a [min, max] interval outward to \"nice\" round numbers so a shared facet\n * axis lands its endpoints on clean tick values (mirrors Vega-Lite's default\n * `nice: true`). Without this, Chart.js adds a tick at the exact data extreme,\n * which overlaps the neighbouring round tick.\n */\nfunction niceBounds(min: number, max: number, targetTicks = 5): { min: number; max: number } {\n    if (!(Number.isFinite(min) && Number.isFinite(max)) || max <= min) {\n        return { min, max };\n    }\n    const niceNum = (range: number, round: boolean): number => {\n        const exp = Math.floor(Math.log10(range));\n        const frac = range / 10 ** exp;\n        let niceFrac: number;\n        if (round) {\n            niceFrac = frac < 1.5 ? 1 : frac < 3 ? 2 : frac < 7 ? 5 : 10;\n        } else {\n            niceFrac = frac <= 1 ? 1 : frac <= 2 ? 2 : frac <= 5 ? 5 : 10;\n        }\n        return niceFrac * 10 ** exp;\n    };\n    const step = niceNum(niceNum(max - min, false) / Math.max(1, targetTicks - 1), true);\n    return {\n        min: Math.floor(min / step) * step,\n        max: Math.ceil(max / step) * step,\n    };\n}\n\n/**\n * Estimate the horizontal space (px) a faceted line/bar y-axis needs for its\n * tick labels plus the rotated axis title. Only the leftmost facet column draws\n * this axis; inner columns reclaim the space, so the figure packs tightly and\n * stays responsive to the canvas size (instead of every panel paying a fixed\n * ~70px gutter).\n */\nfunction estimateYAxisGutter(domain: { min: number; max: number }): number {\n    const fmt = (v: number) => {\n        const r = Math.round(v);\n        return Math.abs(r) >= 1000 ? r.toLocaleString() : String(r);\n    };\n    const chars = Math.max(fmt(domain.min).length, fmt(domain.max).length);\n    // ~6.5px per label char + tick padding (~12) + rotated axis title (~18).\n    return Math.ceil(chars * 6.5) + 30;\n}\n\nfunction cjsCombineFacetPanels(\n    panelRows: any[][],\n    hasColHeader: boolean,\n    hasRowHeader: boolean,\n    sharedYDomain?: { min: number; max: number },\n    axisGutter = 0,\n    colHeaderPerRow = false,\n): any {\n    const rows = panelRows.length;\n    const cols = Math.max(1, ...panelRows.map(r => r.length));\n    const ref = panelRows[0]?.[0]?.config;\n    const panelH = ref?._height || 300;\n    const gap = 16;\n    const colHeaderH = hasColHeader ? 22 : 0;\n    const rowHeaderW = hasRowHeader ? 28 : 0;\n\n    // Column widths vary: the leftmost column keeps the y-axis gutter; the rest\n    // are narrower. Sum the first row's actual panel widths for the figure size.\n    const colWidths = Array.from({ length: cols }, (_, ci) =>\n        (panelRows[0]?.[ci]?.config?._width as number) || ref?._width || 400,\n    );\n    const totalPanelsW = colWidths.reduce((a, b) => a + b, 0);\n\n    // Wrapped column-only facets repeat the column-header band above every row;\n    // otherwise there is a single header band across the top.\n    const headerBands = colHeaderPerRow ? rows : (hasColHeader ? 1 : 0);\n\n    return {\n        _facet: true,\n        _facetPanels: panelRows,\n        _facetRows: rows,\n        _facetCols: cols,\n        _facetSharedYDomain: sharedYDomain,\n        _facetAxisGutter: axisGutter,\n        _facetColHeaderPerRow: colHeaderPerRow,\n        _width: rowHeaderW + totalPanelsW + (cols - 1) * gap,\n        _height: headerBands * colHeaderH + rows * panelH + (rows - 1) * gap,\n    };\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * =============================================================================\n * CHART RECOMMENDATION & ADAPTATION ENGINE\n * =============================================================================\n *\n * Backend-agnostic logic for two chart operations:\n *\n *   1. **Adaptation** — remapping encoding channels when switching chart types\n *      (e.g. Bar→Pie: x→color, y→size because the semantic roles differ).\n *\n *   2. **Recommendation** — suggesting which data fields best fit each\n *      encoding channel for a given chart type, using semantic types,\n *      cardinality constraints, and data-fitness tests.\n *\n * Both functions operate on plain field names (string→string maps) with no\n * UI-layer dependencies.  Backend-specific wrappers (vegalite/recommendation.ts\n * etc.) filter results to channels that actually exist in that backend's\n * template registry.\n *\n * =============================================================================\n */\n\nimport {\n    inferVisCategory,\n    getVisCategory,\n    isMeasureType,\n    isTimeSeriesType,\n    isCategoricalType,\n    isOrdinalType,\n    isGeoType,\n    isGeoCoordinateType,\n    isNonMeasureNumeric,\n} from './semantic-types';\n\n// ============================================================================\n// 1. Semantic Role System (used by adaptation)\n// ============================================================================\n\n/**\n * Semantic role of a channel within a specific chart type.\n */\nexport type SemanticRole =\n    | 'category'\n    | 'measure'\n    | 'measure2'\n    | 'series'\n    | 'facetCol'\n    | 'facetRow'\n    | 'auxiliary'\n    | 'geo'\n    | 'price';\n\ntype ChannelRoleMap = Partial<Record<string, SemanticRole>>;\n\n// ── Chart Families ──────────────────────────────────────────────────────\n\n/** Standard x/y charts: x=category, y=measure, color=series */\nconst FAMILY_XY_STANDARD: ChannelRoleMap = {\n    x: 'category', y: 'measure', color: 'series',\n    opacity: 'auxiliary', size: 'auxiliary', shape: 'auxiliary',\n    detail: 'auxiliary', group: 'series',\n    column: 'facetCol', row: 'facetRow',\n};\n\n/** Horizontal x/y charts (Bar Table, etc.): y=category, x=measure. Same channel\n *  names as standard x/y, but axes are swapped — keeping them as x/y means we\n *  inherit shelf/color/facet plumbing for free, while adaptation knows the\n *  category lives on `y` so switching to/from a vertical bar chart auto-swaps. */\nconst FAMILY_XY_HORIZONTAL: ChannelRoleMap = {\n    y: 'category', x: 'measure', color: 'series',\n    opacity: 'auxiliary', size: 'auxiliary', shape: 'auxiliary',\n    detail: 'auxiliary', group: 'series',\n    column: 'facetCol', row: 'facetRow',\n};\n\n/** Pie-like charts: color=category, size=measure */\nconst FAMILY_PIE: ChannelRoleMap = {\n    color: 'category', size: 'measure',\n    column: 'facetCol', row: 'facetRow',\n};\n\n/** Rose chart: polar radial bar — x=category, y=measure, color=series */\nconst FAMILY_ROSE: ChannelRoleMap = {\n    x: 'category', y: 'measure', color: 'series',\n    column: 'facetCol', row: 'facetRow',\n};\n\n/** Radar chart */\nconst FAMILY_RADAR: ChannelRoleMap = {\n    x: 'category', y: 'measure', color: 'series',\n    column: 'facetCol', row: 'facetRow',\n};\n\n/** Map charts: latitude/longitude = geo */\nconst FAMILY_MAP: ChannelRoleMap = {\n    latitude: 'geo', longitude: 'geo',\n    color: 'series', size: 'auxiliary', opacity: 'auxiliary',\n};\n\n/** Choropleth: id=region (geo), color=measure */\nconst FAMILY_CHOROPLETH: ChannelRoleMap = {\n    id: 'geo', color: 'measure', detail: 'auxiliary',\n};\n\n/** Candlestick: x=category, open/high/low/close=price */\nconst FAMILY_CANDLESTICK: ChannelRoleMap = {\n    x: 'category',\n    open: 'price', high: 'price', low: 'price', close: 'price',\n    column: 'facetCol', row: 'facetRow',\n};\n\n/** Histogram: x=measure (binned) */\nconst FAMILY_HISTOGRAM: ChannelRoleMap = {\n    x: 'measure', color: 'series',\n    column: 'facetCol', row: 'facetRow',\n};\n\n/** Density */\nconst FAMILY_DENSITY: ChannelRoleMap = {\n    x: 'measure', color: 'series',\n    column: 'facetCol', row: 'facetRow',\n};\n\n/** 2-D density (Density Contour): both axes are measures, binned into a joint\n *  distribution — no series channel (colour encodes count). */\nconst FAMILY_DENSITY_2D: ChannelRoleMap = {\n    x: 'measure', y: 'measure2',\n    column: 'facetCol', row: 'facetRow',\n};\n\n/** Heatmap: x=category, y=category, color=measure */\nconst FAMILY_HEATMAP: ChannelRoleMap = {\n    x: 'category', y: 'category', color: 'measure',\n    column: 'facetCol', row: 'facetRow',\n};\n\n/** Gauge: size=measure */\nconst FAMILY_GAUGE: ChannelRoleMap = {\n    size: 'measure', column: 'facetCol',\n};\n\n/** Funnel: y=category, size=measure */\nconst FAMILY_FUNNEL: ChannelRoleMap = {\n    y: 'category', size: 'measure',\n};\n\n/** Treemap / Sunburst */\nconst FAMILY_TREEMAP: ChannelRoleMap = {\n    color: 'category', size: 'measure', detail: 'auxiliary', group: 'auxiliary',\n};\n\n/** Sankey */\nconst FAMILY_SANKEY: ChannelRoleMap = {\n    x: 'category', y: 'category', size: 'measure',\n};\n\n/** Gantt: horizontal interval bar — y=task, x=start, x2=end, color=series */\nconst FAMILY_GANTT: ChannelRoleMap = {\n    y: 'category', x: 'measure', x2: 'measure2', color: 'series',\n    detail: 'auxiliary', column: 'facetCol', row: 'facetRow',\n};\n\n/** Bullet: y=label, x=value (measure), goal=target (measure2) */\nconst FAMILY_BULLET: ChannelRoleMap = {\n    y: 'category', x: 'measure', goal: 'measure2', color: 'series',\n    column: 'facetCol', row: 'facetRow',\n};\n\n// ── Chart → Family lookup ───────────────────────────────────────────────\n\nconst CHART_ROLE_MAP: Record<string, ChannelRoleMap> = {\n    // Axis-based (x/y standard)\n    'Bar Chart': FAMILY_XY_STANDARD,\n    'Pyramid Chart': FAMILY_XY_HORIZONTAL,\n    'Grouped Bar Chart': FAMILY_XY_STANDARD,\n    'Stacked Bar Chart': FAMILY_XY_STANDARD,\n    'Lollipop Chart': FAMILY_XY_STANDARD,\n    'Waterfall Chart': FAMILY_XY_STANDARD,\n    'Gantt Chart': FAMILY_GANTT,\n    'Bullet Chart': FAMILY_BULLET,\n    'Bar Table': FAMILY_XY_HORIZONTAL,\n    'Line Chart': FAMILY_XY_STANDARD,\n    'Bump Chart': FAMILY_XY_STANDARD,\n    'Area Chart': FAMILY_XY_STANDARD,\n    'Streamgraph': FAMILY_XY_STANDARD,\n    'Scatter Plot': FAMILY_XY_STANDARD,\n    'Connected Scatter Plot': FAMILY_XY_STANDARD,\n    'Regression': FAMILY_XY_STANDARD,\n    'Ranged Dot Plot': FAMILY_XY_STANDARD,\n    'Boxplot': FAMILY_XY_STANDARD,\n    'Strip Plot': FAMILY_XY_STANDARD,\n    // Pie-like\n    'Pie Chart': FAMILY_PIE,\n    // Polar\n    'Rose Chart': FAMILY_ROSE,\n    'Radar Chart': FAMILY_RADAR,\n    // Heatmap\n    'Heatmap': FAMILY_HEATMAP,\n    // Histogram / Density\n    'Histogram': FAMILY_HISTOGRAM,\n    'Density Plot': FAMILY_DENSITY,\n    'Density Contour': FAMILY_DENSITY_2D,\n    // Geographic\n    'Map': FAMILY_MAP,\n    'Choropleth': FAMILY_CHOROPLETH,\n    // Financial\n    'Candlestick Chart': FAMILY_CANDLESTICK,\n    // ECharts-only\n    'Gauge Chart': FAMILY_GAUGE,\n    'Funnel Chart': FAMILY_FUNNEL,\n    'Treemap': FAMILY_TREEMAP,\n    'Sunburst Chart': FAMILY_TREEMAP,\n    'Sankey Diagram': FAMILY_SANKEY,\n};\n\n// ── Role helpers ────────────────────────────────────────────────────────\n\nfunction getChannelRole(chartType: string, channel: string): SemanticRole {\n    const roleMap = CHART_ROLE_MAP[chartType];\n    if (roleMap && channel in roleMap) return roleMap[channel]!;\n    if (channel === 'column') return 'facetCol';\n    if (channel === 'row') return 'facetRow';\n    return 'auxiliary';\n}\n\nfunction findChannelsByRole(chartType: string, templateChannels: string[], role: SemanticRole): string[] {\n    return templateChannels.filter(ch => getChannelRole(chartType, ch) === role);\n}\n\n/** Fallback chain when target has no channel with the exact source role. */\nconst FALLBACK_CHAIN: Partial<Record<SemanticRole, SemanticRole[]>> = {\n    measure2: ['measure', 'auxiliary'],\n    series: ['auxiliary'],\n    category: ['series', 'auxiliary'],\n    measure: ['auxiliary'],\n    geo: ['category'],\n    price: ['measure', 'auxiliary'],\n};\n\nconst ROLE_PRIORITY: Record<SemanticRole, number> = {\n    category: 0, measure: 1, series: 2, facetCol: 3, facetRow: 4,\n    measure2: 5, auxiliary: 6, geo: 7, price: 8,\n};\n\n// ============================================================================\n// 2. Adaptation — adapt channel encodings across chart types\n// ============================================================================\n\n/**\n * Adapt encoding channels from one chart type to another.\n *\n * When `data` is provided, uses **recommendation-based adaptation**: re-runs\n * the recommendation engine with a strong preference for the currently-assigned\n * fields, letting the target chart's field-type preferences take effect\n * (e.g. Line Chart prefers temporal on x).  Remaining empty channels are\n * optionally filled from all available fields.\n *\n * When no data is provided, falls back to **structural role-based** adaptation\n * (pure channel remapping by semantic role).\n *\n * @param sourceType      The current chart type name (e.g. \"Bar Chart\")\n * @param targetType      The target chart type name (e.g. \"Pie Chart\")\n * @param targetChannels  Available channels on the target template\n * @param encodings       Current channel→fieldName map (only filled channels)\n * @param data            (optional) Array of data row objects\n * @param semanticTypes   (optional) Field→semantic-type map\n * @returns               New channel→fieldName map for the target\n */\nexport function adaptChannels(\n    sourceType: string,\n    targetType: string,\n    targetChannels: string[],\n    encodings: Record<string, string>,\n    data?: any[],\n    semanticTypes?: Record<string, string>,\n    recommendFn?: RecommendFn,\n): Record<string, string> {\n    // Recommendation-based adaptation when data is available\n    if (data && data.length > 0) {\n        return adaptViaRecommendation(sourceType, targetType, targetChannels, encodings, data, semanticTypes ?? {}, recommendFn ?? getRecommendation);\n    }\n\n    // Fallback: structural role-based adaptation\n    return adaptViaRoles(sourceType, targetType, targetChannels, encodings);\n}\n\n/**\n * Edit-distance-based adaptation: find the minimum-cost mapping from existing\n * field→channel assignments to target chart channels.\n *\n * Cost model (see `assignCost` below):\n *   0    — same channel name AND same semantic role\n *   0.5  — different channel name, same semantic role\n *   1    — same channel name but different role, OR different name + role\n *   1.5  — field is dropped\n *   ∞    — field type is incompatible with target channel\n *\n * No autofill: the result contains at most as many fields as the source had.\n * Empty target channels are left for the user to fill explicitly.\n */\nfunction adaptViaRecommendation(\n    sourceType: string,\n    targetType: string,\n    targetChannels: string[],\n    encodings: Record<string, string>,\n    data: any[],\n    semanticTypes: Record<string, string>,\n    _recommendFn: RecommendFn,\n): Record<string, string> {\n    // --- Pre-process: handle facet channels and filter data ---\n    const FACET_CHANNELS = ['column', 'row'];\n    let facetedData = data;\n    const prePinned: Record<string, string> = {};\n    const prePinnedFields = new Set<string>();\n\n    for (const ch of FACET_CHANNELS) {\n        const field = encodings[ch];\n        if (field && targetChannels.includes(ch)) {\n            prePinned[ch] = field;\n            prePinnedFields.add(field);\n            if (facetedData.length > 0) {\n                const firstVal = facetedData[0][field];\n                facetedData = facetedData.filter(row => row[field] === firstVal);\n            }\n        }\n    }\n\n    const tv = buildTableView(facetedData, semanticTypes);\n\n    // --- Type compatibility check ---\n    const isFieldCompatibleWithRole = (role: SemanticRole, field: string): boolean => {\n        const ft = tv.fieldType[field] ?? 'nominal';\n        const st = tv.fieldSemanticType[field] ?? '';\n        const card = tv.fieldLevels[field]?.length ?? 0;\n        switch (role) {\n            // 'category' is for true discrete axes (nominal/ordinal/temporal).\n            // Quantitative fields — even low-cardinality ones — must NOT\n            // satisfy this role, otherwise a measure can land on the\n            // category axis (e.g. Bar Table y) and push the real discrete\n            // field onto color.\n            case 'category':  return !isQuantitativeField(ft, st) && isDiscreteLike(ft, st, card);\n            case 'measure':   return isQuantitativeField(ft, st);\n            case 'series':    return isDiscreteLike(ft, st, card);\n            case 'geo':       return isGeoCoordinateType(st) || ft === 'quantitative';\n            case 'facetCol':  case 'facetRow': return isDiscreteLike(ft, st, card);\n            case 'auxiliary':  return true;\n            default:          return true;\n        }\n    };\n\n    // --- Cost function for assigning field (from srcCh) to targetCh ---\n    //\n    // Role match is the dominant signal: a field whose role matches the target\n    // channel's role is preferred over a field that merely happens to share the\n    // same channel name.  This is important when swapping between strict\n    // \"category × quantitative\" chart types (Bar, Pie, Heatmap, …) where the\n    // semantic axis assignment of the target should win over channel-name\n    // preservation from the source.\n    const assignCost = (srcCh: string, field: string, targetCh: string): number => {\n        const targetRole = getChannelRole(targetType, targetCh);\n        if (!isFieldCompatibleWithRole(targetRole, field)) return Infinity;\n\n        const srcRole = getChannelRole(sourceType, srcCh);\n\n        // Same channel AND same role → free preservation (e.g. Bar→Stacked Bar x→x)\n        if (srcCh === targetCh && srcRole === targetRole) return 0;\n\n        // Same semantic role, different channel name → small cost\n        //   (e.g. Heatmap.color (measure) → Bar.y (measure))\n        if (srcRole === targetRole) return 0.5;\n\n        // Same channel name but different role → role mismatch is more costly\n        //   than a role-match move; prevents e.g. src.color (series) clobbering\n        //   tgt.color (category) in Pie.\n        if (srcCh === targetCh) return 1;\n\n        // Different role and different name, type-compatible → highest move cost\n        return 1;\n    };\n\n    const COST_DROP = 1.5;  // slightly above move cost to prefer keeping fields\n\n    // --- Collect source entries (excluding pre-pinned facets) ---\n    const entries = Object.entries(encodings)\n        .filter(([ch, f]) => f && !FACET_CHANNELS.includes(ch) && !prePinnedFields.has(f));\n\n    // Available target channels (exclude pre-pinned ones)\n    const availableTargets = targetChannels.filter(ch => !(ch in prePinned));\n\n    // --- Solve minimum-cost assignment via branch-and-bound ---\n    // With typically ≤5 fields and ≤8 channels, this is instant.\n    let bestCost = Infinity;\n    let bestAssignment: Record<string, string> = {};\n\n    const usedTargets = new Set<string>();\n\n    function solve(\n        idx: number,\n        currentCost: number,\n        assignment: Record<string, string>,\n    ): void {\n        if (currentCost >= bestCost) return;  // prune\n\n        if (idx === entries.length) {\n            bestCost = currentCost;\n            bestAssignment = { ...assignment };\n            return;\n        }\n\n        const [srcCh, field] = entries[idx];\n\n        // Option A: assign to each available target channel\n        for (const tch of availableTargets) {\n            if (usedTargets.has(tch)) continue;\n            const cost = assignCost(srcCh, field, tch);\n            if (cost === Infinity) continue;\n\n            usedTargets.add(tch);\n            assignment[tch] = field;\n            solve(idx + 1, currentCost + cost, assignment);\n            delete assignment[tch];\n            usedTargets.delete(tch);\n        }\n\n        // Option B: drop the field\n        solve(idx + 1, currentCost + COST_DROP, assignment);\n    }\n\n    solve(0, 0, {});\n\n    // --- Merge pre-pinned facets + solver result ---\n    //\n    // Intentionally do NOT auto-fill remaining empty target channels via the\n    // recommendation engine: when the user already configured a chart with N\n    // fields and switches type, the adapted chart should also have at most N\n    // fields.  Adding extra fields the user never picked is surprising (e.g.\n    // a 2-encoding Bar Chart turning into a 5-encoding Scatter Plot on type\n    // switch).  Empty channels are left for the user to fill explicitly.\n    const result: Record<string, string> = { ...prePinned, ...bestAssignment };\n\n    return result;\n}\n\n/**\n * Structural role-based adaptation: remap channels by semantic role when no\n * data is available.  Each field keeps its role (category, measure, series…)\n * and is placed into the target channel that has the same role.\n */\nfunction adaptViaRoles(\n    sourceType: string,\n    targetType: string,\n    targetChannels: string[],\n    encodings: Record<string, string>,\n): Record<string, string> {\n    const result: Record<string, string> = {};\n\n    // Collect filled encodings with their semantic roles\n    const filledEncodings: { channel: string; role: SemanticRole; field: string }[] = [];\n    for (const [ch, field] of Object.entries(encodings)) {\n        if (field) {\n            filledEncodings.push({ channel: ch, role: getChannelRole(sourceType, ch), field });\n        }\n    }\n\n    // Sort by priority: category > measure > series > …\n    filledEncodings.sort((a, b) => ROLE_PRIORITY[a.role] - ROLE_PRIORITY[b.role]);\n\n    const assigned = new Set<string>();\n\n    for (const { channel: srcCh, role: srcRole, field } of filledEncodings) {\n        let placed = false;\n\n        // (a) Direct match: same channel name with same role\n        if (targetChannels.includes(srcCh) && !assigned.has(srcCh)) {\n            if (getChannelRole(targetType, srcCh) === srcRole) {\n                result[srcCh] = field;\n                assigned.add(srcCh);\n                placed = true;\n            }\n        }\n\n        if (!placed) {\n            // (b) Role match: find empty target channel with same role\n            placed = tryAssign(srcRole, field, targetType, targetChannels, result, assigned, srcCh);\n        }\n\n        if (!placed) {\n            // (c) Fallback chain\n            const chain = FALLBACK_CHAIN[srcRole];\n            if (chain) {\n                for (const fallbackRole of chain) {\n                    placed = tryAssign(fallbackRole, field, targetType, targetChannels, result, assigned, srcCh);\n                    if (placed) break;\n                }\n            }\n        }\n        // (d) If not placed, encoding is dropped\n    }\n\n    return result;\n}\n\nfunction tryAssign(\n    role: SemanticRole,\n    field: string,\n    targetType: string,\n    targetChannels: string[],\n    result: Record<string, string>,\n    assigned: Set<string>,\n    preferredName?: string,\n): boolean {\n    const candidates = findChannelsByRole(targetType, targetChannels, role)\n        .filter(ch => !assigned.has(ch));\n    if (candidates.length === 0) return false;\n    const best = preferredName && candidates.includes(preferredName)\n        ? preferredName : candidates[0];\n    result[best] = field;\n    assigned.add(best);\n    return true;\n}\n\n// ============================================================================\n// 3. Internal Table View — field classification from data + semantic types\n// ============================================================================\n\nexport interface InternalTableView {\n    names: string[];\n    fieldType: Record<string, string>;\n    fieldSemanticType: Record<string, string>;\n    fieldLevels: Record<string, any[]>;\n    rows: any[];\n    /** Fields the user has already assigned — preferred during pick(). */\n    preferredFields?: Set<string>;\n}\n\n/**\n * Recommendation function signature — used to inject backend-specific\n * chart type handlers into adaptViaRecommendation.\n */\nexport type RecommendFn = (chartType: string, tv: InternalTableView) => Record<string, string>;\n\nexport function buildTableView(data: any[], semanticTypes: Record<string, string>): InternalTableView {\n    const names = data.length > 0 ? Object.keys(data[0]) : [];\n    const fieldType: Record<string, string> = {};\n    const fieldSemanticType: Record<string, string> = {};\n    const fieldLevels: Record<string, any[]> = {};\n\n    for (const name of names) {\n        const values = data.map(r => r[name]);\n        const semanticType = semanticTypes[name] || '';\n        fieldType[name] = (semanticType && getVisCategory(semanticType)) || inferVisCategory(values);\n        fieldSemanticType[name] = semanticType;\n        fieldLevels[name] = [...new Set(data.map(r => r[name]).filter(v => v != null))];\n    }\n\n    return { names, fieldType, fieldSemanticType, fieldLevels, rows: data };\n}\n\n// ============================================================================\n// 4. Preference-Based Assignment Solver\n// ============================================================================\n\n/** Preference tiers for a (channel, field) pair. */\nexport const Pref = { STRONG: 3, OK: 2, WEAK: 1, EXCLUDE: -Infinity } as const;\nexport type PrefScore = number;\n\n/**\n * A scoring function that returns a preference score for a field being\n * assigned to a particular channel.  Return Pref.EXCLUDE to forbid the\n * assignment.\n */\nexport type ChannelPrefFn = (\n    name: string, type: string, semanticType: string,\n    cardinality: number, hasLevels: boolean,\n) => PrefScore;\n\n/**\n * Solve the assignment problem: given N channels each with a preference\n * scoring function, and a set of candidate fields, find the assignment of\n * distinct fields to channels that maximises total score.\n *\n * Returns the best assignment as a Record<channel, fieldName>, or {} if\n * no valid (all-channels-filled) assignment exists.\n *\n * Complexity: O(C! · F^C) where C = number of channels, F = number of\n * fields.  Fine for C ≤ 5 and typical field counts.\n */\nexport function resolveAssignment(\n    tv: InternalTableView,\n    used: Set<string>,\n    channelPrefs: { channel: string; pref: ChannelPrefFn }[],\n): Record<string, string> {\n    // Build the score matrix: scores[channelIdx][fieldIdx]\n    const candidates: string[] = tv.names.filter(n => !used.has(n) && (!isLikelyIdentifierOrRank(n) || tv.preferredFields?.has(n)));\n    const C = channelPrefs.length;\n    const F = candidates.length;\n    if (F < C) return {};\n\n    // Pre-compute all scores\n    const scores: number[][] = [];\n    for (let ci = 0; ci < C; ci++) {\n        scores[ci] = [];\n        for (let fi = 0; fi < F; fi++) {\n            const name = candidates[fi];\n            const type = tv.fieldType[name] ?? 'nominal';\n            const st = tv.fieldSemanticType[name] ?? '';\n            const card = tv.fieldLevels[name]?.length ?? 0;\n            scores[ci][fi] = channelPrefs[ci].pref(name, type, st, card, card > 0);\n        }\n    }\n\n    // Brute-force search over all C-permutations of F fields\n    let bestScore = -Infinity;\n    let bestAssign: number[] | undefined;\n\n    const perm = new Array<number>(C);\n    const usedF = new Uint8Array(F);\n\n    function search(depth: number, totalScore: number) {\n        if (depth === C) {\n            if (totalScore > bestScore) {\n                bestScore = totalScore;\n                bestAssign = [...perm];\n            }\n            return;\n        }\n        for (let fi = 0; fi < F; fi++) {\n            if (usedF[fi]) continue;\n            const s = scores[depth][fi];\n            if (s === -Infinity) continue;            // excluded\n            if (totalScore + s <= bestScore - (C - depth - 1) * Pref.STRONG) continue; // prune\n            perm[depth] = fi;\n            usedF[fi] = 1;\n            search(depth + 1, totalScore + s);\n            usedF[fi] = 0;\n        }\n    }\n\n    search(0, 0);\n\n    if (!bestAssign) return {};\n\n    const result: Record<string, string> = {};\n    for (let ci = 0; ci < C; ci++) {\n        const fieldName = candidates[bestAssign[ci]];\n        result[channelPrefs[ci].channel] = fieldName;\n        used.add(fieldName);\n    }\n    return result;\n}\n\n// ============================================================================\n// 5. Field Classification Utilities (renumbered)\n// ============================================================================\n\nfunction isTemporalField(type: string, semanticType: string): boolean {\n    return type === 'temporal' || isTimeSeriesType(semanticType);\n}\n\nfunction isQuantitativeField(type: string, semanticType: string): boolean {\n    if (isTemporalField(type, semanticType)) return false;\n    if (type !== 'quantitative') return false;\n    if (isNonMeasureNumeric(semanticType)) return false;\n    return isMeasureType(semanticType) || semanticType === '';\n}\n\nfunction isOrdinalField(type: string, semanticType: string, hasLevels: boolean): boolean {\n    if (hasLevels) return true;\n    return isOrdinalType(semanticType);\n}\n\nfunction isCategoricalFieldCheck(type: string, semanticType: string): boolean {\n    if (isTemporalField(type, semanticType)) return false;\n    if (isQuantitativeField(type, semanticType)) return false;\n    return type === 'nominal' || isCategoricalType(semanticType);\n}\n\nfunction isDiscreteLike(type: string, semanticType: string, cardinality: number, maxCard = 50): boolean {\n    if (isCategoricalFieldCheck(type, semanticType)) return true;\n    if (isTemporalField(type, semanticType)) return true;\n    if (isOrdinalType(semanticType)) return true;\n    if (type === 'quantitative' && cardinality > 0 && cardinality <= maxCard) return true;\n    return false;\n}\n\nexport function nameMatches(name: string, patterns: string[]): boolean {\n    const lower = name.toLowerCase();\n    return patterns.some(p => lower === p) || patterns.some(p => lower.includes(p));\n}\n\nfunction isLikelyIdentifierOrRank(name: string): boolean {\n    const lower = name.toLowerCase();\n    const idPatterns = ['rank', 'id', 'index', 'idx', 'row', 'order', 'position', 'pos'];\n    return idPatterns.some(p => lower === p || lower.endsWith('_' + p) || lower.endsWith(p));\n}\n\n// ============================================================================\n// 6. Field Picker Utilities\n// ============================================================================\n\nexport function pick(\n    tv: InternalTableView,\n    used: Set<string>,\n    predicate: (name: string, type: string, semanticType: string, cardinality: number, hasLevels: boolean) => boolean,\n): string | undefined {\n    const candidates: string[] = [];\n    for (const name of tv.names) {\n        if (used.has(name)) continue;\n        const type = tv.fieldType[name] ?? 'nominal';\n        const semanticType = tv.fieldSemanticType[name] ?? '';\n        const cardinality = tv.fieldLevels[name]?.length ?? 0;\n        const hasLevels = cardinality > 0;\n        if (predicate(name, type, semanticType, cardinality, hasLevels)) {\n            candidates.push(name);\n        }\n    }\n    if (candidates.length === 0) return undefined;\n    // Deterministic selection: prefer a field the user already uses, otherwise\n    // the first candidate in table order. Stable, so a given dataset always\n    // yields the same suggestion (no random tie-break).\n    if (tv.preferredFields) {\n        const preferred = candidates.filter(n => tv.preferredFields!.has(n));\n        if (preferred.length > 0) {\n            const chosen = preferred[0];\n            used.add(chosen);\n            return chosen;\n        }\n    }\n    const chosen = candidates[0];\n    used.add(chosen);\n    return chosen;\n}\n\nexport const pickQuantitative = (tv: InternalTableView, u: Set<string>) =>\n    pick(tv, u, (name, ty, st) => isQuantitativeField(ty, st) && (!isLikelyIdentifierOrRank(name) || !!tv.preferredFields?.has(name)));\n\nexport const pickTemporal = (tv: InternalTableView, u: Set<string>) =>\n    pick(tv, u, (_n, ty, st) => isTemporalField(ty, st));\n\nexport const pickNominal = (tv: InternalTableView, u: Set<string>) =>\n    pick(tv, u, (_n, ty, st) => isCategoricalFieldCheck(ty, st));\n\nexport const pickLowCardNominal = (tv: InternalTableView, u: Set<string>, maxCard = 30) =>\n    pick(tv, u, (_n, ty, st, card) => isCategoricalFieldCheck(ty, st) && card > 0 && card <= maxCard);\n\nexport const pickOrdinal = (tv: InternalTableView, u: Set<string>) =>\n    pick(tv, u, (_n, ty, st, _card, hasLevels) => isOrdinalField(ty, st, hasLevels));\n\nexport const pickGeo = (tv: InternalTableView, u: Set<string>) =>\n    pick(tv, u, (_n, _ty, st) => isGeoType(st));\n\nexport const pickDiscrete = (tv: InternalTableView, u: Set<string>) =>\n    pick(tv, u, (name, ty, st, card) => isDiscreteLike(ty, st, card) && (!isLikelyIdentifierOrRank(name) || !!tv.preferredFields?.has(name)));\n\nexport const pickLowCardDiscrete = (tv: InternalTableView, u: Set<string>, maxCard = 30) =>\n    pick(tv, u, (name, ty, st, card) =>\n        isDiscreteLike(ty, st, card, maxCard) && card > 0 && card <= maxCard\n        && (!isLikelyIdentifierOrRank(name) || !!tv.preferredFields?.has(name))\n    );\n\nexport const pickSeriesAxis = (tv: InternalTableView, u: Set<string>) =>\n    pickTemporal(tv, u) ?? pickOrdinal(tv, u) ?? pickNominal(tv, u);\n\nexport const pickQuantitativeByName = (tv: InternalTableView, u: Set<string>, patterns: string[]) =>\n    pick(tv, u, (name, ty, st) => isQuantitativeField(ty, st) && nameMatches(name, patterns));\n\nexport function pickAllQuantitative(tv: InternalTableView, used: Set<string>): string[] {\n    const result: string[] = [];\n    for (const name of tv.names) {\n        if (used.has(name)) continue;\n        const type = tv.fieldType[name] ?? 'nominal';\n        const semanticType = tv.fieldSemanticType[name] ?? '';\n        if (isQuantitativeField(type, semanticType) && (!isLikelyIdentifierOrRank(name) || tv.preferredFields?.has(name))) {\n            result.push(name);\n        }\n    }\n    for (const name of result) used.add(name);\n    return result;\n}\n\n// ============================================================================\n// 7. Data Fitness Tests\n// ============================================================================\n\nexport function hasMultipleValuesPerField(tv: InternalTableView, fieldName: string): boolean {\n    if (!fieldName || !tv.rows || tv.rows.length === 0) return false;\n    const seen = new Set<any>();\n    for (const row of tv.rows) {\n        const val = row[fieldName];\n        if (seen.has(val)) return true;\n        seen.add(val);\n    }\n    return false;\n}\n\nfunction isValidGroupingField(tv: InternalTableView, xField: string, colorField: string): boolean {\n    if (!xField || !colorField || !tv.rows || tv.rows.length === 0) return false;\n    const seen = new Set<string>();\n    for (const row of tv.rows) {\n        const key = `${row[xField]}|||${row[colorField]}`;\n        if (seen.has(key)) return false;\n        seen.add(key);\n    }\n    return true;\n}\n\n/**\n * Deterministic grouping/series selection: choose the lowest-cardinality\n * candidate (fewest distinct values → the most readable legend), breaking ties\n * by table order. Replaces an earlier random tie-break so recommendations are\n * stable and prefer compact color/series encodings.\n */\nfunction lowestCardinality(tv: InternalTableView, candidates: string[]): string {\n    let best = candidates[0];\n    let bestCard = tv.fieldLevels[best]?.length ?? Infinity;\n    for (let i = 1; i < candidates.length; i++) {\n        const card = tv.fieldLevels[candidates[i]]?.length ?? Infinity;\n        if (card < bestCard) { best = candidates[i]; bestCard = card; }\n    }\n    return best;\n}\n\nexport function pickValidGroupingField(\n    tv: InternalTableView, used: Set<string>, xField: string, maxCard = 20,\n): string | undefined {\n    const candidates: string[] = [];\n    for (const name of tv.names) {\n        if (used.has(name)) continue;\n        const type = tv.fieldType[name] ?? 'nominal';\n        const semanticType = tv.fieldSemanticType[name] ?? '';\n        const cardinality = tv.fieldLevels[name]?.length ?? 0;\n        if (!isDiscreteLike(type, semanticType, cardinality, maxCard)) continue;\n        if (cardinality <= 0 || cardinality > maxCard) continue;\n        if (isLikelyIdentifierOrRank(name) && !tv.preferredFields?.has(name)) continue;\n        if (isValidGroupingField(tv, xField, name)) candidates.push(name);\n    }\n    if (candidates.length === 0) return undefined;\n    // Prefer a field the user already uses; otherwise the lowest-cardinality\n    // valid grouping field (fewest colors). Deterministic — no random pick.\n    if (tv.preferredFields) {\n        const preferred = candidates.filter(n => tv.preferredFields!.has(n));\n        if (preferred.length > 0) {\n            const chosen = lowestCardinality(tv, preferred);\n            used.add(chosen);\n            return chosen;\n        }\n    }\n    const chosen = lowestCardinality(tv, candidates);\n    used.add(chosen);\n    return chosen;\n}\n\nexport function isValidLineSeriesData(tv: InternalTableView, xField: string, colorField?: string): boolean {\n    if (!tv.rows || tv.rows.length === 0) return false;\n    const xColorCombinations = new Set<string>();\n    const colorGroupCounts = new Map<string, number>();\n\n    for (const row of tv.rows) {\n        const xVal = row[xField];\n        const colorVal = colorField ? row[colorField] : '__single__';\n        const xColorKey = `${xVal}|||${colorVal}`;\n        if (xColorCombinations.has(xColorKey)) return false;\n        xColorCombinations.add(xColorKey);\n        colorGroupCounts.set(colorVal, (colorGroupCounts.get(colorVal) ?? 0) + 1);\n    }\n\n    let validGroups = 0;\n    let totalGroups = 0;\n    for (const count of colorGroupCounts.values()) {\n        totalGroups++;\n        if (count >= 2) validGroups++;\n    }\n    return totalGroups > 0 && (validGroups / totalGroups) > 0.5;\n}\n\nexport function pickLineChartColorField(\n    tv: InternalTableView, used: Set<string>, xField: string, maxCard = 20,\n): string | undefined {\n    const candidates: string[] = [];\n    for (const name of tv.names) {\n        if (used.has(name)) continue;\n        const type = tv.fieldType[name] ?? 'nominal';\n        const semanticType = tv.fieldSemanticType[name] ?? '';\n        const cardinality = tv.fieldLevels[name]?.length ?? 0;\n        if (!isDiscreteLike(type, semanticType, cardinality, maxCard)) continue;\n        if (cardinality <= 0 || cardinality > maxCard) continue;\n        if (isLikelyIdentifierOrRank(name) && !tv.preferredFields?.has(name)) continue;\n        if (isValidLineSeriesData(tv, xField, name)) candidates.push(name);\n    }\n    if (candidates.length === 0) return undefined;\n    // Prefer a field the user already uses; otherwise the lowest-cardinality\n    // valid series field (fewest lines/colors). Deterministic — no random pick.\n    if (tv.preferredFields) {\n        const preferred = candidates.filter(n => tv.preferredFields!.has(n));\n        if (preferred.length > 0) {\n            const chosen = lowestCardinality(tv, preferred);\n            used.add(chosen);\n            return chosen;\n        }\n    }\n    const chosen = lowestCardinality(tv, candidates);\n    used.add(chosen);\n    return chosen;\n}\n\nfunction calculateMultiplicity(tv: InternalTableView, xField: string, colorField?: string): number {\n    if (!tv.rows || tv.rows.length === 0) return 1;\n    const groups = new Set<string>();\n    for (const row of tv.rows) {\n        const key = colorField ? `${row[xField]}|||${row[colorField]}` : `${row[xField]}`;\n        groups.add(key);\n    }\n    return tv.rows.length / groups.size;\n}\n\nexport function pickBestGroupingField(\n    tv: InternalTableView, used: Set<string>, xField: string, maxMultiplicity = 5,\n): string | undefined {\n    const baseMultiplicity = calculateMultiplicity(tv, xField);\n    if (baseMultiplicity <= 1.0) return undefined;\n\n    let bestField: string | undefined;\n    let bestMultiplicity = baseMultiplicity;\n\n    for (const name of tv.names) {\n        if (used.has(name)) continue;\n        const type = tv.fieldType[name] ?? 'nominal';\n        const semanticType = tv.fieldSemanticType[name] ?? '';\n        const cardinality = tv.fieldLevels[name]?.length ?? 0;\n        if (!isDiscreteLike(type, semanticType, cardinality)) continue;\n        if (isLikelyIdentifierOrRank(name) && !tv.preferredFields?.has(name)) continue;\n\n        const multiplicity = calculateMultiplicity(tv, xField, name);\n        if (multiplicity < bestMultiplicity) {\n            bestMultiplicity = multiplicity;\n            bestField = name;\n            if (multiplicity <= 1.0) break;\n        }\n    }\n\n    if (bestField && bestMultiplicity < baseMultiplicity && bestMultiplicity <= maxMultiplicity) {\n        used.add(bestField);\n        return bestField;\n    }\n    return undefined;\n}\n\n// ============================================================================\n// 8. Per-Chart-Type Recommendation Heuristics\n// ============================================================================\n\n/**\n * Recommend channel→fieldName assignments for a given chart type.\n *\n * Pure logic: takes raw data rows + semantic type annotations, returns\n * a channel→fieldName map.  Backend wrappers filter to valid channels.\n *\n * @param chartType      Chart template name (e.g. \"Bar Chart\")\n * @param data           Array of row objects\n * @param semanticTypes  Field→semantic-type map (e.g. { weight: \"Quantity\" })\n * @returns              channel→fieldName map\n */\nexport function recommendChannels(\n    chartType: string,\n    data: any[],\n    semanticTypes: Record<string, string>,\n    recommendFn?: RecommendFn,\n): Record<string, string> {\n    const fn = recommendFn ?? getRecommendation;\n    return fn(chartType, buildTableView(data, semanticTypes));\n}\n\n/**\n * Core recommendation engine — handles chart types shared across 2+ backends.\n * Backend-specific chart types should be handled in their own recommendation files\n * by extending this function.\n *\n * Exported so that backend wrappers can call it as a fallback in their own\n * extended `getRecommendation` implementations.\n */\nexport function getRecommendation(chartType: string, tv: InternalTableView): Record<string, string> {\n    const used = new Set<string>();\n    const rec: Record<string, string> = {};\n\n    const assign = (channel: string, fieldName: string | undefined) => {\n        if (fieldName) rec[channel] = fieldName;\n    };\n\n    switch (chartType) {\n        case 'Scatter Plot': {\n            const yField = pickQuantitative(tv, used) ?? pickTemporal(tv, used) ?? pickNominal(tv, used);\n            const xField = pickQuantitative(tv, used) ?? pickTemporal(tv, used) ?? pickNominal(tv, used);\n            if (!xField || !yField) return {};\n            assign('x', xField);\n            assign('y', yField);\n            assign('color', pickLowCardNominal(tv, used));\n            break;\n        }\n\n        case 'Bar Chart':\n        case 'Stacked Bar Chart': {\n            const xField = pickDiscrete(tv, used);\n            const yField = pickQuantitative(tv, used);\n            if (!xField || !yField) return {};\n            assign('x', xField);\n            assign('y', yField);\n            if (hasMultipleValuesPerField(tv, xField)) {\n                assign('color', pickBestGroupingField(tv, used, xField));\n            }\n            break;\n        }\n\n        case 'Grouped Bar Chart': {\n            const xField = pickDiscrete(tv, used);\n            const yField = pickQuantitative(tv, used);\n            if (!xField || !yField) return {};\n            const seriesField = pickValidGroupingField(tv, used, xField, 20);\n            if (!seriesField) return {};\n            assign('x', xField);\n            assign('y', yField);\n            // A grouped bar dodges by the `group` channel (not `color`) across\n            // all three backends — assigning `color` here would be dropped by\n            // the Vega-Lite template, leaving an ungrouped bar.\n            assign('group', seriesField);\n            break;\n        }\n\n        case 'Histogram': {\n            const xField = pickQuantitative(tv, used);\n            if (!xField) return {};\n            assign('x', xField);\n            break;\n        }\n\n        case 'Heatmap': {\n            // Semantic-first preference scoring.\n            // 1. Semantic type determines preference (temporal, categorical, measure)\n            // 2. Data type (ty) is a safeguard for compatibility\n            const heatmapResult = resolveAssignment(tv, used, [\n                {\n                    channel: 'x',\n                    pref: (_n, ty, st, card) => {\n                        // Semantic preference\n                        if (isTimeSeriesType(st))                         return Pref.STRONG;\n                        if (isCategoricalType(st))                        return Pref.OK;\n                        if (isOrdinalType(st))                            return Pref.OK;\n                        if (isNonMeasureNumeric(st))                      return Pref.OK;\n                        // Data type safeguard: allow nominal or low-card continuous\n                        if (ty === 'nominal')                             return Pref.OK;\n                        if (ty === 'temporal')                            return Pref.STRONG;\n                        if (ty === 'quantitative' && card > 0 && card <= 50) return Pref.WEAK;\n                        return Pref.EXCLUDE;\n                    },\n                },\n                {\n                    channel: 'y',\n                    pref: (_n, ty, st, card) => {\n                        // Semantic preference\n                        if (isCategoricalType(st))                        return Pref.STRONG;\n                        if (isTimeSeriesType(st))                         return Pref.OK;\n                        if (isOrdinalType(st))                            return Pref.OK;\n                        if (isNonMeasureNumeric(st))                      return Pref.OK;\n                        // Data type safeguard\n                        if (ty === 'nominal')                             return Pref.STRONG;\n                        if (ty === 'temporal')                            return Pref.OK;\n                        if (ty === 'quantitative' && card > 0 && card <= 50) return Pref.WEAK;\n                        return Pref.EXCLUDE;\n                    },\n                },\n                {\n                    channel: 'color',\n                    pref: (_n, ty, st) => {\n                        // Semantic preference: measures are ideal for heatmap color\n                        if (isMeasureType(st))                            return Pref.STRONG;\n                        if (isOrdinalType(st))                            return Pref.OK;\n                        // Data type safeguard: quantitative with no semantic type\n                        if (ty === 'quantitative' && !st)                 return Pref.STRONG;\n                        if (ty === 'temporal')                            return Pref.WEAK;\n                        if (ty === 'nominal')                             return Pref.WEAK;\n                        return Pref.EXCLUDE;\n                    },\n                },\n            ]);\n            if (!heatmapResult['x'] || !heatmapResult['y'] || !heatmapResult['color']) return {};\n            assign('x', heatmapResult['x']);\n            assign('y', heatmapResult['y']);\n            assign('color', heatmapResult['color']);\n            break;\n        }\n\n        case 'Line Chart': {\n            const xField = pickSeriesAxis(tv, used);\n            const yField = pickQuantitative(tv, used);\n            if (!xField || !yField) return {};\n            assign('x', xField);\n            assign('y', yField);\n            if (!isValidLineSeriesData(tv, xField, undefined)) {\n                const colorField = pickLineChartColorField(tv, used, xField, 20)\n                    ?? pickLineChartColorField(tv, used, xField, 200);\n                if (!colorField) return {};\n                assign('color', colorField);\n            }\n            break;\n        }\n\n        case 'Boxplot': {\n            const xField = pickDiscrete(tv, used);\n            const yField = pickQuantitative(tv, used);\n            if (!xField || !yField) return {};\n            assign('x', xField);\n            assign('y', yField);\n            break;\n        }\n\n        case 'Pie Chart': {\n            const sizeField = pickQuantitative(tv, used);\n            const colorField = pickLowCardDiscrete(tv, used, 12);\n            if (!sizeField || !colorField) return {};\n            assign('size', sizeField);\n            assign('color', colorField);\n            break;\n        }\n\n        case 'Area Chart': {\n            const xField = pickSeriesAxis(tv, used);\n            const yField = pickQuantitative(tv, used);\n            if (!xField || !yField) return {};\n            assign('x', xField);\n            assign('y', yField);\n            assign('color', pickLineChartColorField(tv, used, xField, 20));\n            break;\n        }\n\n        case 'Streamgraph': {\n            // Semantic-first preference scoring.\n            // 1. Semantic type determines preference (temporal→x, measure→y, categorical→color)\n            // 2. Data type (ty) is a safeguard for compatibility\n            const streamResult = resolveAssignment(tv, used, [\n                {\n                    channel: 'x',\n                    pref: (_n, ty, st, card) => {\n                        // Semantic preference: temporal types are ideal series axes\n                        if (isTimeSeriesType(st))                            return Pref.STRONG;\n                        if (isOrdinalType(st))                               return Pref.OK;\n                        if (isCategoricalType(st))                           return Pref.OK;\n                        if (isNonMeasureNumeric(st))                         return Pref.OK;\n                        // Data type safeguard\n                        if (ty === 'temporal')                               return Pref.STRONG;\n                        if (ty === 'nominal')                                return Pref.OK;\n                        if (ty === 'quantitative' && card > 0 && card <= 50) return Pref.OK;\n                        return Pref.EXCLUDE;\n                    },\n                },\n                {\n                    channel: 'y',\n                    pref: (_n, ty, st, card) => {\n                        // Semantic preference: true measures are ideal\n                        if (isMeasureType(st))                               return Pref.STRONG;\n                        // Semantic exclusion: temporal / categorical / non-measure\n                        // numeric types should not be used as y-axis measures\n                        if (isTimeSeriesType(st))                            return Pref.EXCLUDE;\n                        if (isCategoricalType(st))                           return Pref.EXCLUDE;\n                        if (isNonMeasureNumeric(st))                         return Pref.EXCLUDE;\n                        // Data type safeguard: quantitative with no semantic type\n                        if (ty === 'quantitative' && !st)\n                            return card > 20 ? Pref.STRONG : Pref.OK;\n                        return Pref.EXCLUDE;\n                    },\n                },\n                {\n                    channel: 'color',\n                    pref: (_n, ty, st, card) => {\n                        // Semantic preference\n                        if (isCategoricalType(st))                           return Pref.STRONG;\n                        if (isOrdinalType(st))                               return Pref.OK;\n                        if (isTimeSeriesType(st))                            return Pref.OK;\n                        // Data type safeguard\n                        if (ty === 'nominal')                                return Pref.STRONG;\n                        if (ty === 'temporal' || ty === 'ordinal')           return Pref.OK;\n                        if (isDiscreteLike(ty, st, card, 20))                return Pref.WEAK;\n                        return Pref.EXCLUDE;\n                    },\n                },\n            ]);\n            if (!streamResult['x'] || !streamResult['y'] || !streamResult['color']) return {};\n            assign('x', streamResult['x']);\n            assign('y', streamResult['y']);\n            assign('color', streamResult['color']);\n            break;\n        }\n\n        case 'Radar Chart': {\n            const xField = pickDiscrete(tv, used) ?? pickLowCardDiscrete(tv, used, 20);\n            const yField = pickQuantitative(tv, used);\n            if (!xField || !yField) return {};\n            assign('x', xField);\n            assign('y', yField);\n            assign('color', pickLowCardDiscrete(tv, used, 20));\n            break;\n        }\n\n        case 'Candlestick Chart': {\n            const xField = pickTemporal(tv, used)\n                ?? pick(tv, used, (name) => nameMatches(name, ['date', 'time', 'day', 'datetime', 'timestamp', 'period']))\n                ?? pickQuantitativeByName(tv, used, ['date', 'time', 'day'])\n                ?? pickDiscrete(tv, used);\n            if (!xField) return {};\n            assign('x', xField);\n            const openField = pickQuantitativeByName(tv, used, ['open']);\n            const highField = pickQuantitativeByName(tv, used, ['high']);\n            const lowField = pickQuantitativeByName(tv, used, ['low']);\n            const closeField = pickQuantitativeByName(tv, used, ['close']);\n            if (openField && highField && lowField && closeField) {\n                assign('open', openField);\n                assign('high', highField);\n                assign('low', lowField);\n                assign('close', closeField);\n            } else {\n                const quants = pickAllQuantitative(tv, used);\n                if (quants.length >= 4) {\n                    assign('open', quants[0]);\n                    assign('high', quants[1]);\n                    assign('low', quants[2]);\n                    assign('close', quants[3]);\n                }\n            }\n            break;\n        }\n\n        default:\n            break;\n    }\n\n    return rec;\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * =============================================================================\n * DATA-DRIVEN CHART *TYPE* RECOMMENDATION\n * =============================================================================\n *\n * `recommendChannels` / `getRecommendation` answer \"which fields go on which\n * channels **for a chart type I already picked**\". They do not answer the step\n * that sits *in front* of them: **which chart type should I use at all?**\n *\n * This module fills that gap. Given raw rows + semantic-type annotations it\n * builds a deterministic {@link DataProfile} (how many measures / temporals /\n * categoricals / geographic fields the table has, and their cardinalities) and\n * scores a ranked list of candidate chart types.\n *\n * It reuses the same semantic-type classification the encoders use\n * (`isMeasureType`, `isTimeSeriesType`, `isGeoType`, …) so the two stages agree\n * on what a field *is*; it only adds the type-selection heuristic on top.\n *\n * Typical use (e.g. Data Formulator surfacing suggestions without a model call):\n *\n * ```ts\n * const types = recommendChartTypes(rows, semanticTypes); // [\"Choropleth\", \"Line Chart\", …]\n * const encodings = vlRecommendEncodings(types[0], rows, semanticTypes);\n * ```\n *\n * Backend wrappers (`vlRecommendChartTypes`, …) pass `supportedTypes` so only\n * chart types that backend can actually render are returned, and pair it with\n * their `…RecommendEncodings` to emit type + channels in one step\n * (`…RecommendCharts`).\n *\n * =============================================================================\n */\n\nimport {\n    isMeasureType,\n    isTimeSeriesType,\n    isCategoricalType,\n    isOrdinalType,\n    isGeoCoordinateType,\n    isGeoLocationString,\n    isNonMeasureNumeric,\n} from './semantic-types';\nimport { buildTableView, nameMatches, type InternalTableView } from './recommendation';\n\n// ── Field roles ─────────────────────────────────────────────────────────\n\n/**\n * The role a field plays when choosing a chart type. Mutually exclusive:\n * every field is classified into exactly one role (the most specific one).\n */\nexport type ChartFieldRole =\n    | 'measure'      // true quantitative measure (aggregatable)\n    | 'temporal'     // date / time-granule — a time axis\n    | 'categorical'  // nominal category / entity\n    | 'ordinal'      // ordered discrete (Rank, Range, Score, …)\n    | 'geoPlace'     // named place: Country, State, City, Region …\n    | 'latitude'     // geographic latitude coordinate\n    | 'longitude'    // geographic longitude coordinate\n    | 'identifier'   // row id / index — not useful as a category or measure\n    | 'other';       // unclassified\n\n/** A single field annotated with its data/semantic type, cardinality, and role. */\nexport interface ProfiledField {\n    name: string;\n    /** Vega-Lite-style vis category: 'quantitative' | 'temporal' | 'nominal' | 'ordinal'. */\n    type: string;\n    /** Semantic type annotation (e.g. \"Country\", \"Amount\"), or '' if none. */\n    semanticType: string;\n    /** Number of distinct non-null values. */\n    cardinality: number;\n    role: ChartFieldRole;\n}\n\n/**\n * A deterministic summary of a table's shape, used to rank chart types.\n * The bucketed arrays are views over {@link fields} grouped by role, plus\n * `dimensions` (all category-axis-capable fields: categorical ∪ ordinal ∪\n * geoPlace ∪ temporal).\n */\nexport interface DataProfile {\n    fields: ProfiledField[];\n    measures: ProfiledField[];\n    temporals: ProfiledField[];\n    categoricals: ProfiledField[];\n    ordinals: ProfiledField[];\n    geoPlaces: ProfiledField[];\n    latitudes: ProfiledField[];\n    longitudes: ProfiledField[];\n    identifiers: ProfiledField[];\n    /** Fields usable on a category/discrete axis (categorical ∪ ordinal ∪ geoPlace ∪ temporal). */\n    dimensions: ProfiledField[];\n    rowCount: number;\n}\n\n// Identifier name patterns — strict (exact or `_suffix`) to avoid false hits\n// like \"grid\" / \"valid\" / \"android\". `rank` is intentionally excluded so a\n// Rank field classifies as ordinal (a usable axis) rather than an identifier.\nconst ID_NAME_PATTERNS = ['id', 'index', 'idx', 'row', 'order', 'position', 'pos'];\n\nfunction looksLikeIdentifier(name: string): boolean {\n    const lower = name.toLowerCase();\n    return ID_NAME_PATTERNS.some(p => lower === p || lower.endsWith('_' + p));\n}\n\n/**\n * Classify one field into a single {@link ChartFieldRole}. The order of checks\n * is significant: the most *specific* interpretation wins (geo coordinate →\n * geo place → temporal → identifier → measure → ordinal → categorical).\n */\nfunction classifyRole(name: string, type: string, semanticType: string): ChartFieldRole {\n    const st = semanticType;\n    // Geographic coordinates (Latitude / Longitude): numeric but not measures.\n    if (isGeoCoordinateType(st)) {\n        if (st === 'Latitude' || nameMatches(name, ['latitude', 'lat'])) return 'latitude';\n        if (st === 'Longitude' || nameMatches(name, ['longitude', 'lon', 'lng', 'long'])) return 'longitude';\n        return 'other';\n    }\n    // Named geographic places (Country / State / City / Region / …).\n    if (isGeoLocationString(st)) return 'geoPlace';\n    // Time axis.\n    if (type === 'temporal' || isTimeSeriesType(st)) return 'temporal';\n    // Row identifiers — demoted so they never become a category or measure.\n    if (st === 'ID' || looksLikeIdentifier(name)) return 'identifier';\n    // True quantitative measure (mirrors isQuantitativeField in the encoders).\n    if (type === 'quantitative' && !isNonMeasureNumeric(st) && (isMeasureType(st) || st === '')) {\n        return 'measure';\n    }\n    // Ordered discrete (Rank, Range, Score-as-ordinal, Direction, …).\n    if (isOrdinalType(st)) return 'ordinal';\n    // Plain category.\n    if (type === 'nominal' || isCategoricalType(st)) return 'categorical';\n    return 'other';\n}\n\n/**\n * Build a {@link DataProfile} from raw rows + semantic-type annotations.\n * Deterministic — no random sampling; classification is per-field and\n * order-independent.\n *\n * @param data           Array of row objects.\n * @param semanticTypes  Field → semantic-type map (e.g. `{ Entity: \"Country\" }`).\n */\nexport function profileData(data: any[], semanticTypes: Record<string, string>): DataProfile {\n    const tv: InternalTableView = buildTableView(data, semanticTypes);\n    const fields: ProfiledField[] = tv.names.map(name => ({\n        name,\n        type: tv.fieldType[name] ?? 'nominal',\n        semanticType: tv.fieldSemanticType[name] ?? '',\n        cardinality: tv.fieldLevels[name]?.length ?? 0,\n        role: classifyRole(name, tv.fieldType[name] ?? 'nominal', tv.fieldSemanticType[name] ?? ''),\n    }));\n\n    const by = (r: ChartFieldRole) => fields.filter(f => f.role === r);\n    const categoricals = by('categorical');\n    const ordinals = by('ordinal');\n    const geoPlaces = by('geoPlace');\n    const temporals = by('temporal');\n\n    return {\n        fields,\n        measures: by('measure'),\n        temporals,\n        categoricals,\n        ordinals,\n        geoPlaces,\n        latitudes: by('latitude'),\n        longitudes: by('longitude'),\n        identifiers: by('identifier'),\n        dimensions: [...categoricals, ...ordinals, ...geoPlaces, ...temporals],\n        rowCount: tv.rows.length,\n    };\n}\n\n// ── Scoring ─────────────────────────────────────────────────────────────\n\n/** A ranked chart-type candidate with its score and human-readable reasons. */\nexport interface ChartTypeSuggestion {\n    chartType: string;\n    /** Higher is a better fit. Scores are relative; only the ordering is meaningful. */\n    score: number;\n    reasons: string[];\n}\n\n/** Options for {@link recommendChartTypes} / {@link recommendChartTypesDetailed}. */\nexport interface RecommendChartTypesOptions {\n    /**\n     * Restrict results to these chart-type names (e.g. a backend's template\n     * catalog). Types not in the list are dropped. Omit for all shared types.\n     */\n    supportedTypes?: string[];\n    /** Cap the number of suggestions returned (after ranking). */\n    max?: number;\n}\n\n/**\n * A recommended chart type paired with its recommended channel → field\n * encodings. Returned by the backend one-step recommenders\n * (`vlRecommendCharts`, …) that chain type selection with encoding selection.\n */\nexport interface RecommendedChart {\n    chartType: string;\n    encodings: Record<string, string>;\n}\n\n// Cardinality thresholds for readability gates.\nconst LOW_CARD_SERIES = 12;   // a legend/series stays readable up to ~12 colors\nconst LOW_CARD_AXIS = 25;     // a discrete heatmap axis stays readable up to ~25 bands\nconst PIE_MAX_SLICES = 8;     // a pie is legible only with a handful of slices\n\n/** Semantic types the choropleth base maps can actually render (see map.ts). */\nconst CHOROPLETH_SEMANTIC = new Set(['Country', 'State']);\nconst CHOROPLETH_NAME_HINTS = ['country', 'state', 'province', 'nation'];\n\n/**\n * Score candidate chart types for a data profile. Returns suggestions sorted by\n * descending score; ties keep a stable, priority-ordered arrangement.\n *\n * The rules are curated design heuristics: more *specific* chart types\n * (maps, time series) outrank generic ones (bar) when the data supports them,\n * so a table with a geographic place + a measure surfaces \"Choropleth\" ahead of\n * \"Bar Chart\" without a model call.\n */\nexport function rankChartTypes(profile: DataProfile): ChartTypeSuggestion[] {\n    const {\n        measures, temporals, categoricals, ordinals, geoPlaces,\n        latitudes, longitudes, rowCount,\n    } = profile;\n\n    const catLike = [...categoricals, ...ordinals, ...geoPlaces]; // discrete, non-temporal\n    const dims = profile.dimensions;\n    const lowCardCatLike = catLike.filter(f => f.cardinality >= 2 && f.cardinality <= LOW_CARD_SERIES);\n    const lowCardDims = dims.filter(f => f.cardinality >= 2 && f.cardinality <= LOW_CARD_AXIS);\n    const hasMeasure = measures.length >= 1;\n\n    // Preserve insertion order for stable tie-breaking; keep the max score per type.\n    const order: string[] = [];\n    const acc = new Map<string, { score: number; reasons: string[] }>();\n    const add = (chartType: string, score: number, reason: string) => {\n        const cur = acc.get(chartType);\n        if (!cur) {\n            order.push(chartType);\n            acc.set(chartType, { score, reasons: [reason] });\n        } else {\n            if (score > cur.score) cur.score = score;\n            if (!cur.reasons.includes(reason)) cur.reasons.push(reason);\n        }\n    };\n\n    // ── Geographic (most specific) ──────────────────────────────────────\n    if (latitudes.length >= 1 && longitudes.length >= 1) {\n        add('Map', 96, 'has latitude + longitude coordinates');\n    }\n    const choroGeo = geoPlaces.filter(\n        f => CHOROPLETH_SEMANTIC.has(f.semanticType) || nameMatches(f.name, CHOROPLETH_NAME_HINTS),\n    );\n    if (choroGeo.length >= 1 && hasMeasure) {\n        add('Choropleth', 92, 'has a geographic region field + a measure');\n    }\n\n    // ── Time series ─────────────────────────────────────────────────────\n    if (temporals.length >= 1 && hasMeasure) {\n        add('Line Chart', 88, 'has a time field + a measure (trend over time)');\n        add('Area Chart', 66, 'has a time field + a measure');\n    }\n\n    // ── Correlation (two measures) ──────────────────────────────────────\n    if (measures.length >= 2) {\n        add('Scatter Plot', 84, 'has two or more measures (relationship)');\n    }\n\n    // ── Category + measure (bar) ────────────────────────────────────────\n    if (dims.length >= 1 && hasMeasure) {\n        add('Bar Chart', 80, 'has a category axis + a measure');\n    }\n\n    // ── Single-measure distribution (histogram) ─────────────────────────\n    if (hasMeasure && dims.length === 0) {\n        add('Histogram', 82, 'has a measure with no category (distribution)');\n    }\n\n    // ── Two-category comparison (grouped / stacked / heatmap) ───────────\n    if (catLike.length >= 2 && lowCardCatLike.length >= 1 && hasMeasure) {\n        add('Grouped Bar Chart', 72, 'has two categories + a measure');\n        add('Stacked Bar Chart', 70, 'has two categories + a measure');\n    }\n    if (lowCardDims.length >= 2 && hasMeasure) {\n        add('Heatmap', 74, 'has two discrete fields + a measure (matrix)');\n    }\n\n    // ── Part-to-whole (pie) ─────────────────────────────────────────────\n    if (catLike.length === 1 && temporals.length === 0 && hasMeasure) {\n        const c = catLike[0];\n        const oneRowPerCategory = rowCount <= c.cardinality * 1.5;\n        if (c.cardinality >= 2 && c.cardinality <= PIE_MAX_SLICES && oneRowPerCategory) {\n            add('Pie Chart', 64, 'a few categories that sum to a whole');\n        }\n    }\n\n    // ── Distribution across groups (box / strip) ────────────────────────\n    if (catLike.length >= 1 && hasMeasure && temporals.length === 0) {\n        const smallest = catLike.reduce((a, b) => (b.cardinality < a.cardinality ? b : a));\n        if (smallest.cardinality >= 1 && rowCount >= smallest.cardinality * 2) {\n            add('Boxplot', 58, 'multiple measure values per group (spread)');\n            add('Strip Plot', 52, 'multiple measure values per group');\n        }\n    }\n\n    // ── Count-only fallbacks (dimensions but no measure) ────────────────\n    if (!hasMeasure && dims.length >= 1) {\n        add('Bar Chart', 60, 'categories without a measure (counts)');\n        if (lowCardDims.length >= 2) add('Heatmap', 55, 'two discrete fields (cross-tab counts)');\n    }\n\n    // ── Last-resort fallback ────────────────────────────────────────────\n    if (order.length === 0) {\n        if (measures.length >= 2) add('Scatter Plot', 20, 'fallback for numeric data');\n        else add('Bar Chart', 15, 'fallback');\n    }\n\n    return order\n        .map(chartType => ({ chartType, score: acc.get(chartType)!.score, reasons: acc.get(chartType)!.reasons }))\n        // Stable sort (ES2019+) — equal scores keep priority insertion order.\n        .sort((a, b) => b.score - a.score);\n}\n\n// ── Public API ──────────────────────────────────────────────────────────\n\n/**\n * Recommend candidate chart types for a dataset, with scores and reasons.\n *\n * @param data           Array of row objects.\n * @param semanticTypes  Field → semantic-type map (e.g. `{ Entity: \"Country\" }`).\n * @param options        Optional `supportedTypes` filter and `max` cap.\n * @returns              Ranked {@link ChartTypeSuggestion}s (best first).\n */\nexport function recommendChartTypesDetailed(\n    data: any[],\n    semanticTypes: Record<string, string>,\n    options: RecommendChartTypesOptions = {},\n): ChartTypeSuggestion[] {\n    const profile = profileData(data, semanticTypes);\n    let ranked = rankChartTypes(profile);\n    if (options.supportedTypes) {\n        const allowed = new Set(options.supportedTypes);\n        ranked = ranked.filter(s => allowed.has(s.chartType));\n    }\n    if (options.max != null) ranked = ranked.slice(0, options.max);\n    return ranked;\n}\n\n/**\n * Recommend a ranked list of chart-type names for a dataset (best first).\n *\n * A convenience wrapper over {@link recommendChartTypesDetailed} that drops the\n * scores/reasons. This is the \"type-selection step that sits in front of\"\n * `recommendChannels` — call it first, then feed the chosen type to\n * `…RecommendEncodings` to populate channels.\n *\n * @param data           Array of row objects.\n * @param semanticTypes  Field → semantic-type map.\n * @param options        Optional `supportedTypes` filter and `max` cap.\n * @returns              Ranked chart-type names (best first).\n */\nexport function recommendChartTypes(\n    data: any[],\n    semanticTypes: Record<string, string>,\n    options: RecommendChartTypesOptions = {},\n): string[] {\n    return recommendChartTypesDetailed(data, semanticTypes, options).map(s => s.chartType);\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Chart.js recommendation & adaptation wrappers.\n */\n\nimport { adaptChannels, recommendChannels } from '../core/recommendation';\nimport {\n    recommendChartTypes,\n    type RecommendChartTypesOptions,\n    type RecommendedChart,\n} from '../core/chart-type-recommendation';\nimport { cjsGetTemplateChannels, cjsAllTemplateDefs } from './templates';\n\nexport function cjsAdaptChart(\n    sourceType: string,\n    targetType: string,\n    encodings: Record<string, string>,\n    data?: any[],\n    semanticTypes?: Record<string, string>,\n): Record<string, string> {\n    const targetChannels = cjsGetTemplateChannels(targetType);\n    return adaptChannels(sourceType, targetType, targetChannels, encodings, data, semanticTypes);\n}\n\nexport function cjsRecommendEncodings(\n    chartType: string,\n    data: any[],\n    semanticTypes: Record<string, string>,\n): Record<string, string> {\n    const rec = recommendChannels(chartType, data, semanticTypes);\n    const validChannels = cjsGetTemplateChannels(chartType);\n    const result: Record<string, string> = {};\n    for (const [ch, field] of Object.entries(rec)) {\n        if (validChannels.includes(ch)) result[ch] = field;\n    }\n    return result;\n}\n\n/** Chart-type names Chart.js can render (its template catalog). */\nconst CJS_SUPPORTED_TYPES = cjsAllTemplateDefs.map(d => d.chart);\n\n/**\n * Recommend a ranked list of Chart.js chart types for a dataset, restricted to\n * chart types Chart.js can render. See {@link cjsRecommendCharts} for the\n * one-step variant that also fills channels.\n */\nexport function cjsRecommendChartTypes(\n    data: any[],\n    semanticTypes: Record<string, string>,\n    options: Omit<RecommendChartTypesOptions, 'supportedTypes'> = {},\n): string[] {\n    return recommendChartTypes(data, semanticTypes, { ...options, supportedTypes: CJS_SUPPORTED_TYPES });\n}\n\n/**\n * One-step recommendation: rank Chart.js chart types for the data, then populate\n * each with {@link cjsRecommendEncodings}. Suggestions whose required channels\n * cannot be filled are dropped, so every returned chart is renderable.\n */\nexport function cjsRecommendCharts(\n    data: any[],\n    semanticTypes: Record<string, string>,\n    options: Omit<RecommendChartTypesOptions, 'supportedTypes'> = {},\n): RecommendedChart[] {\n    const { max, ...rest } = options;\n    const charts = cjsRecommendChartTypes(data, semanticTypes, rest)\n        .map(chartType => ({ chartType, encodings: cjsRecommendEncodings(chartType, data, semanticTypes) }))\n        .filter(s => Object.keys(s.encodings).length > 0);\n    return max != null ? charts.slice(0, max) : charts;\n}\n"]}