@opendata-ai/openchart-engine 6.22.0 → 6.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +3340 -371
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/compile.ts","../src/annotations/collisions.ts","../src/annotations/constants.ts","../src/annotations/geometry.ts","../src/annotations/position.ts","../src/annotations/resolve-text.ts","../src/annotations/resolve-range.ts","../src/annotations/resolve-refline.ts","../src/annotations/compute.ts","../src/transforms/predicates.ts","../src/transforms/conditional.ts","../src/charts/registry.ts","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/ascending.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/descending.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/bisector.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/number.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/bisect.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/extent.js","../../../node_modules/.bun/internmap@2.0.3/node_modules/internmap/src/index.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/ticks.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/max.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/min.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/quantile.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/range.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/init.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/ordinal.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/band.js","../../../node_modules/.bun/d3-color@3.1.0/node_modules/d3-color/src/define.js","../../../node_modules/.bun/d3-color@3.1.0/node_modules/d3-color/src/color.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/basis.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/basisClosed.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/constant.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/color.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/rgb.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/numberArray.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/array.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/date.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/number.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/object.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/string.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/value.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/round.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/constant.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/number.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/continuous.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatDecimal.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/exponent.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatGroup.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatNumerals.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatSpecifier.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatTrim.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatPrefixAuto.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatRounded.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatTypes.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/identity.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/locale.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/defaultLocale.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/precisionFixed.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/precisionPrefix.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/precisionRound.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/tickFormat.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/linear.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/nice.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/log.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/symlog.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/pow.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/quantile.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/quantize.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/threshold.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/interval.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/millisecond.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/duration.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/second.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/minute.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/hour.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/day.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/week.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/month.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/year.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/ticks.js","../../../node_modules/.bun/d3-time-format@4.1.0/node_modules/d3-time-format/src/locale.js","../../../node_modules/.bun/d3-time-format@4.1.0/node_modules/d3-time-format/src/defaultLocale.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/time.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/utcTime.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/sequential.js","../src/charts/post-process.ts","../src/compile/color-scale-range.ts","../src/compile/data-clip.ts","../src/compile/watermark-obstacle.ts","../src/compiler/animation.ts","../src/compiler/normalize.ts","../src/compiler/validate.ts","../src/compiler/index.ts","../src/graphs/compile-graph.ts","../src/graphs/encoding.ts","../src/graphs/community.ts","../src/layout/axes/thinning.ts","../src/layout/axes/ticks.ts","../src/layout/axes.ts","../src/layout/dimensions.ts","../src/layout/gridlines.ts","../src/layout/scales.ts","../src/legend/compute.ts","../src/legend/wrap.ts","../src/sankey/compile-sankey.ts","../../../node_modules/.bun/d3-array@2.12.1/node_modules/d3-array/src/max.js","../../../node_modules/.bun/d3-array@2.12.1/node_modules/d3-array/src/min.js","../../../node_modules/.bun/d3-array@2.12.1/node_modules/d3-array/src/sum.js","../../../node_modules/.bun/d3-sankey@0.12.3/node_modules/d3-sankey/src/align.js","../../../node_modules/.bun/d3-sankey@0.12.3/node_modules/d3-sankey/src/constant.js","../../../node_modules/.bun/d3-sankey@0.12.3/node_modules/d3-sankey/src/sankey.js","../src/sankey/layout.ts","../src/tables/compile-table.ts","../src/tables/bar-column.ts","../src/tables/category-colors.ts","../src/tables/utils.ts","../src/tables/format-cells.ts","../src/tables/heatmap.ts","../src/tables/pagination.ts","../src/tables/search.ts","../src/tables/sort.ts","../src/tables/sparkline.ts","../src/tooltips/compute.ts","../src/transforms/aggregate.ts","../src/transforms/bin.ts","../src/transforms/calculate.ts","../src/transforms/filter.ts","../src/transforms/fold.ts","../src/transforms/timeunit.ts","../src/transforms/index.ts"],"sourcesContent":["/**\n * Main compile API: the public entry points for the engine.\n *\n * Pipeline for charts:\n * validate spec -> normalize -> resolve theme -> dark mode adapt ->\n * compute legend -> compute dimensions (with legend space) ->\n * compute scales -> compute axes -> compute gridlines ->\n * get chart renderer -> compute marks -> compute a11y -> return ChartLayout\n *\n * Table compiler handles full data pipeline (sort, search, pagination, visual enhancements).\n * Graph compiler is a stub for future implementation.\n */\n\nimport type {\n AnimationSpec,\n BinParams,\n BinTransform,\n ChartLayout,\n ChartSpec,\n CompileOptions,\n CompileTableOptions,\n EncodingChannel,\n LayerSpec,\n Mark,\n Rect,\n ResolvedAnnotation,\n ResolvedTheme,\n TableLayout,\n TimeUnit,\n TimeUnitTransform,\n Transform,\n} from '@opendata-ai/openchart-core';\nimport {\n adaptTheme,\n computeLabelBounds,\n generateAltText,\n generateDataTable,\n getBreakpoint,\n getHeightClass,\n getLayoutStrategy,\n resolveTheme,\n} from '@opendata-ai/openchart-core';\nimport { computeAnnotations } from './annotations/compute';\n// Side-effect import: registers all built-in chart renderers with the\n// registry on module load. Tests that clear the registry can import\n// `registerBuiltinRenderers` from `./charts/builtin` to restore defaults.\nimport './charts/builtin';\nimport {\n assignAnimationIndices,\n computeMarkObstacles,\n resolveRendererKey,\n} from './charts/post-process';\nimport { getChartRenderer } from './charts/registry';\nimport { applyColorScaleRange } from './compile/color-scale-range';\nimport { filterClippedDomains } from './compile/data-clip';\nimport { computeWatermarkObstacle } from './compile/watermark-obstacle';\nimport { resolveAnimation } from './compiler/animation';\nimport { compile as compileSpec, flattenLayers } from './compiler/index';\nimport type { NormalizedChartSpec, NormalizedTableSpec } from './compiler/types';\nimport { compileGraph as compileGraphImpl } from './graphs/compile-graph';\nimport type { GraphCompilation } from './graphs/types';\nimport { computeAxes } from './layout/axes';\nimport { computeDimensions } from './layout/dimensions';\nimport { computeGridlines } from './layout/gridlines';\nimport { computeScales } from './layout/scales';\nimport { computeLegend } from './legend/compute';\nimport { compileSankey as compileSankeyImpl } from './sankey/compile-sankey';\nimport { compileTableLayout } from './tables/compile-table';\nimport { computeTooltipDescriptors } from './tooltips/compute';\nimport { runTransforms } from './transforms';\n\n// ---------------------------------------------------------------------------\n// Encoding sugar expansion (bin, timeUnit on encoding channels)\n// ---------------------------------------------------------------------------\n\n/**\n * Expand encoding-level `bin` and `timeUnit` shorthand into explicit transforms.\n *\n * Vega-Lite allows `encoding.x.bin: true` as sugar for a BinTransform.\n * This function detects those shorthands, generates the corresponding transforms,\n * updates encoding field references to the output field names, and prepends the\n * transforms to the spec's transform array.\n *\n * Mutates nothing; returns a new spec object (shallow copy).\n */\nexport function expandEncodingSugar(spec: Record<string, unknown>): Record<string, unknown> {\n const encoding = spec.encoding as Record<string, EncodingChannel | undefined> | undefined;\n if (!encoding) return spec;\n\n const generatedTransforms: Transform[] = [];\n const updatedEncoding = { ...encoding };\n let changed = false;\n\n for (const channel of Object.keys(encoding)) {\n const ch = encoding[channel];\n if (!ch || !ch.field) continue;\n\n // Expand bin shorthand\n if (ch.bin != null && ch.bin !== false) {\n const field = ch.field;\n const outputField = `bin_${field}`;\n const binTransform: BinTransform = {\n bin: ch.bin === true ? true : (ch.bin as BinParams),\n field,\n as: outputField,\n };\n generatedTransforms.push(binTransform);\n\n // Update encoding to reference binned output field, remove bin property\n const { bin: _bin, ...rest } = ch;\n updatedEncoding[channel] = { ...rest, field: outputField } as EncodingChannel;\n changed = true;\n }\n\n // Expand timeUnit shorthand (read from updated encoding in case bin already ran)\n const current = updatedEncoding[channel] ?? ch;\n if (current.timeUnit) {\n const field = current.field;\n const unit = current.timeUnit as TimeUnit;\n const outputField = `${unit}_${field}`;\n const timeUnitTransform: TimeUnitTransform = {\n timeUnit: unit,\n field,\n as: outputField,\n };\n generatedTransforms.push(timeUnitTransform);\n\n // Update encoding to reference timeUnit output field, remove timeUnit property\n const { timeUnit: _tu, ...rest } = current;\n updatedEncoding[channel] = { ...rest, field: outputField } as EncodingChannel;\n changed = true;\n }\n }\n\n if (!changed) return spec;\n\n // Prepend generated transforms before any user-defined transforms\n const existingTransforms = (spec.transform as Transform[] | undefined) ?? [];\n return {\n ...spec,\n encoding: updatedEncoding,\n transform: [...generatedTransforms, ...existingTransforms],\n };\n}\n\n// ---------------------------------------------------------------------------\n// Chart compilation\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a chart spec into a ChartLayout.\n *\n * This is the main engine entry point. Takes a raw spec (any shape,\n * validated at runtime) and compile options, produces a fully resolved\n * ChartLayout with positions, colors, and marks ready for rendering.\n *\n * @param spec - Raw chart spec (validated and normalized internally).\n * @param options - Compile options (width, height, theme, darkMode).\n * @returns ChartLayout with all computed positions.\n * @throws Error if spec is invalid or not a chart type.\n */\nexport function compileChart(spec: unknown, options: CompileOptions): ChartLayout {\n // Expand encoding-level bin/timeUnit sugar before validation + normalization.\n // This converts shorthand (e.g. encoding.x.bin: true) into explicit transforms.\n const expandedSpec =\n spec && typeof spec === 'object' && !Array.isArray(spec)\n ? expandEncodingSugar(spec as Record<string, unknown>)\n : spec;\n\n // Validate + normalize\n const { spec: normalized } = compileSpec(expandedSpec);\n\n if ('type' in normalized && (normalized as unknown as Record<string, unknown>).type === 'table') {\n throw new Error('compileChart received a table spec. Use compileTable instead.');\n }\n if ('type' in normalized && (normalized as unknown as Record<string, unknown>).type === 'graph') {\n throw new Error('compileChart received a graph spec. Use compileGraph instead.');\n }\n if (\n 'type' in normalized &&\n (normalized as unknown as Record<string, unknown>).type === 'sankey'\n ) {\n throw new Error('compileChart received a sankey spec. Use compileSankey instead.');\n }\n\n let chartSpec = normalized as NormalizedChartSpec;\n\n // Resolve watermark: explicit spec value wins, then options fallback, then default true.\n const rawWatermark = (expandedSpec as Record<string, unknown>).watermark;\n const watermark = rawWatermark !== undefined ? chartSpec.watermark : (options.watermark ?? true);\n\n // Run data transforms (filter, bin, calculate, timeUnit) before any other data processing.\n // Transforms are defined on the expanded spec (which includes any auto-generated\n // transforms from encoding-level bin/timeUnit sugar), not the normalized spec,\n // since NormalizedChartSpec doesn't carry the transform field.\n const rawTransforms = (expandedSpec as Record<string, unknown>).transform as\n | import('@opendata-ai/openchart-core').Transform[]\n | undefined;\n if (rawTransforms && rawTransforms.length > 0) {\n chartSpec = { ...chartSpec, data: runTransforms(chartSpec.data, rawTransforms) };\n }\n\n // Responsive strategy\n const breakpoint = getBreakpoint(options.width);\n const heightClass = getHeightClass(options.height);\n let strategy = getLayoutStrategy(breakpoint, heightClass);\n\n // Apply breakpoint-conditional overrides from the expanded spec\n const rawSpec = expandedSpec as Record<string, unknown>;\n const overrides = rawSpec.overrides as\n | Partial<\n Record<\n string,\n { chrome?: unknown; labels?: unknown; legend?: unknown; annotations?: unknown }\n >\n >\n | undefined;\n if (overrides?.[breakpoint]) {\n const bp = overrides[breakpoint]!;\n if (bp.chrome) {\n chartSpec = {\n ...chartSpec,\n chrome: {\n ...chartSpec.chrome,\n ...(bp.chrome as NormalizedChartSpec['chrome']),\n },\n };\n }\n if (bp.labels) {\n chartSpec = {\n ...chartSpec,\n labels: {\n ...chartSpec.labels,\n ...(bp.labels as NormalizedChartSpec['labels']),\n },\n };\n }\n if (bp.legend) {\n chartSpec = {\n ...chartSpec,\n legend: {\n ...chartSpec.legend,\n ...(bp.legend as NormalizedChartSpec['legend']),\n },\n };\n }\n if (bp.annotations) {\n chartSpec = {\n ...chartSpec,\n annotations: bp.annotations as NormalizedChartSpec['annotations'],\n };\n // User explicitly provided annotations at this breakpoint — override the\n // responsive strategy so they render inline instead of being stripped.\n strategy = { ...strategy, annotationPosition: 'inline' };\n }\n }\n\n // Resolve animation spec. Breakpoint override wins over base spec (matching\n // chrome, labels, legend, and annotation override precedence).\n const rawAnimationSpec = ((overrides?.[breakpoint] as Record<string, unknown> | undefined)\n ?.animation ?? rawSpec.animation) as AnimationSpec | undefined;\n const resolvedAnimation = resolveAnimation(rawAnimationSpec);\n\n // Resolve theme: merge spec-level theme with options-level overrides\n const mergedThemeConfig = options.theme\n ? { ...chartSpec.theme, ...options.theme }\n : chartSpec.theme;\n let theme: ResolvedTheme = resolveTheme(mergedThemeConfig);\n if (options.darkMode) {\n theme = adaptTheme(theme);\n }\n\n // INVARIANT 1 — double legend pass: preliminaryArea → computeDimensions → legendArea → final\n // legend. Breaks a dims/legend dependency cycle. Do not collapse into one call.\n // Compute legend first (needs to reserve space)\n const preliminaryArea: Rect = {\n x: 0,\n y: 0,\n width: options.width,\n height: options.height,\n };\n const legendLayout = computeLegend(chartSpec, strategy, theme, preliminaryArea, watermark);\n\n // Compute dimensions (accounts for chrome + legend + responsive strategy)\n const dims = computeDimensions(chartSpec, options, legendLayout, theme, strategy, watermark);\n const chartArea = dims.chartArea;\n\n // Recompute legend bounds relative to actual chart area.\n // chartArea was shrunk to exclude legend space, so expand it back to include\n // the reserved margin. This way computeLegend positions the legend outside\n // the data area (in the margin) instead of overlapping data marks.\n const legendArea: Rect = { ...chartArea };\n if (legendLayout.entries.length > 0) {\n switch (legendLayout.position) {\n case 'top':\n legendArea.y -= legendLayout.bounds.height + 4;\n legendArea.height += legendLayout.bounds.height + 4;\n break;\n case 'bottom':\n legendArea.height += legendLayout.bounds.height + 4;\n break;\n case 'right':\n case 'bottom-right':\n legendArea.width += legendLayout.bounds.width + 8;\n break;\n }\n }\n const finalLegend = computeLegend(chartSpec, strategy, theme, legendArea, watermark);\n\n // Apply data filtering after legend (so legend retains all series), but before\n // scale computation (so hidden/clipped data doesn't affect domains or marks).\n let renderData = chartSpec.data;\n\n // Filter hidden series: removed from rendering but kept in legend (dimmed in the adapter)\n if (\n chartSpec.hiddenSeries.length > 0 &&\n chartSpec.encoding.color &&\n 'field' in chartSpec.encoding.color\n ) {\n const colorField = chartSpec.encoding.color.field;\n const hiddenSet = new Set(chartSpec.hiddenSeries);\n renderData = renderData.filter((row) => !hiddenSet.has(String(row[colorField])));\n }\n\n // Filter clipped scale domains: when scale.clip is true, exclude rows outside the domain\n renderData = filterClippedDomains(renderData, chartSpec.encoding);\n\n // Build a filtered spec for scales and marks, keeping all other properties intact\n const renderSpec = renderData !== chartSpec.data ? { ...chartSpec, data: renderData } : chartSpec;\n\n // Compute scales\n const scales = computeScales(renderSpec, chartArea, renderSpec.data);\n\n // Update color scale to use theme palette (only when user hasn't provided an explicit range)\n applyColorScaleRange(scales, renderSpec.encoding, theme);\n\n // INVARIANT 3 — post-hoc defaultColor: must run AFTER computeScales since resolution needs\n // theme context. Do not move into computeScales (would require threading theme through).\n // If the user set a fill on the mark def, it takes priority over the theme's first categorical.\n scales.defaultColor = chartSpec.markDef.fill ?? theme.colors.categorical[0];\n\n // Arc charts (pie/donut) don't use axes or gridlines\n const isRadial = chartSpec.markType === 'arc';\n\n // Compute axes (skip for radial charts)\n const axes = isRadial\n ? { x: undefined, y: undefined }\n : computeAxes(scales, chartArea, strategy, theme, options.measureText);\n\n // INVARIANT 2 — computeGridlines mutates `axes` in place. Downstream consumers read\n // axes.y.gridlines off the same object. Do not introduce a copy-on-write.\n if (!isRadial) {\n computeGridlines(axes, chartArea);\n }\n\n // Get chart renderer and compute marks (using filtered data).\n const rendererKey = resolveRendererKey(\n renderSpec.markType,\n renderSpec.encoding,\n renderSpec.markDef,\n );\n const renderer = getChartRenderer(rendererKey);\n const marks: Mark[] = renderer ? renderer(renderSpec, scales, chartArea, strategy, theme) : [];\n\n // Compute annotations from spec, passing legend + mark + brand bounds as obstacles\n const obstacles: Rect[] = [];\n if (finalLegend.bounds.width > 0) {\n obstacles.push(finalLegend.bounds);\n }\n obstacles.push(...computeMarkObstacles(marks, scales));\n\n // Add visible data label bounds as obstacles so annotations avoid overlapping them\n for (const mark of marks) {\n if ('label' in mark && mark.label?.visible) {\n obstacles.push(computeLabelBounds(mark.label));\n }\n }\n\n // Add brand watermark as an obstacle so annotations avoid overlapping it.\n const watermarkRect = computeWatermarkObstacle(dims, watermark, axes, theme);\n if (watermarkRect) obstacles.push(watermarkRect);\n const annotations: ResolvedAnnotation[] = computeAnnotations(\n chartSpec,\n scales,\n chartArea,\n strategy,\n theme.isDark,\n obstacles,\n { width: dims.total.width, height: dims.total.height },\n );\n\n // Compute tooltip descriptors from marks and encoding\n const tooltipDescriptors = computeTooltipDescriptors(chartSpec, marks);\n\n // Compute accessibility\n const altText = generateAltText(\n {\n mark: chartSpec.markType,\n data: chartSpec.data,\n encoding: chartSpec.encoding,\n chrome: chartSpec.chrome,\n },\n chartSpec.data,\n );\n const dataTableFallback = generateDataTable(\n {\n mark: chartSpec.markType,\n data: chartSpec.data,\n encoding: chartSpec.encoding,\n },\n chartSpec.data,\n );\n\n // Assign animationIndex for stagger ordering when animation is enabled\n assignAnimationIndices(marks, resolvedAnimation);\n\n return {\n area: chartArea,\n chrome: dims.chrome,\n axes: {\n x: axes.x,\n y: axes.y,\n },\n marks,\n annotations,\n legend: finalLegend,\n tooltipDescriptors,\n a11y: {\n altText,\n dataTableFallback,\n role: 'img',\n keyboardNavigable: marks.length > 0,\n },\n theme,\n dimensions: {\n width: options.width,\n height: options.height,\n },\n animation: resolvedAnimation,\n watermark,\n measureText: options.measureText,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Layer compilation\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a LayerSpec into a single ChartLayout.\n *\n * Flattens nested layers, merges inherited data/encoding/transforms,\n * compiles each leaf layer independently, unions scale domains (shared\n * by default), and concatenates marks in layer order.\n *\n * @param spec - A LayerSpec with child layers.\n * @param options - Compile options (width, height, theme, darkMode).\n * @returns A single ChartLayout with combined marks from all layers.\n */\nexport function compileLayer(spec: LayerSpec, options: CompileOptions): ChartLayout {\n // Flatten nested layers into leaf ChartSpecs with merged data/encoding/transforms\n const leaves = flattenLayers(spec);\n\n if (leaves.length === 0) {\n throw new Error('LayerSpec has no leaf chart specs after flattening');\n }\n\n // If there's only one layer, just compile it directly\n if (leaves.length === 1) {\n const singleSpec = buildPrimarySpec(leaves, spec);\n return compileChart(singleSpec, options);\n }\n\n // Build primary spec with unioned data for shared scale computation.\n // The primary layout provides chrome, axes, dimensions, legend, and a11y.\n const primarySpec = buildPrimarySpec(leaves, spec);\n const primaryLayout = compileChart(primarySpec, options);\n\n // Compile each leaf layer independently but with the full unioned data\n // so they all share the same scale domains.\n const allMarks: Mark[] = [];\n const seenLabels = new Set<string>();\n const mergedLegendEntries = [...primaryLayout.legend.entries];\n for (const entry of mergedLegendEntries) {\n seenLabels.add(entry.label);\n }\n\n for (const leaf of leaves) {\n // Compile each leaf with its own data so marks correspond to its rows only.\n // Scale domains may differ slightly between layers, but this prevents\n // duplicate marks from feeding unioned data into every renderer.\n const leafLayout = compileChart(leaf as unknown, options);\n\n allMarks.push(...leafLayout.marks);\n\n // Deduplicate legend entries across layers\n for (const entry of leafLayout.legend.entries) {\n if (!seenLabels.has(entry.label)) {\n seenLabels.add(entry.label);\n mergedLegendEntries.push(entry);\n }\n }\n }\n\n return {\n ...primaryLayout,\n marks: allMarks,\n legend: {\n ...primaryLayout.legend,\n entries: mergedLegendEntries,\n },\n };\n}\n\n/**\n * Build the primary ChartSpec from all leaves for shared compilation.\n * Unions all data rows across layers so scales see the full domain.\n * Uses the first leaf's mark/encoding as the base, with layer-level chrome.\n */\nfunction buildPrimarySpec(leaves: ChartSpec[], layerSpec: LayerSpec): ChartSpec {\n // Union all data across layers for domain computation\n const allData = leaves.flatMap((leaf) => leaf.data);\n\n const primary = {\n ...leaves[0],\n data: allData,\n // Layer-level chrome overrides leaf chrome\n chrome: layerSpec.chrome ?? leaves[0].chrome,\n labels: layerSpec.labels ?? leaves[0].labels,\n legend: layerSpec.legend ?? leaves[0].legend,\n responsive: layerSpec.responsive ?? leaves[0].responsive,\n theme: layerSpec.theme ?? leaves[0].theme,\n darkMode: layerSpec.darkMode ?? leaves[0].darkMode,\n watermark: layerSpec.watermark ?? leaves[0].watermark,\n hiddenSeries: layerSpec.hiddenSeries ?? leaves[0].hiddenSeries,\n };\n\n return primary;\n}\n\n// ---------------------------------------------------------------------------\n// Table compilation\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a table spec into a TableLayout.\n *\n * Validates and normalizes the spec, resolves the theme, then delegates\n * to compileTableLayout for the full pipeline: column resolution, search,\n * sort, pagination, cell formatting, and visual enhancements.\n *\n * @param spec - Raw table spec.\n * @param options - Compile options with sort, search, pagination state.\n * @returns Fully resolved TableLayout.\n */\nexport function compileTable(spec: unknown, options: CompileTableOptions): TableLayout {\n const { spec: normalized } = compileSpec(spec);\n\n const normType =\n 'type' in normalized ? (normalized as unknown as Record<string, unknown>).type : undefined;\n if (normType !== 'table') {\n throw new Error(`compileTable received a non-table spec. Use compileChart instead.`);\n }\n\n const tableSpec = normalized as NormalizedTableSpec;\n\n // Resolve theme: merge spec-level theme with options-level overrides\n const mergedThemeConfig = options.theme\n ? { ...tableSpec.theme, ...options.theme }\n : tableSpec.theme;\n let theme: ResolvedTheme = resolveTheme(mergedThemeConfig);\n if (options.darkMode) {\n theme = adaptTheme(theme);\n }\n\n // Resolve watermark: spec-level wins, then options, then default true\n const rawWatermark = (spec as Record<string, unknown>).watermark;\n const watermark = rawWatermark !== undefined ? tableSpec.watermark : (options.watermark ?? true);\n\n return compileTableLayout({ ...tableSpec, watermark }, options, theme);\n}\n\n// ---------------------------------------------------------------------------\n// Graph compilation\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a graph spec into a GraphCompilation.\n *\n * The graph pipeline resolves visual properties (size, color, stroke) for\n * nodes and edges, assigns communities, and builds legend/tooltip/a11y data.\n * Unlike charts, the output does NOT include x/y positions since the force\n * simulation in the adapter handles layout at runtime.\n *\n * @param spec - Raw graph spec (validated and normalized internally).\n * @param options - Compile options (width, height, theme, darkMode).\n * @returns GraphCompilation with resolved visual properties and simulation config.\n * @throws Error if spec is invalid or not a graph type.\n */\nexport function compileGraph(spec: unknown, options: CompileOptions): GraphCompilation {\n return compileGraphImpl(spec, options);\n}\n\n// ---------------------------------------------------------------------------\n// Sankey compilation\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a sankey spec into a SankeyLayout.\n *\n * Takes a raw sankey spec, validates, normalizes, resolves theme and chrome,\n * runs the d3-sankey layout algorithm, builds node/link marks with colors and\n * labels, and returns a SankeyLayout ready for rendering.\n *\n * @param spec - Raw sankey spec (validated and normalized internally).\n * @param options - Compile options (width, height, theme, darkMode).\n * @returns SankeyLayout with computed positions and visual properties.\n * @throws Error if spec is invalid or not a sankey type.\n */\nexport function compileSankey(\n spec: unknown,\n options: CompileOptions,\n): import('@opendata-ai/openchart-core').SankeyLayout {\n return compileSankeyImpl(spec, options);\n}\n","/**\n * Collision avoidance for annotations: nudging away from obstacles,\n * resolving annotation-to-annotation overlaps, and clamping to SVG bounds.\n */\n\nimport type {\n Rect,\n ResolvedAnnotation,\n ResolvedLabel,\n TextAnnotation,\n} from '@opendata-ai/openchart-core';\nimport { detectCollision } from '@opendata-ai/openchart-core';\nimport type { NormalizedChartSpec } from '../compiler/types';\nimport type { ResolvedScales } from '../layout/scales';\nimport { CLAMP_MARGIN, NUDGE_PADDING } from './constants';\nimport { estimateLabelBounds, recomputeConnector } from './geometry';\nimport { resolvePosition } from './position';\n\n/**\n * Generate candidate displacement vectors to move `selfBounds` clear of each\n * obstacle in 4 directions (below, above, left, right), sorted by smallest\n * movement first.\n */\nexport function generateNudgeCandidates(\n selfBounds: Rect,\n obstacles: Rect[],\n padding: number,\n): { dx: number; dy: number; distance: number }[] {\n const candidates: { dx: number; dy: number; distance: number }[] = [];\n\n for (const obs of obstacles) {\n // Below: shift self so its top edge clears the obstacle bottom\n const belowDy = obs.y + obs.height + padding - selfBounds.y;\n candidates.push({ dx: 0, dy: belowDy, distance: Math.abs(belowDy) });\n\n // Above: shift self so its bottom edge clears the obstacle top\n const aboveDy = obs.y - padding - (selfBounds.y + selfBounds.height);\n candidates.push({ dx: 0, dy: aboveDy, distance: Math.abs(aboveDy) });\n\n // Left: shift self so its right edge clears the obstacle left\n const leftDx = obs.x - padding - (selfBounds.x + selfBounds.width);\n candidates.push({ dx: leftDx, dy: 0, distance: Math.abs(leftDx) });\n\n // Right: shift self so its left edge clears the obstacle right\n const rightDx = obs.x + obs.width + padding - selfBounds.x;\n candidates.push({ dx: rightDx, dy: 0, distance: Math.abs(rightDx) });\n }\n\n candidates.sort((a, b) => a.distance - b.distance);\n return candidates;\n}\n\n/**\n * Try to reposition a text annotation to avoid overlapping with obstacle rects\n * (legend bounds, etc.). First tries standard anchor alternatives, then\n * calculates specific offsets needed to clear obstacles. Returns true if moved.\n */\nexport function nudgeAnnotationFromObstacles(\n annotation: ResolvedAnnotation,\n originalAnnotation: TextAnnotation,\n scales: ResolvedScales,\n chartArea: Rect,\n obstacles: Rect[],\n): boolean {\n if (annotation.type !== 'text' || !annotation.label) return false;\n\n const labelBounds = estimateLabelBounds(annotation.label);\n const collidingObs = obstacles.filter(\n (obs) => obs.width > 0 && obs.height > 0 && detectCollision(labelBounds, obs),\n );\n\n if (collidingObs.length === 0) return false;\n\n // Resolve the data point pixel position for offset calculations\n const px = resolvePosition(originalAnnotation.x, scales.x);\n const py = resolvePosition(originalAnnotation.y, scales.y);\n if (px === null || py === null) return false;\n\n const candidates = generateNudgeCandidates(labelBounds, collidingObs, NUDGE_PADDING);\n const fontSize = labelBounds.height / Math.max(1, annotation.label.text.split('\\n').length);\n\n for (const { dx, dy } of candidates) {\n const newLabelX = annotation.label.x + dx;\n const newLabelY = annotation.label.y + dy;\n\n const candidateLabel: ResolvedLabel = {\n ...annotation.label,\n x: newLabelX,\n y: newLabelY,\n connector: recomputeConnector({ ...annotation.label, x: newLabelX, y: newLabelY }, px, py),\n };\n\n const candidateBounds = estimateLabelBounds(candidateLabel);\n\n // Check no collisions with any obstacle\n const stillCollides = obstacles.some(\n (obs) => obs.width > 0 && obs.height > 0 && detectCollision(candidateBounds, obs),\n );\n if (stillCollides) continue;\n\n // Annotations render outside the clip path, so they can extend into margins.\n // Only check that the label center is reasonably within the chart and that\n // the text doesn't go completely off-screen.\n const labelCenterX = candidateBounds.x + candidateBounds.width / 2;\n const labelCenterY = candidateBounds.y + candidateBounds.height / 2;\n // Allow nudged labels to extend into the chrome region below the chart\n // (source/footer area) since annotations near the bottom edge often\n // need to shift into that space to avoid marks or the brand watermark.\n const inBounds =\n labelCenterX >= chartArea.x &&\n labelCenterX <= chartArea.x + chartArea.width + 10 &&\n labelCenterY >= chartArea.y - fontSize &&\n labelCenterY <= chartArea.y + chartArea.height + fontSize * 3;\n\n if (inBounds) {\n annotation.label = candidateLabel;\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Resolve collisions between text annotation labels using a greedy algorithm.\n *\n * Iterates through text annotations in order, building a list of \"placed\"\n * bounding rects. When a later annotation overlaps an already-placed one,\n * it tries offset positions (below, above, left, right) to find a\n * non-colliding spot. Recomputes the connector origin after nudging.\n */\nexport function resolveAnnotationCollisions(\n annotations: ResolvedAnnotation[],\n originalSpecs: NormalizedChartSpec['annotations'],\n scales: ResolvedScales,\n chartArea: Rect,\n): void {\n const placedBounds: Rect[] = [];\n\n for (let i = 0; i < annotations.length; i++) {\n const annotation = annotations[i];\n if (annotation.type !== 'text' || !annotation.label) {\n continue;\n }\n\n const bounds = estimateLabelBounds(annotation.label);\n\n // Check against all previously placed annotation labels\n const collidingBounds = placedBounds.filter(\n (pb) => pb.width > 0 && pb.height > 0 && detectCollision(bounds, pb),\n );\n\n if (collidingBounds.length > 0) {\n // Find the original spec to get data point coordinates for connector recomputation\n const originalSpec = originalSpecs[i];\n\n if (originalSpec?.type === 'text') {\n const px = resolvePosition(originalSpec.x, scales.x);\n const py = resolvePosition(originalSpec.y, scales.y);\n\n if (px !== null && py !== null) {\n const candidates = generateNudgeCandidates(bounds, collidingBounds, NUDGE_PADDING);\n const fontSize = bounds.height / Math.max(1, annotation.label.text.split('\\n').length);\n\n for (const { dx, dy } of candidates) {\n const newLabelX = annotation.label.x + dx;\n const newLabelY = annotation.label.y + dy;\n\n const candidateLabel: ResolvedLabel = {\n ...annotation.label,\n x: newLabelX,\n y: newLabelY,\n };\n const candidateBounds = estimateLabelBounds(candidateLabel);\n\n // Check no collisions with any placed label\n const stillCollides = placedBounds.some(\n (pb) => pb.width > 0 && pb.height > 0 && detectCollision(candidateBounds, pb),\n );\n if (stillCollides) continue;\n\n // Check the label center stays reasonably in bounds\n const labelCenterX = candidateBounds.x + candidateBounds.width / 2;\n const labelCenterY = candidateBounds.y + candidateBounds.height / 2;\n const inBounds =\n labelCenterX >= chartArea.x &&\n labelCenterX <= chartArea.x + chartArea.width + 10 &&\n labelCenterY >= chartArea.y - fontSize &&\n labelCenterY <= chartArea.y + chartArea.height + fontSize;\n\n if (inBounds) {\n annotation.label = {\n ...annotation.label,\n x: newLabelX,\n y: newLabelY,\n connector: recomputeConnector(\n { ...annotation.label, x: newLabelX, y: newLabelY },\n px,\n py,\n ),\n };\n break;\n }\n }\n }\n }\n }\n\n // Add this annotation's final bounds to the placed list\n placedBounds.push(estimateLabelBounds(annotation.label));\n }\n}\n\n/**\n * Shift text annotation labels so they stay within the total SVG bounds.\n * If a label overflows the right, left, top, or bottom edge, its position\n * is adjusted inward by the overflow amount. Connector geometry is updated\n * to match.\n */\nexport function clampAnnotationsToBounds(\n annotations: ResolvedAnnotation[],\n svgWidth: number,\n svgHeight: number,\n): void {\n for (const annotation of annotations) {\n if (annotation.type !== 'text' || !annotation.label) continue;\n\n const bounds = estimateLabelBounds(annotation.label);\n let dx = 0;\n let dy = 0;\n\n // Right overflow\n if (bounds.x + bounds.width > svgWidth - CLAMP_MARGIN) {\n dx = svgWidth - CLAMP_MARGIN - (bounds.x + bounds.width);\n }\n // Left overflow\n if (bounds.x + dx < CLAMP_MARGIN) {\n dx = CLAMP_MARGIN - bounds.x;\n }\n // Top overflow\n if (bounds.y < CLAMP_MARGIN) {\n dy = CLAMP_MARGIN - bounds.y;\n }\n // Bottom overflow\n if (bounds.y + bounds.height + dy > svgHeight - CLAMP_MARGIN) {\n dy = svgHeight - CLAMP_MARGIN - (bounds.y + bounds.height);\n }\n\n if (dx === 0 && dy === 0) continue;\n\n const newX = annotation.label.x + dx;\n const newY = annotation.label.y + dy;\n\n const connector = annotation.label.connector;\n annotation.label = {\n ...annotation.label,\n x: newX,\n y: newY,\n connector: connector\n ? recomputeConnector(\n { ...annotation.label, x: newX, y: newY },\n connector.to.x,\n connector.to.y,\n )\n : undefined,\n };\n }\n}\n","/** Default font size for annotation labels. */\nexport const DEFAULT_ANNOTATION_FONT_SIZE = 12;\n\n/** Default font weight for annotation labels. */\nexport const DEFAULT_ANNOTATION_FONT_WEIGHT = 400;\n\n/** Default line height multiplier for annotation text. */\nexport const DEFAULT_LINE_HEIGHT = 1.3;\n\n/** Default fill color for range annotations. */\nexport const DEFAULT_RANGE_FILL = '#f0c040';\n\n/** Default opacity for range annotations. */\nexport const DEFAULT_RANGE_OPACITY = 0.15;\n\n/** Default dash pattern for reference lines. */\nexport const DEFAULT_REFLINE_DASH = '4 3';\n\n// Theme-aware defaults for text and stroke colors\nexport const LIGHT_TEXT_FILL = '#333333';\nexport const DARK_TEXT_FILL = '#d1d5db';\nexport const LIGHT_REFLINE_STROKE = '#888888';\nexport const DARK_REFLINE_STROKE = '#9ca3af';\n\n/** Default label offset when using anchor directions. */\nexport const ANCHOR_OFFSET = 8;\n\n/** Padding between annotation and obstacle when nudging. */\nexport const NUDGE_PADDING = 6;\n\n/** Small inset margin so labels don't touch the SVG edge. */\nexport const CLAMP_MARGIN = 4;\n","/**\n * Geometry utilities for annotation text bounds, connector origins, and offsets.\n */\n\nimport type {\n AnnotationAnchor,\n AnnotationOffset,\n Rect,\n ResolvedLabel,\n} from '@opendata-ai/openchart-core';\nimport { estimateTextWidth } from '@opendata-ai/openchart-core';\nimport {\n ANCHOR_OFFSET,\n DEFAULT_ANNOTATION_FONT_SIZE,\n DEFAULT_ANNOTATION_FONT_WEIGHT,\n DEFAULT_LINE_HEIGHT,\n} from './constants';\n\n/**\n * Compute the bounding box of annotation text at a given label position.\n * Multi-line text is centered at labelX; single-line starts at labelX.\n */\nexport function computeTextBounds(\n labelX: number,\n labelY: number,\n text: string,\n fontSize: number,\n fontWeight: number,\n): Rect {\n const lines = text.split('\\n');\n const isMultiLine = lines.length > 1;\n const maxWidth = Math.max(...lines.map((line) => estimateTextWidth(line, fontSize, fontWeight)));\n const totalHeight = lines.length * fontSize * DEFAULT_LINE_HEIGHT;\n const x = isMultiLine ? labelX - maxWidth / 2 : labelX;\n\n return {\n x,\n y: labelY - fontSize,\n width: maxWidth,\n height: totalHeight,\n };\n}\n\n/**\n * Apply anchor direction to compute label offset from data point.\n * Returns { dx, dy } pixel offsets.\n */\nexport function computeAnchorOffset(\n anchor: AnnotationAnchor | undefined,\n _px: number,\n py: number,\n chartArea: Rect,\n): { dx: number; dy: number } {\n if (!anchor || anchor === 'auto') {\n // Auto: place above if in the lower half, below if upper half\n const isUpperHalf = py < chartArea.y + chartArea.height / 2;\n return isUpperHalf\n ? { dx: ANCHOR_OFFSET, dy: ANCHOR_OFFSET } // below-right\n : { dx: ANCHOR_OFFSET, dy: -ANCHOR_OFFSET }; // above-right\n }\n\n switch (anchor) {\n case 'top':\n return { dx: 0, dy: -ANCHOR_OFFSET };\n case 'bottom':\n return { dx: 0, dy: ANCHOR_OFFSET };\n case 'left':\n return { dx: -ANCHOR_OFFSET, dy: 0 };\n case 'right':\n return { dx: ANCHOR_OFFSET, dy: 0 };\n }\n}\n\n/** Apply user offset on top of computed anchor offset. */\nexport function applyOffset(\n base: { dx: number; dy: number },\n offset: AnnotationOffset | undefined,\n): { dx: number; dy: number } {\n if (!offset) return base;\n return {\n dx: base.dx + (offset.dx ?? 0),\n dy: base.dy + (offset.dy ?? 0),\n };\n}\n\n/**\n * Compute the connector origin point on the text bounding box.\n * For straight connectors, finds the edge midpoint (top, bottom, left, right)\n * closest to the data point. For curve connectors, always uses the right edge.\n */\nexport function computeConnectorOrigin(\n labelX: number,\n labelY: number,\n text: string,\n fontSize: number,\n fontWeight: number,\n targetX: number,\n targetY: number,\n connectorStyle: 'straight' | 'curve',\n): { x: number; y: number } {\n const box = computeTextBounds(labelX, labelY, text, fontSize, fontWeight);\n const boxCenterX = box.x + box.width / 2;\n const boxCenterY = box.y + box.height / 2;\n\n // Curve connectors always start from the right edge\n if (connectorStyle === 'curve') {\n return {\n x: box.x + box.width,\n y: boxCenterY,\n };\n }\n\n // Normalize the vector from box center to target by the box half-dimensions.\n // This accounts for the box aspect ratio: a wide text box should prefer\n // top/bottom exits even when the target is also offset horizontally.\n const halfW = box.width / 2 || 1;\n const halfH = box.height / 2 || 1;\n const ndx = (targetX - boxCenterX) / halfW;\n const ndy = (targetY - boxCenterY) / halfH;\n\n if (Math.abs(ndy) >= Math.abs(ndx)) {\n // Target is more above/below than left/right → use top or bottom edge\n return ndy < 0\n ? { x: boxCenterX, y: box.y } // top\n : { x: boxCenterX, y: box.y + box.height }; // bottom\n }\n // Target is more left/right → use left or right edge\n return ndx < 0\n ? { x: box.x, y: boxCenterY } // left\n : { x: box.x + box.width, y: boxCenterY }; // right\n}\n\n/** Estimate the bounding box of an annotation label. */\nexport function estimateLabelBounds(label: ResolvedLabel): Rect {\n const fontSize = label.style.fontSize ?? DEFAULT_ANNOTATION_FONT_SIZE;\n const fontWeight = label.style.fontWeight ?? DEFAULT_ANNOTATION_FONT_WEIGHT;\n return computeTextBounds(label.x, label.y, label.text, fontSize, fontWeight);\n}\n\n/**\n * Recompute the connector origin for a label after it has been repositioned.\n * Encapsulates the pattern of recalculating which edge of the text box the\n * connector should exit from based on the target data point.\n */\nexport function recomputeConnector(\n label: ResolvedLabel,\n targetX: number,\n targetY: number,\n): ResolvedLabel['connector'] {\n const connector = label.connector;\n if (!connector) return connector;\n\n const fontSize = label.style.fontSize ?? DEFAULT_ANNOTATION_FONT_SIZE;\n const fontWeight = label.style.fontWeight ?? DEFAULT_ANNOTATION_FONT_WEIGHT;\n const connStyle = connector.style === 'curve' ? ('curve' as const) : ('straight' as const);\n const newFrom = computeConnectorOrigin(\n label.x,\n label.y,\n label.text,\n fontSize,\n fontWeight,\n targetX,\n targetY,\n connStyle,\n );\n return { ...connector, from: newFrom };\n}\n","/**\n * Data-coordinate to pixel-coordinate resolution for annotations.\n */\n\nimport type { ScaleBand, ScaleLinear, ScaleTime } from 'd3-scale';\nimport type { ResolvedScales } from '../layout/scales';\n\n/**\n * Interpolate a numeric value between sorted domain entries.\n * Used when an annotation references a value not present in a categorical domain\n * (e.g. \"2008\" on an axis with data points at \"2007\" and \"2009\").\n * Returns null if domain values aren't numeric or the domain is too small.\n */\nexport function interpolateInDomain(\n numValue: number,\n domain: string[],\n positionOf: (entry: string) => number,\n): number | null {\n if (domain.length < 2) return null;\n const nums = domain.map(Number);\n if (!nums.every(Number.isFinite)) return null;\n\n // Sort by numeric value so bracket-finding works regardless of data order\n const sorted = nums.map((n, i) => ({ n, i })).sort((a, b) => a.n - b.n);\n\n // Find the two sorted neighbors that bracket this value\n let lower = 0;\n let upper = sorted.length - 1;\n for (let i = 0; i < sorted.length; i++) {\n if (sorted[i].n <= numValue) lower = i;\n if (sorted[i].n >= numValue) {\n upper = i;\n break;\n }\n }\n\n const lowerPos = positionOf(domain[sorted[lower].i]);\n const upperPos = positionOf(domain[sorted[upper].i]);\n if (lower === upper) return lowerPos;\n const t = (numValue - sorted[lower].n) / (sorted[upper].n - sorted[lower].n);\n return lowerPos + t * (upperPos - lowerPos);\n}\n\n/** Resolve a data value to a pixel position on a given axis. */\nexport function resolvePosition(\n value: string | number,\n scale: ResolvedScales['x'] | ResolvedScales['y'],\n): number | null {\n if (!scale) return null;\n\n const s = scale.scale;\n const type = scale.type;\n\n if (type === 'time') {\n const date = new Date(String(value));\n if (Number.isNaN(date.getTime())) return null;\n return (s as ScaleTime<number, number>)(date);\n }\n\n if (type === 'linear' || type === 'log') {\n const num = typeof value === 'number' ? value : Number(value);\n if (!Number.isFinite(num)) return null;\n return (s as ScaleLinear<number, number>)(num);\n }\n\n if (type === 'band') {\n const bandScale = s as ScaleBand<string>;\n const strValue = String(value);\n const pos = bandScale(strValue);\n if (pos !== undefined) return pos + (bandScale.bandwidth?.() ?? 0) / 2;\n\n const bw = bandScale.bandwidth?.() ?? 0;\n return interpolateInDomain(\n Number(strValue),\n bandScale.domain(),\n (entry) => (bandScale(entry) ?? 0) + bw / 2,\n );\n }\n\n // point or ordinal: try direct lookup, fall back to interpolation\n const strValue = String(value);\n const directResult = (s as (v: string) => number | undefined)(strValue);\n if (directResult !== undefined) return directResult;\n\n if (type === 'point' || type === 'ordinal') {\n const domain = (s as { domain(): string[] }).domain();\n return interpolateInDomain(\n Number(strValue),\n domain,\n (entry) => (s as (v: string) => number)(entry) ?? 0,\n );\n }\n\n return null;\n}\n","/**\n * Text annotation resolver: positions a label at data coordinates with an\n * optional callout connector to the data point.\n */\n\nimport type {\n Rect,\n ResolvedAnnotation,\n ResolvedLabel,\n TextAnnotation,\n TextStyle,\n} from '@opendata-ai/openchart-core';\nimport type { ResolvedScales } from '../layout/scales';\nimport {\n DARK_TEXT_FILL,\n DEFAULT_ANNOTATION_FONT_SIZE,\n DEFAULT_ANNOTATION_FONT_WEIGHT,\n DEFAULT_LINE_HEIGHT,\n LIGHT_TEXT_FILL,\n} from './constants';\nimport { applyOffset, computeAnchorOffset, computeConnectorOrigin } from './geometry';\nimport { resolvePosition } from './position';\n\nexport function makeAnnotationLabelStyle(\n fontSize?: number,\n fontWeight?: number,\n fill?: string,\n isDark?: boolean,\n): TextStyle {\n const defaultFill = isDark ? DARK_TEXT_FILL : LIGHT_TEXT_FILL;\n return {\n fontFamily: 'Inter, system-ui, sans-serif',\n fontSize: fontSize ?? DEFAULT_ANNOTATION_FONT_SIZE,\n fontWeight: fontWeight ?? DEFAULT_ANNOTATION_FONT_WEIGHT,\n fill: fill ?? defaultFill,\n lineHeight: DEFAULT_LINE_HEIGHT,\n textAnchor: 'start',\n };\n}\n\nexport function resolveTextAnnotation(\n annotation: TextAnnotation,\n scales: ResolvedScales,\n chartArea: Rect,\n isDark: boolean,\n): ResolvedAnnotation | null {\n const px = resolvePosition(annotation.x, scales.x);\n const py = resolvePosition(annotation.y, scales.y);\n\n if (px === null || py === null) return null;\n\n const defaultTextFill = isDark ? DARK_TEXT_FILL : LIGHT_TEXT_FILL;\n\n const labelStyle = makeAnnotationLabelStyle(\n annotation.fontSize,\n annotation.fontWeight,\n annotation.fill ?? defaultTextFill,\n isDark,\n );\n\n // Compute position from anchor direction + user offset\n const anchorDelta = computeAnchorOffset(annotation.anchor, px, py, chartArea);\n const finalDelta = applyOffset(anchorDelta, annotation.offset);\n\n const labelX = px + finalDelta.dx;\n const labelY = py + finalDelta.dy;\n\n // Connector: draw unless explicitly disabled\n const showConnector = annotation.connector !== false;\n const connectorStyle = annotation.connector === 'curve' ? 'curve' : 'straight';\n\n // Compute connector origin: pick the edge midpoint closest to the data point\n const fontSize = annotation.fontSize ?? DEFAULT_ANNOTATION_FONT_SIZE;\n const fontWeight = annotation.fontWeight ?? DEFAULT_ANNOTATION_FONT_WEIGHT;\n const { x: connectorFromX, y: connectorFromY } = computeConnectorOrigin(\n labelX,\n labelY,\n annotation.text,\n fontSize,\n fontWeight,\n px,\n py,\n connectorStyle,\n );\n\n // Apply user-provided connector endpoint offsets\n const baseFrom = { x: connectorFromX, y: connectorFromY };\n const baseTo = { x: px, y: py };\n const adjustedFrom = {\n x: baseFrom.x + (annotation.connectorOffset?.from?.dx ?? 0),\n y: baseFrom.y + (annotation.connectorOffset?.from?.dy ?? 0),\n };\n const adjustedToRaw = {\n x: baseTo.x + (annotation.connectorOffset?.to?.dx ?? 0),\n y: baseTo.y + (annotation.connectorOffset?.to?.dy ?? 0),\n };\n\n // Pull the \"to\" endpoint back along the connector direction so the\n // line doesn't touch the data point directly (leaves a small gap).\n const GAP = 4;\n const cdx = adjustedToRaw.x - adjustedFrom.x;\n const cdy = adjustedToRaw.y - adjustedFrom.y;\n const dist = Math.sqrt(cdx * cdx + cdy * cdy);\n const adjustedTo =\n dist > GAP * 2\n ? { x: adjustedToRaw.x - (cdx / dist) * GAP, y: adjustedToRaw.y - (cdy / dist) * GAP }\n : adjustedToRaw;\n\n const label: ResolvedLabel = {\n text: annotation.text,\n x: labelX,\n y: labelY,\n style: labelStyle,\n visible: true,\n connector: showConnector\n ? {\n from: adjustedFrom,\n to: adjustedTo,\n stroke: annotation.stroke ?? '#999999',\n style: connectorStyle,\n }\n : undefined,\n background: annotation.background,\n };\n\n return {\n type: 'text',\n id: annotation.id,\n label,\n stroke: annotation.stroke,\n fill: annotation.fill,\n opacity: annotation.opacity,\n zIndex: annotation.zIndex,\n };\n}\n","/**\n * Range annotation resolver: creates a highlighted rectangular band\n * between two data values on x or y axis.\n */\n\nimport type {\n RangeAnnotation,\n Rect,\n ResolvedAnnotation,\n ResolvedLabel,\n} from '@opendata-ai/openchart-core';\nimport type { ResolvedScales } from '../layout/scales';\nimport { DEFAULT_RANGE_FILL, DEFAULT_RANGE_OPACITY } from './constants';\nimport { applyOffset } from './geometry';\nimport { resolvePosition } from './position';\nimport { makeAnnotationLabelStyle } from './resolve-text';\n\nexport function resolveRangeAnnotation(\n annotation: RangeAnnotation,\n scales: ResolvedScales,\n chartArea: Rect,\n isDark: boolean,\n): ResolvedAnnotation | null {\n let x = chartArea.x;\n let y = chartArea.y;\n let width = chartArea.width;\n let height = chartArea.height;\n\n // X-range (vertical band)\n if (annotation.x1 !== undefined && annotation.x2 !== undefined) {\n const x1px = resolvePosition(annotation.x1, scales.x);\n const x2px = resolvePosition(annotation.x2, scales.x);\n if (x1px === null || x2px === null) return null;\n\n x = Math.min(x1px, x2px);\n width = Math.abs(x2px - x1px);\n }\n\n // Y-range (horizontal band)\n if (annotation.y1 !== undefined && annotation.y2 !== undefined) {\n const y1px = resolvePosition(annotation.y1, scales.y);\n const y2px = resolvePosition(annotation.y2, scales.y);\n if (y1px === null || y2px === null) return null;\n\n y = Math.min(y1px, y2px);\n height = Math.abs(y2px - y1px);\n }\n\n const rect: Rect = { x, y, width, height };\n\n // Label positioned within the range, with optional offset.\n // labelAnchor controls horizontal placement:\n // \"top\" (default): horizontally centered, text-anchor middle\n // \"left\": left edge, text-anchor start\n // \"right\": right edge, text-anchor end\n // \"bottom\"/\"auto\": horizontally centered, text-anchor middle\n let label: ResolvedLabel | undefined;\n if (annotation.label) {\n const anchor = annotation.labelAnchor ?? 'top';\n const centered = anchor === 'top' || anchor === 'bottom' || anchor === 'auto';\n const baseDx = centered ? 0 : anchor === 'right' ? -4 : 4;\n const baseDy = 14;\n const labelDelta = applyOffset({ dx: baseDx, dy: baseDy }, annotation.labelOffset);\n\n const style = makeAnnotationLabelStyle(11, 500, undefined, isDark);\n if (centered) {\n style.textAnchor = 'middle';\n } else if (anchor === 'right') {\n style.textAnchor = 'end';\n }\n\n // Position label horizontally centered within the range band by default.\n // For left/right anchors, position at the respective edge.\n const baseX = centered ? x + width / 2 : anchor === 'right' ? x + width : x;\n\n label = {\n text: annotation.label,\n x: baseX + labelDelta.dx,\n y: y + labelDelta.dy,\n style,\n visible: true,\n };\n }\n\n // In dark mode, boost range opacity slightly for better visibility\n const defaultOpacity = isDark ? 0.2 : DEFAULT_RANGE_OPACITY;\n\n return {\n type: 'range',\n id: annotation.id,\n rect,\n label,\n fill: annotation.fill ?? DEFAULT_RANGE_FILL,\n opacity: annotation.opacity ?? defaultOpacity,\n stroke: annotation.stroke,\n zIndex: annotation.zIndex,\n };\n}\n","/**\n * Reference line annotation resolver: creates a horizontal or vertical\n * reference line at a data value with optional label.\n */\n\nimport type {\n Point,\n Rect,\n RefLineAnnotation,\n ResolvedAnnotation,\n ResolvedLabel,\n} from '@opendata-ai/openchart-core';\nimport type { ResolvedScales } from '../layout/scales';\nimport { DARK_REFLINE_STROKE, DEFAULT_REFLINE_DASH, LIGHT_REFLINE_STROKE } from './constants';\nimport { applyOffset } from './geometry';\nimport { resolvePosition } from './position';\nimport { makeAnnotationLabelStyle } from './resolve-text';\n\nexport function resolveRefLineAnnotation(\n annotation: RefLineAnnotation,\n scales: ResolvedScales,\n chartArea: Rect,\n isDark: boolean,\n): ResolvedAnnotation | null {\n let start: Point;\n let end: Point;\n\n if (annotation.y !== undefined) {\n // Horizontal reference line\n const yPx = resolvePosition(annotation.y, scales.y);\n if (yPx === null) return null;\n\n start = { x: chartArea.x, y: yPx };\n end = { x: chartArea.x + chartArea.width, y: yPx };\n } else if (annotation.x !== undefined) {\n // Vertical reference line\n const xPx = resolvePosition(annotation.x, scales.x);\n if (xPx === null) return null;\n\n start = { x: xPx, y: chartArea.y };\n end = { x: xPx, y: chartArea.y + chartArea.height };\n } else {\n return null;\n }\n\n // Determine dash pattern from style\n let strokeDasharray: string | undefined;\n if (annotation.style === 'dashed' || annotation.style === undefined) {\n strokeDasharray = DEFAULT_REFLINE_DASH;\n } else if (annotation.style === 'dotted') {\n strokeDasharray = '2 2';\n }\n // 'solid' gets no dasharray\n\n // Label placement on reflines. labelAnchor controls position:\n //\n // Horizontal reflines (y set):\n // \"left\": left end of line, above \"right\"/\"top\" (default): right end, above\n // \"bottom\": right end of line, below\n //\n // Vertical reflines (x set):\n // \"right\": label to the left of the line, near top\n // \"bottom\": label to the right of the line, near bottom\n // \"left\"/\"top\" (default): label to the right of the line, near top\n let label: ResolvedLabel | undefined;\n if (annotation.label) {\n const isHorizontal = annotation.y !== undefined;\n const anchor = annotation.labelAnchor ?? (isHorizontal ? 'top' : 'left');\n\n let baseDx: number;\n let baseDy: number;\n let labelX: number;\n let labelY: number;\n let textAnchor: 'start' | 'middle' | 'end';\n\n if (isHorizontal) {\n if (anchor === 'left') {\n baseDx = 4;\n baseDy = -4;\n labelX = start.x;\n labelY = start.y;\n textAnchor = 'start';\n } else if (anchor === 'bottom') {\n baseDx = -4;\n baseDy = 14;\n labelX = end.x;\n labelY = end.y;\n textAnchor = 'end';\n } else {\n // 'right', 'top' (default), 'auto'\n baseDx = -4;\n baseDy = -4;\n labelX = end.x;\n labelY = end.y;\n textAnchor = 'end';\n }\n } else {\n // Vertical refline\n if (anchor === 'right') {\n baseDx = -4;\n baseDy = 14;\n labelX = start.x;\n labelY = start.y;\n textAnchor = 'end';\n } else if (anchor === 'bottom') {\n baseDx = 4;\n baseDy = -4;\n labelX = start.x;\n labelY = end.y;\n textAnchor = 'start';\n } else {\n // 'left', 'top' (default), 'auto' — label to the right of the line, near top\n baseDx = 4;\n baseDy = 14;\n labelX = start.x;\n labelY = start.y;\n textAnchor = 'start';\n }\n }\n\n const labelDelta = applyOffset({ dx: baseDx, dy: baseDy }, annotation.labelOffset);\n\n const defaultStroke = isDark ? DARK_REFLINE_STROKE : LIGHT_REFLINE_STROKE;\n const style = makeAnnotationLabelStyle(11, 400, annotation.stroke ?? defaultStroke, isDark);\n style.textAnchor = textAnchor;\n\n label = {\n text: annotation.label,\n x: labelX + labelDelta.dx,\n y: labelY + labelDelta.dy,\n style,\n visible: true,\n };\n }\n\n const defaultStroke = isDark ? DARK_REFLINE_STROKE : LIGHT_REFLINE_STROKE;\n\n return {\n type: 'refline',\n id: annotation.id,\n line: { start, end },\n label,\n stroke: annotation.stroke ?? defaultStroke,\n strokeDasharray,\n strokeWidth: annotation.strokeWidth ?? 1,\n zIndex: annotation.zIndex,\n };\n}\n","/**\n * Annotation computation: converts spec-level annotations to pixel-positioned\n * ResolvedAnnotation objects using the resolved scales.\n *\n * Handles three annotation types:\n * - text: positioned at a data coordinate with an optional callout\n * - range: a highlighted rectangle between two data values\n * - refline: a horizontal or vertical reference line at a data value\n *\n * Supports fine-grained positioning via offset, anchor, connector, and zIndex.\n * At compact breakpoints, annotations are simplified or hidden.\n */\n\nimport type { LayoutStrategy, Rect, ResolvedAnnotation } from '@opendata-ai/openchart-core';\nimport type { NormalizedChartSpec } from '../compiler/types';\nimport type { ResolvedScales } from '../layout/scales';\nimport {\n clampAnnotationsToBounds,\n nudgeAnnotationFromObstacles,\n resolveAnnotationCollisions,\n} from './collisions';\nimport { resolveRangeAnnotation } from './resolve-range';\nimport { resolveRefLineAnnotation } from './resolve-refline';\nimport { resolveTextAnnotation } from './resolve-text';\n\n/**\n * Compute resolved annotations from spec annotations using the resolved scales.\n *\n * Converts data-coordinate annotations to pixel-positioned ResolvedAnnotation\n * objects. Supports offset, anchor, connector, and zIndex. At compact\n * breakpoints, annotations are hidden (strategy says \"tooltip-only\").\n *\n * When obstacle rects are provided (e.g. legend bounds), text annotations\n * that overlap with them are automatically repositioned using alternate\n * anchor directions. After individual obstacle avoidance, annotation-to-\n * annotation collisions are resolved using a greedy placement algorithm.\n * Finally, labels are clamped to stay within the total SVG bounds.\n */\nexport function computeAnnotations(\n spec: NormalizedChartSpec,\n scales: ResolvedScales,\n chartArea: Rect,\n strategy: LayoutStrategy,\n isDark = false,\n obstacles: Rect[] = [],\n svgDimensions?: { width: number; height: number },\n): ResolvedAnnotation[] {\n // At compact breakpoints, skip all annotations\n if (strategy.annotationPosition === 'tooltip-only') {\n return [];\n }\n\n const annotations: ResolvedAnnotation[] = [];\n\n for (const annotation of spec.annotations) {\n let resolved: ResolvedAnnotation | null = null;\n\n switch (annotation.type) {\n case 'text':\n resolved = resolveTextAnnotation(annotation, scales, chartArea, isDark);\n break;\n case 'range':\n resolved = resolveRangeAnnotation(annotation, scales, chartArea, isDark);\n break;\n case 'refline':\n resolved = resolveRefLineAnnotation(annotation, scales, chartArea, isDark);\n break;\n }\n\n if (resolved) {\n // For text annotations, check for collisions with obstacles and nudge if needed\n if (annotation.type === 'text' && obstacles.length > 0) {\n nudgeAnnotationFromObstacles(resolved, annotation, scales, chartArea, obstacles);\n }\n annotations.push(resolved);\n }\n }\n\n // Resolve annotation-to-annotation collisions (greedy, order-preserving)\n resolveAnnotationCollisions(annotations, spec.annotations, scales, chartArea);\n\n // Clamp labels that overflow the SVG boundary back inside\n if (svgDimensions) {\n clampAnnotationsToBounds(annotations, svgDimensions.width, svgDimensions.height);\n }\n\n // Sort by zIndex (lower first, undefined treated as 0)\n annotations.sort((a, b) => (a.zIndex ?? 0) - (b.zIndex ?? 0));\n\n return annotations;\n}\n","/**\n * Predicate evaluation for filter transforms and conditional encoding.\n *\n * Supports field predicates (equal, lt, gt, range, oneOf, valid)\n * and logical combinators (and, or, not).\n */\n\nimport type { DataRow, FieldPredicate, FilterPredicate } from '@opendata-ai/openchart-core';\n\n/**\n * Check if a predicate is a FieldPredicate (has a 'field' property).\n */\nfunction isFieldPredicate(pred: FilterPredicate): pred is FieldPredicate {\n return 'field' in pred;\n}\n\n/**\n * Evaluate a single field predicate against a datum.\n */\nfunction evaluateFieldPredicate(datum: DataRow, pred: FieldPredicate): boolean {\n const value = datum[pred.field];\n\n // valid: check for non-null, non-undefined, non-NaN\n if (pred.valid !== undefined) {\n const isValid = value !== null && value !== undefined && !Number.isNaN(value);\n return pred.valid ? isValid : !isValid;\n }\n\n // equal: use loose equality so \"181\" == 181 matches across type boundaries\n // (data values may arrive as strings from CSV/JSON parsing)\n if (pred.equal !== undefined) {\n // biome-ignore lint/suspicious/noDoubleEquals: intentional loose equality for CSV/JSON type coercion\n return value == pred.equal;\n }\n\n // Numeric comparisons\n const numValue = Number(value);\n\n if (pred.lt !== undefined) {\n return numValue < pred.lt;\n }\n if (pred.lte !== undefined) {\n return numValue <= pred.lte;\n }\n if (pred.gt !== undefined) {\n return numValue > pred.gt;\n }\n if (pred.gte !== undefined) {\n return numValue >= pred.gte;\n }\n\n // range: inclusive [min, max]\n if (pred.range !== undefined) {\n const [min, max] = pred.range;\n return numValue >= min && numValue <= max;\n }\n\n // oneOf: use loose equality (same rationale as equal above)\n if (pred.oneOf !== undefined) {\n // biome-ignore lint/suspicious/noDoubleEquals: intentional loose equality for CSV/JSON type coercion\n return pred.oneOf.some((v) => v == value);\n }\n\n // No condition specified, default to true\n return true;\n}\n\n/**\n * Evaluate a filter predicate (field predicate or logical combinator) against a datum.\n *\n * @param datum - The data row to test.\n * @param predicate - The filter predicate to evaluate.\n * @returns Whether the datum passes the predicate.\n */\nexport function evaluatePredicate(datum: DataRow, predicate: FilterPredicate): boolean {\n if (isFieldPredicate(predicate)) {\n return evaluateFieldPredicate(datum, predicate);\n }\n\n if ('and' in predicate) {\n return predicate.and.every((p) => evaluatePredicate(datum, p));\n }\n\n if ('or' in predicate) {\n return predicate.or.some((p) => evaluatePredicate(datum, p));\n }\n\n if ('not' in predicate) {\n return !evaluatePredicate(datum, predicate.not);\n }\n\n return true;\n}\n","/**\n * Conditional encoding evaluation.\n *\n * Resolves conditional value definitions per-datum by evaluating\n * predicates and returning the first matching condition's value.\n */\n\nimport type { ConditionalValueDef, DataRow } from '@opendata-ai/openchart-core';\nimport { evaluatePredicate } from './predicates';\n\n/**\n * Resolve a conditional value definition for a datum.\n *\n * Evaluates conditions in order, returning the value from the first\n * condition whose test passes. Falls back to the default value if\n * no condition matches.\n *\n * @param datum - The data row to evaluate against.\n * @param channelDef - The conditional value definition.\n * @returns The resolved value, or undefined if no condition matches and no default.\n */\nexport function resolveConditionalValue(datum: DataRow, channelDef: ConditionalValueDef): unknown {\n const conditions = Array.isArray(channelDef.condition)\n ? channelDef.condition\n : [channelDef.condition];\n\n for (const cond of conditions) {\n if (evaluatePredicate(datum, cond.test)) {\n // If the condition specifies a field, return the datum's field value\n if (cond.field !== undefined) {\n return datum[cond.field];\n }\n return cond.value;\n }\n }\n\n // No condition matched, return default\n return channelDef.value;\n}\n\n/**\n * Check if a channel definition is a ConditionalValueDef.\n */\nexport function isConditionalValueDef(def: unknown): def is ConditionalValueDef {\n return def !== null && typeof def === 'object' && 'condition' in (def as Record<string, unknown>);\n}\n","/**\n * Chart renderer registry.\n *\n * Each chart type (line, bar, column, scatter, pie, donut, dot) registers\n * a renderer that produces marks from normalized specs and resolved scales.\n * The registry pattern decouples chart-type logic from the compile pipeline.\n */\n\nimport type { LayoutStrategy, Mark, Rect, ResolvedTheme } from '@opendata-ai/openchart-core';\n\nimport type { NormalizedChartSpec } from '../compiler/types';\nimport type { ResolvedScales } from '../layout/scales';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A chart renderer function.\n *\n * Takes a normalized spec, resolved scales, chart area, layout strategy,\n * and the resolved theme for theme-aware styling (e.g. label colors).\n * Returns an array of marks to render.\n */\nexport type ChartRenderer = (\n spec: NormalizedChartSpec,\n scales: ResolvedScales,\n chartArea: Rect,\n strategy: LayoutStrategy,\n theme: ResolvedTheme,\n) => Mark[];\n\n// ---------------------------------------------------------------------------\n// Registry\n// ---------------------------------------------------------------------------\n\nconst renderers = new Map<string, ChartRenderer>();\n\n/**\n * Register a chart renderer for a specific chart type.\n *\n * @param type - Chart type string (e.g. \"line\", \"bar\").\n * @param renderer - The renderer function.\n */\nexport function registerChartRenderer(type: string, renderer: ChartRenderer): void {\n renderers.set(type, renderer);\n}\n\n/**\n * Get the registered chart renderer for a type.\n *\n * @param type - Chart type string.\n * @returns The renderer, or undefined if no renderer is registered.\n */\nexport function getChartRenderer(type: string): ChartRenderer | undefined {\n return renderers.get(type);\n}\n\n/**\n * Clear all registered renderers. Useful for testing.\n *\n * Note: the built-in renderers (line, bar, column, ...) register as a\n * side-effect of importing `./builtin`. Once cleared, they do not come\n * back on their own — subsequent `compileChart(...)` calls will return\n * empty marks. Tests that call `clearRenderers()` should follow up with\n * `registerBuiltinRenderers()` from `./builtin` to restore the defaults.\n */\nexport function clearRenderers(): void {\n renderers.clear();\n}\n","export default function ascending(a, b) {\n return a == null || b == null ? NaN : a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n}\n","export default function descending(a, b) {\n return a == null || b == null ? NaN\n : b < a ? -1\n : b > a ? 1\n : b >= a ? 0\n : NaN;\n}\n","import ascending from \"./ascending.js\";\nimport descending from \"./descending.js\";\n\nexport default function bisector(f) {\n let compare1, compare2, delta;\n\n // If an accessor is specified, promote it to a comparator. In this case we\n // can test whether the search value is (self-) comparable. We can’t do this\n // for a comparator (except for specific, known comparators) because we can’t\n // tell if the comparator is symmetric, and an asymmetric comparator can’t be\n // used to test whether a single value is comparable.\n if (f.length !== 2) {\n compare1 = ascending;\n compare2 = (d, x) => ascending(f(d), x);\n delta = (d, x) => f(d) - x;\n } else {\n compare1 = f === ascending || f === descending ? f : zero;\n compare2 = f;\n delta = f;\n }\n\n function left(a, x, lo = 0, hi = a.length) {\n if (lo < hi) {\n if (compare1(x, x) !== 0) return hi;\n do {\n const mid = (lo + hi) >>> 1;\n if (compare2(a[mid], x) < 0) lo = mid + 1;\n else hi = mid;\n } while (lo < hi);\n }\n return lo;\n }\n\n function right(a, x, lo = 0, hi = a.length) {\n if (lo < hi) {\n if (compare1(x, x) !== 0) return hi;\n do {\n const mid = (lo + hi) >>> 1;\n if (compare2(a[mid], x) <= 0) lo = mid + 1;\n else hi = mid;\n } while (lo < hi);\n }\n return lo;\n }\n\n function center(a, x, lo = 0, hi = a.length) {\n const i = left(a, x, lo, hi - 1);\n return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i;\n }\n\n return {left, center, right};\n}\n\nfunction zero() {\n return 0;\n}\n","export default function number(x) {\n return x === null ? NaN : +x;\n}\n\nexport function* numbers(values, valueof) {\n if (valueof === undefined) {\n for (let value of values) {\n if (value != null && (value = +value) >= value) {\n yield value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null && (value = +value) >= value) {\n yield value;\n }\n }\n }\n}\n","import ascending from \"./ascending.js\";\nimport bisector from \"./bisector.js\";\nimport number from \"./number.js\";\n\nconst ascendingBisect = bisector(ascending);\nexport const bisectRight = ascendingBisect.right;\nexport const bisectLeft = ascendingBisect.left;\nexport const bisectCenter = bisector(number).center;\nexport default bisectRight;\n","export default function extent(values, valueof) {\n let min;\n let max;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null) {\n if (min === undefined) {\n if (value >= value) min = max = value;\n } else {\n if (min > value) min = value;\n if (max < value) max = value;\n }\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null) {\n if (min === undefined) {\n if (value >= value) min = max = value;\n } else {\n if (min > value) min = value;\n if (max < value) max = value;\n }\n }\n }\n }\n return [min, max];\n}\n","export class InternMap extends Map {\n constructor(entries, key = keyof) {\n super();\n Object.defineProperties(this, {_intern: {value: new Map()}, _key: {value: key}});\n if (entries != null) for (const [key, value] of entries) this.set(key, value);\n }\n get(key) {\n return super.get(intern_get(this, key));\n }\n has(key) {\n return super.has(intern_get(this, key));\n }\n set(key, value) {\n return super.set(intern_set(this, key), value);\n }\n delete(key) {\n return super.delete(intern_delete(this, key));\n }\n}\n\nexport class InternSet extends Set {\n constructor(values, key = keyof) {\n super();\n Object.defineProperties(this, {_intern: {value: new Map()}, _key: {value: key}});\n if (values != null) for (const value of values) this.add(value);\n }\n has(value) {\n return super.has(intern_get(this, value));\n }\n add(value) {\n return super.add(intern_set(this, value));\n }\n delete(value) {\n return super.delete(intern_delete(this, value));\n }\n}\n\nfunction intern_get({_intern, _key}, value) {\n const key = _key(value);\n return _intern.has(key) ? _intern.get(key) : value;\n}\n\nfunction intern_set({_intern, _key}, value) {\n const key = _key(value);\n if (_intern.has(key)) return _intern.get(key);\n _intern.set(key, value);\n return value;\n}\n\nfunction intern_delete({_intern, _key}, value) {\n const key = _key(value);\n if (_intern.has(key)) {\n value = _intern.get(key);\n _intern.delete(key);\n }\n return value;\n}\n\nfunction keyof(value) {\n return value !== null && typeof value === \"object\" ? value.valueOf() : value;\n}\n","const e10 = Math.sqrt(50),\n e5 = Math.sqrt(10),\n e2 = Math.sqrt(2);\n\nfunction tickSpec(start, stop, count) {\n const step = (stop - start) / Math.max(0, count),\n power = Math.floor(Math.log10(step)),\n error = step / Math.pow(10, power),\n factor = error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1;\n let i1, i2, inc;\n if (power < 0) {\n inc = Math.pow(10, -power) / factor;\n i1 = Math.round(start * inc);\n i2 = Math.round(stop * inc);\n if (i1 / inc < start) ++i1;\n if (i2 / inc > stop) --i2;\n inc = -inc;\n } else {\n inc = Math.pow(10, power) * factor;\n i1 = Math.round(start / inc);\n i2 = Math.round(stop / inc);\n if (i1 * inc < start) ++i1;\n if (i2 * inc > stop) --i2;\n }\n if (i2 < i1 && 0.5 <= count && count < 2) return tickSpec(start, stop, count * 2);\n return [i1, i2, inc];\n}\n\nexport default function ticks(start, stop, count) {\n stop = +stop, start = +start, count = +count;\n if (!(count > 0)) return [];\n if (start === stop) return [start];\n const reverse = stop < start, [i1, i2, inc] = reverse ? tickSpec(stop, start, count) : tickSpec(start, stop, count);\n if (!(i2 >= i1)) return [];\n const n = i2 - i1 + 1, ticks = new Array(n);\n if (reverse) {\n if (inc < 0) for (let i = 0; i < n; ++i) ticks[i] = (i2 - i) / -inc;\n else for (let i = 0; i < n; ++i) ticks[i] = (i2 - i) * inc;\n } else {\n if (inc < 0) for (let i = 0; i < n; ++i) ticks[i] = (i1 + i) / -inc;\n else for (let i = 0; i < n; ++i) ticks[i] = (i1 + i) * inc;\n }\n return ticks;\n}\n\nexport function tickIncrement(start, stop, count) {\n stop = +stop, start = +start, count = +count;\n return tickSpec(start, stop, count)[2];\n}\n\nexport function tickStep(start, stop, count) {\n stop = +stop, start = +start, count = +count;\n const reverse = stop < start, inc = reverse ? tickIncrement(stop, start, count) : tickIncrement(start, stop, count);\n return (reverse ? -1 : 1) * (inc < 0 ? 1 / -inc : inc);\n}\n","export default function max(values, valueof) {\n let max;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n }\n return max;\n}\n","export default function min(values, valueof) {\n let min;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n }\n return min;\n}\n","import max from \"./max.js\";\nimport maxIndex from \"./maxIndex.js\";\nimport min from \"./min.js\";\nimport minIndex from \"./minIndex.js\";\nimport quickselect from \"./quickselect.js\";\nimport number, {numbers} from \"./number.js\";\nimport {ascendingDefined} from \"./sort.js\";\nimport greatest from \"./greatest.js\";\n\nexport default function quantile(values, p, valueof) {\n values = Float64Array.from(numbers(values, valueof));\n if (!(n = values.length) || isNaN(p = +p)) return;\n if (p <= 0 || n < 2) return min(values);\n if (p >= 1) return max(values);\n var n,\n i = (n - 1) * p,\n i0 = Math.floor(i),\n value0 = max(quickselect(values, i0).subarray(0, i0 + 1)),\n value1 = min(values.subarray(i0 + 1));\n return value0 + (value1 - value0) * (i - i0);\n}\n\nexport function quantileSorted(values, p, valueof = number) {\n if (!(n = values.length) || isNaN(p = +p)) return;\n if (p <= 0 || n < 2) return +valueof(values[0], 0, values);\n if (p >= 1) return +valueof(values[n - 1], n - 1, values);\n var n,\n i = (n - 1) * p,\n i0 = Math.floor(i),\n value0 = +valueof(values[i0], i0, values),\n value1 = +valueof(values[i0 + 1], i0 + 1, values);\n return value0 + (value1 - value0) * (i - i0);\n}\n\nexport function quantileIndex(values, p, valueof = number) {\n if (isNaN(p = +p)) return;\n numbers = Float64Array.from(values, (_, i) => number(valueof(values[i], i, values)));\n if (p <= 0) return minIndex(numbers);\n if (p >= 1) return maxIndex(numbers);\n var numbers,\n index = Uint32Array.from(values, (_, i) => i),\n j = numbers.length - 1,\n i = Math.floor(j * p);\n quickselect(index, i, 0, j, (i, j) => ascendingDefined(numbers[i], numbers[j]));\n i = greatest(index.subarray(0, i + 1), (i) => numbers[i]);\n return i >= 0 ? i : -1;\n}\n","export default function range(start, stop, step) {\n start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;\n\n var i = -1,\n n = Math.max(0, Math.ceil((stop - start) / step)) | 0,\n range = new Array(n);\n\n while (++i < n) {\n range[i] = start + i * step;\n }\n\n return range;\n}\n","export function initRange(domain, range) {\n switch (arguments.length) {\n case 0: break;\n case 1: this.range(domain); break;\n default: this.range(range).domain(domain); break;\n }\n return this;\n}\n\nexport function initInterpolator(domain, interpolator) {\n switch (arguments.length) {\n case 0: break;\n case 1: {\n if (typeof domain === \"function\") this.interpolator(domain);\n else this.range(domain);\n break;\n }\n default: {\n this.domain(domain);\n if (typeof interpolator === \"function\") this.interpolator(interpolator);\n else this.range(interpolator);\n break;\n }\n }\n return this;\n}\n","import {InternMap} from \"d3-array\";\nimport {initRange} from \"./init.js\";\n\nexport const implicit = Symbol(\"implicit\");\n\nexport default function ordinal() {\n var index = new InternMap(),\n domain = [],\n range = [],\n unknown = implicit;\n\n function scale(d) {\n let i = index.get(d);\n if (i === undefined) {\n if (unknown !== implicit) return unknown;\n index.set(d, i = domain.push(d) - 1);\n }\n return range[i % range.length];\n }\n\n scale.domain = function(_) {\n if (!arguments.length) return domain.slice();\n domain = [], index = new InternMap();\n for (const value of _) {\n if (index.has(value)) continue;\n index.set(value, domain.push(value) - 1);\n }\n return scale;\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = Array.from(_), scale) : range.slice();\n };\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n scale.copy = function() {\n return ordinal(domain, range).unknown(unknown);\n };\n\n initRange.apply(scale, arguments);\n\n return scale;\n}\n","import {range as sequence} from \"d3-array\";\nimport {initRange} from \"./init.js\";\nimport ordinal from \"./ordinal.js\";\n\nexport default function band() {\n var scale = ordinal().unknown(undefined),\n domain = scale.domain,\n ordinalRange = scale.range,\n r0 = 0,\n r1 = 1,\n step,\n bandwidth,\n round = false,\n paddingInner = 0,\n paddingOuter = 0,\n align = 0.5;\n\n delete scale.unknown;\n\n function rescale() {\n var n = domain().length,\n reverse = r1 < r0,\n start = reverse ? r1 : r0,\n stop = reverse ? r0 : r1;\n step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);\n if (round) step = Math.floor(step);\n start += (stop - start - step * (n - paddingInner)) * align;\n bandwidth = step * (1 - paddingInner);\n if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);\n var values = sequence(n).map(function(i) { return start + step * i; });\n return ordinalRange(reverse ? values.reverse() : values);\n }\n\n scale.domain = function(_) {\n return arguments.length ? (domain(_), rescale()) : domain();\n };\n\n scale.range = function(_) {\n return arguments.length ? ([r0, r1] = _, r0 = +r0, r1 = +r1, rescale()) : [r0, r1];\n };\n\n scale.rangeRound = function(_) {\n return [r0, r1] = _, r0 = +r0, r1 = +r1, round = true, rescale();\n };\n\n scale.bandwidth = function() {\n return bandwidth;\n };\n\n scale.step = function() {\n return step;\n };\n\n scale.round = function(_) {\n return arguments.length ? (round = !!_, rescale()) : round;\n };\n\n scale.padding = function(_) {\n return arguments.length ? (paddingInner = Math.min(1, paddingOuter = +_), rescale()) : paddingInner;\n };\n\n scale.paddingInner = function(_) {\n return arguments.length ? (paddingInner = Math.min(1, _), rescale()) : paddingInner;\n };\n\n scale.paddingOuter = function(_) {\n return arguments.length ? (paddingOuter = +_, rescale()) : paddingOuter;\n };\n\n scale.align = function(_) {\n return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;\n };\n\n scale.copy = function() {\n return band(domain(), [r0, r1])\n .round(round)\n .paddingInner(paddingInner)\n .paddingOuter(paddingOuter)\n .align(align);\n };\n\n return initRange.apply(rescale(), arguments);\n}\n\nfunction pointish(scale) {\n var copy = scale.copy;\n\n scale.padding = scale.paddingOuter;\n delete scale.paddingInner;\n delete scale.paddingOuter;\n\n scale.copy = function() {\n return pointish(copy());\n };\n\n return scale;\n}\n\nexport function point() {\n return pointish(band.apply(null, arguments).paddingInner(1));\n}\n","export default function(constructor, factory, prototype) {\n constructor.prototype = factory.prototype = prototype;\n prototype.constructor = constructor;\n}\n\nexport function extend(parent, definition) {\n var prototype = Object.create(parent.prototype);\n for (var key in definition) prototype[key] = definition[key];\n return prototype;\n}\n","import define, {extend} from \"./define.js\";\n\nexport function Color() {}\n\nexport var darker = 0.7;\nexport var brighter = 1 / darker;\n\nvar reI = \"\\\\s*([+-]?\\\\d+)\\\\s*\",\n reN = \"\\\\s*([+-]?(?:\\\\d*\\\\.)?\\\\d+(?:[eE][+-]?\\\\d+)?)\\\\s*\",\n reP = \"\\\\s*([+-]?(?:\\\\d*\\\\.)?\\\\d+(?:[eE][+-]?\\\\d+)?)%\\\\s*\",\n reHex = /^#([0-9a-f]{3,8})$/,\n reRgbInteger = new RegExp(`^rgb\\\\(${reI},${reI},${reI}\\\\)$`),\n reRgbPercent = new RegExp(`^rgb\\\\(${reP},${reP},${reP}\\\\)$`),\n reRgbaInteger = new RegExp(`^rgba\\\\(${reI},${reI},${reI},${reN}\\\\)$`),\n reRgbaPercent = new RegExp(`^rgba\\\\(${reP},${reP},${reP},${reN}\\\\)$`),\n reHslPercent = new RegExp(`^hsl\\\\(${reN},${reP},${reP}\\\\)$`),\n reHslaPercent = new RegExp(`^hsla\\\\(${reN},${reP},${reP},${reN}\\\\)$`);\n\nvar named = {\n aliceblue: 0xf0f8ff,\n antiquewhite: 0xfaebd7,\n aqua: 0x00ffff,\n aquamarine: 0x7fffd4,\n azure: 0xf0ffff,\n beige: 0xf5f5dc,\n bisque: 0xffe4c4,\n black: 0x000000,\n blanchedalmond: 0xffebcd,\n blue: 0x0000ff,\n blueviolet: 0x8a2be2,\n brown: 0xa52a2a,\n burlywood: 0xdeb887,\n cadetblue: 0x5f9ea0,\n chartreuse: 0x7fff00,\n chocolate: 0xd2691e,\n coral: 0xff7f50,\n cornflowerblue: 0x6495ed,\n cornsilk: 0xfff8dc,\n crimson: 0xdc143c,\n cyan: 0x00ffff,\n darkblue: 0x00008b,\n darkcyan: 0x008b8b,\n darkgoldenrod: 0xb8860b,\n darkgray: 0xa9a9a9,\n darkgreen: 0x006400,\n darkgrey: 0xa9a9a9,\n darkkhaki: 0xbdb76b,\n darkmagenta: 0x8b008b,\n darkolivegreen: 0x556b2f,\n darkorange: 0xff8c00,\n darkorchid: 0x9932cc,\n darkred: 0x8b0000,\n darksalmon: 0xe9967a,\n darkseagreen: 0x8fbc8f,\n darkslateblue: 0x483d8b,\n darkslategray: 0x2f4f4f,\n darkslategrey: 0x2f4f4f,\n darkturquoise: 0x00ced1,\n darkviolet: 0x9400d3,\n deeppink: 0xff1493,\n deepskyblue: 0x00bfff,\n dimgray: 0x696969,\n dimgrey: 0x696969,\n dodgerblue: 0x1e90ff,\n firebrick: 0xb22222,\n floralwhite: 0xfffaf0,\n forestgreen: 0x228b22,\n fuchsia: 0xff00ff,\n gainsboro: 0xdcdcdc,\n ghostwhite: 0xf8f8ff,\n gold: 0xffd700,\n goldenrod: 0xdaa520,\n gray: 0x808080,\n green: 0x008000,\n greenyellow: 0xadff2f,\n grey: 0x808080,\n honeydew: 0xf0fff0,\n hotpink: 0xff69b4,\n indianred: 0xcd5c5c,\n indigo: 0x4b0082,\n ivory: 0xfffff0,\n khaki: 0xf0e68c,\n lavender: 0xe6e6fa,\n lavenderblush: 0xfff0f5,\n lawngreen: 0x7cfc00,\n lemonchiffon: 0xfffacd,\n lightblue: 0xadd8e6,\n lightcoral: 0xf08080,\n lightcyan: 0xe0ffff,\n lightgoldenrodyellow: 0xfafad2,\n lightgray: 0xd3d3d3,\n lightgreen: 0x90ee90,\n lightgrey: 0xd3d3d3,\n lightpink: 0xffb6c1,\n lightsalmon: 0xffa07a,\n lightseagreen: 0x20b2aa,\n lightskyblue: 0x87cefa,\n lightslategray: 0x778899,\n lightslategrey: 0x778899,\n lightsteelblue: 0xb0c4de,\n lightyellow: 0xffffe0,\n lime: 0x00ff00,\n limegreen: 0x32cd32,\n linen: 0xfaf0e6,\n magenta: 0xff00ff,\n maroon: 0x800000,\n mediumaquamarine: 0x66cdaa,\n mediumblue: 0x0000cd,\n mediumorchid: 0xba55d3,\n mediumpurple: 0x9370db,\n mediumseagreen: 0x3cb371,\n mediumslateblue: 0x7b68ee,\n mediumspringgreen: 0x00fa9a,\n mediumturquoise: 0x48d1cc,\n mediumvioletred: 0xc71585,\n midnightblue: 0x191970,\n mintcream: 0xf5fffa,\n mistyrose: 0xffe4e1,\n moccasin: 0xffe4b5,\n navajowhite: 0xffdead,\n navy: 0x000080,\n oldlace: 0xfdf5e6,\n olive: 0x808000,\n olivedrab: 0x6b8e23,\n orange: 0xffa500,\n orangered: 0xff4500,\n orchid: 0xda70d6,\n palegoldenrod: 0xeee8aa,\n palegreen: 0x98fb98,\n paleturquoise: 0xafeeee,\n palevioletred: 0xdb7093,\n papayawhip: 0xffefd5,\n peachpuff: 0xffdab9,\n peru: 0xcd853f,\n pink: 0xffc0cb,\n plum: 0xdda0dd,\n powderblue: 0xb0e0e6,\n purple: 0x800080,\n rebeccapurple: 0x663399,\n red: 0xff0000,\n rosybrown: 0xbc8f8f,\n royalblue: 0x4169e1,\n saddlebrown: 0x8b4513,\n salmon: 0xfa8072,\n sandybrown: 0xf4a460,\n seagreen: 0x2e8b57,\n seashell: 0xfff5ee,\n sienna: 0xa0522d,\n silver: 0xc0c0c0,\n skyblue: 0x87ceeb,\n slateblue: 0x6a5acd,\n slategray: 0x708090,\n slategrey: 0x708090,\n snow: 0xfffafa,\n springgreen: 0x00ff7f,\n steelblue: 0x4682b4,\n tan: 0xd2b48c,\n teal: 0x008080,\n thistle: 0xd8bfd8,\n tomato: 0xff6347,\n turquoise: 0x40e0d0,\n violet: 0xee82ee,\n wheat: 0xf5deb3,\n white: 0xffffff,\n whitesmoke: 0xf5f5f5,\n yellow: 0xffff00,\n yellowgreen: 0x9acd32\n};\n\ndefine(Color, color, {\n copy(channels) {\n return Object.assign(new this.constructor, this, channels);\n },\n displayable() {\n return this.rgb().displayable();\n },\n hex: color_formatHex, // Deprecated! Use color.formatHex.\n formatHex: color_formatHex,\n formatHex8: color_formatHex8,\n formatHsl: color_formatHsl,\n formatRgb: color_formatRgb,\n toString: color_formatRgb\n});\n\nfunction color_formatHex() {\n return this.rgb().formatHex();\n}\n\nfunction color_formatHex8() {\n return this.rgb().formatHex8();\n}\n\nfunction color_formatHsl() {\n return hslConvert(this).formatHsl();\n}\n\nfunction color_formatRgb() {\n return this.rgb().formatRgb();\n}\n\nexport default function color(format) {\n var m, l;\n format = (format + \"\").trim().toLowerCase();\n return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000\n : l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00\n : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000\n : l === 4 ? rgba((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000\n : null) // invalid hex\n : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)\n : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)\n : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)\n : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)\n : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)\n : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)\n : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins\n : format === \"transparent\" ? new Rgb(NaN, NaN, NaN, 0)\n : null;\n}\n\nfunction rgbn(n) {\n return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);\n}\n\nfunction rgba(r, g, b, a) {\n if (a <= 0) r = g = b = NaN;\n return new Rgb(r, g, b, a);\n}\n\nexport function rgbConvert(o) {\n if (!(o instanceof Color)) o = color(o);\n if (!o) return new Rgb;\n o = o.rgb();\n return new Rgb(o.r, o.g, o.b, o.opacity);\n}\n\nexport function rgb(r, g, b, opacity) {\n return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);\n}\n\nexport function Rgb(r, g, b, opacity) {\n this.r = +r;\n this.g = +g;\n this.b = +b;\n this.opacity = +opacity;\n}\n\ndefine(Rgb, rgb, extend(Color, {\n brighter(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n },\n darker(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n },\n rgb() {\n return this;\n },\n clamp() {\n return new Rgb(clampi(this.r), clampi(this.g), clampi(this.b), clampa(this.opacity));\n },\n displayable() {\n return (-0.5 <= this.r && this.r < 255.5)\n && (-0.5 <= this.g && this.g < 255.5)\n && (-0.5 <= this.b && this.b < 255.5)\n && (0 <= this.opacity && this.opacity <= 1);\n },\n hex: rgb_formatHex, // Deprecated! Use color.formatHex.\n formatHex: rgb_formatHex,\n formatHex8: rgb_formatHex8,\n formatRgb: rgb_formatRgb,\n toString: rgb_formatRgb\n}));\n\nfunction rgb_formatHex() {\n return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}`;\n}\n\nfunction rgb_formatHex8() {\n return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}${hex((isNaN(this.opacity) ? 1 : this.opacity) * 255)}`;\n}\n\nfunction rgb_formatRgb() {\n const a = clampa(this.opacity);\n return `${a === 1 ? \"rgb(\" : \"rgba(\"}${clampi(this.r)}, ${clampi(this.g)}, ${clampi(this.b)}${a === 1 ? \")\" : `, ${a})`}`;\n}\n\nfunction clampa(opacity) {\n return isNaN(opacity) ? 1 : Math.max(0, Math.min(1, opacity));\n}\n\nfunction clampi(value) {\n return Math.max(0, Math.min(255, Math.round(value) || 0));\n}\n\nfunction hex(value) {\n value = clampi(value);\n return (value < 16 ? \"0\" : \"\") + value.toString(16);\n}\n\nfunction hsla(h, s, l, a) {\n if (a <= 0) h = s = l = NaN;\n else if (l <= 0 || l >= 1) h = s = NaN;\n else if (s <= 0) h = NaN;\n return new Hsl(h, s, l, a);\n}\n\nexport function hslConvert(o) {\n if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);\n if (!(o instanceof Color)) o = color(o);\n if (!o) return new Hsl;\n if (o instanceof Hsl) return o;\n o = o.rgb();\n var r = o.r / 255,\n g = o.g / 255,\n b = o.b / 255,\n min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n h = NaN,\n s = max - min,\n l = (max + min) / 2;\n if (s) {\n if (r === max) h = (g - b) / s + (g < b) * 6;\n else if (g === max) h = (b - r) / s + 2;\n else h = (r - g) / s + 4;\n s /= l < 0.5 ? max + min : 2 - max - min;\n h *= 60;\n } else {\n s = l > 0 && l < 1 ? 0 : h;\n }\n return new Hsl(h, s, l, o.opacity);\n}\n\nexport function hsl(h, s, l, opacity) {\n return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);\n}\n\nfunction Hsl(h, s, l, opacity) {\n this.h = +h;\n this.s = +s;\n this.l = +l;\n this.opacity = +opacity;\n}\n\ndefine(Hsl, hsl, extend(Color, {\n brighter(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Hsl(this.h, this.s, this.l * k, this.opacity);\n },\n darker(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Hsl(this.h, this.s, this.l * k, this.opacity);\n },\n rgb() {\n var h = this.h % 360 + (this.h < 0) * 360,\n s = isNaN(h) || isNaN(this.s) ? 0 : this.s,\n l = this.l,\n m2 = l + (l < 0.5 ? l : 1 - l) * s,\n m1 = 2 * l - m2;\n return new Rgb(\n hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),\n hsl2rgb(h, m1, m2),\n hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),\n this.opacity\n );\n },\n clamp() {\n return new Hsl(clamph(this.h), clampt(this.s), clampt(this.l), clampa(this.opacity));\n },\n displayable() {\n return (0 <= this.s && this.s <= 1 || isNaN(this.s))\n && (0 <= this.l && this.l <= 1)\n && (0 <= this.opacity && this.opacity <= 1);\n },\n formatHsl() {\n const a = clampa(this.opacity);\n return `${a === 1 ? \"hsl(\" : \"hsla(\"}${clamph(this.h)}, ${clampt(this.s) * 100}%, ${clampt(this.l) * 100}%${a === 1 ? \")\" : `, ${a})`}`;\n }\n}));\n\nfunction clamph(value) {\n value = (value || 0) % 360;\n return value < 0 ? value + 360 : value;\n}\n\nfunction clampt(value) {\n return Math.max(0, Math.min(1, value || 0));\n}\n\n/* From FvD 13.37, CSS Color Module Level 3 */\nfunction hsl2rgb(h, m1, m2) {\n return (h < 60 ? m1 + (m2 - m1) * h / 60\n : h < 180 ? m2\n : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60\n : m1) * 255;\n}\n","export function basis(t1, v0, v1, v2, v3) {\n var t2 = t1 * t1, t3 = t2 * t1;\n return ((1 - 3 * t1 + 3 * t2 - t3) * v0\n + (4 - 6 * t2 + 3 * t3) * v1\n + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2\n + t3 * v3) / 6;\n}\n\nexport default function(values) {\n var n = values.length - 1;\n return function(t) {\n var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),\n v1 = values[i],\n v2 = values[i + 1],\n v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,\n v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;\n return basis((t - i / n) * n, v0, v1, v2, v3);\n };\n}\n","import {basis} from \"./basis.js\";\n\nexport default function(values) {\n var n = values.length;\n return function(t) {\n var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),\n v0 = values[(i + n - 1) % n],\n v1 = values[i % n],\n v2 = values[(i + 1) % n],\n v3 = values[(i + 2) % n];\n return basis((t - i / n) * n, v0, v1, v2, v3);\n };\n}\n","export default x => () => x;\n","import constant from \"./constant.js\";\n\nfunction linear(a, d) {\n return function(t) {\n return a + t * d;\n };\n}\n\nfunction exponential(a, b, y) {\n return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {\n return Math.pow(a + t * b, y);\n };\n}\n\nexport function hue(a, b) {\n var d = b - a;\n return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant(isNaN(a) ? b : a);\n}\n\nexport function gamma(y) {\n return (y = +y) === 1 ? nogamma : function(a, b) {\n return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a);\n };\n}\n\nexport default function nogamma(a, b) {\n var d = b - a;\n return d ? linear(a, d) : constant(isNaN(a) ? b : a);\n}\n","import {rgb as colorRgb} from \"d3-color\";\nimport basis from \"./basis.js\";\nimport basisClosed from \"./basisClosed.js\";\nimport nogamma, {gamma} from \"./color.js\";\n\nexport default (function rgbGamma(y) {\n var color = gamma(y);\n\n function rgb(start, end) {\n var r = color((start = colorRgb(start)).r, (end = colorRgb(end)).r),\n g = color(start.g, end.g),\n b = color(start.b, end.b),\n opacity = nogamma(start.opacity, end.opacity);\n return function(t) {\n start.r = r(t);\n start.g = g(t);\n start.b = b(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n\n rgb.gamma = rgbGamma;\n\n return rgb;\n})(1);\n\nfunction rgbSpline(spline) {\n return function(colors) {\n var n = colors.length,\n r = new Array(n),\n g = new Array(n),\n b = new Array(n),\n i, color;\n for (i = 0; i < n; ++i) {\n color = colorRgb(colors[i]);\n r[i] = color.r || 0;\n g[i] = color.g || 0;\n b[i] = color.b || 0;\n }\n r = spline(r);\n g = spline(g);\n b = spline(b);\n color.opacity = 1;\n return function(t) {\n color.r = r(t);\n color.g = g(t);\n color.b = b(t);\n return color + \"\";\n };\n };\n}\n\nexport var rgbBasis = rgbSpline(basis);\nexport var rgbBasisClosed = rgbSpline(basisClosed);\n","export default function(a, b) {\n if (!b) b = [];\n var n = a ? Math.min(b.length, a.length) : 0,\n c = b.slice(),\n i;\n return function(t) {\n for (i = 0; i < n; ++i) c[i] = a[i] * (1 - t) + b[i] * t;\n return c;\n };\n}\n\nexport function isNumberArray(x) {\n return ArrayBuffer.isView(x) && !(x instanceof DataView);\n}\n","import value from \"./value.js\";\nimport numberArray, {isNumberArray} from \"./numberArray.js\";\n\nexport default function(a, b) {\n return (isNumberArray(b) ? numberArray : genericArray)(a, b);\n}\n\nexport function genericArray(a, b) {\n var nb = b ? b.length : 0,\n na = a ? Math.min(nb, a.length) : 0,\n x = new Array(na),\n c = new Array(nb),\n i;\n\n for (i = 0; i < na; ++i) x[i] = value(a[i], b[i]);\n for (; i < nb; ++i) c[i] = b[i];\n\n return function(t) {\n for (i = 0; i < na; ++i) c[i] = x[i](t);\n return c;\n };\n}\n","export default function(a, b) {\n var d = new Date;\n return a = +a, b = +b, function(t) {\n return d.setTime(a * (1 - t) + b * t), d;\n };\n}\n","export default function(a, b) {\n return a = +a, b = +b, function(t) {\n return a * (1 - t) + b * t;\n };\n}\n","import value from \"./value.js\";\n\nexport default function(a, b) {\n var i = {},\n c = {},\n k;\n\n if (a === null || typeof a !== \"object\") a = {};\n if (b === null || typeof b !== \"object\") b = {};\n\n for (k in b) {\n if (k in a) {\n i[k] = value(a[k], b[k]);\n } else {\n c[k] = b[k];\n }\n }\n\n return function(t) {\n for (k in i) c[k] = i[k](t);\n return c;\n };\n}\n","import number from \"./number.js\";\n\nvar reA = /[-+]?(?:\\d+\\.?\\d*|\\.?\\d+)(?:[eE][-+]?\\d+)?/g,\n reB = new RegExp(reA.source, \"g\");\n\nfunction zero(b) {\n return function() {\n return b;\n };\n}\n\nfunction one(b) {\n return function(t) {\n return b(t) + \"\";\n };\n}\n\nexport default function(a, b) {\n var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b\n am, // current match in a\n bm, // current match in b\n bs, // string preceding current number in b, if any\n i = -1, // index in s\n s = [], // string constants and placeholders\n q = []; // number interpolators\n\n // Coerce inputs to strings.\n a = a + \"\", b = b + \"\";\n\n // Interpolate pairs of numbers in a & b.\n while ((am = reA.exec(a))\n && (bm = reB.exec(b))) {\n if ((bs = bm.index) > bi) { // a string precedes the next number in b\n bs = b.slice(bi, bs);\n if (s[i]) s[i] += bs; // coalesce with previous string\n else s[++i] = bs;\n }\n if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match\n if (s[i]) s[i] += bm; // coalesce with previous string\n else s[++i] = bm;\n } else { // interpolate non-matching numbers\n s[++i] = null;\n q.push({i: i, x: number(am, bm)});\n }\n bi = reB.lastIndex;\n }\n\n // Add remains of b.\n if (bi < b.length) {\n bs = b.slice(bi);\n if (s[i]) s[i] += bs; // coalesce with previous string\n else s[++i] = bs;\n }\n\n // Special optimization for only a single match.\n // Otherwise, interpolate each of the numbers and rejoin the string.\n return s.length < 2 ? (q[0]\n ? one(q[0].x)\n : zero(b))\n : (b = q.length, function(t) {\n for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);\n return s.join(\"\");\n });\n}\n","import {color} from \"d3-color\";\nimport rgb from \"./rgb.js\";\nimport {genericArray} from \"./array.js\";\nimport date from \"./date.js\";\nimport number from \"./number.js\";\nimport object from \"./object.js\";\nimport string from \"./string.js\";\nimport constant from \"./constant.js\";\nimport numberArray, {isNumberArray} from \"./numberArray.js\";\n\nexport default function(a, b) {\n var t = typeof b, c;\n return b == null || t === \"boolean\" ? constant(b)\n : (t === \"number\" ? number\n : t === \"string\" ? ((c = color(b)) ? (b = c, rgb) : string)\n : b instanceof color ? rgb\n : b instanceof Date ? date\n : isNumberArray(b) ? numberArray\n : Array.isArray(b) ? genericArray\n : typeof b.valueOf !== \"function\" && typeof b.toString !== \"function\" || isNaN(b) ? object\n : number)(a, b);\n}\n","export default function(a, b) {\n return a = +a, b = +b, function(t) {\n return Math.round(a * (1 - t) + b * t);\n };\n}\n","export default function constants(x) {\n return function() {\n return x;\n };\n}\n","export default function number(x) {\n return +x;\n}\n","import {bisect} from \"d3-array\";\nimport {interpolate as interpolateValue, interpolateNumber, interpolateRound} from \"d3-interpolate\";\nimport constant from \"./constant.js\";\nimport number from \"./number.js\";\n\nvar unit = [0, 1];\n\nexport function identity(x) {\n return x;\n}\n\nfunction normalize(a, b) {\n return (b -= (a = +a))\n ? function(x) { return (x - a) / b; }\n : constant(isNaN(b) ? NaN : 0.5);\n}\n\nfunction clamper(a, b) {\n var t;\n if (a > b) t = a, a = b, b = t;\n return function(x) { return Math.max(a, Math.min(b, x)); };\n}\n\n// normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].\n// interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b].\nfunction bimap(domain, range, interpolate) {\n var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1];\n if (d1 < d0) d0 = normalize(d1, d0), r0 = interpolate(r1, r0);\n else d0 = normalize(d0, d1), r0 = interpolate(r0, r1);\n return function(x) { return r0(d0(x)); };\n}\n\nfunction polymap(domain, range, interpolate) {\n var j = Math.min(domain.length, range.length) - 1,\n d = new Array(j),\n r = new Array(j),\n i = -1;\n\n // Reverse descending domains.\n if (domain[j] < domain[0]) {\n domain = domain.slice().reverse();\n range = range.slice().reverse();\n }\n\n while (++i < j) {\n d[i] = normalize(domain[i], domain[i + 1]);\n r[i] = interpolate(range[i], range[i + 1]);\n }\n\n return function(x) {\n var i = bisect(domain, x, 1, j) - 1;\n return r[i](d[i](x));\n };\n}\n\nexport function copy(source, target) {\n return target\n .domain(source.domain())\n .range(source.range())\n .interpolate(source.interpolate())\n .clamp(source.clamp())\n .unknown(source.unknown());\n}\n\nexport function transformer() {\n var domain = unit,\n range = unit,\n interpolate = interpolateValue,\n transform,\n untransform,\n unknown,\n clamp = identity,\n piecewise,\n output,\n input;\n\n function rescale() {\n var n = Math.min(domain.length, range.length);\n if (clamp !== identity) clamp = clamper(domain[0], domain[n - 1]);\n piecewise = n > 2 ? polymap : bimap;\n output = input = null;\n return scale;\n }\n\n function scale(x) {\n return x == null || isNaN(x = +x) ? unknown : (output || (output = piecewise(domain.map(transform), range, interpolate)))(transform(clamp(x)));\n }\n\n scale.invert = function(y) {\n return clamp(untransform((input || (input = piecewise(range, domain.map(transform), interpolateNumber)))(y)));\n };\n\n scale.domain = function(_) {\n return arguments.length ? (domain = Array.from(_, number), rescale()) : domain.slice();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = Array.from(_), rescale()) : range.slice();\n };\n\n scale.rangeRound = function(_) {\n return range = Array.from(_), interpolate = interpolateRound, rescale();\n };\n\n scale.clamp = function(_) {\n return arguments.length ? (clamp = _ ? true : identity, rescale()) : clamp !== identity;\n };\n\n scale.interpolate = function(_) {\n return arguments.length ? (interpolate = _, rescale()) : interpolate;\n };\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n return function(t, u) {\n transform = t, untransform = u;\n return rescale();\n };\n}\n\nexport default function continuous() {\n return transformer()(identity, identity);\n}\n","export default function(x) {\n return Math.abs(x = Math.round(x)) >= 1e21\n ? x.toLocaleString(\"en\").replace(/,/g, \"\")\n : x.toString(10);\n}\n\n// Computes the decimal coefficient and exponent of the specified number x with\n// significant digits p, where x is positive and p is in [1, 21] or undefined.\n// For example, formatDecimalParts(1.23) returns [\"123\", 0].\nexport function formatDecimalParts(x, p) {\n if (!isFinite(x) || x === 0) return null; // NaN, ±Infinity, ±0\n var i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf(\"e\"), coefficient = x.slice(0, i);\n\n // The string returned by toExponential either has the form \\d\\.\\d+e[-+]\\d+\n // (e.g., 1.2e+3) or the form \\de[-+]\\d+ (e.g., 1e+3).\n return [\n coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,\n +x.slice(i + 1)\n ];\n}\n","import {formatDecimalParts} from \"./formatDecimal.js\";\n\nexport default function(x) {\n return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN;\n}\n","export default function(grouping, thousands) {\n return function(value, width) {\n var i = value.length,\n t = [],\n j = 0,\n g = grouping[0],\n length = 0;\n\n while (i > 0 && g > 0) {\n if (length + g + 1 > width) g = Math.max(1, width - length);\n t.push(value.substring(i -= g, i + g));\n if ((length += g + 1) > width) break;\n g = grouping[j = (j + 1) % grouping.length];\n }\n\n return t.reverse().join(thousands);\n };\n}\n","export default function(numerals) {\n return function(value) {\n return value.replace(/[0-9]/g, function(i) {\n return numerals[+i];\n });\n };\n}\n","// [[fill]align][sign][symbol][0][width][,][.precision][~][type]\nvar re = /^(?:(.)?([<>=^]))?([+\\-( ])?([$#])?(0)?(\\d+)?(,)?(\\.\\d+)?(~)?([a-z%])?$/i;\n\nexport default function formatSpecifier(specifier) {\n if (!(match = re.exec(specifier))) throw new Error(\"invalid format: \" + specifier);\n var match;\n return new FormatSpecifier({\n fill: match[1],\n align: match[2],\n sign: match[3],\n symbol: match[4],\n zero: match[5],\n width: match[6],\n comma: match[7],\n precision: match[8] && match[8].slice(1),\n trim: match[9],\n type: match[10]\n });\n}\n\nformatSpecifier.prototype = FormatSpecifier.prototype; // instanceof\n\nexport function FormatSpecifier(specifier) {\n this.fill = specifier.fill === undefined ? \" \" : specifier.fill + \"\";\n this.align = specifier.align === undefined ? \">\" : specifier.align + \"\";\n this.sign = specifier.sign === undefined ? \"-\" : specifier.sign + \"\";\n this.symbol = specifier.symbol === undefined ? \"\" : specifier.symbol + \"\";\n this.zero = !!specifier.zero;\n this.width = specifier.width === undefined ? undefined : +specifier.width;\n this.comma = !!specifier.comma;\n this.precision = specifier.precision === undefined ? undefined : +specifier.precision;\n this.trim = !!specifier.trim;\n this.type = specifier.type === undefined ? \"\" : specifier.type + \"\";\n}\n\nFormatSpecifier.prototype.toString = function() {\n return this.fill\n + this.align\n + this.sign\n + this.symbol\n + (this.zero ? \"0\" : \"\")\n + (this.width === undefined ? \"\" : Math.max(1, this.width | 0))\n + (this.comma ? \",\" : \"\")\n + (this.precision === undefined ? \"\" : \".\" + Math.max(0, this.precision | 0))\n + (this.trim ? \"~\" : \"\")\n + this.type;\n};\n","// Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k.\nexport default function(s) {\n out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) {\n switch (s[i]) {\n case \".\": i0 = i1 = i; break;\n case \"0\": if (i0 === 0) i0 = i; i1 = i; break;\n default: if (!+s[i]) break out; if (i0 > 0) i0 = 0; break;\n }\n }\n return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s;\n}\n","import {formatDecimalParts} from \"./formatDecimal.js\";\n\nexport var prefixExponent;\n\nexport default function(x, p) {\n var d = formatDecimalParts(x, p);\n if (!d) return prefixExponent = undefined, x.toPrecision(p);\n var coefficient = d[0],\n exponent = d[1],\n i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,\n n = coefficient.length;\n return i === n ? coefficient\n : i > n ? coefficient + new Array(i - n + 1).join(\"0\")\n : i > 0 ? coefficient.slice(0, i) + \".\" + coefficient.slice(i)\n : \"0.\" + new Array(1 - i).join(\"0\") + formatDecimalParts(x, Math.max(0, p + i - 1))[0]; // less than 1y!\n}\n","import {formatDecimalParts} from \"./formatDecimal.js\";\n\nexport default function(x, p) {\n var d = formatDecimalParts(x, p);\n if (!d) return x + \"\";\n var coefficient = d[0],\n exponent = d[1];\n return exponent < 0 ? \"0.\" + new Array(-exponent).join(\"0\") + coefficient\n : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + \".\" + coefficient.slice(exponent + 1)\n : coefficient + new Array(exponent - coefficient.length + 2).join(\"0\");\n}\n","import formatDecimal from \"./formatDecimal.js\";\nimport formatPrefixAuto from \"./formatPrefixAuto.js\";\nimport formatRounded from \"./formatRounded.js\";\n\nexport default {\n \"%\": (x, p) => (x * 100).toFixed(p),\n \"b\": (x) => Math.round(x).toString(2),\n \"c\": (x) => x + \"\",\n \"d\": formatDecimal,\n \"e\": (x, p) => x.toExponential(p),\n \"f\": (x, p) => x.toFixed(p),\n \"g\": (x, p) => x.toPrecision(p),\n \"o\": (x) => Math.round(x).toString(8),\n \"p\": (x, p) => formatRounded(x * 100, p),\n \"r\": formatRounded,\n \"s\": formatPrefixAuto,\n \"X\": (x) => Math.round(x).toString(16).toUpperCase(),\n \"x\": (x) => Math.round(x).toString(16)\n};\n","export default function(x) {\n return x;\n}\n","import exponent from \"./exponent.js\";\nimport formatGroup from \"./formatGroup.js\";\nimport formatNumerals from \"./formatNumerals.js\";\nimport formatSpecifier from \"./formatSpecifier.js\";\nimport formatTrim from \"./formatTrim.js\";\nimport formatTypes from \"./formatTypes.js\";\nimport {prefixExponent} from \"./formatPrefixAuto.js\";\nimport identity from \"./identity.js\";\n\nvar map = Array.prototype.map,\n prefixes = [\"y\",\"z\",\"a\",\"f\",\"p\",\"n\",\"µ\",\"m\",\"\",\"k\",\"M\",\"G\",\"T\",\"P\",\"E\",\"Z\",\"Y\"];\n\nexport default function(locale) {\n var group = locale.grouping === undefined || locale.thousands === undefined ? identity : formatGroup(map.call(locale.grouping, Number), locale.thousands + \"\"),\n currencyPrefix = locale.currency === undefined ? \"\" : locale.currency[0] + \"\",\n currencySuffix = locale.currency === undefined ? \"\" : locale.currency[1] + \"\",\n decimal = locale.decimal === undefined ? \".\" : locale.decimal + \"\",\n numerals = locale.numerals === undefined ? identity : formatNumerals(map.call(locale.numerals, String)),\n percent = locale.percent === undefined ? \"%\" : locale.percent + \"\",\n minus = locale.minus === undefined ? \"−\" : locale.minus + \"\",\n nan = locale.nan === undefined ? \"NaN\" : locale.nan + \"\";\n\n function newFormat(specifier, options) {\n specifier = formatSpecifier(specifier);\n\n var fill = specifier.fill,\n align = specifier.align,\n sign = specifier.sign,\n symbol = specifier.symbol,\n zero = specifier.zero,\n width = specifier.width,\n comma = specifier.comma,\n precision = specifier.precision,\n trim = specifier.trim,\n type = specifier.type;\n\n // The \"n\" type is an alias for \",g\".\n if (type === \"n\") comma = true, type = \"g\";\n\n // The \"\" type, and any invalid type, is an alias for \".12~g\".\n else if (!formatTypes[type]) precision === undefined && (precision = 12), trim = true, type = \"g\";\n\n // If zero fill is specified, padding goes after sign and before digits.\n if (zero || (fill === \"0\" && align === \"=\")) zero = true, fill = \"0\", align = \"=\";\n\n // Compute the prefix and suffix.\n // For SI-prefix, the suffix is lazily computed.\n var prefix = (options && options.prefix !== undefined ? options.prefix : \"\") + (symbol === \"$\" ? currencyPrefix : symbol === \"#\" && /[boxX]/.test(type) ? \"0\" + type.toLowerCase() : \"\"),\n suffix = (symbol === \"$\" ? currencySuffix : /[%p]/.test(type) ? percent : \"\") + (options && options.suffix !== undefined ? options.suffix : \"\");\n\n // What format function should we use?\n // Is this an integer type?\n // Can this type generate exponential notation?\n var formatType = formatTypes[type],\n maybeSuffix = /[defgprs%]/.test(type);\n\n // Set the default precision if not specified,\n // or clamp the specified precision to the supported range.\n // For significant precision, it must be in [1, 21].\n // For fixed precision, it must be in [0, 20].\n precision = precision === undefined ? 6\n : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))\n : Math.max(0, Math.min(20, precision));\n\n function format(value) {\n var valuePrefix = prefix,\n valueSuffix = suffix,\n i, n, c;\n\n if (type === \"c\") {\n valueSuffix = formatType(value) + valueSuffix;\n value = \"\";\n } else {\n value = +value;\n\n // Determine the sign. -0 is not less than 0, but 1 / -0 is!\n var valueNegative = value < 0 || 1 / value < 0;\n\n // Perform the initial formatting.\n value = isNaN(value) ? nan : formatType(Math.abs(value), precision);\n\n // Trim insignificant zeros.\n if (trim) value = formatTrim(value);\n\n // If a negative value rounds to zero after formatting, and no explicit positive sign is requested, hide the sign.\n if (valueNegative && +value === 0 && sign !== \"+\") valueNegative = false;\n\n // Compute the prefix and suffix.\n valuePrefix = (valueNegative ? (sign === \"(\" ? sign : minus) : sign === \"-\" || sign === \"(\" ? \"\" : sign) + valuePrefix;\n valueSuffix = (type === \"s\" && !isNaN(value) && prefixExponent !== undefined ? prefixes[8 + prefixExponent / 3] : \"\") + valueSuffix + (valueNegative && sign === \"(\" ? \")\" : \"\");\n\n // Break the formatted value into the integer “value” part that can be\n // grouped, and fractional or exponential “suffix” part that is not.\n if (maybeSuffix) {\n i = -1, n = value.length;\n while (++i < n) {\n if (c = value.charCodeAt(i), 48 > c || c > 57) {\n valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;\n value = value.slice(0, i);\n break;\n }\n }\n }\n }\n\n // If the fill character is not \"0\", grouping is applied before padding.\n if (comma && !zero) value = group(value, Infinity);\n\n // Compute the padding.\n var length = valuePrefix.length + value.length + valueSuffix.length,\n padding = length < width ? new Array(width - length + 1).join(fill) : \"\";\n\n // If the fill character is \"0\", grouping is applied after padding.\n if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = \"\";\n\n // Reconstruct the final output based on the desired alignment.\n switch (align) {\n case \"<\": value = valuePrefix + value + valueSuffix + padding; break;\n case \"=\": value = valuePrefix + padding + value + valueSuffix; break;\n case \"^\": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;\n default: value = padding + valuePrefix + value + valueSuffix; break;\n }\n\n return numerals(value);\n }\n\n format.toString = function() {\n return specifier + \"\";\n };\n\n return format;\n }\n\n function formatPrefix(specifier, value) {\n var e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3,\n k = Math.pow(10, -e),\n f = newFormat((specifier = formatSpecifier(specifier), specifier.type = \"f\", specifier), {suffix: prefixes[8 + e / 3]});\n return function(value) {\n return f(k * value);\n };\n }\n\n return {\n format: newFormat,\n formatPrefix: formatPrefix\n };\n}\n","import formatLocale from \"./locale.js\";\n\nvar locale;\nexport var format;\nexport var formatPrefix;\n\ndefaultLocale({\n thousands: \",\",\n grouping: [3],\n currency: [\"$\", \"\"]\n});\n\nexport default function defaultLocale(definition) {\n locale = formatLocale(definition);\n format = locale.format;\n formatPrefix = locale.formatPrefix;\n return locale;\n}\n","import exponent from \"./exponent.js\";\n\nexport default function(step) {\n return Math.max(0, -exponent(Math.abs(step)));\n}\n","import exponent from \"./exponent.js\";\n\nexport default function(step, value) {\n return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step)));\n}\n","import exponent from \"./exponent.js\";\n\nexport default function(step, max) {\n step = Math.abs(step), max = Math.abs(max) - step;\n return Math.max(0, exponent(max) - exponent(step)) + 1;\n}\n","import {tickStep} from \"d3-array\";\nimport {format, formatPrefix, formatSpecifier, precisionFixed, precisionPrefix, precisionRound} from \"d3-format\";\n\nexport default function tickFormat(start, stop, count, specifier) {\n var step = tickStep(start, stop, count),\n precision;\n specifier = formatSpecifier(specifier == null ? \",f\" : specifier);\n switch (specifier.type) {\n case \"s\": {\n var value = Math.max(Math.abs(start), Math.abs(stop));\n if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;\n return formatPrefix(specifier, value);\n }\n case \"\":\n case \"e\":\n case \"g\":\n case \"p\":\n case \"r\": {\n if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === \"e\");\n break;\n }\n case \"f\":\n case \"%\": {\n if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === \"%\") * 2;\n break;\n }\n }\n return format(specifier);\n}\n","import {ticks, tickIncrement} from \"d3-array\";\nimport continuous, {copy} from \"./continuous.js\";\nimport {initRange} from \"./init.js\";\nimport tickFormat from \"./tickFormat.js\";\n\nexport function linearish(scale) {\n var domain = scale.domain;\n\n scale.ticks = function(count) {\n var d = domain();\n return ticks(d[0], d[d.length - 1], count == null ? 10 : count);\n };\n\n scale.tickFormat = function(count, specifier) {\n var d = domain();\n return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier);\n };\n\n scale.nice = function(count) {\n if (count == null) count = 10;\n\n var d = domain();\n var i0 = 0;\n var i1 = d.length - 1;\n var start = d[i0];\n var stop = d[i1];\n var prestep;\n var step;\n var maxIter = 10;\n\n if (stop < start) {\n step = start, start = stop, stop = step;\n step = i0, i0 = i1, i1 = step;\n }\n \n while (maxIter-- > 0) {\n step = tickIncrement(start, stop, count);\n if (step === prestep) {\n d[i0] = start\n d[i1] = stop\n return domain(d);\n } else if (step > 0) {\n start = Math.floor(start / step) * step;\n stop = Math.ceil(stop / step) * step;\n } else if (step < 0) {\n start = Math.ceil(start * step) / step;\n stop = Math.floor(stop * step) / step;\n } else {\n break;\n }\n prestep = step;\n }\n\n return scale;\n };\n\n return scale;\n}\n\nexport default function linear() {\n var scale = continuous();\n\n scale.copy = function() {\n return copy(scale, linear());\n };\n\n initRange.apply(scale, arguments);\n\n return linearish(scale);\n}\n","export default function nice(domain, interval) {\n domain = domain.slice();\n\n var i0 = 0,\n i1 = domain.length - 1,\n x0 = domain[i0],\n x1 = domain[i1],\n t;\n\n if (x1 < x0) {\n t = i0, i0 = i1, i1 = t;\n t = x0, x0 = x1, x1 = t;\n }\n\n domain[i0] = interval.floor(x0);\n domain[i1] = interval.ceil(x1);\n return domain;\n}\n","import {ticks} from \"d3-array\";\nimport {format, formatSpecifier} from \"d3-format\";\nimport nice from \"./nice.js\";\nimport {copy, transformer} from \"./continuous.js\";\nimport {initRange} from \"./init.js\";\n\nfunction transformLog(x) {\n return Math.log(x);\n}\n\nfunction transformExp(x) {\n return Math.exp(x);\n}\n\nfunction transformLogn(x) {\n return -Math.log(-x);\n}\n\nfunction transformExpn(x) {\n return -Math.exp(-x);\n}\n\nfunction pow10(x) {\n return isFinite(x) ? +(\"1e\" + x) : x < 0 ? 0 : x;\n}\n\nfunction powp(base) {\n return base === 10 ? pow10\n : base === Math.E ? Math.exp\n : x => Math.pow(base, x);\n}\n\nfunction logp(base) {\n return base === Math.E ? Math.log\n : base === 10 && Math.log10\n || base === 2 && Math.log2\n || (base = Math.log(base), x => Math.log(x) / base);\n}\n\nfunction reflect(f) {\n return (x, k) => -f(-x, k);\n}\n\nexport function loggish(transform) {\n const scale = transform(transformLog, transformExp);\n const domain = scale.domain;\n let base = 10;\n let logs;\n let pows;\n\n function rescale() {\n logs = logp(base), pows = powp(base);\n if (domain()[0] < 0) {\n logs = reflect(logs), pows = reflect(pows);\n transform(transformLogn, transformExpn);\n } else {\n transform(transformLog, transformExp);\n }\n return scale;\n }\n\n scale.base = function(_) {\n return arguments.length ? (base = +_, rescale()) : base;\n };\n\n scale.domain = function(_) {\n return arguments.length ? (domain(_), rescale()) : domain();\n };\n\n scale.ticks = count => {\n const d = domain();\n let u = d[0];\n let v = d[d.length - 1];\n const r = v < u;\n\n if (r) ([u, v] = [v, u]);\n\n let i = logs(u);\n let j = logs(v);\n let k;\n let t;\n const n = count == null ? 10 : +count;\n let z = [];\n\n if (!(base % 1) && j - i < n) {\n i = Math.floor(i), j = Math.ceil(j);\n if (u > 0) for (; i <= j; ++i) {\n for (k = 1; k < base; ++k) {\n t = i < 0 ? k / pows(-i) : k * pows(i);\n if (t < u) continue;\n if (t > v) break;\n z.push(t);\n }\n } else for (; i <= j; ++i) {\n for (k = base - 1; k >= 1; --k) {\n t = i > 0 ? k / pows(-i) : k * pows(i);\n if (t < u) continue;\n if (t > v) break;\n z.push(t);\n }\n }\n if (z.length * 2 < n) z = ticks(u, v, n);\n } else {\n z = ticks(i, j, Math.min(j - i, n)).map(pows);\n }\n return r ? z.reverse() : z;\n };\n\n scale.tickFormat = (count, specifier) => {\n if (count == null) count = 10;\n if (specifier == null) specifier = base === 10 ? \"s\" : \",\";\n if (typeof specifier !== \"function\") {\n if (!(base % 1) && (specifier = formatSpecifier(specifier)).precision == null) specifier.trim = true;\n specifier = format(specifier);\n }\n if (count === Infinity) return specifier;\n const k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?\n return d => {\n let i = d / pows(Math.round(logs(d)));\n if (i * base < base - 0.5) i *= base;\n return i <= k ? specifier(d) : \"\";\n };\n };\n\n scale.nice = () => {\n return domain(nice(domain(), {\n floor: x => pows(Math.floor(logs(x))),\n ceil: x => pows(Math.ceil(logs(x)))\n }));\n };\n\n return scale;\n}\n\nexport default function log() {\n const scale = loggish(transformer()).domain([1, 10]);\n scale.copy = () => copy(scale, log()).base(scale.base());\n initRange.apply(scale, arguments);\n return scale;\n}\n","import {linearish} from \"./linear.js\";\nimport {copy, transformer} from \"./continuous.js\";\nimport {initRange} from \"./init.js\";\n\nfunction transformSymlog(c) {\n return function(x) {\n return Math.sign(x) * Math.log1p(Math.abs(x / c));\n };\n}\n\nfunction transformSymexp(c) {\n return function(x) {\n return Math.sign(x) * Math.expm1(Math.abs(x)) * c;\n };\n}\n\nexport function symlogish(transform) {\n var c = 1, scale = transform(transformSymlog(c), transformSymexp(c));\n\n scale.constant = function(_) {\n return arguments.length ? transform(transformSymlog(c = +_), transformSymexp(c)) : c;\n };\n\n return linearish(scale);\n}\n\nexport default function symlog() {\n var scale = symlogish(transformer());\n\n scale.copy = function() {\n return copy(scale, symlog()).constant(scale.constant());\n };\n\n return initRange.apply(scale, arguments);\n}\n","import {linearish} from \"./linear.js\";\nimport {copy, identity, transformer} from \"./continuous.js\";\nimport {initRange} from \"./init.js\";\n\nfunction transformPow(exponent) {\n return function(x) {\n return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);\n };\n}\n\nfunction transformSqrt(x) {\n return x < 0 ? -Math.sqrt(-x) : Math.sqrt(x);\n}\n\nfunction transformSquare(x) {\n return x < 0 ? -x * x : x * x;\n}\n\nexport function powish(transform) {\n var scale = transform(identity, identity),\n exponent = 1;\n\n function rescale() {\n return exponent === 1 ? transform(identity, identity)\n : exponent === 0.5 ? transform(transformSqrt, transformSquare)\n : transform(transformPow(exponent), transformPow(1 / exponent));\n }\n\n scale.exponent = function(_) {\n return arguments.length ? (exponent = +_, rescale()) : exponent;\n };\n\n return linearish(scale);\n}\n\nexport default function pow() {\n var scale = powish(transformer());\n\n scale.copy = function() {\n return copy(scale, pow()).exponent(scale.exponent());\n };\n\n initRange.apply(scale, arguments);\n\n return scale;\n}\n\nexport function sqrt() {\n return pow.apply(null, arguments).exponent(0.5);\n}\n","import {ascending, bisect, quantileSorted as threshold} from \"d3-array\";\nimport {initRange} from \"./init.js\";\n\nexport default function quantile() {\n var domain = [],\n range = [],\n thresholds = [],\n unknown;\n\n function rescale() {\n var i = 0, n = Math.max(1, range.length);\n thresholds = new Array(n - 1);\n while (++i < n) thresholds[i - 1] = threshold(domain, i / n);\n return scale;\n }\n\n function scale(x) {\n return x == null || isNaN(x = +x) ? unknown : range[bisect(thresholds, x)];\n }\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return i < 0 ? [NaN, NaN] : [\n i > 0 ? thresholds[i - 1] : domain[0],\n i < thresholds.length ? thresholds[i] : domain[domain.length - 1]\n ];\n };\n\n scale.domain = function(_) {\n if (!arguments.length) return domain.slice();\n domain = [];\n for (let d of _) if (d != null && !isNaN(d = +d)) domain.push(d);\n domain.sort(ascending);\n return rescale();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = Array.from(_), rescale()) : range.slice();\n };\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n scale.quantiles = function() {\n return thresholds.slice();\n };\n\n scale.copy = function() {\n return quantile()\n .domain(domain)\n .range(range)\n .unknown(unknown);\n };\n\n return initRange.apply(scale, arguments);\n}\n","import {bisect} from \"d3-array\";\nimport {linearish} from \"./linear.js\";\nimport {initRange} from \"./init.js\";\n\nexport default function quantize() {\n var x0 = 0,\n x1 = 1,\n n = 1,\n domain = [0.5],\n range = [0, 1],\n unknown;\n\n function scale(x) {\n return x != null && x <= x ? range[bisect(domain, x, 0, n)] : unknown;\n }\n\n function rescale() {\n var i = -1;\n domain = new Array(n);\n while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);\n return scale;\n }\n\n scale.domain = function(_) {\n return arguments.length ? ([x0, x1] = _, x0 = +x0, x1 = +x1, rescale()) : [x0, x1];\n };\n\n scale.range = function(_) {\n return arguments.length ? (n = (range = Array.from(_)).length - 1, rescale()) : range.slice();\n };\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return i < 0 ? [NaN, NaN]\n : i < 1 ? [x0, domain[0]]\n : i >= n ? [domain[n - 1], x1]\n : [domain[i - 1], domain[i]];\n };\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : scale;\n };\n\n scale.thresholds = function() {\n return domain.slice();\n };\n\n scale.copy = function() {\n return quantize()\n .domain([x0, x1])\n .range(range)\n .unknown(unknown);\n };\n\n return initRange.apply(linearish(scale), arguments);\n}\n","import {bisect} from \"d3-array\";\nimport {initRange} from \"./init.js\";\n\nexport default function threshold() {\n var domain = [0.5],\n range = [0, 1],\n unknown,\n n = 1;\n\n function scale(x) {\n return x != null && x <= x ? range[bisect(domain, x, 0, n)] : unknown;\n }\n\n scale.domain = function(_) {\n return arguments.length ? (domain = Array.from(_), n = Math.min(domain.length, range.length - 1), scale) : domain.slice();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = Array.from(_), n = Math.min(domain.length, range.length - 1), scale) : range.slice();\n };\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return [domain[i - 1], domain[i]];\n };\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n scale.copy = function() {\n return threshold()\n .domain(domain)\n .range(range)\n .unknown(unknown);\n };\n\n return initRange.apply(scale, arguments);\n}\n","const t0 = new Date, t1 = new Date;\n\nexport function timeInterval(floori, offseti, count, field) {\n\n function interval(date) {\n return floori(date = arguments.length === 0 ? new Date : new Date(+date)), date;\n }\n\n interval.floor = (date) => {\n return floori(date = new Date(+date)), date;\n };\n\n interval.ceil = (date) => {\n return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;\n };\n\n interval.round = (date) => {\n const d0 = interval(date), d1 = interval.ceil(date);\n return date - d0 < d1 - date ? d0 : d1;\n };\n\n interval.offset = (date, step) => {\n return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;\n };\n\n interval.range = (start, stop, step) => {\n const range = [];\n start = interval.ceil(start);\n step = step == null ? 1 : Math.floor(step);\n if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date\n let previous;\n do range.push(previous = new Date(+start)), offseti(start, step), floori(start);\n while (previous < start && start < stop);\n return range;\n };\n\n interval.filter = (test) => {\n return timeInterval((date) => {\n if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);\n }, (date, step) => {\n if (date >= date) {\n if (step < 0) while (++step <= 0) {\n while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty\n } else while (--step >= 0) {\n while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty\n }\n }\n });\n };\n\n if (count) {\n interval.count = (start, end) => {\n t0.setTime(+start), t1.setTime(+end);\n floori(t0), floori(t1);\n return Math.floor(count(t0, t1));\n };\n\n interval.every = (step) => {\n step = Math.floor(step);\n return !isFinite(step) || !(step > 0) ? null\n : !(step > 1) ? interval\n : interval.filter(field\n ? (d) => field(d) % step === 0\n : (d) => interval.count(0, d) % step === 0);\n };\n }\n\n return interval;\n}\n","import {timeInterval} from \"./interval.js\";\n\nexport const millisecond = timeInterval(() => {\n // noop\n}, (date, step) => {\n date.setTime(+date + step);\n}, (start, end) => {\n return end - start;\n});\n\n// An optimized implementation for this simple case.\nmillisecond.every = (k) => {\n k = Math.floor(k);\n if (!isFinite(k) || !(k > 0)) return null;\n if (!(k > 1)) return millisecond;\n return timeInterval((date) => {\n date.setTime(Math.floor(date / k) * k);\n }, (date, step) => {\n date.setTime(+date + step * k);\n }, (start, end) => {\n return (end - start) / k;\n });\n};\n\nexport const milliseconds = millisecond.range;\n","export const durationSecond = 1000;\nexport const durationMinute = durationSecond * 60;\nexport const durationHour = durationMinute * 60;\nexport const durationDay = durationHour * 24;\nexport const durationWeek = durationDay * 7;\nexport const durationMonth = durationDay * 30;\nexport const durationYear = durationDay * 365;\n","import {timeInterval} from \"./interval.js\";\nimport {durationSecond} from \"./duration.js\";\n\nexport const second = timeInterval((date) => {\n date.setTime(date - date.getMilliseconds());\n}, (date, step) => {\n date.setTime(+date + step * durationSecond);\n}, (start, end) => {\n return (end - start) / durationSecond;\n}, (date) => {\n return date.getUTCSeconds();\n});\n\nexport const seconds = second.range;\n","import {timeInterval} from \"./interval.js\";\nimport {durationMinute, durationSecond} from \"./duration.js\";\n\nexport const timeMinute = timeInterval((date) => {\n date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond);\n}, (date, step) => {\n date.setTime(+date + step * durationMinute);\n}, (start, end) => {\n return (end - start) / durationMinute;\n}, (date) => {\n return date.getMinutes();\n});\n\nexport const timeMinutes = timeMinute.range;\n\nexport const utcMinute = timeInterval((date) => {\n date.setUTCSeconds(0, 0);\n}, (date, step) => {\n date.setTime(+date + step * durationMinute);\n}, (start, end) => {\n return (end - start) / durationMinute;\n}, (date) => {\n return date.getUTCMinutes();\n});\n\nexport const utcMinutes = utcMinute.range;\n","import {timeInterval} from \"./interval.js\";\nimport {durationHour, durationMinute, durationSecond} from \"./duration.js\";\n\nexport const timeHour = timeInterval((date) => {\n date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond - date.getMinutes() * durationMinute);\n}, (date, step) => {\n date.setTime(+date + step * durationHour);\n}, (start, end) => {\n return (end - start) / durationHour;\n}, (date) => {\n return date.getHours();\n});\n\nexport const timeHours = timeHour.range;\n\nexport const utcHour = timeInterval((date) => {\n date.setUTCMinutes(0, 0, 0);\n}, (date, step) => {\n date.setTime(+date + step * durationHour);\n}, (start, end) => {\n return (end - start) / durationHour;\n}, (date) => {\n return date.getUTCHours();\n});\n\nexport const utcHours = utcHour.range;\n","import {timeInterval} from \"./interval.js\";\nimport {durationDay, durationMinute} from \"./duration.js\";\n\nexport const timeDay = timeInterval(\n date => date.setHours(0, 0, 0, 0),\n (date, step) => date.setDate(date.getDate() + step),\n (start, end) => (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay,\n date => date.getDate() - 1\n);\n\nexport const timeDays = timeDay.range;\n\nexport const utcDay = timeInterval((date) => {\n date.setUTCHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setUTCDate(date.getUTCDate() + step);\n}, (start, end) => {\n return (end - start) / durationDay;\n}, (date) => {\n return date.getUTCDate() - 1;\n});\n\nexport const utcDays = utcDay.range;\n\nexport const unixDay = timeInterval((date) => {\n date.setUTCHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setUTCDate(date.getUTCDate() + step);\n}, (start, end) => {\n return (end - start) / durationDay;\n}, (date) => {\n return Math.floor(date / durationDay);\n});\n\nexport const unixDays = unixDay.range;\n","import {timeInterval} from \"./interval.js\";\nimport {durationMinute, durationWeek} from \"./duration.js\";\n\nfunction timeWeekday(i) {\n return timeInterval((date) => {\n date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);\n date.setHours(0, 0, 0, 0);\n }, (date, step) => {\n date.setDate(date.getDate() + step * 7);\n }, (start, end) => {\n return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek;\n });\n}\n\nexport const timeSunday = timeWeekday(0);\nexport const timeMonday = timeWeekday(1);\nexport const timeTuesday = timeWeekday(2);\nexport const timeWednesday = timeWeekday(3);\nexport const timeThursday = timeWeekday(4);\nexport const timeFriday = timeWeekday(5);\nexport const timeSaturday = timeWeekday(6);\n\nexport const timeSundays = timeSunday.range;\nexport const timeMondays = timeMonday.range;\nexport const timeTuesdays = timeTuesday.range;\nexport const timeWednesdays = timeWednesday.range;\nexport const timeThursdays = timeThursday.range;\nexport const timeFridays = timeFriday.range;\nexport const timeSaturdays = timeSaturday.range;\n\nfunction utcWeekday(i) {\n return timeInterval((date) => {\n date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);\n date.setUTCHours(0, 0, 0, 0);\n }, (date, step) => {\n date.setUTCDate(date.getUTCDate() + step * 7);\n }, (start, end) => {\n return (end - start) / durationWeek;\n });\n}\n\nexport const utcSunday = utcWeekday(0);\nexport const utcMonday = utcWeekday(1);\nexport const utcTuesday = utcWeekday(2);\nexport const utcWednesday = utcWeekday(3);\nexport const utcThursday = utcWeekday(4);\nexport const utcFriday = utcWeekday(5);\nexport const utcSaturday = utcWeekday(6);\n\nexport const utcSundays = utcSunday.range;\nexport const utcMondays = utcMonday.range;\nexport const utcTuesdays = utcTuesday.range;\nexport const utcWednesdays = utcWednesday.range;\nexport const utcThursdays = utcThursday.range;\nexport const utcFridays = utcFriday.range;\nexport const utcSaturdays = utcSaturday.range;\n","import {timeInterval} from \"./interval.js\";\n\nexport const timeMonth = timeInterval((date) => {\n date.setDate(1);\n date.setHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setMonth(date.getMonth() + step);\n}, (start, end) => {\n return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;\n}, (date) => {\n return date.getMonth();\n});\n\nexport const timeMonths = timeMonth.range;\n\nexport const utcMonth = timeInterval((date) => {\n date.setUTCDate(1);\n date.setUTCHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setUTCMonth(date.getUTCMonth() + step);\n}, (start, end) => {\n return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;\n}, (date) => {\n return date.getUTCMonth();\n});\n\nexport const utcMonths = utcMonth.range;\n","import {timeInterval} from \"./interval.js\";\n\nexport const timeYear = timeInterval((date) => {\n date.setMonth(0, 1);\n date.setHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setFullYear(date.getFullYear() + step);\n}, (start, end) => {\n return end.getFullYear() - start.getFullYear();\n}, (date) => {\n return date.getFullYear();\n});\n\n// An optimized implementation for this simple case.\ntimeYear.every = (k) => {\n return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : timeInterval((date) => {\n date.setFullYear(Math.floor(date.getFullYear() / k) * k);\n date.setMonth(0, 1);\n date.setHours(0, 0, 0, 0);\n }, (date, step) => {\n date.setFullYear(date.getFullYear() + step * k);\n });\n};\n\nexport const timeYears = timeYear.range;\n\nexport const utcYear = timeInterval((date) => {\n date.setUTCMonth(0, 1);\n date.setUTCHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setUTCFullYear(date.getUTCFullYear() + step);\n}, (start, end) => {\n return end.getUTCFullYear() - start.getUTCFullYear();\n}, (date) => {\n return date.getUTCFullYear();\n});\n\n// An optimized implementation for this simple case.\nutcYear.every = (k) => {\n return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : timeInterval((date) => {\n date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);\n date.setUTCMonth(0, 1);\n date.setUTCHours(0, 0, 0, 0);\n }, (date, step) => {\n date.setUTCFullYear(date.getUTCFullYear() + step * k);\n });\n};\n\nexport const utcYears = utcYear.range;\n","import {bisector, tickStep} from \"d3-array\";\nimport {durationDay, durationHour, durationMinute, durationMonth, durationSecond, durationWeek, durationYear} from \"./duration.js\";\nimport {millisecond} from \"./millisecond.js\";\nimport {second} from \"./second.js\";\nimport {timeMinute, utcMinute} from \"./minute.js\";\nimport {timeHour, utcHour} from \"./hour.js\";\nimport {timeDay, unixDay} from \"./day.js\";\nimport {timeSunday, utcSunday} from \"./week.js\";\nimport {timeMonth, utcMonth} from \"./month.js\";\nimport {timeYear, utcYear} from \"./year.js\";\n\nfunction ticker(year, month, week, day, hour, minute) {\n\n const tickIntervals = [\n [second, 1, durationSecond],\n [second, 5, 5 * durationSecond],\n [second, 15, 15 * durationSecond],\n [second, 30, 30 * durationSecond],\n [minute, 1, durationMinute],\n [minute, 5, 5 * durationMinute],\n [minute, 15, 15 * durationMinute],\n [minute, 30, 30 * durationMinute],\n [ hour, 1, durationHour ],\n [ hour, 3, 3 * durationHour ],\n [ hour, 6, 6 * durationHour ],\n [ hour, 12, 12 * durationHour ],\n [ day, 1, durationDay ],\n [ day, 2, 2 * durationDay ],\n [ week, 1, durationWeek ],\n [ month, 1, durationMonth ],\n [ month, 3, 3 * durationMonth ],\n [ year, 1, durationYear ]\n ];\n\n function ticks(start, stop, count) {\n const reverse = stop < start;\n if (reverse) [start, stop] = [stop, start];\n const interval = count && typeof count.range === \"function\" ? count : tickInterval(start, stop, count);\n const ticks = interval ? interval.range(start, +stop + 1) : []; // inclusive stop\n return reverse ? ticks.reverse() : ticks;\n }\n\n function tickInterval(start, stop, count) {\n const target = Math.abs(stop - start) / count;\n const i = bisector(([,, step]) => step).right(tickIntervals, target);\n if (i === tickIntervals.length) return year.every(tickStep(start / durationYear, stop / durationYear, count));\n if (i === 0) return millisecond.every(Math.max(tickStep(start, stop, count), 1));\n const [t, step] = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];\n return t.every(step);\n }\n\n return [ticks, tickInterval];\n}\n\nconst [utcTicks, utcTickInterval] = ticker(utcYear, utcMonth, utcSunday, unixDay, utcHour, utcMinute);\nconst [timeTicks, timeTickInterval] = ticker(timeYear, timeMonth, timeSunday, timeDay, timeHour, timeMinute);\n\nexport {utcTicks, utcTickInterval, timeTicks, timeTickInterval};\n","import {\n timeDay,\n timeSunday,\n timeMonday,\n timeThursday,\n timeYear,\n utcDay,\n utcSunday,\n utcMonday,\n utcThursday,\n utcYear\n} from \"d3-time\";\n\nfunction localDate(d) {\n if (0 <= d.y && d.y < 100) {\n var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);\n date.setFullYear(d.y);\n return date;\n }\n return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);\n}\n\nfunction utcDate(d) {\n if (0 <= d.y && d.y < 100) {\n var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));\n date.setUTCFullYear(d.y);\n return date;\n }\n return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));\n}\n\nfunction newDate(y, m, d) {\n return {y: y, m: m, d: d, H: 0, M: 0, S: 0, L: 0};\n}\n\nexport default function formatLocale(locale) {\n var locale_dateTime = locale.dateTime,\n locale_date = locale.date,\n locale_time = locale.time,\n locale_periods = locale.periods,\n locale_weekdays = locale.days,\n locale_shortWeekdays = locale.shortDays,\n locale_months = locale.months,\n locale_shortMonths = locale.shortMonths;\n\n var periodRe = formatRe(locale_periods),\n periodLookup = formatLookup(locale_periods),\n weekdayRe = formatRe(locale_weekdays),\n weekdayLookup = formatLookup(locale_weekdays),\n shortWeekdayRe = formatRe(locale_shortWeekdays),\n shortWeekdayLookup = formatLookup(locale_shortWeekdays),\n monthRe = formatRe(locale_months),\n monthLookup = formatLookup(locale_months),\n shortMonthRe = formatRe(locale_shortMonths),\n shortMonthLookup = formatLookup(locale_shortMonths);\n\n var formats = {\n \"a\": formatShortWeekday,\n \"A\": formatWeekday,\n \"b\": formatShortMonth,\n \"B\": formatMonth,\n \"c\": null,\n \"d\": formatDayOfMonth,\n \"e\": formatDayOfMonth,\n \"f\": formatMicroseconds,\n \"g\": formatYearISO,\n \"G\": formatFullYearISO,\n \"H\": formatHour24,\n \"I\": formatHour12,\n \"j\": formatDayOfYear,\n \"L\": formatMilliseconds,\n \"m\": formatMonthNumber,\n \"M\": formatMinutes,\n \"p\": formatPeriod,\n \"q\": formatQuarter,\n \"Q\": formatUnixTimestamp,\n \"s\": formatUnixTimestampSeconds,\n \"S\": formatSeconds,\n \"u\": formatWeekdayNumberMonday,\n \"U\": formatWeekNumberSunday,\n \"V\": formatWeekNumberISO,\n \"w\": formatWeekdayNumberSunday,\n \"W\": formatWeekNumberMonday,\n \"x\": null,\n \"X\": null,\n \"y\": formatYear,\n \"Y\": formatFullYear,\n \"Z\": formatZone,\n \"%\": formatLiteralPercent\n };\n\n var utcFormats = {\n \"a\": formatUTCShortWeekday,\n \"A\": formatUTCWeekday,\n \"b\": formatUTCShortMonth,\n \"B\": formatUTCMonth,\n \"c\": null,\n \"d\": formatUTCDayOfMonth,\n \"e\": formatUTCDayOfMonth,\n \"f\": formatUTCMicroseconds,\n \"g\": formatUTCYearISO,\n \"G\": formatUTCFullYearISO,\n \"H\": formatUTCHour24,\n \"I\": formatUTCHour12,\n \"j\": formatUTCDayOfYear,\n \"L\": formatUTCMilliseconds,\n \"m\": formatUTCMonthNumber,\n \"M\": formatUTCMinutes,\n \"p\": formatUTCPeriod,\n \"q\": formatUTCQuarter,\n \"Q\": formatUnixTimestamp,\n \"s\": formatUnixTimestampSeconds,\n \"S\": formatUTCSeconds,\n \"u\": formatUTCWeekdayNumberMonday,\n \"U\": formatUTCWeekNumberSunday,\n \"V\": formatUTCWeekNumberISO,\n \"w\": formatUTCWeekdayNumberSunday,\n \"W\": formatUTCWeekNumberMonday,\n \"x\": null,\n \"X\": null,\n \"y\": formatUTCYear,\n \"Y\": formatUTCFullYear,\n \"Z\": formatUTCZone,\n \"%\": formatLiteralPercent\n };\n\n var parses = {\n \"a\": parseShortWeekday,\n \"A\": parseWeekday,\n \"b\": parseShortMonth,\n \"B\": parseMonth,\n \"c\": parseLocaleDateTime,\n \"d\": parseDayOfMonth,\n \"e\": parseDayOfMonth,\n \"f\": parseMicroseconds,\n \"g\": parseYear,\n \"G\": parseFullYear,\n \"H\": parseHour24,\n \"I\": parseHour24,\n \"j\": parseDayOfYear,\n \"L\": parseMilliseconds,\n \"m\": parseMonthNumber,\n \"M\": parseMinutes,\n \"p\": parsePeriod,\n \"q\": parseQuarter,\n \"Q\": parseUnixTimestamp,\n \"s\": parseUnixTimestampSeconds,\n \"S\": parseSeconds,\n \"u\": parseWeekdayNumberMonday,\n \"U\": parseWeekNumberSunday,\n \"V\": parseWeekNumberISO,\n \"w\": parseWeekdayNumberSunday,\n \"W\": parseWeekNumberMonday,\n \"x\": parseLocaleDate,\n \"X\": parseLocaleTime,\n \"y\": parseYear,\n \"Y\": parseFullYear,\n \"Z\": parseZone,\n \"%\": parseLiteralPercent\n };\n\n // These recursive directive definitions must be deferred.\n formats.x = newFormat(locale_date, formats);\n formats.X = newFormat(locale_time, formats);\n formats.c = newFormat(locale_dateTime, formats);\n utcFormats.x = newFormat(locale_date, utcFormats);\n utcFormats.X = newFormat(locale_time, utcFormats);\n utcFormats.c = newFormat(locale_dateTime, utcFormats);\n\n function newFormat(specifier, formats) {\n return function(date) {\n var string = [],\n i = -1,\n j = 0,\n n = specifier.length,\n c,\n pad,\n format;\n\n if (!(date instanceof Date)) date = new Date(+date);\n\n while (++i < n) {\n if (specifier.charCodeAt(i) === 37) {\n string.push(specifier.slice(j, i));\n if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);\n else pad = c === \"e\" ? \" \" : \"0\";\n if (format = formats[c]) c = format(date, pad);\n string.push(c);\n j = i + 1;\n }\n }\n\n string.push(specifier.slice(j, i));\n return string.join(\"\");\n };\n }\n\n function newParse(specifier, Z) {\n return function(string) {\n var d = newDate(1900, undefined, 1),\n i = parseSpecifier(d, specifier, string += \"\", 0),\n week, day;\n if (i != string.length) return null;\n\n // If a UNIX timestamp is specified, return it.\n if (\"Q\" in d) return new Date(d.Q);\n if (\"s\" in d) return new Date(d.s * 1000 + (\"L\" in d ? d.L : 0));\n\n // If this is utcParse, never use the local timezone.\n if (Z && !(\"Z\" in d)) d.Z = 0;\n\n // The am-pm flag is 0 for AM, and 1 for PM.\n if (\"p\" in d) d.H = d.H % 12 + d.p * 12;\n\n // If the month was not specified, inherit from the quarter.\n if (d.m === undefined) d.m = \"q\" in d ? d.q : 0;\n\n // Convert day-of-week and week-of-year to day-of-year.\n if (\"V\" in d) {\n if (d.V < 1 || d.V > 53) return null;\n if (!(\"w\" in d)) d.w = 1;\n if (\"Z\" in d) {\n week = utcDate(newDate(d.y, 0, 1)), day = week.getUTCDay();\n week = day > 4 || day === 0 ? utcMonday.ceil(week) : utcMonday(week);\n week = utcDay.offset(week, (d.V - 1) * 7);\n d.y = week.getUTCFullYear();\n d.m = week.getUTCMonth();\n d.d = week.getUTCDate() + (d.w + 6) % 7;\n } else {\n week = localDate(newDate(d.y, 0, 1)), day = week.getDay();\n week = day > 4 || day === 0 ? timeMonday.ceil(week) : timeMonday(week);\n week = timeDay.offset(week, (d.V - 1) * 7);\n d.y = week.getFullYear();\n d.m = week.getMonth();\n d.d = week.getDate() + (d.w + 6) % 7;\n }\n } else if (\"W\" in d || \"U\" in d) {\n if (!(\"w\" in d)) d.w = \"u\" in d ? d.u % 7 : \"W\" in d ? 1 : 0;\n day = \"Z\" in d ? utcDate(newDate(d.y, 0, 1)).getUTCDay() : localDate(newDate(d.y, 0, 1)).getDay();\n d.m = 0;\n d.d = \"W\" in d ? (d.w + 6) % 7 + d.W * 7 - (day + 5) % 7 : d.w + d.U * 7 - (day + 6) % 7;\n }\n\n // If a time zone is specified, all fields are interpreted as UTC and then\n // offset according to the specified time zone.\n if (\"Z\" in d) {\n d.H += d.Z / 100 | 0;\n d.M += d.Z % 100;\n return utcDate(d);\n }\n\n // Otherwise, all fields are in local time.\n return localDate(d);\n };\n }\n\n function parseSpecifier(d, specifier, string, j) {\n var i = 0,\n n = specifier.length,\n m = string.length,\n c,\n parse;\n\n while (i < n) {\n if (j >= m) return -1;\n c = specifier.charCodeAt(i++);\n if (c === 37) {\n c = specifier.charAt(i++);\n parse = parses[c in pads ? specifier.charAt(i++) : c];\n if (!parse || ((j = parse(d, string, j)) < 0)) return -1;\n } else if (c != string.charCodeAt(j++)) {\n return -1;\n }\n }\n\n return j;\n }\n\n function parsePeriod(d, string, i) {\n var n = periodRe.exec(string.slice(i));\n return n ? (d.p = periodLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseShortWeekday(d, string, i) {\n var n = shortWeekdayRe.exec(string.slice(i));\n return n ? (d.w = shortWeekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseWeekday(d, string, i) {\n var n = weekdayRe.exec(string.slice(i));\n return n ? (d.w = weekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseShortMonth(d, string, i) {\n var n = shortMonthRe.exec(string.slice(i));\n return n ? (d.m = shortMonthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseMonth(d, string, i) {\n var n = monthRe.exec(string.slice(i));\n return n ? (d.m = monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseLocaleDateTime(d, string, i) {\n return parseSpecifier(d, locale_dateTime, string, i);\n }\n\n function parseLocaleDate(d, string, i) {\n return parseSpecifier(d, locale_date, string, i);\n }\n\n function parseLocaleTime(d, string, i) {\n return parseSpecifier(d, locale_time, string, i);\n }\n\n function formatShortWeekday(d) {\n return locale_shortWeekdays[d.getDay()];\n }\n\n function formatWeekday(d) {\n return locale_weekdays[d.getDay()];\n }\n\n function formatShortMonth(d) {\n return locale_shortMonths[d.getMonth()];\n }\n\n function formatMonth(d) {\n return locale_months[d.getMonth()];\n }\n\n function formatPeriod(d) {\n return locale_periods[+(d.getHours() >= 12)];\n }\n\n function formatQuarter(d) {\n return 1 + ~~(d.getMonth() / 3);\n }\n\n function formatUTCShortWeekday(d) {\n return locale_shortWeekdays[d.getUTCDay()];\n }\n\n function formatUTCWeekday(d) {\n return locale_weekdays[d.getUTCDay()];\n }\n\n function formatUTCShortMonth(d) {\n return locale_shortMonths[d.getUTCMonth()];\n }\n\n function formatUTCMonth(d) {\n return locale_months[d.getUTCMonth()];\n }\n\n function formatUTCPeriod(d) {\n return locale_periods[+(d.getUTCHours() >= 12)];\n }\n\n function formatUTCQuarter(d) {\n return 1 + ~~(d.getUTCMonth() / 3);\n }\n\n return {\n format: function(specifier) {\n var f = newFormat(specifier += \"\", formats);\n f.toString = function() { return specifier; };\n return f;\n },\n parse: function(specifier) {\n var p = newParse(specifier += \"\", false);\n p.toString = function() { return specifier; };\n return p;\n },\n utcFormat: function(specifier) {\n var f = newFormat(specifier += \"\", utcFormats);\n f.toString = function() { return specifier; };\n return f;\n },\n utcParse: function(specifier) {\n var p = newParse(specifier += \"\", true);\n p.toString = function() { return specifier; };\n return p;\n }\n };\n}\n\nvar pads = {\"-\": \"\", \"_\": \" \", \"0\": \"0\"},\n numberRe = /^\\s*\\d+/, // note: ignores next directive\n percentRe = /^%/,\n requoteRe = /[\\\\^$*+?|[\\]().{}]/g;\n\nfunction pad(value, fill, width) {\n var sign = value < 0 ? \"-\" : \"\",\n string = (sign ? -value : value) + \"\",\n length = string.length;\n return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);\n}\n\nfunction requote(s) {\n return s.replace(requoteRe, \"\\\\$&\");\n}\n\nfunction formatRe(names) {\n return new RegExp(\"^(?:\" + names.map(requote).join(\"|\") + \")\", \"i\");\n}\n\nfunction formatLookup(names) {\n return new Map(names.map((name, i) => [name.toLowerCase(), i]));\n}\n\nfunction parseWeekdayNumberSunday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.w = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekdayNumberMonday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.u = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberSunday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.U = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberISO(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.V = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberMonday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.W = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseFullYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 4));\n return n ? (d.y = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;\n}\n\nfunction parseZone(d, string, i) {\n var n = /^(Z)|([+-]\\d\\d)(?::?(\\d\\d))?/.exec(string.slice(i, i + 6));\n return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || \"00\")), i + n[0].length) : -1;\n}\n\nfunction parseQuarter(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.q = n[0] * 3 - 3, i + n[0].length) : -1;\n}\n\nfunction parseMonthNumber(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.m = n[0] - 1, i + n[0].length) : -1;\n}\n\nfunction parseDayOfMonth(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseDayOfYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 3));\n return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseHour24(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.H = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMinutes(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.M = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseSeconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.S = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMilliseconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 3));\n return n ? (d.L = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMicroseconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 6));\n return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1;\n}\n\nfunction parseLiteralPercent(d, string, i) {\n var n = percentRe.exec(string.slice(i, i + 1));\n return n ? i + n[0].length : -1;\n}\n\nfunction parseUnixTimestamp(d, string, i) {\n var n = numberRe.exec(string.slice(i));\n return n ? (d.Q = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseUnixTimestampSeconds(d, string, i) {\n var n = numberRe.exec(string.slice(i));\n return n ? (d.s = +n[0], i + n[0].length) : -1;\n}\n\nfunction formatDayOfMonth(d, p) {\n return pad(d.getDate(), p, 2);\n}\n\nfunction formatHour24(d, p) {\n return pad(d.getHours(), p, 2);\n}\n\nfunction formatHour12(d, p) {\n return pad(d.getHours() % 12 || 12, p, 2);\n}\n\nfunction formatDayOfYear(d, p) {\n return pad(1 + timeDay.count(timeYear(d), d), p, 3);\n}\n\nfunction formatMilliseconds(d, p) {\n return pad(d.getMilliseconds(), p, 3);\n}\n\nfunction formatMicroseconds(d, p) {\n return formatMilliseconds(d, p) + \"000\";\n}\n\nfunction formatMonthNumber(d, p) {\n return pad(d.getMonth() + 1, p, 2);\n}\n\nfunction formatMinutes(d, p) {\n return pad(d.getMinutes(), p, 2);\n}\n\nfunction formatSeconds(d, p) {\n return pad(d.getSeconds(), p, 2);\n}\n\nfunction formatWeekdayNumberMonday(d) {\n var day = d.getDay();\n return day === 0 ? 7 : day;\n}\n\nfunction formatWeekNumberSunday(d, p) {\n return pad(timeSunday.count(timeYear(d) - 1, d), p, 2);\n}\n\nfunction dISO(d) {\n var day = d.getDay();\n return (day >= 4 || day === 0) ? timeThursday(d) : timeThursday.ceil(d);\n}\n\nfunction formatWeekNumberISO(d, p) {\n d = dISO(d);\n return pad(timeThursday.count(timeYear(d), d) + (timeYear(d).getDay() === 4), p, 2);\n}\n\nfunction formatWeekdayNumberSunday(d) {\n return d.getDay();\n}\n\nfunction formatWeekNumberMonday(d, p) {\n return pad(timeMonday.count(timeYear(d) - 1, d), p, 2);\n}\n\nfunction formatYear(d, p) {\n return pad(d.getFullYear() % 100, p, 2);\n}\n\nfunction formatYearISO(d, p) {\n d = dISO(d);\n return pad(d.getFullYear() % 100, p, 2);\n}\n\nfunction formatFullYear(d, p) {\n return pad(d.getFullYear() % 10000, p, 4);\n}\n\nfunction formatFullYearISO(d, p) {\n var day = d.getDay();\n d = (day >= 4 || day === 0) ? timeThursday(d) : timeThursday.ceil(d);\n return pad(d.getFullYear() % 10000, p, 4);\n}\n\nfunction formatZone(d) {\n var z = d.getTimezoneOffset();\n return (z > 0 ? \"-\" : (z *= -1, \"+\"))\n + pad(z / 60 | 0, \"0\", 2)\n + pad(z % 60, \"0\", 2);\n}\n\nfunction formatUTCDayOfMonth(d, p) {\n return pad(d.getUTCDate(), p, 2);\n}\n\nfunction formatUTCHour24(d, p) {\n return pad(d.getUTCHours(), p, 2);\n}\n\nfunction formatUTCHour12(d, p) {\n return pad(d.getUTCHours() % 12 || 12, p, 2);\n}\n\nfunction formatUTCDayOfYear(d, p) {\n return pad(1 + utcDay.count(utcYear(d), d), p, 3);\n}\n\nfunction formatUTCMilliseconds(d, p) {\n return pad(d.getUTCMilliseconds(), p, 3);\n}\n\nfunction formatUTCMicroseconds(d, p) {\n return formatUTCMilliseconds(d, p) + \"000\";\n}\n\nfunction formatUTCMonthNumber(d, p) {\n return pad(d.getUTCMonth() + 1, p, 2);\n}\n\nfunction formatUTCMinutes(d, p) {\n return pad(d.getUTCMinutes(), p, 2);\n}\n\nfunction formatUTCSeconds(d, p) {\n return pad(d.getUTCSeconds(), p, 2);\n}\n\nfunction formatUTCWeekdayNumberMonday(d) {\n var dow = d.getUTCDay();\n return dow === 0 ? 7 : dow;\n}\n\nfunction formatUTCWeekNumberSunday(d, p) {\n return pad(utcSunday.count(utcYear(d) - 1, d), p, 2);\n}\n\nfunction UTCdISO(d) {\n var day = d.getUTCDay();\n return (day >= 4 || day === 0) ? utcThursday(d) : utcThursday.ceil(d);\n}\n\nfunction formatUTCWeekNumberISO(d, p) {\n d = UTCdISO(d);\n return pad(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2);\n}\n\nfunction formatUTCWeekdayNumberSunday(d) {\n return d.getUTCDay();\n}\n\nfunction formatUTCWeekNumberMonday(d, p) {\n return pad(utcMonday.count(utcYear(d) - 1, d), p, 2);\n}\n\nfunction formatUTCYear(d, p) {\n return pad(d.getUTCFullYear() % 100, p, 2);\n}\n\nfunction formatUTCYearISO(d, p) {\n d = UTCdISO(d);\n return pad(d.getUTCFullYear() % 100, p, 2);\n}\n\nfunction formatUTCFullYear(d, p) {\n return pad(d.getUTCFullYear() % 10000, p, 4);\n}\n\nfunction formatUTCFullYearISO(d, p) {\n var day = d.getUTCDay();\n d = (day >= 4 || day === 0) ? utcThursday(d) : utcThursday.ceil(d);\n return pad(d.getUTCFullYear() % 10000, p, 4);\n}\n\nfunction formatUTCZone() {\n return \"+0000\";\n}\n\nfunction formatLiteralPercent() {\n return \"%\";\n}\n\nfunction formatUnixTimestamp(d) {\n return +d;\n}\n\nfunction formatUnixTimestampSeconds(d) {\n return Math.floor(+d / 1000);\n}\n","import formatLocale from \"./locale.js\";\n\nvar locale;\nexport var timeFormat;\nexport var timeParse;\nexport var utcFormat;\nexport var utcParse;\n\ndefaultLocale({\n dateTime: \"%x, %X\",\n date: \"%-m/%-d/%Y\",\n time: \"%-I:%M:%S %p\",\n periods: [\"AM\", \"PM\"],\n days: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n shortDays: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n months: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"],\n shortMonths: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\n});\n\nexport default function defaultLocale(definition) {\n locale = formatLocale(definition);\n timeFormat = locale.format;\n timeParse = locale.parse;\n utcFormat = locale.utcFormat;\n utcParse = locale.utcParse;\n return locale;\n}\n","import {timeYear, timeMonth, timeWeek, timeDay, timeHour, timeMinute, timeSecond, timeTicks, timeTickInterval} from \"d3-time\";\nimport {timeFormat} from \"d3-time-format\";\nimport continuous, {copy} from \"./continuous.js\";\nimport {initRange} from \"./init.js\";\nimport nice from \"./nice.js\";\n\nfunction date(t) {\n return new Date(t);\n}\n\nfunction number(t) {\n return t instanceof Date ? +t : +new Date(+t);\n}\n\nexport function calendar(ticks, tickInterval, year, month, week, day, hour, minute, second, format) {\n var scale = continuous(),\n invert = scale.invert,\n domain = scale.domain;\n\n var formatMillisecond = format(\".%L\"),\n formatSecond = format(\":%S\"),\n formatMinute = format(\"%I:%M\"),\n formatHour = format(\"%I %p\"),\n formatDay = format(\"%a %d\"),\n formatWeek = format(\"%b %d\"),\n formatMonth = format(\"%B\"),\n formatYear = format(\"%Y\");\n\n function tickFormat(date) {\n return (second(date) < date ? formatMillisecond\n : minute(date) < date ? formatSecond\n : hour(date) < date ? formatMinute\n : day(date) < date ? formatHour\n : month(date) < date ? (week(date) < date ? formatDay : formatWeek)\n : year(date) < date ? formatMonth\n : formatYear)(date);\n }\n\n scale.invert = function(y) {\n return new Date(invert(y));\n };\n\n scale.domain = function(_) {\n return arguments.length ? domain(Array.from(_, number)) : domain().map(date);\n };\n\n scale.ticks = function(interval) {\n var d = domain();\n return ticks(d[0], d[d.length - 1], interval == null ? 10 : interval);\n };\n\n scale.tickFormat = function(count, specifier) {\n return specifier == null ? tickFormat : format(specifier);\n };\n\n scale.nice = function(interval) {\n var d = domain();\n if (!interval || typeof interval.range !== \"function\") interval = tickInterval(d[0], d[d.length - 1], interval == null ? 10 : interval);\n return interval ? domain(nice(d, interval)) : scale;\n };\n\n scale.copy = function() {\n return copy(scale, calendar(ticks, tickInterval, year, month, week, day, hour, minute, second, format));\n };\n\n return scale;\n}\n\nexport default function time() {\n return initRange.apply(calendar(timeTicks, timeTickInterval, timeYear, timeMonth, timeWeek, timeDay, timeHour, timeMinute, timeSecond, timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]), arguments);\n}\n","import {utcYear, utcMonth, utcWeek, utcDay, utcHour, utcMinute, utcSecond, utcTicks, utcTickInterval} from \"d3-time\";\nimport {utcFormat} from \"d3-time-format\";\nimport {calendar} from \"./time.js\";\nimport {initRange} from \"./init.js\";\n\nexport default function utcTime() {\n return initRange.apply(calendar(utcTicks, utcTickInterval, utcYear, utcMonth, utcWeek, utcDay, utcHour, utcMinute, utcSecond, utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]), arguments);\n}\n","import {interpolate, interpolateRound} from \"d3-interpolate\";\nimport {identity} from \"./continuous.js\";\nimport {initInterpolator} from \"./init.js\";\nimport {linearish} from \"./linear.js\";\nimport {loggish} from \"./log.js\";\nimport {symlogish} from \"./symlog.js\";\nimport {powish} from \"./pow.js\";\n\nfunction transformer() {\n var x0 = 0,\n x1 = 1,\n t0,\n t1,\n k10,\n transform,\n interpolator = identity,\n clamp = false,\n unknown;\n\n function scale(x) {\n return x == null || isNaN(x = +x) ? unknown : interpolator(k10 === 0 ? 0.5 : (x = (transform(x) - t0) * k10, clamp ? Math.max(0, Math.min(1, x)) : x));\n }\n\n scale.domain = function(_) {\n return arguments.length ? ([x0, x1] = _, t0 = transform(x0 = +x0), t1 = transform(x1 = +x1), k10 = t0 === t1 ? 0 : 1 / (t1 - t0), scale) : [x0, x1];\n };\n\n scale.clamp = function(_) {\n return arguments.length ? (clamp = !!_, scale) : clamp;\n };\n\n scale.interpolator = function(_) {\n return arguments.length ? (interpolator = _, scale) : interpolator;\n };\n\n function range(interpolate) {\n return function(_) {\n var r0, r1;\n return arguments.length ? ([r0, r1] = _, interpolator = interpolate(r0, r1), scale) : [interpolator(0), interpolator(1)];\n };\n }\n\n scale.range = range(interpolate);\n\n scale.rangeRound = range(interpolateRound);\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n return function(t) {\n transform = t, t0 = t(x0), t1 = t(x1), k10 = t0 === t1 ? 0 : 1 / (t1 - t0);\n return scale;\n };\n}\n\nexport function copy(source, target) {\n return target\n .domain(source.domain())\n .interpolator(source.interpolator())\n .clamp(source.clamp())\n .unknown(source.unknown());\n}\n\nexport default function sequential() {\n var scale = linearish(transformer()(identity));\n\n scale.copy = function() {\n return copy(scale, sequential());\n };\n\n return initInterpolator.apply(scale, arguments);\n}\n\nexport function sequentialLog() {\n var scale = loggish(transformer()).domain([1, 10]);\n\n scale.copy = function() {\n return copy(scale, sequentialLog()).base(scale.base());\n };\n\n return initInterpolator.apply(scale, arguments);\n}\n\nexport function sequentialSymlog() {\n var scale = symlogish(transformer());\n\n scale.copy = function() {\n return copy(scale, sequentialSymlog()).constant(scale.constant());\n };\n\n return initInterpolator.apply(scale, arguments);\n}\n\nexport function sequentialPow() {\n var scale = powish(transformer());\n\n scale.copy = function() {\n return copy(scale, sequentialPow()).exponent(scale.exponent());\n };\n\n return initInterpolator.apply(scale, arguments);\n}\n\nexport function sequentialSqrt() {\n return sequentialPow.apply(null, arguments).exponent(0.5);\n}\n","/**\n * Mark post-processing: obstacle computation, renderer dispatch, and\n * animation index assignment. These are mark-type-aware operations that\n * run after the chart renderer has produced marks.\n */\n\nimport type {\n Encoding,\n Mark,\n MarkDef,\n PointMark,\n Rect,\n RectMark,\n ResolvedAnimation,\n} from '@opendata-ai/openchart-core';\nimport type { ResolvedScales } from '../layout/scales';\n\n// ---------------------------------------------------------------------------\n// Mark obstacles for annotation collision avoidance\n// ---------------------------------------------------------------------------\n\n/**\n * Compute bounding rects from marks to use as obstacles for annotation nudging.\n *\n * For band-scale charts (bar, dot): groups marks by band row and returns\n * a single obstacle per row spanning the full band height and x-range.\n *\n * For other charts (column, scatter): returns individual mark bounds so\n * annotations avoid overlapping any visible data mark.\n */\nexport function computeMarkObstacles(marks: Mark[], scales: ResolvedScales): Rect[] {\n // Band-scale y-axis: group marks by row for efficient obstacle computation\n if (scales.y?.type === 'band') {\n return computeBandRowObstacles(marks, scales);\n }\n\n // All other charts: use individual rect/point mark bounds as obstacles\n const obstacles: Rect[] = [];\n for (const mark of marks) {\n if (mark.type === 'rect') {\n const rm = mark as RectMark;\n obstacles.push({ x: rm.x, y: rm.y, width: rm.width, height: rm.height });\n } else if (mark.type === 'point') {\n const pm = mark as PointMark;\n obstacles.push({\n x: pm.cx - pm.r,\n y: pm.cy - pm.r,\n width: pm.r * 2,\n height: pm.r * 2,\n });\n }\n }\n return obstacles;\n}\n\n/** Group band-scale marks by row, returning one obstacle per band. */\nfunction computeBandRowObstacles(marks: Mark[], scales: ResolvedScales): Rect[] {\n const rows = new Map<number, { minX: number; maxX: number; bandY: number }>();\n\n for (const mark of marks) {\n let cy: number;\n let left: number;\n let right: number;\n\n if (mark.type === 'point') {\n const pm = mark as PointMark;\n cy = pm.cy;\n left = pm.cx - pm.r;\n right = pm.cx + pm.r;\n } else if (mark.type === 'rect') {\n const rm = mark as RectMark;\n cy = rm.y + rm.height / 2;\n left = rm.x;\n right = rm.x + rm.width;\n } else {\n continue;\n }\n\n // Round cy to group marks on the same band\n const key = Math.round(cy);\n const existing = rows.get(key);\n if (existing) {\n existing.minX = Math.min(existing.minX, left);\n existing.maxX = Math.max(existing.maxX, right);\n } else {\n rows.set(key, { minX: left, maxX: right, bandY: cy });\n }\n }\n\n // Get bandwidth from the band scale\n const bandScale = scales.y!.scale as { bandwidth?: () => number };\n const bandwidth = bandScale.bandwidth?.() ?? 0;\n if (bandwidth === 0) return [];\n\n const obstacles: Rect[] = [];\n for (const { minX, maxX, bandY } of rows.values()) {\n obstacles.push({\n x: minX,\n y: bandY - bandwidth / 2,\n width: maxX - minX,\n height: bandwidth,\n });\n }\n\n return obstacles;\n}\n\n// ---------------------------------------------------------------------------\n// Renderer key dispatch\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the renderer key from mark type, encoding, and mark definition.\n *\n * - 'bar' -> 'bar' (horizontal) or 'bar:vertical' based on encoding axis types\n * - 'arc' -> 'arc' (pie) or 'arc:donut' based on innerRadius\n * - All other mark types pass through unchanged\n */\nexport function resolveRendererKey(\n markType: string,\n encoding: Partial<Encoding>,\n markDef: Partial<MarkDef>,\n): string {\n if (markType === 'bar') {\n const xType = encoding.x?.type;\n const yType = encoding.y?.type;\n const isVertical =\n (xType === 'nominal' || xType === 'ordinal' || xType === 'temporal') &&\n yType === 'quantitative';\n if (isVertical) {\n return 'bar:vertical';\n }\n } else if (markType === 'arc') {\n const innerRadius = markDef.innerRadius;\n if (innerRadius && innerRadius > 0) {\n return 'arc:donut';\n }\n }\n return markType;\n}\n\n// ---------------------------------------------------------------------------\n// Animation index assignment\n// ---------------------------------------------------------------------------\n\n/** Extract the primary quantitative value from a mark for value-based stagger ordering. */\nfunction getMarkPrimaryValue(mark: Mark): number {\n switch (mark.type) {\n case 'rect':\n return mark.height; // bar height is the primary value encoding\n case 'point':\n return mark.cy; // y position for scatter\n case 'arc':\n return mark.endAngle - mark.startAngle; // arc angle extent\n case 'line':\n case 'area':\n return 0; // series marks don't have individual values\n default:\n return 0;\n }\n}\n\n/**\n * Assign animation indices to marks for stagger ordering.\n *\n * Two phases:\n * 1. Value-based stagger: sorts marks by primary value, assigns sequential indices.\n * Skips stacked rects since they get group-based indices in phase 2.\n * 2. Stack-based stagger: groups marks by stackGroup, assigns the same index to\n * all segments in a group, and computes stackPos (segment position: 0, 1, 2...).\n * This intentionally overwrites any value-based indices for stacked marks.\n */\nexport function assignAnimationIndices(\n marks: Mark[],\n animation: ResolvedAnimation | undefined,\n): void {\n if (!animation?.enabled) return;\n\n // Phase 1: Value-based stagger ordering. Skip stacked rects\n // since they get group-based indices below (avoids wasted work that gets overwritten).\n if (animation.staggerOrder === 'value') {\n const indexed = marks.map((m, i) => ({ mark: m, idx: i }));\n indexed.sort((a, b) => {\n const av = getMarkPrimaryValue(a.mark);\n const bv = getMarkPrimaryValue(b.mark);\n return av - bv;\n });\n for (let i = 0; i < indexed.length; i++) {\n const m = indexed[i].mark;\n if (m.type === 'rect' && (m as RectMark).stackGroup) continue;\n m.animationIndex = i;\n }\n }\n\n // Phase 2: For stacked bars/columns, assign the same animationIndex to all segments\n // sharing a stackGroup so they animate as one contiguous bar per category.\n // Also compute stackPos (segment position within each group: 0, 1, 2...)\n // so the renderer can chain segment animations sequentially.\n const groupIndexMap = new Map<string, number>();\n const groupStackPos = new Map<string, number>();\n let nextGroupIndex = 0;\n for (const mark of marks) {\n if (mark.type === 'rect' && (mark as RectMark).stackGroup) {\n const rect = mark as RectMark;\n const group = rect.stackGroup!;\n if (!groupIndexMap.has(group)) {\n groupIndexMap.set(group, nextGroupIndex++);\n }\n rect.animationIndex = groupIndexMap.get(group)!;\n const pos = groupStackPos.get(group) ?? 0;\n rect.stackPos = pos;\n groupStackPos.set(group, pos + 1);\n }\n }\n}\n","/**\n * Apply the theme palette as the color scale range when no explicit range was provided.\n *\n * Sequential scales take the first/last stops of the first sequential palette\n * (or the categorical endpoints as a fallback). Categorical scales get the\n * full categorical palette. A user-provided `encoding.color.scale.range`\n * always wins.\n */\n\nimport type { Encoding, ResolvedTheme } from '@opendata-ai/openchart-core';\nimport type { ScaleLinear, ScaleOrdinal } from 'd3-scale';\nimport type { ResolvedScales } from '../layout/scales';\n\n/** Mutates `scales.color.scale.range` in place when no explicit palette was set. */\nexport function applyColorScaleRange(\n scales: ResolvedScales,\n encoding: Encoding,\n theme: ResolvedTheme,\n): void {\n if (!scales.color) return;\n\n const hasExplicitRange = !!(\n encoding.color &&\n 'field' in encoding.color &&\n (encoding.color.scale?.range as string[] | undefined)?.length\n );\n if (hasExplicitRange) return;\n\n if (scales.color.type === 'sequential') {\n const seqStops = Object.values(theme.colors.sequential)[0] ?? theme.colors.categorical;\n (scales.color.scale as unknown as ScaleLinear<string, string>).range([\n seqStops[0],\n seqStops[seqStops.length - 1],\n ]);\n } else {\n (scales.color.scale as ScaleOrdinal<string, string>).range(theme.colors.categorical);\n }\n}\n","/**\n * Data filter for clipped scale domains.\n *\n * When an x or y encoding declares `scale.clip: true` with a numeric\n * [lo, hi] domain, rows whose field value falls outside that range are\n * dropped before scales and marks are computed. Pure and side-effect free.\n */\n\nimport type { DataRow, Encoding } from '@opendata-ai/openchart-core';\n\n/**\n * Return a new data array with rows outside any clipped scale domain removed.\n *\n * Only inspects the `x` and `y` channels. Non-numeric domains and channels\n * without `scale.clip` are passed through unchanged.\n */\nexport function filterClippedDomains(data: DataRow[], encoding: Encoding): DataRow[] {\n let result = data;\n for (const channel of ['x', 'y'] as const) {\n const enc = encoding[channel];\n if (!enc?.scale?.clip || !enc.scale.domain) continue;\n const domain = enc.scale.domain;\n const field = enc.field;\n if (Array.isArray(domain) && domain.length === 2 && typeof domain[0] === 'number') {\n const [lo, hi] = domain as [number, number];\n result = result.filter((row) => {\n const v = Number(row[field]);\n return Number.isFinite(v) && v >= lo && v <= hi;\n });\n }\n }\n return result;\n}\n","/**\n * Compute the brand watermark obstacle rect.\n *\n * The watermark is right-aligned on the same baseline as the first bottom\n * chrome element (source, byline, or footer), offset below the chart area\n * by the x-axis extent (tick labels + axis title). Returns null when the\n * watermark is disabled so callers can skip obstacle collection entirely.\n */\n\nimport type { Rect, ResolvedTheme } from '@opendata-ai/openchart-core';\nimport { BRAND_RESERVE_WIDTH } from '@opendata-ai/openchart-core';\nimport type { AxesResult } from '../layout/axes';\nimport type { LayoutDimensions } from '../layout/dimensions';\n\n/** Height of the watermark element used for obstacle avoidance. */\nconst WATERMARK_HEIGHT = 30;\n\n/** Vertical padding below the x-axis label when an axis title is present. */\nconst X_AXIS_EXTENT_WITH_LABEL = 48;\n\n/** Vertical padding below the x-axis ticks when no axis title is present. */\nconst X_AXIS_EXTENT_TICKS_ONLY = 26;\n\n/**\n * Compute the rect occupied by the watermark, or null when it is disabled.\n *\n * @param dims - Layout dimensions (for total width and chrome positions).\n * @param watermark - Whether the watermark is enabled for this chart.\n * @param axes - Computed axes (the x-axis determines how far below the chart the watermark sits).\n * @param theme - Resolved theme (padding + fallback spacing).\n */\nexport function computeWatermarkObstacle(\n dims: LayoutDimensions,\n watermark: boolean,\n axes: AxesResult,\n theme: ResolvedTheme,\n): Rect | null {\n if (!watermark) return null;\n\n const chartArea = dims.chartArea;\n const brandPadding = theme.spacing.padding;\n const brandX = dims.total.width - brandPadding - BRAND_RESERVE_WIDTH;\n const xAxisExtent = axes.x?.label\n ? X_AXIS_EXTENT_WITH_LABEL\n : axes.x\n ? X_AXIS_EXTENT_TICKS_ONLY\n : 0;\n const firstBottomChrome = dims.chrome.source ?? dims.chrome.byline ?? dims.chrome.footer;\n const brandY = firstBottomChrome\n ? chartArea.y + chartArea.height + xAxisExtent + firstBottomChrome.y\n : chartArea.y + chartArea.height + xAxisExtent + theme.spacing.chartToFooter;\n\n return { x: brandX, y: brandY, width: BRAND_RESERVE_WIDTH, height: WATERMARK_HEIGHT };\n}\n","/**\n * Animation resolver: normalizes AnimationSpec into fully resolved config.\n *\n * Handles the shorthand forms:\n * - true -> { enter: true } -> full defaults\n * - { enter: { duration: 800 } } -> merge with defaults\n * - false/undefined -> undefined (no animation)\n */\n\nimport type {\n AnimationConfig,\n AnimationEase,\n AnimationPhaseConfig,\n AnimationSpec,\n AnimationStagger,\n ResolvedAnimation,\n} from '@opendata-ai/openchart-core';\n\n/** Default values for entrance animation. */\nconst ENTER_DEFAULTS = {\n duration: 500,\n ease: 'smooth' as AnimationEase,\n staggerDelay: 80,\n staggerOrder: 'index' as const,\n annotationDelay: 200,\n} as const;\n\n/** Maximum total stagger time in ms. Prevents 200-bar charts from taking 6s. */\nconst MAX_TOTAL_STAGGER_MS = 2000;\n\n/**\n * Resolve an AnimationSpec into a fully resolved config with all defaults filled.\n * Returns undefined if animation is disabled (false or omitted).\n */\nexport function resolveAnimation(spec: AnimationSpec | undefined): ResolvedAnimation | undefined {\n if (spec === undefined || spec === false) return undefined;\n\n // true -> default enter animation\n if (spec === true) {\n return {\n enabled: true,\n duration: ENTER_DEFAULTS.duration,\n ease: ENTER_DEFAULTS.ease,\n staggerDelay: ENTER_DEFAULTS.staggerDelay,\n staggerOrder: ENTER_DEFAULTS.staggerOrder,\n annotationDelay: ENTER_DEFAULTS.annotationDelay,\n };\n }\n\n // AnimationConfig object\n const config = spec as AnimationConfig;\n\n // If no enter phase specified or enter is false, no animation\n if (config.enter === false || (config.enter === undefined && !hasAnyPhase(config))) {\n return undefined;\n }\n\n const enterConfig = resolvePhaseConfig(config.enter);\n\n return {\n enabled: true,\n duration: enterConfig.duration,\n ease: enterConfig.ease,\n staggerDelay: enterConfig.staggerDelay,\n staggerOrder: enterConfig.staggerOrder,\n annotationDelay: config.annotationDelay ?? ENTER_DEFAULTS.annotationDelay,\n };\n}\n\n/**\n * Clamp stagger delay so total stagger time doesn't exceed MAX_TOTAL_STAGGER_MS.\n */\nexport function clampStaggerDelay(delay: number, elementCount: number): number {\n if (elementCount <= 1) return 0;\n return Math.min(delay, MAX_TOTAL_STAGGER_MS / elementCount);\n}\n\nfunction hasAnyPhase(config: AnimationConfig): boolean {\n return config.enter !== undefined || config.update !== undefined || config.exit !== undefined;\n}\n\ninterface ResolvedPhase {\n duration: number;\n ease: AnimationEase;\n staggerDelay: number;\n staggerOrder: 'index' | 'value' | 'reverse';\n}\n\nfunction resolvePhaseConfig(phase: AnimationPhaseConfig | boolean | undefined): ResolvedPhase {\n if (phase === undefined || phase === true) {\n return {\n duration: ENTER_DEFAULTS.duration,\n ease: ENTER_DEFAULTS.ease,\n staggerDelay: ENTER_DEFAULTS.staggerDelay,\n staggerOrder: ENTER_DEFAULTS.staggerOrder,\n };\n }\n\n const cfg = phase as AnimationPhaseConfig;\n const stagger = resolveStagger(cfg.stagger);\n\n return {\n duration: cfg.duration ?? ENTER_DEFAULTS.duration,\n ease: cfg.ease ?? ENTER_DEFAULTS.ease,\n staggerDelay: stagger.delay,\n staggerOrder: stagger.order,\n };\n}\n\nfunction resolveStagger(stagger: AnimationStagger | boolean | undefined): {\n delay: number;\n order: 'index' | 'value' | 'reverse';\n} {\n if (stagger === false) return { delay: 0, order: 'index' };\n if (stagger === undefined || stagger === true) {\n return { delay: ENTER_DEFAULTS.staggerDelay, order: ENTER_DEFAULTS.staggerOrder };\n }\n return {\n delay: stagger.delay ?? ENTER_DEFAULTS.staggerDelay,\n order: stagger.order ?? ENTER_DEFAULTS.staggerOrder,\n };\n}\n","/**\n * Spec normalization: fill in defaults and infer types.\n *\n * Takes a validated VizSpec and produces a NormalizedSpec where:\n * - All optional fields have sensible defaults\n * - Chrome strings are converted to ChromeText objects\n * - Encoding types are inferred from data if not specified\n * - Annotations have default styles\n */\n\nimport type {\n Annotation,\n ChartSpec,\n Chrome,\n ChromeText,\n DataRow,\n Encoding,\n FieldType,\n GraphSpec,\n LayerSpec,\n SankeySpec,\n TableSpec,\n VizSpec,\n} from '@opendata-ai/openchart-core';\nimport {\n isChartSpec,\n isGraphSpec,\n isLayerSpec,\n isSankeySpec,\n isTableSpec,\n resolveMarkDef,\n resolveMarkType,\n} from '@opendata-ai/openchart-core';\nimport type { NormalizedSankeySpec } from '../sankey/types';\nimport type {\n NormalizedChartSpec,\n NormalizedChrome,\n NormalizedGraphSpec,\n NormalizedSpec,\n NormalizedTableSpec,\n} from './types';\n\n// ---------------------------------------------------------------------------\n// Chrome normalization\n// ---------------------------------------------------------------------------\n\n/** Convert a string | ChromeText | undefined to ChromeText | undefined. */\nfunction normalizeChromeField(value: string | ChromeText | undefined): ChromeText | undefined {\n if (value === undefined) return undefined;\n if (typeof value === 'string') return { text: value };\n return value;\n}\n\n/** Normalize all chrome fields from strings to ChromeText objects. */\nfunction normalizeChrome(chrome: Chrome | undefined): NormalizedChrome {\n if (!chrome) return {};\n return {\n title: normalizeChromeField(chrome.title),\n subtitle: normalizeChromeField(chrome.subtitle),\n source: normalizeChromeField(chrome.source),\n byline: normalizeChromeField(chrome.byline),\n footer: normalizeChromeField(chrome.footer),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Type inference\n// ---------------------------------------------------------------------------\n\n/** Sample values from a data column and infer the field type. */\nfunction inferFieldType(data: DataRow[], field: string): FieldType {\n // Sample up to 50 rows for more reliable inference on mixed/messy data\n const sampleSize = Math.min(50, data.length);\n let numericCount = 0;\n let dateCount = 0;\n let totalNonNull = 0;\n\n for (let i = 0; i < sampleSize; i++) {\n const value = data[i][field];\n if (value == null) continue;\n totalNonNull++;\n\n // Check numeric\n if (typeof value === 'number' && Number.isFinite(value)) {\n numericCount++;\n continue;\n }\n\n // Check date-like strings\n if (typeof value === 'string') {\n // Try as number first\n const num = Number(value);\n if (!Number.isNaN(num) && Number.isFinite(num) && value.trim() !== '') {\n numericCount++;\n continue;\n }\n\n // Try as date\n const date = new Date(value);\n if (!Number.isNaN(date.getTime())) {\n dateCount++;\n continue;\n }\n }\n\n if (value instanceof Date && !Number.isNaN(value.getTime())) {\n dateCount++;\n }\n }\n\n if (totalNonNull === 0) return 'nominal';\n\n // If >80% of sampled values are dates, it's temporal\n if (dateCount / totalNonNull > 0.8) return 'temporal';\n // If >80% are numeric, it's quantitative\n if (numericCount / totalNonNull > 0.8) return 'quantitative';\n // Otherwise it's nominal\n return 'nominal';\n}\n\n/** Infer types for encoding channels that don't have one specified. */\nfunction inferEncodingTypes(encoding: Encoding, data: DataRow[], warnings: string[]): Encoding {\n const result = { ...encoding };\n\n for (const channel of ['x', 'y', 'color', 'size', 'detail'] as const) {\n const spec = result[channel];\n if (!spec) continue;\n\n // Skip conditional value definitions - they don't have field/type at the top level\n if ('condition' in spec) continue;\n\n if (!spec.type) {\n const inferred = inferFieldType(data, spec.field);\n (result as Record<string, unknown>)[channel] = { ...spec, type: inferred };\n warnings.push(\n `Inferred encoding.${channel}.type as \"${inferred}\" from data values for field \"${spec.field}\"`,\n );\n } else {\n // Check for potential mismatches and warn\n const actualType = inferFieldType(data, spec.field);\n if (spec.type === 'nominal' && actualType === 'temporal') {\n warnings.push(`Field \"${spec.field}\" looks temporal but was declared as nominal`);\n }\n if (spec.type === 'nominal' && actualType === 'quantitative') {\n warnings.push(`Field \"${spec.field}\" looks quantitative but was declared as nominal`);\n }\n }\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Annotation normalization\n// ---------------------------------------------------------------------------\n\n/** Apply default styles to annotations that don't have them. */\nfunction normalizeAnnotations(annotations: Annotation[] | undefined): Annotation[] {\n if (!annotations || annotations.length === 0) return [];\n\n return annotations.map((ann) => {\n switch (ann.type) {\n case 'text':\n return {\n ...ann,\n fontSize: ann.fontSize ?? 12,\n fontWeight: ann.fontWeight ?? 400,\n opacity: ann.opacity ?? 1,\n };\n case 'range':\n return {\n ...ann,\n opacity: ann.opacity ?? 0.1,\n fill: ann.fill ?? '#000000',\n };\n case 'refline':\n return {\n ...ann,\n style: ann.style ?? 'dashed',\n strokeWidth: ann.strokeWidth ?? 1,\n stroke: ann.stroke ?? '#666666',\n opacity: ann.opacity ?? 0.8,\n };\n default:\n return ann;\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Spec-level normalization\n// ---------------------------------------------------------------------------\n\nfunction normalizeChartSpec(spec: ChartSpec, warnings: string[]): NormalizedChartSpec {\n const encoding = inferEncodingTypes(spec.encoding, spec.data, warnings);\n const markType = resolveMarkType(spec.mark);\n const markDef = resolveMarkDef(spec.mark);\n\n return {\n markType,\n markDef,\n data: spec.data,\n encoding,\n chrome: normalizeChrome(spec.chrome),\n annotations: normalizeAnnotations(spec.annotations),\n labels: {\n density: spec.labels?.density ?? 'auto',\n format: spec.labels?.format ?? '',\n prefix: spec.labels?.prefix ?? '',\n offsets: spec.labels?.offsets,\n },\n legend: spec.legend,\n responsive: spec.responsive ?? true,\n theme: spec.theme ?? {},\n darkMode: spec.darkMode ?? 'off',\n hiddenSeries: spec.hiddenSeries ?? [],\n seriesStyles: spec.seriesStyles ?? {},\n watermark: spec.watermark ?? true,\n };\n}\n\nfunction normalizeTableSpec(spec: TableSpec, _warnings: string[]): NormalizedTableSpec {\n return {\n type: 'table',\n data: spec.data,\n columns: spec.columns,\n rowKey: spec.rowKey,\n chrome: normalizeChrome(spec.chrome),\n theme: spec.theme ?? {},\n darkMode: spec.darkMode ?? 'off',\n search: spec.search ?? false,\n pagination: spec.pagination ?? false,\n stickyFirstColumn: spec.stickyFirstColumn ?? false,\n compact: spec.compact ?? false,\n responsive: spec.responsive ?? true,\n animation: spec.animation,\n watermark: spec.watermark ?? true,\n };\n}\n\nfunction normalizeSankeySpec(spec: SankeySpec, _warnings: string[]): NormalizedSankeySpec {\n return {\n type: 'sankey',\n data: spec.data,\n encoding: spec.encoding,\n nodeWidth: spec.nodeWidth ?? 12,\n nodePadding: spec.nodePadding ?? 16,\n nodeAlign: spec.nodeAlign ?? 'justify',\n iterations: spec.iterations ?? 6,\n linkStyle: spec.linkStyle ?? 'gradient',\n nodeLabelAlign: spec.nodeLabelAlign ?? 'auto',\n nodeSort: spec.nodeSort,\n chrome: normalizeChrome(spec.chrome),\n legend: spec.legend,\n theme: spec.theme ?? {},\n darkMode: spec.darkMode ?? 'off',\n animation: spec.animation,\n valueFormat: spec.valueFormat,\n linkOpacity: spec.linkOpacity,\n watermark: spec.watermark ?? true,\n };\n}\n\nfunction normalizeGraphSpec(spec: GraphSpec, _warnings: string[]): NormalizedGraphSpec {\n // Default layout with chargeStrength and linkDistance\n const defaultLayout = {\n type: 'force' as const,\n chargeStrength: -300,\n linkDistance: 30,\n };\n const layout = spec.layout\n ? {\n ...defaultLayout,\n ...spec.layout,\n }\n : defaultLayout;\n\n return {\n type: 'graph',\n nodes: spec.nodes,\n edges: spec.edges,\n encoding: spec.encoding ?? {},\n layout,\n nodeOverrides: spec.nodeOverrides,\n chrome: normalizeChrome(spec.chrome),\n annotations: normalizeAnnotations(spec.annotations),\n theme: spec.theme ?? {},\n darkMode: spec.darkMode ?? 'off',\n watermark: spec.watermark ?? true,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize a validated VizSpec, filling in all defaults.\n *\n * @param spec - A validated VizSpec (must pass validateSpec first).\n * @param warnings - Mutable array to collect non-fatal warnings.\n * @returns A NormalizedSpec with all optionals filled.\n */\nexport function normalizeSpec(spec: VizSpec, warnings: string[] = []): NormalizedSpec {\n if (isLayerSpec(spec)) {\n // For LayerSpec, we flatten and normalize the first leaf to get a valid NormalizedChartSpec.\n // The actual layer compilation happens in compileLayer, not here.\n // This path exists so the generic compile() pipeline doesn't reject layer specs.\n const leaves = flattenLayers(spec);\n if (leaves.length === 0) {\n throw new Error('LayerSpec has no leaf chart specs after flattening');\n }\n return normalizeChartSpec(leaves[0], warnings);\n }\n if (isChartSpec(spec)) {\n return normalizeChartSpec(spec, warnings);\n }\n if (isTableSpec(spec)) {\n return normalizeTableSpec(spec, warnings);\n }\n if (isGraphSpec(spec)) {\n return normalizeGraphSpec(spec, warnings);\n }\n if (isSankeySpec(spec)) {\n return normalizeSankeySpec(spec, warnings);\n }\n // Should never happen after validation\n throw new Error(\n `Unknown spec shape. Expected mark (chart), layer, type: 'table', type: 'graph', or type: 'sankey'.`,\n );\n}\n\n// ---------------------------------------------------------------------------\n// Layer flattening (used by compileLayer in compile.ts)\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively flatten a LayerSpec into leaf ChartSpecs.\n * Merges parent data, encoding, and transforms down to children.\n */\nexport function flattenLayers(\n spec: LayerSpec,\n parentData?: DataRow[],\n parentEncoding?: Encoding,\n parentTransforms?: import('@opendata-ai/openchart-core').Transform[],\n parentWatermark?: boolean,\n): ChartSpec[] {\n const resolvedData = spec.data ?? parentData;\n const resolvedEncoding: Encoding | undefined =\n parentEncoding && spec.encoding\n ? { ...parentEncoding, ...spec.encoding }\n : (spec.encoding ?? parentEncoding);\n const resolvedTransforms = [...(parentTransforms ?? []), ...(spec.transform ?? [])];\n // Layer-level watermark propagates to children (child can still override)\n const resolvedWatermark = spec.watermark ?? parentWatermark;\n\n const leaves: ChartSpec[] = [];\n\n for (const child of spec.layer) {\n if (isLayerSpec(child)) {\n // Nested layer: recurse with merged context\n leaves.push(\n ...flattenLayers(\n child,\n resolvedData,\n resolvedEncoding,\n resolvedTransforms,\n resolvedWatermark,\n ),\n );\n } else {\n // Leaf ChartSpec: merge inherited properties\n const mergedData = child.data ?? resolvedData ?? [];\n const mergedEncoding = resolvedEncoding\n ? { ...resolvedEncoding, ...child.encoding }\n : child.encoding;\n const mergedTransforms = [...resolvedTransforms, ...(child.transform ?? [])];\n\n leaves.push({\n ...child,\n data: mergedData,\n encoding: mergedEncoding,\n transform: mergedTransforms.length > 0 ? mergedTransforms : undefined,\n // Inherit parent watermark if child doesn't explicitly set one\n ...(child.watermark === undefined && resolvedWatermark !== undefined\n ? { watermark: resolvedWatermark }\n : {}),\n });\n }\n }\n\n return leaves;\n}\n","/**\n * Runtime spec validation.\n *\n * TypeScript catches compile-time errors for specs written in code.\n * This module catches runtime errors for specs coming from JSON, APIs,\n * or Claude-generated output where the TypeScript compiler can't help.\n *\n * Every error includes a machine-readable code and an actionable suggestion\n * so consumers (and LLMs) can fix issues programmatically.\n */\n\nimport {\n type FieldType,\n MARK_ENCODING_RULES,\n MARK_TYPES,\n type MarkType,\n type VizSpec,\n} from '@opendata-ai/openchart-core';\n\nimport type { ValidationError, ValidationResult } from './types';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst VALID_FIELD_TYPES = new Set<string>(['quantitative', 'temporal', 'nominal', 'ordinal']);\n\nconst VALID_DARK_MODES = new Set<string>(['auto', 'force', 'off']);\n\n/** Check if a value looks like a parseable date. */\nfunction isParseableDate(value: unknown): boolean {\n if (value instanceof Date) return !Number.isNaN(value.getTime());\n if (typeof value === 'string') {\n const d = new Date(value);\n return !Number.isNaN(d.getTime());\n }\n if (typeof value === 'number') return true;\n return false;\n}\n\n/** Check if a value is numeric. */\nfunction isNumeric(value: unknown): boolean {\n if (typeof value === 'number') return Number.isFinite(value);\n if (typeof value === 'string') {\n const n = Number(value);\n return !Number.isNaN(n) && Number.isFinite(n);\n }\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Chart validation\n// ---------------------------------------------------------------------------\n\nfunction validateChartSpec(spec: Record<string, unknown>, errors: ValidationError[]): void {\n const markType =\n typeof spec.mark === 'string' ? spec.mark : (spec.mark as Record<string, unknown>)?.type;\n\n // Check data\n if (!Array.isArray(spec.data)) {\n errors.push({\n message: 'Spec error: \"data\" must be an array',\n path: 'data',\n code: 'INVALID_TYPE',\n suggestion: 'Provide data as an array of objects, e.g. data: [{ x: 1, y: 2 }]',\n });\n return; // Can't validate further without data\n }\n\n if (spec.data.length === 0) {\n errors.push({\n message: 'Spec error: \"data\" must be a non-empty array',\n path: 'data',\n code: 'EMPTY_DATA',\n suggestion: 'Add at least one data row, e.g. data: [{ x: 1, y: 2 }]',\n });\n return;\n }\n\n // Validate data entries are objects\n const firstRow = spec.data[0] as unknown;\n if (typeof firstRow !== 'object' || firstRow === null || Array.isArray(firstRow)) {\n errors.push({\n message: 'Spec error: each item in \"data\" must be a plain object',\n path: 'data[0]',\n code: 'INVALID_TYPE',\n suggestion:\n 'Each data item should be an object with key-value pairs, e.g. { name: \"Alice\", value: 10 }',\n });\n return;\n }\n\n // Check encoding exists\n if (!spec.encoding || typeof spec.encoding !== 'object') {\n const rules = MARK_ENCODING_RULES[markType as MarkType];\n const requiredChannels = Object.entries(rules)\n .filter(([, rule]) => rule.required)\n .map(([ch]) => ch);\n errors.push({\n message: `Spec error: ${markType} chart requires an \"encoding\" object`,\n path: 'encoding',\n code: 'MISSING_FIELD',\n suggestion: `Add an encoding object with required channels: ${requiredChannels.join(', ')}. Example: encoding: { ${requiredChannels.map((ch) => `${ch}: { field: \"...\", type: \"...\" }`).join(', ')} }`,\n });\n return;\n }\n\n const rules = MARK_ENCODING_RULES[markType as MarkType];\n const encoding = spec.encoding as Record<string, unknown>;\n const dataColumns = new Set(Object.keys(firstRow as Record<string, unknown>));\n const availableColumns = [...dataColumns].join(', ');\n\n // Validate required channels\n for (const [channel, rule] of Object.entries(rules)) {\n if (rule.required && !encoding[channel]) {\n const allowedTypes = rule.allowedTypes.join(' or ');\n errors.push({\n message: `Spec error: ${markType} chart requires encoding.${channel} but none was provided`,\n path: `encoding.${channel}`,\n code: 'MISSING_FIELD',\n suggestion: `Add encoding.${channel} with a field from your data (${availableColumns}) and type (${allowedTypes}). Example: ${channel}: { field: \"${[...dataColumns][0] ?? 'myField'}\", type: \"${rule.allowedTypes[0]}\" }`,\n });\n }\n }\n\n // Collect fields that transforms will create, so we don't reject them\n const transformFields = new Set<string>();\n if (Array.isArray(spec.transform)) {\n for (const t of spec.transform as Record<string, unknown>[]) {\n if (typeof t.as === 'string') transformFields.add(t.as);\n if (Array.isArray(t.as)) {\n for (const f of t.as) {\n if (typeof f === 'string') transformFields.add(f);\n }\n }\n }\n }\n\n // Validate provided channels\n for (const [channel, channelSpec] of Object.entries(encoding)) {\n if (!channelSpec || typeof channelSpec !== 'object') continue;\n\n // Tooltip can be an array of encoding channels\n if (channel === 'tooltip' && Array.isArray(channelSpec)) {\n for (let i = 0; i < channelSpec.length; i++) {\n const elem = channelSpec[i] as Record<string, unknown> | null;\n if (!elem || typeof elem !== 'object') continue;\n if (!elem.field || typeof elem.field !== 'string') {\n errors.push({\n message: `Spec error: encoding.tooltip[${i}] must have a \"field\" string`,\n path: `encoding.tooltip[${i}].field`,\n code: 'MISSING_FIELD',\n suggestion: `Add a field name from your data columns: ${availableColumns}`,\n });\n continue;\n }\n if (!dataColumns.has(elem.field) && !transformFields.has(elem.field)) {\n errors.push({\n message: `Spec error: encoding.tooltip[${i}].field \"${elem.field}\" does not exist in data. Available columns: ${availableColumns}`,\n path: `encoding.tooltip[${i}].field`,\n code: 'DATA_FIELD_MISSING',\n suggestion: `Use one of the available data columns: ${availableColumns}`,\n });\n }\n if (elem.type && !VALID_FIELD_TYPES.has(elem.type as string)) {\n errors.push({\n message: `Spec error: encoding.tooltip[${i}].type \"${elem.type}\" is not valid. Must be one of: ${[...VALID_FIELD_TYPES].join(', ')}`,\n path: `encoding.tooltip[${i}].type`,\n code: 'INVALID_VALUE',\n suggestion: `Use one of: ${[...VALID_FIELD_TYPES].join(', ')}`,\n });\n }\n }\n continue;\n }\n\n const channelObj = channelSpec as Record<string, unknown>;\n const channelRule = rules[channel as keyof typeof rules];\n\n // Skip ConditionalValueDef channels (they have 'condition' instead of 'field')\n if ('condition' in channelObj) continue;\n\n // Check field exists\n if (!channelObj.field || typeof channelObj.field !== 'string') {\n errors.push({\n message: `Spec error: encoding.${channel} must have a \"field\" string`,\n path: `encoding.${channel}.field`,\n code: 'MISSING_FIELD',\n suggestion: `For constant colors, use mark.fill (e.g., mark: { type: \"bar\", fill: \"#1b7fa3\" }) instead of encoding.${channel}. Encoding channels require a data field: ${availableColumns}`,\n });\n continue;\n }\n\n // Check field references a column in data (or will be created by a transform)\n if (!dataColumns.has(channelObj.field) && !transformFields.has(channelObj.field)) {\n errors.push({\n message: `Spec error: encoding.${channel}.field \"${channelObj.field}\" does not exist in data. Available columns: ${availableColumns}`,\n path: `encoding.${channel}.field`,\n code: 'DATA_FIELD_MISSING',\n suggestion: `Use one of the available data columns: ${availableColumns}`,\n });\n }\n\n // Check field type is valid\n if (channelObj.type && !VALID_FIELD_TYPES.has(channelObj.type as string)) {\n errors.push({\n message: `Spec error: encoding.${channel}.type \"${channelObj.type}\" is not valid. Must be one of: ${[...VALID_FIELD_TYPES].join(', ')}`,\n path: `encoding.${channel}.type`,\n code: 'INVALID_VALUE',\n suggestion: `Use one of: ${[...VALID_FIELD_TYPES].join(', ')}`,\n });\n }\n\n // Check field type is allowed for this channel\n if (channelRule && channelObj.type && channelRule.allowedTypes.length > 0) {\n if (!channelRule.allowedTypes.includes(channelObj.type as FieldType)) {\n errors.push({\n message: `Spec error: encoding.${channel} for ${markType} chart does not accept type \"${channelObj.type}\". Allowed types: ${channelRule.allowedTypes.join(', ')}`,\n path: `encoding.${channel}.type`,\n code: 'ENCODING_MISMATCH',\n suggestion: `Change encoding.${channel}.type to one of: ${channelRule.allowedTypes.join(', ')}`,\n });\n }\n }\n\n // Check field values match declared type\n if (channelObj.type && channelObj.field && dataColumns.has(channelObj.field as string)) {\n const data = spec.data as Record<string, unknown>[];\n const fieldName = channelObj.field as string;\n const fieldType = channelObj.type as string;\n // Sample up to 5 values for type checking\n const sampleSize = Math.min(5, data.length);\n\n if (fieldType === 'temporal') {\n let nonDateCount = 0;\n for (let i = 0; i < sampleSize; i++) {\n const val = data[i][fieldName];\n if (val != null && !isParseableDate(val)) {\n nonDateCount++;\n }\n }\n if (nonDateCount > 0) {\n errors.push({\n message: `Spec error: encoding.${channel}.field \"${fieldName}\" is declared as temporal but contains non-date values`,\n path: `encoding.${channel}`,\n code: 'ENCODING_MISMATCH',\n suggestion: `Either change the type to \"nominal\" or ensure \"${fieldName}\" values are parseable dates (ISO 8601 strings like \"2024-01-15\" or Date objects)`,\n });\n }\n }\n\n if (fieldType === 'quantitative') {\n let nonNumericCount = 0;\n for (let i = 0; i < sampleSize; i++) {\n const val = data[i][fieldName];\n if (val != null && !isNumeric(val)) {\n nonNumericCount++;\n }\n }\n if (nonNumericCount > 0) {\n errors.push({\n message: `Spec error: encoding.${channel}.field \"${fieldName}\" is declared as quantitative but contains non-numeric values`,\n path: `encoding.${channel}`,\n code: 'ENCODING_MISMATCH',\n suggestion: `Either change the type to \"nominal\" or ensure \"${fieldName}\" values are numbers`,\n });\n }\n }\n }\n }\n\n // Validate darkMode if provided\n if (spec.darkMode !== undefined && !VALID_DARK_MODES.has(spec.darkMode as string)) {\n errors.push({\n message: `Spec error: darkMode must be \"auto\", \"force\", or \"off\"`,\n path: 'darkMode',\n code: 'INVALID_VALUE',\n suggestion:\n 'Use one of: \"auto\" (system preference), \"force\" (always dark), or \"off\" (always light)',\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Table validation\n// ---------------------------------------------------------------------------\n\nfunction validateTableSpec(spec: Record<string, unknown>, errors: ValidationError[]): void {\n if (!Array.isArray(spec.data)) {\n errors.push({\n message: 'Spec error: \"data\" must be an array',\n path: 'data',\n code: 'INVALID_TYPE',\n suggestion: 'Provide data as an array of objects, e.g. data: [{ name: \"Alice\", age: 30 }]',\n });\n return;\n }\n\n if (spec.data.length === 0) {\n errors.push({\n message: 'Spec error: \"data\" must be a non-empty array',\n path: 'data',\n code: 'EMPTY_DATA',\n suggestion: 'Add at least one data row to the data array',\n });\n return;\n }\n\n if (!Array.isArray(spec.columns)) {\n errors.push({\n message: 'Spec error: table spec requires a \"columns\" array',\n path: 'columns',\n code: 'MISSING_FIELD',\n suggestion:\n 'Add a columns array defining which data fields to display, e.g. columns: [{ key: \"name\" }, { key: \"age\" }]',\n });\n return;\n }\n\n const data = spec.data as Record<string, unknown>[];\n const firstRow = data[0];\n if (typeof firstRow !== 'object' || firstRow === null || Array.isArray(firstRow)) {\n errors.push({\n message: 'Spec error: each item in \"data\" must be a plain object',\n path: 'data[0]',\n code: 'INVALID_TYPE',\n suggestion:\n 'Each data item should be an object with key-value pairs, e.g. { name: \"Alice\", age: 30 }',\n });\n return;\n }\n\n const dataColumns = new Set(Object.keys(firstRow as Record<string, unknown>));\n const availableColumns = [...dataColumns].join(', ');\n const columns = spec.columns as Record<string, unknown>[];\n\n for (let i = 0; i < columns.length; i++) {\n const col = columns[i];\n if (!col || typeof col !== 'object') {\n errors.push({\n message: `Spec error: columns[${i}] must be an object`,\n path: `columns[${i}]`,\n code: 'INVALID_TYPE',\n suggestion: 'Each column entry should be an object, e.g. { key: \"fieldName\" }',\n });\n continue;\n }\n\n // Check key exists\n if (!col.key || typeof col.key !== 'string') {\n errors.push({\n message: `Spec error: columns[${i}] must have a \"key\" string`,\n path: `columns[${i}].key`,\n code: 'MISSING_FIELD',\n suggestion: `Add a key referencing a data field. Available columns: ${availableColumns}`,\n });\n continue;\n }\n\n // Check key references a field in data\n if (!dataColumns.has(col.key as string)) {\n errors.push({\n message: `Spec error: columns[${i}].key \"${col.key}\" does not exist in data. Available columns: ${availableColumns}`,\n path: `columns[${i}].key`,\n code: 'DATA_FIELD_MISSING',\n suggestion: `Use one of the available data columns: ${availableColumns}`,\n });\n }\n\n // Check at most one visual enhancement\n const visuals = ['heatmap', 'bar', 'sparkline', 'image', 'flag', 'categoryColors'].filter(\n (v) => col[v] != null && col[v] !== false,\n );\n if (visuals.length > 1) {\n errors.push({\n message: `Spec error: columns[${i}] has multiple visual features (${visuals.join(', ')}). Only one is allowed per column.`,\n path: `columns[${i}]`,\n code: 'INVALID_VALUE',\n suggestion: `Keep only one visual feature per column. Remove all but one of: ${visuals.join(', ')}`,\n });\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Graph validation\n// ---------------------------------------------------------------------------\n\nfunction validateGraphSpec(spec: Record<string, unknown>, errors: ValidationError[]): void {\n // Validate nodes array exists and is non-empty\n if (!Array.isArray(spec.nodes)) {\n errors.push({\n message: 'Spec error: graph spec requires a \"nodes\" array',\n path: 'nodes',\n code: 'MISSING_FIELD',\n suggestion:\n 'Add a nodes array with objects that have an \"id\" field, e.g. nodes: [{ id: \"a\" }, { id: \"b\" }]',\n });\n return; // Can't validate further without nodes\n }\n\n if (spec.nodes.length === 0) {\n errors.push({\n message: 'Spec error: \"nodes\" must be a non-empty array',\n path: 'nodes',\n code: 'EMPTY_DATA',\n suggestion: 'Add at least one node, e.g. nodes: [{ id: \"a\" }]',\n });\n return;\n }\n\n // Validate each node has a string id\n const nodeIds = new Set<string>();\n const nodes = spec.nodes as Record<string, unknown>[];\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n if (!node || typeof node !== 'object') {\n errors.push({\n message: `Spec error: nodes[${i}] must be an object`,\n path: `nodes[${i}]`,\n code: 'INVALID_TYPE',\n suggestion: 'Each node must be an object with at least an \"id\" field, e.g. { id: \"a\" }',\n });\n continue;\n }\n if (typeof node.id !== 'string' || node.id === '') {\n errors.push({\n message: `Spec error: nodes[${i}] must have a non-empty string \"id\" field`,\n path: `nodes[${i}].id`,\n code: 'MISSING_FIELD',\n suggestion: 'Add a string id to the node, e.g. { id: \"node1\" }',\n });\n } else {\n nodeIds.add(node.id);\n }\n }\n\n // Validate edges array exists\n if (!Array.isArray(spec.edges)) {\n errors.push({\n message: 'Spec error: graph spec requires an \"edges\" array',\n path: 'edges',\n code: 'MISSING_FIELD',\n suggestion: 'Add an edges array (can be empty), e.g. edges: [{ source: \"a\", target: \"b\" }]',\n });\n return;\n }\n\n // Validate each edge has string source and target that reference existing nodes\n const edges = spec.edges as Record<string, unknown>[];\n for (let i = 0; i < edges.length; i++) {\n const edge = edges[i];\n if (!edge || typeof edge !== 'object') {\n errors.push({\n message: `Spec error: edges[${i}] must be an object`,\n path: `edges[${i}]`,\n code: 'INVALID_TYPE',\n suggestion:\n 'Each edge must be an object with \"source\" and \"target\" fields, e.g. { source: \"a\", target: \"b\" }',\n });\n continue;\n }\n\n if (typeof edge.source !== 'string' || edge.source === '') {\n errors.push({\n message: `Spec error: edges[${i}] must have a non-empty string \"source\" field`,\n path: `edges[${i}].source`,\n code: 'MISSING_FIELD',\n suggestion: 'Add a source node id, e.g. { source: \"a\", target: \"b\" }',\n });\n } else if (nodeIds.size > 0 && !nodeIds.has(edge.source)) {\n errors.push({\n message: `Spec error: edges[${i}].source \"${edge.source}\" does not reference an existing node id`,\n path: `edges[${i}].source`,\n code: 'DATA_FIELD_MISSING',\n suggestion: `Use one of the existing node ids: ${[...nodeIds].slice(0, 5).join(', ')}${nodeIds.size > 5 ? '...' : ''}`,\n });\n }\n\n if (typeof edge.target !== 'string' || edge.target === '') {\n errors.push({\n message: `Spec error: edges[${i}] must have a non-empty string \"target\" field`,\n path: `edges[${i}].target`,\n code: 'MISSING_FIELD',\n suggestion: 'Add a target node id, e.g. { source: \"a\", target: \"b\" }',\n });\n } else if (nodeIds.size > 0 && !nodeIds.has(edge.target)) {\n errors.push({\n message: `Spec error: edges[${i}].target \"${edge.target}\" does not reference an existing node id`,\n path: `edges[${i}].target`,\n code: 'DATA_FIELD_MISSING',\n suggestion: `Use one of the existing node ids: ${[...nodeIds].slice(0, 5).join(', ')}${nodeIds.size > 5 ? '...' : ''}`,\n });\n }\n }\n\n // Validate encoding fields exist on at least the first node/edge\n if (spec.encoding && typeof spec.encoding === 'object') {\n const encoding = spec.encoding as Record<string, unknown>;\n const firstNode = nodes[0] as Record<string, unknown>;\n const firstEdge = edges.length > 0 ? (edges[0] as Record<string, unknown>) : null;\n const nodeFields = firstNode ? new Set(Object.keys(firstNode)) : new Set<string>();\n const edgeFields = firstEdge ? new Set(Object.keys(firstEdge)) : new Set<string>();\n\n const nodeChannels = ['nodeColor', 'nodeSize', 'nodeLabel'] as const;\n for (const channel of nodeChannels) {\n const ch = encoding[channel] as Record<string, unknown> | undefined;\n if (ch?.field && typeof ch.field === 'string' && !nodeFields.has(ch.field)) {\n errors.push({\n message: `Spec error: encoding.${channel}.field \"${ch.field}\" does not exist on nodes. Available fields: ${[...nodeFields].join(', ')}`,\n path: `encoding.${channel}.field`,\n code: 'DATA_FIELD_MISSING',\n suggestion: `Use one of the node fields: ${[...nodeFields].join(', ')}`,\n });\n }\n }\n\n const edgeChannels = ['edgeColor', 'edgeWidth'] as const;\n for (const channel of edgeChannels) {\n const ch = encoding[channel] as Record<string, unknown> | undefined;\n if (ch?.field && typeof ch.field === 'string' && firstEdge && !edgeFields.has(ch.field)) {\n errors.push({\n message: `Spec error: encoding.${channel}.field \"${ch.field}\" does not exist on edges. Available fields: ${[...edgeFields].join(', ')}`,\n path: `encoding.${channel}.field`,\n code: 'DATA_FIELD_MISSING',\n suggestion: `Use one of the edge fields: ${[...edgeFields].join(', ')}`,\n });\n }\n }\n }\n\n // Validate layout type if specified\n if (spec.layout && typeof spec.layout === 'object') {\n const layout = spec.layout as Record<string, unknown>;\n if (layout.type && layout.type !== 'force') {\n errors.push({\n message: `Spec error: layout.type \"${layout.type}\" is not supported. Only \"force\" is currently supported`,\n path: 'layout.type',\n code: 'INVALID_VALUE',\n suggestion:\n 'Use layout.type: \"force\" or omit the layout field to use the default force layout',\n });\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Sankey validation\n// ---------------------------------------------------------------------------\n\nfunction validateSankeySpec(spec: Record<string, unknown>, errors: ValidationError[]): void {\n // Validate data\n if (!Array.isArray(spec.data)) {\n errors.push({\n message: 'Spec error: sankey spec requires a \"data\" array',\n path: 'data',\n code: 'INVALID_TYPE',\n suggestion:\n 'Provide data as an array of objects, e.g. data: [{ source: \"A\", target: \"B\", value: 10 }]',\n });\n return;\n }\n\n if (spec.data.length === 0) {\n errors.push({\n message: 'Spec error: \"data\" must be a non-empty array',\n path: 'data',\n code: 'EMPTY_DATA',\n suggestion: 'Add at least one data row, e.g. data: [{ source: \"A\", target: \"B\", value: 10 }]',\n });\n return;\n }\n\n const firstRow = spec.data[0] as unknown;\n if (typeof firstRow !== 'object' || firstRow === null || Array.isArray(firstRow)) {\n errors.push({\n message: 'Spec error: each item in \"data\" must be a plain object',\n path: 'data[0]',\n code: 'INVALID_TYPE',\n suggestion:\n 'Each data item should be an object, e.g. { source: \"A\", target: \"B\", value: 10 }',\n });\n return;\n }\n\n // Validate encoding\n if (!spec.encoding || typeof spec.encoding !== 'object') {\n errors.push({\n message:\n 'Spec error: sankey spec requires an \"encoding\" object with source, target, and value channels',\n path: 'encoding',\n code: 'MISSING_FIELD',\n suggestion:\n 'Add an encoding object, e.g. encoding: { source: { field: \"source\", type: \"nominal\" }, target: { field: \"target\", type: \"nominal\" }, value: { field: \"value\", type: \"quantitative\" } }',\n });\n return;\n }\n\n const encoding = spec.encoding as Record<string, unknown>;\n const dataColumns = new Set(Object.keys(firstRow as Record<string, unknown>));\n const availableColumns = [...dataColumns].join(', ');\n\n // Required channels\n for (const channel of ['source', 'target', 'value'] as const) {\n const ch = encoding[channel] as Record<string, unknown> | undefined;\n if (!ch || typeof ch !== 'object') {\n errors.push({\n message: `Spec error: sankey encoding requires \"${channel}\" channel`,\n path: `encoding.${channel}`,\n code: 'MISSING_FIELD',\n suggestion: `Add encoding.${channel} with a field from your data (${availableColumns}). Example: ${channel}: { field: \"${[...dataColumns][0] ?? 'myField'}\", type: \"${channel === 'value' ? 'quantitative' : 'nominal'}\" }`,\n });\n continue;\n }\n\n if (!ch.field || typeof ch.field !== 'string') {\n errors.push({\n message: `Spec error: encoding.${channel} must have a \"field\" string`,\n path: `encoding.${channel}.field`,\n code: 'MISSING_FIELD',\n suggestion: `Add a field name from your data columns: ${availableColumns}`,\n });\n continue;\n }\n\n if (!dataColumns.has(ch.field as string)) {\n errors.push({\n message: `Spec error: encoding.${channel}.field \"${ch.field}\" does not exist in data. Available columns: ${availableColumns}`,\n path: `encoding.${channel}.field`,\n code: 'DATA_FIELD_MISSING',\n suggestion: `Use one of the available data columns: ${availableColumns}`,\n });\n }\n }\n\n // Validate darkMode if provided\n if (spec.darkMode !== undefined && !VALID_DARK_MODES.has(spec.darkMode as string)) {\n errors.push({\n message: 'Spec error: darkMode must be \"auto\", \"force\", or \"off\"',\n path: 'darkMode',\n code: 'INVALID_VALUE',\n suggestion:\n 'Use one of: \"auto\" (system preference), \"force\" (always dark), or \"off\" (always light)',\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Layer validation\n// ---------------------------------------------------------------------------\n\nfunction validateLayerSpec(spec: Record<string, unknown>, errors: ValidationError[]): void {\n const layer = spec.layer as unknown[];\n\n if (layer.length === 0) {\n errors.push({\n message: 'Spec error: \"layer\" must be a non-empty array',\n path: 'layer',\n code: 'EMPTY_DATA',\n suggestion: 'Add at least one layer with a mark and encoding',\n });\n return;\n }\n\n for (let i = 0; i < layer.length; i++) {\n const child = layer[i];\n if (!child || typeof child !== 'object' || Array.isArray(child)) {\n errors.push({\n message: `Spec error: layer[${i}] must be an object`,\n path: `layer[${i}]`,\n code: 'INVALID_TYPE',\n suggestion:\n 'Each layer must be a chart spec (with mark) or a nested layer spec (with layer)',\n });\n continue;\n }\n\n const childObj = child as Record<string, unknown>;\n const isNestedLayer = 'layer' in childObj && Array.isArray(childObj.layer);\n const isChildChart = 'mark' in childObj;\n\n if (!isNestedLayer && !isChildChart) {\n errors.push({\n message: `Spec error: layer[${i}] must have a \"mark\" field or a \"layer\" array`,\n path: `layer[${i}]`,\n code: 'MISSING_FIELD',\n suggestion:\n 'Each layer must be a chart spec (with mark + encoding) or a nested layer spec (with layer array)',\n });\n continue;\n }\n\n if (isNestedLayer) {\n validateLayerSpec(childObj, errors);\n } else if (isChildChart) {\n // Validate mark type\n const mark = childObj.mark;\n let markValue: string | undefined;\n if (typeof mark === 'string') {\n markValue = mark;\n } else if (mark && typeof mark === 'object' && !Array.isArray(mark)) {\n markValue = (mark as Record<string, unknown>).type as string | undefined;\n }\n\n if (!markValue || !MARK_TYPES.has(markValue)) {\n errors.push({\n message: `Spec error: layer[${i}].mark \"${markValue ?? String(mark)}\" is not a valid mark type`,\n path: `layer[${i}].mark`,\n code: 'INVALID_VALUE',\n suggestion: `Change mark to one of: ${[...MARK_TYPES].join(', ')}`,\n });\n continue;\n }\n\n // Child layers can inherit data and encoding from parent, so only validate\n // if the child has its own data (or the parent provides shared data).\n const hasOwnData = Array.isArray(childObj.data) && (childObj.data as unknown[]).length > 0;\n const parentHasData = Array.isArray(spec.data) && (spec.data as unknown[]).length > 0;\n\n if (hasOwnData || parentHasData) {\n // Build a merged spec for validation purposes\n const mergedForValidation = { ...childObj };\n if (!hasOwnData && parentHasData) {\n mergedForValidation.data = spec.data;\n }\n // Merge encoding: parent fields are inherited unless child overrides\n if (spec.encoding && typeof spec.encoding === 'object') {\n mergedForValidation.encoding = {\n ...(spec.encoding as Record<string, unknown>),\n ...((childObj.encoding as Record<string, unknown>) ?? {}),\n };\n }\n if (mergedForValidation.data && mergedForValidation.encoding) {\n validateChartSpec(mergedForValidation, errors);\n }\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Validate a spec at runtime.\n *\n * Checks structure, required fields, encoding rules, data shape, and\n * field type compatibility. Returns structured errors with machine-readable\n * codes and actionable suggestions for each problem found.\n */\nexport function validateSpec(spec: unknown): ValidationResult {\n const errors: ValidationError[] = [];\n\n // Basic shape check\n if (!spec || typeof spec !== 'object' || Array.isArray(spec)) {\n return {\n valid: false,\n errors: [\n {\n message: 'Spec error: spec must be a non-null object',\n code: 'INVALID_TYPE',\n suggestion:\n 'Pass a spec object with at least a \"mark\" field for charts, e.g. { mark: \"line\", data: [...], encoding: {...} }',\n },\n ],\n normalized: null,\n };\n }\n\n const obj = spec as Record<string, unknown>;\n\n // Determine spec type via structural discrimination:\n // - Layer specs have a 'layer' array\n // - Chart specs have a 'mark' field (string or object with type property)\n // - Table specs have type: 'table'\n // - Graph specs have type: 'graph'\n const hasLayer = 'layer' in obj && Array.isArray(obj.layer);\n const hasMark = 'mark' in obj;\n const isTable = obj.type === 'table';\n const isGraph = obj.type === 'graph';\n const isSankey = obj.type === 'sankey';\n const isLayer = hasLayer && !isTable && !isGraph && !isSankey;\n const isChart = hasMark && !hasLayer && !isTable && !isGraph && !isSankey;\n\n if (!isChart && !isTable && !isGraph && !isSankey && !isLayer) {\n return {\n valid: false,\n errors: [\n {\n message:\n 'Spec error: spec must have a \"mark\" field for charts, a \"layer\" array for layered charts, or a \"type\" field for tables/graphs/sankey',\n path: 'mark',\n code: 'MISSING_FIELD',\n suggestion: `Add a \"mark\" field for charts (e.g. mark: \"bar\"), a \"layer\" array for layered charts, or a \"type\" field for tables/graphs/sankey (type: \"table\", type: \"graph\", or type: \"sankey\"). Valid mark types: ${[...MARK_TYPES].join(', ')}`,\n },\n ],\n normalized: null,\n };\n }\n\n // For layer specs, validate each child layer recursively\n if (isLayer) {\n validateLayerSpec(obj, errors);\n }\n\n // For chart specs, validate the mark field\n if (isChart) {\n const mark = obj.mark;\n let markValue: string | undefined;\n\n if (typeof mark === 'string') {\n markValue = mark;\n } else if (mark && typeof mark === 'object' && !Array.isArray(mark)) {\n markValue = (mark as Record<string, unknown>).type as string | undefined;\n }\n\n if (!markValue || !MARK_TYPES.has(markValue)) {\n return {\n valid: false,\n errors: [\n {\n message: `Spec error: \"${markValue ?? String(mark)}\" is not a valid mark type. Valid mark types: ${[...MARK_TYPES].join(', ')}`,\n path: 'mark',\n code: 'INVALID_VALUE',\n suggestion: `Change mark to one of: ${[...MARK_TYPES].join(', ')}`,\n },\n ],\n normalized: null,\n };\n }\n\n validateChartSpec(obj, errors);\n } else if (isTable) {\n validateTableSpec(obj, errors);\n } else if (isGraph) {\n validateGraphSpec(obj, errors);\n } else if (isSankey) {\n validateSankeySpec(obj, errors);\n }\n\n if (errors.length > 0) {\n return { valid: false, errors, normalized: null };\n }\n\n return {\n valid: true,\n errors: [],\n normalized: spec as VizSpec,\n };\n}\n","/**\n * Spec compiler: validate -> normalize pipeline.\n *\n * This is the first stage of the engine: take raw user input (possibly JSON\n * from an API or Claude), validate it, fill in defaults, and produce a\n * NormalizedSpec that the rest of the engine can work with safely.\n */\n\nimport { normalizeSpec } from './normalize';\nimport type { CompileResult } from './types';\nimport { validateSpec } from './validate';\n\n/**\n * Compile a raw spec through the validate -> normalize pipeline.\n *\n * @param spec - Raw spec input (unknown type, could be anything).\n * @returns CompileResult with the normalized spec and any warnings.\n * @throws Error if the spec is invalid.\n */\nexport function compile(spec: unknown): CompileResult {\n const validation = validateSpec(spec);\n\n if (!validation.valid || !validation.normalized) {\n const errorMessages = validation.errors.map((e) => e.message).join('\\n');\n throw new Error(`Invalid spec:\\n${errorMessages}`);\n }\n\n const warnings: string[] = [];\n const normalized = normalizeSpec(validation.normalized, warnings);\n\n return { spec: normalized, warnings };\n}\n\nexport { flattenLayers, normalizeSpec } from './normalize';\nexport type {\n CompileResult,\n NormalizedChartSpec,\n NormalizedChrome,\n NormalizedGraphSpec,\n NormalizedSpec,\n NormalizedTableSpec,\n ValidationError,\n ValidationErrorCode,\n ValidationResult,\n} from './types';\n// Re-export everything\nexport { validateSpec } from './validate';\n","/**\n * Graph compilation pipeline.\n *\n * Takes a raw graph spec (unknown shape), validates, normalizes, resolves\n * encoding channels to visual properties, assigns communities, builds\n * legend/tooltips/a11y, and returns a GraphCompilation.\n *\n * The pipeline mirrors compileChart's structure:\n * validate -> normalize -> resolve theme -> resolve visuals ->\n * community assignment -> legend -> tooltips -> a11y -> return\n *\n * Key difference from charts: the output does NOT include x/y positions.\n * The force simulation in the adapter handles layout at runtime.\n */\n\nimport type {\n CompileOptions,\n LegendEntry,\n LegendLayout,\n ResolvedTheme,\n TextStyle,\n TooltipContent,\n TooltipField,\n} from '@opendata-ai/openchart-core';\nimport { adaptTheme, computeChrome, resolveTheme } from '@opendata-ai/openchart-core';\n\nimport { compile as compileSpec } from '../compiler/index';\nimport type { NormalizedGraphSpec } from '../compiler/types';\nimport { applyCommunityColors, assignCommunities, buildCommunityColorMap } from './community';\nimport { resolveEdgeVisuals, resolveNodeVisuals } from './encoding';\nimport type { CompiledGraphNode, GraphCompilation, SimulationConfig } from './types';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst SWATCH_SIZE = 12;\nconst SWATCH_GAP = 6;\nconst ENTRY_GAP = 16;\n\n// ---------------------------------------------------------------------------\n// Legend builder\n// ---------------------------------------------------------------------------\n\n/**\n * Build a legend from community assignments or nodeColor encoding.\n *\n * Built manually instead of reusing computeLegend (which assumes chart\n * encoding channels). Returns entries with color swatches and labels.\n * Position is placeholder (adapter determines actual placement).\n */\nfunction buildGraphLegend(\n nodes: CompiledGraphNode[],\n communityColorMap: Map<string, string>,\n hasCommunities: boolean,\n theme: ResolvedTheme,\n nodeColorField?: string,\n): LegendLayout {\n const labelStyle: TextStyle = {\n fontFamily: theme.fonts.family,\n fontSize: theme.fonts.sizes.small,\n fontWeight: theme.fonts.weights.normal,\n fill: theme.colors.text,\n lineHeight: 1.3,\n };\n\n let entries: LegendEntry[];\n\n if (hasCommunities && communityColorMap.size > 0) {\n // One entry per community\n entries = [...communityColorMap.entries()].map(([label, color]) => ({\n label,\n color,\n shape: 'circle' as const,\n active: true,\n }));\n } else {\n // Build legend from nodeColor encoding: group by the color field value\n // so each legend entry shows the categorical value (e.g. \"Dataset\", \"bls\")\n // rather than an arbitrary node label.\n const categoryColors = new Map<string, string>();\n for (const node of nodes) {\n const category = nodeColorField\n ? String(node.data[nodeColorField] ?? node.label ?? node.id)\n : (node.label ?? node.id);\n if (!categoryColors.has(category)) {\n categoryColors.set(category, node.fill);\n }\n }\n\n // Only show legend if there are multiple categories\n if (categoryColors.size <= 1) {\n entries = [];\n } else {\n entries = [...categoryColors.entries()].map(([label, color]) => ({\n label,\n color,\n shape: 'circle' as const,\n active: true,\n }));\n }\n }\n\n return {\n position: 'top',\n entries,\n bounds: { x: 0, y: 0, width: 0, height: 0 },\n labelStyle,\n swatchSize: SWATCH_SIZE,\n swatchGap: SWATCH_GAP,\n entryGap: ENTRY_GAP,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Tooltip builder\n// ---------------------------------------------------------------------------\n\n/**\n * Build tooltip descriptors for each node.\n *\n * Keyed by node id. Shows all data fields, label, and community.\n */\nfunction buildGraphTooltips(nodes: CompiledGraphNode[]): Map<string, TooltipContent> {\n const descriptors = new Map<string, TooltipContent>();\n\n for (const node of nodes) {\n const fields: TooltipField[] = [];\n\n // Add community if present\n if (node.community != null) {\n fields.push({\n label: 'Community',\n value: node.community,\n color: node.fill,\n });\n }\n\n // Add all data fields (excluding id since it's the title)\n for (const [key, value] of Object.entries(node.data)) {\n if (key === 'id') continue;\n if (value == null) continue;\n\n fields.push({\n label: key,\n value: typeof value === 'number' ? value.toLocaleString() : String(value),\n });\n }\n\n descriptors.set(node.id, {\n title: node.label ?? node.id,\n fields,\n });\n }\n\n return descriptors;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a graph spec into a GraphCompilation.\n *\n * Pipeline:\n * 1. Validate + normalize via the shared compiler pipeline\n * 2. Resolve theme (merge spec + options, apply dark mode)\n * 3. Resolve node visuals (size, color, label, stroke)\n * 4. Assign communities if layout.clustering is set\n * 5. Apply community colors (override nodeColor)\n * 6. Resolve edge visuals (width, color)\n * 7. Build legend from communities or nodeColor\n * 8. Build tooltip descriptors for each node\n * 9. Build a11y metadata\n * 10. Build simulation config from spec layout\n * 11. Build chrome from spec + theme\n * 12. Return GraphCompilation\n *\n * @param spec - Raw graph spec (validated at runtime).\n * @param options - Compile options (width, height, theme, darkMode).\n * @returns GraphCompilation with resolved visual properties.\n * @throws Error if spec is invalid or not a graph type.\n */\nexport function compileGraph(spec: unknown, options: CompileOptions): GraphCompilation {\n // 1. Validate + normalize\n const { spec: normalized } = compileSpec(spec);\n\n if (!('type' in normalized) || normalized.type !== 'graph') {\n throw new Error(\n 'compileGraph received a non-graph spec. Use compileChart or compileTable instead.',\n );\n }\n\n const graphSpec = normalized as NormalizedGraphSpec;\n\n // Resolve watermark: explicit spec value wins, then options fallback, then default true.\n const rawWatermark = (spec as Record<string, unknown>).watermark;\n const watermark = rawWatermark !== undefined ? graphSpec.watermark : (options.watermark ?? true);\n\n // 2. Resolve theme\n const mergedThemeConfig = options.theme\n ? { ...graphSpec.theme, ...options.theme }\n : graphSpec.theme;\n let theme: ResolvedTheme = resolveTheme(mergedThemeConfig);\n if (options.darkMode) {\n theme = adaptTheme(theme);\n }\n\n // 3. Resolve node visuals\n const compiledNodes = resolveNodeVisuals(\n graphSpec.nodes,\n graphSpec.encoding,\n graphSpec.edges,\n theme,\n graphSpec.nodeOverrides,\n );\n\n // 4. Assign communities (for force simulation grouping)\n const clusteringField = graphSpec.layout.clustering?.field;\n const hasCommunities = !!clusteringField;\n assignCommunities(compiledNodes, clusteringField);\n\n // 5. Apply community colors only when no explicit nodeColor encoding is set.\n // When the consumer specifies nodeColor (e.g. by nodeType or provider), that\n // encoding should drive both fill colors and legend entries.\n const hasNodeColorEncoding = !!graphSpec.encoding.nodeColor?.field;\n let communityColorMap = new Map<string, string>();\n if (hasCommunities && !hasNodeColorEncoding) {\n communityColorMap = buildCommunityColorMap(compiledNodes, theme);\n applyCommunityColors(compiledNodes, communityColorMap);\n }\n\n // 6. Resolve edge visuals\n const compiledEdges = resolveEdgeVisuals(graphSpec.edges, graphSpec.encoding, theme);\n\n // 7. Build legend (use nodeColor encoding colors when present, community otherwise)\n const useCommunitiesForLegend = hasCommunities && !hasNodeColorEncoding;\n const legend = buildGraphLegend(\n compiledNodes,\n communityColorMap,\n useCommunitiesForLegend,\n theme,\n graphSpec.encoding.nodeColor?.field,\n );\n\n // 8. Build tooltips\n const tooltipDescriptors = buildGraphTooltips(compiledNodes);\n\n // 9. Build a11y metadata\n const communityCount = communityColorMap.size;\n const altParts = [\n `Network graph with ${compiledNodes.length} nodes and ${compiledEdges.length} edges`,\n ];\n if (communityCount > 0) {\n altParts.push(`organized into ${communityCount} communities`);\n }\n const a11y = {\n altText: altParts.join(', '),\n dataTableFallback: compiledNodes.map((n) => [n.id, n.community ?? '', n.label ?? '']),\n role: 'img',\n keyboardNavigable: compiledNodes.length > 0,\n };\n\n // 10. Build simulation config\n const collisionPadding = graphSpec.layout.collisionPadding ?? 2;\n const maxRadius =\n compiledNodes.length > 0\n ? Math.max(...compiledNodes.map((n) => n.radius))\n : DEFAULT_COLLISION_PADDING;\n const simulationConfig: SimulationConfig = {\n chargeStrength: graphSpec.layout.chargeStrength ?? -300,\n linkDistance: graphSpec.layout.linkDistance ?? 30,\n clustering: clusteringField ? { field: clusteringField, strength: 0.5 } : null,\n alphaDecay: 0.0228,\n velocityDecay: 0.4,\n collisionRadius: maxRadius + collisionPadding,\n collisionPadding,\n linkStrength: graphSpec.layout.linkStrength,\n centerForce: graphSpec.layout.centerForce,\n };\n\n // 11. Build chrome\n const chrome = computeChrome(\n {\n title: graphSpec.chrome.title,\n subtitle: graphSpec.chrome.subtitle,\n source: graphSpec.chrome.source,\n byline: graphSpec.chrome.byline,\n footer: graphSpec.chrome.footer,\n },\n theme,\n options.width,\n options.measureText,\n 'full',\n undefined,\n watermark,\n );\n\n // 12. Return compilation\n return {\n nodes: compiledNodes,\n edges: compiledEdges,\n legend,\n chrome,\n tooltipDescriptors,\n a11y,\n theme,\n dimensions: {\n width: options.width,\n height: options.height,\n },\n simulationConfig,\n watermark,\n };\n}\n\n/** Default padding for collision radius when there are no nodes. */\nconst DEFAULT_COLLISION_PADDING = 5;\n","/**\n * Graph encoding resolution.\n *\n * Maps graph encoding channels (nodeSize, nodeColor, edgeWidth, edgeColor,\n * nodeLabel) to computed visual properties on nodes and edges. Uses d3 scales\n * the same way scatter/bubble charts do: scaleSqrt for size, scaleOrdinal\n * for categorical color, scaleLinear for quantitative color.\n */\n\nimport type {\n GraphEdge,\n GraphEncoding,\n GraphNode,\n NodeOverride,\n ResolvedTheme,\n} from '@opendata-ai/openchart-core';\nimport { max, min } from 'd3-array';\nimport { scaleLinear, scaleOrdinal, scaleSqrt } from 'd3-scale';\n\nimport type { CompiledGraphEdge, CompiledGraphNode } from './types';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_NODE_RADIUS = 5;\nconst MIN_NODE_RADIUS = 3;\nconst MAX_NODE_RADIUS = 12;\n\nconst DEFAULT_EDGE_WIDTH = 1;\nconst MIN_EDGE_WIDTH = 0.5;\nconst MAX_EDGE_WIDTH = 4;\n\nconst DEFAULT_STROKE_WIDTH = 1;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Darken a hex color by a percentage.\n *\n * Doesn't use d3-color (engine doesn't depend on it). Operates directly\n * on hex RGB channels. Falls back to the original color on parse failure.\n */\nexport function darkenColor(hex: string, amount: number = 0.2): string {\n // Strip # prefix\n const clean = hex.replace(/^#/, '');\n if (clean.length !== 6 && clean.length !== 3) return hex;\n\n // Expand shorthand\n const full =\n clean.length === 3\n ? clean\n .split('')\n .map((c) => c + c)\n .join('')\n : clean;\n\n const r = Math.max(0, Math.round(parseInt(full.substring(0, 2), 16) * (1 - amount)));\n const g = Math.max(0, Math.round(parseInt(full.substring(2, 4), 16) * (1 - amount)));\n const b = Math.max(0, Math.round(parseInt(full.substring(4, 6), 16) * (1 - amount)));\n\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;\n}\n\n/**\n * Apply opacity to a hex color, returning an rgba string.\n */\nfunction hexWithOpacity(hex: string, opacity: number): string {\n const clean = hex.replace(/^#/, '');\n if (clean.length !== 6 && clean.length !== 3) {\n // Non-hex input: return as-is with opacity via CSS\n return hex;\n }\n\n const full =\n clean.length === 3\n ? clean\n .split('')\n .map((c) => c + c)\n .join('')\n : clean;\n\n const r = parseInt(full.substring(0, 2), 16);\n const g = parseInt(full.substring(2, 4), 16);\n const b = parseInt(full.substring(4, 6), 16);\n\n return `rgba(${r}, ${g}, ${b}, ${opacity})`;\n}\n\n/**\n * Compute the degree of each node (number of edges touching it).\n */\nfunction computeDegrees(nodes: GraphNode[], edges: GraphEdge[]): Map<string, number> {\n const degrees = new Map<string, number>();\n for (const node of nodes) {\n degrees.set(node.id, 0);\n }\n for (const edge of edges) {\n degrees.set(edge.source, (degrees.get(edge.source) ?? 0) + 1);\n degrees.set(edge.target, (degrees.get(edge.target) ?? 0) + 1);\n }\n return degrees;\n}\n\n// ---------------------------------------------------------------------------\n// Node visual resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve visual properties for all graph nodes.\n *\n * Applies nodeSize, nodeColor, and nodeLabel encoding channels from the\n * spec to produce CompiledGraphNode objects with computed fill, radius,\n * stroke, label, and label priority.\n */\nexport function resolveNodeVisuals(\n nodes: GraphNode[],\n encoding: GraphEncoding,\n edges: GraphEdge[],\n theme: ResolvedTheme,\n nodeOverrides?: Record<string, NodeOverride>,\n): CompiledGraphNode[] {\n const degrees = computeDegrees(nodes, edges);\n const maxDegree = Math.max(1, ...degrees.values());\n\n // Build node size scale\n let sizeScale: ((v: number) => number) | undefined;\n if (encoding.nodeSize?.field) {\n const field = encoding.nodeSize.field;\n const values = nodes.map((n) => Number(n[field])).filter((v) => Number.isFinite(v));\n\n const sizeMin = min(values) ?? 0;\n const sizeMax = max(values) ?? 1;\n\n sizeScale = scaleSqrt().domain([sizeMin, sizeMax]).range([MIN_NODE_RADIUS, MAX_NODE_RADIUS]);\n }\n\n // Build node color scale\n let colorFn: ((node: GraphNode) => string) | undefined;\n if (encoding.nodeColor?.field) {\n const field = encoding.nodeColor.field;\n const fieldType = encoding.nodeColor.type ?? 'nominal';\n const scaleConfig = encoding.nodeColor.scale;\n\n if (fieldType === 'quantitative') {\n const values = nodes.map((n) => Number(n[field])).filter((v) => Number.isFinite(v));\n const colorMin = min(values) ?? 0;\n const colorMax = max(values) ?? 1;\n\n // Use first sequential palette\n const seqPalettes = Object.values(theme.colors.sequential);\n const palette = seqPalettes.length > 0 ? seqPalettes[0] : ['#ccc', '#333'];\n\n const domain =\n scaleConfig?.domain && scaleConfig.domain.length === 2\n ? (scaleConfig.domain as [number, number])\n : [colorMin, colorMax];\n const range =\n scaleConfig?.range && scaleConfig.range.length >= 2\n ? (scaleConfig.range as string[])\n : [palette[0], palette[palette.length - 1]];\n\n const colorScale = scaleLinear<string>().domain(domain).range(range);\n\n colorFn = (node: GraphNode) => {\n const val = Number(node[field]);\n return Number.isFinite(val) ? colorScale(val) : theme.colors.categorical[0];\n };\n } else {\n // nominal/ordinal\n const domain =\n scaleConfig?.domain && Array.isArray(scaleConfig.domain)\n ? (scaleConfig.domain as string[])\n : [...new Set(nodes.map((n) => String(n[field] ?? '')))];\n const range =\n scaleConfig?.range && scaleConfig.range.length > 0\n ? (scaleConfig.range as string[])\n : theme.colors.categorical;\n\n const ordinalScale = scaleOrdinal<string>().domain(domain).range(range);\n\n colorFn = (node: GraphNode) => ordinalScale(String(node[field] ?? ''));\n }\n }\n\n const defaultColor = theme.colors.categorical[0];\n\n return nodes.map((node) => {\n // Radius\n let radius = DEFAULT_NODE_RADIUS;\n if (sizeScale && encoding.nodeSize?.field) {\n const val = Number(node[encoding.nodeSize.field]);\n if (Number.isFinite(val)) {\n radius = sizeScale(val);\n }\n }\n\n // Color\n const fill = colorFn ? colorFn(node) : defaultColor;\n\n // Stroke: darken fill by 20%\n const stroke = darkenColor(fill);\n\n // Label\n let label: string | undefined;\n if (encoding.nodeLabel?.field) {\n const labelVal = node[encoding.nodeLabel.field];\n label = labelVal != null ? String(labelVal) : undefined;\n } else {\n label = node.id;\n }\n\n // Label priority: degree / maxDegree (0 to 1)\n const degree = degrees.get(node.id) ?? 0;\n const labelPriority = maxDegree > 0 ? degree / maxDegree : 0;\n\n // Data: spread all original node fields\n const { id: _id, ...rest } = node;\n const data: Record<string, unknown> = { id: node.id, ...rest };\n\n // Apply per-node overrides if present\n const override = nodeOverrides?.[node.id];\n const finalFill = override?.fill ?? fill;\n const finalRadius = override?.radius ?? radius;\n const finalStrokeWidth = override?.strokeWidth ?? DEFAULT_STROKE_WIDTH;\n const finalStroke = override?.stroke ?? stroke;\n const finalLabelPriority = override?.alwaysShowLabel ? Infinity : labelPriority;\n\n return {\n id: node.id,\n radius: finalRadius,\n fill: finalFill,\n stroke: finalStroke,\n strokeWidth: finalStrokeWidth,\n label,\n labelPriority: finalLabelPriority,\n community: undefined,\n data,\n };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Edge visual resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve visual properties for all graph edges.\n *\n * Applies edgeWidth and edgeColor encoding channels to produce\n * CompiledGraphEdge objects with computed stroke, strokeWidth, and style.\n */\nexport function resolveEdgeVisuals(\n edges: GraphEdge[],\n encoding: GraphEncoding,\n theme: ResolvedTheme,\n): CompiledGraphEdge[] {\n // Edge width scale\n let widthScale: ((v: number) => number) | undefined;\n if (encoding.edgeWidth?.field) {\n const field = encoding.edgeWidth.field;\n const values = edges.map((e) => Number(e[field])).filter((v) => Number.isFinite(v));\n\n const widthMin = min(values) ?? 0;\n const widthMax = max(values) ?? 1;\n\n widthScale = scaleLinear().domain([widthMin, widthMax]).range([MIN_EDGE_WIDTH, MAX_EDGE_WIDTH]);\n }\n\n // Edge color scale\n let edgeColorFn: ((edge: GraphEdge) => string) | undefined;\n if (encoding.edgeColor?.field) {\n const field = encoding.edgeColor.field;\n const fieldType = encoding.edgeColor.type ?? 'nominal';\n const scaleConfig = encoding.edgeColor.scale;\n\n if (fieldType === 'quantitative') {\n const values = edges.map((e) => Number(e[field])).filter((v) => Number.isFinite(v));\n const colorMin = min(values) ?? 0;\n const colorMax = max(values) ?? 1;\n\n const seqPalettes = Object.values(theme.colors.sequential);\n const palette = seqPalettes.length > 0 ? seqPalettes[0] : ['#ccc', '#333'];\n\n const domain =\n scaleConfig?.domain && scaleConfig.domain.length === 2\n ? (scaleConfig.domain as [number, number])\n : [colorMin, colorMax];\n const range =\n scaleConfig?.range && scaleConfig.range.length >= 2\n ? (scaleConfig.range as string[])\n : [palette[0], palette[palette.length - 1]];\n\n const colorScale = scaleLinear<string>().domain(domain).range(range);\n\n edgeColorFn = (edge: GraphEdge) => {\n const val = Number(edge[field]);\n return Number.isFinite(val) ? colorScale(val) : hexWithOpacity(theme.colors.axis, 0.4);\n };\n } else {\n const domain =\n scaleConfig?.domain && Array.isArray(scaleConfig.domain)\n ? (scaleConfig.domain as string[])\n : [...new Set(edges.map((e) => String(e[field] ?? '')))];\n const range =\n scaleConfig?.range && scaleConfig.range.length > 0\n ? (scaleConfig.range as string[])\n : theme.colors.categorical;\n\n const ordinalScale = scaleOrdinal<string>().domain(domain).range(range);\n\n edgeColorFn = (edge: GraphEdge) => ordinalScale(String(edge[field] ?? ''));\n }\n }\n\n const defaultEdgeColor = hexWithOpacity(theme.colors.axis, 0.4);\n\n // Edge style mapping (ordinal: map unique field values to solid/dashed/dotted)\n const EDGE_STYLES: Array<'solid' | 'dashed' | 'dotted'> = ['solid', 'dashed', 'dotted'];\n let styleFn: ((edge: GraphEdge) => 'solid' | 'dashed' | 'dotted') | undefined;\n if (encoding.edgeStyle?.field) {\n const field = encoding.edgeStyle.field;\n const uniqueValues = [...new Set(edges.map((e) => String(e[field] ?? '')))];\n const styleMap = new Map<string, 'solid' | 'dashed' | 'dotted'>();\n for (let i = 0; i < uniqueValues.length; i++) {\n styleMap.set(uniqueValues[i], EDGE_STYLES[i % EDGE_STYLES.length]);\n }\n styleFn = (edge: GraphEdge) => styleMap.get(String(edge[field] ?? '')) ?? 'solid';\n }\n\n return edges.map((edge) => {\n const { source, target, ...rest } = edge;\n\n let strokeWidth = DEFAULT_EDGE_WIDTH;\n if (widthScale && encoding.edgeWidth?.field) {\n const val = Number(edge[encoding.edgeWidth.field]);\n if (Number.isFinite(val)) {\n strokeWidth = widthScale(val);\n }\n }\n\n const stroke = edgeColorFn ? edgeColorFn(edge) : defaultEdgeColor;\n const style = styleFn ? styleFn(edge) : ('solid' as const);\n\n return {\n source,\n target,\n stroke,\n strokeWidth,\n style,\n data: { source, target, ...rest } as Record<string, unknown>,\n };\n });\n}\n","/**\n * Community assignment and color mapping for graph clustering.\n *\n * When a graph spec has layout.clustering.field, nodes are grouped into\n * communities based on their data values for that field. Each community\n * gets a color from the theme's categorical palette. Community colors\n * override nodeColor encoding when clustering is active.\n */\n\nimport type { ResolvedTheme } from '@opendata-ai/openchart-core';\nimport { darkenColor } from './encoding';\nimport type { CompiledGraphNode } from './types';\n\n// ---------------------------------------------------------------------------\n// Community assignment\n// ---------------------------------------------------------------------------\n\n/**\n * Assign community labels to compiled nodes based on a clustering field.\n *\n * Reads node.data[clusteringField] as the community label. If the field\n * is missing on a node, community remains undefined.\n *\n * Mutates nodes in-place for efficiency (no copy needed since we just\n * built them in the compilation pipeline).\n */\nexport function assignCommunities(\n nodes: CompiledGraphNode[],\n clusteringField: string | undefined,\n): void {\n if (!clusteringField) return;\n\n for (const node of nodes) {\n const value = node.data[clusteringField];\n node.community = value != null ? String(value) : undefined;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Community color mapping\n// ---------------------------------------------------------------------------\n\n/**\n * Build a map from community label to color.\n *\n * Collects unique community values (in order of first appearance),\n * then assigns theme categorical colors round-robin.\n */\nexport function buildCommunityColorMap(\n nodes: CompiledGraphNode[],\n theme: ResolvedTheme,\n): Map<string, string> {\n const colorMap = new Map<string, string>();\n const palette = theme.colors.categorical;\n let colorIndex = 0;\n\n for (const node of nodes) {\n if (node.community != null && !colorMap.has(node.community)) {\n colorMap.set(node.community, palette[colorIndex % palette.length]);\n colorIndex++;\n }\n }\n\n return colorMap;\n}\n\n// ---------------------------------------------------------------------------\n// Apply community colors\n// ---------------------------------------------------------------------------\n\n/**\n * Override node fill and stroke colors with community colors.\n *\n * Only affects nodes that have a community assignment. Nodes without\n * a community keep their existing fill/stroke from encoding resolution.\n *\n * Mutates nodes in-place.\n */\nexport function applyCommunityColors(\n nodes: CompiledGraphNode[],\n colorMap: Map<string, string>,\n): void {\n for (const node of nodes) {\n if (node.community != null) {\n const communityColor = colorMap.get(node.community);\n if (communityColor) {\n node.fill = communityColor;\n node.stroke = darkenColor(communityColor);\n }\n }\n }\n}\n","/**\n * Tick label overlap detection and density thinning.\n *\n * Horizontal orientation (x-axis): checks label width against adjacent\n * positions. Vertical orientation (y-axis): checks font-based label height\n * against adjacent positions, ignoring text width so wide numeric labels\n * don't trigger aggressive thinning.\n */\n\nimport type { AxisTick, MeasureTextFn } from '@opendata-ai/openchart-core';\nimport { estimateTextWidth } from '@opendata-ai/openchart-core';\n\n/**\n * Minimum gap between adjacent tick labels as a multiple of font size.\n * At the default 12px axis font, this yields ~12px of breathing room.\n */\nconst MIN_TICK_GAP_FACTOR = 1.0;\n\n/** Always show at least this many ticks, even if they overlap. */\nconst MIN_TICK_COUNT = 2;\n\n/** Measure a single label's width using real measurement or heuristic fallback. */\nexport function measureLabel(\n text: string,\n fontSize: number,\n fontWeight: number,\n measureText?: MeasureTextFn,\n): number {\n return measureText\n ? measureText(text, fontSize, fontWeight).width\n : estimateTextWidth(text, fontSize, fontWeight);\n}\n\n/** Check whether any adjacent tick labels overlap along the axis direction. */\nexport function ticksOverlap(\n ticks: AxisTick[],\n fontSize: number,\n fontWeight: number,\n measureText?: MeasureTextFn,\n orientation: 'horizontal' | 'vertical' = 'horizontal',\n): boolean {\n if (ticks.length < 2) return false;\n const minGap = fontSize * MIN_TICK_GAP_FACTOR;\n\n if (orientation === 'vertical') {\n // Y-axis: labels are stacked vertically. Check if vertical extent\n // (based on font height) overlaps between adjacent ticks.\n // Positions decrease going up in SVG coords, so sort ascending.\n const sorted = [...ticks].sort((a, b) => a.position - b.position);\n const labelHeight = fontSize * 1.2; // lineHeight\n for (let i = 0; i < sorted.length - 1; i++) {\n const aBottom = sorted[i].position + labelHeight / 2;\n const bTop = sorted[i + 1].position - labelHeight / 2;\n if (aBottom + minGap > bTop) return true;\n }\n return false;\n }\n\n for (let i = 0; i < ticks.length - 1; i++) {\n const aWidth = measureLabel(ticks[i].label, fontSize, fontWeight, measureText);\n const bWidth = measureLabel(ticks[i + 1].label, fontSize, fontWeight, measureText);\n const aRight = ticks[i].position + aWidth / 2;\n const bLeft = ticks[i + 1].position - bWidth / 2;\n if (aRight + minGap > bLeft) return true;\n }\n return false;\n}\n\n/**\n * Thin a tick array by removing every other tick until labels don't overlap.\n * Always keeps first and last tick. O(log n) iterations max.\n * Returns the original array if no thinning is needed.\n */\nexport function thinTicksUntilFit(\n ticks: AxisTick[],\n fontSize: number,\n fontWeight: number,\n measureText?: MeasureTextFn,\n orientation: 'horizontal' | 'vertical' = 'horizontal',\n): AxisTick[] {\n if (!ticksOverlap(ticks, fontSize, fontWeight, measureText, orientation)) return ticks;\n\n let current = ticks;\n while (current.length > MIN_TICK_COUNT) {\n // Keep first, last, and every other tick in between\n const thinned = [current[0]];\n for (let i = 2; i < current.length - 1; i += 2) {\n thinned.push(current[i]);\n }\n if (current.length > 1) thinned.push(current[current.length - 1]);\n current = thinned;\n\n if (!ticksOverlap(current, fontSize, fontWeight, measureText, orientation)) break;\n }\n return current;\n}\n","/**\n * Tick generation: produces raw AxisTick[] from a resolved scale.\n *\n * Pure with respect to layout dimensions — positions come from the scale,\n * not from the chart area. Density thinning lives in ./thinning.ts.\n */\n\nimport type { AxisLabelDensity, AxisTick } from '@opendata-ai/openchart-core';\nimport {\n abbreviateNumber,\n buildD3Formatter,\n buildTemporalFormatter,\n formatDate,\n formatNumber,\n} from '@opendata-ai/openchart-core';\nimport type { ScaleBand } from 'd3-scale';\nimport type { D3CategoricalScale, D3ContinuousScale, ResolvedScale } from '../scales';\n\n/**\n * Target pixels-per-tick for continuous axes. The target count is computed as\n * `axisLength / PX_PER_TICK[density]` and then clamped into the count range.\n *\n * Rationale:\n * - Observable Plot uses 50px/tick on y, 80px/tick on x as its baseline.\n * - ONS editorial guidance recommends 6-10 y-gridlines at desktop, 3-6 mobile.\n * - The Economist / FT / NYT typically show 4-6 labeled y-ticks on finished charts.\n *\n * Y gets tighter spacing than X because vertical label extent is the font height\n * (~14px) versus horizontal label extent which can be 60-100px for dates/abbreviated\n * numbers. X uses wider spacing so labels don't need aggressive rotation or thinning.\n *\n * \"full\" is the publication-ready default; \"reduced\" and \"minimal\" step down as the\n * responsive breakpoint system shifts to smaller containers.\n *\n * @internal — these are tuning constants, not part of the configuration API.\n * Consumers should configure tick density through `axis.tickCount` on the spec.\n */\nconst Y_PX_PER_TICK: Record<AxisLabelDensity, number> = {\n full: 55,\n reduced: 90,\n minimal: 140,\n};\n\nconst X_PX_PER_TICK: Record<AxisLabelDensity, number> = {\n full: 110,\n reduced: 160,\n minimal: 220,\n};\n\n/**\n * Count clamps per density. The lower bound keeps a chart from collapsing to\n * a single label on very short axes; the upper bound stops tall/wide charts\n * from growing a ladder of ticks past the point of editorial usefulness.\n *\n * The upper bound is deliberately <=6 for y on standard tiers: D3's\n * `scale.ticks(n)` only produces \"nice\" step sizes (1, 2, 5 × 10^k), and for\n * many domains the jump from step=10 to step=5 happens between count 6 and 7.\n * Requesting 7 can give back 10, which reads as visually dense. Capping at 6\n * keeps the editorial ~5 gridline average regardless of domain shape.\n *\n * @internal — see PX_PER_TICK comment.\n */\nconst Y_TICK_COUNT_RANGE: Record<AxisLabelDensity, [number, number]> = {\n full: [4, 6],\n reduced: [3, 5],\n minimal: [2, 3],\n};\n\nconst X_TICK_COUNT_RANGE: Record<AxisLabelDensity, [number, number]> = {\n full: [3, 6],\n reduced: [3, 5],\n minimal: [2, 3],\n};\n\n/**\n * Fallback tick counts for callers that don't have an axis length handy\n * (categorical band-scale thinning uses this as a cap, and `continuousTicks`\n * uses it when no `targetCount` is provided).\n *\n * @internal\n */\nconst TICK_COUNTS: Record<AxisLabelDensity, number> = {\n full: 7,\n reduced: 5,\n minimal: 3,\n};\n\n/**\n * Compute a target tick count for a continuous axis from its pixel length and\n * density tier. Uses the Plot-style pixels-per-tick heuristic, then clamps\n * into the density's count range.\n */\nexport function targetTickCount(\n axisLength: number,\n density: AxisLabelDensity,\n orientation: 'x' | 'y',\n): number {\n const pxPerTick = orientation === 'y' ? Y_PX_PER_TICK[density] : X_PX_PER_TICK[density];\n const [min, max] =\n orientation === 'y' ? Y_TICK_COUNT_RANGE[density] : X_TICK_COUNT_RANGE[density];\n const raw = Math.round(axisLength / pxPerTick);\n return Math.max(min, Math.min(max, raw));\n}\n\n/** Set of continuous numeric scale types that should format as numbers. */\nconst NUMERIC_SCALE_TYPES = new Set([\n 'linear',\n 'log',\n 'pow',\n 'sqrt',\n 'symlog',\n 'quantile',\n 'quantize',\n 'threshold',\n]);\n\n/** Set of temporal scale types. */\nconst TEMPORAL_SCALE_TYPES = new Set(['time', 'utc']);\n\n/** Format a tick value based on the scale type. */\nfunction formatTickLabel(value: unknown, resolvedScale: ResolvedScale): string {\n const formatStr = resolvedScale.channel.axis?.format;\n\n if (TEMPORAL_SCALE_TYPES.has(resolvedScale.type)) {\n const temporalFmt = buildTemporalFormatter(formatStr);\n if (temporalFmt) return temporalFmt(value as Date);\n const useUtc = resolvedScale.type === 'utc';\n return formatDate(value as Date, undefined, undefined, useUtc);\n }\n\n if (NUMERIC_SCALE_TYPES.has(resolvedScale.type)) {\n const num = value as number;\n if (formatStr) {\n const fmt = buildD3Formatter(formatStr);\n if (fmt) return fmt(num);\n }\n // Abbreviate large numbers for axis labels\n if (Math.abs(num) >= 1000) return abbreviateNumber(num);\n return formatNumber(num);\n }\n\n return String(value);\n}\n\n/**\n * Generate ticks for a continuous scale (linear, time, log, pow, sqrt, symlog).\n *\n * `targetCount` lets callers that know the axis pixel length pass a\n * density-appropriate count (see `targetTickCount`). When omitted, falls back\n * to the coarse `TICK_COUNTS` tier, which is only used by tests and callers\n * that don't have an axis length.\n */\nexport function continuousTicks(\n resolvedScale: ResolvedScale,\n density: AxisLabelDensity,\n targetCount?: number,\n): AxisTick[] {\n const scale = resolvedScale.scale as D3ContinuousScale;\n\n // Discretizing scales (quantile, quantize, threshold) don't have .ticks().\n // Use their domain thresholds as ticks instead.\n if (!('ticks' in scale) || typeof scale.ticks !== 'function') {\n const domain = scale.domain() as unknown[];\n return domain.map((value: unknown) => ({\n value,\n position: (scale as D3ContinuousScale)(value as number & Date) as number,\n label: formatTickLabel(value, resolvedScale),\n }));\n }\n\n const explicitCount = resolvedScale.channel.axis?.tickCount;\n const count = explicitCount ?? targetCount ?? TICK_COUNTS[density];\n return buildContinuousTicks(resolvedScale, count);\n}\n\n/**\n * Build positioned, labeled ticks for a continuous scale at an exact count.\n * Exposed so callers that need to re-request ticks at a lower count (for\n * overlap-driven density adaptation) can regenerate without manual pruning.\n * D3's `scale.ticks(n)` always returns evenly-spaced round values, so\n * requesting a smaller `n` never produces squished neighbors — unlike\n * \"keep first+last, drop middle\" pruning which can stack the last tick\n * next to an endpoint and cascade to 2 ticks.\n */\nexport function buildContinuousTicks(resolvedScale: ResolvedScale, count: number): AxisTick[] {\n const scale = resolvedScale.scale as D3ContinuousScale;\n if (!('ticks' in scale) || typeof scale.ticks !== 'function') {\n return continuousTicks(resolvedScale, 'full');\n }\n const raw: unknown[] = scale.ticks(count);\n return raw.map((value: unknown) => ({\n value,\n position: scale(value as number & Date) as number,\n label: formatTickLabel(value, resolvedScale),\n }));\n}\n\n/** True if this scale supports regenerating ticks at an arbitrary count. */\nexport function scaleSupportsTickCount(resolvedScale: ResolvedScale): boolean {\n const scale = resolvedScale.scale as D3ContinuousScale;\n return 'ticks' in scale && typeof scale.ticks === 'function';\n}\n\n/** Generate ticks for a band/point/ordinal scale. */\nexport function categoricalTicks(\n resolvedScale: ResolvedScale,\n density: AxisLabelDensity,\n): AxisTick[] {\n const scale = resolvedScale.scale as D3CategoricalScale;\n const domain: string[] = scale.domain();\n const explicitTickCount = resolvedScale.channel.axis?.tickCount;\n const maxTicks = explicitTickCount ?? TICK_COUNTS[density];\n\n // Band scales (bar charts) show all category labels by default.\n // Only thin when there's an explicit tickCount override or for point/ordinal scales.\n let selectedValues = domain;\n if ((resolvedScale.type !== 'band' || explicitTickCount) && domain.length > maxTicks) {\n const step = Math.ceil(domain.length / maxTicks);\n selectedValues = domain.filter((_: string, i: number) => i % step === 0);\n }\n\n const ticks = selectedValues.map((value: string) => {\n // Band scales: use the center of the band\n const bandScale = resolvedScale.type === 'band' ? (scale as ScaleBand<string>) : null;\n const pos = bandScale\n ? (bandScale(value) ?? 0) + bandScale.bandwidth() / 2\n : ((scale(value) as number | undefined) ?? 0);\n\n return {\n value,\n position: pos,\n label: value,\n };\n });\n\n return ticks;\n}\n\n/** Resolve explicit tick values from axis config into positioned ticks. */\nexport function resolveExplicitTicks(values: unknown[], resolvedScale: ResolvedScale): AxisTick[] {\n const scale = resolvedScale.scale;\n return values.map((value) => {\n let position: number;\n if (TEMPORAL_SCALE_TYPES.has(resolvedScale.type)) {\n const d = value instanceof Date ? value : new Date(String(value));\n position = (scale as D3ContinuousScale)(d as number & Date) as number;\n } else if (\n resolvedScale.type === 'band' ||\n resolvedScale.type === 'point' ||\n resolvedScale.type === 'ordinal'\n ) {\n const s = String(value);\n const bandScale = resolvedScale.type === 'band' ? (scale as ScaleBand<string>) : null;\n position = bandScale\n ? (bandScale(s) ?? 0) + bandScale.bandwidth() / 2\n : ((scale(s as string & number) as number | undefined) ?? 0);\n } else {\n position = (scale as D3ContinuousScale)(value as number & Date) as number;\n }\n return {\n value,\n position,\n label: formatTickLabel(value, resolvedScale),\n };\n });\n}\n","/**\n * Axis computation: tick positions, labels, and axis lines.\n *\n * Generates ticks manually (no d3-axis) so we have full control over\n * responsive tick density and formatting. Tick generation and label\n * thinning live in sibling modules under ./axes/.\n */\n\nimport type {\n AxisLabelDensity,\n AxisLayout,\n AxisTick,\n Gridline,\n LayoutStrategy,\n MeasureTextFn,\n Rect,\n ResolvedTheme,\n TextStyle,\n} from '@opendata-ai/openchart-core';\nimport type { ScaleBand } from 'd3-scale';\nimport { measureLabel, thinTicksUntilFit, ticksOverlap } from './axes/thinning';\nimport {\n buildContinuousTicks,\n categoricalTicks,\n continuousTicks,\n resolveExplicitTicks,\n scaleSupportsTickCount,\n targetTickCount,\n} from './axes/ticks';\nimport type { ResolvedScales } from './scales';\n\n// Re-export pure helpers so external consumers (and tests) continue to import\n// them from './layout/axes'.\nexport { thinTicksUntilFit, ticksOverlap } from './axes/thinning';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/**\n * Height thresholds for reducing y-axis tick density.\n * Below these pixel heights, we step down the density regardless of the\n * width-based strategy. This prevents overlapping y-axis labels in short\n * containers like thumbnail previews.\n */\nconst HEIGHT_MINIMAL_THRESHOLD = 120;\nconst HEIGHT_REDUCED_THRESHOLD = 200;\n\n/**\n * Width thresholds for reducing x-axis tick density.\n * Mirrors the height logic for the x-axis: narrow containers get fewer ticks.\n */\nconst WIDTH_MINIMAL_THRESHOLD = 150;\nconst WIDTH_REDUCED_THRESHOLD = 300;\n\n/** Ordered densities from most to fewest ticks. */\nconst DENSITY_ORDER: AxisLabelDensity[] = ['full', 'reduced', 'minimal'];\n\n/**\n * Compute effective axis tick density by considering available space.\n *\n * The width-based breakpoint system sets a base density, but it doesn't know\n * about the actual chart area dimensions (which shrink after chrome/legend\n * allocation). This function steps density down further when the axis\n * dimension is too small for the requested tick count.\n *\n * @param baseDensity - The density from the responsive layout strategy.\n * @param axisLength - Available pixels along this axis (height for y, width for x).\n * @param minimalThreshold - Below this pixel size, force minimal density.\n * @param reducedThreshold - Below this pixel size, cap at reduced density.\n * @returns The effective density, never looser than the base.\n */\nexport function effectiveDensity(\n baseDensity: AxisLabelDensity,\n axisLength: number,\n minimalThreshold: number,\n reducedThreshold: number,\n): AxisLabelDensity {\n let density = baseDensity;\n\n if (axisLength < minimalThreshold) {\n density = 'minimal';\n } else if (axisLength < reducedThreshold) {\n // Don't increase density beyond what the base strategy allows.\n // If base is already 'minimal', keep it.\n const baseIdx = DENSITY_ORDER.indexOf(baseDensity);\n const reducedIdx = DENSITY_ORDER.indexOf('reduced');\n density = DENSITY_ORDER[Math.max(baseIdx, reducedIdx)];\n }\n\n return density;\n}\n\n/**\n * Floor tick count for continuous axes when the axis is long enough to show\n * more than a min/max pair. Keeps the editorial ~5 target when possible.\n * Very short axes bypass this floor and can legitimately fall to 2.\n */\nconst CONTINUOUS_TICK_FLOOR = 4;\n\n/**\n * How much D3 is allowed to overshoot what we asked for before we treat the\n * output as \"too dense\" and step down. D3's `scale.ticks(n)` only produces\n * nice step sizes (1, 2, 5 × 10^k, or calendar units for time), so a request\n * for n=6 can come back with 12 quarterly dates or 10 step-5 values. Accepting\n * up to 1.5× target catches the obvious overshoots without trimming acceptable\n * ones.\n *\n * The reference point stays fixed to the initial requested count even as we\n * iterate downward — we're measuring \"did this candidate land near the target\n * the caller actually wanted?\", not \"is the candidate near what we just asked\n * for on this iteration?\". If a candidate at n=3 returns 8 ticks, it's still\n * a 1.3× overshoot of the target-6, which is fine.\n */\nconst OVERSHOOT_TOLERANCE = 1.5;\n\n/**\n * Fit continuous ticks by re-requesting progressively fewer ticks from the\n * scale. D3's `scale.ticks(n)` always returns evenly-spaced round values, so\n * stepping `n` down keeps spacing uniform — unlike middle-pruning which can\n * strand the last tick next to an endpoint and cascade to 2 ticks.\n *\n * Two conditions trigger a step-down:\n * 1. The label heuristic detects overlap at the initial count.\n * 2. D3 overshot the requested count by more than OVERSHOOT_TOLERANCE.\n * (Time scales jump between calendar units; linear scales jump between\n * nice step sizes. Either can return 2× what we asked for.)\n *\n * Falls back to overlap-safe thinning on the best-so-far candidate if no\n * count produces a clean fit. The fallback starts from the smallest candidate\n * that still meets the floor, so `thinTicksUntilFit` never receives the\n * overshot initial set (which was the bug this function exists to avoid).\n */\nfunction fitContinuousTicks(\n scale: ResolvedScales['x' | 'y'],\n initialTicks: AxisTick[],\n initialCount: number,\n fontSize: number,\n fontWeight: number,\n axisLength: number,\n orientation: 'horizontal' | 'vertical',\n measureText?: MeasureTextFn,\n): AxisTick[] {\n if (!scale || !scaleSupportsTickCount(scale)) return initialTicks;\n\n const tolerance = initialCount * OVERSHOOT_TOLERANCE;\n const overshoots = initialTicks.length > tolerance;\n const overlaps = ticksOverlap(initialTicks, fontSize, fontWeight, measureText, orientation);\n if (!overshoots && !overlaps) return initialTicks;\n\n // Enforce the floor only when the axis is long enough to fit that many\n // labels without overlap. Very short axes can fall below.\n const minThreshold =\n orientation === 'vertical' ? HEIGHT_MINIMAL_THRESHOLD : WIDTH_MINIMAL_THRESHOLD;\n const floor = axisLength >= minThreshold ? CONTINUOUS_TICK_FLOOR : 2;\n\n // Track the smallest candidate that meets the floor. If no candidate fits\n // cleanly, we thin this instead of the overshot `initialTicks` so the\n // fallback doesn't reintroduce the cascading-to-2-ticks bug.\n let bestWithinFloor: AxisTick[] | undefined;\n for (let n = initialCount - 1; n >= 2; n--) {\n const candidate = buildContinuousTicks(scale, n);\n const candidateOvershoots = candidate.length > tolerance;\n const candidateOverlaps = ticksOverlap(\n candidate,\n fontSize,\n fontWeight,\n measureText,\n orientation,\n );\n if (!candidateOvershoots && !candidateOverlaps) {\n return candidate;\n }\n if (candidate.length >= floor) bestWithinFloor = candidate;\n }\n\n // No candidate fit cleanly. Thin whatever most recently met the floor; if\n // nothing did, synthesize a floor-count set directly from the scale so we\n // never hand the overshot initialTicks to the middle-pruning thinner.\n const fallback = bestWithinFloor ?? buildContinuousTicks(scale, floor);\n return thinTicksUntilFit(fallback, fontSize, fontWeight, measureText, orientation);\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/** Output of computeAxes. */\nexport interface AxesResult {\n x?: AxisLayout;\n y?: AxisLayout;\n}\n\n/**\n * Compute axis layouts with tick positions, labels, and axis lines.\n *\n * @param scales - Resolved scales from computeScales.\n * @param chartArea - The chart drawing area.\n * @param strategy - Responsive layout strategy.\n * @param theme - Resolved theme for styling.\n * @param measureText - Optional real text measurement from the adapter.\n */\nexport function computeAxes(\n scales: ResolvedScales,\n chartArea: Rect,\n strategy: LayoutStrategy,\n theme: ResolvedTheme,\n measureText?: MeasureTextFn,\n): AxesResult {\n const result: AxesResult = {};\n const baseDensity = strategy.axisLabelDensity;\n\n // Compute per-axis density based on available space.\n // Y-axis density adapts to chart height; X-axis density adapts to chart width.\n const yDensity = effectiveDensity(\n baseDensity,\n chartArea.height,\n HEIGHT_MINIMAL_THRESHOLD,\n HEIGHT_REDUCED_THRESHOLD,\n );\n const xDensity = effectiveDensity(\n baseDensity,\n chartArea.width,\n WIDTH_MINIMAL_THRESHOLD,\n WIDTH_REDUCED_THRESHOLD,\n );\n\n const tickLabelStyle: TextStyle = {\n fontFamily: theme.fonts.family,\n fontSize: theme.fonts.sizes.axisTick,\n fontWeight: theme.fonts.weights.normal,\n fill: theme.colors.axis,\n lineHeight: 1.2,\n fontVariant: 'tabular-nums',\n };\n\n const axisLabelStyle: TextStyle = {\n fontFamily: theme.fonts.family,\n fontSize: theme.fonts.sizes.body,\n fontWeight: theme.fonts.weights.medium,\n fill: theme.colors.text,\n lineHeight: 1.3,\n };\n\n const { fontSize } = tickLabelStyle;\n const { fontWeight } = tickLabelStyle;\n\n if (scales.x) {\n const axisConfig = scales.x.channel.axis;\n const isContinuousX =\n scales.x.type !== 'band' && scales.x.type !== 'point' && scales.x.type !== 'ordinal';\n\n const xTargetCount = isContinuousX\n ? targetTickCount(chartArea.width, xDensity, 'x')\n : undefined;\n\n // Use explicit tick values from axis config if provided\n let allTicks: AxisTick[];\n if (axisConfig?.values) {\n allTicks = resolveExplicitTicks(axisConfig.values, scales.x);\n } else if (!isContinuousX) {\n allTicks = categoricalTicks(scales.x, xDensity);\n } else {\n allTicks = continuousTicks(scales.x, xDensity, xTargetCount);\n }\n\n // Gridlines use the full tick set so they remain visible even when labels\n // are thinned to prevent overlap.\n const gridlines: Gridline[] = allTicks.map((t) => ({\n position: t.position,\n major: true,\n }));\n\n // Thin tick labels to prevent overlap (skip for band scales which use\n // auto-rotation, and when the user set an explicit tickCount or values).\n const shouldThin = scales.x.type !== 'band' && !axisConfig?.tickCount && !axisConfig?.values;\n let ticks: AxisTick[];\n if (!shouldThin) {\n ticks = allTicks;\n } else if (isContinuousX) {\n // Continuous x-axis: re-request ticks at a lower count on overlap so\n // time-scale quartile/monthly jumps don't leave a too-dense axis.\n ticks = fitContinuousTicks(\n scales.x,\n allTicks,\n xTargetCount ?? allTicks.length,\n fontSize,\n fontWeight,\n chartArea.width,\n 'horizontal',\n measureText,\n );\n } else {\n ticks = thinTicksUntilFit(allTicks, fontSize, fontWeight, measureText);\n }\n\n // Auto-rotate labels when band scale labels would overlap.\n // Uses max label width (not average) since one long label is enough to overlap.\n let tickAngle = axisConfig?.labelAngle;\n if (tickAngle === undefined && scales.x.type === 'band' && ticks.length > 1) {\n const bandwidth = (scales.x.scale as ScaleBand<string>).bandwidth();\n let maxLabelWidth = 0;\n for (const t of ticks) {\n const w = measureLabel(t.label, fontSize, fontWeight, measureText);\n if (w > maxLabelWidth) maxLabelWidth = w;\n }\n // If the widest label exceeds 85% of the bandwidth, rotate to avoid overlap\n if (maxLabelWidth > bandwidth * 0.85) {\n tickAngle = -45;\n }\n }\n\n const axisTitle = axisConfig?.title;\n\n result.x = {\n ticks,\n gridlines: axisConfig?.grid ? gridlines : [],\n label: axisTitle,\n labelStyle: axisLabelStyle,\n tickLabelStyle,\n tickAngle,\n start: { x: chartArea.x, y: chartArea.y + chartArea.height },\n end: { x: chartArea.x + chartArea.width, y: chartArea.y + chartArea.height },\n orient: axisConfig?.orient,\n domainLine: axisConfig?.domain,\n tickMarks: axisConfig?.ticks,\n offset: axisConfig?.offset,\n titlePadding: axisConfig?.titlePadding,\n labelPadding: axisConfig?.labelPadding,\n labelOverlap: axisConfig?.labelOverlap,\n labelFlush: axisConfig?.labelFlush,\n };\n }\n\n if (scales.y) {\n const axisConfig = scales.y.channel.axis;\n const isContinuousY =\n scales.y.type !== 'band' && scales.y.type !== 'point' && scales.y.type !== 'ordinal';\n\n // Target count from pixels-per-tick when we have a continuous y-axis.\n const yTargetCount = isContinuousY\n ? targetTickCount(chartArea.height, yDensity, 'y')\n : undefined;\n\n // Use explicit tick values from axis config if provided\n let allTicks: AxisTick[];\n if (axisConfig?.values) {\n allTicks = resolveExplicitTicks(axisConfig.values, scales.y);\n } else if (!isContinuousY) {\n allTicks = categoricalTicks(scales.y, yDensity);\n } else {\n allTicks = continuousTicks(scales.y, yDensity, yTargetCount);\n }\n\n // Thin tick labels to prevent overlap (skip for band scales, explicit tickCount, and values).\n const shouldThin = scales.y.type !== 'band' && !axisConfig?.tickCount && !axisConfig?.values;\n let ticks: AxisTick[];\n if (!shouldThin) {\n ticks = allTicks;\n } else if (isContinuousY) {\n // Continuous y-axis: re-request ticks at a lower count on overlap so\n // spacing stays uniform and we don't collapse to min/max.\n ticks = fitContinuousTicks(\n scales.y,\n allTicks,\n yTargetCount ?? allTicks.length,\n fontSize,\n fontWeight,\n chartArea.height,\n 'vertical',\n measureText,\n );\n } else {\n ticks = thinTicksUntilFit(allTicks, fontSize, fontWeight, measureText, 'vertical');\n }\n\n // Gridlines match the tick set so every gridline has a label.\n const gridlines: Gridline[] = ticks.map((t) => ({\n position: t.position,\n major: true,\n }));\n\n const axisTitle = axisConfig?.title;\n const tickAngle = axisConfig?.labelAngle;\n\n result.y = {\n ticks,\n // Y-axis gridlines are shown by default (standard editorial practice)\n gridlines,\n label: axisTitle,\n labelStyle: axisLabelStyle,\n tickLabelStyle,\n tickAngle,\n start: { x: chartArea.x, y: chartArea.y },\n end: { x: chartArea.x, y: chartArea.y + chartArea.height },\n orient: axisConfig?.orient,\n domainLine: axisConfig?.domain,\n tickMarks: axisConfig?.ticks,\n offset: axisConfig?.offset,\n titlePadding: axisConfig?.titlePadding,\n labelPadding: axisConfig?.labelPadding,\n labelOverlap: axisConfig?.labelOverlap,\n labelFlush: axisConfig?.labelFlush,\n };\n }\n\n return result;\n}\n","/**\n * Dimension computation for the chart layout.\n *\n * Takes the normalized spec + compile options + legend layout and produces\n * LayoutDimensions with the total area, chrome layout, chart drawing area,\n * and margins. The chart area is what's left after subtracting chrome,\n * legend space, and axis margins.\n *\n * Padding and chrome scale down at smaller container sizes to maximize\n * the usable chart area. When the chart area is still too small after\n * scaling, chrome is progressively stripped as a fallback.\n */\n\nimport type {\n CompileOptions,\n Encoding,\n LayoutStrategy,\n LegendLayout,\n Margins,\n Rect,\n ResolvedChrome,\n ResolvedTheme,\n} from '@opendata-ai/openchart-core';\nimport { computeChrome, estimateTextWidth } from '@opendata-ai/openchart-core';\nimport { format as d3Format } from 'd3-format';\n\nimport type { NormalizedChartSpec, NormalizedChrome } from '../compiler/types';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** The complete dimension layout for a chart. */\nexport interface LayoutDimensions {\n /** Total available space. */\n total: Rect;\n /** Resolved chrome (title, subtitle, source, etc.). */\n chrome: ResolvedChrome;\n /** The chart drawing area (after subtracting chrome, legend, margins). */\n chartArea: Rect;\n /** Margins around the chart area. */\n margins: Margins;\n /** Resolved theme used for this layout. */\n theme: ResolvedTheme;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Convert NormalizedChrome back to a Chrome-compatible shape for computeChrome. */\nfunction chromeToInput(chrome: NormalizedChrome): import('@opendata-ai/openchart-core').Chrome {\n return {\n title: chrome.title,\n subtitle: chrome.subtitle,\n source: chrome.source,\n byline: chrome.byline,\n footer: chrome.footer,\n };\n}\n\n/**\n * Scale padding based on the smaller container dimension.\n * At >= 500px, padding is unchanged. At <= 200px, padding is halved (min 4px).\n * Linear interpolation between 200-500px.\n */\nfunction scalePadding(basePadding: number, width: number, height: number): number {\n const minDim = Math.min(width, height);\n if (minDim >= 500) return basePadding;\n if (minDim <= 200) return Math.max(Math.round(basePadding * 0.5), 4);\n const t = (minDim - 200) / 300;\n return Math.max(Math.round(basePadding * (0.5 + t * 0.5)), 4);\n}\n\n/** Minimum chart area dimensions before guardrails kick in. */\nconst MIN_CHART_WIDTH = 60;\nconst MIN_CHART_HEIGHT = 40;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute chart dimensions, reserving space for chrome, legend, and axes.\n *\n * @param spec - Normalized chart spec.\n * @param options - Compile options (width, height, theme, darkMode).\n * @param legendLayout - Pre-computed legend layout (used to reserve space).\n * @param theme - Already-resolved theme (resolved once in compileChart).\n * @param strategy - Responsive layout strategy (controls chrome mode).\n * @returns LayoutDimensions with chart area rect.\n */\nexport function computeDimensions(\n spec: NormalizedChartSpec,\n options: CompileOptions,\n legendLayout: LegendLayout,\n theme: ResolvedTheme,\n strategy?: LayoutStrategy,\n watermark: boolean = true,\n): LayoutDimensions {\n const { width, height } = options;\n\n const padding = scalePadding(theme.spacing.padding, width, height);\n const axisMargin = theme.spacing.axisMargin;\n const chromeMode = strategy?.chromeMode ?? 'full';\n\n // Compute chrome with mode and scaled padding\n const chrome = computeChrome(\n chromeToInput(spec.chrome),\n theme,\n width,\n options.measureText,\n chromeMode,\n padding,\n watermark,\n );\n\n // Start with the total rect\n const total: Rect = { x: 0, y: 0, width, height };\n\n // Radial charts (arc) don't have axes, so skip axis space\n const isRadial = spec.markType === 'arc';\n const encoding = spec.encoding as Encoding;\n\n // Estimate x-axis height below chart area: tick labels sit 14px below,\n // axis title sits 35px below. These extend past the chart area bottom\n // and source/footer chrome must be positioned below them.\n const xAxis = encoding.x?.axis as (Record<string, unknown> & { labelAngle?: number }) | undefined;\n const hasXAxisLabel = !!xAxis?.title;\n const xTickAngle = xAxis?.labelAngle;\n\n let xAxisHeight: number;\n if (isRadial) {\n xAxisHeight = 0;\n } else if (xTickAngle && Math.abs(xTickAngle) > 10) {\n // Rotated labels: estimate height from the longest label text.\n // At -90 degrees, the label height = text width. At -45, it's width * sin(45).\n const angleRad = Math.abs(xTickAngle) * (Math.PI / 180);\n const xField = encoding.x?.field;\n let maxLabelWidth = 40; // fallback\n if (xField) {\n for (const row of spec.data) {\n const label = String(row[xField] ?? '');\n const w = estimateTextWidth(label, theme.fonts.sizes.axisTick, theme.fonts.weights.normal);\n if (w > maxLabelWidth) maxLabelWidth = w;\n }\n }\n // Rotated label height: width * sin(angle), plus a small gap\n const rotatedHeight = maxLabelWidth * Math.sin(angleRad) + 6;\n // Cap at a reasonable max to avoid absurd margins\n const labelHeight = Math.min(rotatedHeight, 120);\n xAxisHeight = hasXAxisLabel ? labelHeight + 20 : labelHeight;\n } else {\n xAxisHeight = hasXAxisLabel ? 48 : 26;\n }\n\n // Build margins: padding + chrome + axis space.\n // For radial charts (arc/donut), axes don't exist, so axisMargin is only\n // added when there's actual chrome content that needs separation from the\n // chart area. When chrome is empty the margin is just padding.\n const topAxisGap = isRadial && chrome.topHeight === 0 ? 0 : axisMargin;\n const margins: Margins = {\n top: padding + chrome.topHeight + topAxisGap,\n right: padding + (isRadial ? padding : axisMargin),\n bottom: padding + chrome.bottomHeight + xAxisHeight,\n left: padding + (isRadial ? padding : axisMargin),\n };\n\n // Dynamic right margin for line/area end-of-line labels.\n // Only reserve space when labels will actually render (density != 'none').\n const labelDensity = spec.labels.density;\n if ((spec.markType === 'line' || spec.markType === 'area') && labelDensity !== 'none') {\n // Estimate label width from longest series name (color encoding domain)\n const colorEnc = encoding.color;\n const colorField = colorEnc && 'field' in colorEnc ? colorEnc.field : undefined;\n if (colorField) {\n let maxLabelWidth = 0;\n const seen = new Set<string>();\n for (const row of spec.data) {\n const label = String(row[colorField] ?? '');\n if (!seen.has(label)) {\n seen.add(label);\n const w = estimateTextWidth(label, 11, 600);\n if (w > maxLabelWidth) maxLabelWidth = w;\n }\n }\n if (maxLabelWidth > 0) {\n margins.right = Math.max(margins.right, padding + maxLabelWidth + 8);\n }\n }\n }\n\n // Reserve right margin for text annotations near the chart's right edge.\n // Without this, annotation text at the last data point clips outside the SVG.\n // Account for anchor direction and offset.dx to avoid over-reserving space.\n // Skip when annotations are hidden (tooltip-only at compact breakpoints).\n if (\n strategy?.annotationPosition !== 'tooltip-only' &&\n spec.annotations.length > 0 &&\n encoding.x\n ) {\n const xField = encoding.x.field;\n // Find the maximum x value in the data\n let maxX: string | number | undefined;\n for (const row of spec.data) {\n const v = row[xField];\n if (v != null && (maxX == null || String(v) >= String(maxX))) maxX = v as string | number;\n }\n if (maxX != null) {\n const maxXStr = String(maxX);\n for (const ann of spec.annotations) {\n if (ann.type === 'text' && String(ann.x) === maxXStr) {\n const textWidth = estimateTextWidth(ann.text, ann.fontSize ?? 11, ann.fontWeight ?? 600);\n const dx = ann.offset?.dx ?? 0;\n // How much text extends right of the anchor point depends on alignment:\n // - anchor \"right\" or \"left\": text is off to one side, full width extends\n // - anchor \"top\"/\"bottom\"/\"auto\"/undefined: text is centered, half extends right\n const anchor = ann.anchor ?? 'auto';\n const baseRightExtent =\n anchor === 'left'\n ? textWidth\n : // text is to the right of anchor\n anchor === 'right'\n ? 0\n : // text is to the left of anchor\n textWidth / 2; // centered (top/bottom/auto)\n const rightOverflow = Math.max(0, baseRightExtent + dx);\n if (rightOverflow > 0) {\n margins.right = Math.max(margins.right, padding + rightOverflow + 12);\n }\n }\n }\n }\n }\n\n // Dynamic left margin for y-axis labels\n if (encoding.y && !isRadial) {\n if (\n spec.markType === 'bar' ||\n spec.markType === 'circle' ||\n spec.markType === 'lollipop' ||\n encoding.y.type === 'nominal' ||\n encoding.y.type === 'ordinal'\n ) {\n // Category labels on the left for bar/dot charts\n const yField = encoding.y.field;\n let maxLabelWidth = 0;\n for (const row of spec.data) {\n const label = String(row[yField] ?? '');\n const w = estimateTextWidth(label, theme.fonts.sizes.axisTick, theme.fonts.weights.normal);\n if (w > maxLabelWidth) maxLabelWidth = w;\n }\n if (maxLabelWidth > 0) {\n margins.left = Math.max(margins.left, padding + maxLabelWidth + 12);\n }\n } else if (encoding.y.type === 'quantitative' || encoding.y.type === 'temporal') {\n // Numeric tick labels on the left. Estimate width from the data range.\n const yField = encoding.y.field;\n const yAxisFormat = (encoding.y.axis as Record<string, unknown> | undefined)?.format as\n | string\n | undefined;\n let maxAbsVal = 0;\n for (const row of spec.data) {\n const v = Number(row[yField]);\n if (Number.isFinite(v) && Math.abs(v) > maxAbsVal) maxAbsVal = Math.abs(v);\n }\n\n let sampleLabel: string;\n if (yAxisFormat) {\n // Use the actual d3-format to produce a realistic label estimate\n try {\n const fmt = d3Format(yAxisFormat);\n sampleLabel = fmt(maxAbsVal);\n } catch {\n sampleLabel = String(maxAbsVal);\n }\n } else {\n // Fallback: estimate from magnitude\n if (maxAbsVal >= 1_000_000_000) sampleLabel = '1.5B';\n else if (maxAbsVal >= 1_000_000) sampleLabel = '1.5M';\n else if (maxAbsVal >= 1_000) sampleLabel = '1.5K';\n else if (maxAbsVal >= 100) sampleLabel = '100';\n else if (maxAbsVal >= 10) sampleLabel = '10';\n else sampleLabel = '0.0';\n }\n // Account for negative sign\n const negPrefix = spec.data.some((r) => Number(r[yField]) < 0) ? '-' : '';\n const labelEst = negPrefix + sampleLabel;\n const labelWidth = estimateTextWidth(\n labelEst,\n theme.fonts.sizes.axisTick,\n theme.fonts.weights.normal,\n );\n // 6px gap between label and chart area edge\n margins.left = Math.max(margins.left, padding + labelWidth + 10);\n }\n }\n\n // Rotated y-axis label needs extra left margin (rendered at area.x - 45 in SVG)\n const yAxis = encoding.y?.axis as Record<string, unknown> | undefined;\n if (yAxis && (yAxis.title || yAxis.label) && !isRadial) {\n const rotatedLabelMargin = 45 + Math.ceil(theme.fonts.sizes.body / 2) + 4;\n margins.left = Math.max(margins.left, padding + rotatedLabelMargin);\n }\n\n // Reserve legend space\n if (legendLayout.entries.length > 0) {\n if (legendLayout.position === 'right' || legendLayout.position === 'bottom-right') {\n margins.right += legendLayout.bounds.width + 8;\n } else if (legendLayout.position === 'top') {\n margins.top += legendLayout.bounds.height + 4;\n } else if (legendLayout.position === 'bottom') {\n margins.bottom += legendLayout.bounds.height + 4;\n }\n }\n\n // Chart area is what's left after margins\n let chartArea: Rect = {\n x: margins.left,\n y: margins.top,\n width: Math.max(0, width - margins.left - margins.right),\n height: Math.max(0, height - margins.top - margins.bottom),\n };\n\n // Guardrail: if chart area is too small, progressively strip chrome\n if (\n (chartArea.width < MIN_CHART_WIDTH || chartArea.height < MIN_CHART_HEIGHT) &&\n chromeMode !== 'hidden'\n ) {\n // Try compact first, then hidden\n const fallbackMode = chromeMode === 'full' ? 'compact' : 'hidden';\n const fallbackChrome = computeChrome(\n chromeToInput(spec.chrome),\n theme,\n width,\n options.measureText,\n fallbackMode as 'compact' | 'hidden',\n padding,\n watermark,\n );\n\n // Recalculate top/bottom margins with stripped chrome\n const fallbackTopAxisGap = isRadial && fallbackChrome.topHeight === 0 ? 0 : axisMargin;\n const newTop = padding + fallbackChrome.topHeight + fallbackTopAxisGap;\n const topDelta = margins.top - newTop;\n const newBottom = padding + fallbackChrome.bottomHeight + xAxisHeight;\n const bottomDelta = margins.bottom - newBottom;\n\n if (topDelta > 0 || bottomDelta > 0) {\n margins.top =\n newTop +\n (legendLayout.entries.length > 0 && legendLayout.position === 'top'\n ? legendLayout.bounds.height + 4\n : 0);\n margins.bottom = newBottom;\n\n chartArea = {\n x: margins.left,\n y: margins.top,\n width: Math.max(0, width - margins.left - margins.right),\n height: Math.max(0, height - margins.top - margins.bottom),\n };\n\n return { total, chrome: fallbackChrome, chartArea, margins, theme };\n }\n }\n\n return { total, chrome, chartArea, margins, theme };\n}\n","/**\n * Gridline computation.\n *\n * Produces horizontal gridlines at y-axis tick positions and optional\n * vertical gridlines at x-axis tick positions.\n */\n\nimport type { Rect } from '@opendata-ai/openchart-core';\nimport type { AxesResult } from './axes';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** A single gridline with start/end positions. */\nexport interface GridlineSpec {\n /** Start x. */\n x1: number;\n /** Start y. */\n y1: number;\n /** End x. */\n x2: number;\n /** End y. */\n y2: number;\n /** Whether this is a major gridline. */\n major: boolean;\n}\n\n/** Complete gridline layout. */\nexport interface GridlineLayout {\n horizontal: GridlineSpec[];\n vertical: GridlineSpec[];\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute gridlines from axis layouts.\n *\n * Horizontal gridlines span the chart width at y-axis tick positions.\n * Vertical gridlines span the chart height at x-axis tick positions.\n *\n * @param axes - Computed axis layouts.\n * @param chartArea - The chart drawing area.\n * @param showVertical - Whether to include vertical gridlines (default: false).\n */\nexport function computeGridlines(\n axes: AxesResult,\n chartArea: Rect,\n showVertical = false,\n): GridlineLayout {\n const horizontal: GridlineSpec[] = [];\n const vertical: GridlineSpec[] = [];\n\n // Horizontal gridlines at y-axis ticks\n if (axes.y) {\n for (const gridline of axes.y.gridlines) {\n horizontal.push({\n x1: chartArea.x,\n y1: gridline.position,\n x2: chartArea.x + chartArea.width,\n y2: gridline.position,\n major: gridline.major,\n });\n }\n }\n\n // Vertical gridlines at x-axis ticks (off by default)\n if (showVertical && axes.x) {\n for (const gridline of axes.x.gridlines) {\n vertical.push({\n x1: gridline.position,\n y1: chartArea.y,\n x2: gridline.position,\n y2: chartArea.y + chartArea.height,\n major: gridline.major,\n });\n }\n }\n\n return { horizontal, vertical };\n}\n","/**\n * Scale computation from encoding spec + data.\n *\n * Creates D3 scales that map data values to pixel positions.\n * Temporal -> scaleTime(), quantitative -> scaleLinear(),\n * nominal/ordinal -> scaleBand() or scaleOrdinal(), depending on context.\n */\n\nimport type {\n DataRow,\n Encoding,\n EncodingChannel,\n Rect,\n ScaleType,\n} from '@opendata-ai/openchart-core';\nimport { extent, max, min } from 'd3-array';\nimport type {\n ScaleBand,\n ScaleLinear,\n ScaleLogarithmic,\n ScaleOrdinal,\n ScalePoint,\n ScalePower,\n ScaleQuantile,\n ScaleQuantize,\n ScaleSymLog,\n ScaleThreshold,\n ScaleTime,\n} from 'd3-scale';\nimport {\n scaleBand,\n scaleLinear,\n scaleLog,\n scaleOrdinal,\n scalePoint,\n scalePow,\n scaleQuantile,\n scaleQuantize,\n scaleSqrt,\n scaleSymlog,\n scaleThreshold,\n scaleTime,\n scaleUtc,\n} from 'd3-scale';\n\nimport type { NormalizedChartSpec } from '../compiler/types';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Continuous D3 scales (linear, time, log, pow, sqrt, symlog) that support .ticks() and .nice(). */\nexport type D3ContinuousScale =\n | ScaleLinear<number, number>\n | ScaleTime<number, number>\n | ScaleLogarithmic<number, number>\n | ScalePower<number, number>\n | ScaleSymLog<number, number>;\n\n/** Discretizing D3 scales (quantile, quantize, threshold). */\nexport type D3DiscretizingScale =\n | ScaleQuantile<number>\n | ScaleQuantize<number>\n | ScaleThreshold<number, number>;\n\n/** Categorical D3 scales (band, point, ordinal) that support .domain() as string[]. */\nexport type D3CategoricalScale =\n | ScaleBand<string>\n | ScalePoint<string>\n | ScaleOrdinal<string, string>;\n\n/** Union of all D3 scale types used by the engine. */\nexport type D3Scale = D3ContinuousScale | D3CategoricalScale | D3DiscretizingScale;\n\n/** A sequential color scale mapping numbers to color strings. */\nexport type D3SequentialColorScale = ScaleLinear<string, string>;\n\n/** All resolved scale type identifiers. */\nexport type ResolvedScaleType = ScaleType | 'sequential';\n\n/**\n * A resolved scale wrapping a d3 scale with type metadata.\n * We need to carry the scale type around so axes and marks know\n * how to interpret the domain/range. Consumers use the `type` discriminant\n * to determine which D3 methods are available on the scale.\n */\nexport interface ResolvedScale {\n /** The d3 scale function. Maps domain value -> pixel position or color. */\n scale: D3Scale;\n /** The scale type for downstream use. */\n type: ResolvedScaleType;\n /** The encoding channel this scale was derived from. */\n channel: EncodingChannel;\n}\n\n/** All resolved scales for a chart. */\nexport interface ResolvedScales {\n x?: ResolvedScale;\n y?: ResolvedScale;\n color?: ResolvedScale;\n size?: ResolvedScale;\n /** Default color for single-series charts (first categorical palette color or markDef.fill gradient). */\n defaultColor?: string | import('@opendata-ai/openchart-core').GradientDef;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Extract all non-null values for a field from data. */\nfunction fieldValues(data: DataRow[], field: string): unknown[] {\n return data.map((d) => d[field]).filter((v) => v != null);\n}\n\n/** Parse values to dates. */\nfunction parseDates(values: unknown[]): Date[] {\n return values\n .map((v) => (v instanceof Date ? v : new Date(String(v))))\n .filter((d) => !Number.isNaN(d.getTime()));\n}\n\n/** Parse values to numbers. */\nfunction parseNumbers(values: unknown[]): number[] {\n return values\n .map((v) => (typeof v === 'number' ? v : Number(v)))\n .filter((n) => Number.isFinite(n));\n}\n\n/** Get unique string values preserving order. */\nfunction uniqueStrings(values: unknown[]): string[] {\n const seen = new Set<string>();\n const result: string[] = [];\n for (const v of values) {\n const s = String(v);\n if (!seen.has(s)) {\n seen.add(s);\n result.push(s);\n }\n }\n return result;\n}\n\n/**\n * Apply sort order to categorical domain values.\n * - 'ascending': sort alphabetically/numerically ascending\n * - 'descending': sort descending\n * - null | undefined: preserve data order (no sorting)\n */\nfunction applyCategoricalSort(\n values: string[],\n sort: 'ascending' | 'descending' | null | undefined,\n): string[] {\n if (!sort) return values;\n\n const sorted = [...values].sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));\n if (sort === 'descending') sorted.reverse();\n return sorted;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers: apply common scale config\n// ---------------------------------------------------------------------------\n\n/** Apply clamp and reverse config to a continuous scale. */\nfunction applyContinuousConfig(\n scale: { clamp(v: boolean): unknown; range(): number[]; range(r: number[]): unknown },\n channel: EncodingChannel,\n): void {\n if (channel.scale?.clamp) {\n scale.clamp(true);\n }\n if (channel.scale?.reverse) {\n const [r0, r1] = scale.range() as number[];\n scale.range([r1, r0]);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Scale builders\n// ---------------------------------------------------------------------------\n\nfunction buildTimeScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseDates(fieldValues(data, channel.field));\n const domain = channel.scale?.domain\n ? [new Date(channel.scale.domain[0] as string), new Date(channel.scale.domain[1] as string)]\n : (extent(values) as [Date, Date]);\n\n const scale = scaleTime().domain(domain).range([rangeStart, rangeEnd]);\n\n // Temporal scales default to nice: false because date data typically starts\n // at clean boundaries and nice() rounds the domain outward, creating visible\n // gaps (e.g. data starting 2018-01-01 gets rounded to 2017-01-01).\n // Users can opt in with scale: { nice: true }.\n if (!channel.scale?.domain && channel.scale?.nice === true) {\n scale.nice();\n }\n applyContinuousConfig(scale, channel);\n\n return { scale, type: 'time', channel };\n}\n\nfunction buildUtcScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseDates(fieldValues(data, channel.field));\n const domain = channel.scale?.domain\n ? [new Date(channel.scale.domain[0] as string), new Date(channel.scale.domain[1] as string)]\n : (extent(values) as [Date, Date]);\n\n const scale = scaleUtc().domain(domain).range([rangeStart, rangeEnd]);\n\n // Temporal scales default to nice: false (see buildTimeScale comment).\n if (!channel.scale?.domain && channel.scale?.nice === true) {\n scale.nice();\n }\n applyContinuousConfig(scale, channel);\n\n return { scale, type: 'utc', channel };\n}\n\nfunction buildLinearScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseNumbers(fieldValues(data, channel.field));\n\n let domainMin: number;\n let domainMax: number;\n\n if (channel.scale?.domain) {\n const [d0, d1] = channel.scale.domain as [number, number];\n domainMin = d0;\n domainMax = d1;\n } else {\n domainMin = min(values) ?? 0;\n domainMax = max(values) ?? 1;\n\n // Include zero by default for quantitative scales\n if (channel.scale?.zero !== false) {\n domainMin = Math.min(0, domainMin);\n domainMax = Math.max(0, domainMax);\n }\n }\n\n const scale = scaleLinear().domain([domainMin, domainMax]).range([rangeStart, rangeEnd]);\n\n if (!channel.scale?.domain && channel.scale?.nice !== false) {\n scale.nice();\n }\n applyContinuousConfig(scale, channel);\n\n return { scale, type: 'linear', channel };\n}\n\nfunction buildLogScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseNumbers(fieldValues(data, channel.field)).filter((v) => v > 0);\n const domainMin = channel.scale?.domain\n ? (channel.scale.domain as [number, number])[0]\n : (min(values) ?? 1);\n const domainMax = channel.scale?.domain\n ? (channel.scale.domain as [number, number])[1]\n : (max(values) ?? 10);\n\n const scale = scaleLog().domain([domainMin, domainMax]).range([rangeStart, rangeEnd]);\n\n if (channel.scale?.base !== undefined) {\n scale.base(channel.scale.base);\n }\n if (!channel.scale?.domain && channel.scale?.nice !== false) {\n scale.nice();\n }\n applyContinuousConfig(scale, channel);\n\n return { scale, type: 'log', channel };\n}\n\nfunction buildPowScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseNumbers(fieldValues(data, channel.field));\n\n let domainMin: number;\n let domainMax: number;\n\n if (channel.scale?.domain) {\n [domainMin, domainMax] = channel.scale.domain as [number, number];\n } else {\n domainMin = min(values) ?? 0;\n domainMax = max(values) ?? 1;\n if (channel.scale?.zero !== false) {\n domainMin = Math.min(0, domainMin);\n domainMax = Math.max(0, domainMax);\n }\n }\n\n const scale = scalePow().domain([domainMin, domainMax]).range([rangeStart, rangeEnd]);\n\n if (channel.scale?.exponent !== undefined) {\n scale.exponent(channel.scale.exponent);\n }\n if (!channel.scale?.domain && channel.scale?.nice !== false) {\n scale.nice();\n }\n applyContinuousConfig(scale, channel);\n\n return { scale, type: 'pow', channel };\n}\n\nfunction buildSqrtScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseNumbers(fieldValues(data, channel.field));\n\n let domainMin: number;\n let domainMax: number;\n\n if (channel.scale?.domain) {\n [domainMin, domainMax] = channel.scale.domain as [number, number];\n } else {\n domainMin = min(values) ?? 0;\n domainMax = max(values) ?? 1;\n if (channel.scale?.zero !== false) {\n domainMin = Math.min(0, domainMin);\n domainMax = Math.max(0, domainMax);\n }\n }\n\n const scale = scaleSqrt().domain([domainMin, domainMax]).range([rangeStart, rangeEnd]);\n\n if (!channel.scale?.domain && channel.scale?.nice !== false) {\n scale.nice();\n }\n applyContinuousConfig(scale, channel);\n\n return { scale, type: 'sqrt', channel };\n}\n\nfunction buildSymlogScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseNumbers(fieldValues(data, channel.field));\n\n let domainMin: number;\n let domainMax: number;\n\n if (channel.scale?.domain) {\n [domainMin, domainMax] = channel.scale.domain as [number, number];\n } else {\n domainMin = min(values) ?? 0;\n domainMax = max(values) ?? 1;\n if (channel.scale?.zero !== false) {\n domainMin = Math.min(0, domainMin);\n domainMax = Math.max(0, domainMax);\n }\n }\n\n const scale = scaleSymlog().domain([domainMin, domainMax]).range([rangeStart, rangeEnd]);\n\n if (channel.scale?.constant !== undefined) {\n scale.constant(channel.scale.constant);\n }\n if (!channel.scale?.domain && channel.scale?.nice !== false) {\n scale.nice();\n }\n applyContinuousConfig(scale, channel);\n\n return { scale, type: 'symlog', channel };\n}\n\nfunction buildQuantileScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseNumbers(fieldValues(data, channel.field));\n const range = channel.scale?.range\n ? (channel.scale.range as number[])\n : evenRange(rangeStart, rangeEnd, 4);\n\n const scale = scaleQuantile<number>().domain(values).range(range);\n\n return { scale: scale as unknown as D3Scale, type: 'quantile', channel };\n}\n\nfunction buildQuantizeScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseNumbers(fieldValues(data, channel.field));\n const domainMin = channel.scale?.domain\n ? (channel.scale.domain as [number, number])[0]\n : (min(values) ?? 0);\n const domainMax = channel.scale?.domain\n ? (channel.scale.domain as [number, number])[1]\n : (max(values) ?? 1);\n const range = channel.scale?.range\n ? (channel.scale.range as number[])\n : evenRange(rangeStart, rangeEnd, 4);\n\n const scale = scaleQuantize<number>().domain([domainMin, domainMax]).range(range);\n\n return { scale: scale as unknown as D3Scale, type: 'quantize', channel };\n}\n\nfunction buildThresholdScale(\n channel: EncodingChannel,\n _data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n // Threshold scales require explicit domain breakpoints\n const domainBreaks = channel.scale?.domain ? (channel.scale.domain as number[]) : [0.5];\n const range = channel.scale?.range\n ? (channel.scale.range as number[])\n : evenRange(rangeStart, rangeEnd, domainBreaks.length + 1);\n\n const scale = scaleThreshold<number, number>().domain(domainBreaks).range(range);\n\n return { scale: scale as unknown as D3Scale, type: 'threshold', channel };\n}\n\n/** Generate an evenly-spaced range of `count` values between start and end. */\nfunction evenRange(start: number, end: number, count: number): number[] {\n if (count <= 1) return [start];\n const step = (end - start) / (count - 1);\n return Array.from({ length: count }, (_, i) => start + step * i);\n}\n\nfunction buildBandScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = channel.scale?.domain\n ? (channel.scale.domain as string[])\n : applyCategoricalSort(uniqueStrings(fieldValues(data, channel.field)), channel.sort);\n\n const padding = channel.scale?.padding ?? 0.35;\n const scale = scaleBand().domain(values).range([rangeStart, rangeEnd]).padding(padding);\n\n if (channel.scale?.paddingInner !== undefined) {\n scale.paddingInner(channel.scale.paddingInner);\n }\n if (channel.scale?.paddingOuter !== undefined) {\n scale.paddingOuter(channel.scale.paddingOuter);\n }\n if (channel.scale?.reverse) {\n const [r0, r1] = scale.range();\n scale.range([r1, r0]);\n }\n\n return { scale, type: 'band', channel };\n}\n\nfunction buildPointScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = channel.scale?.domain\n ? (channel.scale.domain as string[])\n : applyCategoricalSort(uniqueStrings(fieldValues(data, channel.field)), channel.sort);\n\n const padding = channel.scale?.padding ?? 0.5;\n const scale = scalePoint().domain(values).range([rangeStart, rangeEnd]).padding(padding);\n\n if (channel.scale?.reverse) {\n const [r0, r1] = scale.range();\n scale.range([r1, r0]);\n }\n\n return { scale, type: 'point', channel };\n}\n\nfunction buildOrdinalColorScale(\n channel: EncodingChannel,\n data: DataRow[],\n palette: string[],\n): ResolvedScale {\n // Use explicit domain if provided, otherwise derive from data\n const explicitDomain = channel.scale?.domain as string[] | undefined;\n const values = explicitDomain\n ? explicitDomain.map(String)\n : applyCategoricalSort(uniqueStrings(fieldValues(data, channel.field)), channel.sort);\n\n // Use explicit range if provided, otherwise fall back to theme palette\n const explicitRange = channel.scale?.range as string[] | undefined;\n const colors = explicitRange ?? palette;\n\n const scale = scaleOrdinal<string>().domain(values).range(colors);\n\n return { scale, type: 'ordinal', channel };\n}\n\nfunction buildSequentialColorScale(\n channel: EncodingChannel,\n data: DataRow[],\n palette: string[],\n): ResolvedScale {\n const values = parseNumbers(fieldValues(data, channel.field));\n const domainMin = min(values) ?? 0;\n const domainMax = max(values) ?? 1;\n\n // Use explicit range if provided, otherwise fall back to theme palette endpoints\n const explicitRange = channel.scale?.range as string[] | undefined;\n const colors = explicitRange ?? palette;\n\n const scale = scaleLinear<string>()\n .domain([domainMin, domainMax])\n .range([colors[0], colors[colors.length - 1]])\n .clamp(true);\n\n // Cast: sequential color scale (number -> string) is structurally incompatible\n // with D3Scale (number -> number), but is only ever accessed via scales.color\n // where consumers already cast appropriately.\n return { scale: scale as unknown as D3Scale, type: 'sequential', channel };\n}\n\n// ---------------------------------------------------------------------------\n// Positional scale selection\n// ---------------------------------------------------------------------------\n\n/**\n * Choose the right scale type for a positional channel (x or y).\n * Respects explicit scale.type overrides from the spec.\n */\nfunction buildPositionalScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n chartType: string,\n axis: 'x' | 'y',\n): ResolvedScale {\n // Explicit scale type override\n if (channel.scale?.type) {\n switch (channel.scale.type) {\n case 'time':\n return buildTimeScale(channel, data, rangeStart, rangeEnd);\n case 'utc':\n return buildUtcScale(channel, data, rangeStart, rangeEnd);\n case 'linear':\n return buildLinearScale(channel, data, rangeStart, rangeEnd);\n case 'log':\n return buildLogScale(channel, data, rangeStart, rangeEnd);\n case 'pow':\n return buildPowScale(channel, data, rangeStart, rangeEnd);\n case 'sqrt':\n return buildSqrtScale(channel, data, rangeStart, rangeEnd);\n case 'symlog':\n return buildSymlogScale(channel, data, rangeStart, rangeEnd);\n case 'quantile':\n return buildQuantileScale(channel, data, rangeStart, rangeEnd);\n case 'quantize':\n return buildQuantizeScale(channel, data, rangeStart, rangeEnd);\n case 'threshold':\n return buildThresholdScale(channel, data, rangeStart, rangeEnd);\n case 'band':\n return buildBandScale(channel, data, rangeStart, rangeEnd);\n case 'point':\n return buildPointScale(channel, data, rangeStart, rangeEnd);\n case 'ordinal':\n return buildBandScale(channel, data, rangeStart, rangeEnd);\n }\n }\n\n // Infer from field type\n switch (channel.type) {\n case 'temporal':\n return buildTimeScale(channel, data, rangeStart, rangeEnd);\n case 'quantitative':\n return buildLinearScale(channel, data, rangeStart, rangeEnd);\n case 'nominal':\n case 'ordinal':\n // Bar charts use band scales for their categorical axis (both orientations)\n if (\n chartType === 'bar' ||\n ((chartType === 'circle' || chartType === 'lollipop') && axis === 'y')\n ) {\n return buildBandScale(channel, data, rangeStart, rangeEnd);\n }\n return buildPointScale(channel, data, rangeStart, rangeEnd);\n default:\n return buildLinearScale(channel, data, rangeStart, rangeEnd);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute D3 scales from encoding channels and data.\n *\n * @param spec - Normalized chart spec.\n * @param chartArea - The computed chart drawing area.\n * @param data - Data rows.\n * @returns ResolvedScales with d3 scale instances.\n */\nexport function computeScales(\n spec: NormalizedChartSpec,\n chartArea: Rect,\n data: DataRow[],\n): ResolvedScales {\n const result: ResolvedScales = {};\n const encoding = spec.encoding as Encoding;\n\n // Scatter/bubble charts should NOT include zero by default (tight domain fits data range)\n if (spec.markType === 'point') {\n if (encoding.x?.type === 'quantitative' && encoding.x.scale?.zero === undefined) {\n if (!encoding.x.scale) {\n (encoding.x as { scale?: Record<string, unknown> }).scale = { zero: false };\n } else {\n (encoding.x.scale as Record<string, unknown>).zero = false;\n }\n }\n if (encoding.y?.type === 'quantitative' && encoding.y.scale?.zero === undefined) {\n if (!encoding.y.scale) {\n (encoding.y as { scale?: Record<string, unknown> }).scale = { zero: false };\n } else {\n (encoding.y.scale as Record<string, unknown>).zero = false;\n }\n }\n }\n\n if (encoding.x) {\n // For stacked bars, the x-domain needs the max category sum, not max individual value.\n // Without this, stacked bars would clip past the chart area.\n let xData = data;\n let xChannel = encoding.x;\n const xStackDisabled = encoding.x.stack === null || encoding.x.stack === false;\n if (\n spec.markType === 'bar' &&\n encoding.color &&\n encoding.x.type === 'quantitative' &&\n !xStackDisabled\n ) {\n if (encoding.x.stack === 'normalize') {\n // Normalize: domain is [0, 1]\n xChannel = { ...encoding.x, scale: { ...encoding.x.scale, domain: [0, 1], nice: false } };\n } else if (encoding.x.stack === 'center') {\n // Center: compute max half-sum for symmetric domain\n const yField = encoding.y?.field;\n const xField = encoding.x.field;\n if (yField) {\n const sums = new Map<string, number>();\n for (const row of data) {\n const cat = String(row[yField] ?? '');\n const val = Number(row[xField] ?? 0);\n if (Number.isFinite(val) && val > 0) {\n sums.set(cat, (sums.get(cat) ?? 0) + val);\n }\n }\n const maxSum = Math.max(...sums.values(), 0);\n const half = maxSum / 2;\n xChannel = {\n ...encoding.x,\n scale: { ...encoding.x.scale, domain: [-half, half], zero: true },\n };\n }\n } else {\n // Zero (default): domain extends to max category sum\n const yField = encoding.y?.field;\n const xField = encoding.x.field;\n if (yField) {\n const sums = new Map<string, number>();\n for (const row of data) {\n const cat = String(row[yField] ?? '');\n const val = Number(row[xField] ?? 0);\n if (Number.isFinite(val) && val > 0) {\n sums.set(cat, (sums.get(cat) ?? 0) + val);\n }\n }\n const maxSum = Math.max(...sums.values(), 0);\n // Create a synthetic row with the max stack sum so buildLinearScale sees it\n xData = [...data, { [xField]: maxSum } as DataRow];\n }\n }\n }\n\n result.x = buildPositionalScale(\n xChannel,\n xData,\n chartArea.x,\n chartArea.x + chartArea.width,\n spec.markType,\n 'x',\n );\n }\n\n if (encoding.y) {\n // For stacked vertical bars and stacked areas, the y-domain needs the max\n // category sum, not the max individual value. Without this, stacked marks\n // would clip above the chart area.\n // Vertical bar = x is categorical and y is quantitative (old 'column' chart type).\n let yData = data;\n let yChannel = encoding.y;\n const isVerticalBar =\n spec.markType === 'bar' &&\n (encoding.x?.type === 'nominal' || encoding.x?.type === 'ordinal') &&\n encoding.y.type === 'quantitative';\n const yStackDisabled = encoding.y.stack === null || encoding.y.stack === false;\n if (\n (isVerticalBar || spec.markType === 'area') &&\n encoding.color &&\n encoding.y.type === 'quantitative' &&\n !yStackDisabled\n ) {\n if (encoding.y.stack === 'normalize') {\n // Normalize: domain is [0, 1] (VL convention)\n yChannel = { ...encoding.y, scale: { ...encoding.y.scale, domain: [0, 1], nice: false } };\n } else if (encoding.y.stack === 'center') {\n // Center: compute max half-sum for symmetric domain\n const xField = encoding.x?.field;\n const yField = encoding.y.field;\n if (xField) {\n const sums = new Map<string, number>();\n for (const row of data) {\n const cat = String(row[xField] ?? '');\n const val = Number(row[yField] ?? 0);\n if (Number.isFinite(val) && val > 0) {\n sums.set(cat, (sums.get(cat) ?? 0) + val);\n }\n }\n const maxSum = Math.max(...sums.values(), 0);\n const half = maxSum / 2;\n yChannel = {\n ...encoding.y,\n scale: { ...encoding.y.scale, domain: [-half, half], zero: true },\n };\n }\n } else {\n // Zero (default): domain extends to max category sum\n const xField = encoding.x?.field;\n const yField = encoding.y.field;\n if (xField) {\n const sums = new Map<string, number>();\n for (const row of data) {\n const cat = String(row[xField] ?? '');\n const val = Number(row[yField] ?? 0);\n if (Number.isFinite(val) && val > 0) {\n sums.set(cat, (sums.get(cat) ?? 0) + val);\n }\n }\n const maxSum = Math.max(...sums.values(), 0);\n // Create a synthetic row with the max stack sum so buildLinearScale sees it\n yData = [...data, { [yField]: maxSum } as DataRow];\n }\n }\n }\n\n // Y axis: range is inverted (SVG y goes down, data y goes up)\n result.y = buildPositionalScale(\n yChannel,\n yData,\n chartArea.y + chartArea.height,\n chartArea.y,\n spec.markType,\n 'y',\n );\n }\n\n if (encoding.color) {\n const defaultPalette = [\n '#1b7fa3',\n '#c44e52',\n '#6a9f58',\n '#d47215',\n '#507e79',\n '#9a6a8d',\n '#c4636b',\n '#9c755f',\n '#a88f22',\n '#858078',\n ];\n\n // Only build color scales for field-based encodings, not conditional value defs\n if ('field' in encoding.color) {\n if (encoding.color.type === 'quantitative') {\n // Sequential color scale for value-based coloring\n result.color = buildSequentialColorScale(encoding.color, data, defaultPalette);\n } else {\n // Categorical color scale for nominal/ordinal grouping\n result.color = buildOrdinalColorScale(encoding.color, data, defaultPalette);\n }\n }\n }\n\n return result;\n}\n","/**\n * Legend computation.\n *\n * Derives legend entries from the color encoding's unique values in data,\n * computes position based on layout strategy, and returns a LegendLayout\n * that dimensions.ts uses to reserve space in the chart area.\n *\n * The legend is computed early (before marks) so the chartArea accounts\n * for legend space. Entries come from data + encoding, not marks.\n *\n * Overflow protection: when there are too many entries for the available\n * space, entries are truncated and a \"+N more\" indicator is appended.\n */\n\nimport type {\n LayoutStrategy,\n LegendEntry,\n LegendLayout,\n Rect,\n ResolvedTheme,\n TextStyle,\n} from '@opendata-ai/openchart-core';\nimport { BRAND_RESERVE_WIDTH, estimateTextWidth } from '@opendata-ai/openchart-core';\n\nimport type { NormalizedChartSpec } from '../compiler/types';\nimport { ENTRY_GAP, measureLegendWrap, SWATCH_GAP, SWATCH_SIZE } from './wrap';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst LEGEND_PADDING = 8;\nconst LEGEND_RIGHT_WIDTH = 120;\n\n/** Max fraction of chart area height for right-positioned legends. */\nconst RIGHT_LEGEND_MAX_HEIGHT_RATIO = 0.4;\n\n/** Max number of rows for top-positioned legends before truncation. */\nconst TOP_LEGEND_MAX_ROWS = 2;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Determine the swatch shape based on mark type. */\nfunction swatchShapeForType(markType: string): LegendEntry['shape'] {\n switch (markType) {\n case 'line':\n return 'line';\n case 'point':\n case 'circle':\n case 'lollipop':\n return 'circle';\n default:\n return 'square';\n }\n}\n\n/** Extract unique color values from data based on the color encoding. */\nfunction extractColorEntries(spec: NormalizedChartSpec, theme: ResolvedTheme): LegendEntry[] {\n const colorEnc = spec.encoding.color;\n if (!colorEnc) return [];\n\n // Conditional color definitions don't produce legend entries\n if ('condition' in colorEnc) return [];\n\n // Sequential (quantitative) color doesn't produce discrete legend entries\n if (colorEnc.type === 'quantitative') return [];\n\n const uniqueValues = [...new Set(spec.data.map((d) => String(d[colorEnc.field])))];\n const explicitDomain = colorEnc.scale?.domain as string[] | undefined;\n const explicitRange = colorEnc.scale?.range as string[] | undefined;\n const palette = explicitRange ?? theme.colors.categorical;\n const shape = swatchShapeForType(spec.markType);\n\n return uniqueValues.map((value, i) => {\n // When explicit domain+range are provided, look up the color by domain index\n // so legend colors match the mark colors exactly.\n let colorIndex = i;\n if (explicitDomain && explicitRange) {\n const domainIdx = explicitDomain.indexOf(value);\n if (domainIdx >= 0) colorIndex = domainIdx;\n }\n return {\n label: value,\n color: palette[colorIndex % palette.length],\n shape,\n active: true,\n };\n });\n}\n\n/**\n * Truncate entries and add a \"+N more\" indicator if needed.\n */\nfunction truncateEntries(entries: LegendEntry[], maxCount: number): LegendEntry[] {\n if (maxCount >= entries.length || maxCount <= 0) return entries;\n\n const truncated = entries.slice(0, maxCount);\n const remaining = entries.length - maxCount;\n truncated.push({\n label: `+${remaining} more`,\n color: '#999999',\n shape: 'square',\n active: false,\n overflow: true,\n });\n\n return truncated;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute legend layout for a chart spec.\n *\n * @param spec - Normalized chart spec.\n * @param strategy - Responsive layout strategy.\n * @param theme - Resolved theme.\n * @param chartArea - The available chart area (before legend space is reserved).\n * @returns LegendLayout with position, entries, and bounds.\n */\nexport function computeLegend(\n spec: NormalizedChartSpec,\n strategy: LayoutStrategy,\n theme: ResolvedTheme,\n chartArea: Rect,\n watermark: boolean = true,\n): LegendLayout {\n // Legend explicitly hidden via show: false, or height strategy says no legend\n if (spec.legend?.show === false || strategy.legendMaxHeight === 0) {\n return {\n position: 'top',\n entries: [],\n bounds: { x: 0, y: 0, width: 0, height: 0 },\n labelStyle: {\n fontFamily: theme.fonts.family,\n fontSize: theme.fonts.sizes.small,\n fontWeight: theme.fonts.weights.normal,\n fill: theme.colors.text,\n lineHeight: 1.3,\n },\n swatchSize: SWATCH_SIZE,\n swatchGap: SWATCH_GAP,\n entryGap: ENTRY_GAP,\n };\n }\n\n let entries = extractColorEntries(spec, theme);\n\n // Auto-suppress legend when endpoint labels identify series on line/area charts.\n // Guards: keep legend at compact breakpoints (labels hidden), for stacked areas\n // (endpoint labels overlap), and when user explicitly forces legend on.\n const isLineOrArea = spec.markType === 'line' || spec.markType === 'area';\n const hasLabels = spec.labels.density !== 'none';\n const labelsWillRender = strategy.labelMode !== 'none';\n const hasColorEncoding = spec.encoding.color != null;\n const legendNotForced = spec.legend?.show !== true;\n\n if (isLineOrArea && hasLabels && labelsWillRender && hasColorEncoding && legendNotForced) {\n const isArea = spec.markType === 'area';\n const quantChannel =\n spec.encoding.y?.type === 'quantitative' ? spec.encoding.y : spec.encoding.x;\n const stackValue = quantChannel?.stack;\n const isStacked = stackValue !== null && stackValue !== false;\n\n if (!isArea || !isStacked) {\n entries = [];\n }\n }\n\n const labelStyle: TextStyle = {\n fontFamily: theme.fonts.family,\n fontSize: theme.fonts.sizes.small,\n fontWeight: theme.fonts.weights.normal,\n fill: theme.colors.text,\n lineHeight: 1.3,\n };\n\n // Resolve position: spec-level override wins, then responsive strategy\n const resolvedPosition =\n spec.legend?.position ?? (strategy.legendPosition === 'right' ? 'right' : 'top');\n\n // No entries = empty legend with no space\n if (entries.length === 0) {\n return {\n position: resolvedPosition,\n entries: [],\n bounds: { x: 0, y: 0, width: 0, height: 0 },\n labelStyle,\n swatchSize: SWATCH_SIZE,\n swatchGap: SWATCH_GAP,\n entryGap: ENTRY_GAP,\n };\n }\n\n if (resolvedPosition === 'right' || resolvedPosition === 'bottom-right') {\n // Right-positioned legend: vertical stack\n const maxLabelWidth = Math.max(\n ...entries.map((e) => estimateTextWidth(e.label, labelStyle.fontSize, labelStyle.fontWeight)),\n );\n const legendWidth = Math.min(\n LEGEND_RIGHT_WIDTH,\n SWATCH_SIZE + SWATCH_GAP + maxLabelWidth + LEGEND_PADDING * 2,\n );\n const entryHeight = Math.max(SWATCH_SIZE, labelStyle.fontSize * labelStyle.lineHeight);\n\n // Apply max height ratio (default 40% of chart area, strategy can override)\n const maxHeightRatio =\n strategy.legendMaxHeight > 0 ? strategy.legendMaxHeight : RIGHT_LEGEND_MAX_HEIGHT_RATIO;\n const maxLegendHeight = chartArea.height * maxHeightRatio;\n\n // Calculate how many entries fit\n const maxFromSpace = Math.max(\n 1,\n Math.floor((maxLegendHeight - LEGEND_PADDING * 2) / (entryHeight + 4)),\n );\n // symbolLimit overrides the space-based limit when explicitly set (minimum 1)\n const maxEntries =\n spec.legend?.symbolLimit != null ? Math.max(1, spec.legend.symbolLimit) : maxFromSpace;\n if (entries.length > maxEntries) {\n entries = truncateEntries(entries, maxEntries);\n }\n\n const legendHeight =\n entries.length * entryHeight + (entries.length - 1) * 4 + LEGEND_PADDING * 2;\n const clampedHeight = Math.min(legendHeight, chartArea.height);\n\n // bottom-right anchors to the bottom of the chart area\n const legendY =\n resolvedPosition === 'bottom-right'\n ? chartArea.y + chartArea.height - clampedHeight\n : chartArea.y;\n\n // Apply user-provided legend offset\n const offsetDx = spec.legend?.offset?.dx ?? 0;\n const offsetDy = spec.legend?.offset?.dy ?? 0;\n\n return {\n position: resolvedPosition,\n entries,\n bounds: {\n x: chartArea.x + chartArea.width - legendWidth + offsetDx,\n y: legendY + offsetDy,\n width: legendWidth,\n height: clampedHeight,\n },\n labelStyle,\n swatchSize: SWATCH_SIZE,\n swatchGap: SWATCH_GAP,\n entryGap: 4,\n };\n }\n\n // Top/bottom-positioned legend: horizontal flow with overflow protection.\n // Reserve space on the right for bottom legends so they don't overlap the brand\n // watermark. Top legends don't need this since the brand renders at the bottom.\n const reserveBrand = watermark && resolvedPosition === 'bottom';\n const availableWidth =\n chartArea.width - LEGEND_PADDING * 2 - (reserveBrand ? BRAND_RESERVE_WIDTH : 0);\n\n // Apply symbolLimit first if set (minimum 1), then fit remaining entries to available rows.\n if (spec.legend?.symbolLimit != null) {\n const limit = Math.max(1, spec.legend.symbolLimit);\n if (limit < entries.length) {\n entries = truncateEntries(entries, limit);\n }\n }\n\n // Resolve max rows: explicit maxRows wins, then columns-derived, then default.\n const maxRows =\n spec.legend?.maxRows != null\n ? Math.max(1, spec.legend.maxRows)\n : spec.legend?.columns != null\n ? Math.ceil(entries.length / spec.legend.columns)\n : TOP_LEGEND_MAX_ROWS;\n const { fittingCount } = measureLegendWrap(entries, availableWidth, labelStyle, maxRows);\n\n if (fittingCount < entries.length) {\n entries = truncateEntries(entries, fittingCount);\n }\n\n const totalWidth = entries.reduce((sum, entry) => {\n const labelWidth = estimateTextWidth(entry.label, labelStyle.fontSize, labelStyle.fontWeight);\n return sum + SWATCH_SIZE + SWATCH_GAP + labelWidth + ENTRY_GAP;\n }, 0);\n\n // Calculate actual row count for height (recompute after truncation).\n const { rowCount } = measureLegendWrap(entries, availableWidth, labelStyle);\n\n const rowHeight = SWATCH_SIZE + 4;\n const legendHeight = rowCount * rowHeight + LEGEND_PADDING * 2;\n\n // Apply user-provided legend offset\n const offsetDx = spec.legend?.offset?.dx ?? 0;\n const offsetDy = spec.legend?.offset?.dy ?? 0;\n\n return {\n position: resolvedPosition,\n entries,\n bounds: {\n x: chartArea.x + offsetDx,\n y:\n (resolvedPosition === 'bottom'\n ? chartArea.y + chartArea.height - legendHeight\n : chartArea.y) + offsetDy,\n width: Math.min(totalWidth, availableWidth),\n height: legendHeight,\n },\n labelStyle,\n swatchSize: SWATCH_SIZE,\n swatchGap: SWATCH_GAP,\n entryGap: ENTRY_GAP,\n };\n}\n","/**\n * Legend row-wrap geometry.\n *\n * Shared helper for measuring how legend entries flow across horizontal rows\n * when wrapped at a max width. Both the main legend compute and the sankey\n * legend compile use this to size their legends — the main legend uses\n * `fittingCount` for truncation decisions, while sankey uses `rowCount` to\n * reserve vertical height.\n *\n * The geometry matches the existing layout exactly: each entry occupies\n * SWATCH_SIZE + SWATCH_GAP + labelWidth + ENTRY_GAP pixels, a new row is\n * started when the accumulated row width plus the next entry would exceed\n * maxWidth (and the current row is non-empty), and rowWidths captures the\n * in-row accumulated width at the point of wrapping.\n */\n\nimport type { LegendEntry, TextStyle } from '@opendata-ai/openchart-core';\nimport { estimateTextWidth } from '@opendata-ai/openchart-core';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n//\n// Single source of truth for legend row geometry. Both compute.ts and the\n// sankey compile site import these so the wrap math here can never drift from\n// the layout math at the call sites.\n\nexport const SWATCH_SIZE = 12;\nexport const SWATCH_GAP = 6;\nexport const ENTRY_GAP = 16;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport interface LegendWrapResult {\n /** Total number of rows the entries occupy when wrapped at maxWidth. */\n rowCount: number;\n /** Entries that fit within maxRows (for truncation). Equals entries.length when maxRows is not set or all entries fit. */\n fittingCount: number;\n /** Width (in px) of each row — callers can use for alignment. */\n rowWidths: number[];\n}\n\n/**\n * Measure how legend entries wrap across rows at a given max width.\n *\n * @param entries - Legend entries to measure.\n * @param maxWidth - Maximum width (in px) available for a single row.\n * @param labelStyle - Text style used to estimate label widths.\n * @param maxRows - Optional cap used only for the `fittingCount` truncation decision. When provided, `fittingCount` will be the index of the first entry that would spill onto a row beyond `maxRows`. `rowCount` is always the real row count regardless of this cap.\n */\nexport function measureLegendWrap(\n entries: LegendEntry[],\n maxWidth: number,\n labelStyle: TextStyle,\n maxRows?: number,\n): LegendWrapResult {\n if (entries.length === 0) {\n return { rowCount: 0, fittingCount: 0, rowWidths: [] };\n }\n\n let rowCount = 1;\n let rowWidth = 0;\n const rowWidths: number[] = [];\n let fittingCount = entries.length;\n let fittingCountLocked = false;\n\n for (let i = 0; i < entries.length; i++) {\n const labelWidth = estimateTextWidth(\n entries[i].label,\n labelStyle.fontSize,\n labelStyle.fontWeight,\n );\n const entryWidth = SWATCH_SIZE + SWATCH_GAP + labelWidth + ENTRY_GAP;\n\n if (rowWidth + entryWidth > maxWidth && rowWidth > 0) {\n rowWidths.push(rowWidth);\n rowCount++;\n rowWidth = entryWidth;\n if (!fittingCountLocked && maxRows != null && rowCount > maxRows) {\n fittingCount = i;\n fittingCountLocked = true;\n }\n } else {\n rowWidth += entryWidth;\n }\n }\n\n // Flush the final row width so rowWidths has one entry per row.\n rowWidths.push(rowWidth);\n\n return { rowCount, fittingCount, rowWidths };\n}\n","/**\n * Sankey diagram compilation pipeline.\n *\n * Takes a raw sankey spec (unknown shape), validates, normalizes, resolves\n * theme, computes chrome, runs d3-sankey layout, builds marks with colors\n * and labels, and returns a SankeyLayout.\n *\n * Pipeline:\n * validate -> normalize -> resolve theme -> dark mode adapt ->\n * compute chrome -> compute drawing area -> d3-sankey layout ->\n * build node marks -> build link marks -> legend -> tooltips ->\n * a11y -> animation -> return SankeyLayout\n */\n\nimport type {\n CompileOptions,\n LegendEntry,\n LegendLayout,\n Rect,\n ResolvedAnimation,\n ResolvedTheme,\n SankeyLayout,\n SankeyLinkMark,\n SankeyNodeMark,\n TextStyle,\n TooltipContent,\n TooltipField,\n} from '@opendata-ai/openchart-core';\nimport {\n adaptTheme,\n buildD3Formatter,\n computeChrome,\n estimateTextWidth,\n formatNumber,\n resolveTheme,\n} from '@opendata-ai/openchart-core';\n\nimport { resolveAnimation } from '../compiler/animation';\nimport { compile as compileSpec } from '../compiler/index';\nimport { ENTRY_GAP, measureLegendWrap, SWATCH_GAP, SWATCH_SIZE } from '../legend/wrap';\nimport { type ComputedNode, computeSankeyLayout, generateLinkPath } from './layout';\nimport type { NormalizedSankeySpec } from './types';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst LABEL_GAP = 6;\nconst LINK_OPACITY_LIGHT = 0.5;\nconst LINK_OPACITY_DARK = 0.75;\nconst NODE_CORNER_RADIUS = 2;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Assign a color from the categorical palette, cycling through it. */\nfunction pickColor(palette: string[], index: number): string {\n return palette[index % palette.length];\n}\n\n/**\n * Build a color map for nodes.\n * If encoding.color is specified, groups by that field's value.\n * Otherwise, assigns by unique node ID cycling the palette.\n * Accepts any array with `id` field (works with ComputedNode[] or plain objects).\n */\nfunction buildNodeColorMap(\n nodes: Array<{ id: string }>,\n palette: string[],\n colorField: string | undefined,\n data: Record<string, unknown>[],\n sourceField: string,\n targetField: string,\n): Map<string, string> {\n const colorMap = new Map<string, string>();\n\n if (colorField) {\n // Build a mapping from node ID to color category value\n const nodeCategoryMap = new Map<string, string>();\n for (const row of data) {\n const src = String(row[sourceField]);\n const tgt = String(row[targetField]);\n const cat = String(row[colorField]);\n if (!nodeCategoryMap.has(src)) nodeCategoryMap.set(src, cat);\n if (!nodeCategoryMap.has(tgt)) nodeCategoryMap.set(tgt, cat);\n }\n\n // Assign colors by unique category\n const categoryIndex = new Map<string, number>();\n let nextIdx = 0;\n for (const node of nodes) {\n const category = nodeCategoryMap.get(node.id) ?? node.id;\n if (!categoryIndex.has(category)) {\n categoryIndex.set(category, nextIdx++);\n }\n colorMap.set(node.id, pickColor(palette, categoryIndex.get(category)!));\n }\n } else {\n // Default: assign colors cycling through palette by node order\n for (let i = 0; i < nodes.length; i++) {\n colorMap.set(nodes[i].id, pickColor(palette, i));\n }\n }\n\n return colorMap;\n}\n\n/**\n * Get colors for a link based on the linkStyle strategy.\n */\nfunction getLinkColors(\n linkStyle: string,\n sourceColor: string,\n targetColor: string,\n neutralColor: string,\n): { sourceColor: string; targetColor: string } {\n switch (linkStyle) {\n case 'source':\n return { sourceColor, targetColor: sourceColor };\n case 'target':\n return { sourceColor: targetColor, targetColor };\n case 'neutral':\n return { sourceColor: neutralColor, targetColor: neutralColor };\n default:\n return { sourceColor, targetColor };\n }\n}\n\n/**\n * Determine label position for a node based on its column depth.\n * Default ('auto'): leftmost/middle columns label right, rightmost column labels left.\n * 'right': all labels to the right. 'left': all labels to the left.\n */\nfunction computeNodeLabel(\n node: ComputedNode,\n maxDepth: number,\n theme: ResolvedTheme,\n nodeWidth: number,\n nodeLabelAlign: 'auto' | 'left' | 'right' = 'auto',\n containerWidth?: number,\n padding?: number,\n): SankeyNodeMark['label'] {\n const depth = node.depth ?? 0;\n\n // Determine which side to place the label\n let placeLeft: boolean;\n if (nodeLabelAlign === 'left') {\n placeLeft = true;\n } else if (nodeLabelAlign === 'right') {\n placeLeft = false;\n } else {\n // 'auto': rightmost column goes left, everything else goes right\n placeLeft = depth === maxDepth;\n }\n\n const style: TextStyle = {\n fontFamily: theme.fonts.family,\n fontSize: theme.fonts.sizes.small,\n fontWeight: theme.fonts.weights.normal,\n fill: theme.colors.text,\n lineHeight: 1.3,\n };\n\n const x0 = node.x0 ?? 0;\n const x1 = node.x1 ?? nodeWidth;\n const y0 = node.y0 ?? 0;\n const y1 = node.y1 ?? 0;\n const midY = (y0 + y1) / 2;\n\n // Compute maxWidth: space from label position to the container edge\n const pad = padding ?? 0;\n let maxWidth: number | undefined;\n if (containerWidth !== undefined) {\n if (placeLeft) {\n // Label goes left from x0: available space is from left padding to x0\n maxWidth = x0 - LABEL_GAP - pad;\n } else {\n // Label goes right from x1: available space is from x1 to right edge\n maxWidth = containerWidth - pad - (x1 + LABEL_GAP);\n }\n if (maxWidth !== undefined && maxWidth < 0) maxWidth = 0;\n }\n\n if (placeLeft) {\n return {\n text: node.label ?? node.id,\n x: x0 - LABEL_GAP,\n y: midY,\n style: { ...style, textAnchor: 'end', dominantBaseline: 'central' },\n visible: true,\n maxWidth,\n };\n }\n\n return {\n text: node.label ?? node.id,\n x: x1 + LABEL_GAP,\n y: midY,\n style: { ...style, textAnchor: 'start', dominantBaseline: 'central' },\n visible: true,\n maxWidth,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a sankey spec into a SankeyLayout.\n *\n * @param spec - Raw sankey spec (validated at runtime).\n * @param options - Compile options (width, height, theme, darkMode).\n * @returns SankeyLayout with all computed positions and visual properties.\n * @throws Error if spec is invalid or not a sankey type.\n */\nexport function compileSankey(spec: unknown, options: CompileOptions): SankeyLayout {\n // 1. Validate + normalize via the shared compiler pipeline\n const { spec: normalized } = compileSpec(spec);\n\n if (!('type' in normalized) || normalized.type !== 'sankey') {\n throw new Error(\n 'compileSankey received a non-sankey spec. Use compileChart, compileTable, or compileGraph instead.',\n );\n }\n\n const sankeySpec = normalized as NormalizedSankeySpec;\n\n // Resolve watermark: explicit spec value wins, then options fallback, then default true.\n const rawWatermark = (spec as Record<string, unknown>).watermark;\n const watermark = rawWatermark !== undefined ? sankeySpec.watermark : (options.watermark ?? true);\n\n // 2. Resolve theme\n const mergedThemeConfig = options.theme\n ? { ...sankeySpec.theme, ...options.theme }\n : sankeySpec.theme;\n const lightTheme: ResolvedTheme = resolveTheme(mergedThemeConfig);\n let theme: ResolvedTheme = lightTheme;\n if (options.darkMode) {\n theme = adaptTheme(theme);\n // Sankey nodes and link gradients need vivid colors that stand out on dark\n // backgrounds. The adapted palette preserves contrast ratios designed for\n // text, but those contrast-matched colors are too dark for filled shapes.\n // Use the original light-theme categorical palette for node/link colors.\n theme = {\n ...theme,\n colors: { ...theme.colors, categorical: lightTheme.colors.categorical },\n };\n }\n\n // 3. Compute chrome\n const chrome = computeChrome(\n {\n title: sankeySpec.chrome.title,\n subtitle: sankeySpec.chrome.subtitle,\n source: sankeySpec.chrome.source,\n byline: sankeySpec.chrome.byline,\n footer: sankeySpec.chrome.footer,\n },\n theme,\n options.width,\n options.measureText,\n 'full',\n undefined,\n watermark,\n );\n\n // 4. Compute drawing area (total space minus chrome)\n const padding = theme.spacing.padding;\n const fullArea: Rect = {\n x: padding,\n y: padding + chrome.topHeight,\n width: options.width - padding * 2,\n height: options.height - chrome.topHeight - chrome.bottomHeight - padding * 2,\n };\n\n // Guard against negative dimensions\n if (fullArea.width <= 0 || fullArea.height <= 0) {\n return emptyLayout(fullArea, chrome, theme, options, watermark);\n }\n\n // 5. Extract encoding fields\n const sourceField = sankeySpec.encoding.source.field;\n const targetField = sankeySpec.encoding.target.field;\n const valueField = sankeySpec.encoding.value.field;\n const colorField = sankeySpec.encoding.color?.field;\n\n // 5b. Pre-compute legend to reserve vertical space\n // We need the color map first, so build a temporary one from raw data\n const tempNodeIds = new Set<string>();\n for (const row of sankeySpec.data) {\n tempNodeIds.add(String(row[sourceField]));\n tempNodeIds.add(String(row[targetField]));\n }\n const tempColorMap = buildNodeColorMap(\n [...tempNodeIds].map((id) => ({ id })),\n theme.colors.categorical,\n colorField,\n sankeySpec.data,\n sourceField,\n targetField,\n );\n const legend = buildSankeyLegend(\n tempColorMap,\n colorField,\n sankeySpec.data,\n sourceField,\n targetField,\n theme,\n fullArea,\n );\n\n // Reserve legend space by shrinking the drawing area\n const legendGap = legend.entries.length > 0 ? 4 : 0;\n const area: Rect = {\n x: fullArea.x,\n y: fullArea.y + legend.bounds.height + legendGap,\n width: fullArea.width,\n height: fullArea.height - legend.bounds.height - legendGap,\n };\n\n if (area.height <= 0) {\n return emptyLayout(area, chrome, theme, options, watermark);\n }\n\n // 6. Run d3-sankey layout (may re-run once if labels overflow)\n const labelFontSize = theme.fonts.sizes.small;\n const labelFontWeight = theme.fonts.weights.normal;\n const nodeWidth = sankeySpec.nodeWidth ?? 12;\n\n let layoutArea: Rect = { ...area };\n let { nodes, links } = computeSankeyLayout(\n sankeySpec.data,\n sourceField,\n targetField,\n valueField,\n layoutArea,\n sankeySpec.nodeWidth,\n sankeySpec.nodePadding,\n sankeySpec.nodeAlign,\n sankeySpec.iterations,\n sankeySpec.nodeSort,\n );\n\n // 6b. Check if any right-side node labels overflow the right edge.\n const nodeLabelAlign = sankeySpec.nodeLabelAlign ?? 'auto';\n const maxDepthFirst = nodes.reduce((max, n) => Math.max(max, n.depth ?? 0), 0);\n const rightEdge = area.x + area.width;\n let maxOverflow = 0;\n for (const node of nodes) {\n const depth = node.depth ?? 0;\n // Skip nodes whose labels go left (they can't overflow the right edge)\n const labelsLeft =\n nodeLabelAlign === 'left' || (nodeLabelAlign === 'auto' && depth === maxDepthFirst);\n if (labelsLeft) continue;\n const labelX = (node.x1 ?? nodeWidth) + LABEL_GAP;\n const labelText = node.label ?? node.id;\n const labelWidth = estimateTextWidth(labelText, labelFontSize, labelFontWeight);\n const overflow = labelX + labelWidth - rightEdge;\n if (overflow > maxOverflow) maxOverflow = overflow;\n }\n\n // Re-run layout with tighter width if labels would clip\n if (maxOverflow > 0) {\n const margin = Math.ceil(maxOverflow) + 4; // small extra buffer\n layoutArea = {\n x: area.x,\n y: area.y,\n width: Math.max(area.width - margin, 40),\n height: area.height,\n };\n ({ nodes, links } = computeSankeyLayout(\n sankeySpec.data,\n sourceField,\n targetField,\n valueField,\n layoutArea,\n sankeySpec.nodeWidth,\n sankeySpec.nodePadding,\n sankeySpec.nodeAlign,\n sankeySpec.iterations,\n sankeySpec.nodeSort,\n ));\n }\n\n // 7. Build node color map\n const nodeColorMap = buildNodeColorMap(\n nodes,\n theme.colors.categorical,\n colorField,\n sankeySpec.data,\n sourceField,\n targetField,\n );\n\n // 8. Compute max depth for label positioning\n const maxDepth = nodes.reduce((max, n) => Math.max(max, n.depth ?? 0), 0);\n\n // 9. Build SankeyNodeMark[]\n const nodeMarks: SankeyNodeMark[] = nodes.map((node) => {\n const fill = nodeColorMap.get(node.id) ?? theme.colors.categorical[0];\n const depth = node.depth ?? 0;\n\n return {\n type: 'sankeyNode' as const,\n x: node.x0 ?? 0,\n y: node.y0 ?? 0,\n width: (node.x1 ?? 0) - (node.x0 ?? 0),\n height: (node.y1 ?? 0) - (node.y0 ?? 0),\n fill,\n cornerRadius: NODE_CORNER_RADIUS,\n label: computeNodeLabel(\n node,\n maxDepth,\n theme,\n sankeySpec.nodeWidth,\n nodeLabelAlign,\n options.width,\n padding,\n ),\n nodeId: node.id,\n value: node.value ?? 0,\n depth,\n data: { id: node.id, label: node.label },\n aria: {\n role: 'img',\n label: `${node.label}: ${formatFlowValue(node.value ?? 0, sankeySpec.valueFormat)}`,\n },\n animationIndex: 0, // Reassigned below after sorting by depth\n };\n });\n\n // 10. Assign node animation indices by column (left-to-right, top-to-bottom within column)\n nodeMarks.sort((a, b) => a.depth - b.depth || a.y - b.y);\n for (let i = 0; i < nodeMarks.length; i++) {\n nodeMarks[i].animationIndex = i;\n }\n\n // 11. Build SankeyLinkMark[]\n const neutralColor = theme.colors.gridline;\n const linkMarks: SankeyLinkMark[] = links.map((link, i) => {\n const sourceNode = link.source as ComputedNode;\n const targetNode = link.target as ComputedNode;\n const srcColor = nodeColorMap.get(sourceNode.id) ?? theme.colors.categorical[0];\n const tgtColor = nodeColorMap.get(targetNode.id) ?? theme.colors.categorical[0];\n const colors = getLinkColors(sankeySpec.linkStyle, srcColor, tgtColor, neutralColor);\n\n return {\n type: 'sankeyLink' as const,\n path: generateLinkPath(link),\n sourceColor: colors.sourceColor,\n targetColor: colors.targetColor,\n fillOpacity:\n sankeySpec.linkOpacity ?? (options.darkMode ? LINK_OPACITY_DARK : LINK_OPACITY_LIGHT),\n sourceId: sourceNode.id,\n targetId: targetNode.id,\n width: link.width ?? 0,\n value: link.value,\n data: (link as unknown as { data: Record<string, unknown> }).data ?? {},\n aria: {\n role: 'img',\n label: `${sourceNode.label} to ${targetNode.label}: ${formatFlowValue(link.value, sankeySpec.valueFormat)}`,\n },\n // Links animate after nodes\n animationIndex: nodeMarks.length + i,\n };\n });\n\n // 12. Rebuild legend with final color map (temp map may differ in node order)\n const finalLegend = buildSankeyLegend(\n nodeColorMap,\n colorField,\n sankeySpec.data,\n sourceField,\n targetField,\n theme,\n fullArea,\n );\n\n // 13. Build tooltip descriptors\n const tooltipDescriptors = buildTooltipDescriptors(nodeMarks, linkMarks, sankeySpec.valueFormat);\n\n // 14. Build a11y metadata\n const a11y = {\n altText: `Sankey diagram with ${nodeMarks.length} nodes and ${linkMarks.length} links`,\n dataTableFallback: linkMarks.map((l) => [l.sourceId, l.targetId, String(l.value)]),\n role: 'img',\n keyboardNavigable: nodeMarks.length > 0,\n };\n\n // 15. Resolve animation\n const resolvedAnimation: ResolvedAnimation | undefined = resolveAnimation(sankeySpec.animation);\n\n return {\n area,\n chrome,\n nodes: nodeMarks,\n links: linkMarks,\n legend: finalLegend,\n tooltipDescriptors,\n a11y,\n theme,\n dimensions: {\n width: options.width,\n height: options.height,\n },\n animation: resolvedAnimation,\n watermark,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Legend builder\n// ---------------------------------------------------------------------------\n\nfunction buildSankeyLegend(\n nodeColorMap: Map<string, string>,\n colorField: string | undefined,\n data: Record<string, unknown>[],\n sourceField: string,\n targetField: string,\n theme: ResolvedTheme,\n area: Rect,\n): LegendLayout {\n const labelStyle: TextStyle = {\n fontFamily: theme.fonts.family,\n fontSize: theme.fonts.sizes.small,\n fontWeight: theme.fonts.weights.normal,\n fill: theme.colors.text,\n lineHeight: 1.3,\n };\n\n let entries: LegendEntry[];\n\n if (colorField) {\n // Group by color field value for legend entries\n const categoryColors = new Map<string, string>();\n const nodeCategoryMap = new Map<string, string>();\n for (const row of data) {\n const src = String(row[sourceField]);\n const tgt = String(row[targetField]);\n const cat = String(row[colorField]);\n if (!nodeCategoryMap.has(src)) nodeCategoryMap.set(src, cat);\n if (!nodeCategoryMap.has(tgt)) nodeCategoryMap.set(tgt, cat);\n }\n for (const [nodeId, category] of nodeCategoryMap) {\n if (!categoryColors.has(category)) {\n categoryColors.set(category, nodeColorMap.get(nodeId) ?? theme.colors.categorical[0]);\n }\n }\n\n entries = [...categoryColors.entries()].map(([label, color]) => ({\n label,\n color,\n shape: 'square' as const,\n active: true,\n }));\n } else {\n // No color encoding: no legend needed (nodes are individually colored)\n entries = [];\n }\n\n // Compute bounds for horizontal top legend\n let bounds = { x: 0, y: 0, width: 0, height: 0 };\n\n if (entries.length > 0) {\n const ROW_HEIGHT = SWATCH_SIZE + 4;\n const availableWidth = area.width;\n\n // Compute row count via shared wrap geometry, then cap at 2 rows.\n const { rowCount } = measureLegendWrap(entries, availableWidth, labelStyle);\n const cappedRowCount = Math.min(rowCount, 2);\n const legendHeight = cappedRowCount * ROW_HEIGHT;\n\n bounds = {\n x: area.x,\n y: area.y,\n width: availableWidth,\n height: legendHeight,\n };\n }\n\n return {\n position: 'top',\n entries,\n bounds,\n labelStyle,\n swatchSize: SWATCH_SIZE,\n swatchGap: SWATCH_GAP,\n entryGap: ENTRY_GAP,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Tooltip builder\n// ---------------------------------------------------------------------------\n\nfunction formatFlowValue(value: number, valueFormat?: string): string {\n if (valueFormat) {\n const fmt = buildD3Formatter(valueFormat);\n if (fmt) return fmt(value);\n }\n return formatNumber(value);\n}\n\nfunction buildTooltipDescriptors(\n nodes: SankeyNodeMark[],\n links: SankeyLinkMark[],\n valueFormat?: string,\n): Map<string, TooltipContent> {\n const descriptors = new Map<string, TooltipContent>();\n\n // Node tooltips: keyed by \"node-{nodeId}\" to match renderer data-mark-id\n for (const node of nodes) {\n const fields: TooltipField[] = [\n {\n label: 'Total flow',\n value: formatFlowValue(node.value, valueFormat),\n },\n ];\n descriptors.set(`node-${node.nodeId}`, {\n title: node.label.text,\n fields,\n });\n }\n\n // Link tooltips: keyed by \"link-{sourceId}-{targetId}\" to match renderer data-mark-id\n for (let i = 0; i < links.length; i++) {\n const link = links[i];\n const fields: TooltipField[] = [\n {\n label: 'Flow',\n value: formatFlowValue(link.value, valueFormat),\n },\n ];\n descriptors.set(`link-${link.sourceId}-${link.targetId}-${i}`, {\n title: `${link.sourceId} \\u2192 ${link.targetId}`,\n fields,\n });\n }\n\n return descriptors;\n}\n\n// ---------------------------------------------------------------------------\n// Empty layout fallback\n// ---------------------------------------------------------------------------\n\nfunction emptyLayout(\n area: Rect,\n chrome: ReturnType<typeof computeChrome>,\n theme: ResolvedTheme,\n options: CompileOptions,\n watermark: boolean,\n): SankeyLayout {\n return {\n area,\n chrome,\n nodes: [],\n links: [],\n legend: {\n position: 'top',\n entries: [],\n bounds: { x: 0, y: 0, width: 0, height: 0 },\n labelStyle: {\n fontFamily: theme.fonts.family,\n fontSize: theme.fonts.sizes.small,\n fontWeight: theme.fonts.weights.normal,\n fill: theme.colors.text,\n lineHeight: 1.3,\n },\n swatchSize: SWATCH_SIZE,\n swatchGap: SWATCH_GAP,\n entryGap: ENTRY_GAP,\n },\n tooltipDescriptors: new Map(),\n a11y: {\n altText: 'Empty sankey diagram',\n dataTableFallback: [],\n role: 'img',\n keyboardNavigable: false,\n },\n theme,\n dimensions: {\n width: options.width,\n height: options.height,\n },\n watermark,\n };\n}\n","export default function max(values, valueof) {\n let max;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n }\n return max;\n}\n","export default function min(values, valueof) {\n let min;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n }\n return min;\n}\n","export default function sum(values, valueof) {\n let sum = 0;\n if (valueof === undefined) {\n for (let value of values) {\n if (value = +value) {\n sum += value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if (value = +valueof(value, ++index, values)) {\n sum += value;\n }\n }\n }\n return sum;\n}\n","import {min} from \"d3-array\";\n\nfunction targetDepth(d) {\n return d.target.depth;\n}\n\nexport function left(node) {\n return node.depth;\n}\n\nexport function right(node, n) {\n return n - 1 - node.height;\n}\n\nexport function justify(node, n) {\n return node.sourceLinks.length ? node.depth : n - 1;\n}\n\nexport function center(node) {\n return node.targetLinks.length ? node.depth\n : node.sourceLinks.length ? min(node.sourceLinks, targetDepth) - 1\n : 0;\n}\n","export default function constant(x) {\n return function() {\n return x;\n };\n}\n","import {max, min, sum} from \"d3-array\";\nimport {justify} from \"./align.js\";\nimport constant from \"./constant.js\";\n\nfunction ascendingSourceBreadth(a, b) {\n return ascendingBreadth(a.source, b.source) || a.index - b.index;\n}\n\nfunction ascendingTargetBreadth(a, b) {\n return ascendingBreadth(a.target, b.target) || a.index - b.index;\n}\n\nfunction ascendingBreadth(a, b) {\n return a.y0 - b.y0;\n}\n\nfunction value(d) {\n return d.value;\n}\n\nfunction defaultId(d) {\n return d.index;\n}\n\nfunction defaultNodes(graph) {\n return graph.nodes;\n}\n\nfunction defaultLinks(graph) {\n return graph.links;\n}\n\nfunction find(nodeById, id) {\n const node = nodeById.get(id);\n if (!node) throw new Error(\"missing: \" + id);\n return node;\n}\n\nfunction computeLinkBreadths({nodes}) {\n for (const node of nodes) {\n let y0 = node.y0;\n let y1 = y0;\n for (const link of node.sourceLinks) {\n link.y0 = y0 + link.width / 2;\n y0 += link.width;\n }\n for (const link of node.targetLinks) {\n link.y1 = y1 + link.width / 2;\n y1 += link.width;\n }\n }\n}\n\nexport default function Sankey() {\n let x0 = 0, y0 = 0, x1 = 1, y1 = 1; // extent\n let dx = 24; // nodeWidth\n let dy = 8, py; // nodePadding\n let id = defaultId;\n let align = justify;\n let sort;\n let linkSort;\n let nodes = defaultNodes;\n let links = defaultLinks;\n let iterations = 6;\n\n function sankey() {\n const graph = {nodes: nodes.apply(null, arguments), links: links.apply(null, arguments)};\n computeNodeLinks(graph);\n computeNodeValues(graph);\n computeNodeDepths(graph);\n computeNodeHeights(graph);\n computeNodeBreadths(graph);\n computeLinkBreadths(graph);\n return graph;\n }\n\n sankey.update = function(graph) {\n computeLinkBreadths(graph);\n return graph;\n };\n\n sankey.nodeId = function(_) {\n return arguments.length ? (id = typeof _ === \"function\" ? _ : constant(_), sankey) : id;\n };\n\n sankey.nodeAlign = function(_) {\n return arguments.length ? (align = typeof _ === \"function\" ? _ : constant(_), sankey) : align;\n };\n\n sankey.nodeSort = function(_) {\n return arguments.length ? (sort = _, sankey) : sort;\n };\n\n sankey.nodeWidth = function(_) {\n return arguments.length ? (dx = +_, sankey) : dx;\n };\n\n sankey.nodePadding = function(_) {\n return arguments.length ? (dy = py = +_, sankey) : dy;\n };\n\n sankey.nodes = function(_) {\n return arguments.length ? (nodes = typeof _ === \"function\" ? _ : constant(_), sankey) : nodes;\n };\n\n sankey.links = function(_) {\n return arguments.length ? (links = typeof _ === \"function\" ? _ : constant(_), sankey) : links;\n };\n\n sankey.linkSort = function(_) {\n return arguments.length ? (linkSort = _, sankey) : linkSort;\n };\n\n sankey.size = function(_) {\n return arguments.length ? (x0 = y0 = 0, x1 = +_[0], y1 = +_[1], sankey) : [x1 - x0, y1 - y0];\n };\n\n sankey.extent = function(_) {\n return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], sankey) : [[x0, y0], [x1, y1]];\n };\n\n sankey.iterations = function(_) {\n return arguments.length ? (iterations = +_, sankey) : iterations;\n };\n\n function computeNodeLinks({nodes, links}) {\n for (const [i, node] of nodes.entries()) {\n node.index = i;\n node.sourceLinks = [];\n node.targetLinks = [];\n }\n const nodeById = new Map(nodes.map((d, i) => [id(d, i, nodes), d]));\n for (const [i, link] of links.entries()) {\n link.index = i;\n let {source, target} = link;\n if (typeof source !== \"object\") source = link.source = find(nodeById, source);\n if (typeof target !== \"object\") target = link.target = find(nodeById, target);\n source.sourceLinks.push(link);\n target.targetLinks.push(link);\n }\n if (linkSort != null) {\n for (const {sourceLinks, targetLinks} of nodes) {\n sourceLinks.sort(linkSort);\n targetLinks.sort(linkSort);\n }\n }\n }\n\n function computeNodeValues({nodes}) {\n for (const node of nodes) {\n node.value = node.fixedValue === undefined\n ? Math.max(sum(node.sourceLinks, value), sum(node.targetLinks, value))\n : node.fixedValue;\n }\n }\n\n function computeNodeDepths({nodes}) {\n const n = nodes.length;\n let current = new Set(nodes);\n let next = new Set;\n let x = 0;\n while (current.size) {\n for (const node of current) {\n node.depth = x;\n for (const {target} of node.sourceLinks) {\n next.add(target);\n }\n }\n if (++x > n) throw new Error(\"circular link\");\n current = next;\n next = new Set;\n }\n }\n\n function computeNodeHeights({nodes}) {\n const n = nodes.length;\n let current = new Set(nodes);\n let next = new Set;\n let x = 0;\n while (current.size) {\n for (const node of current) {\n node.height = x;\n for (const {source} of node.targetLinks) {\n next.add(source);\n }\n }\n if (++x > n) throw new Error(\"circular link\");\n current = next;\n next = new Set;\n }\n }\n\n function computeNodeLayers({nodes}) {\n const x = max(nodes, d => d.depth) + 1;\n const kx = (x1 - x0 - dx) / (x - 1);\n const columns = new Array(x);\n for (const node of nodes) {\n const i = Math.max(0, Math.min(x - 1, Math.floor(align.call(null, node, x))));\n node.layer = i;\n node.x0 = x0 + i * kx;\n node.x1 = node.x0 + dx;\n if (columns[i]) columns[i].push(node);\n else columns[i] = [node];\n }\n if (sort) for (const column of columns) {\n column.sort(sort);\n }\n return columns;\n }\n\n function initializeNodeBreadths(columns) {\n const ky = min(columns, c => (y1 - y0 - (c.length - 1) * py) / sum(c, value));\n for (const nodes of columns) {\n let y = y0;\n for (const node of nodes) {\n node.y0 = y;\n node.y1 = y + node.value * ky;\n y = node.y1 + py;\n for (const link of node.sourceLinks) {\n link.width = link.value * ky;\n }\n }\n y = (y1 - y + py) / (nodes.length + 1);\n for (let i = 0; i < nodes.length; ++i) {\n const node = nodes[i];\n node.y0 += y * (i + 1);\n node.y1 += y * (i + 1);\n }\n reorderLinks(nodes);\n }\n }\n\n function computeNodeBreadths(graph) {\n const columns = computeNodeLayers(graph);\n py = Math.min(dy, (y1 - y0) / (max(columns, c => c.length) - 1));\n initializeNodeBreadths(columns);\n for (let i = 0; i < iterations; ++i) {\n const alpha = Math.pow(0.99, i);\n const beta = Math.max(1 - alpha, (i + 1) / iterations);\n relaxRightToLeft(columns, alpha, beta);\n relaxLeftToRight(columns, alpha, beta);\n }\n }\n\n // Reposition each node based on its incoming (target) links.\n function relaxLeftToRight(columns, alpha, beta) {\n for (let i = 1, n = columns.length; i < n; ++i) {\n const column = columns[i];\n for (const target of column) {\n let y = 0;\n let w = 0;\n for (const {source, value} of target.targetLinks) {\n let v = value * (target.layer - source.layer);\n y += targetTop(source, target) * v;\n w += v;\n }\n if (!(w > 0)) continue;\n let dy = (y / w - target.y0) * alpha;\n target.y0 += dy;\n target.y1 += dy;\n reorderNodeLinks(target);\n }\n if (sort === undefined) column.sort(ascendingBreadth);\n resolveCollisions(column, beta);\n }\n }\n\n // Reposition each node based on its outgoing (source) links.\n function relaxRightToLeft(columns, alpha, beta) {\n for (let n = columns.length, i = n - 2; i >= 0; --i) {\n const column = columns[i];\n for (const source of column) {\n let y = 0;\n let w = 0;\n for (const {target, value} of source.sourceLinks) {\n let v = value * (target.layer - source.layer);\n y += sourceTop(source, target) * v;\n w += v;\n }\n if (!(w > 0)) continue;\n let dy = (y / w - source.y0) * alpha;\n source.y0 += dy;\n source.y1 += dy;\n reorderNodeLinks(source);\n }\n if (sort === undefined) column.sort(ascendingBreadth);\n resolveCollisions(column, beta);\n }\n }\n\n function resolveCollisions(nodes, alpha) {\n const i = nodes.length >> 1;\n const subject = nodes[i];\n resolveCollisionsBottomToTop(nodes, subject.y0 - py, i - 1, alpha);\n resolveCollisionsTopToBottom(nodes, subject.y1 + py, i + 1, alpha);\n resolveCollisionsBottomToTop(nodes, y1, nodes.length - 1, alpha);\n resolveCollisionsTopToBottom(nodes, y0, 0, alpha);\n }\n\n // Push any overlapping nodes down.\n function resolveCollisionsTopToBottom(nodes, y, i, alpha) {\n for (; i < nodes.length; ++i) {\n const node = nodes[i];\n const dy = (y - node.y0) * alpha;\n if (dy > 1e-6) node.y0 += dy, node.y1 += dy;\n y = node.y1 + py;\n }\n }\n\n // Push any overlapping nodes up.\n function resolveCollisionsBottomToTop(nodes, y, i, alpha) {\n for (; i >= 0; --i) {\n const node = nodes[i];\n const dy = (node.y1 - y) * alpha;\n if (dy > 1e-6) node.y0 -= dy, node.y1 -= dy;\n y = node.y0 - py;\n }\n }\n\n function reorderNodeLinks({sourceLinks, targetLinks}) {\n if (linkSort === undefined) {\n for (const {source: {sourceLinks}} of targetLinks) {\n sourceLinks.sort(ascendingTargetBreadth);\n }\n for (const {target: {targetLinks}} of sourceLinks) {\n targetLinks.sort(ascendingSourceBreadth);\n }\n }\n }\n\n function reorderLinks(nodes) {\n if (linkSort === undefined) {\n for (const {sourceLinks, targetLinks} of nodes) {\n sourceLinks.sort(ascendingTargetBreadth);\n targetLinks.sort(ascendingSourceBreadth);\n }\n }\n }\n\n // Returns the target.y0 that would produce an ideal link from source to target.\n function targetTop(source, target) {\n let y = source.y0 - (source.sourceLinks.length - 1) * py / 2;\n for (const {target: node, width} of source.sourceLinks) {\n if (node === target) break;\n y += width + py;\n }\n for (const {source: node, width} of target.targetLinks) {\n if (node === source) break;\n y -= width;\n }\n return y;\n }\n\n // Returns the source.y0 that would produce an ideal link from source to target.\n function sourceTop(source, target) {\n let y = target.y0 - (target.targetLinks.length - 1) * py / 2;\n for (const {source: node, width} of target.targetLinks) {\n if (node === source) break;\n y += width + py;\n }\n for (const {target: node, width} of source.sourceLinks) {\n if (node === target) break;\n y -= width;\n }\n return y;\n }\n\n return sankey;\n}\n","/**\n * d3-sankey layout wrapper.\n *\n * Extracts unique nodes from tabular data rows, configures the d3-sankey\n * generator, and returns computed node/link positions. Clones input data\n * before passing to d3-sankey since it mutates objects in place.\n */\n\nimport type { Rect, SankeyNodeAlign } from '@opendata-ai/openchart-core';\nimport type { SankeyExtraProperties, SankeyGraph, SankeyLink, SankeyNode } from 'd3-sankey';\nimport { sankey, sankeyCenter, sankeyJustify, sankeyLeft, sankeyRight } from 'd3-sankey';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Extra properties carried on our sankey nodes. */\ninterface NodeExtra extends SankeyExtraProperties {\n id: string;\n label: string;\n}\n\n/** Extra properties carried on our sankey links. */\ninterface LinkExtra extends SankeyExtraProperties {\n /** Original data row for this link. */\n data: Record<string, unknown>;\n}\n\nexport type ComputedNode = SankeyNode<NodeExtra, LinkExtra>;\nexport type ComputedLink = SankeyLink<NodeExtra, LinkExtra>;\n\nexport interface SankeyLayoutResult {\n nodes: ComputedNode[];\n links: ComputedLink[];\n}\n\n// ---------------------------------------------------------------------------\n// Alignment resolver\n// ---------------------------------------------------------------------------\n\nconst ALIGN_MAP: Record<SankeyNodeAlign, typeof sankeyJustify> = {\n justify: sankeyJustify,\n left: sankeyLeft,\n right: sankeyRight,\n center: sankeyCenter,\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Run the d3-sankey layout algorithm on tabular flow data.\n *\n * @param data - Array of data rows (each row is a source-target-value flow).\n * @param sourceField - Field name for the source node.\n * @param targetField - Field name for the target node.\n * @param valueField - Field name for the flow value.\n * @param area - Drawing area rect (after chrome subtracted).\n * @param nodeWidth - Width of node rectangles in px.\n * @param nodePadding - Vertical padding between nodes in px.\n * @param nodeAlign - Node alignment strategy.\n * @param iterations - Number of layout relaxation iterations.\n * @returns Computed node and link positions.\n */\nexport function computeSankeyLayout(\n data: Record<string, unknown>[],\n sourceField: string,\n targetField: string,\n valueField: string,\n area: Rect,\n nodeWidth: number,\n nodePadding: number,\n nodeAlign: SankeyNodeAlign,\n iterations: number,\n nodeSort?: string[],\n): SankeyLayoutResult {\n // Extract unique node IDs from source and target columns\n const nodeSet = new Set<string>();\n for (const row of data) {\n nodeSet.add(String(row[sourceField]));\n nodeSet.add(String(row[targetField]));\n }\n\n // Build node and link arrays (cloned so d3-sankey mutations don't affect input)\n const nodes: Array<{ id: string; label: string }> = [...nodeSet].map((id) => ({\n id,\n label: id,\n }));\n\n const links: Array<{\n source: string;\n target: string;\n value: number;\n data: Record<string, unknown>;\n }> = data.map((row) => ({\n source: String(row[sourceField]),\n target: String(row[targetField]),\n value: Number(row[valueField]) || 0,\n data: { ...row },\n }));\n\n // Configure and run d3-sankey\n const alignFn = ALIGN_MAP[nodeAlign] ?? sankeyJustify;\n\n const generator = sankey<SankeyGraph<NodeExtra, LinkExtra>, NodeExtra, LinkExtra>()\n .nodeId((d) => d.id)\n .nodeAlign(alignFn as unknown as (node: SankeyNode<NodeExtra, LinkExtra>, n: number) => number)\n .nodeWidth(nodeWidth)\n .nodePadding(nodePadding)\n .extent([\n [area.x, area.y],\n [area.x + area.width, area.y + area.height],\n ])\n .iterations(iterations);\n\n // Apply explicit node ordering when provided.\n // Builds a comparator from the ordered ID array so d3-sankey places nodes\n // top-to-bottom within each column according to the spec's nodeSort.\n if (nodeSort && nodeSort.length > 0) {\n const orderMap = new Map(nodeSort.map((id, i) => [id, i]));\n const fallback = nodeSort.length;\n generator.nodeSort(\n (a: SankeyNode<NodeExtra, LinkExtra>, b: SankeyNode<NodeExtra, LinkExtra>) =>\n (orderMap.get((a as unknown as NodeExtra).id) ?? fallback) -\n (orderMap.get((b as unknown as NodeExtra).id) ?? fallback),\n );\n }\n\n const graph = generator({\n nodes: nodes as unknown as Array<SankeyNode<NodeExtra, LinkExtra>>,\n links: links as unknown as Array<SankeyLink<NodeExtra, LinkExtra>>,\n });\n\n return {\n nodes: graph.nodes,\n links: graph.links,\n };\n}\n\n/**\n * Generate a filled ribbon SVG path for a sankey link.\n *\n * d3-sankey's sankeyLinkHorizontal() only produces a stroke centerline.\n * This generates a closed area path with two cubic bezier edges (top and\n * bottom) forming a ribbon whose width is proportional to flow value.\n *\n * The link object from d3-sankey provides:\n * - y0: center y at source side\n * - y1: center y at target side\n * - width: thickness of the ribbon\n * - source.x1: right edge of source node\n * - target.x0: left edge of target node\n */\nexport function generateLinkPath(link: ComputedLink): string {\n const source = link.source as ComputedNode;\n const target = link.target as ComputedNode;\n\n const x0 = source.x1 ?? 0;\n const x1 = target.x0 ?? 0;\n const y0 = link.y0 ?? 0;\n const y1 = link.y1 ?? 0;\n const halfWidth0 = (link.width ?? 0) / 2;\n const halfWidth1 = halfWidth0;\n\n // Control point x at the horizontal midpoint for smooth S-curves\n const mx = (x0 + x1) / 2;\n\n // Top edge: left-to-right\n const topY0 = y0 - halfWidth0;\n const topY1 = y1 - halfWidth1;\n\n // Bottom edge: right-to-left\n const botY0 = y0 + halfWidth0;\n const botY1 = y1 + halfWidth1;\n\n return [\n `M${x0},${topY0}`,\n `C${mx},${topY0} ${mx},${topY1} ${x1},${topY1}`,\n `L${x1},${botY1}`,\n `C${mx},${botY1} ${mx},${botY0} ${x0},${botY0}`,\n 'Z',\n ].join(' ');\n}\n","/**\n * Table compilation pipeline.\n *\n * Takes a NormalizedTableSpec and produces a fully resolved TableLayout:\n * resolve columns -> build search index -> sort data -> filter by search ->\n * paginate -> format visible cells -> apply visual enhancements -> return\n */\n\nimport type {\n CellStyle,\n ColumnConfig,\n CompileTableOptions,\n PaginationState,\n ResolvedColumn,\n ResolvedTheme,\n TableCell,\n TableLayout,\n TableRow,\n} from '@opendata-ai/openchart-core';\nimport { computeChrome, estimateTextWidth } from '@opendata-ai/openchart-core';\n\nimport { resolveAnimation } from '../compiler/animation';\nimport type { NormalizedTableSpec } from '../compiler/types';\nimport { computeBarCell, computeColumnMax, computeColumnMin } from './bar-column';\nimport { computeCategoryColors } from './category-colors';\nimport { formatCell } from './format-cells';\nimport { computeHeatmapColors } from './heatmap';\nimport { paginateData } from './pagination';\nimport { buildSearchIndex, filterBySearch } from './search';\nimport { sortData } from './sort';\nimport { computeSparklineForRow, type SparklineData } from './sparkline';\n\n// ---------------------------------------------------------------------------\n// Column resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Determine the cell type for a column based on its config.\n * Precedence: sparkline > bar > heatmap > image > flag > categoryColors > text\n */\nfunction determineCellType(col: ColumnConfig): ResolvedColumn['cellType'] {\n if (col.sparkline) return 'sparkline';\n if (col.bar) return 'bar';\n if (col.heatmap) return 'heatmap';\n if (col.image) return 'image';\n if (col.flag) return 'flag';\n if (col.categoryColors) return 'category';\n return 'text';\n}\n\n/**\n * Infer alignment for a column.\n * Explicit align wins. Otherwise: right for numeric data, left for everything else.\n */\nfunction inferAlignment(\n col: ColumnConfig,\n data: Record<string, unknown>[],\n): 'left' | 'center' | 'right' {\n if (col.align) return col.align;\n\n // Check first non-null value in the data\n for (const row of data) {\n const val = row[col.key];\n if (val != null) {\n return typeof val === 'number' ? 'right' : 'left';\n }\n }\n return 'left';\n}\n\n/**\n * Estimate the needed width for a column by measuring header and data values.\n * Samples up to 100 rows for estimation.\n */\nfunction estimateColumnWidth(\n col: ColumnConfig,\n data: Record<string, unknown>[],\n fontSize: number,\n): number {\n const MIN_WIDTH = 60;\n const PADDING = 24; // cell padding\n\n // Visual columns get fixed widths (they render graphics, not text)\n if (col.sparkline) return 140;\n if (col.image) return (col.image.width ?? 24) + PADDING;\n if (col.flag) return 60;\n\n // Header width\n const label = col.label ?? col.key;\n const headerWidth = estimateTextWidth(label, fontSize, 600) + PADDING;\n\n // Sample data values\n const sampleSize = Math.min(100, data.length);\n let maxDataWidth = 0;\n\n for (let i = 0; i < sampleSize; i++) {\n const val = data[i][col.key];\n const text = val == null ? '' : String(val);\n const width = estimateTextWidth(text, fontSize, 400) + PADDING;\n if (width > maxDataWidth) maxDataWidth = width;\n }\n\n return Math.max(MIN_WIDTH, headerWidth, maxDataWidth);\n}\n\n/**\n * Resolve all columns: compute widths, types, alignment.\n */\nfunction resolveColumns(\n columns: ColumnConfig[],\n data: Record<string, unknown>[],\n totalWidth: number,\n theme: ResolvedTheme,\n): ResolvedColumn[] {\n const fontSize = theme.fonts.sizes.body;\n\n // Compute natural widths and identify fixed-width visual columns.\n // Visual columns (sparkline, image, flag) get fixed sizes; only text\n // columns participate in proportional scaling to fill the container.\n const isFixed = columns.map((col) => !!(col.sparkline || col.image || col.flag));\n\n const naturalWidths = columns.map((col) => {\n if (col.width) {\n // Parse explicit width\n if (col.width.endsWith('px')) {\n return parseInt(col.width, 10) || 100;\n }\n if (col.width.endsWith('%')) {\n return (parseFloat(col.width) / 100) * totalWidth || 100;\n }\n return parseInt(col.width, 10) || 100;\n }\n return estimateColumnWidth(col, data, fontSize);\n });\n\n // Fixed columns keep their natural width; remaining space goes to text columns\n const fixedTotal = naturalWidths.reduce((sum, w, i) => sum + (isFixed[i] ? w : 0), 0);\n const flexTotal = naturalWidths.reduce((sum, w, i) => sum + (isFixed[i] ? 0 : w), 0);\n const remainingWidth = totalWidth - fixedTotal;\n const flexScale = flexTotal > 0 && remainingWidth > 0 ? remainingWidth / flexTotal : 1;\n\n return columns.map((col, i) => ({\n key: col.key,\n label: col.label ?? col.key,\n width: Math.max(60, isFixed[i] ? naturalWidths[i] : Math.round(naturalWidths[i] * flexScale)),\n sortable: col.sortable ?? true,\n align: inferAlignment(col, data),\n cellType: determineCellType(col),\n }));\n}\n\n// ---------------------------------------------------------------------------\n// Cell building\n// ---------------------------------------------------------------------------\n\n/**\n * Build a fully resolved TableCell from a data value and column config.\n */\nfunction buildCell(\n value: unknown,\n column: ColumnConfig,\n resolvedColumn: ResolvedColumn,\n heatmapStyle: CellStyle | undefined,\n categoryStyle: CellStyle | undefined,\n barData:\n | { barPercent: number; barOffset: number; barColor: string; isNegative: boolean }\n | undefined,\n sparklineData: SparklineData | null,\n): TableCell {\n const base = formatCell(value, column);\n\n // Apply font variant for number columns\n if (typeof value === 'number') {\n base.style = { ...base.style, fontVariant: 'tabular-nums' };\n }\n\n const cellType = resolvedColumn.cellType;\n\n switch (cellType) {\n case 'heatmap': {\n const merged = heatmapStyle ? { ...base.style, ...heatmapStyle } : base.style;\n return {\n ...base,\n cellType: 'heatmap',\n style: merged,\n };\n }\n case 'category': {\n const merged = categoryStyle ? { ...base.style, ...categoryStyle } : base.style;\n return {\n ...base,\n cellType: 'category',\n style: merged,\n };\n }\n case 'bar': {\n return {\n ...base,\n cellType: 'bar',\n barWidth: barData?.barPercent ?? 0,\n barOffset: barData?.barOffset ?? 0,\n barColor: barData?.barColor ?? '#ccc',\n isNegative: barData?.isNegative ?? false,\n };\n }\n case 'sparkline': {\n return {\n ...base,\n cellType: 'sparkline',\n sparklineData,\n };\n }\n case 'image': {\n const src = typeof value === 'string' ? value : '';\n const imgConfig = column.image ?? {};\n return {\n ...base,\n cellType: 'image',\n src,\n imageWidth: imgConfig.width ?? 24,\n imageHeight: imgConfig.height ?? 24,\n rounded: imgConfig.rounded ?? false,\n };\n }\n case 'flag': {\n const code = typeof value === 'string' ? value : '';\n return {\n ...base,\n cellType: 'flag',\n countryCode: code,\n };\n }\n default: {\n return {\n ...base,\n cellType: 'text',\n };\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main pipeline\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a normalized table spec into a TableLayout.\n *\n * Pipeline:\n * 1. Resolve columns (widths, types, alignment)\n * 2. Build search index\n * 3. Sort data\n * 4. Filter by search\n * 5. Paginate\n * 6. Format visible cells and apply visual enhancements\n * 7. Return TableLayout\n */\nexport function compileTableLayout(\n spec: NormalizedTableSpec,\n options: CompileTableOptions,\n theme: ResolvedTheme,\n): TableLayout {\n const data = spec.data;\n const darkMode = theme.isDark;\n\n // 1. Resolve columns\n const resolvedColumns = resolveColumns(spec.columns, data, options.width, theme);\n\n // 2. Build search index (over full dataset, using original indices)\n const searchIndex = spec.search\n ? buildSearchIndex(data, spec.columns)\n : new Map<number, string>();\n\n // 3. Track original indices through the pipeline\n let currentData = data;\n let originalIndices = data.map((_, i) => i);\n\n // 4. Sort\n if (options.sort) {\n const sorted = sortData(currentData, options.sort);\n // Map sorted originalIndices back through our current index mapping\n originalIndices = sorted.originalIndices.map((i) => originalIndices[i]);\n currentData = sorted.data;\n }\n\n // 5. Filter by search\n if (spec.search && options.search) {\n const filtered = filterBySearch(currentData, options.search, searchIndex, originalIndices);\n currentData = filtered.data;\n originalIndices = filtered.indices;\n }\n\n const totalFiltered = currentData.length;\n\n // 6. Paginate\n let pageSize = 0;\n let currentPage = 0;\n let paginationState: PaginationState | undefined;\n\n if (spec.pagination) {\n pageSize =\n options.pageSize ?? (typeof spec.pagination === 'object' ? spec.pagination.pageSize : 25);\n currentPage = options.page ?? 0;\n const paginated = paginateData(currentData, currentPage, pageSize);\n\n // Slice indices too\n const start = paginated.page * pageSize;\n const end = start + paginated.rows.length;\n const pageIndices = originalIndices.slice(start, end);\n\n currentData = paginated.rows;\n originalIndices = pageIndices;\n\n paginationState = {\n page: paginated.page,\n pageSize,\n totalRows: paginated.totalRows,\n totalPages: paginated.totalPages,\n };\n }\n\n // 7. Pre-compute visual enhancements for visible data columns\n // We need heatmap/category colors computed over the FULL dataset, then\n // applied only to visible rows.\n const heatmapMaps = new Map<string, Map<number, CellStyle>>();\n const categoryMaps = new Map<string, Map<number, CellStyle>>();\n const barMaxes = new Map<string, number>();\n const barMins = new Map<string, number>();\n\n for (let c = 0; c < spec.columns.length; c++) {\n const col = spec.columns[c];\n const resolved = resolvedColumns[c];\n\n if (resolved.cellType === 'heatmap' && col.heatmap) {\n heatmapMaps.set(col.key, computeHeatmapColors(data, col, theme, darkMode));\n }\n if (resolved.cellType === 'category' && col.categoryColors) {\n categoryMaps.set(col.key, computeCategoryColors(data, col, theme, darkMode));\n }\n if (resolved.cellType === 'bar' && col.bar) {\n barMaxes.set(col.key, computeColumnMax(data, col.key));\n barMins.set(col.key, computeColumnMin(data, col.key));\n }\n }\n\n // 8. Build rows from visible data\n const rows: TableRow[] = currentData.map((row, i) => {\n const origIdx = originalIndices[i];\n const rowId = spec.rowKey ? String(row[spec.rowKey] ?? origIdx) : String(origIdx);\n\n const cells: TableCell[] = spec.columns.map((col, c) => {\n const resolved = resolvedColumns[c];\n const value = row[col.key];\n\n // Lookup visual enhancement data\n const heatmapStyle = heatmapMaps.get(col.key)?.get(origIdx);\n const categoryStyle = categoryMaps.get(col.key)?.get(origIdx);\n\n let barData:\n | { barPercent: number; barOffset: number; barColor: string; isNegative: boolean }\n | undefined;\n if (resolved.cellType === 'bar' && col.bar && typeof value === 'number') {\n barData = computeBarCell(\n value,\n col.bar,\n barMaxes.get(col.key) ?? 0,\n barMins.get(col.key) ?? 0,\n theme,\n darkMode,\n );\n }\n\n let sparklineData: SparklineData | null = null;\n if (resolved.cellType === 'sparkline' && col.sparkline) {\n sparklineData = computeSparklineForRow(row, col.key, col.sparkline, theme, darkMode);\n }\n\n return buildCell(value, col, resolved, heatmapStyle, categoryStyle, barData, sparklineData);\n });\n\n return { id: rowId, cells, data: row };\n });\n\n // 9. Compute chrome\n const watermark = spec.watermark;\n const chrome = computeChrome(\n {\n title: spec.chrome.title,\n subtitle: spec.chrome.subtitle,\n source: spec.chrome.source,\n byline: spec.chrome.byline,\n footer: spec.chrome.footer,\n },\n theme,\n options.width,\n options.measureText,\n 'full',\n undefined,\n watermark,\n );\n\n // 10. Build a11y\n const titleText = spec.chrome.title?.text ?? '';\n const caption = titleText ? `Table: ${titleText}` : `Data table with ${data.length} rows`;\n\n return {\n chrome,\n columns: resolvedColumns,\n rows,\n sort: options.sort,\n pagination: paginationState,\n search: {\n enabled: spec.search,\n placeholder: 'Search...',\n query: options.search ?? '',\n },\n stickyFirstColumn: spec.stickyFirstColumn,\n compact: spec.compact,\n a11y: {\n caption,\n summary: `${resolvedColumns.length} columns, ${totalFiltered} rows`,\n },\n theme,\n animation: resolveAnimation(spec.animation),\n watermark,\n };\n}\n","/**\n * Bar column computation for inline bar visualization in table cells.\n *\n * Computes bar width as a proportion of the max value.\n * Supports negative values with bidirectional bars.\n */\n\nimport type { BarColumnConfig, ResolvedTheme } from '@opendata-ai/openchart-core';\n\nconst NEGATIVE_BAR_COLOR = '#c44e52';\n\n/**\n * Compute the bar percentage, offset, and color for a single cell value.\n *\n * barPercent is 0-1. barOffset is 0-1 (left edge position).\n * When the column has negative values, bars extend bidirectionally from a zero line.\n */\nexport function computeBarCell(\n value: number,\n config: BarColumnConfig,\n columnMax: number,\n columnMin: number,\n theme: ResolvedTheme,\n _darkMode: boolean,\n): { barPercent: number; barOffset: number; barColor: string; isNegative: boolean } {\n const barColor = config.color ?? theme.colors.categorical[0];\n const hasNegatives = columnMin < 0;\n\n if (!Number.isFinite(value)) {\n return { barPercent: 0, barOffset: 0, barColor, isNegative: false };\n }\n\n if (!hasNegatives) {\n // Positive-only column: simple left-to-right bars\n const maxValue = config.maxValue ?? columnMax;\n if (maxValue <= 0) {\n return { barPercent: 0, barOffset: 0, barColor, isNegative: false };\n }\n const barPercent = Math.max(0, Math.min(1, value / maxValue));\n return { barPercent, barOffset: 0, barColor, isNegative: false };\n }\n\n // Bidirectional: zero line position proportional to data range\n const maxPos = config.maxValue ?? columnMax;\n const absMin = Math.abs(columnMin);\n const totalRange = maxPos + absMin;\n if (totalRange === 0) {\n return { barPercent: 0, barOffset: 0, barColor, isNegative: false };\n }\n\n const zeroPos = absMin / totalRange;\n\n if (value >= 0) {\n const barPercent = value / totalRange;\n return { barPercent, barOffset: zeroPos, barColor, isNegative: false };\n }\n\n // Negative value: red bar extending left from zero\n const barPercent = Math.abs(value) / totalRange;\n return {\n barPercent,\n barOffset: zeroPos - barPercent,\n barColor: config.color ?? NEGATIVE_BAR_COLOR,\n isNegative: true,\n };\n}\n\n/**\n * Compute the column max and min from data for bar scaling.\n */\nexport function computeColumnMax(data: Record<string, unknown>[], key: string): number {\n let max = 0;\n for (const row of data) {\n const val = row[key];\n if (typeof val === 'number' && Number.isFinite(val) && val > max) {\n max = val;\n }\n }\n return max;\n}\n\n/**\n * Compute the column minimum from data (for negative bar support).\n */\nexport function computeColumnMin(data: Record<string, unknown>[], key: string): number {\n let min = 0;\n for (const row of data) {\n const val = row[key];\n if (typeof val === 'number' && Number.isFinite(val) && val < min) {\n min = val;\n }\n }\n return min;\n}\n","/**\n * Category color assignment for table columns.\n *\n * Maps categorical values to colors using explicit mappings or\n * theme categorical palette, with AA-contrast text colors.\n */\n\nimport type { CellStyle, ColumnConfig, ResolvedTheme } from '@opendata-ai/openchart-core';\nimport { adaptColorForDarkMode } from '@opendata-ai/openchart-core';\nimport { accessibleTextColor } from './utils';\n\n/**\n * Compute category-colored cell styles for a column.\n *\n * Uses column.categoryColors for explicit value-to-color mappings.\n * Unmapped values get colors from the theme's categorical palette.\n *\n * Returns a Map keyed by original data index with background and text colors.\n */\nexport function computeCategoryColors(\n data: Record<string, unknown>[],\n column: ColumnConfig,\n theme: ResolvedTheme,\n darkMode: boolean,\n): Map<number, CellStyle> {\n const result = new Map<number, CellStyle>();\n const explicitMap = column.categoryColors;\n if (!explicitMap) return result;\n\n const categoricalPalette = theme.colors.categorical;\n let nextPaletteIndex = 0;\n const autoAssigned = new Map<string, string>();\n const lightBg = '#ffffff';\n const darkBg = theme.colors.background;\n\n for (let i = 0; i < data.length; i++) {\n const raw = data[i][column.key];\n if (raw == null) continue;\n\n const key = String(raw);\n let bg: string;\n let isExplicit = false;\n\n if (explicitMap[key] != null) {\n if (explicitMap[key] === 'transparent' || explicitMap[key] === 'none') {\n // Skip transparent/none — let the cell inherit default table styling\n continue;\n }\n bg = explicitMap[key];\n isExplicit = true;\n } else if (column.autoAssign) {\n // Auto-assign from palette only when explicitly opted in\n if (autoAssigned.has(key)) {\n bg = autoAssigned.get(key)!;\n } else {\n bg = categoricalPalette[nextPaletteIndex % categoricalPalette.length];\n nextPaletteIndex++;\n autoAssigned.set(key, bg);\n }\n } else {\n // Default: skip unmapped values (no color assigned)\n continue;\n }\n\n // Dark mode adaptation (skip for explicit user-provided colors)\n if (darkMode && !isExplicit) {\n bg = adaptColorForDarkMode(bg, lightBg, darkBg);\n }\n\n const textColor = accessibleTextColor(bg);\n result.set(i, {\n backgroundColor: bg,\n color: textColor,\n });\n }\n\n return result;\n}\n","/**\n * Shared utilities for table column computations.\n */\n\nimport { contrastRatio } from '@opendata-ai/openchart-core';\n\n/**\n * Pick a text color (black or white) that meets better contrast against the background.\n */\nexport function accessibleTextColor(bg: string): string {\n const white = '#ffffff';\n const black = '#000000';\n const whiteRatio = contrastRatio(white, bg);\n const blackRatio = contrastRatio(black, bg);\n return whiteRatio >= blackRatio ? white : black;\n}\n","/**\n * Cell value formatting for table columns.\n *\n * Handles number formatting (d3-format), date formatting, and\n * null/undefined values. Produces the formattedValue string and\n * base style for each cell.\n */\n\nimport type { CellStyle, ColumnConfig, TableCellBase } from '@opendata-ai/openchart-core';\nimport { buildD3Formatter, formatDate, formatNumber } from '@opendata-ai/openchart-core';\n\n/**\n * Check if a value is numeric (finite number or parseable numeric string).\n */\nfunction isNumericValue(value: unknown): value is number {\n if (typeof value === 'number') return Number.isFinite(value);\n return false;\n}\n\n/**\n * Check if a value is a date.\n */\nfunction isDateValue(value: unknown): boolean {\n if (value instanceof Date) return !Number.isNaN(value.getTime());\n return false;\n}\n\n/**\n * Format a raw cell value into a display string with styling.\n *\n * Formatting precedence:\n * 1. null/undefined -> \"\"\n * 2. column.format (d3-format string) for numbers\n * 3. Auto-format: numbers via formatNumber, dates via formatDate\n * 4. Fallback: String(value)\n */\nexport function formatCell(value: unknown, column: ColumnConfig): TableCellBase {\n const style: CellStyle = {};\n\n // Null/undefined -> empty\n if (value == null) {\n return {\n value,\n formattedValue: '',\n style,\n };\n }\n\n // If column has a d3-format string and value is numeric\n if (column.format && isNumericValue(value)) {\n const formatter = buildD3Formatter(column.format);\n if (formatter) {\n return {\n value,\n formattedValue: formatter(value),\n style,\n };\n }\n }\n\n // Auto-format numbers\n if (isNumericValue(value)) {\n return {\n value,\n formattedValue: formatNumber(value),\n style,\n };\n }\n\n // Auto-format dates\n if (isDateValue(value)) {\n return {\n value,\n formattedValue: formatDate(value as Date),\n style,\n };\n }\n\n // String and everything else\n return {\n value,\n formattedValue: String(value),\n style,\n };\n}\n\n/**\n * Format a value into a string for search indexing.\n * Uses d3-format for numeric columns, otherwise String().\n */\nexport function formatValueForSearch(value: unknown, column: ColumnConfig): string {\n if (value == null) return '';\n\n if (column.format && isNumericValue(value)) {\n const formatter = buildD3Formatter(column.format);\n if (formatter) {\n return formatter(value);\n }\n }\n\n if (isNumericValue(value)) {\n return formatNumber(value);\n }\n\n return String(value);\n}\n","/**\n * Heatmap coloring for table columns.\n *\n * Colors cell backgrounds using sequential or diverging color scales,\n * then picks an accessible text color for each background.\n */\n\nimport type { CellStyle, ColumnConfig, ResolvedTheme } from '@opendata-ai/openchart-core';\nimport { adaptColorForDarkMode } from '@opendata-ai/openchart-core';\nimport { interpolateRgb } from 'd3-interpolate';\nimport { scaleSequential } from 'd3-scale';\nimport { accessibleTextColor } from './utils';\n\n/**\n * Build an interpolator from an array of color stops.\n * Uses d3-interpolate for smooth color transitions.\n */\nfunction interpolatorFromStops(stops: string[]): (t: number) => string {\n if (stops.length === 0) return () => '#ffffff';\n if (stops.length === 1) return () => stops[0];\n\n return (t: number) => {\n const clamped = Math.max(0, Math.min(1, t));\n const segment = clamped * (stops.length - 1);\n const lo = Math.floor(segment);\n const hi = Math.min(lo + 1, stops.length - 1);\n const frac = segment - lo;\n return interpolateRgb(stops[lo], stops[hi])(frac);\n };\n}\n\n/**\n * Resolve palette from column config or theme.\n *\n * - If palette is an array of color stops, use directly\n * - If palette is a string name, look it up in theme sequential then diverging\n * - If no palette specified, use the first sequential palette from the theme\n */\nfunction resolvePalette(palette: string | string[] | undefined, theme: ResolvedTheme): string[] {\n if (Array.isArray(palette)) return palette;\n\n const seqPalettes = theme.colors.sequential;\n const divPalettes = theme.colors.diverging;\n\n if (typeof palette === 'string') {\n if (seqPalettes[palette]) return seqPalettes[palette];\n if (divPalettes[palette]) return divPalettes[palette];\n }\n\n // Default: first sequential palette\n const firstSeqKey = Object.keys(seqPalettes)[0];\n return firstSeqKey ? seqPalettes[firstSeqKey] : ['#deebf7', '#08519c'];\n}\n\n/**\n * Compute heatmap cell styles for a column.\n *\n * Returns a Map keyed by original data index with background and text colors.\n */\nexport function computeHeatmapColors(\n data: Record<string, unknown>[],\n column: ColumnConfig,\n theme: ResolvedTheme,\n darkMode: boolean,\n): Map<number, CellStyle> {\n const result = new Map<number, CellStyle>();\n const config = column.heatmap;\n if (!config) return result;\n\n // Determine which field provides the color values\n const colorField = config.colorByField ?? column.key;\n\n // Extract numeric values and compute domain\n const numericValues: { index: number; value: number }[] = [];\n for (let i = 0; i < data.length; i++) {\n const raw = data[i][colorField];\n if (typeof raw === 'number' && Number.isFinite(raw)) {\n numericValues.push({ index: i, value: raw });\n }\n }\n\n if (numericValues.length === 0) return result;\n\n // Domain: from config or data min/max\n let domain: [number, number];\n if (config.domain) {\n domain = config.domain;\n } else {\n let min = Infinity;\n let max = -Infinity;\n for (const { value } of numericValues) {\n if (value < min) min = value;\n if (value > max) max = value;\n }\n domain = [min, max];\n }\n\n // Resolve palette and build scale\n let stops = resolvePalette(config.palette, theme);\n if (darkMode) {\n const lightBg = '#ffffff';\n const darkBg = theme.colors.background;\n stops = stops.map((c) => adaptColorForDarkMode(c, lightBg, darkBg));\n }\n\n const interpolator = interpolatorFromStops(stops);\n const scale = scaleSequential(interpolator).domain(domain).clamp(true);\n\n // Apply to each row\n for (const { index, value } of numericValues) {\n const bg = scale(value);\n const textColor = accessibleTextColor(bg);\n\n result.set(index, {\n backgroundColor: bg,\n color: textColor,\n });\n }\n\n return result;\n}\n","/**\n * Table pagination: slice data into pages.\n */\n\n/**\n * Paginate data rows.\n *\n * Returns the current page's rows along with pagination metadata.\n * Page is 0-indexed and clamped to valid range.\n * If pageSize is 0 or negative, pagination is disabled (returns all rows).\n */\nexport function paginateData(\n data: Record<string, unknown>[],\n page: number,\n pageSize: number,\n): {\n rows: Record<string, unknown>[];\n totalRows: number;\n totalPages: number;\n page: number;\n} {\n const totalRows = data.length;\n\n // Disabled pagination\n if (pageSize <= 0) {\n return {\n rows: data,\n totalRows,\n totalPages: 1,\n page: 0,\n };\n }\n\n const totalPages = Math.max(1, Math.ceil(totalRows / pageSize));\n // Clamp page to valid range\n const clampedPage = Math.max(0, Math.min(page, totalPages - 1));\n const start = clampedPage * pageSize;\n const end = Math.min(start + pageSize, totalRows);\n\n return {\n rows: data.slice(start, end),\n totalRows,\n totalPages,\n page: clampedPage,\n };\n}\n","/**\n * Table search: build a search index and filter rows by query.\n *\n * The search index concatenates formatted cell values per row so\n * substring matching works across all columns.\n */\n\nimport type { ColumnConfig } from '@opendata-ai/openchart-core';\nimport { formatValueForSearch } from './format-cells';\n\n/**\n * Build a search index mapping original data indices to searchable strings.\n * Each row's searchable string is the concatenation of all column values,\n * separated by spaces, lowercased.\n */\nexport function buildSearchIndex(\n data: Record<string, unknown>[],\n columns: ColumnConfig[],\n): Map<number, string> {\n const index = new Map<number, string>();\n\n for (let i = 0; i < data.length; i++) {\n const row = data[i];\n const parts: string[] = [];\n\n for (const col of columns) {\n parts.push(formatValueForSearch(row[col.key], col));\n }\n\n index.set(i, parts.join(' ').toLowerCase());\n }\n\n return index;\n}\n\n/**\n * Filter data by a search query using the pre-built search index.\n *\n * Returns the filtered data and the original indices of matching rows.\n * Empty query returns all data.\n */\nexport function filterBySearch(\n data: Record<string, unknown>[],\n query: string,\n searchIndex: Map<number, string>,\n originalIndices: number[],\n): { data: Record<string, unknown>[]; indices: number[] } {\n if (!query || query.trim() === '') {\n return { data, indices: originalIndices };\n }\n\n const lowerQuery = query.toLowerCase();\n const filteredData: Record<string, unknown>[] = [];\n const filteredIndices: number[] = [];\n\n for (let i = 0; i < data.length; i++) {\n const originalIdx = originalIndices[i];\n const searchText = searchIndex.get(originalIdx);\n if (searchText?.includes(lowerQuery)) {\n filteredData.push(data[i]);\n filteredIndices.push(originalIdx);\n }\n }\n\n return { data: filteredData, indices: filteredIndices };\n}\n","/**\n * Stable sort for table data.\n *\n * Sorts data by a column key with type-aware comparison:\n * - Numbers: numeric comparison\n * - Strings: localeCompare\n * - Dates: timestamp comparison\n * - Nulls: always sorted last regardless of direction\n */\n\nimport type { SortState } from '@opendata-ai/openchart-core';\n\n/** Result of sorting: sorted data rows with their original indices preserved. */\nexport interface SortResult {\n data: Record<string, unknown>[];\n originalIndices: number[];\n}\n\n/**\n * Sort data rows by the specified column.\n * Returns a new array (no mutation). Stable sort preserves\n * original order for rows with equal values.\n *\n * Also returns the original indices so callers can track\n * which row came from where (needed for heatmap/category color lookups).\n */\nexport function sortData(data: Record<string, unknown>[], sort: SortState): SortResult {\n const { column, direction } = sort;\n const multiplier = direction === 'asc' ? 1 : -1;\n\n // Create index-value pairs for stable sort\n const indexed = data.map((row, i) => ({ row, index: i }));\n\n indexed.sort((a, b) => {\n const aVal = a.row[column];\n const bVal = b.row[column];\n\n // Nulls always last\n const aNull = aVal == null;\n const bNull = bVal == null;\n if (aNull && bNull) return a.index - b.index; // preserve order\n if (aNull) return 1;\n if (bNull) return -1;\n\n let cmp = 0;\n\n // Number comparison\n if (typeof aVal === 'number' && typeof bVal === 'number') {\n cmp = aVal - bVal;\n }\n // Date comparison\n else if (aVal instanceof Date && bVal instanceof Date) {\n cmp = aVal.getTime() - bVal.getTime();\n }\n // String comparison (or mixed types)\n else {\n cmp = String(aVal).localeCompare(String(bVal));\n }\n\n // Stable sort: fall back to original index for equal values\n if (cmp === 0) return a.index - b.index;\n return cmp * multiplier;\n });\n\n return {\n data: indexed.map((item) => item.row),\n originalIndices: indexed.map((item) => item.index),\n };\n}\n","/**\n * Sparkline computation for inline mini-charts in table cells.\n *\n * Produces normalized data points (0-1 range) for sparkline rendering.\n * The adapter handles the actual drawing.\n */\n\nimport type {\n ResolvedTheme,\n SparklineColumnConfig,\n SparklineData,\n} from '@opendata-ai/openchart-core';\n\nexport type { SparklineData };\n\n/**\n * Extract numeric values from a row for sparkline rendering.\n *\n * If valuesField is specified, reads an array from that field.\n * Otherwise uses the column's own key (expects an array value).\n */\nfunction extractValues(\n row: Record<string, unknown>,\n columnKey: string,\n config: SparklineColumnConfig,\n): number[] {\n const field = config.valuesField ?? columnKey;\n const raw = row[field];\n\n if (!Array.isArray(raw)) return [];\n\n return raw\n .map((v) => (typeof v === 'number' && Number.isFinite(v) ? v : null))\n .filter((v): v is number => v !== null);\n}\n\n/**\n * Compute sparkline data for a single row.\n *\n * Normalizes values to 0-1 range. Returns null if no valid values.\n */\nexport function computeSparkline(\n values: number[],\n config: SparklineColumnConfig,\n theme: ResolvedTheme,\n _darkMode: boolean,\n): SparklineData | null {\n if (values.length === 0) return null;\n\n const type = config.type ?? 'line';\n const color = config.color ?? theme.colors.categorical[0];\n\n let min = Infinity;\n let max = -Infinity;\n for (const v of values) {\n if (v < min) min = v;\n if (v > max) max = v;\n }\n\n const range = max - min;\n const normalize = (v: number): number => (range === 0 ? 0.5 : (v - min) / range);\n\n const startValue = values[0];\n const endValue = values[values.length - 1];\n\n if (type === 'line') {\n const points = values.map((v, i) => ({\n x: values.length === 1 ? 0.5 : i / (values.length - 1),\n y: normalize(v),\n }));\n\n return {\n type,\n points,\n bars: [],\n color,\n count: values.length,\n startValue,\n endValue,\n };\n }\n\n // Bar (horizontal) or column (vertical): normalized as proportions\n const bars = values.map(normalize);\n const points = values.map((v, i) => ({\n x: values.length === 1 ? 0.5 : i / (values.length - 1),\n y: normalize(v),\n }));\n\n return {\n type,\n points,\n bars,\n color,\n count: values.length,\n startValue,\n endValue,\n };\n}\n\n/**\n * Extract values and compute sparkline data for a cell.\n */\nexport function computeSparklineForRow(\n row: Record<string, unknown>,\n columnKey: string,\n config: SparklineColumnConfig,\n theme: ResolvedTheme,\n darkMode: boolean,\n): SparklineData | null {\n const values = extractValues(row, columnKey, config);\n return computeSparkline(values, config, theme, darkMode);\n}\n","/**\n * Tooltip descriptor computation.\n *\n * Generates a Map of mark-id -> TooltipContent from the spec encoding and marks.\n * Each mark gets a tooltip that shows relevant field values formatted for display.\n * The mark-id keys match the data-mark-id attributes set by the SVG renderer.\n */\n\nimport type {\n ArcMark,\n AreaMark,\n DataRow,\n Encoding,\n EncodingChannel,\n LineMark,\n Mark,\n PointMark,\n RectMark,\n TooltipContent,\n TooltipField,\n} from '@opendata-ai/openchart-core';\nimport {\n buildTemporalFormatter,\n formatDate,\n formatNumber,\n getRepresentativeColor,\n} from '@opendata-ai/openchart-core';\nimport { format as d3Format } from 'd3-format';\n\nimport type { NormalizedChartSpec } from '../compiler/types';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Format a raw data value for tooltip display. */\nfunction formatValue(value: unknown, fieldType?: string, format?: string): string {\n if (value == null) return '';\n\n if (fieldType === 'temporal' || value instanceof Date) {\n const temporalFmt = buildTemporalFormatter(format);\n if (temporalFmt) return temporalFmt(value as Date | string | number);\n return formatDate(value as Date | string | number);\n }\n\n if (typeof value === 'number') {\n if (format) {\n try {\n return d3Format(format)(value);\n } catch {\n return formatNumber(value);\n }\n }\n return formatNumber(value);\n }\n\n return String(value);\n}\n\n/** Resolve the display label for an encoding channel: title > axis.title > field name. */\nfunction resolveLabel(ch: EncodingChannel): string {\n return ch.title ?? ch.axis?.title ?? ch.field;\n}\n\n/** Resolve the format string for an encoding channel: format > axis.format. */\nfunction resolveFormat(ch: EncodingChannel): string | undefined {\n return ch.format ?? ch.axis?.format;\n}\n\n/** Build tooltip fields from explicit tooltip encoding channels. */\nfunction buildExplicitTooltipFields(row: DataRow, channels: EncodingChannel[]): TooltipField[] {\n return channels.map((ch) => ({\n label: resolveLabel(ch),\n value: formatValue(row[ch.field], ch.type, resolveFormat(ch)),\n }));\n}\n\n/** Build tooltip fields from a data row based on the spec encoding. */\nfunction buildFields(row: DataRow, encoding: Encoding, color?: string): TooltipField[] {\n if (encoding.tooltip) {\n const channels = Array.isArray(encoding.tooltip) ? encoding.tooltip : [encoding.tooltip];\n return buildExplicitTooltipFields(row, channels);\n }\n\n const fields: TooltipField[] = [];\n\n // Color/series field (e.g. \"Source: Coal\") so the user knows which series\n if (encoding.color && 'field' in encoding.color) {\n fields.push({\n label: resolveLabel(encoding.color),\n value: formatValue(\n row[encoding.color.field],\n encoding.color.type,\n resolveFormat(encoding.color),\n ),\n color,\n });\n }\n\n // Y-axis value (the \"main\" value in most charts)\n if (encoding.y) {\n fields.push({\n label: resolveLabel(encoding.y),\n value: formatValue(row[encoding.y.field], encoding.y.type, resolveFormat(encoding.y)),\n color: encoding.color ? undefined : color,\n });\n }\n\n // X-axis value (often the category or date)\n if (encoding.x) {\n fields.push({\n label: resolveLabel(encoding.x),\n value: formatValue(row[encoding.x.field], encoding.x.type, resolveFormat(encoding.x)),\n });\n }\n\n // Size (for scatter/bubble) - skip conditional size definitions\n if (encoding.size && 'field' in encoding.size) {\n fields.push({\n label: resolveLabel(encoding.size),\n value: formatValue(\n row[encoding.size.field],\n encoding.size.type,\n resolveFormat(encoding.size),\n ),\n });\n }\n\n return fields;\n}\n\n/** Determine the title for a tooltip based on encoding. */\nfunction getTooltipTitle(row: DataRow, encoding: Encoding): string | undefined {\n // Detail channel provides an explicit label (e.g. district name in scatter)\n if (encoding.detail) {\n return String(row[encoding.detail.field] ?? '');\n }\n\n // For charts with a temporal x-axis, use the date as the title\n if (encoding.x?.type === 'temporal') {\n return formatValue(row[encoding.x.field], 'temporal');\n }\n\n // For nominal x, use the category\n if (encoding.x?.type === 'nominal' || encoding.x?.type === 'ordinal') {\n return String(row[encoding.x.field] ?? '');\n }\n\n // For nominal y (e.g. horizontal bar charts), use the category\n if (encoding.y?.type === 'nominal' || encoding.y?.type === 'ordinal') {\n return String(row[encoding.y.field] ?? '');\n }\n\n // For scatter/bubble (both axes quantitative), find a name-like string field\n // in the data row that isn't already used by an encoding channel\n if (encoding.x?.type === 'quantitative' && encoding.y?.type === 'quantitative') {\n const encodedFields = new Set(\n [encoding.x, encoding.y, encoding.color, encoding.size, encoding.detail]\n .filter((ch): ch is EncodingChannel => !!ch && 'field' in ch)\n .map((ch) => ch.field),\n );\n for (const [key, value] of Object.entries(row)) {\n if (!encodedFields.has(key) && typeof value === 'string') {\n return value;\n }\n }\n }\n\n // For color-encoded series, use the series name (skip conditional defs)\n if (encoding.color && 'field' in encoding.color) {\n return String(row[encoding.color.field] ?? '');\n }\n\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Per-mark-type tooltip generation\n// ---------------------------------------------------------------------------\n\nfunction tooltipsForLine(\n mark: LineMark,\n encoding: Encoding,\n _markIndex: number,\n): Array<[string, TooltipContent]> {\n // Populate tooltip content on each dataPoint for voronoi overlay lookup.\n // Line marks don't emit per-mark tooltip descriptors (the overlay handles it).\n if (mark.dataPoints) {\n for (const dp of mark.dataPoints) {\n dp.tooltip = {\n title: getTooltipTitle(dp.datum, encoding),\n fields: buildFields(dp.datum, encoding, mark.stroke),\n };\n }\n }\n return [];\n}\n\nfunction tooltipsForPoint(\n mark: PointMark,\n encoding: Encoding,\n markIndex: number,\n): Array<[string, TooltipContent]> {\n const title = getTooltipTitle(mark.data, encoding);\n const fields = buildFields(mark.data, encoding, getRepresentativeColor(mark.fill));\n\n return [[`point-${markIndex}`, { title, fields }]];\n}\n\nfunction tooltipsForRect(\n mark: RectMark,\n encoding: Encoding,\n markIndex: number,\n): Array<[string, TooltipContent]> {\n const title = getTooltipTitle(mark.data, encoding);\n const fields = buildFields(mark.data, encoding, getRepresentativeColor(mark.fill));\n\n return [[`rect-${markIndex}`, { title, fields }]];\n}\n\nfunction tooltipsForArc(\n mark: ArcMark,\n encoding: Encoding,\n markIndex: number,\n): Array<[string, TooltipContent]> {\n const row = mark.data;\n const fields: TooltipField[] = [];\n\n // For pie/donut, show the category and its value\n const colorEnc = encoding.color && 'field' in encoding.color ? encoding.color : undefined;\n if (colorEnc) {\n const categoryName = String(row[colorEnc.field] ?? '');\n if (encoding.y) {\n fields.push({\n label: categoryName,\n value: formatValue(row[encoding.y.field], encoding.y.type, resolveFormat(encoding.y)),\n color: getRepresentativeColor(mark.fill),\n });\n }\n } else if (encoding.y) {\n fields.push({\n label: resolveLabel(encoding.y),\n value: formatValue(row[encoding.y.field], encoding.y.type, resolveFormat(encoding.y)),\n color: getRepresentativeColor(mark.fill),\n });\n }\n\n const title = colorEnc ? String(row[colorEnc.field] ?? '') : undefined;\n\n return [[`arc-${markIndex}`, { title, fields }]];\n}\n\nfunction tooltipsForArea(\n mark: AreaMark,\n encoding: Encoding,\n _markIndex: number,\n): Array<[string, TooltipContent]> {\n // Populate tooltip content on each dataPoint for voronoi overlay lookup.\n // Area marks don't emit per-mark tooltip descriptors (the overlay handles it).\n if (mark.dataPoints) {\n for (const dp of mark.dataPoints) {\n dp.tooltip = {\n title: getTooltipTitle(dp.datum, encoding),\n fields: buildFields(dp.datum, encoding, getRepresentativeColor(mark.fill)),\n };\n }\n }\n return [];\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute tooltip descriptors for all marks in the layout.\n *\n * Returns a Map keyed by data-mark-id (matching the SVG attribute)\n * to TooltipContent objects. The vanilla adapter uses this to show\n * tooltips on hover/tap/keyboard focus.\n */\nexport function computeTooltipDescriptors(\n spec: NormalizedChartSpec,\n marks: Mark[],\n): Map<string, TooltipContent> {\n const encoding = spec.encoding as Encoding;\n const descriptors = new Map<string, TooltipContent>();\n\n for (let i = 0; i < marks.length; i++) {\n const mark = marks[i];\n let entries: Array<[string, TooltipContent]> = [];\n\n switch (mark.type) {\n case 'line':\n entries = tooltipsForLine(mark, encoding, i);\n break;\n case 'area':\n entries = tooltipsForArea(mark, encoding, i);\n break;\n case 'point':\n entries = tooltipsForPoint(mark, encoding, i);\n break;\n case 'rect':\n entries = tooltipsForRect(mark, encoding, i);\n break;\n case 'arc':\n entries = tooltipsForArc(mark, encoding, i);\n break;\n }\n\n for (const [key, content] of entries) {\n descriptors.set(key, content);\n }\n }\n\n return descriptors;\n}\n","/**\n * Aggregate transform: groups rows and computes summary statistics.\n *\n * Follows Vega-Lite aggregate transform conventions.\n * Groups input data by the specified fields, then applies aggregate\n * operations (sum, mean, count, etc.) to produce one row per group.\n */\n\nimport type { AggregateOp, AggregateTransform, DataRow } from '@opendata-ai/openchart-core';\n\n/**\n * Compute a single aggregate operation over an array of numeric values.\n */\nfunction computeAggregate(op: AggregateOp, values: number[]): number {\n if (values.length === 0) return 0;\n\n switch (op) {\n case 'count':\n return values.length;\n case 'sum':\n return values.reduce((a, b) => a + b, 0);\n case 'mean': {\n const sum = values.reduce((a, b) => a + b, 0);\n return sum / values.length;\n }\n case 'median': {\n const sorted = [...values].sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];\n }\n case 'min':\n return Math.min(...values);\n case 'max':\n return Math.max(...values);\n case 'variance': {\n if (values.length < 2) return 0;\n const mean = values.reduce((a, b) => a + b, 0) / values.length;\n return values.reduce((a, v) => a + (v - mean) ** 2, 0) / values.length;\n }\n case 'stdev': {\n if (values.length < 2) return 0;\n const m = values.reduce((a, b) => a + b, 0) / values.length;\n return Math.sqrt(values.reduce((a, v) => a + (v - m) ** 2, 0) / values.length);\n }\n case 'q1': {\n const s = [...values].sort((a, b) => a - b);\n const i = (s.length - 1) * 0.25;\n const lo = Math.floor(i);\n const frac = i - lo;\n return s[lo] + frac * ((s[lo + 1] ?? s[lo]) - s[lo]);\n }\n case 'q3': {\n const s = [...values].sort((a, b) => a - b);\n const i = (s.length - 1) * 0.75;\n const lo = Math.floor(i);\n const frac = i - lo;\n return s[lo] + frac * ((s[lo + 1] ?? s[lo]) - s[lo]);\n }\n default:\n return 0;\n }\n}\n\n/**\n * Build a composite group key from a row's groupby field values.\n */\nfunction groupKey(row: DataRow, groupby: string[]): string {\n return groupby.map((f) => String(row[f] ?? '')).join('\\x00');\n}\n\n/**\n * Apply an aggregate transform to data rows.\n *\n * Groups rows by the groupby fields, then computes each aggregate\n * operation within each group. Returns one row per group containing\n * the groupby field values plus computed aggregate fields.\n *\n * @param data - Input rows.\n * @param transform - Aggregate transform definition.\n * @returns Aggregated rows (one per group).\n */\nexport function runAggregate(data: DataRow[], transform: AggregateTransform): DataRow[] {\n const { aggregate, groupby } = transform;\n\n // Group rows by the groupby fields\n const groups = new Map<string, DataRow[]>();\n for (const row of data) {\n const key = groupKey(row, groupby);\n const existing = groups.get(key);\n if (existing) {\n existing.push(row);\n } else {\n groups.set(key, [row]);\n }\n }\n\n // Compute aggregates for each group\n const result: DataRow[] = [];\n for (const rows of groups.values()) {\n // Start with groupby field values from the first row in the group\n const outRow: DataRow = {};\n for (const field of groupby) {\n outRow[field] = rows[0][field];\n }\n\n // Compute each aggregate operation\n for (const agg of aggregate) {\n // distinct counts unique raw values (not just numeric)\n if (agg.op === 'distinct') {\n outRow[agg.as] = new Set(rows.map((r) => r[agg.field])).size;\n continue;\n }\n\n const values = rows\n .map((r) => {\n // For count, the field value doesn't matter, just count rows\n if (agg.op === 'count') return 1;\n const v = Number(r[agg.field]);\n return Number.isFinite(v) ? v : NaN;\n })\n .filter((v) => !Number.isNaN(v));\n\n outRow[agg.as] = computeAggregate(agg.op, values);\n }\n\n result.push(outRow);\n }\n\n return result;\n}\n","/**\n * Bin transform: discretizes a continuous field into bins.\n *\n * Adds bin start (and optionally bin end) fields to each row.\n */\n\nimport type { BinParams, BinTransform, DataRow } from '@opendata-ai/openchart-core';\n\n/**\n * Compute a nice step size for binning.\n */\nfunction computeStep(extent: [number, number], maxbins: number, nice: boolean): number {\n const span = extent[1] - extent[0];\n if (span === 0) return 1;\n\n let step = span / maxbins;\n\n if (nice) {\n // Round to a nice step: 1, 2, 5, 10, 20, 50, etc.\n const magnitude = 10 ** Math.floor(Math.log10(step));\n const residual = step / magnitude;\n\n if (residual <= 1.5) {\n step = magnitude;\n } else if (residual <= 3.5) {\n step = 2 * magnitude;\n } else if (residual <= 7.5) {\n step = 5 * magnitude;\n } else {\n step = 10 * magnitude;\n }\n }\n\n return step;\n}\n\n/**\n * Apply a bin transform to data rows.\n *\n * Adds one or two fields to each row:\n * - If `as` is a string: adds `as` with the bin start value.\n * - If `as` is [start, end]: adds both bin start and bin end fields.\n *\n * @param data - Input rows.\n * @param transform - Bin transform definition.\n * @returns New rows with binned field(s) added.\n */\nexport function runBin(data: DataRow[], transform: BinTransform): DataRow[] {\n const params: BinParams = transform.bin === true ? {} : transform.bin;\n const maxbins = params.maxbins ?? 10;\n const nice = params.nice ?? true;\n const field = transform.field;\n\n // Compute extent from data if not provided\n let extent = params.extent;\n if (!extent) {\n let min = Infinity;\n let max = -Infinity;\n for (const row of data) {\n const v = Number(row[field]);\n if (Number.isFinite(v)) {\n if (v < min) min = v;\n if (v > max) max = v;\n }\n }\n extent = [min === Infinity ? 0 : min, max === -Infinity ? 0 : max];\n }\n\n const step = params.step ?? computeStep(extent, maxbins, nice);\n const [startAs, endAs] = Array.isArray(transform.as) ? transform.as : [transform.as, undefined];\n\n return data.map((row) => {\n const v = Number(row[field]);\n const newRow = { ...row };\n\n if (!Number.isFinite(v)) {\n newRow[startAs] = null;\n if (endAs) newRow[endAs] = null;\n } else {\n const binStart = Math.floor((v - extent![0]) / step) * step + extent![0];\n newRow[startAs] = binStart;\n if (endAs) newRow[endAs] = binStart + step;\n }\n\n return newRow;\n });\n}\n","/**\n * Calculate transform: adds a computed field to each row.\n *\n * Supports arithmetic operations on fields and constant values.\n */\n\nimport type { CalculateExpression, CalculateTransform, DataRow } from '@opendata-ai/openchart-core';\n\n/**\n * Evaluate a calculate expression against a datum.\n */\nfunction evaluateExpression(datum: DataRow, expr: CalculateExpression): number {\n const fieldValue = Number(datum[expr.field]);\n\n // Unary operations (single field)\n switch (expr.op) {\n case 'abs':\n return Math.abs(fieldValue);\n case 'round':\n return Math.round(fieldValue);\n case 'floor':\n return Math.floor(fieldValue);\n case 'ceil':\n return Math.ceil(fieldValue);\n case 'log':\n return Math.log(fieldValue);\n case 'sqrt':\n return Math.sqrt(fieldValue);\n }\n\n // Binary operations (field + field2 or field + value)\n const operand = expr.field2 !== undefined ? Number(datum[expr.field2]) : (expr.value ?? 0);\n\n switch (expr.op) {\n case '+':\n return fieldValue + operand;\n case '-':\n return fieldValue - operand;\n case '*':\n return fieldValue * operand;\n case '/':\n return operand === 0 ? NaN : fieldValue / operand;\n }\n}\n\n/**\n * Apply a calculate transform to data rows.\n *\n * Adds a new field with the computed value to each row.\n *\n * @param data - Input rows.\n * @param transform - Calculate transform definition.\n * @returns New rows with the calculated field added.\n */\nexport function runCalculate(data: DataRow[], transform: CalculateTransform): DataRow[] {\n return data.map((row) => ({\n ...row,\n [transform.as]: evaluateExpression(row, transform.calculate),\n }));\n}\n","/**\n * Filter transform: removes rows that don't match a predicate.\n */\n\nimport type { DataRow, FilterPredicate } from '@opendata-ai/openchart-core';\nimport { evaluatePredicate } from './predicates';\n\n/**\n * Filter data rows by a predicate.\n *\n * @param data - Input rows.\n * @param predicate - Filter predicate to evaluate per row.\n * @returns Rows that pass the predicate.\n */\nexport function runFilter(data: DataRow[], predicate: FilterPredicate): DataRow[] {\n return data.filter((datum) => evaluatePredicate(datum, predicate));\n}\n","/**\n * Fold transform: unpivots wide-format data into long format.\n *\n * Follows Vega-Lite fold transform conventions.\n * For each input row, creates N new rows (one per fold field),\n * copying all non-fold fields and adding key/value columns.\n */\n\nimport type { DataRow, FoldTransform } from '@opendata-ai/openchart-core';\n\n/**\n * Apply a fold transform to data rows.\n *\n * For each input row, creates one output row per fold field. Each output\n * row contains all fields from the original row (except the fold fields),\n * plus a key field (the fold field name) and a value field (the fold field value).\n *\n * @param data - Input rows.\n * @param transform - Fold transform definition.\n * @returns Folded rows (N rows per input row, where N = fold fields count).\n */\nexport function runFold(data: DataRow[], transform: FoldTransform): DataRow[] {\n const { fold } = transform;\n const [keyAs, valueAs] = transform.as ?? ['key', 'value'];\n const foldSet = new Set(fold);\n\n const result: DataRow[] = [];\n\n for (const row of data) {\n // Copy all non-fold fields\n const base: DataRow = {};\n for (const [k, v] of Object.entries(row)) {\n if (!foldSet.has(k)) {\n base[k] = v;\n }\n }\n\n // Create one row per fold field\n for (const field of fold) {\n result.push({\n ...base,\n [keyAs]: field,\n [valueAs]: row[field],\n });\n }\n }\n\n return result;\n}\n","/**\n * Time unit transform: extracts temporal components from date fields.\n *\n * Follows Vega-Lite time unit conventions.\n */\n\nimport type { DataRow, TimeUnit, TimeUnitTransform } from '@opendata-ai/openchart-core';\n\n/**\n * Extract a time unit value from a Date object.\n */\nfunction extractTimeUnit(date: Date, unit: TimeUnit): number | string {\n switch (unit) {\n case 'year':\n return date.getFullYear();\n case 'quarter':\n return Math.floor(date.getMonth() / 3) + 1;\n case 'month':\n return date.getMonth(); // 0-indexed like JS Date\n case 'week': {\n // ISO week number\n const d = new Date(date.getTime());\n d.setHours(0, 0, 0, 0);\n d.setDate(d.getDate() + 3 - ((d.getDay() + 6) % 7));\n const yearStart = new Date(d.getFullYear(), 0, 1);\n return Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);\n }\n case 'day':\n return date.getDay(); // 0 = Sunday\n case 'dayofyear': {\n const start = new Date(date.getFullYear(), 0, 0);\n const diff = date.getTime() - start.getTime();\n return Math.floor(diff / 86400000);\n }\n case 'date':\n return date.getDate(); // 1-31\n case 'hours':\n return date.getHours();\n case 'minutes':\n return date.getMinutes();\n case 'seconds':\n return date.getSeconds();\n case 'milliseconds':\n return date.getMilliseconds();\n // Compound units\n case 'yearmonth':\n return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;\n case 'yearmonthdate':\n return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;\n case 'monthdate':\n return `${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;\n case 'hoursminutes':\n return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;\n }\n}\n\n/**\n * Parse a value into a Date object.\n * Handles Date objects, ISO strings, and numeric timestamps.\n */\nfunction toDate(value: unknown): Date | null {\n if (value instanceof Date) return value;\n if (typeof value === 'string' || typeof value === 'number') {\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n return null;\n}\n\n/**\n * Apply a time unit transform to data rows.\n *\n * Parses the field as a date and extracts the specified time unit,\n * storing the result in a new field.\n *\n * @param data - Input rows.\n * @param transform - Time unit transform definition.\n * @returns New rows with the time unit field added.\n */\nexport function runTimeUnit(data: DataRow[], transform: TimeUnitTransform): DataRow[] {\n return data.map((row) => {\n const date = toDate(row[transform.field]);\n return {\n ...row,\n [transform.as]: date ? extractTimeUnit(date, transform.timeUnit) : null,\n };\n });\n}\n","/**\n * Data transform pipeline.\n *\n * Runs an ordered sequence of transforms (filter, bin, calculate, timeUnit)\n * against a data array. Each transform produces a new array, feeding into\n * the next transform in sequence.\n */\n\nimport type { DataRow, Transform } from '@opendata-ai/openchart-core';\nimport { runAggregate } from './aggregate';\nimport { runBin } from './bin';\nimport { runCalculate } from './calculate';\nimport { runFilter } from './filter';\nimport { runFold } from './fold';\nimport { runTimeUnit } from './timeunit';\n\nexport { runAggregate } from './aggregate';\nexport { runBin } from './bin';\nexport { runCalculate } from './calculate';\nexport { isConditionalValueDef, resolveConditionalValue } from './conditional';\nexport { runFilter } from './filter';\nexport { runFold } from './fold';\nexport { evaluatePredicate } from './predicates';\nexport { runTimeUnit } from './timeunit';\n\n/**\n * Run a sequence of transforms against a data array.\n *\n * Each transform is applied in order, producing a new data array\n * that feeds into the next transform. The original data is not mutated.\n *\n * @param data - Input data rows.\n * @param transforms - Ordered array of transform definitions.\n * @returns Transformed data rows.\n */\nexport function runTransforms(data: DataRow[], transforms: Transform[]): DataRow[] {\n let result = data;\n\n for (const transform of transforms) {\n if ('filter' in transform) {\n result = runFilter(result, transform.filter);\n } else if ('bin' in transform) {\n result = runBin(result, transform);\n } else if ('calculate' in transform) {\n result = runCalculate(result, transform);\n } else if ('timeUnit' in transform) {\n result = runTimeUnit(result, transform);\n } else if ('aggregate' in transform) {\n result = runAggregate(result, transform);\n } else if ('fold' in transform) {\n result = runFold(result, transform);\n }\n }\n\n return result;\n}\n"],"mappings":"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","names":["adaptTheme","resolveTheme","value","date","strValue","defaultStroke","value","min","max","left","right","center","min","max","value","key","value","value","ticks","max","value","min","value","range","range","range","value","copy","format","value","min","max","t1","color","rgb","zero","i","number","range","i","number","value","value","locale","zero","format","value","formatPrefix","value","max","value","linear","quantile","range","range","range","date","range","date","date","date","date","date","date","date","date","ticks","step","date","locale","formats","pad","format","value","locale","defaultLocale","number","ticks","second","format","formatYear","tickFormat","date","transformer","t0","t1","range","copy","left","right","value","date","value","rules","hex","range","linear","value","color","value","estimateTextWidth","ticks","min","max","value","ticks","ticks","computeChrome","estimateTextWidth","computeChrome","estimateTextWidth","linear","range","quantile","BRAND_RESERVE_WIDTH","estimateTextWidth","estimateTextWidth","SWATCH_SIZE","SWATCH_GAP","ENTRY_GAP","value","SWATCH_SIZE","SWATCH_GAP","ENTRY_GAP","estimateTextWidth","legendHeight","offsetDx","offsetDy","BRAND_RESERVE_WIDTH","sum","adaptTheme","buildD3Formatter","computeChrome","estimateTextWidth","formatNumber","resolveTheme","max","value","min","value","sum","value","min","nodes","links","max","min","value","dy","sourceLinks","targetLinks","pad","resolveTheme","adaptTheme","computeChrome","max","estimateTextWidth","color","SWATCH_SIZE","SWATCH_GAP","ENTRY_GAP","value","buildD3Formatter","formatNumber","computeChrome","estimateTextWidth","value","barPercent","max","min","buildD3Formatter","formatDate","formatNumber","value","adaptColorForDarkMode","min","max","value","adaptColorForDarkMode","color","min","max","range","normalize","points","estimateTextWidth","sum","value","computeChrome","buildTemporalFormatter","formatDate","formatNumber","value","format","buildTemporalFormatter","formatDate","formatNumber","color","sum","extent","nice","min","max","date","unit","value","unit","resolveTheme","adaptTheme","compileGraph","compileSankey"]}
|
|
1
|
+
{"version":3,"sources":["../src/compile.ts","../src/annotations/collisions.ts","../src/annotations/constants.ts","../src/annotations/geometry.ts","../src/annotations/position.ts","../src/annotations/resolve-text.ts","../src/annotations/resolve-range.ts","../src/annotations/resolve-refline.ts","../src/annotations/compute.ts","../src/charts/bar/compute.ts","../src/transforms/predicates.ts","../src/transforms/conditional.ts","../src/charts/_shared/format-label-value.ts","../src/charts/utils.ts","../src/charts/bar/labels.ts","../src/charts/_shared/density-filter.ts","../src/charts/bar/index.ts","../src/charts/column/compute.ts","../src/charts/column/labels.ts","../src/charts/column/index.ts","../src/charts/dot/compute.ts","../src/charts/dot/labels.ts","../src/charts/dot/index.ts","../src/charts/line/index.ts","../src/charts/line/area.ts","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/constant.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/math.js","../../../node_modules/.bun/d3-path@3.1.0/node_modules/d3-path/src/path.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/path.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/arc.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/array.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/curve/linear.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/point.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/line.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/area.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/descending.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/identity.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/pie.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/curve/basis.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/curve/cardinal.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/curve/monotone.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/curve/natural.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/curve/step.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/offset/none.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/order/none.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/stack.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/offset/expand.js","../../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/offset/silhouette.js","../src/charts/line/curves.ts","../src/charts/line/compute.ts","../src/charts/line/labels.ts","../src/charts/pie/compute.ts","../src/charts/pie/labels.ts","../src/charts/pie/index.ts","../src/charts/registry.ts","../src/charts/rule/index.ts","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/ascending.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/descending.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/bisector.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/number.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/bisect.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/extent.js","../../../node_modules/.bun/internmap@2.0.3/node_modules/internmap/src/index.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/ticks.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/max.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/min.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/quantile.js","../../../node_modules/.bun/d3-array@3.2.4/node_modules/d3-array/src/range.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/init.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/ordinal.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/band.js","../../../node_modules/.bun/d3-color@3.1.0/node_modules/d3-color/src/define.js","../../../node_modules/.bun/d3-color@3.1.0/node_modules/d3-color/src/color.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/basis.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/basisClosed.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/constant.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/color.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/rgb.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/numberArray.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/array.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/date.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/number.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/object.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/string.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/value.js","../../../node_modules/.bun/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/round.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/constant.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/number.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/continuous.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatDecimal.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/exponent.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatGroup.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatNumerals.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatSpecifier.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatTrim.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatPrefixAuto.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatRounded.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/formatTypes.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/identity.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/locale.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/defaultLocale.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/precisionFixed.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/precisionPrefix.js","../../../node_modules/.bun/d3-format@3.1.2/node_modules/d3-format/src/precisionRound.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/tickFormat.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/linear.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/nice.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/log.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/symlog.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/pow.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/quantile.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/quantize.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/threshold.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/interval.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/millisecond.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/duration.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/second.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/minute.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/hour.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/day.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/week.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/month.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/year.js","../../../node_modules/.bun/d3-time@3.1.0/node_modules/d3-time/src/ticks.js","../../../node_modules/.bun/d3-time-format@4.1.0/node_modules/d3-time-format/src/locale.js","../../../node_modules/.bun/d3-time-format@4.1.0/node_modules/d3-time-format/src/defaultLocale.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/time.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/utcTime.js","../../../node_modules/.bun/d3-scale@4.0.2/node_modules/d3-scale/src/sequential.js","../src/charts/scatter/compute.ts","../src/charts/scatter/trendline.ts","../src/charts/scatter/index.ts","../src/charts/text/index.ts","../src/charts/tick/index.ts","../src/charts/builtin.ts","../src/charts/post-process.ts","../src/compile/color-scale-range.ts","../src/compile/data-clip.ts","../src/compile/watermark-obstacle.ts","../src/compiler/animation.ts","../src/compiler/normalize.ts","../src/compiler/validate.ts","../src/compiler/index.ts","../src/graphs/compile-graph.ts","../src/graphs/encoding.ts","../src/graphs/community.ts","../src/layout/axes/thinning.ts","../src/layout/axes/ticks.ts","../src/layout/axes.ts","../src/layout/dimensions.ts","../src/layout/gridlines.ts","../src/layout/scales.ts","../src/legend/compute.ts","../src/legend/wrap.ts","../src/sankey/compile-sankey.ts","../../../node_modules/.bun/d3-array@2.12.1/node_modules/d3-array/src/max.js","../../../node_modules/.bun/d3-array@2.12.1/node_modules/d3-array/src/min.js","../../../node_modules/.bun/d3-array@2.12.1/node_modules/d3-array/src/sum.js","../../../node_modules/.bun/d3-sankey@0.12.3/node_modules/d3-sankey/src/align.js","../../../node_modules/.bun/d3-sankey@0.12.3/node_modules/d3-sankey/src/constant.js","../../../node_modules/.bun/d3-sankey@0.12.3/node_modules/d3-sankey/src/sankey.js","../src/sankey/layout.ts","../src/tables/compile-table.ts","../src/tables/bar-column.ts","../src/tables/category-colors.ts","../src/tables/utils.ts","../src/tables/format-cells.ts","../src/tables/heatmap.ts","../src/tables/pagination.ts","../src/tables/search.ts","../src/tables/sort.ts","../src/tables/sparkline.ts","../src/tooltips/compute.ts","../src/transforms/aggregate.ts","../src/transforms/bin.ts","../src/transforms/calculate.ts","../src/transforms/filter.ts","../src/transforms/fold.ts","../src/transforms/timeunit.ts","../src/transforms/index.ts"],"sourcesContent":["/**\n * Main compile API: the public entry points for the engine.\n *\n * Pipeline for charts:\n * validate spec -> normalize -> resolve theme -> dark mode adapt ->\n * compute legend -> compute dimensions (with legend space) ->\n * compute scales -> compute axes -> compute gridlines ->\n * get chart renderer -> compute marks -> compute a11y -> return ChartLayout\n *\n * Table compiler handles full data pipeline (sort, search, pagination, visual enhancements).\n * Graph compiler is a stub for future implementation.\n */\n\nimport type {\n AnimationSpec,\n BinParams,\n BinTransform,\n ChartLayout,\n ChartSpec,\n CompileOptions,\n CompileTableOptions,\n EncodingChannel,\n LayerSpec,\n Mark,\n Rect,\n ResolvedAnnotation,\n ResolvedTheme,\n TableLayout,\n TimeUnit,\n TimeUnitTransform,\n Transform,\n} from '@opendata-ai/openchart-core';\nimport {\n adaptTheme,\n computeLabelBounds,\n generateAltText,\n generateDataTable,\n getBreakpoint,\n getHeightClass,\n getLayoutStrategy,\n resolveTheme,\n} from '@opendata-ai/openchart-core';\nimport { computeAnnotations } from './annotations/compute';\n// Side-effect import: registers all built-in chart renderers with the\n// registry on module load. Tests that clear the registry can import\n// `registerBuiltinRenderers` from `./charts/builtin` to restore defaults.\nimport './charts/builtin';\nimport {\n assignAnimationIndices,\n computeMarkObstacles,\n resolveRendererKey,\n} from './charts/post-process';\nimport { getChartRenderer } from './charts/registry';\nimport { applyColorScaleRange } from './compile/color-scale-range';\nimport { filterClippedDomains } from './compile/data-clip';\nimport { computeWatermarkObstacle } from './compile/watermark-obstacle';\nimport { resolveAnimation } from './compiler/animation';\nimport { compile as compileSpec, flattenLayers } from './compiler/index';\nimport type { NormalizedChartSpec, NormalizedTableSpec } from './compiler/types';\nimport { compileGraph as compileGraphImpl } from './graphs/compile-graph';\nimport type { GraphCompilation } from './graphs/types';\nimport { computeAxes } from './layout/axes';\nimport { computeDimensions } from './layout/dimensions';\nimport { computeGridlines } from './layout/gridlines';\nimport { computeScales } from './layout/scales';\nimport { computeLegend } from './legend/compute';\nimport { compileSankey as compileSankeyImpl } from './sankey/compile-sankey';\nimport { compileTableLayout } from './tables/compile-table';\nimport { computeTooltipDescriptors } from './tooltips/compute';\nimport { runTransforms } from './transforms';\n\n// ---------------------------------------------------------------------------\n// Encoding sugar expansion (bin, timeUnit on encoding channels)\n// ---------------------------------------------------------------------------\n\n/**\n * Expand encoding-level `bin` and `timeUnit` shorthand into explicit transforms.\n *\n * Vega-Lite allows `encoding.x.bin: true` as sugar for a BinTransform.\n * This function detects those shorthands, generates the corresponding transforms,\n * updates encoding field references to the output field names, and prepends the\n * transforms to the spec's transform array.\n *\n * Mutates nothing; returns a new spec object (shallow copy).\n */\nexport function expandEncodingSugar(spec: Record<string, unknown>): Record<string, unknown> {\n const encoding = spec.encoding as Record<string, EncodingChannel | undefined> | undefined;\n if (!encoding) return spec;\n\n const generatedTransforms: Transform[] = [];\n const updatedEncoding = { ...encoding };\n let changed = false;\n\n for (const channel of Object.keys(encoding)) {\n const ch = encoding[channel];\n if (!ch || !ch.field) continue;\n\n // Expand bin shorthand\n if (ch.bin != null && ch.bin !== false) {\n const field = ch.field;\n const outputField = `bin_${field}`;\n const binTransform: BinTransform = {\n bin: ch.bin === true ? true : (ch.bin as BinParams),\n field,\n as: outputField,\n };\n generatedTransforms.push(binTransform);\n\n // Update encoding to reference binned output field, remove bin property\n const { bin: _bin, ...rest } = ch;\n updatedEncoding[channel] = { ...rest, field: outputField } as EncodingChannel;\n changed = true;\n }\n\n // Expand timeUnit shorthand (read from updated encoding in case bin already ran)\n const current = updatedEncoding[channel] ?? ch;\n if (current.timeUnit) {\n const field = current.field;\n const unit = current.timeUnit as TimeUnit;\n const outputField = `${unit}_${field}`;\n const timeUnitTransform: TimeUnitTransform = {\n timeUnit: unit,\n field,\n as: outputField,\n };\n generatedTransforms.push(timeUnitTransform);\n\n // Update encoding to reference timeUnit output field, remove timeUnit property\n const { timeUnit: _tu, ...rest } = current;\n updatedEncoding[channel] = { ...rest, field: outputField } as EncodingChannel;\n changed = true;\n }\n }\n\n if (!changed) return spec;\n\n // Prepend generated transforms before any user-defined transforms\n const existingTransforms = (spec.transform as Transform[] | undefined) ?? [];\n return {\n ...spec,\n encoding: updatedEncoding,\n transform: [...generatedTransforms, ...existingTransforms],\n };\n}\n\n// ---------------------------------------------------------------------------\n// Chart compilation\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a chart spec into a ChartLayout.\n *\n * This is the main engine entry point. Takes a raw spec (any shape,\n * validated at runtime) and compile options, produces a fully resolved\n * ChartLayout with positions, colors, and marks ready for rendering.\n *\n * @param spec - Raw chart spec (validated and normalized internally).\n * @param options - Compile options (width, height, theme, darkMode).\n * @returns ChartLayout with all computed positions.\n * @throws Error if spec is invalid or not a chart type.\n */\nexport function compileChart(spec: unknown, options: CompileOptions): ChartLayout {\n // Expand encoding-level bin/timeUnit sugar before validation + normalization.\n // This converts shorthand (e.g. encoding.x.bin: true) into explicit transforms.\n const expandedSpec =\n spec && typeof spec === 'object' && !Array.isArray(spec)\n ? expandEncodingSugar(spec as Record<string, unknown>)\n : spec;\n\n // Validate + normalize\n const { spec: normalized } = compileSpec(expandedSpec);\n\n if ('type' in normalized && (normalized as unknown as Record<string, unknown>).type === 'table') {\n throw new Error('compileChart received a table spec. Use compileTable instead.');\n }\n if ('type' in normalized && (normalized as unknown as Record<string, unknown>).type === 'graph') {\n throw new Error('compileChart received a graph spec. Use compileGraph instead.');\n }\n if (\n 'type' in normalized &&\n (normalized as unknown as Record<string, unknown>).type === 'sankey'\n ) {\n throw new Error('compileChart received a sankey spec. Use compileSankey instead.');\n }\n\n let chartSpec = normalized as NormalizedChartSpec;\n\n // Resolve watermark: explicit spec value wins, then options fallback, then default true.\n const rawWatermark = (expandedSpec as Record<string, unknown>).watermark;\n const watermark = rawWatermark !== undefined ? chartSpec.watermark : (options.watermark ?? true);\n\n // Run data transforms (filter, bin, calculate, timeUnit) before any other data processing.\n // Transforms are defined on the expanded spec (which includes any auto-generated\n // transforms from encoding-level bin/timeUnit sugar), not the normalized spec,\n // since NormalizedChartSpec doesn't carry the transform field.\n const rawTransforms = (expandedSpec as Record<string, unknown>).transform as\n | import('@opendata-ai/openchart-core').Transform[]\n | undefined;\n if (rawTransforms && rawTransforms.length > 0) {\n chartSpec = { ...chartSpec, data: runTransforms(chartSpec.data, rawTransforms) };\n }\n\n // Responsive strategy\n const breakpoint = getBreakpoint(options.width);\n const heightClass = getHeightClass(options.height);\n let strategy = getLayoutStrategy(breakpoint, heightClass);\n\n // Apply breakpoint-conditional overrides from the expanded spec\n const rawSpec = expandedSpec as Record<string, unknown>;\n const overrides = rawSpec.overrides as\n | Partial<\n Record<\n string,\n { chrome?: unknown; labels?: unknown; legend?: unknown; annotations?: unknown }\n >\n >\n | undefined;\n if (overrides?.[breakpoint]) {\n const bp = overrides[breakpoint]!;\n if (bp.chrome) {\n chartSpec = {\n ...chartSpec,\n chrome: {\n ...chartSpec.chrome,\n ...(bp.chrome as NormalizedChartSpec['chrome']),\n },\n };\n }\n if (bp.labels) {\n chartSpec = {\n ...chartSpec,\n labels: {\n ...chartSpec.labels,\n ...(bp.labels as NormalizedChartSpec['labels']),\n },\n };\n }\n if (bp.legend) {\n chartSpec = {\n ...chartSpec,\n legend: {\n ...chartSpec.legend,\n ...(bp.legend as NormalizedChartSpec['legend']),\n },\n };\n }\n if (bp.annotations) {\n chartSpec = {\n ...chartSpec,\n annotations: bp.annotations as NormalizedChartSpec['annotations'],\n };\n // User explicitly provided annotations at this breakpoint — override the\n // responsive strategy so they render inline instead of being stripped.\n strategy = { ...strategy, annotationPosition: 'inline' };\n }\n }\n\n // Resolve animation spec. Breakpoint override wins over base spec (matching\n // chrome, labels, legend, and annotation override precedence).\n const rawAnimationSpec = ((overrides?.[breakpoint] as Record<string, unknown> | undefined)\n ?.animation ?? rawSpec.animation) as AnimationSpec | undefined;\n const resolvedAnimation = resolveAnimation(rawAnimationSpec);\n\n // Resolve theme: merge spec-level theme with options-level overrides\n const mergedThemeConfig = options.theme\n ? { ...chartSpec.theme, ...options.theme }\n : chartSpec.theme;\n let theme: ResolvedTheme = resolveTheme(mergedThemeConfig);\n if (options.darkMode) {\n theme = adaptTheme(theme);\n }\n\n // INVARIANT 1 — double legend pass: preliminaryArea → computeDimensions → legendArea → final\n // legend. Breaks a dims/legend dependency cycle. Do not collapse into one call.\n // Compute legend first (needs to reserve space)\n const preliminaryArea: Rect = {\n x: 0,\n y: 0,\n width: options.width,\n height: options.height,\n };\n const legendLayout = computeLegend(chartSpec, strategy, theme, preliminaryArea, watermark);\n\n // Compute dimensions (accounts for chrome + legend + responsive strategy)\n const dims = computeDimensions(chartSpec, options, legendLayout, theme, strategy, watermark);\n const chartArea = dims.chartArea;\n\n // Recompute legend bounds relative to actual chart area.\n // chartArea was shrunk to exclude legend space, so expand it back to include\n // the reserved margin. This way computeLegend positions the legend outside\n // the data area (in the margin) instead of overlapping data marks.\n const legendArea: Rect = { ...chartArea };\n if (legendLayout.entries.length > 0) {\n switch (legendLayout.position) {\n case 'top':\n legendArea.y -= legendLayout.bounds.height + 4;\n legendArea.height += legendLayout.bounds.height + 4;\n break;\n case 'bottom':\n legendArea.height += legendLayout.bounds.height + 4;\n break;\n case 'right':\n case 'bottom-right':\n legendArea.width += legendLayout.bounds.width + 8;\n break;\n }\n }\n const finalLegend = computeLegend(chartSpec, strategy, theme, legendArea, watermark);\n\n // Apply data filtering after legend (so legend retains all series), but before\n // scale computation (so hidden/clipped data doesn't affect domains or marks).\n let renderData = chartSpec.data;\n\n // Filter hidden series: removed from rendering but kept in legend (dimmed in the adapter)\n if (\n chartSpec.hiddenSeries.length > 0 &&\n chartSpec.encoding.color &&\n 'field' in chartSpec.encoding.color\n ) {\n const colorField = chartSpec.encoding.color.field;\n const hiddenSet = new Set(chartSpec.hiddenSeries);\n renderData = renderData.filter((row) => !hiddenSet.has(String(row[colorField])));\n }\n\n // Filter clipped scale domains: when scale.clip is true, exclude rows outside the domain\n renderData = filterClippedDomains(renderData, chartSpec.encoding);\n\n // Build a filtered spec for scales and marks, keeping all other properties intact\n const renderSpec = renderData !== chartSpec.data ? { ...chartSpec, data: renderData } : chartSpec;\n\n // Compute scales\n const scales = computeScales(renderSpec, chartArea, renderSpec.data);\n\n // Update color scale to use theme palette (only when user hasn't provided an explicit range)\n applyColorScaleRange(scales, renderSpec.encoding, theme);\n\n // INVARIANT 3 — post-hoc defaultColor: must run AFTER computeScales since resolution needs\n // theme context. Do not move into computeScales (would require threading theme through).\n // If the user set a fill on the mark def, it takes priority over the theme's first categorical.\n scales.defaultColor = chartSpec.markDef.fill ?? theme.colors.categorical[0];\n\n // Arc charts (pie/donut) don't use axes or gridlines\n const isRadial = chartSpec.markType === 'arc';\n\n // Compute axes (skip for radial charts)\n const axes = isRadial\n ? { x: undefined, y: undefined }\n : computeAxes(scales, chartArea, strategy, theme, options.measureText);\n\n // INVARIANT 2 — computeGridlines mutates `axes` in place. Downstream consumers read\n // axes.y.gridlines off the same object. Do not introduce a copy-on-write.\n if (!isRadial) {\n computeGridlines(axes, chartArea);\n }\n\n // Get chart renderer and compute marks (using filtered data).\n const rendererKey = resolveRendererKey(\n renderSpec.markType,\n renderSpec.encoding,\n renderSpec.markDef,\n );\n const renderer = getChartRenderer(rendererKey);\n const marks: Mark[] = renderer ? renderer(renderSpec, scales, chartArea, strategy, theme) : [];\n\n // Compute annotations from spec, passing legend + mark + brand bounds as obstacles\n const obstacles: Rect[] = [];\n if (finalLegend.bounds.width > 0) {\n obstacles.push(finalLegend.bounds);\n }\n obstacles.push(...computeMarkObstacles(marks, scales));\n\n // Add visible data label bounds as obstacles so annotations avoid overlapping them\n for (const mark of marks) {\n if ('label' in mark && mark.label?.visible) {\n obstacles.push(computeLabelBounds(mark.label));\n }\n }\n\n // Add brand watermark as an obstacle so annotations avoid overlapping it.\n const watermarkRect = computeWatermarkObstacle(dims, watermark, axes, theme);\n if (watermarkRect) obstacles.push(watermarkRect);\n const annotations: ResolvedAnnotation[] = computeAnnotations(\n chartSpec,\n scales,\n chartArea,\n strategy,\n theme.isDark,\n obstacles,\n { width: dims.total.width, height: dims.total.height },\n );\n\n // Compute tooltip descriptors from marks and encoding\n const tooltipDescriptors = computeTooltipDescriptors(chartSpec, marks);\n\n // Compute accessibility\n const altText = generateAltText(\n {\n mark: chartSpec.markType,\n data: chartSpec.data,\n encoding: chartSpec.encoding,\n chrome: chartSpec.chrome,\n },\n chartSpec.data,\n );\n const dataTableFallback = generateDataTable(\n {\n mark: chartSpec.markType,\n data: chartSpec.data,\n encoding: chartSpec.encoding,\n },\n chartSpec.data,\n );\n\n // Assign animationIndex for stagger ordering when animation is enabled\n assignAnimationIndices(marks, resolvedAnimation);\n\n return {\n area: chartArea,\n chrome: dims.chrome,\n axes: {\n x: axes.x,\n y: axes.y,\n },\n marks,\n annotations,\n legend: finalLegend,\n tooltipDescriptors,\n a11y: {\n altText,\n dataTableFallback,\n role: 'img',\n keyboardNavigable: marks.length > 0,\n },\n theme,\n dimensions: {\n width: options.width,\n height: options.height,\n },\n animation: resolvedAnimation,\n watermark,\n measureText: options.measureText,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Layer compilation\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a LayerSpec into a single ChartLayout.\n *\n * Flattens nested layers, merges inherited data/encoding/transforms,\n * compiles each leaf layer independently, unions scale domains (shared\n * by default), and concatenates marks in layer order.\n *\n * @param spec - A LayerSpec with child layers.\n * @param options - Compile options (width, height, theme, darkMode).\n * @returns A single ChartLayout with combined marks from all layers.\n */\nexport function compileLayer(spec: LayerSpec, options: CompileOptions): ChartLayout {\n // Flatten nested layers into leaf ChartSpecs with merged data/encoding/transforms\n const leaves = flattenLayers(spec);\n\n if (leaves.length === 0) {\n throw new Error('LayerSpec has no leaf chart specs after flattening');\n }\n\n // If there's only one layer, just compile it directly\n if (leaves.length === 1) {\n const singleSpec = buildPrimarySpec(leaves, spec);\n return compileChart(singleSpec, options);\n }\n\n // Build primary spec with unioned data for shared scale computation.\n // The primary layout provides chrome, axes, dimensions, legend, and a11y.\n const primarySpec = buildPrimarySpec(leaves, spec);\n const primaryLayout = compileChart(primarySpec, options);\n\n // Compile each leaf layer independently but with the full unioned data\n // so they all share the same scale domains.\n const allMarks: Mark[] = [];\n const seenLabels = new Set<string>();\n const mergedLegendEntries = [...primaryLayout.legend.entries];\n for (const entry of mergedLegendEntries) {\n seenLabels.add(entry.label);\n }\n\n for (const leaf of leaves) {\n // Compile each leaf with its own data so marks correspond to its rows only.\n // Scale domains may differ slightly between layers, but this prevents\n // duplicate marks from feeding unioned data into every renderer.\n const leafLayout = compileChart(leaf as unknown, options);\n\n allMarks.push(...leafLayout.marks);\n\n // Deduplicate legend entries across layers\n for (const entry of leafLayout.legend.entries) {\n if (!seenLabels.has(entry.label)) {\n seenLabels.add(entry.label);\n mergedLegendEntries.push(entry);\n }\n }\n }\n\n return {\n ...primaryLayout,\n marks: allMarks,\n legend: {\n ...primaryLayout.legend,\n entries: mergedLegendEntries,\n },\n };\n}\n\n/**\n * Build the primary ChartSpec from all leaves for shared compilation.\n * Unions all data rows across layers so scales see the full domain.\n * Uses the first leaf's mark/encoding as the base, with layer-level chrome.\n */\nfunction buildPrimarySpec(leaves: ChartSpec[], layerSpec: LayerSpec): ChartSpec {\n // Union all data across layers for domain computation\n const allData = leaves.flatMap((leaf) => leaf.data);\n\n const primary = {\n ...leaves[0],\n data: allData,\n // Layer-level chrome overrides leaf chrome\n chrome: layerSpec.chrome ?? leaves[0].chrome,\n labels: layerSpec.labels ?? leaves[0].labels,\n legend: layerSpec.legend ?? leaves[0].legend,\n responsive: layerSpec.responsive ?? leaves[0].responsive,\n theme: layerSpec.theme ?? leaves[0].theme,\n darkMode: layerSpec.darkMode ?? leaves[0].darkMode,\n watermark: layerSpec.watermark ?? leaves[0].watermark,\n hiddenSeries: layerSpec.hiddenSeries ?? leaves[0].hiddenSeries,\n };\n\n return primary;\n}\n\n// ---------------------------------------------------------------------------\n// Table compilation\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a table spec into a TableLayout.\n *\n * Validates and normalizes the spec, resolves the theme, then delegates\n * to compileTableLayout for the full pipeline: column resolution, search,\n * sort, pagination, cell formatting, and visual enhancements.\n *\n * @param spec - Raw table spec.\n * @param options - Compile options with sort, search, pagination state.\n * @returns Fully resolved TableLayout.\n */\nexport function compileTable(spec: unknown, options: CompileTableOptions): TableLayout {\n const { spec: normalized } = compileSpec(spec);\n\n const normType =\n 'type' in normalized ? (normalized as unknown as Record<string, unknown>).type : undefined;\n if (normType !== 'table') {\n throw new Error(`compileTable received a non-table spec. Use compileChart instead.`);\n }\n\n const tableSpec = normalized as NormalizedTableSpec;\n\n // Resolve theme: merge spec-level theme with options-level overrides\n const mergedThemeConfig = options.theme\n ? { ...tableSpec.theme, ...options.theme }\n : tableSpec.theme;\n let theme: ResolvedTheme = resolveTheme(mergedThemeConfig);\n if (options.darkMode) {\n theme = adaptTheme(theme);\n }\n\n // Resolve watermark: spec-level wins, then options, then default true\n const rawWatermark = (spec as Record<string, unknown>).watermark;\n const watermark = rawWatermark !== undefined ? tableSpec.watermark : (options.watermark ?? true);\n\n return compileTableLayout({ ...tableSpec, watermark }, options, theme);\n}\n\n// ---------------------------------------------------------------------------\n// Graph compilation\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a graph spec into a GraphCompilation.\n *\n * The graph pipeline resolves visual properties (size, color, stroke) for\n * nodes and edges, assigns communities, and builds legend/tooltip/a11y data.\n * Unlike charts, the output does NOT include x/y positions since the force\n * simulation in the adapter handles layout at runtime.\n *\n * @param spec - Raw graph spec (validated and normalized internally).\n * @param options - Compile options (width, height, theme, darkMode).\n * @returns GraphCompilation with resolved visual properties and simulation config.\n * @throws Error if spec is invalid or not a graph type.\n */\nexport function compileGraph(spec: unknown, options: CompileOptions): GraphCompilation {\n return compileGraphImpl(spec, options);\n}\n\n// ---------------------------------------------------------------------------\n// Sankey compilation\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a sankey spec into a SankeyLayout.\n *\n * Takes a raw sankey spec, validates, normalizes, resolves theme and chrome,\n * runs the d3-sankey layout algorithm, builds node/link marks with colors and\n * labels, and returns a SankeyLayout ready for rendering.\n *\n * @param spec - Raw sankey spec (validated and normalized internally).\n * @param options - Compile options (width, height, theme, darkMode).\n * @returns SankeyLayout with computed positions and visual properties.\n * @throws Error if spec is invalid or not a sankey type.\n */\nexport function compileSankey(\n spec: unknown,\n options: CompileOptions,\n): import('@opendata-ai/openchart-core').SankeyLayout {\n return compileSankeyImpl(spec, options);\n}\n","/**\n * Collision avoidance for annotations: nudging away from obstacles,\n * resolving annotation-to-annotation overlaps, and clamping to SVG bounds.\n */\n\nimport type {\n Rect,\n ResolvedAnnotation,\n ResolvedLabel,\n TextAnnotation,\n} from '@opendata-ai/openchart-core';\nimport { detectCollision } from '@opendata-ai/openchart-core';\nimport type { NormalizedChartSpec } from '../compiler/types';\nimport type { ResolvedScales } from '../layout/scales';\nimport { CLAMP_MARGIN, NUDGE_PADDING } from './constants';\nimport { estimateLabelBounds, recomputeConnector } from './geometry';\nimport { resolvePosition } from './position';\n\n/**\n * Generate candidate displacement vectors to move `selfBounds` clear of each\n * obstacle in 4 directions (below, above, left, right), sorted by smallest\n * movement first.\n */\nexport function generateNudgeCandidates(\n selfBounds: Rect,\n obstacles: Rect[],\n padding: number,\n): { dx: number; dy: number; distance: number }[] {\n const candidates: { dx: number; dy: number; distance: number }[] = [];\n\n for (const obs of obstacles) {\n // Below: shift self so its top edge clears the obstacle bottom\n const belowDy = obs.y + obs.height + padding - selfBounds.y;\n candidates.push({ dx: 0, dy: belowDy, distance: Math.abs(belowDy) });\n\n // Above: shift self so its bottom edge clears the obstacle top\n const aboveDy = obs.y - padding - (selfBounds.y + selfBounds.height);\n candidates.push({ dx: 0, dy: aboveDy, distance: Math.abs(aboveDy) });\n\n // Left: shift self so its right edge clears the obstacle left\n const leftDx = obs.x - padding - (selfBounds.x + selfBounds.width);\n candidates.push({ dx: leftDx, dy: 0, distance: Math.abs(leftDx) });\n\n // Right: shift self so its left edge clears the obstacle right\n const rightDx = obs.x + obs.width + padding - selfBounds.x;\n candidates.push({ dx: rightDx, dy: 0, distance: Math.abs(rightDx) });\n }\n\n candidates.sort((a, b) => a.distance - b.distance);\n return candidates;\n}\n\n/**\n * Try to reposition a text annotation to avoid overlapping with obstacle rects\n * (legend bounds, etc.). First tries standard anchor alternatives, then\n * calculates specific offsets needed to clear obstacles. Returns true if moved.\n */\nexport function nudgeAnnotationFromObstacles(\n annotation: ResolvedAnnotation,\n originalAnnotation: TextAnnotation,\n scales: ResolvedScales,\n chartArea: Rect,\n obstacles: Rect[],\n): boolean {\n if (annotation.type !== 'text' || !annotation.label) return false;\n\n const labelBounds = estimateLabelBounds(annotation.label);\n const collidingObs = obstacles.filter(\n (obs) => obs.width > 0 && obs.height > 0 && detectCollision(labelBounds, obs),\n );\n\n if (collidingObs.length === 0) return false;\n\n // Resolve the data point pixel position for offset calculations\n const px = resolvePosition(originalAnnotation.x, scales.x);\n const py = resolvePosition(originalAnnotation.y, scales.y);\n if (px === null || py === null) return false;\n\n const candidates = generateNudgeCandidates(labelBounds, collidingObs, NUDGE_PADDING);\n const fontSize = labelBounds.height / Math.max(1, annotation.label.text.split('\\n').length);\n\n for (const { dx, dy } of candidates) {\n const newLabelX = annotation.label.x + dx;\n const newLabelY = annotation.label.y + dy;\n\n const candidateLabel: ResolvedLabel = {\n ...annotation.label,\n x: newLabelX,\n y: newLabelY,\n connector: recomputeConnector({ ...annotation.label, x: newLabelX, y: newLabelY }, px, py),\n };\n\n const candidateBounds = estimateLabelBounds(candidateLabel);\n\n // Check no collisions with any obstacle\n const stillCollides = obstacles.some(\n (obs) => obs.width > 0 && obs.height > 0 && detectCollision(candidateBounds, obs),\n );\n if (stillCollides) continue;\n\n // Annotations render outside the clip path, so they can extend into margins.\n // Only check that the label center is reasonably within the chart and that\n // the text doesn't go completely off-screen.\n const labelCenterX = candidateBounds.x + candidateBounds.width / 2;\n const labelCenterY = candidateBounds.y + candidateBounds.height / 2;\n // Allow nudged labels to extend into the chrome region below the chart\n // (source/footer area) since annotations near the bottom edge often\n // need to shift into that space to avoid marks or the brand watermark.\n const inBounds =\n labelCenterX >= chartArea.x &&\n labelCenterX <= chartArea.x + chartArea.width + 10 &&\n labelCenterY >= chartArea.y - fontSize &&\n labelCenterY <= chartArea.y + chartArea.height + fontSize * 3;\n\n if (inBounds) {\n annotation.label = candidateLabel;\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Resolve collisions between text annotation labels using a greedy algorithm.\n *\n * Iterates through text annotations in order, building a list of \"placed\"\n * bounding rects. When a later annotation overlaps an already-placed one,\n * it tries offset positions (below, above, left, right) to find a\n * non-colliding spot. Recomputes the connector origin after nudging.\n */\nexport function resolveAnnotationCollisions(\n annotations: ResolvedAnnotation[],\n originalSpecs: NormalizedChartSpec['annotations'],\n scales: ResolvedScales,\n chartArea: Rect,\n): void {\n const placedBounds: Rect[] = [];\n\n for (let i = 0; i < annotations.length; i++) {\n const annotation = annotations[i];\n if (annotation.type !== 'text' || !annotation.label) {\n continue;\n }\n\n const bounds = estimateLabelBounds(annotation.label);\n\n // Check against all previously placed annotation labels\n const collidingBounds = placedBounds.filter(\n (pb) => pb.width > 0 && pb.height > 0 && detectCollision(bounds, pb),\n );\n\n if (collidingBounds.length > 0) {\n // Find the original spec to get data point coordinates for connector recomputation\n const originalSpec = originalSpecs[i];\n\n if (originalSpec?.type === 'text') {\n const px = resolvePosition(originalSpec.x, scales.x);\n const py = resolvePosition(originalSpec.y, scales.y);\n\n if (px !== null && py !== null) {\n const candidates = generateNudgeCandidates(bounds, collidingBounds, NUDGE_PADDING);\n const fontSize = bounds.height / Math.max(1, annotation.label.text.split('\\n').length);\n\n for (const { dx, dy } of candidates) {\n const newLabelX = annotation.label.x + dx;\n const newLabelY = annotation.label.y + dy;\n\n const candidateLabel: ResolvedLabel = {\n ...annotation.label,\n x: newLabelX,\n y: newLabelY,\n };\n const candidateBounds = estimateLabelBounds(candidateLabel);\n\n // Check no collisions with any placed label\n const stillCollides = placedBounds.some(\n (pb) => pb.width > 0 && pb.height > 0 && detectCollision(candidateBounds, pb),\n );\n if (stillCollides) continue;\n\n // Check the label center stays reasonably in bounds\n const labelCenterX = candidateBounds.x + candidateBounds.width / 2;\n const labelCenterY = candidateBounds.y + candidateBounds.height / 2;\n const inBounds =\n labelCenterX >= chartArea.x &&\n labelCenterX <= chartArea.x + chartArea.width + 10 &&\n labelCenterY >= chartArea.y - fontSize &&\n labelCenterY <= chartArea.y + chartArea.height + fontSize;\n\n if (inBounds) {\n annotation.label = {\n ...annotation.label,\n x: newLabelX,\n y: newLabelY,\n connector: recomputeConnector(\n { ...annotation.label, x: newLabelX, y: newLabelY },\n px,\n py,\n ),\n };\n break;\n }\n }\n }\n }\n }\n\n // Add this annotation's final bounds to the placed list\n placedBounds.push(estimateLabelBounds(annotation.label));\n }\n}\n\n/**\n * Shift text annotation labels so they stay within the total SVG bounds.\n * If a label overflows the right, left, top, or bottom edge, its position\n * is adjusted inward by the overflow amount. Connector geometry is updated\n * to match.\n */\nexport function clampAnnotationsToBounds(\n annotations: ResolvedAnnotation[],\n svgWidth: number,\n svgHeight: number,\n): void {\n for (const annotation of annotations) {\n if (annotation.type !== 'text' || !annotation.label) continue;\n\n const bounds = estimateLabelBounds(annotation.label);\n let dx = 0;\n let dy = 0;\n\n // Right overflow\n if (bounds.x + bounds.width > svgWidth - CLAMP_MARGIN) {\n dx = svgWidth - CLAMP_MARGIN - (bounds.x + bounds.width);\n }\n // Left overflow\n if (bounds.x + dx < CLAMP_MARGIN) {\n dx = CLAMP_MARGIN - bounds.x;\n }\n // Top overflow\n if (bounds.y < CLAMP_MARGIN) {\n dy = CLAMP_MARGIN - bounds.y;\n }\n // Bottom overflow\n if (bounds.y + bounds.height + dy > svgHeight - CLAMP_MARGIN) {\n dy = svgHeight - CLAMP_MARGIN - (bounds.y + bounds.height);\n }\n\n if (dx === 0 && dy === 0) continue;\n\n const newX = annotation.label.x + dx;\n const newY = annotation.label.y + dy;\n\n const connector = annotation.label.connector;\n annotation.label = {\n ...annotation.label,\n x: newX,\n y: newY,\n connector: connector\n ? recomputeConnector(\n { ...annotation.label, x: newX, y: newY },\n connector.to.x,\n connector.to.y,\n )\n : undefined,\n };\n }\n}\n","/** Default font size for annotation labels. */\nexport const DEFAULT_ANNOTATION_FONT_SIZE = 12;\n\n/** Default font weight for annotation labels. */\nexport const DEFAULT_ANNOTATION_FONT_WEIGHT = 400;\n\n/** Default line height multiplier for annotation text. */\nexport const DEFAULT_LINE_HEIGHT = 1.3;\n\n/** Default fill color for range annotations. */\nexport const DEFAULT_RANGE_FILL = '#f0c040';\n\n/** Default opacity for range annotations. */\nexport const DEFAULT_RANGE_OPACITY = 0.15;\n\n/** Default dash pattern for reference lines. */\nexport const DEFAULT_REFLINE_DASH = '4 3';\n\n// Theme-aware defaults for text and stroke colors\nexport const LIGHT_TEXT_FILL = '#333333';\nexport const DARK_TEXT_FILL = '#d1d5db';\nexport const LIGHT_REFLINE_STROKE = '#888888';\nexport const DARK_REFLINE_STROKE = '#9ca3af';\n\n/** Default label offset when using anchor directions. */\nexport const ANCHOR_OFFSET = 8;\n\n/** Padding between annotation and obstacle when nudging. */\nexport const NUDGE_PADDING = 6;\n\n/** Small inset margin so labels don't touch the SVG edge. */\nexport const CLAMP_MARGIN = 4;\n","/**\n * Geometry utilities for annotation text bounds, connector origins, and offsets.\n */\n\nimport type {\n AnnotationAnchor,\n AnnotationOffset,\n Rect,\n ResolvedLabel,\n} from '@opendata-ai/openchart-core';\nimport { estimateTextWidth } from '@opendata-ai/openchart-core';\nimport {\n ANCHOR_OFFSET,\n DEFAULT_ANNOTATION_FONT_SIZE,\n DEFAULT_ANNOTATION_FONT_WEIGHT,\n DEFAULT_LINE_HEIGHT,\n} from './constants';\n\n/**\n * Compute the bounding box of annotation text at a given label position.\n * Multi-line text is centered at labelX; single-line starts at labelX.\n */\nexport function computeTextBounds(\n labelX: number,\n labelY: number,\n text: string,\n fontSize: number,\n fontWeight: number,\n): Rect {\n const lines = text.split('\\n');\n const isMultiLine = lines.length > 1;\n const maxWidth = Math.max(...lines.map((line) => estimateTextWidth(line, fontSize, fontWeight)));\n const totalHeight = lines.length * fontSize * DEFAULT_LINE_HEIGHT;\n const x = isMultiLine ? labelX - maxWidth / 2 : labelX;\n\n return {\n x,\n y: labelY - fontSize,\n width: maxWidth,\n height: totalHeight,\n };\n}\n\n/**\n * Apply anchor direction to compute label offset from data point.\n * Returns { dx, dy } pixel offsets.\n */\nexport function computeAnchorOffset(\n anchor: AnnotationAnchor | undefined,\n _px: number,\n py: number,\n chartArea: Rect,\n): { dx: number; dy: number } {\n if (!anchor || anchor === 'auto') {\n // Auto: place above if in the lower half, below if upper half\n const isUpperHalf = py < chartArea.y + chartArea.height / 2;\n return isUpperHalf\n ? { dx: ANCHOR_OFFSET, dy: ANCHOR_OFFSET } // below-right\n : { dx: ANCHOR_OFFSET, dy: -ANCHOR_OFFSET }; // above-right\n }\n\n switch (anchor) {\n case 'top':\n return { dx: 0, dy: -ANCHOR_OFFSET };\n case 'bottom':\n return { dx: 0, dy: ANCHOR_OFFSET };\n case 'left':\n return { dx: -ANCHOR_OFFSET, dy: 0 };\n case 'right':\n return { dx: ANCHOR_OFFSET, dy: 0 };\n }\n}\n\n/** Apply user offset on top of computed anchor offset. */\nexport function applyOffset(\n base: { dx: number; dy: number },\n offset: AnnotationOffset | undefined,\n): { dx: number; dy: number } {\n if (!offset) return base;\n return {\n dx: base.dx + (offset.dx ?? 0),\n dy: base.dy + (offset.dy ?? 0),\n };\n}\n\n/**\n * Compute the connector origin point on the text bounding box.\n * For straight connectors, finds the edge midpoint (top, bottom, left, right)\n * closest to the data point. For curve connectors, always uses the right edge.\n */\nexport function computeConnectorOrigin(\n labelX: number,\n labelY: number,\n text: string,\n fontSize: number,\n fontWeight: number,\n targetX: number,\n targetY: number,\n connectorStyle: 'straight' | 'curve',\n): { x: number; y: number } {\n const box = computeTextBounds(labelX, labelY, text, fontSize, fontWeight);\n const boxCenterX = box.x + box.width / 2;\n const boxCenterY = box.y + box.height / 2;\n\n // Curve connectors always start from the right edge\n if (connectorStyle === 'curve') {\n return {\n x: box.x + box.width,\n y: boxCenterY,\n };\n }\n\n // Normalize the vector from box center to target by the box half-dimensions.\n // This accounts for the box aspect ratio: a wide text box should prefer\n // top/bottom exits even when the target is also offset horizontally.\n const halfW = box.width / 2 || 1;\n const halfH = box.height / 2 || 1;\n const ndx = (targetX - boxCenterX) / halfW;\n const ndy = (targetY - boxCenterY) / halfH;\n\n if (Math.abs(ndy) >= Math.abs(ndx)) {\n // Target is more above/below than left/right → use top or bottom edge\n return ndy < 0\n ? { x: boxCenterX, y: box.y } // top\n : { x: boxCenterX, y: box.y + box.height }; // bottom\n }\n // Target is more left/right → use left or right edge\n return ndx < 0\n ? { x: box.x, y: boxCenterY } // left\n : { x: box.x + box.width, y: boxCenterY }; // right\n}\n\n/** Estimate the bounding box of an annotation label. */\nexport function estimateLabelBounds(label: ResolvedLabel): Rect {\n const fontSize = label.style.fontSize ?? DEFAULT_ANNOTATION_FONT_SIZE;\n const fontWeight = label.style.fontWeight ?? DEFAULT_ANNOTATION_FONT_WEIGHT;\n return computeTextBounds(label.x, label.y, label.text, fontSize, fontWeight);\n}\n\n/**\n * Recompute the connector origin for a label after it has been repositioned.\n * Encapsulates the pattern of recalculating which edge of the text box the\n * connector should exit from based on the target data point.\n */\nexport function recomputeConnector(\n label: ResolvedLabel,\n targetX: number,\n targetY: number,\n): ResolvedLabel['connector'] {\n const connector = label.connector;\n if (!connector) return connector;\n\n const fontSize = label.style.fontSize ?? DEFAULT_ANNOTATION_FONT_SIZE;\n const fontWeight = label.style.fontWeight ?? DEFAULT_ANNOTATION_FONT_WEIGHT;\n const connStyle = connector.style === 'curve' ? ('curve' as const) : ('straight' as const);\n const newFrom = computeConnectorOrigin(\n label.x,\n label.y,\n label.text,\n fontSize,\n fontWeight,\n targetX,\n targetY,\n connStyle,\n );\n return { ...connector, from: newFrom };\n}\n","/**\n * Data-coordinate to pixel-coordinate resolution for annotations.\n */\n\nimport type { ScaleBand, ScaleLinear, ScaleTime } from 'd3-scale';\nimport type { ResolvedScales } from '../layout/scales';\n\n/**\n * Interpolate a numeric value between sorted domain entries.\n * Used when an annotation references a value not present in a categorical domain\n * (e.g. \"2008\" on an axis with data points at \"2007\" and \"2009\").\n * Returns null if domain values aren't numeric or the domain is too small.\n */\nexport function interpolateInDomain(\n numValue: number,\n domain: string[],\n positionOf: (entry: string) => number,\n): number | null {\n if (domain.length < 2) return null;\n const nums = domain.map(Number);\n if (!nums.every(Number.isFinite)) return null;\n\n // Sort by numeric value so bracket-finding works regardless of data order\n const sorted = nums.map((n, i) => ({ n, i })).sort((a, b) => a.n - b.n);\n\n // Find the two sorted neighbors that bracket this value\n let lower = 0;\n let upper = sorted.length - 1;\n for (let i = 0; i < sorted.length; i++) {\n if (sorted[i].n <= numValue) lower = i;\n if (sorted[i].n >= numValue) {\n upper = i;\n break;\n }\n }\n\n const lowerPos = positionOf(domain[sorted[lower].i]);\n const upperPos = positionOf(domain[sorted[upper].i]);\n if (lower === upper) return lowerPos;\n const t = (numValue - sorted[lower].n) / (sorted[upper].n - sorted[lower].n);\n return lowerPos + t * (upperPos - lowerPos);\n}\n\n/** Resolve a data value to a pixel position on a given axis. */\nexport function resolvePosition(\n value: string | number,\n scale: ResolvedScales['x'] | ResolvedScales['y'],\n): number | null {\n if (!scale) return null;\n\n const s = scale.scale;\n const type = scale.type;\n\n if (type === 'time') {\n const date = new Date(String(value));\n if (Number.isNaN(date.getTime())) return null;\n return (s as ScaleTime<number, number>)(date);\n }\n\n if (type === 'linear' || type === 'log') {\n const num = typeof value === 'number' ? value : Number(value);\n if (!Number.isFinite(num)) return null;\n return (s as ScaleLinear<number, number>)(num);\n }\n\n if (type === 'band') {\n const bandScale = s as ScaleBand<string>;\n const strValue = String(value);\n const pos = bandScale(strValue);\n if (pos !== undefined) return pos + (bandScale.bandwidth?.() ?? 0) / 2;\n\n const bw = bandScale.bandwidth?.() ?? 0;\n return interpolateInDomain(\n Number(strValue),\n bandScale.domain(),\n (entry) => (bandScale(entry) ?? 0) + bw / 2,\n );\n }\n\n // point or ordinal: try direct lookup, fall back to interpolation\n const strValue = String(value);\n const directResult = (s as (v: string) => number | undefined)(strValue);\n if (directResult !== undefined) return directResult;\n\n if (type === 'point' || type === 'ordinal') {\n const domain = (s as { domain(): string[] }).domain();\n return interpolateInDomain(\n Number(strValue),\n domain,\n (entry) => (s as (v: string) => number)(entry) ?? 0,\n );\n }\n\n return null;\n}\n","/**\n * Text annotation resolver: positions a label at data coordinates with an\n * optional callout connector to the data point.\n */\n\nimport type {\n Rect,\n ResolvedAnnotation,\n ResolvedLabel,\n TextAnnotation,\n TextStyle,\n} from '@opendata-ai/openchart-core';\nimport type { ResolvedScales } from '../layout/scales';\nimport {\n DARK_TEXT_FILL,\n DEFAULT_ANNOTATION_FONT_SIZE,\n DEFAULT_ANNOTATION_FONT_WEIGHT,\n DEFAULT_LINE_HEIGHT,\n LIGHT_TEXT_FILL,\n} from './constants';\nimport { applyOffset, computeAnchorOffset, computeConnectorOrigin } from './geometry';\nimport { resolvePosition } from './position';\n\nexport function makeAnnotationLabelStyle(\n fontSize?: number,\n fontWeight?: number,\n fill?: string,\n isDark?: boolean,\n): TextStyle {\n const defaultFill = isDark ? DARK_TEXT_FILL : LIGHT_TEXT_FILL;\n return {\n fontFamily: 'Inter, system-ui, sans-serif',\n fontSize: fontSize ?? DEFAULT_ANNOTATION_FONT_SIZE,\n fontWeight: fontWeight ?? DEFAULT_ANNOTATION_FONT_WEIGHT,\n fill: fill ?? defaultFill,\n lineHeight: DEFAULT_LINE_HEIGHT,\n textAnchor: 'start',\n };\n}\n\nexport function resolveTextAnnotation(\n annotation: TextAnnotation,\n scales: ResolvedScales,\n chartArea: Rect,\n isDark: boolean,\n): ResolvedAnnotation | null {\n const px = resolvePosition(annotation.x, scales.x);\n const py = resolvePosition(annotation.y, scales.y);\n\n if (px === null || py === null) return null;\n\n const defaultTextFill = isDark ? DARK_TEXT_FILL : LIGHT_TEXT_FILL;\n\n const labelStyle = makeAnnotationLabelStyle(\n annotation.fontSize,\n annotation.fontWeight,\n annotation.fill ?? defaultTextFill,\n isDark,\n );\n\n // Compute position from anchor direction + user offset\n const anchorDelta = computeAnchorOffset(annotation.anchor, px, py, chartArea);\n const finalDelta = applyOffset(anchorDelta, annotation.offset);\n\n const labelX = px + finalDelta.dx;\n const labelY = py + finalDelta.dy;\n\n // Connector: draw unless explicitly disabled\n const showConnector = annotation.connector !== false;\n const connectorStyle = annotation.connector === 'curve' ? 'curve' : 'straight';\n\n // Compute connector origin: pick the edge midpoint closest to the data point\n const fontSize = annotation.fontSize ?? DEFAULT_ANNOTATION_FONT_SIZE;\n const fontWeight = annotation.fontWeight ?? DEFAULT_ANNOTATION_FONT_WEIGHT;\n const { x: connectorFromX, y: connectorFromY } = computeConnectorOrigin(\n labelX,\n labelY,\n annotation.text,\n fontSize,\n fontWeight,\n px,\n py,\n connectorStyle,\n );\n\n // Apply user-provided connector endpoint offsets\n const baseFrom = { x: connectorFromX, y: connectorFromY };\n const baseTo = { x: px, y: py };\n const adjustedFrom = {\n x: baseFrom.x + (annotation.connectorOffset?.from?.dx ?? 0),\n y: baseFrom.y + (annotation.connectorOffset?.from?.dy ?? 0),\n };\n const adjustedToRaw = {\n x: baseTo.x + (annotation.connectorOffset?.to?.dx ?? 0),\n y: baseTo.y + (annotation.connectorOffset?.to?.dy ?? 0),\n };\n\n // Pull the \"to\" endpoint back along the connector direction so the\n // line doesn't touch the data point directly (leaves a small gap).\n const GAP = 4;\n const cdx = adjustedToRaw.x - adjustedFrom.x;\n const cdy = adjustedToRaw.y - adjustedFrom.y;\n const dist = Math.sqrt(cdx * cdx + cdy * cdy);\n const adjustedTo =\n dist > GAP * 2\n ? { x: adjustedToRaw.x - (cdx / dist) * GAP, y: adjustedToRaw.y - (cdy / dist) * GAP }\n : adjustedToRaw;\n\n const label: ResolvedLabel = {\n text: annotation.text,\n x: labelX,\n y: labelY,\n style: labelStyle,\n visible: true,\n connector: showConnector\n ? {\n from: adjustedFrom,\n to: adjustedTo,\n stroke: annotation.stroke ?? '#999999',\n style: connectorStyle,\n }\n : undefined,\n background: annotation.background,\n };\n\n return {\n type: 'text',\n id: annotation.id,\n label,\n stroke: annotation.stroke,\n fill: annotation.fill,\n opacity: annotation.opacity,\n zIndex: annotation.zIndex,\n };\n}\n","/**\n * Range annotation resolver: creates a highlighted rectangular band\n * between two data values on x or y axis.\n */\n\nimport type {\n RangeAnnotation,\n Rect,\n ResolvedAnnotation,\n ResolvedLabel,\n} from '@opendata-ai/openchart-core';\nimport type { ResolvedScales } from '../layout/scales';\nimport { DEFAULT_RANGE_FILL, DEFAULT_RANGE_OPACITY } from './constants';\nimport { applyOffset } from './geometry';\nimport { resolvePosition } from './position';\nimport { makeAnnotationLabelStyle } from './resolve-text';\n\nexport function resolveRangeAnnotation(\n annotation: RangeAnnotation,\n scales: ResolvedScales,\n chartArea: Rect,\n isDark: boolean,\n): ResolvedAnnotation | null {\n let x = chartArea.x;\n let y = chartArea.y;\n let width = chartArea.width;\n let height = chartArea.height;\n\n // X-range (vertical band)\n if (annotation.x1 !== undefined && annotation.x2 !== undefined) {\n const x1px = resolvePosition(annotation.x1, scales.x);\n const x2px = resolvePosition(annotation.x2, scales.x);\n if (x1px === null || x2px === null) return null;\n\n x = Math.min(x1px, x2px);\n width = Math.abs(x2px - x1px);\n }\n\n // Y-range (horizontal band)\n if (annotation.y1 !== undefined && annotation.y2 !== undefined) {\n const y1px = resolvePosition(annotation.y1, scales.y);\n const y2px = resolvePosition(annotation.y2, scales.y);\n if (y1px === null || y2px === null) return null;\n\n y = Math.min(y1px, y2px);\n height = Math.abs(y2px - y1px);\n }\n\n const rect: Rect = { x, y, width, height };\n\n // Label positioned within the range, with optional offset.\n // labelAnchor controls horizontal placement:\n // \"top\" (default): horizontally centered, text-anchor middle\n // \"left\": left edge, text-anchor start\n // \"right\": right edge, text-anchor end\n // \"bottom\"/\"auto\": horizontally centered, text-anchor middle\n let label: ResolvedLabel | undefined;\n if (annotation.label) {\n const anchor = annotation.labelAnchor ?? 'top';\n const centered = anchor === 'top' || anchor === 'bottom' || anchor === 'auto';\n const baseDx = centered ? 0 : anchor === 'right' ? -4 : 4;\n const baseDy = 14;\n const labelDelta = applyOffset({ dx: baseDx, dy: baseDy }, annotation.labelOffset);\n\n const style = makeAnnotationLabelStyle(11, 500, undefined, isDark);\n if (centered) {\n style.textAnchor = 'middle';\n } else if (anchor === 'right') {\n style.textAnchor = 'end';\n }\n\n // Position label horizontally centered within the range band by default.\n // For left/right anchors, position at the respective edge.\n const baseX = centered ? x + width / 2 : anchor === 'right' ? x + width : x;\n\n label = {\n text: annotation.label,\n x: baseX + labelDelta.dx,\n y: y + labelDelta.dy,\n style,\n visible: true,\n };\n }\n\n // In dark mode, boost range opacity slightly for better visibility\n const defaultOpacity = isDark ? 0.2 : DEFAULT_RANGE_OPACITY;\n\n return {\n type: 'range',\n id: annotation.id,\n rect,\n label,\n fill: annotation.fill ?? DEFAULT_RANGE_FILL,\n opacity: annotation.opacity ?? defaultOpacity,\n stroke: annotation.stroke,\n zIndex: annotation.zIndex,\n };\n}\n","/**\n * Reference line annotation resolver: creates a horizontal or vertical\n * reference line at a data value with optional label.\n */\n\nimport type {\n Point,\n Rect,\n RefLineAnnotation,\n ResolvedAnnotation,\n ResolvedLabel,\n} from '@opendata-ai/openchart-core';\nimport type { ResolvedScales } from '../layout/scales';\nimport { DARK_REFLINE_STROKE, DEFAULT_REFLINE_DASH, LIGHT_REFLINE_STROKE } from './constants';\nimport { applyOffset } from './geometry';\nimport { resolvePosition } from './position';\nimport { makeAnnotationLabelStyle } from './resolve-text';\n\nexport function resolveRefLineAnnotation(\n annotation: RefLineAnnotation,\n scales: ResolvedScales,\n chartArea: Rect,\n isDark: boolean,\n): ResolvedAnnotation | null {\n let start: Point;\n let end: Point;\n\n if (annotation.y !== undefined) {\n // Horizontal reference line\n const yPx = resolvePosition(annotation.y, scales.y);\n if (yPx === null) return null;\n\n start = { x: chartArea.x, y: yPx };\n end = { x: chartArea.x + chartArea.width, y: yPx };\n } else if (annotation.x !== undefined) {\n // Vertical reference line\n const xPx = resolvePosition(annotation.x, scales.x);\n if (xPx === null) return null;\n\n start = { x: xPx, y: chartArea.y };\n end = { x: xPx, y: chartArea.y + chartArea.height };\n } else {\n return null;\n }\n\n // Determine dash pattern from style\n let strokeDasharray: string | undefined;\n if (annotation.style === 'dashed' || annotation.style === undefined) {\n strokeDasharray = DEFAULT_REFLINE_DASH;\n } else if (annotation.style === 'dotted') {\n strokeDasharray = '2 2';\n }\n // 'solid' gets no dasharray\n\n // Label placement on reflines. labelAnchor controls position:\n //\n // Horizontal reflines (y set):\n // \"left\": left end of line, above \"right\"/\"top\" (default): right end, above\n // \"bottom\": right end of line, below\n //\n // Vertical reflines (x set):\n // \"right\": label to the left of the line, near top\n // \"bottom\": label to the right of the line, near bottom\n // \"left\"/\"top\" (default): label to the right of the line, near top\n let label: ResolvedLabel | undefined;\n if (annotation.label) {\n const isHorizontal = annotation.y !== undefined;\n const anchor = annotation.labelAnchor ?? (isHorizontal ? 'top' : 'left');\n\n let baseDx: number;\n let baseDy: number;\n let labelX: number;\n let labelY: number;\n let textAnchor: 'start' | 'middle' | 'end';\n\n if (isHorizontal) {\n if (anchor === 'left') {\n baseDx = 4;\n baseDy = -4;\n labelX = start.x;\n labelY = start.y;\n textAnchor = 'start';\n } else if (anchor === 'bottom') {\n baseDx = -4;\n baseDy = 14;\n labelX = end.x;\n labelY = end.y;\n textAnchor = 'end';\n } else {\n // 'right', 'top' (default), 'auto'\n baseDx = -4;\n baseDy = -4;\n labelX = end.x;\n labelY = end.y;\n textAnchor = 'end';\n }\n } else {\n // Vertical refline\n if (anchor === 'right') {\n baseDx = -4;\n baseDy = 14;\n labelX = start.x;\n labelY = start.y;\n textAnchor = 'end';\n } else if (anchor === 'bottom') {\n baseDx = 4;\n baseDy = -4;\n labelX = start.x;\n labelY = end.y;\n textAnchor = 'start';\n } else {\n // 'left', 'top' (default), 'auto' — label to the right of the line, near top\n baseDx = 4;\n baseDy = 14;\n labelX = start.x;\n labelY = start.y;\n textAnchor = 'start';\n }\n }\n\n const labelDelta = applyOffset({ dx: baseDx, dy: baseDy }, annotation.labelOffset);\n\n const defaultStroke = isDark ? DARK_REFLINE_STROKE : LIGHT_REFLINE_STROKE;\n const style = makeAnnotationLabelStyle(11, 400, annotation.stroke ?? defaultStroke, isDark);\n style.textAnchor = textAnchor;\n\n label = {\n text: annotation.label,\n x: labelX + labelDelta.dx,\n y: labelY + labelDelta.dy,\n style,\n visible: true,\n };\n }\n\n const defaultStroke = isDark ? DARK_REFLINE_STROKE : LIGHT_REFLINE_STROKE;\n\n return {\n type: 'refline',\n id: annotation.id,\n line: { start, end },\n label,\n stroke: annotation.stroke ?? defaultStroke,\n strokeDasharray,\n strokeWidth: annotation.strokeWidth ?? 1,\n zIndex: annotation.zIndex,\n };\n}\n","/**\n * Annotation computation: converts spec-level annotations to pixel-positioned\n * ResolvedAnnotation objects using the resolved scales.\n *\n * Handles three annotation types:\n * - text: positioned at a data coordinate with an optional callout\n * - range: a highlighted rectangle between two data values\n * - refline: a horizontal or vertical reference line at a data value\n *\n * Supports fine-grained positioning via offset, anchor, connector, and zIndex.\n * At compact breakpoints, annotations are simplified or hidden.\n */\n\nimport type { LayoutStrategy, Rect, ResolvedAnnotation } from '@opendata-ai/openchart-core';\nimport type { NormalizedChartSpec } from '../compiler/types';\nimport type { ResolvedScales } from '../layout/scales';\nimport {\n clampAnnotationsToBounds,\n nudgeAnnotationFromObstacles,\n resolveAnnotationCollisions,\n} from './collisions';\nimport { resolveRangeAnnotation } from './resolve-range';\nimport { resolveRefLineAnnotation } from './resolve-refline';\nimport { resolveTextAnnotation } from './resolve-text';\n\n/**\n * Compute resolved annotations from spec annotations using the resolved scales.\n *\n * Converts data-coordinate annotations to pixel-positioned ResolvedAnnotation\n * objects. Supports offset, anchor, connector, and zIndex. At compact\n * breakpoints, annotations are hidden (strategy says \"tooltip-only\").\n *\n * When obstacle rects are provided (e.g. legend bounds), text annotations\n * that overlap with them are automatically repositioned using alternate\n * anchor directions. After individual obstacle avoidance, annotation-to-\n * annotation collisions are resolved using a greedy placement algorithm.\n * Finally, labels are clamped to stay within the total SVG bounds.\n */\nexport function computeAnnotations(\n spec: NormalizedChartSpec,\n scales: ResolvedScales,\n chartArea: Rect,\n strategy: LayoutStrategy,\n isDark = false,\n obstacles: Rect[] = [],\n svgDimensions?: { width: number; height: number },\n): ResolvedAnnotation[] {\n // At compact breakpoints, skip all annotations\n if (strategy.annotationPosition === 'tooltip-only') {\n return [];\n }\n\n const annotations: ResolvedAnnotation[] = [];\n\n for (const annotation of spec.annotations) {\n let resolved: ResolvedAnnotation | null = null;\n\n switch (annotation.type) {\n case 'text':\n resolved = resolveTextAnnotation(annotation, scales, chartArea, isDark);\n break;\n case 'range':\n resolved = resolveRangeAnnotation(annotation, scales, chartArea, isDark);\n break;\n case 'refline':\n resolved = resolveRefLineAnnotation(annotation, scales, chartArea, isDark);\n break;\n }\n\n if (resolved) {\n // For text annotations, check for collisions with obstacles and nudge if needed\n if (annotation.type === 'text' && obstacles.length > 0) {\n nudgeAnnotationFromObstacles(resolved, annotation, scales, chartArea, obstacles);\n }\n annotations.push(resolved);\n }\n }\n\n // Resolve annotation-to-annotation collisions (greedy, order-preserving)\n resolveAnnotationCollisions(annotations, spec.annotations, scales, chartArea);\n\n // Clamp labels that overflow the SVG boundary back inside\n if (svgDimensions) {\n clampAnnotationsToBounds(annotations, svgDimensions.width, svgDimensions.height);\n }\n\n // Sort by zIndex (lower first, undefined treated as 0)\n annotations.sort((a, b) => (a.zIndex ?? 0) - (b.zIndex ?? 0));\n\n return annotations;\n}\n","/**\n * Bar chart (horizontal) mark computation.\n *\n * Takes a normalized chart spec with resolved scales and produces\n * RectMark[] for rendering horizontal bars. Supports grouped and\n * stacked variants via the color encoding channel.\n */\n\nimport type {\n ConditionalValueDef,\n DataRow,\n Encoding,\n GradientDef,\n LayoutStrategy,\n LinearGradient,\n MarkAria,\n Rect,\n RectMark,\n} from '@opendata-ai/openchart-core';\nimport { isGradientDef } from '@opendata-ai/openchart-core';\nimport type { ScaleBand, ScaleLinear } from 'd3-scale';\nimport type { NormalizedChartSpec } from '../../compiler/types';\nimport type { ResolvedScales } from '../../layout/scales';\nimport { isConditionalValueDef, resolveConditionalValue } from '../../transforms/conditional';\nimport { formatLabelValue } from '../_shared/format-label-value';\nimport { getColor, getSequentialColor, groupByField } from '../utils';\n\n/**\n * Auto-orient a gradient for horizontal bars.\n *\n * If the gradient uses the default top-to-bottom direction (no explicit\n * x1/y1/x2/y2, or the defaults x1:0, y1:0, x2:0, y2:1), rotate it to\n * left-to-right so the gradient follows the bar's data direction.\n *\n * Gradients with explicit non-default coordinates are left unchanged.\n */\nfunction orientGradientForHorizontalBar(grad: GradientDef): GradientDef {\n if (grad.gradient !== 'linear') return grad;\n const lg = grad as LinearGradient;\n // Only auto-orient if using the default vertical direction.\n // Default is x1:0, y1:0, x2:0, y2:1 (top-to-bottom).\n const isDefaultVertical =\n (lg.x1 === undefined || lg.x1 === 0) &&\n (lg.y1 === undefined || lg.y1 === 0) &&\n (lg.x2 === undefined || lg.x2 === 0) &&\n (lg.y2 === undefined || lg.y2 === 1);\n if (!isDefaultVertical) return grad;\n return { ...lg, x1: 0, y1: 0, x2: 1, y2: 0 };\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst MIN_BAR_WIDTH = 1;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute horizontal bar marks from a normalized chart spec.\n *\n * Y axis uses a band scale for categories. X axis uses a linear scale\n * for values. When a color encoding is present, bars within each category\n * are grouped (subdivided bands) or stacked (cumulative widths).\n */\nexport function computeBarMarks(\n spec: NormalizedChartSpec,\n scales: ResolvedScales,\n _chartArea: Rect,\n _strategy: LayoutStrategy,\n): RectMark[] {\n const encoding = spec.encoding as Encoding;\n const xChannel = encoding.x;\n const yChannel = encoding.y;\n\n if (!xChannel || !yChannel || !scales.x || !scales.y) {\n return [];\n }\n\n const yScale = scales.y.scale as ScaleBand<string>;\n const xScale = scales.x.scale as ScaleLinear<number, number>;\n\n // Band scale should provide bandwidth\n if (typeof yScale.bandwidth !== 'function') {\n return [];\n }\n\n const bandwidth = yScale.bandwidth();\n const baseline = xScale(0);\n const colorEnc = encoding.color && 'field' in encoding.color ? encoding.color : undefined;\n const conditionalColor =\n encoding.color && isConditionalValueDef(encoding.color)\n ? (encoding.color as ConditionalValueDef)\n : undefined;\n const colorField = colorEnc?.field;\n const isSequentialColor = colorEnc?.type === 'quantitative';\n\n // If no color encoding, or sequential color (value-based gradient), render simple bars\n if (!colorField || isSequentialColor) {\n return computeSimpleBars(\n spec.data,\n xChannel.field,\n yChannel.field,\n xScale,\n yScale,\n bandwidth,\n baseline,\n scales,\n isSequentialColor,\n conditionalColor,\n );\n }\n\n // Color encoding present: decide between colored simple bars vs stacked\n const categoryGroups = groupByField(spec.data, yChannel.field);\n const needsStacking = Array.from(categoryGroups.values()).some((rows) => rows.length > 1);\n\n if (needsStacking) {\n const stackDisabled = xChannel.stack === null || xChannel.stack === false;\n\n if (stackDisabled) {\n return computeGroupedBars(\n spec.data,\n xChannel.field,\n yChannel.field,\n colorField,\n xScale,\n yScale,\n bandwidth,\n baseline,\n scales,\n );\n }\n\n const stackMode =\n xChannel.stack === 'normalize'\n ? 'normalize'\n : xChannel.stack === 'center'\n ? 'center'\n : 'zero';\n\n return computeStackedBars(\n spec.data,\n xChannel.field,\n yChannel.field,\n colorField,\n xScale,\n yScale,\n bandwidth,\n baseline,\n scales,\n stackMode,\n );\n }\n\n // Single row per category: render like simple bars but with color from scale\n return computeColoredBars(\n spec.data,\n xChannel.field,\n yChannel.field,\n colorField,\n xScale,\n yScale,\n bandwidth,\n baseline,\n scales,\n );\n}\n\n/** Compute stacked horizontal bars with support for zero/normalize/center modes. */\nfunction computeStackedBars(\n data: DataRow[],\n valueField: string,\n categoryField: string,\n colorField: string,\n xScale: ScaleLinear<number, number>,\n yScale: ScaleBand<string>,\n bandwidth: number,\n _baseline: number,\n scales: ResolvedScales,\n stackMode: 'zero' | 'normalize' | 'center' = 'zero',\n): RectMark[] {\n const marks: RectMark[] = [];\n const categoryGroups = groupByField(data, categoryField);\n\n for (const [category, rows] of categoryGroups) {\n const bandY = yScale(category);\n if (bandY === undefined) continue;\n\n // Compute category total for normalize/center modes\n let categoryTotal = 0;\n for (const row of rows) {\n const v = Number(row[valueField] ?? 0);\n if (Number.isFinite(v) && v > 0) categoryTotal += v;\n }\n\n // For center mode, offset so the stack is centered around zero\n let cumulativeValue = stackMode === 'center' ? -categoryTotal / 2 : 0;\n\n for (const row of rows) {\n const groupKey = String(row[colorField] ?? '');\n const rawValue = Number(row[valueField] ?? 0);\n // Only stack positive values (same approach as stacked columns)\n if (!Number.isFinite(rawValue) || rawValue <= 0) continue;\n\n // For normalize mode, scale the value to a fraction of the total\n const value =\n stackMode === 'normalize' && categoryTotal > 0 ? rawValue / categoryTotal : rawValue;\n\n const color = getColor(scales, groupKey);\n\n const xLeft = xScale(cumulativeValue);\n const xRight = xScale(cumulativeValue + value);\n const barWidth = Math.max(Math.abs(xRight - xLeft), MIN_BAR_WIDTH);\n\n const aria: MarkAria = {\n label: `${category}, ${groupKey}: ${formatLabelValue(rawValue)}`,\n };\n\n marks.push({\n type: 'rect',\n x: Math.min(xLeft, xRight),\n y: bandY,\n width: barWidth,\n height: bandwidth,\n fill: isGradientDef(color) ? orientGradientForHorizontalBar(color) : color,\n cornerRadius: 0,\n data: row as Record<string, unknown>,\n aria,\n orient: 'horizontal',\n stackGroup: category,\n });\n\n cumulativeValue += value;\n }\n }\n\n return marks;\n}\n\n/** Compute grouped (dodged) horizontal bars -- side-by-side within each category band. */\nfunction computeGroupedBars(\n data: DataRow[],\n valueField: string,\n categoryField: string,\n colorField: string,\n xScale: ScaleLinear<number, number>,\n yScale: ScaleBand<string>,\n bandwidth: number,\n baseline: number,\n scales: ResolvedScales,\n): RectMark[] {\n const marks: RectMark[] = [];\n const categoryGroups = groupByField(data, categoryField);\n\n // Build a stable group order from first appearance in data (Map for O(1) lookup)\n const groupIndexMap = new Map<string, number>();\n for (const row of data) {\n const key = String(row[colorField] ?? '');\n if (!groupIndexMap.has(key)) {\n groupIndexMap.set(key, groupIndexMap.size);\n }\n }\n const groupCount = groupIndexMap.size;\n if (groupCount === 0) return marks;\n\n // Subdivide the band height by group count with a small gap\n const gap = Math.min(1, bandwidth * 0.05);\n const subBandHeight = Math.max((bandwidth - gap * (groupCount - 1)) / groupCount, MIN_BAR_WIDTH);\n\n for (const [category, rows] of categoryGroups) {\n const bandY = yScale(category);\n if (bandY === undefined) continue;\n\n for (const row of rows) {\n const groupKey = String(row[colorField] ?? '');\n const value = Number(row[valueField] ?? 0);\n if (!Number.isFinite(value)) continue;\n\n const groupIndex = groupIndexMap.get(groupKey) ?? 0;\n const color = getColor(scales, groupKey);\n const xPos = value >= 0 ? baseline : xScale(value);\n const barWidth = Math.max(Math.abs(xScale(value) - baseline), MIN_BAR_WIDTH);\n const subY = bandY + groupIndex * (subBandHeight + gap);\n\n const aria: MarkAria = {\n label: `${category}, ${groupKey}: ${formatLabelValue(value)}`,\n };\n\n marks.push({\n type: 'rect',\n x: xPos,\n y: subY,\n width: barWidth,\n height: subBandHeight,\n fill: isGradientDef(color) ? orientGradientForHorizontalBar(color) : color,\n cornerRadius: 2,\n data: row as Record<string, unknown>,\n aria,\n orient: 'horizontal',\n });\n }\n }\n\n return marks;\n}\n\n/** Compute colored (non-stacked) horizontal bars. Used when color encoding\n * is present but each category has only one row (e.g., diverging charts). */\nfunction computeColoredBars(\n data: DataRow[],\n valueField: string,\n categoryField: string,\n colorField: string,\n xScale: ScaleLinear<number, number>,\n yScale: ScaleBand<string>,\n bandwidth: number,\n baseline: number,\n scales: ResolvedScales,\n): RectMark[] {\n const marks: RectMark[] = [];\n\n for (const row of data) {\n const category = String(row[categoryField] ?? '');\n const value = Number(row[valueField] ?? 0);\n if (!Number.isFinite(value)) continue;\n\n const bandY = yScale(category);\n if (bandY === undefined) continue;\n\n const groupKey = String(row[colorField] ?? '');\n const color = getColor(scales, groupKey);\n const xPos = value >= 0 ? baseline : xScale(value);\n const barWidth = Math.max(Math.abs(xScale(value) - baseline), MIN_BAR_WIDTH);\n\n const aria: MarkAria = {\n label: `${category}, ${groupKey}: ${formatLabelValue(value)}`,\n };\n\n marks.push({\n type: 'rect',\n x: xPos,\n y: bandY,\n width: barWidth,\n height: bandwidth,\n fill: isGradientDef(color) ? orientGradientForHorizontalBar(color) : color,\n cornerRadius: 2,\n data: row as Record<string, unknown>,\n aria,\n orient: 'horizontal',\n });\n }\n\n return marks;\n}\n\n/** Compute simple (non-grouped) horizontal bars. */\nfunction computeSimpleBars(\n data: DataRow[],\n valueField: string,\n categoryField: string,\n xScale: ScaleLinear<number, number>,\n yScale: ScaleBand<string>,\n bandwidth: number,\n baseline: number,\n scales: ResolvedScales,\n sequentialColor = false,\n conditionalColor?: ConditionalValueDef,\n): RectMark[] {\n const marks: RectMark[] = [];\n\n for (const row of data) {\n const category = String(row[categoryField] ?? '');\n const value = Number(row[valueField] ?? 0);\n if (!Number.isFinite(value)) continue;\n\n const bandY = yScale(category);\n if (bandY === undefined) continue;\n\n let color: string | GradientDef;\n if (conditionalColor) {\n const resolved = resolveConditionalValue(row, conditionalColor);\n if (resolved != null) {\n color = isGradientDef(resolved) ? resolved : String(resolved);\n } else {\n color = getColor(scales, '__default__');\n }\n } else if (sequentialColor) {\n color = getSequentialColor(scales, value);\n } else {\n color = getColor(scales, '__default__');\n }\n const xPos = value >= 0 ? baseline : xScale(value);\n const barWidth = Math.max(Math.abs(xScale(value) - baseline), MIN_BAR_WIDTH);\n\n const aria: MarkAria = {\n label: `${category}: ${formatLabelValue(value)}`,\n };\n\n marks.push({\n type: 'rect',\n x: xPos,\n y: bandY,\n width: barWidth,\n height: bandwidth,\n fill: isGradientDef(color) ? orientGradientForHorizontalBar(color) : color,\n cornerRadius: 2,\n data: row as Record<string, unknown>,\n aria,\n orient: 'horizontal',\n });\n }\n\n return marks;\n}\n","/**\n * Predicate evaluation for filter transforms and conditional encoding.\n *\n * Supports field predicates (equal, lt, gt, range, oneOf, valid)\n * and logical combinators (and, or, not).\n */\n\nimport type { DataRow, FieldPredicate, FilterPredicate } from '@opendata-ai/openchart-core';\n\n/**\n * Check if a predicate is a FieldPredicate (has a 'field' property).\n */\nfunction isFieldPredicate(pred: FilterPredicate): pred is FieldPredicate {\n return 'field' in pred;\n}\n\n/**\n * Evaluate a single field predicate against a datum.\n */\nfunction evaluateFieldPredicate(datum: DataRow, pred: FieldPredicate): boolean {\n const value = datum[pred.field];\n\n // valid: check for non-null, non-undefined, non-NaN\n if (pred.valid !== undefined) {\n const isValid = value !== null && value !== undefined && !Number.isNaN(value);\n return pred.valid ? isValid : !isValid;\n }\n\n // equal: use loose equality so \"181\" == 181 matches across type boundaries\n // (data values may arrive as strings from CSV/JSON parsing)\n if (pred.equal !== undefined) {\n // biome-ignore lint/suspicious/noDoubleEquals: intentional loose equality for CSV/JSON type coercion\n return value == pred.equal;\n }\n\n // Numeric comparisons\n const numValue = Number(value);\n\n if (pred.lt !== undefined) {\n return numValue < pred.lt;\n }\n if (pred.lte !== undefined) {\n return numValue <= pred.lte;\n }\n if (pred.gt !== undefined) {\n return numValue > pred.gt;\n }\n if (pred.gte !== undefined) {\n return numValue >= pred.gte;\n }\n\n // range: inclusive [min, max]\n if (pred.range !== undefined) {\n const [min, max] = pred.range;\n return numValue >= min && numValue <= max;\n }\n\n // oneOf: use loose equality (same rationale as equal above)\n if (pred.oneOf !== undefined) {\n // biome-ignore lint/suspicious/noDoubleEquals: intentional loose equality for CSV/JSON type coercion\n return pred.oneOf.some((v) => v == value);\n }\n\n // No condition specified, default to true\n return true;\n}\n\n/**\n * Evaluate a filter predicate (field predicate or logical combinator) against a datum.\n *\n * @param datum - The data row to test.\n * @param predicate - The filter predicate to evaluate.\n * @returns Whether the datum passes the predicate.\n */\nexport function evaluatePredicate(datum: DataRow, predicate: FilterPredicate): boolean {\n if (isFieldPredicate(predicate)) {\n return evaluateFieldPredicate(datum, predicate);\n }\n\n if ('and' in predicate) {\n return predicate.and.every((p) => evaluatePredicate(datum, p));\n }\n\n if ('or' in predicate) {\n return predicate.or.some((p) => evaluatePredicate(datum, p));\n }\n\n if ('not' in predicate) {\n return !evaluatePredicate(datum, predicate.not);\n }\n\n return true;\n}\n","/**\n * Conditional encoding evaluation.\n *\n * Resolves conditional value definitions per-datum by evaluating\n * predicates and returning the first matching condition's value.\n */\n\nimport type { ConditionalValueDef, DataRow } from '@opendata-ai/openchart-core';\nimport { evaluatePredicate } from './predicates';\n\n/**\n * Resolve a conditional value definition for a datum.\n *\n * Evaluates conditions in order, returning the value from the first\n * condition whose test passes. Falls back to the default value if\n * no condition matches.\n *\n * @param datum - The data row to evaluate against.\n * @param channelDef - The conditional value definition.\n * @returns The resolved value, or undefined if no condition matches and no default.\n */\nexport function resolveConditionalValue(datum: DataRow, channelDef: ConditionalValueDef): unknown {\n const conditions = Array.isArray(channelDef.condition)\n ? channelDef.condition\n : [channelDef.condition];\n\n for (const cond of conditions) {\n if (evaluatePredicate(datum, cond.test)) {\n // If the condition specifies a field, return the datum's field value\n if (cond.field !== undefined) {\n return datum[cond.field];\n }\n return cond.value;\n }\n }\n\n // No condition matched, return default\n return channelDef.value;\n}\n\n/**\n * Check if a channel definition is a ConditionalValueDef.\n */\nexport function isConditionalValueDef(def: unknown): def is ConditionalValueDef {\n return def !== null && typeof def === 'object' && 'condition' in (def as Record<string, unknown>);\n}\n","/**\n * Shared numeric value formatter for data labels.\n *\n * Used by bar, column, and dot label computation to display a value:\n * abbreviated (K/M/B/T) for magnitudes >= 1000, otherwise the default\n * numeric format.\n */\n\nimport { abbreviateNumber, formatNumber } from '@opendata-ai/openchart-core';\n\n/** Format a label value for display (abbreviate large numbers). */\nexport function formatLabelValue(value: number): string {\n if (Math.abs(value) >= 1000) return abbreviateNumber(value);\n return formatNumber(value);\n}\n","/**\n * Shared utilities for chart mark computation.\n *\n * Common helpers used across multiple chart types: scale value resolution,\n * data grouping, color lookup, and shared constants.\n */\n\nimport type { DataRow, GradientDef } from '@opendata-ai/openchart-core';\nimport type { ScaleBand, ScaleLinear, ScalePoint, ScaleTime } from 'd3-scale';\nimport type { D3Scale, ResolvedScales } from '../layout/scales';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Default single-series color when no color encoding is present. */\nexport const DEFAULT_COLOR = '#1b7fa3';\n\n// ---------------------------------------------------------------------------\n// Scale helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a data value to a pixel position using a D3 scale.\n *\n * Handles time scales (parsing string dates), categorical scales\n * (point, band, ordinal - passing string values directly), and\n * linear/log scales (coercing to number). Returns null for values\n * that can't be resolved (null, NaN, invalid dates, or values not\n * in a categorical scale's domain).\n */\nexport function scaleValue(scale: D3Scale, scaleType: string, value: unknown): number | null {\n if (value == null) return null;\n\n if (scaleType === 'time' || scaleType === 'utc') {\n const date = value instanceof Date ? value : new Date(String(value));\n if (Number.isNaN(date.getTime())) return null;\n return (scale as ScaleTime<number, number>)(date);\n }\n\n // Categorical scales: pass string values directly\n if (scaleType === 'point' || scaleType === 'band' || scaleType === 'ordinal') {\n const result = (scale as ScalePoint<string> | ScaleBand<string>)(String(value));\n return result ?? null;\n }\n\n const num = typeof value === 'number' ? value : Number(value);\n if (!Number.isFinite(num)) return null;\n return (scale as ScaleLinear<number, number>)(num);\n}\n\n// ---------------------------------------------------------------------------\n// Data grouping\n// ---------------------------------------------------------------------------\n\n/**\n * Group data rows by a field value.\n *\n * If no field is provided, all rows are grouped under '__default__'.\n * Returns a Map preserving insertion order.\n */\nexport function groupByField(data: DataRow[], field: string | undefined): Map<string, DataRow[]> {\n const groups = new Map<string, DataRow[]>();\n\n if (!field) {\n groups.set('__default__', data);\n return groups;\n }\n\n for (const row of data) {\n const key = String(row[field] ?? '__default__');\n const existing = groups.get(key);\n if (existing) {\n existing.push(row);\n } else {\n groups.set(key, [row]);\n }\n }\n\n return groups;\n}\n\n// ---------------------------------------------------------------------------\n// Sorting\n// ---------------------------------------------------------------------------\n\n/**\n * Sort data rows by a field value in ascending order.\n *\n * Type-aware: numbers compared numerically, Date objects by timestamp,\n * string-encoded numbers parsed and compared numerically, and everything\n * else compared lexicographically (which also handles ISO date strings).\n * Nulls are sorted last. Returns a new array (no mutation).\n */\nexport function sortByField(data: DataRow[], field: string): DataRow[] {\n if (data.length <= 1) return [...data];\n\n return [...data].sort((a, b) => {\n const aVal = a[field];\n const bVal = b[field];\n\n // Nulls last\n if (aVal == null && bVal == null) return 0;\n if (aVal == null) return 1;\n if (bVal == null) return -1;\n\n // Both numbers\n if (typeof aVal === 'number' && typeof bVal === 'number') {\n return aVal - bVal;\n }\n\n // Both Dates\n if (aVal instanceof Date && bVal instanceof Date) {\n return aVal.getTime() - bVal.getTime();\n }\n\n // String values: try numeric parse, then lexicographic\n const aStr = String(aVal);\n const bStr = String(bVal);\n\n const aNum = Number(aStr);\n const bNum = Number(bStr);\n if (Number.isFinite(aNum) && Number.isFinite(bNum)) {\n return aNum - bNum;\n }\n\n return aStr.localeCompare(bStr);\n });\n}\n\n// ---------------------------------------------------------------------------\n// Color helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Get the color for a series/category from the resolved color scale.\n *\n * For single-series charts (key === '__default__'), uses the theme's\n * first categorical color via scales.defaultColor.\n */\nexport function getColor(\n scales: ResolvedScales,\n key: string,\n _index?: number,\n fallback: string = DEFAULT_COLOR,\n): string | GradientDef {\n if (scales.color && key !== '__default__') {\n const colorScale = scales.color.scale as (v: string) => string;\n return colorScale(key);\n }\n return scales.defaultColor ?? fallback;\n}\n\n/**\n * Get color from a sequential (quantitative) color scale.\n * Maps a numeric value to a color via linear interpolation.\n */\nexport function getSequentialColor(\n scales: ResolvedScales,\n value: number,\n fallback: string = DEFAULT_COLOR,\n): string | GradientDef {\n if (scales.color?.type === 'sequential') {\n const colorScale = scales.color.scale as unknown as (v: number) => string;\n return colorScale(value);\n }\n return scales.defaultColor ?? fallback;\n}\n","/**\n * Bar chart label computation.\n *\n * Produces value labels for horizontal bars, positioned inside the bar\n * if the bar is wide enough, or outside (to the right) otherwise.\n *\n * Respects the spec's label density setting:\n * - 'all': show every label, skip collision detection\n * - 'auto': existing behavior (collision detection)\n * - 'endpoints': first and last bars only\n * - 'none': return empty array\n */\n\nimport type {\n LabelCandidate,\n LabelDensity,\n RectMark,\n ResolvedLabel,\n} from '@opendata-ai/openchart-core';\nimport {\n buildD3Formatter,\n estimateTextWidth,\n getRepresentativeColor,\n resolveCollisions,\n} from '@opendata-ai/openchart-core';\nimport { filterByDensity } from '../_shared/density-filter';\nimport { formatLabelValue } from '../_shared/format-label-value';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Suffix multipliers mirroring core's abbreviateNumber output (K/M/B/T). */\nconst SUFFIX_MULTIPLIERS: Record<string, number> = {\n K: 1_000,\n M: 1_000_000,\n B: 1_000_000_000,\n T: 1_000_000_000_000,\n};\n\n/**\n * Parse a numeric string that may include comma separators and/or a\n * K/M/B/T abbreviation suffix (as produced by `abbreviateNumber`).\n * Returns NaN when the string cannot be parsed.\n */\nfunction parseDisplayNumber(raw: string): number {\n // Normalize Unicode minus (U+2212, produced by d3-format) to ASCII hyphen-minus\n const trimmed = raw.trim().replace(/\\u2212/g, '-');\n if (!trimmed) return NaN;\n\n // Check for trailing abbreviation suffix (case-insensitive)\n const last = trimmed[trimmed.length - 1].toUpperCase();\n const multiplier = SUFFIX_MULTIPLIERS[last];\n if (multiplier) {\n const numPart = trimmed.slice(0, -1).replace(/,/g, '');\n const n = Number(numPart);\n return Number.isNaN(n) ? NaN : n * multiplier;\n }\n\n // Strip literal % suffix (e.g., from \"+.0f%\" d3-format strings)\n if (last === '%') {\n return Number(trimmed.slice(0, -1).replace(/,/g, ''));\n }\n\n // No suffix — strip commas and parse\n return Number(trimmed.replace(/,/g, ''));\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst LABEL_FONT_SIZE = 11;\nconst LABEL_FONT_WEIGHT = 600;\nconst LABEL_PADDING = 6;\nconst MIN_WIDTH_FOR_INSIDE_LABEL = 40;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute value labels for bar marks.\n *\n * For each bar, the value from the data is formatted and placed either\n * inside the bar (right-aligned) if the bar is wide enough, or just\n * outside the bar's right edge.\n */\nexport function computeBarLabels(\n marks: RectMark[],\n _chartArea: { x: number; y: number; width: number; height: number },\n density: LabelDensity = 'auto',\n labelFormat?: string,\n labelPrefix?: string,\n valueField?: string,\n): ResolvedLabel[] {\n const targetMarks = filterByDensity(marks, density);\n\n const candidates: LabelCandidate[] = [];\n // Track whether each candidate fits within its stacked segment.\n // Non-stacked bars are always considered fitting (undefined = fits).\n const fitsInSegment: boolean[] = [];\n\n const formatter = buildD3Formatter(labelFormat);\n\n for (const mark of targetMarks) {\n // Get the original numeric value from the data row when possible,\n // falling back to parsing the aria label (which may lose precision\n // due to abbreviation rounding, e.g. 1955 → \"2K\" → 2000).\n let valuePart: string;\n const rawNum = valueField != null ? Number(mark.data[valueField]) : NaN;\n\n if (formatter && Number.isFinite(rawNum)) {\n valuePart = formatter(rawNum);\n } else if (Number.isFinite(rawNum)) {\n valuePart = formatLabelValue(rawNum);\n } else {\n // Fallback: extract from aria label\n const ariaLabel = mark.aria.label;\n const lastColon = ariaLabel.lastIndexOf(':');\n const rawValue = lastColon >= 0 ? ariaLabel.slice(lastColon + 1).trim() : '';\n if (!rawValue) continue;\n if (formatter) {\n const num = parseDisplayNumber(rawValue);\n valuePart = !Number.isNaN(num) ? formatter(num) : rawValue;\n } else {\n valuePart = rawValue;\n }\n }\n if (labelPrefix) valuePart = labelPrefix + valuePart;\n\n const textWidth = estimateTextWidth(valuePart, LABEL_FONT_SIZE, LABEL_FONT_WEIGHT);\n const textHeight = LABEL_FONT_SIZE * 1.2;\n\n // Detect stacked bars: cornerRadius 0 indicates stacked segment\n const isStacked = mark.cornerRadius === 0;\n\n // Determine if label goes inside or outside the bar\n const isInside = mark.width >= MIN_WIDTH_FOR_INSIDE_LABEL;\n\n let anchorX: number;\n let fill: string;\n let textAnchor: 'start' | 'end' | 'middle';\n\n if (isStacked && isInside) {\n // Stacked: centered within segment\n anchorX = mark.x + mark.width / 2;\n fill = '#ffffff';\n textAnchor = 'middle';\n } else if (isInside) {\n // Simple: right-aligned within bar\n anchorX = mark.x + mark.width - LABEL_PADDING;\n fill = '#ffffff';\n textAnchor = 'end';\n } else {\n // Outside: just past the bar's right edge\n anchorX = mark.x + mark.width + LABEL_PADDING;\n fill = getRepresentativeColor(mark.fill);\n textAnchor = 'start';\n }\n\n // anchorY = bar vertical center. With dominant-baseline: central,\n // SVG places the text center at this y coordinate.\n const anchorY = mark.y + mark.height / 2;\n\n // Check if label text fits within the stacked segment\n const fits = !(isStacked && textWidth > mark.width - 2 * LABEL_PADDING);\n\n fitsInSegment.push(fits);\n candidates.push({\n text: valuePart,\n anchorX,\n anchorY,\n width: textWidth,\n height: textHeight,\n priority: 'data',\n style: {\n fontFamily: 'system-ui, -apple-system, sans-serif',\n fontSize: LABEL_FONT_SIZE,\n fontWeight: LABEL_FONT_WEIGHT,\n fill,\n lineHeight: 1.2,\n textAnchor,\n dominantBaseline: 'central',\n },\n });\n }\n\n if (candidates.length === 0) return [];\n\n // 'all': skip collision detection, mark everything visible\n // (but hide labels that don't fit in their stacked segment)\n if (density === 'all') {\n return candidates.map((c, i) => ({\n text: c.text,\n x: c.anchorX,\n y: c.anchorY,\n style: c.style,\n visible: fitsInSegment[i] !== false,\n }));\n }\n\n // For 'auto' and 'endpoints': pre-mark candidates that don't fit their\n // stacked segment as hidden before running collision detection.\n const fittingCandidates: LabelCandidate[] = [];\n const unfittingIndices = new Set<number>();\n for (let i = 0; i < candidates.length; i++) {\n if (fitsInSegment[i] === false) {\n unfittingIndices.add(i);\n } else {\n fittingCandidates.push(candidates[i]);\n }\n }\n\n const resolved = resolveCollisions(fittingCandidates);\n\n // Re-insert hidden labels for candidates that didn't fit, preserving order\n const results: ResolvedLabel[] = [];\n let resolvedIdx = 0;\n for (let i = 0; i < candidates.length; i++) {\n if (unfittingIndices.has(i)) {\n results.push({\n text: candidates[i].text,\n x: candidates[i].anchorX,\n y: candidates[i].anchorY,\n style: candidates[i].style,\n visible: false,\n });\n } else {\n results.push(resolved[resolvedIdx++]);\n }\n }\n\n return results;\n}\n","/**\n * Shared density filter for data labels.\n *\n * Maps a `LabelDensity` setting to the subset of marks eligible for\n * labeling. The `'auto'` branch is a pass-through — auto resolution\n * happens upstream in the per-chart label modules (typically via\n * collision detection on the full candidate set).\n */\n\nimport type { LabelDensity } from '@opendata-ai/openchart-core';\n\n/**\n * Filter a mark array by label density.\n *\n * - `'none'` returns `[]` (no labels)\n * - `'endpoints'` returns first + last marks when `marks.length > 1`,\n * otherwise the input unchanged (preserves single-element arrays as-is)\n * - `'all'` and `'auto'` return the input unchanged\n */\nexport function filterByDensity<T>(marks: T[], density: LabelDensity): T[] {\n if (density === 'none') return [];\n if (density === 'endpoints' && marks.length > 1) {\n return [marks[0], marks[marks.length - 1]];\n }\n return marks;\n}\n","/**\n * Bar chart module (horizontal bars).\n *\n * Exports the bar chart renderer and computation functions.\n */\n\nimport type { Mark } from '@opendata-ai/openchart-core';\nimport type { ChartRenderer } from '../registry';\nimport { computeBarMarks } from './compute';\nimport { computeBarLabels } from './labels';\n\n// ---------------------------------------------------------------------------\n// Bar chart renderer\n// ---------------------------------------------------------------------------\n\nexport const barRenderer: ChartRenderer = (spec, scales, chartArea, strategy, _theme) => {\n const marks = computeBarMarks(spec, scales, chartArea, strategy);\n\n // Compute and attach value labels (respects spec.labels.density)\n const valueField =\n spec.encoding?.x && 'field' in spec.encoding.x ? spec.encoding.x.field : undefined;\n const labels = computeBarLabels(\n marks,\n chartArea,\n spec.labels.density,\n spec.labels.format,\n spec.labels.prefix,\n valueField,\n );\n for (let i = 0; i < marks.length && i < labels.length; i++) {\n marks[i].label = labels[i];\n }\n\n return marks as Mark[];\n};\n\n// ---------------------------------------------------------------------------\n// Public exports\n// ---------------------------------------------------------------------------\n\nexport { computeBarMarks } from './compute';\nexport { computeBarLabels } from './labels';\n","/**\n * Column chart (vertical bars) mark computation.\n *\n * Takes a normalized chart spec with resolved scales and produces\n * RectMark[] for rendering vertical columns. When a color encoding\n * is present, columns are either stacked (cumulative heights) or grouped\n * (side-by-side) based on the `stack` property of the quantitative channel.\n *\n * Shares conceptual logic with bar chart but axes are swapped:\n * x-axis is categorical (band scale), y-axis is quantitative.\n */\n\nimport type {\n ConditionalValueDef,\n DataRow,\n Encoding,\n GradientDef,\n LayoutStrategy,\n MarkAria,\n Rect,\n RectMark,\n} from '@opendata-ai/openchart-core';\nimport { isGradientDef } from '@opendata-ai/openchart-core';\nimport type { ScaleBand, ScaleLinear } from 'd3-scale';\nimport type { NormalizedChartSpec } from '../../compiler/types';\nimport type { ResolvedScales } from '../../layout/scales';\nimport { isConditionalValueDef, resolveConditionalValue } from '../../transforms/conditional';\nimport { formatLabelValue } from '../_shared/format-label-value';\nimport { getColor, getSequentialColor, groupByField } from '../utils';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst MIN_COLUMN_HEIGHT = 1;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute vertical column marks from a normalized chart spec.\n *\n * X axis uses a band scale for categories. Y axis uses a linear scale\n * for values. When a color encoding is present, columns within each\n * category are stacked (cumulative heights).\n */\nexport function computeColumnMarks(\n spec: NormalizedChartSpec,\n scales: ResolvedScales,\n _chartArea: Rect,\n _strategy: LayoutStrategy,\n): RectMark[] {\n const encoding = spec.encoding as Encoding;\n const xChannel = encoding.x;\n const yChannel = encoding.y;\n\n if (!xChannel || !yChannel || !scales.x || !scales.y) {\n return [];\n }\n\n const xScale = scales.x.scale as ScaleBand<string>;\n const yScale = scales.y.scale as ScaleLinear<number, number>;\n\n // Band scale should provide bandwidth\n if (typeof xScale.bandwidth !== 'function') {\n return [];\n }\n\n const bandwidth = xScale.bandwidth();\n const baseline = yScale(0);\n const colorEnc = encoding.color && 'field' in encoding.color ? encoding.color : undefined;\n const conditionalColor =\n encoding.color && isConditionalValueDef(encoding.color)\n ? (encoding.color as ConditionalValueDef)\n : undefined;\n const colorField = colorEnc?.field;\n\n const isSequentialColor = colorEnc?.type === 'quantitative';\n\n // Color encoding present: decide between colored simple columns vs stacked\n if (colorField && !isSequentialColor) {\n // Check if any category has multiple rows (actual stacking needed)\n const categoryGroups = groupByField(spec.data, xChannel.field);\n const needsStacking = Array.from(categoryGroups.values()).some((rows) => rows.length > 1);\n\n if (needsStacking) {\n const stackDisabled = yChannel.stack === null || yChannel.stack === false;\n\n if (stackDisabled) {\n return computeGroupedColumns(\n spec.data,\n xChannel.field,\n yChannel.field,\n colorField,\n xScale,\n yScale,\n bandwidth,\n baseline,\n scales,\n );\n }\n\n const stackMode =\n yChannel.stack === 'normalize'\n ? 'normalize'\n : yChannel.stack === 'center'\n ? 'center'\n : 'zero';\n\n return computeStackedColumns(\n spec.data,\n xChannel.field,\n yChannel.field,\n colorField,\n xScale,\n yScale,\n bandwidth,\n baseline,\n scales,\n stackMode,\n );\n }\n\n // Single row per category: render like simple columns but with color from scale\n return computeColoredColumns(\n spec.data,\n xChannel.field,\n yChannel.field,\n colorField,\n xScale,\n yScale,\n bandwidth,\n baseline,\n scales,\n );\n }\n\n return computeSimpleColumns(\n spec.data,\n xChannel.field,\n yChannel.field,\n xScale,\n yScale,\n bandwidth,\n baseline,\n scales,\n isSequentialColor,\n conditionalColor,\n );\n}\n\n/** Compute simple (non-grouped) vertical columns. */\nfunction computeSimpleColumns(\n data: DataRow[],\n categoryField: string,\n valueField: string,\n xScale: ScaleBand<string>,\n yScale: ScaleLinear<number, number>,\n bandwidth: number,\n baseline: number,\n scales: ResolvedScales,\n sequentialColor = false,\n conditionalColor?: ConditionalValueDef,\n): RectMark[] {\n const marks: RectMark[] = [];\n\n for (const row of data) {\n const category = String(row[categoryField] ?? '');\n const value = Number(row[valueField] ?? 0);\n if (!Number.isFinite(value)) continue;\n\n const bandX = xScale(category);\n if (bandX === undefined) continue;\n\n let color: string | GradientDef;\n if (conditionalColor) {\n const resolved = resolveConditionalValue(row, conditionalColor);\n if (resolved != null) {\n color = isGradientDef(resolved) ? resolved : String(resolved);\n } else {\n color = getColor(scales, '__default__');\n }\n } else if (sequentialColor) {\n color = getSequentialColor(scales, value);\n } else {\n color = getColor(scales, '__default__');\n }\n const yPos = yScale(value);\n const columnHeight = Math.max(Math.abs(baseline - yPos), MIN_COLUMN_HEIGHT);\n\n // For positive values, column goes upward from baseline.\n // For negative values, column goes downward from baseline.\n const y = value >= 0 ? yPos : baseline;\n\n const aria: MarkAria = {\n label: `${category}: ${formatLabelValue(value)}`,\n };\n\n marks.push({\n type: 'rect',\n x: bandX,\n y,\n width: bandwidth,\n height: columnHeight,\n fill: color,\n cornerRadius: 2,\n data: row as Record<string, unknown>,\n aria,\n orient: 'vertical',\n });\n }\n\n return marks;\n}\n\n/** Compute colored (non-stacked) vertical columns. Used when color encoding\n * is present but each category has only one row (e.g., diverging charts). */\nfunction computeColoredColumns(\n data: DataRow[],\n categoryField: string,\n valueField: string,\n colorField: string,\n xScale: ScaleBand<string>,\n yScale: ScaleLinear<number, number>,\n bandwidth: number,\n baseline: number,\n scales: ResolvedScales,\n): RectMark[] {\n const marks: RectMark[] = [];\n\n for (const row of data) {\n const category = String(row[categoryField] ?? '');\n const value = Number(row[valueField] ?? 0);\n if (!Number.isFinite(value)) continue;\n\n const bandX = xScale(category);\n if (bandX === undefined) continue;\n\n const groupKey = String(row[colorField] ?? '');\n const color = getColor(scales, groupKey);\n const yPos = yScale(value);\n const columnHeight = Math.max(Math.abs(baseline - yPos), MIN_COLUMN_HEIGHT);\n\n const y = value >= 0 ? yPos : baseline;\n\n const aria: MarkAria = {\n label: `${category}, ${groupKey}: ${formatLabelValue(value)}`,\n };\n\n marks.push({\n type: 'rect',\n x: bandX,\n y,\n width: bandwidth,\n height: columnHeight,\n fill: color,\n cornerRadius: 2,\n data: row as Record<string, unknown>,\n aria,\n orient: 'vertical',\n });\n }\n\n return marks;\n}\n\n/** Compute grouped (dodged) vertical columns -- side-by-side within each category band. */\nfunction computeGroupedColumns(\n data: DataRow[],\n categoryField: string,\n valueField: string,\n colorField: string,\n xScale: ScaleBand<string>,\n yScale: ScaleLinear<number, number>,\n bandwidth: number,\n baseline: number,\n scales: ResolvedScales,\n): RectMark[] {\n const marks: RectMark[] = [];\n const categoryGroups = groupByField(data, categoryField);\n\n // Build a stable group order from first appearance in data (Map for O(1) lookup)\n const groupIndexMap = new Map<string, number>();\n for (const row of data) {\n const key = String(row[colorField] ?? '');\n if (!groupIndexMap.has(key)) {\n groupIndexMap.set(key, groupIndexMap.size);\n }\n }\n const groupCount = groupIndexMap.size;\n if (groupCount === 0) return marks;\n\n // Subdivide the band width by group count with a small gap\n const gap = Math.min(1, bandwidth * 0.05);\n const subBandWidth = Math.max(\n (bandwidth - gap * (groupCount - 1)) / groupCount,\n MIN_COLUMN_HEIGHT,\n );\n\n for (const [category, rows] of categoryGroups) {\n const bandX = xScale(category);\n if (bandX === undefined) continue;\n\n for (const row of rows) {\n const groupKey = String(row[colorField] ?? '');\n const value = Number(row[valueField] ?? 0);\n if (!Number.isFinite(value)) continue;\n\n const groupIndex = groupIndexMap.get(groupKey) ?? 0;\n const color = getColor(scales, groupKey);\n const yPos = yScale(value);\n const columnHeight = Math.max(Math.abs(baseline - yPos), MIN_COLUMN_HEIGHT);\n const y = value >= 0 ? yPos : baseline;\n const subX = bandX + groupIndex * (subBandWidth + gap);\n\n const aria: MarkAria = {\n label: `${category}, ${groupKey}: ${formatLabelValue(value)}`,\n };\n\n marks.push({\n type: 'rect',\n x: subX,\n y,\n width: subBandWidth,\n height: columnHeight,\n fill: color,\n cornerRadius: 2,\n data: row as Record<string, unknown>,\n aria,\n orient: 'vertical',\n });\n }\n }\n\n return marks;\n}\n\n/** Compute stacked vertical columns with support for zero/normalize/center modes. */\nfunction computeStackedColumns(\n data: DataRow[],\n categoryField: string,\n valueField: string,\n colorField: string,\n xScale: ScaleBand<string>,\n yScale: ScaleLinear<number, number>,\n bandwidth: number,\n _baseline: number,\n scales: ResolvedScales,\n stackMode: 'zero' | 'normalize' | 'center' = 'zero',\n): RectMark[] {\n const marks: RectMark[] = [];\n const categoryGroups = groupByField(data, categoryField);\n\n for (const [category, rows] of categoryGroups) {\n const bandX = xScale(category);\n if (bandX === undefined) continue;\n\n // Compute category total for normalize/center modes\n let categoryTotal = 0;\n for (const row of rows) {\n const v = Number(row[valueField] ?? 0);\n if (Number.isFinite(v) && v > 0) categoryTotal += v;\n }\n\n // For center mode, offset so the stack is centered around zero\n let cumulativeValue = stackMode === 'center' ? -categoryTotal / 2 : 0;\n\n for (const row of rows) {\n const groupKey = String(row[colorField] ?? '');\n const rawValue = Number(row[valueField] ?? 0);\n // Stacking only applies to positive values; negative/zero rows are skipped\n // since cumulative stacking doesn't make visual sense for mixed signs.\n if (!Number.isFinite(rawValue) || rawValue <= 0) continue;\n\n // For normalize mode, scale the value to a fraction of the total\n const value =\n stackMode === 'normalize' && categoryTotal > 0 ? rawValue / categoryTotal : rawValue;\n\n const color = getColor(scales, groupKey);\n\n const yTop = yScale(cumulativeValue + value);\n const yBottom = yScale(cumulativeValue);\n const columnHeight = Math.max(Math.abs(yBottom - yTop), MIN_COLUMN_HEIGHT);\n\n const aria: MarkAria = {\n label: `${category}, ${groupKey}: ${formatLabelValue(rawValue)}`,\n };\n\n marks.push({\n type: 'rect',\n x: bandX,\n y: Math.min(yTop, yBottom),\n width: bandwidth,\n height: columnHeight,\n fill: color,\n cornerRadius: 0,\n data: row as Record<string, unknown>,\n aria,\n orient: 'vertical',\n stackGroup: category,\n });\n\n cumulativeValue += value;\n }\n }\n\n return marks;\n}\n","/**\n * Column chart label computation.\n *\n * Produces value labels positioned above each column (for positive values)\n * or below (for negative values).\n *\n * Respects the spec's label density setting:\n * - 'all': show every label, skip collision detection\n * - 'auto': existing behavior (collision detection)\n * - 'endpoints': first and last columns only\n * - 'none': return empty array\n */\n\nimport type {\n LabelCandidate,\n LabelDensity,\n RectMark,\n ResolvedLabel,\n} from '@opendata-ai/openchart-core';\nimport {\n buildD3Formatter,\n estimateTextWidth,\n getRepresentativeColor,\n resolveCollisions,\n} from '@opendata-ai/openchart-core';\nimport { filterByDensity } from '../_shared/density-filter';\nimport { formatLabelValue } from '../_shared/format-label-value';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst LABEL_FONT_SIZE = 10;\nconst LABEL_FONT_WEIGHT = 600;\nconst LABEL_OFFSET_Y = 6;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute value labels for column marks.\n *\n * For each column, the value is placed centered above the column top.\n */\nexport function computeColumnLabels(\n marks: RectMark[],\n _chartArea: { x: number; y: number; width: number; height: number },\n density: LabelDensity = 'auto',\n labelFormat?: string,\n labelPrefix?: string,\n valueField?: string,\n): ResolvedLabel[] {\n const targetMarks = filterByDensity(marks, density);\n\n const formatter = buildD3Formatter(labelFormat);\n\n const candidates: LabelCandidate[] = [];\n\n for (const mark of targetMarks) {\n // Get the original numeric value from the data row when possible,\n // falling back to parsing the aria label (which may lose precision\n // due to abbreviation rounding, e.g. 1955 → \"2K\" → 2000).\n let valuePart: string;\n const rawNum = valueField != null ? Number(mark.data[valueField]) : NaN;\n\n if (formatter && Number.isFinite(rawNum)) {\n valuePart = formatter(rawNum);\n } else if (Number.isFinite(rawNum)) {\n valuePart = formatLabelValue(rawNum);\n } else {\n // Fallback: extract from aria label\n const ariaLabel = mark.aria.label;\n const lastColon = ariaLabel.lastIndexOf(':');\n const rawValue = lastColon >= 0 ? ariaLabel.slice(lastColon + 1).trim() : '';\n if (!rawValue) continue;\n if (formatter) {\n const num = Number(rawValue.replace(/[^0-9.-]/g, ''));\n valuePart = !Number.isNaN(num) ? formatter(num) : rawValue;\n } else {\n valuePart = rawValue;\n }\n }\n if (labelPrefix) valuePart = labelPrefix + valuePart;\n\n const numericValue = parseFloat(valuePart);\n const isNegative = Number.isFinite(numericValue) && numericValue < 0;\n\n const textWidth = estimateTextWidth(valuePart, LABEL_FONT_SIZE, LABEL_FONT_WEIGHT);\n const textHeight = LABEL_FONT_SIZE * 1.2;\n\n // For positive values, place label above the column top.\n // For negative values, place label below the column bottom.\n const anchorX = mark.x + mark.width / 2;\n const anchorY = isNegative\n ? mark.y + mark.height + LABEL_OFFSET_Y\n : mark.y - LABEL_OFFSET_Y - textHeight;\n\n candidates.push({\n text: valuePart,\n anchorX,\n anchorY,\n width: textWidth,\n height: textHeight,\n priority: 'data',\n style: {\n fontFamily: 'system-ui, -apple-system, sans-serif',\n fontSize: LABEL_FONT_SIZE,\n fontWeight: LABEL_FONT_WEIGHT,\n fill: getRepresentativeColor(mark.fill),\n lineHeight: 1.2,\n textAnchor: 'middle',\n dominantBaseline: isNegative ? 'hanging' : 'auto',\n },\n });\n }\n\n if (candidates.length === 0) return [];\n\n // 'all': skip collision detection, mark everything visible\n if (density === 'all') {\n return candidates.map((c) => ({\n text: c.text,\n x: c.anchorX,\n y: c.anchorY,\n style: c.style,\n visible: true,\n }));\n }\n\n return resolveCollisions(candidates);\n}\n","/**\n * Column chart module (vertical bars).\n *\n * Exports the column chart renderer and computation functions.\n */\n\nimport type { Mark } from '@opendata-ai/openchart-core';\nimport type { ChartRenderer } from '../registry';\nimport { computeColumnMarks } from './compute';\nimport { computeColumnLabels } from './labels';\n\n// ---------------------------------------------------------------------------\n// Column chart renderer\n// ---------------------------------------------------------------------------\n\nexport const columnRenderer: ChartRenderer = (spec, scales, chartArea, strategy, _theme) => {\n const marks = computeColumnMarks(spec, scales, chartArea, strategy);\n\n // Compute and attach value labels (respects spec.labels.density)\n const valueField =\n spec.encoding?.y && 'field' in spec.encoding.y ? spec.encoding.y.field : undefined;\n const labels = computeColumnLabels(\n marks,\n chartArea,\n spec.labels.density,\n spec.labels.format,\n spec.labels.prefix,\n valueField,\n );\n for (let i = 0; i < marks.length && i < labels.length; i++) {\n marks[i].label = labels[i];\n }\n\n return marks as Mark[];\n};\n\n// ---------------------------------------------------------------------------\n// Public exports\n// ---------------------------------------------------------------------------\n\nexport { computeColumnMarks } from './compute';\nexport { computeColumnLabels } from './labels';\n","/**\n * Dot plot / lollipop chart mark computation.\n *\n * Category axis (band scale) + value axis (linear scale). Produces\n * PointMark[] for the dots plus RectMark[] for lollipop stems\n * (thin lines from axis baseline to each dot).\n *\n * When a color encoding is present (multi-series), renders as a dumbbell\n * chart: a connecting bar spans min-to-max per category instead of\n * baseline-to-dot stems.\n */\n\nimport type {\n Encoding,\n LayoutStrategy,\n MarkAria,\n PointMark,\n Rect,\n RectMark,\n} from '@opendata-ai/openchart-core';\nimport type { ScaleBand, ScaleLinear } from 'd3-scale';\n\nimport type { NormalizedChartSpec } from '../../compiler/types';\nimport type { ResolvedScales } from '../../layout/scales';\nimport { getColor, getSequentialColor, groupByField } from '../utils';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DOT_RADIUS = 6;\nconst STEM_WIDTH = 2;\nconst STEM_COLOR = '#cccccc';\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute dot plot marks from a normalized chart spec.\n *\n * Y axis uses a band scale for categories. X axis uses a linear scale\n * for values. When no color encoding is present, each data point produces\n * a lollipop stem + dot. When color is present (multi-series), renders\n * connecting bars between min/max values per category (dumbbell style).\n */\nexport function computeDotMarks(\n spec: NormalizedChartSpec,\n scales: ResolvedScales,\n _chartArea: Rect,\n _strategy: LayoutStrategy,\n): (PointMark | RectMark)[] {\n const encoding = spec.encoding as Encoding;\n const xChannel = encoding.x;\n const yChannel = encoding.y;\n\n if (!xChannel || !yChannel || !scales.x || !scales.y) {\n return [];\n }\n\n const xScale = scales.x.scale as ScaleLinear<number, number>;\n const yScale = scales.y.scale as ScaleBand<string>;\n\n // Band scale should provide bandwidth\n if (typeof yScale.bandwidth !== 'function') {\n return [];\n }\n\n const bandwidth = yScale.bandwidth();\n const baseline = xScale(0);\n const colorEnc = encoding.color && 'field' in encoding.color ? encoding.color : undefined;\n const isSequentialColor = colorEnc?.type === 'quantitative';\n const colorField = isSequentialColor ? undefined : colorEnc?.field;\n\n // Multi-series (categorical): dumbbell chart with connecting bars\n if (colorField) {\n return computeDumbbellMarks(\n spec.data,\n xChannel.field,\n yChannel.field,\n colorField,\n xScale,\n yScale,\n bandwidth,\n scales,\n );\n }\n\n // Single series: lollipop stems from baseline\n return computeLollipopMarks(\n spec.data,\n xChannel.field,\n yChannel.field,\n xScale,\n yScale,\n bandwidth,\n baseline,\n scales,\n isSequentialColor,\n );\n}\n\n// ---------------------------------------------------------------------------\n// Dumbbell (multi-series)\n// ---------------------------------------------------------------------------\n\n/** Compute dumbbell marks: connecting bar + colored dots per category. */\nfunction computeDumbbellMarks(\n data: readonly Record<string, unknown>[],\n valueField: string,\n categoryField: string,\n colorField: string,\n xScale: ScaleLinear<number, number>,\n yScale: ScaleBand<string>,\n bandwidth: number,\n scales: ResolvedScales,\n): (PointMark | RectMark)[] {\n const marks: (PointMark | RectMark)[] = [];\n const categoryGroups = groupByField([...data], categoryField);\n\n for (const [category, rows] of categoryGroups) {\n const bandY = yScale(category);\n if (bandY === undefined) continue;\n\n const cy = bandY + bandwidth / 2;\n\n // Collect all x-values for this category to find the range\n const xValues: number[] = [];\n for (const row of rows) {\n const value = Number(row[valueField] ?? 0);\n if (Number.isFinite(value)) xValues.push(value);\n }\n\n if (xValues.length === 0) continue;\n\n const minVal = Math.min(...xValues);\n const maxVal = Math.max(...xValues);\n const xLeft = xScale(minVal);\n const xRight = xScale(maxVal);\n const barWidth = Math.abs(xRight - xLeft);\n\n // Connecting bar (rendered first so dots layer on top)\n if (barWidth > 0) {\n const stemAria: MarkAria = {\n label: `Range for ${category}: ${minVal} to ${maxVal}`,\n };\n\n marks.push({\n type: 'rect',\n x: Math.min(xLeft, xRight),\n y: cy - STEM_WIDTH / 2,\n width: barWidth,\n height: STEM_WIDTH,\n fill: STEM_COLOR,\n data: rows[0] as Record<string, unknown>,\n aria: stemAria,\n });\n }\n\n // Individual dots for each series value\n for (const row of rows) {\n const value = Number(row[valueField] ?? 0);\n if (!Number.isFinite(value)) continue;\n\n const cx = xScale(value);\n const colorCategory = String(row[colorField] ?? '');\n const color = getColor(scales, colorCategory);\n\n const dotAria: MarkAria = {\n label: `${category}, ${colorCategory}: ${value}`,\n };\n\n marks.push({\n type: 'point',\n cx,\n cy,\n r: DOT_RADIUS,\n fill: color,\n stroke: '#ffffff',\n strokeWidth: 2,\n data: row as Record<string, unknown>,\n aria: dotAria,\n });\n }\n }\n\n return marks;\n}\n\n// ---------------------------------------------------------------------------\n// Lollipop (single series)\n// ---------------------------------------------------------------------------\n\n/** Compute lollipop marks: stem from baseline + dot. */\nfunction computeLollipopMarks(\n data: readonly Record<string, unknown>[],\n valueField: string,\n categoryField: string,\n xScale: ScaleLinear<number, number>,\n yScale: ScaleBand<string>,\n bandwidth: number,\n baseline: number,\n scales: ResolvedScales,\n isSequentialColor = false,\n): (PointMark | RectMark)[] {\n const marks: (PointMark | RectMark)[] = [];\n\n for (const row of data) {\n const category = String(row[categoryField] ?? '');\n const value = Number(row[valueField] ?? 0);\n if (!Number.isFinite(value)) continue;\n\n const bandY = yScale(category);\n if (bandY === undefined) continue;\n\n const cx = xScale(value);\n const cy = bandY + bandwidth / 2;\n\n const color = isSequentialColor\n ? getSequentialColor(scales, value)\n : getColor(scales, '__default__');\n\n // Stem: thin rectangle from baseline to dot center\n const stemX = Math.min(baseline, cx);\n const stemWidth = Math.abs(cx - baseline);\n\n if (stemWidth > 0) {\n const stemAria: MarkAria = {\n label: `Stem for ${category}`,\n };\n\n marks.push({\n type: 'rect',\n x: stemX,\n y: cy - STEM_WIDTH / 2,\n width: stemWidth,\n height: STEM_WIDTH,\n fill: STEM_COLOR,\n data: row as Record<string, unknown>,\n aria: stemAria,\n });\n }\n\n // Dot\n const dotAria: MarkAria = {\n label: `${category}: ${value}`,\n };\n\n marks.push({\n type: 'point',\n cx,\n cy,\n r: DOT_RADIUS,\n fill: color,\n stroke: '#ffffff',\n strokeWidth: 2,\n data: row as Record<string, unknown>,\n aria: dotAria,\n });\n }\n\n return marks;\n}\n","/**\n * Dot chart label computation.\n *\n * Produces value labels positioned to the right of each dot.\n *\n * Respects the spec's label density setting:\n * - 'all': show every label, skip collision detection\n * - 'auto': existing behavior (collision detection)\n * - 'endpoints': first and last dots only\n * - 'none': return empty array\n */\n\nimport type {\n LabelCandidate,\n LabelDensity,\n PointMark,\n Rect,\n ResolvedLabel,\n} from '@opendata-ai/openchart-core';\nimport {\n buildD3Formatter,\n estimateTextWidth,\n getRepresentativeColor,\n resolveCollisions,\n} from '@opendata-ai/openchart-core';\nimport { filterByDensity } from '../_shared/density-filter';\nimport { formatLabelValue } from '../_shared/format-label-value';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst LABEL_FONT_SIZE = 11;\nconst LABEL_FONT_WEIGHT = 600;\nconst LABEL_OFFSET_X = 10;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute value labels for dot marks.\n *\n * Places labels to the right of each dot point.\n */\nexport function computeDotLabels(\n marks: PointMark[],\n _chartArea: Rect,\n density: LabelDensity = 'auto',\n labelPrefix?: string,\n labelFormat?: string,\n valueField?: string,\n): ResolvedLabel[] {\n const targetMarks = filterByDensity(marks, density);\n\n const formatter = buildD3Formatter(labelFormat);\n const candidates: LabelCandidate[] = [];\n\n for (const mark of targetMarks) {\n // Get the original numeric value from the data row when possible,\n // falling back to parsing the aria label (which may lose precision\n // due to abbreviation rounding, e.g. 1955 → \"2K\" → 2000).\n let valuePart: string;\n const rawNum = valueField != null ? Number(mark.data[valueField]) : NaN;\n\n if (formatter && Number.isFinite(rawNum)) {\n valuePart = formatter(rawNum);\n } else if (Number.isFinite(rawNum)) {\n valuePart = formatLabelValue(rawNum);\n } else {\n // Fallback: extract from aria label\n const ariaLabel = mark.aria.label;\n const lastColon = ariaLabel.lastIndexOf(':');\n valuePart = lastColon >= 0 ? ariaLabel.slice(lastColon + 1).trim() : '';\n if (!valuePart) continue;\n if (formatter) {\n const num = Number(valuePart.replace(/[^0-9.-]/g, ''));\n if (!Number.isNaN(num)) valuePart = formatter(num);\n }\n }\n if (labelPrefix) valuePart = labelPrefix + valuePart;\n\n const textWidth = estimateTextWidth(valuePart, LABEL_FONT_SIZE, LABEL_FONT_WEIGHT);\n const textHeight = LABEL_FONT_SIZE * 1.2;\n\n candidates.push({\n text: valuePart,\n anchorX: mark.cx + mark.r + LABEL_OFFSET_X,\n anchorY: mark.cy - textHeight / 2,\n width: textWidth,\n height: textHeight,\n priority: 'data',\n style: {\n fontFamily: 'system-ui, -apple-system, sans-serif',\n fontSize: LABEL_FONT_SIZE,\n fontWeight: LABEL_FONT_WEIGHT,\n fill: getRepresentativeColor(mark.fill),\n lineHeight: 1.2,\n textAnchor: 'start',\n dominantBaseline: 'central',\n },\n });\n }\n\n if (candidates.length === 0) return [];\n\n // 'all': skip collision detection, mark everything visible\n if (density === 'all') {\n return candidates.map((c) => ({\n text: c.text,\n x: c.anchorX,\n y: c.anchorY,\n style: c.style,\n visible: true,\n }));\n }\n\n return resolveCollisions(candidates);\n}\n","/**\n * Dot plot / lollipop chart module.\n *\n * Exports the dot chart renderer and computation functions.\n */\n\nimport type { Mark, PointMark } from '@opendata-ai/openchart-core';\nimport type { ChartRenderer } from '../registry';\nimport { computeDotMarks } from './compute';\nimport { computeDotLabels } from './labels';\n\n// ---------------------------------------------------------------------------\n// Dot chart renderer\n// ---------------------------------------------------------------------------\n\n/**\n * Dot/lollipop chart renderer.\n *\n * Produces stem (RectMark) and dot (PointMark) pairs for each data point.\n * Value labels are attached to the dot marks.\n */\nexport const dotRenderer: ChartRenderer = (spec, scales, chartArea, strategy, _theme) => {\n const marks = computeDotMarks(spec, scales, chartArea, strategy);\n\n // Extract just the point marks for label computation\n const pointMarks = marks.filter((m): m is PointMark => m.type === 'point');\n\n // Compute and attach labels to point marks (respects spec.labels.density)\n const valueField =\n spec.encoding?.x && 'field' in spec.encoding.x ? spec.encoding.x.field : undefined;\n const labels = computeDotLabels(\n pointMarks,\n chartArea,\n spec.labels.density,\n spec.labels.prefix,\n spec.labels.format,\n valueField,\n );\n let labelIdx = 0;\n for (const mark of marks) {\n if (mark.type === 'point' && labelIdx < labels.length) {\n mark.label = labels[labelIdx];\n labelIdx++;\n }\n }\n\n return marks as Mark[];\n};\n\n// ---------------------------------------------------------------------------\n// Public exports\n// ---------------------------------------------------------------------------\n\nexport { computeDotMarks } from './compute';\nexport { computeDotLabels } from './labels';\n","/**\n * Line & area chart module.\n *\n * Exports line and area chart renderers and computation functions.\n */\n\nimport type { AreaMark, LineMark, Mark } from '@opendata-ai/openchart-core';\nimport { getRepresentativeColor } from '@opendata-ai/openchart-core';\nimport type { ChartRenderer } from '../registry';\nimport { computeAreaMarks } from './area';\nimport { computeLineMarks } from './compute';\nimport { computeLineLabels } from './labels';\n\n// ---------------------------------------------------------------------------\n// Line chart renderer\n// ---------------------------------------------------------------------------\n\n/**\n * Line chart renderer.\n *\n * Computes line marks + point marks for hover targets, then resolves\n * end-of-line labels and attaches them to the corresponding line marks.\n */\nexport const lineRenderer: ChartRenderer = (spec, scales, chartArea, strategy, _theme) => {\n const marks = computeLineMarks(spec, scales, chartArea, strategy);\n\n // Extract just the line marks for label computation\n const lineMarks = marks.filter((m): m is LineMark => m.type === 'line');\n\n // Compute and attach labels to line marks by seriesKey lookup\n const labelMap = computeLineLabels(lineMarks, strategy, spec.labels.density, spec.labels.offsets);\n for (const mark of marks) {\n if (mark.type === 'line' && mark.seriesKey) {\n const label = labelMap.get(mark.seriesKey);\n if (label) {\n mark.label = label;\n }\n }\n }\n\n return marks as Mark[];\n};\n\n// ---------------------------------------------------------------------------\n// Area chart renderer\n// ---------------------------------------------------------------------------\n\n/**\n * Area chart renderer.\n *\n * Computes area fill marks (stacked if multi-series).\n * Also computes line marks for the top boundary and point marks\n * for hover targets, layered on top of the areas.\n */\nexport const areaRenderer: ChartRenderer = (spec, scales, chartArea, strategy, _theme) => {\n const areas = computeAreaMarks(spec, scales, chartArea);\n\n const encoding = spec.encoding;\n const hasColor = !!(encoding.color && 'field' in encoding.color);\n\n // For stacked areas, derive line marks from the area top paths so lines\n // align with stacked positions. For non-stacked, compute lines normally.\n const lines = hasColor\n ? linesFromAreas(areas)\n : computeLineMarks(spec, scales, chartArea, strategy);\n\n // Areas go first (rendered behind lines), then lines on top\n return [...areas, ...lines] as Mark[];\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Derive LineMark[] from stacked AreaMark[] using each area's top boundary.\n * This ensures lines sit on top of their corresponding stacked area bands.\n */\nfunction linesFromAreas(areas: AreaMark[]): LineMark[] {\n return areas.map((a) => ({\n type: 'line' as const,\n points: a.topPoints,\n path: a.topPath,\n stroke: getRepresentativeColor(a.fill),\n strokeWidth: a.strokeWidth ?? 1,\n seriesKey: a.seriesKey,\n data: a.data,\n dataPoints: a.dataPoints,\n aria: { label: `${a.seriesKey ?? 'Series'}: line with ${a.topPoints.length} data points` },\n }));\n}\n\n// ---------------------------------------------------------------------------\n// Public exports\n// ---------------------------------------------------------------------------\n\nexport { computeAreaMarks } from './area';\nexport { computeLineMarks } from './compute';\nexport { computeLineLabels } from './labels';\n","/**\n * Area chart mark computation.\n *\n * Uses D3 area() generator to produce AreaMark[] with top/bottom\n * boundary points and SVG path strings. Supports single areas and\n * stacked areas via d3-shape stack layout.\n */\n\nimport type { AreaMark, DataRow, Encoding, MarkAria, Rect } from '@opendata-ai/openchart-core';\nimport { getRepresentativeColor } from '@opendata-ai/openchart-core';\nimport type { ScaleLinear } from 'd3-scale';\nimport {\n area,\n line,\n stack,\n stackOffsetExpand,\n stackOffsetNone,\n stackOffsetSilhouette,\n stackOrderNone,\n} from 'd3-shape';\n\nimport type { NormalizedChartSpec } from '../../compiler/types';\nimport type { ResolvedScales } from '../../layout/scales';\nimport { getColor, scaleValue, sortByField } from '../utils';\nimport { resolveCurve } from './curves';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_FILL_OPACITY = 0.15;\n\n// ---------------------------------------------------------------------------\n// Single area (non-stacked)\n// ---------------------------------------------------------------------------\n\nfunction computeSingleArea(\n spec: NormalizedChartSpec,\n scales: ResolvedScales,\n _chartArea: Rect,\n): AreaMark[] {\n const encoding = spec.encoding as Encoding;\n const xChannel = encoding.x;\n const yChannel = encoding.y;\n\n if (!xChannel || !yChannel || !scales.x || !scales.y) return [];\n\n const yScale = scales.y.scale as ScaleLinear<number, number>;\n // Use the domain minimum as the baseline so the area fill doesn't drop\n // below the visible scale range when zero: false excludes 0 from the domain.\n const domain = yScale.domain();\n const baselineY = yScale(Math.min(domain[0], domain[1]));\n\n // Group by color field\n const colorField = encoding.color && 'field' in encoding.color ? encoding.color.field : undefined;\n const groups = new Map<string, DataRow[]>();\n\n if (!colorField) {\n groups.set('__default__', spec.data);\n } else {\n for (const row of spec.data) {\n const key = String(row[colorField] ?? '__default__');\n const existing = groups.get(key);\n if (existing) {\n existing.push(row);\n } else {\n groups.set(key, [row]);\n }\n }\n }\n\n const marks: AreaMark[] = [];\n\n for (const [seriesKey, rows] of groups) {\n const color = getColor(scales, seriesKey);\n\n // Sort rows by x-axis field so areas draw left-to-right.\n // For nominal/ordinal axes, preserve data order.\n const sortedRows =\n xChannel.type === 'nominal' || xChannel.type === 'ordinal'\n ? rows\n : sortByField(rows, xChannel.field);\n\n // Compute points, filtering out null values\n const validPoints: { x: number; yTop: number; yBottom: number; row: DataRow }[] = [];\n\n for (const row of sortedRows) {\n const xVal = scaleValue(scales.x.scale, scales.x.type, row[xChannel.field]);\n const yVal = scaleValue(scales.y.scale, scales.y.type, row[yChannel.field]);\n\n if (xVal === null || yVal === null) continue;\n\n validPoints.push({\n x: xVal,\n yTop: yVal,\n yBottom: baselineY,\n row,\n });\n }\n\n if (validPoints.length === 0) continue;\n\n // Build the area path with configured interpolation\n const curve = resolveCurve(spec.markDef.interpolate);\n const areaGenerator = area<{ x: number; yTop: number; yBottom: number }>()\n .x((d) => d.x)\n .y0((d) => d.yBottom)\n .y1((d) => d.yTop)\n .curve(curve);\n\n const pathStr = areaGenerator(validPoints) ?? '';\n\n // Top-line path for stroking only the data line (not the baseline)\n const topLineGenerator = line<{ x: number; yTop: number }>()\n .x((d) => d.x)\n .y((d) => d.yTop)\n .curve(curve);\n const topPathStr = topLineGenerator(validPoints) ?? '';\n\n const topPoints = validPoints.map((p) => ({ x: p.x, y: p.yTop }));\n const bottomPoints = validPoints.map((p) => ({ x: p.x, y: p.yBottom }));\n\n const ariaLabel =\n seriesKey === '__default__'\n ? `Area with ${validPoints.length} data points`\n : `${seriesKey}: area with ${validPoints.length} data points`;\n\n const aria: MarkAria = { label: ariaLabel };\n\n marks.push({\n type: 'area',\n topPoints,\n bottomPoints,\n path: pathStr,\n topPath: topPathStr,\n fill: color,\n fillOpacity: DEFAULT_FILL_OPACITY,\n stroke: getRepresentativeColor(color),\n strokeWidth: 2,\n seriesKey: seriesKey === '__default__' ? undefined : seriesKey,\n data: validPoints.map((p) => p.row),\n dataPoints: validPoints.map((p) => ({ x: p.x, y: p.yTop, datum: p.row })),\n aria,\n });\n }\n\n return marks;\n}\n\n// ---------------------------------------------------------------------------\n// Stacked area\n// ---------------------------------------------------------------------------\n\nfunction computeStackedArea(\n spec: NormalizedChartSpec,\n scales: ResolvedScales,\n chartArea: Rect,\n): AreaMark[] {\n const encoding = spec.encoding as Encoding;\n const xChannel = encoding.x;\n const yChannel = encoding.y;\n const colorField = encoding.color && 'field' in encoding.color ? encoding.color.field : undefined;\n\n if (!xChannel || !yChannel || !scales.x || !scales.y || !colorField) {\n // If no color field, can't stack -- fall back to single area\n return computeSingleArea(spec, scales, chartArea);\n }\n\n // Sort data by x field so stacked areas render left-to-right.\n // For nominal/ordinal axes, preserve data order.\n const sortedData =\n xChannel.type === 'nominal' || xChannel.type === 'ordinal'\n ? spec.data\n : sortByField(spec.data, xChannel.field);\n\n // Collect unique series keys and x values, and build a lookup from\n // (x-value, series-key) -> original data row so stacked area marks\n // get original rows instead of pivot rows.\n const seriesKeys = new Set<string>();\n const xValueSet = new Set<string>();\n const rowsByXSeries = new Map<string, DataRow>();\n const rowsByX = new Map<string, DataRow[]>();\n\n for (const row of sortedData) {\n const xStr = String(row[xChannel.field]);\n const series = String(row[colorField]);\n seriesKeys.add(series);\n xValueSet.add(xStr);\n rowsByXSeries.set(`${xStr}::${series}`, row);\n\n const existing = rowsByX.get(xStr);\n if (existing) {\n existing.push(row);\n } else {\n rowsByX.set(xStr, [row]);\n }\n }\n\n const keys = Array.from(seriesKeys);\n const xValues = Array.from(xValueSet);\n\n // Build a pivot table: one row per x value, one column per series\n const pivotData: Record<string, unknown>[] = xValues.map((xVal) => {\n const pivot: Record<string, unknown> = { __x__: xVal };\n for (const key of keys) {\n pivot[key] = 0;\n }\n // Fill in actual values from pre-grouped data\n const xRows = rowsByX.get(xVal);\n if (xRows) {\n for (const row of xRows) {\n const series = String(row[colorField]);\n pivot[series] = row[yChannel.field] ?? 0;\n }\n }\n return pivot;\n });\n\n // Resolve stack offset from the y channel's stack property\n const stackProp = yChannel.stack;\n const offsetFn =\n stackProp === 'normalize'\n ? stackOffsetExpand\n : stackProp === 'center'\n ? stackOffsetSilhouette\n : stackOffsetNone;\n\n // Use d3 stack to compute the stacked layout\n const stackGenerator = stack<Record<string, unknown>>()\n .keys(keys)\n .order(stackOrderNone)\n .offset(offsetFn);\n\n const stackedData = stackGenerator(pivotData);\n const yScale = scales.y.scale as ScaleLinear<number, number>;\n const marks: AreaMark[] = [];\n\n for (const layer of stackedData) {\n const seriesKey = layer.key;\n const color = getColor(scales, seriesKey);\n\n const validPoints: { x: number; yTop: number; yBottom: number }[] = [];\n\n for (const d of layer) {\n const xVal = scaleValue(scales.x.scale, scales.x.type, d.data.__x__);\n\n if (xVal === null) continue;\n\n const yTop = yScale(d[1] as number);\n const yBottom = yScale(d[0] as number);\n\n validPoints.push({ x: xVal, yTop, yBottom });\n }\n\n if (validPoints.length === 0) continue;\n\n const stackCurve = resolveCurve(spec.markDef.interpolate);\n const areaGenerator = area<{ x: number; yTop: number; yBottom: number }>()\n .x((p) => p.x)\n .y0((p) => p.yBottom)\n .y1((p) => p.yTop)\n .curve(stackCurve);\n\n const pathStr = areaGenerator(validPoints) ?? '';\n\n const topLineGenerator = line<{ x: number; yTop: number }>()\n .x((p) => p.x)\n .y((p) => p.yTop)\n .curve(stackCurve);\n const topPathStr = topLineGenerator(validPoints) ?? '';\n\n const topPoints = validPoints.map((p) => ({ x: p.x, y: p.yTop }));\n const bottomPoints = validPoints.map((p) => ({ x: p.x, y: p.yBottom }));\n\n const aria: MarkAria = {\n label: `${seriesKey}: stacked area with ${validPoints.length} data points`,\n };\n\n marks.push({\n type: 'area',\n topPoints,\n bottomPoints,\n path: pathStr,\n topPath: topPathStr,\n fill: color,\n fillOpacity: 0.7, // Higher opacity for stacked so layers are visible\n stroke: getRepresentativeColor(color),\n strokeWidth: 1,\n seriesKey,\n data: layer.map((d) => {\n const xStr = String(d.data.__x__);\n return (rowsByXSeries.get(`${xStr}::${seriesKey}`) ?? d.data) as Record<string, unknown>;\n }),\n dataPoints: validPoints.map((p, idx) => {\n const xStr = String(layer[idx]?.data.__x__);\n const datum = (rowsByXSeries.get(`${xStr}::${seriesKey}`) ??\n layer[idx]?.data ??\n {}) as Record<string, unknown>;\n return { x: p.x, y: p.yTop, datum };\n }),\n aria,\n });\n }\n\n return marks;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute area marks from a normalized chart spec.\n *\n * For multi-series with color encoding, produces stacked areas.\n * For single series, produces a simple area fill from the line to baseline (y=0).\n */\nexport function computeAreaMarks(\n spec: NormalizedChartSpec,\n scales: ResolvedScales,\n chartArea: Rect,\n): AreaMark[] {\n const encoding = spec.encoding as Encoding;\n const hasColor = !!encoding.color;\n\n if (hasColor) {\n return computeStackedArea(spec, scales, chartArea);\n }\n\n return computeSingleArea(spec, scales, chartArea);\n}\n","export default function(x) {\n return function constant() {\n return x;\n };\n}\n","export const abs = Math.abs;\nexport const atan2 = Math.atan2;\nexport const cos = Math.cos;\nexport const max = Math.max;\nexport const min = Math.min;\nexport const sin = Math.sin;\nexport const sqrt = Math.sqrt;\n\nexport const epsilon = 1e-12;\nexport const pi = Math.PI;\nexport const halfPi = pi / 2;\nexport const tau = 2 * pi;\n\nexport function acos(x) {\n return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);\n}\n\nexport function asin(x) {\n return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x);\n}\n","const pi = Math.PI,\n tau = 2 * pi,\n epsilon = 1e-6,\n tauEpsilon = tau - epsilon;\n\nfunction append(strings) {\n this._ += strings[0];\n for (let i = 1, n = strings.length; i < n; ++i) {\n this._ += arguments[i] + strings[i];\n }\n}\n\nfunction appendRound(digits) {\n let d = Math.floor(digits);\n if (!(d >= 0)) throw new Error(`invalid digits: ${digits}`);\n if (d > 15) return append;\n const k = 10 ** d;\n return function(strings) {\n this._ += strings[0];\n for (let i = 1, n = strings.length; i < n; ++i) {\n this._ += Math.round(arguments[i] * k) / k + strings[i];\n }\n };\n}\n\nexport class Path {\n constructor(digits) {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n this._append = digits == null ? append : appendRound(digits);\n }\n moveTo(x, y) {\n this._append`M${this._x0 = this._x1 = +x},${this._y0 = this._y1 = +y}`;\n }\n closePath() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._append`Z`;\n }\n }\n lineTo(x, y) {\n this._append`L${this._x1 = +x},${this._y1 = +y}`;\n }\n quadraticCurveTo(x1, y1, x, y) {\n this._append`Q${+x1},${+y1},${this._x1 = +x},${this._y1 = +y}`;\n }\n bezierCurveTo(x1, y1, x2, y2, x, y) {\n this._append`C${+x1},${+y1},${+x2},${+y2},${this._x1 = +x},${this._y1 = +y}`;\n }\n arcTo(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(`negative radius: ${r}`);\n\n let x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._append`M${this._x1 = x1},${this._y1 = y1}`;\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon));\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {\n this._append`L${this._x1 = x1},${this._y1 = y1}`;\n }\n\n // Otherwise, draw an arc!\n else {\n let x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon) {\n this._append`L${x1 + t01 * x01},${y1 + t01 * y01}`;\n }\n\n this._append`A${r},${r},0,0,${+(y01 * x20 > x01 * y20)},${this._x1 = x1 + t21 * x21},${this._y1 = y1 + t21 * y21}`;\n }\n }\n arc(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r, ccw = !!ccw;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(`negative radius: ${r}`);\n\n let dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._append`M${x0},${y0}`;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {\n this._append`L${x0},${y0}`;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau + tau;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._append`A${r},${r},0,1,${cw},${x - dx},${y - dy}A${r},${r},0,1,${cw},${this._x1 = x0},${this._y1 = y0}`;\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon) {\n this._append`A${r},${r},0,${+(da >= pi)},${cw},${this._x1 = x + r * Math.cos(a1)},${this._y1 = y + r * Math.sin(a1)}`;\n }\n }\n rect(x, y, w, h) {\n this._append`M${this._x0 = this._x1 = +x},${this._y0 = this._y1 = +y}h${w = +w}v${+h}h${-w}Z`;\n }\n toString() {\n return this._;\n }\n}\n\nexport function path() {\n return new Path;\n}\n\n// Allow instanceof d3.path\npath.prototype = Path.prototype;\n\nexport function pathRound(digits = 3) {\n return new Path(+digits);\n}\n","import {Path} from \"d3-path\";\n\nexport function withPath(shape) {\n let digits = 3;\n\n shape.digits = function(_) {\n if (!arguments.length) return digits;\n if (_ == null) {\n digits = null;\n } else {\n const d = Math.floor(_);\n if (!(d >= 0)) throw new RangeError(`invalid digits: ${_}`);\n digits = d;\n }\n return shape;\n };\n\n return () => new Path(digits);\n}\n","import constant from \"./constant.js\";\nimport {abs, acos, asin, atan2, cos, epsilon, halfPi, max, min, pi, sin, sqrt, tau} from \"./math.js\";\nimport {withPath} from \"./path.js\";\n\nfunction arcInnerRadius(d) {\n return d.innerRadius;\n}\n\nfunction arcOuterRadius(d) {\n return d.outerRadius;\n}\n\nfunction arcStartAngle(d) {\n return d.startAngle;\n}\n\nfunction arcEndAngle(d) {\n return d.endAngle;\n}\n\nfunction arcPadAngle(d) {\n return d && d.padAngle; // Note: optional!\n}\n\nfunction intersect(x0, y0, x1, y1, x2, y2, x3, y3) {\n var x10 = x1 - x0, y10 = y1 - y0,\n x32 = x3 - x2, y32 = y3 - y2,\n t = y32 * x10 - x32 * y10;\n if (t * t < epsilon) return;\n t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / t;\n return [x0 + t * x10, y0 + t * y10];\n}\n\n// Compute perpendicular offset line of length rc.\n// http://mathworld.wolfram.com/Circle-LineIntersection.html\nfunction cornerTangents(x0, y0, x1, y1, r1, rc, cw) {\n var x01 = x0 - x1,\n y01 = y0 - y1,\n lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01),\n ox = lo * y01,\n oy = -lo * x01,\n x11 = x0 + ox,\n y11 = y0 + oy,\n x10 = x1 + ox,\n y10 = y1 + oy,\n x00 = (x11 + x10) / 2,\n y00 = (y11 + y10) / 2,\n dx = x10 - x11,\n dy = y10 - y11,\n d2 = dx * dx + dy * dy,\n r = r1 - rc,\n D = x11 * y10 - x10 * y11,\n d = (dy < 0 ? -1 : 1) * sqrt(max(0, r * r * d2 - D * D)),\n cx0 = (D * dy - dx * d) / d2,\n cy0 = (-D * dx - dy * d) / d2,\n cx1 = (D * dy + dx * d) / d2,\n cy1 = (-D * dx + dy * d) / d2,\n dx0 = cx0 - x00,\n dy0 = cy0 - y00,\n dx1 = cx1 - x00,\n dy1 = cy1 - y00;\n\n // Pick the closer of the two intersection points.\n // TODO Is there a faster way to determine which intersection to use?\n if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;\n\n return {\n cx: cx0,\n cy: cy0,\n x01: -ox,\n y01: -oy,\n x11: cx0 * (r1 / r - 1),\n y11: cy0 * (r1 / r - 1)\n };\n}\n\nexport default function() {\n var innerRadius = arcInnerRadius,\n outerRadius = arcOuterRadius,\n cornerRadius = constant(0),\n padRadius = null,\n startAngle = arcStartAngle,\n endAngle = arcEndAngle,\n padAngle = arcPadAngle,\n context = null,\n path = withPath(arc);\n\n function arc() {\n var buffer,\n r,\n r0 = +innerRadius.apply(this, arguments),\n r1 = +outerRadius.apply(this, arguments),\n a0 = startAngle.apply(this, arguments) - halfPi,\n a1 = endAngle.apply(this, arguments) - halfPi,\n da = abs(a1 - a0),\n cw = a1 > a0;\n\n if (!context) context = buffer = path();\n\n // Ensure that the outer radius is always larger than the inner radius.\n if (r1 < r0) r = r1, r1 = r0, r0 = r;\n\n // Is it a point?\n if (!(r1 > epsilon)) context.moveTo(0, 0);\n\n // Or is it a circle or annulus?\n else if (da > tau - epsilon) {\n context.moveTo(r1 * cos(a0), r1 * sin(a0));\n context.arc(0, 0, r1, a0, a1, !cw);\n if (r0 > epsilon) {\n context.moveTo(r0 * cos(a1), r0 * sin(a1));\n context.arc(0, 0, r0, a1, a0, cw);\n }\n }\n\n // Or is it a circular or annular sector?\n else {\n var a01 = a0,\n a11 = a1,\n a00 = a0,\n a10 = a1,\n da0 = da,\n da1 = da,\n ap = padAngle.apply(this, arguments) / 2,\n rp = (ap > epsilon) && (padRadius ? +padRadius.apply(this, arguments) : sqrt(r0 * r0 + r1 * r1)),\n rc = min(abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),\n rc0 = rc,\n rc1 = rc,\n t0,\n t1;\n\n // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.\n if (rp > epsilon) {\n var p0 = asin(rp / r0 * sin(ap)),\n p1 = asin(rp / r1 * sin(ap));\n if ((da0 -= p0 * 2) > epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;\n else da0 = 0, a00 = a10 = (a0 + a1) / 2;\n if ((da1 -= p1 * 2) > epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;\n else da1 = 0, a01 = a11 = (a0 + a1) / 2;\n }\n\n var x01 = r1 * cos(a01),\n y01 = r1 * sin(a01),\n x10 = r0 * cos(a10),\n y10 = r0 * sin(a10);\n\n // Apply rounded corners?\n if (rc > epsilon) {\n var x11 = r1 * cos(a11),\n y11 = r1 * sin(a11),\n x00 = r0 * cos(a00),\n y00 = r0 * sin(a00),\n oc;\n\n // Restrict the corner radius according to the sector angle. If this\n // intersection fails, it’s probably because the arc is too small, so\n // disable the corner radius entirely.\n if (da < pi) {\n if (oc = intersect(x01, y01, x00, y00, x11, y11, x10, y10)) {\n var ax = x01 - oc[0],\n ay = y01 - oc[1],\n bx = x11 - oc[0],\n by = y11 - oc[1],\n kc = 1 / sin(acos((ax * bx + ay * by) / (sqrt(ax * ax + ay * ay) * sqrt(bx * bx + by * by))) / 2),\n lc = sqrt(oc[0] * oc[0] + oc[1] * oc[1]);\n rc0 = min(rc, (r0 - lc) / (kc - 1));\n rc1 = min(rc, (r1 - lc) / (kc + 1));\n } else {\n rc0 = rc1 = 0;\n }\n }\n }\n\n // Is the sector collapsed to a line?\n if (!(da1 > epsilon)) context.moveTo(x01, y01);\n\n // Does the sector’s outer ring have rounded corners?\n else if (rc1 > epsilon) {\n t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);\n t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);\n\n context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n // Have the corners merged?\n if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);\n\n // Otherwise, draw the two corners and the ring.\n else {\n context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);\n context.arc(0, 0, r1, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);\n context.arc(t1.cx, t1.cy, rc1, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);\n }\n }\n\n // Or is the outer ring just a circular arc?\n else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);\n\n // Is there no inner ring, and it’s a circular sector?\n // Or perhaps it’s an annular sector collapsed due to padding?\n if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10);\n\n // Does the sector’s inner ring (or point) have rounded corners?\n else if (rc0 > epsilon) {\n t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);\n t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);\n\n context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n // Have the corners merged?\n if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);\n\n // Otherwise, draw the two corners and the ring.\n else {\n context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);\n context.arc(0, 0, r0, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw);\n context.arc(t1.cx, t1.cy, rc0, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);\n }\n }\n\n // Or is the inner ring just a circular arc?\n else context.arc(0, 0, r0, a10, a00, cw);\n }\n\n context.closePath();\n\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n arc.centroid = function() {\n var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,\n a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2;\n return [cos(a) * r, sin(a) * r];\n };\n\n arc.innerRadius = function(_) {\n return arguments.length ? (innerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : innerRadius;\n };\n\n arc.outerRadius = function(_) {\n return arguments.length ? (outerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : outerRadius;\n };\n\n arc.cornerRadius = function(_) {\n return arguments.length ? (cornerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : cornerRadius;\n };\n\n arc.padRadius = function(_) {\n return arguments.length ? (padRadius = _ == null ? null : typeof _ === \"function\" ? _ : constant(+_), arc) : padRadius;\n };\n\n arc.startAngle = function(_) {\n return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : startAngle;\n };\n\n arc.endAngle = function(_) {\n return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : endAngle;\n };\n\n arc.padAngle = function(_) {\n return arguments.length ? (padAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : padAngle;\n };\n\n arc.context = function(_) {\n return arguments.length ? ((context = _ == null ? null : _), arc) : context;\n };\n\n return arc;\n}\n","export var slice = Array.prototype.slice;\n\nexport default function(x) {\n return typeof x === \"object\" && \"length\" in x\n ? x // Array, TypedArray, NodeList, array-like\n : Array.from(x); // Map, Set, iterable, string, or anything else\n}\n","function Linear(context) {\n this._context = context;\n}\n\nLinear.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // falls through\n default: this._context.lineTo(x, y); break;\n }\n }\n};\n\nexport default function(context) {\n return new Linear(context);\n}\n","export function x(p) {\n return p[0];\n}\n\nexport function y(p) {\n return p[1];\n}\n","import array from \"./array.js\";\nimport constant from \"./constant.js\";\nimport curveLinear from \"./curve/linear.js\";\nimport {withPath} from \"./path.js\";\nimport {x as pointX, y as pointY} from \"./point.js\";\n\nexport default function(x, y) {\n var defined = constant(true),\n context = null,\n curve = curveLinear,\n output = null,\n path = withPath(line);\n\n x = typeof x === \"function\" ? x : (x === undefined) ? pointX : constant(x);\n y = typeof y === \"function\" ? y : (y === undefined) ? pointY : constant(y);\n\n function line(data) {\n var i,\n n = (data = array(data)).length,\n d,\n defined0 = false,\n buffer;\n\n if (context == null) output = curve(buffer = path());\n\n for (i = 0; i <= n; ++i) {\n if (!(i < n && defined(d = data[i], i, data)) === defined0) {\n if (defined0 = !defined0) output.lineStart();\n else output.lineEnd();\n }\n if (defined0) output.point(+x(d, i, data), +y(d, i, data));\n }\n\n if (buffer) return output = null, buffer + \"\" || null;\n }\n\n line.x = function(_) {\n return arguments.length ? (x = typeof _ === \"function\" ? _ : constant(+_), line) : x;\n };\n\n line.y = function(_) {\n return arguments.length ? (y = typeof _ === \"function\" ? _ : constant(+_), line) : y;\n };\n\n line.defined = function(_) {\n return arguments.length ? (defined = typeof _ === \"function\" ? _ : constant(!!_), line) : defined;\n };\n\n line.curve = function(_) {\n return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;\n };\n\n line.context = function(_) {\n return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;\n };\n\n return line;\n}\n","import array from \"./array.js\";\nimport constant from \"./constant.js\";\nimport curveLinear from \"./curve/linear.js\";\nimport line from \"./line.js\";\nimport {withPath} from \"./path.js\";\nimport {x as pointX, y as pointY} from \"./point.js\";\n\nexport default function(x0, y0, y1) {\n var x1 = null,\n defined = constant(true),\n context = null,\n curve = curveLinear,\n output = null,\n path = withPath(area);\n\n x0 = typeof x0 === \"function\" ? x0 : (x0 === undefined) ? pointX : constant(+x0);\n y0 = typeof y0 === \"function\" ? y0 : (y0 === undefined) ? constant(0) : constant(+y0);\n y1 = typeof y1 === \"function\" ? y1 : (y1 === undefined) ? pointY : constant(+y1);\n\n function area(data) {\n var i,\n j,\n k,\n n = (data = array(data)).length,\n d,\n defined0 = false,\n buffer,\n x0z = new Array(n),\n y0z = new Array(n);\n\n if (context == null) output = curve(buffer = path());\n\n for (i = 0; i <= n; ++i) {\n if (!(i < n && defined(d = data[i], i, data)) === defined0) {\n if (defined0 = !defined0) {\n j = i;\n output.areaStart();\n output.lineStart();\n } else {\n output.lineEnd();\n output.lineStart();\n for (k = i - 1; k >= j; --k) {\n output.point(x0z[k], y0z[k]);\n }\n output.lineEnd();\n output.areaEnd();\n }\n }\n if (defined0) {\n x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);\n output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);\n }\n }\n\n if (buffer) return output = null, buffer + \"\" || null;\n }\n\n function arealine() {\n return line().defined(defined).curve(curve).context(context);\n }\n\n area.x = function(_) {\n return arguments.length ? (x0 = typeof _ === \"function\" ? _ : constant(+_), x1 = null, area) : x0;\n };\n\n area.x0 = function(_) {\n return arguments.length ? (x0 = typeof _ === \"function\" ? _ : constant(+_), area) : x0;\n };\n\n area.x1 = function(_) {\n return arguments.length ? (x1 = _ == null ? null : typeof _ === \"function\" ? _ : constant(+_), area) : x1;\n };\n\n area.y = function(_) {\n return arguments.length ? (y0 = typeof _ === \"function\" ? _ : constant(+_), y1 = null, area) : y0;\n };\n\n area.y0 = function(_) {\n return arguments.length ? (y0 = typeof _ === \"function\" ? _ : constant(+_), area) : y0;\n };\n\n area.y1 = function(_) {\n return arguments.length ? (y1 = _ == null ? null : typeof _ === \"function\" ? _ : constant(+_), area) : y1;\n };\n\n area.lineX0 =\n area.lineY0 = function() {\n return arealine().x(x0).y(y0);\n };\n\n area.lineY1 = function() {\n return arealine().x(x0).y(y1);\n };\n\n area.lineX1 = function() {\n return arealine().x(x1).y(y0);\n };\n\n area.defined = function(_) {\n return arguments.length ? (defined = typeof _ === \"function\" ? _ : constant(!!_), area) : defined;\n };\n\n area.curve = function(_) {\n return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;\n };\n\n area.context = function(_) {\n return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;\n };\n\n return area;\n}\n","export default function(a, b) {\n return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;\n}\n","export default function(d) {\n return d;\n}\n","import array from \"./array.js\";\nimport constant from \"./constant.js\";\nimport descending from \"./descending.js\";\nimport identity from \"./identity.js\";\nimport {tau} from \"./math.js\";\n\nexport default function() {\n var value = identity,\n sortValues = descending,\n sort = null,\n startAngle = constant(0),\n endAngle = constant(tau),\n padAngle = constant(0);\n\n function pie(data) {\n var i,\n n = (data = array(data)).length,\n j,\n k,\n sum = 0,\n index = new Array(n),\n arcs = new Array(n),\n a0 = +startAngle.apply(this, arguments),\n da = Math.min(tau, Math.max(-tau, endAngle.apply(this, arguments) - a0)),\n a1,\n p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),\n pa = p * (da < 0 ? -1 : 1),\n v;\n\n for (i = 0; i < n; ++i) {\n if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {\n sum += v;\n }\n }\n\n // Optionally sort the arcs by previously-computed values or by data.\n if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });\n else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });\n\n // Compute the arcs! They are stored in the original data's order.\n for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {\n j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {\n data: data[j],\n index: i,\n value: v,\n startAngle: a0,\n endAngle: a1,\n padAngle: p\n };\n }\n\n return arcs;\n }\n\n pie.value = function(_) {\n return arguments.length ? (value = typeof _ === \"function\" ? _ : constant(+_), pie) : value;\n };\n\n pie.sortValues = function(_) {\n return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;\n };\n\n pie.sort = function(_) {\n return arguments.length ? (sort = _, sortValues = null, pie) : sort;\n };\n\n pie.startAngle = function(_) {\n return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant(+_), pie) : startAngle;\n };\n\n pie.endAngle = function(_) {\n return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant(+_), pie) : endAngle;\n };\n\n pie.padAngle = function(_) {\n return arguments.length ? (padAngle = typeof _ === \"function\" ? _ : constant(+_), pie) : padAngle;\n };\n\n return pie;\n}\n","export function point(that, x, y) {\n that._context.bezierCurveTo(\n (2 * that._x0 + that._x1) / 3,\n (2 * that._y0 + that._y1) / 3,\n (that._x0 + 2 * that._x1) / 3,\n (that._y0 + 2 * that._y1) / 3,\n (that._x0 + 4 * that._x1 + x) / 6,\n (that._y0 + 4 * that._y1 + y) / 6\n );\n}\n\nexport function Basis(context) {\n this._context = context;\n}\n\nBasis.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 3: point(this, this._x1, this._y1); // falls through\n case 2: this._context.lineTo(this._x1, this._y1); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // falls through\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nexport default function(context) {\n return new Basis(context);\n}\n","export function point(that, x, y) {\n that._context.bezierCurveTo(\n that._x1 + that._k * (that._x2 - that._x0),\n that._y1 + that._k * (that._y2 - that._y0),\n that._x2 + that._k * (that._x1 - x),\n that._y2 + that._k * (that._y1 - y),\n that._x2,\n that._y2\n );\n}\n\nexport function Cardinal(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinal.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x2, this._y2); break;\n case 3: point(this, this._x1, this._y1); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; this._x1 = x, this._y1 = y; break;\n case 2: this._point = 3; // falls through\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(tension) {\n\n function cardinal(context) {\n return new Cardinal(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n","function sign(x) {\n return x < 0 ? -1 : 1;\n}\n\n// Calculate the slopes of the tangents (Hermite-type interpolation) based on\n// the following paper: Steffen, M. 1990. A Simple Method for Monotonic\n// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.\n// NOV(II), P. 443, 1990.\nfunction slope3(that, x2, y2) {\n var h0 = that._x1 - that._x0,\n h1 = x2 - that._x1,\n s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),\n s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),\n p = (s0 * h1 + s1 * h0) / (h0 + h1);\n return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;\n}\n\n// Calculate a one-sided slope.\nfunction slope2(that, t) {\n var h = that._x1 - that._x0;\n return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;\n}\n\n// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations\n// \"you can express cubic Hermite interpolation in terms of cubic Bézier curves\n// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1\".\nfunction point(that, t0, t1) {\n var x0 = that._x0,\n y0 = that._y0,\n x1 = that._x1,\n y1 = that._y1,\n dx = (x1 - x0) / 3;\n that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);\n}\n\nfunction MonotoneX(context) {\n this._context = context;\n}\n\nMonotoneX.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 =\n this._t0 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x1, this._y1); break;\n case 3: point(this, this._t0, slope2(this, this._t0)); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n var t1 = NaN;\n\n x = +x, y = +y;\n if (x === this._x1 && y === this._y1) return; // Ignore coincident points.\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; point(this, slope2(this, t1 = slope3(this, x, y)), t1); break;\n default: point(this, this._t0, t1 = slope3(this, x, y)); break;\n }\n\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n this._t0 = t1;\n }\n}\n\nfunction MonotoneY(context) {\n this._context = new ReflectContext(context);\n}\n\n(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {\n MonotoneX.prototype.point.call(this, y, x);\n};\n\nfunction ReflectContext(context) {\n this._context = context;\n}\n\nReflectContext.prototype = {\n moveTo: function(x, y) { this._context.moveTo(y, x); },\n closePath: function() { this._context.closePath(); },\n lineTo: function(x, y) { this._context.lineTo(y, x); },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }\n};\n\nexport function monotoneX(context) {\n return new MonotoneX(context);\n}\n\nexport function monotoneY(context) {\n return new MonotoneY(context);\n}\n","function Natural(context) {\n this._context = context;\n}\n\nNatural.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x = [];\n this._y = [];\n },\n lineEnd: function() {\n var x = this._x,\n y = this._y,\n n = x.length;\n\n if (n) {\n this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);\n if (n === 2) {\n this._context.lineTo(x[1], y[1]);\n } else {\n var px = controlPoints(x),\n py = controlPoints(y);\n for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {\n this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);\n }\n }\n }\n\n if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();\n this._line = 1 - this._line;\n this._x = this._y = null;\n },\n point: function(x, y) {\n this._x.push(+x);\n this._y.push(+y);\n }\n};\n\n// See https://www.particleincell.com/2012/bezier-splines/ for derivation.\nfunction controlPoints(x) {\n var i,\n n = x.length - 1,\n m,\n a = new Array(n),\n b = new Array(n),\n r = new Array(n);\n a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];\n for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];\n a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];\n for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];\n a[n - 1] = r[n - 1] / b[n - 1];\n for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];\n b[n - 1] = (x[n] + a[n - 1]) / 2;\n for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];\n return [a, b];\n}\n\nexport default function(context) {\n return new Natural(context);\n}\n","function Step(context, t) {\n this._context = context;\n this._t = t;\n}\n\nStep.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x = this._y = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // falls through\n default: {\n if (this._t <= 0) {\n this._context.lineTo(this._x, y);\n this._context.lineTo(x, y);\n } else {\n var x1 = this._x * (1 - this._t) + x * this._t;\n this._context.lineTo(x1, this._y);\n this._context.lineTo(x1, y);\n }\n break;\n }\n }\n this._x = x, this._y = y;\n }\n};\n\nexport default function(context) {\n return new Step(context, 0.5);\n}\n\nexport function stepBefore(context) {\n return new Step(context, 0);\n}\n\nexport function stepAfter(context) {\n return new Step(context, 1);\n}\n","export default function(series, order) {\n if (!((n = series.length) > 1)) return;\n for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {\n s0 = s1, s1 = series[order[i]];\n for (j = 0; j < m; ++j) {\n s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];\n }\n }\n}\n","export default function(series) {\n var n = series.length, o = new Array(n);\n while (--n >= 0) o[n] = n;\n return o;\n}\n","import array from \"./array.js\";\nimport constant from \"./constant.js\";\nimport offsetNone from \"./offset/none.js\";\nimport orderNone from \"./order/none.js\";\n\nfunction stackValue(d, key) {\n return d[key];\n}\n\nfunction stackSeries(key) {\n const series = [];\n series.key = key;\n return series;\n}\n\nexport default function() {\n var keys = constant([]),\n order = orderNone,\n offset = offsetNone,\n value = stackValue;\n\n function stack(data) {\n var sz = Array.from(keys.apply(this, arguments), stackSeries),\n i, n = sz.length, j = -1,\n oz;\n\n for (const d of data) {\n for (i = 0, ++j; i < n; ++i) {\n (sz[i][j] = [0, +value(d, sz[i].key, j, data)]).data = d;\n }\n }\n\n for (i = 0, oz = array(order(sz)); i < n; ++i) {\n sz[oz[i]].index = i;\n }\n\n offset(sz, oz);\n return sz;\n }\n\n stack.keys = function(_) {\n return arguments.length ? (keys = typeof _ === \"function\" ? _ : constant(Array.from(_)), stack) : keys;\n };\n\n stack.value = function(_) {\n return arguments.length ? (value = typeof _ === \"function\" ? _ : constant(+_), stack) : value;\n };\n\n stack.order = function(_) {\n return arguments.length ? (order = _ == null ? orderNone : typeof _ === \"function\" ? _ : constant(Array.from(_)), stack) : order;\n };\n\n stack.offset = function(_) {\n return arguments.length ? (offset = _ == null ? offsetNone : _, stack) : offset;\n };\n\n return stack;\n}\n","import none from \"./none.js\";\n\nexport default function(series, order) {\n if (!((n = series.length) > 0)) return;\n for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {\n for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;\n if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;\n }\n none(series, order);\n}\n","import none from \"./none.js\";\n\nexport default function(series, order) {\n if (!((n = series.length) > 0)) return;\n for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {\n for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;\n s0[j][1] += s0[j][0] = -y / 2;\n }\n none(series, order);\n}\n","/**\n * Curve interpolation mapping.\n *\n * Maps Vega-Lite-style interpolation strings to d3-shape curve factories.\n * Used by both line and area chart computations.\n */\n\nimport type { MarkDef } from '@opendata-ai/openchart-core';\nimport type { CurveFactory } from 'd3-shape';\nimport {\n curveBasis,\n curveCardinal,\n curveLinear,\n curveMonotoneX,\n curveNatural,\n curveStep,\n curveStepAfter,\n curveStepBefore,\n} from 'd3-shape';\n\n/** Map of interpolation string names to d3 curve factories. */\nconst CURVE_MAP: Record<NonNullable<MarkDef['interpolate']>, CurveFactory> = {\n linear: curveLinear,\n monotone: curveMonotoneX,\n step: curveStep,\n 'step-before': curveStepBefore,\n 'step-after': curveStepAfter,\n basis: curveBasis,\n cardinal: curveCardinal,\n natural: curveNatural,\n};\n\n/**\n * Resolve an interpolation string to a d3 curve factory.\n * Defaults to `curveMonotoneX` when no interpolation is specified.\n */\nexport function resolveCurve(interpolate?: MarkDef['interpolate']): CurveFactory {\n if (!interpolate) return curveMonotoneX;\n return CURVE_MAP[interpolate] ?? curveMonotoneX;\n}\n","/**\n * Line chart mark computation.\n *\n * Takes a normalized chart spec with resolved scales and produces\n * LineMark[] and PointMark[] arrays for rendering. Groups data by\n * color field for multi-series, uses D3 line() generator for SVG\n * path computation, and handles missing data with line breaks.\n */\n\nimport type {\n DataRow,\n Encoding,\n GradientDef,\n LayoutStrategy,\n LineMark,\n MarkAria,\n PointMark,\n Rect,\n} from '@opendata-ai/openchart-core';\nimport { getRepresentativeColor } from '@opendata-ai/openchart-core';\nimport { line } from 'd3-shape';\n\nimport type { NormalizedChartSpec } from '../../compiler/types';\nimport type { ResolvedScales } from '../../layout/scales';\nimport { getColor, getSequentialColor, groupByField, scaleValue, sortByField } from '../utils';\nimport { resolveCurve } from './curves';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Default stroke width for line marks. */\nconst DEFAULT_STROKE_WIDTH = 2.5;\n\n/** Default radius for point marks (hover targets). */\nconst DEFAULT_POINT_RADIUS = 3;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute line marks from a normalized chart spec.\n *\n * Produces one LineMark per series (grouped by color field) plus\n * PointMark entries at each data point for hover targets. Missing\n * data (null/undefined y values) breaks the line path.\n */\nexport function computeLineMarks(\n spec: NormalizedChartSpec,\n scales: ResolvedScales,\n _chartArea: Rect,\n _strategy: LayoutStrategy,\n): (LineMark | PointMark)[] {\n const encoding = spec.encoding as Encoding;\n const xChannel = encoding.x;\n const yChannel = encoding.y;\n\n if (!xChannel || !yChannel || !scales.x || !scales.y) {\n return [];\n }\n\n const colorEnc = encoding.color && 'field' in encoding.color ? encoding.color : undefined;\n const isSequentialColor = colorEnc?.type === 'quantitative';\n // Sequential color: single series, per-point coloring. Categorical: group by color field.\n const colorField = isSequentialColor ? undefined : colorEnc?.field;\n const sequentialColorField = isSequentialColor ? colorEnc.field : undefined;\n const groups = groupByField(spec.data, colorField);\n const marks: (LineMark | PointMark)[] = [];\n\n for (const [seriesKey, rows] of groups) {\n // For sequential color, use a mid-range color for the line stroke\n const color: string | GradientDef = isSequentialColor\n ? getSequentialColor(scales, _getMidValue(rows, sequentialColorField!))\n : getColor(scales, seriesKey);\n const strokeColor = getRepresentativeColor(color);\n\n // Sort rows by x-axis field so lines draw left-to-right.\n // For nominal/ordinal axes, preserve data order since there's no\n // natural sort and the scale domain already reflects intended order.\n const sortedRows =\n xChannel.type === 'nominal' || xChannel.type === 'ordinal'\n ? rows\n : sortByField(rows, xChannel.field);\n\n // Compute pixel positions for each data point, preserving nulls\n // for line break handling\n const pointsWithData: {\n x: number;\n y: number;\n row: DataRow;\n }[] = [];\n\n // We need to track segments separated by null values\n const segments: { x: number; y: number }[][] = [];\n let currentSegment: { x: number; y: number }[] = [];\n\n for (const row of sortedRows) {\n const xVal = scaleValue(scales.x.scale, scales.x.type, row[xChannel.field]);\n const yVal = scaleValue(scales.y.scale, scales.y.type, row[yChannel.field]);\n\n if (xVal === null || yVal === null) {\n // Break the line here. Push current segment if non-empty.\n if (currentSegment.length > 0) {\n segments.push(currentSegment);\n currentSegment = [];\n }\n continue;\n }\n\n const point = { x: xVal, y: yVal };\n currentSegment.push(point);\n pointsWithData.push({ ...point, row });\n }\n\n // Push the last segment\n if (currentSegment.length > 0) {\n segments.push(currentSegment);\n }\n\n // Build the D3 line generator with configured interpolation\n const curve = resolveCurve(spec.markDef.interpolate);\n const lineGenerator = line<{ x: number; y: number }>()\n .x((d) => d.x)\n .y((d) => d.y)\n .curve(curve);\n\n // Combine all segments into a single path string with M/L commands.\n // Each segment starts a new M (moveto) command, creating line breaks\n // where data is missing.\n const allPoints: { x: number; y: number }[] = [];\n const pathParts: string[] = [];\n\n for (const segment of segments) {\n if (segment.length === 0) continue;\n const pathStr = lineGenerator(segment);\n if (pathStr) {\n pathParts.push(pathStr);\n }\n allPoints.push(...segment);\n }\n\n // Skip this series if there are no valid data points\n if (allPoints.length === 0) continue;\n\n const ariaLabel =\n seriesKey === '__default__'\n ? `Line with ${allPoints.length} data points`\n : `${seriesKey}: line with ${allPoints.length} data points`;\n\n const aria: MarkAria = {\n label: ariaLabel,\n };\n\n // Combine D3 curve path segments into a single path string.\n // Each segment produces a smooth monotone curve; line breaks between\n // segments are created by starting a new M command.\n const combinedPath = pathParts.join(' ');\n\n // Look up per-series style overrides\n const seriesStyleKey = seriesKey === '__default__' ? undefined : seriesKey;\n const styleOverride = seriesStyleKey ? spec.seriesStyles?.[seriesStyleKey] : undefined;\n\n // Map lineStyle to SVG strokeDasharray\n let strokeDasharray: string | undefined;\n if (styleOverride?.lineStyle === 'dashed') strokeDasharray = '6 4';\n else if (styleOverride?.lineStyle === 'dotted') strokeDasharray = '2 3';\n\n // Create the LineMark with the combined path points.\n // The points array includes all valid points across all segments.\n // dataPoints carries pixel coordinates + original data for voronoi tooltip overlay.\n const lineMark: LineMark = {\n type: 'line',\n points: allPoints,\n path: combinedPath,\n stroke: strokeColor,\n strokeWidth: styleOverride?.strokeWidth ?? DEFAULT_STROKE_WIDTH,\n strokeDasharray,\n opacity: styleOverride?.opacity,\n seriesKey: seriesStyleKey,\n data: pointsWithData.map((p) => p.row),\n dataPoints: pointsWithData.map((p) => ({ x: p.x, y: p.y, datum: p.row })),\n aria,\n };\n\n marks.push(lineMark);\n\n // Emit PointMark objects when markDef.point is truthy, or when sequential\n // color is active (points carry the gradient since SVG paths are single-color).\n const markPoint = spec.markDef.point;\n const showPoints = markPoint === true || markPoint === 'transparent' || isSequentialColor;\n\n if (showPoints) {\n const isTransparent = markPoint === 'transparent';\n // Also respect per-series showPoints override\n const seriesShowPoints = styleOverride?.showPoints !== false;\n\n for (let i = 0; i < pointsWithData.length; i++) {\n const p = pointsWithData[i];\n const visible = seriesShowPoints && !isTransparent;\n // Sequential color: each point gets colored by its data value\n let pointColor = color;\n if (isSequentialColor) {\n const val = Number(p.row[sequentialColorField!]);\n pointColor = Number.isFinite(val) ? getSequentialColor(scales, val) : color;\n }\n const pointMark: PointMark = {\n type: 'point',\n cx: p.x,\n cy: p.y,\n r: visible ? DEFAULT_POINT_RADIUS : 0,\n fill: pointColor,\n stroke: visible ? '#ffffff' : 'transparent',\n strokeWidth: visible ? 1.5 : 0,\n fillOpacity: isTransparent ? 0 : 1,\n data: p.row,\n aria: {\n label: `Data point: ${xChannel.field}=${String(p.row[xChannel.field])}, ${yChannel.field}=${String(p.row[yChannel.field])}`,\n },\n };\n marks.push(pointMark);\n }\n }\n }\n\n return marks;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Get the midpoint numeric value of a field across rows (for sequential line stroke). */\nfunction _getMidValue(rows: DataRow[], field: string): number {\n const values = rows.map((r) => Number(r[field])).filter(Number.isFinite);\n if (values.length === 0) return 0;\n const sorted = values.sort((a, b) => a - b);\n return sorted[Math.floor(sorted.length / 2)];\n}\n","/**\n * Line chart label computation.\n *\n * Produces end-of-line labels (series name at the last data point)\n * and feeds them through the core collision engine. At compact\n * breakpoints, labels are suppressed in favor of the legend.\n *\n * Respects the spec's label density setting:\n * - 'all': show every label, skip collision detection\n * - 'auto': existing behavior (collision detection)\n * - 'endpoints': first and last data point labels per series\n * - 'none': return empty map\n */\n\nimport type {\n LabelCandidate,\n LabelDensity,\n LayoutStrategy,\n LineMark,\n ResolvedLabel,\n} from '@opendata-ai/openchart-core';\nimport {\n EXTENDED_OFFSET_STRATEGIES,\n estimateTextWidth,\n resolveCollisions,\n} from '@opendata-ai/openchart-core';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Default label font size. */\nconst LABEL_FONT_SIZE = 11;\n\n/** Default label font weight. */\nconst LABEL_FONT_WEIGHT = 600;\n\n/** Horizontal offset from last point to label. */\nconst LABEL_OFFSET_X = 6;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute end-of-line labels for line marks.\n *\n * For each series, places a label at the position of the last data point.\n * At compact breakpoints (labelMode === 'none'), all labels are hidden\n * so the legend takes over. Labels go through collision detection to\n * avoid overlap.\n *\n * Returns a Map keyed by seriesKey so callers can look up labels by\n * mark identity instead of relying on positional indices.\n *\n * @param marks - Line marks (only processes marks with type === 'line').\n * @param strategy - Layout strategy from the responsive breakpoint.\n * @param density - Label density mode from spec.labels.density.\n * @returns Map of seriesKey -> ResolvedLabel after collision detection.\n */\nexport function computeLineLabels(\n marks: LineMark[],\n strategy: LayoutStrategy,\n density: LabelDensity = 'auto',\n labelOffsets?: Record<string, { dx?: number; dy?: number }>,\n): Map<string, ResolvedLabel> {\n const result = new Map<string, ResolvedLabel>();\n\n // 'none': no labels\n if (density === 'none') return result;\n\n // At compact breakpoint, suppress inline labels entirely\n if (strategy.labelMode === 'none') {\n return result;\n }\n\n const candidates: LabelCandidate[] = [];\n const seriesOrder: string[] = [];\n\n for (const mark of marks) {\n if (mark.points.length === 0) continue;\n\n const labelText = mark.seriesKey ?? '';\n if (!labelText) continue;\n\n const lastPoint = mark.points[mark.points.length - 1];\n const textWidth = estimateTextWidth(labelText, LABEL_FONT_SIZE, LABEL_FONT_WEIGHT);\n const textHeight = LABEL_FONT_SIZE * 1.2;\n\n candidates.push({\n text: labelText,\n anchorX: lastPoint.x + LABEL_OFFSET_X,\n anchorY: lastPoint.y - textHeight / 2,\n width: textWidth,\n height: textHeight,\n priority: 'data',\n style: {\n fontFamily: 'system-ui, -apple-system, sans-serif',\n fontSize: LABEL_FONT_SIZE,\n fontWeight: LABEL_FONT_WEIGHT,\n fill: mark.stroke,\n lineHeight: 1.2,\n textAnchor: 'start',\n dominantBaseline: 'central',\n },\n });\n\n seriesOrder.push(labelText);\n }\n\n if (candidates.length === 0) return result;\n\n // 'all': skip collision detection, mark everything visible\n if (density === 'all') {\n for (let i = 0; i < candidates.length; i++) {\n const c = candidates[i];\n const seriesKey = seriesOrder[i];\n const userOffset = labelOffsets?.[seriesKey];\n result.set(seriesKey, {\n text: c.text,\n x: c.anchorX + (userOffset?.dx ?? 0),\n y: c.anchorY + (userOffset?.dy ?? 0),\n style: c.style,\n visible: true,\n });\n }\n return result;\n }\n\n // 'endpoints': for line charts, endpoints means showing just the end-of-line\n // label (which is what we already compute). This is the same as 'auto' for lines\n // since we only compute the endpoint label per series.\n\n const resolved = resolveCollisions(candidates, EXTENDED_OFFSET_STRATEGIES);\n for (let i = 0; i < resolved.length; i++) {\n const seriesKey = seriesOrder[i];\n const label = resolved[i];\n // Apply user-provided per-series label offset after collision resolution\n const userOffset = labelOffsets?.[seriesKey];\n if (userOffset) {\n label.x += userOffset.dx ?? 0;\n label.y += userOffset.dy ?? 0;\n }\n result.set(seriesKey, label);\n }\n\n return result;\n}\n","/**\n * Pie / donut chart mark computation.\n *\n * Uses d3.pie() for angle calculation and d3.arc() for SVG path\n * generation. Supports sorting by value (largest first), small-slice\n * grouping into \"Other\", and donut variant with inner radius.\n */\n\nimport type {\n ArcMark,\n ConditionalValueDef,\n DataRow,\n Encoding,\n GradientDef,\n LayoutStrategy,\n MarkAria,\n Rect,\n} from '@opendata-ai/openchart-core';\nimport { isConditionalDef, isGradientDef } from '@opendata-ai/openchart-core';\nimport type { PieArcDatum } from 'd3-shape';\nimport { arc as d3Arc, pie as d3Pie } from 'd3-shape';\n\nimport type { NormalizedChartSpec } from '../../compiler/types';\nimport type { ResolvedScales } from '../../layout/scales';\nimport { resolveConditionalValue } from '../../transforms/conditional';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Slices smaller than this fraction are grouped into \"Other\". */\nconst SMALL_SLICE_THRESHOLD = 0.03;\n\n/** Default color palette when no color scale is available. */\nconst DEFAULT_PALETTE = [\n '#1b7fa3',\n '#c44e52',\n '#6a9f58',\n '#d47215',\n '#507e79',\n '#9a6a8d',\n '#c4636b',\n '#9c755f',\n '#a88f22',\n '#858078',\n];\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface SliceData {\n label: string;\n value: number;\n originalRow: DataRow;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Group small slices (< threshold) into an \"Other\" category. */\nfunction groupSmallSlices(slices: SliceData[], threshold: number): SliceData[] {\n const total = slices.reduce((sum, s) => sum + s.value, 0);\n if (total === 0) return slices;\n\n const big: SliceData[] = [];\n let otherValue = 0;\n\n for (const slice of slices) {\n if (slice.value / total < threshold) {\n otherValue += slice.value;\n } else {\n big.push(slice);\n }\n }\n\n if (otherValue > 0) {\n big.push({\n label: 'Other',\n value: otherValue,\n originalRow: { label: 'Other', value: otherValue },\n });\n }\n\n return big;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute pie or donut arc marks from a normalized chart spec.\n *\n * Extracts category and value from the encoding channels. Categories\n * come from the color field, values from the quantitative y (or x) field.\n * Slices are sorted largest first. Small slices are grouped into \"Other\".\n *\n * @param isDonut - When true, creates a donut with inner radius at 60% of outer.\n */\nexport function computePieMarks(\n spec: NormalizedChartSpec,\n scales: ResolvedScales,\n chartArea: Rect,\n _strategy: LayoutStrategy,\n isDonut = false,\n): ArcMark[] {\n const encoding = spec.encoding as Encoding;\n\n // For pie/donut charts, we need a value field (typically y or x) and\n // a category field (typically color). The value field provides the slice sizes.\n const valueChannel = encoding.y ?? encoding.x;\n const categoryField =\n encoding.color && 'field' in encoding.color ? encoding.color.field : undefined;\n const conditionalColor =\n encoding.color && isConditionalDef(encoding.color)\n ? (encoding.color as ConditionalValueDef)\n : undefined;\n\n if (!valueChannel) return [];\n\n // Build slices from data\n let slices: SliceData[] = [];\n\n if (categoryField) {\n // Aggregate by category\n const categoryTotals = new Map<string, number>();\n const categoryRows = new Map<string, DataRow>();\n\n for (const row of spec.data) {\n const cat = String(row[categoryField] ?? '');\n const val = Number(row[valueChannel.field] ?? 0);\n if (!Number.isFinite(val) || val < 0) continue;\n\n categoryTotals.set(cat, (categoryTotals.get(cat) ?? 0) + val);\n if (!categoryRows.has(cat)) {\n categoryRows.set(cat, row);\n }\n }\n\n for (const [label, value] of categoryTotals) {\n slices.push({\n label,\n value,\n originalRow: categoryRows.get(label) ?? {\n [categoryField]: label,\n [valueChannel.field]: value,\n },\n });\n }\n } else {\n // Each data row is a slice. Use a label field if present, or index.\n for (let i = 0; i < spec.data.length; i++) {\n const row = spec.data[i];\n const val = Number(row[valueChannel.field] ?? 0);\n if (!Number.isFinite(val) || val < 0) continue;\n\n // Try common label fields\n const label = String(row.label ?? row.name ?? row.category ?? `Slice ${i + 1}`);\n\n slices.push({ label, value: val, originalRow: row });\n }\n }\n\n if (slices.length === 0) return [];\n\n // Sort by value descending (largest first)\n slices.sort((a, b) => b.value - a.value);\n\n // Group small slices into \"Other\"\n slices = groupSmallSlices(slices, SMALL_SLICE_THRESHOLD);\n\n // Compute pie layout\n const pieGenerator = d3Pie<SliceData>()\n .value((d) => d.value)\n .sort(null) // Already sorted\n .padAngle(0.01);\n\n const arcs = pieGenerator(slices);\n\n // Compute arc dimensions\n const centerX = chartArea.x + chartArea.width / 2;\n const centerY = chartArea.y + chartArea.height / 2;\n const outerRadius = (Math.min(chartArea.width, chartArea.height) / 2) * 0.85;\n const innerRadius = isDonut ? outerRadius * 0.6 : 0;\n\n const arcGenerator = d3Arc<PieArcDatum<SliceData>>()\n .innerRadius(innerRadius)\n .outerRadius(outerRadius);\n\n // Build arc marks\n const marks: ArcMark[] = [];\n const center = { x: centerX, y: centerY };\n const total = slices.reduce((sum, s) => sum + s.value, 0);\n\n for (let i = 0; i < arcs.length; i++) {\n const arcDatum = arcs[i];\n const slice = arcDatum.data;\n\n // Get color: conditional (supports gradients) > scale > default palette\n let color: string | GradientDef;\n if (conditionalColor) {\n const resolved = resolveConditionalValue(\n slice.originalRow as Record<string, unknown>,\n conditionalColor,\n );\n if (resolved != null) {\n color = isGradientDef(resolved) ? resolved : String(resolved);\n } else if (scales.color && categoryField) {\n const colorScale = scales.color.scale as (v: string) => string;\n color = colorScale(slice.label);\n } else {\n color = DEFAULT_PALETTE[i % DEFAULT_PALETTE.length];\n }\n } else if (scales.color && categoryField) {\n const colorScale = scales.color.scale as (v: string) => string;\n color = colorScale(slice.label);\n } else {\n color = DEFAULT_PALETTE[i % DEFAULT_PALETTE.length];\n }\n\n // Generate SVG path (relative to 0,0; renderer wraps in translate)\n const path = arcGenerator(arcDatum) ?? '';\n\n // Compute centroid (for label positioning), offset to chart center\n const centroidResult = arcGenerator.centroid(arcDatum);\n\n const percentage = total > 0 ? ((slice.value / total) * 100).toFixed(1) : '0';\n\n const aria: MarkAria = {\n label: `${slice.label}: ${slice.value} (${percentage}%)`,\n };\n\n marks.push({\n type: 'arc',\n path,\n centroid: {\n x: centroidResult[0] + centerX,\n y: centroidResult[1] + centerY,\n },\n center,\n innerRadius,\n outerRadius,\n startAngle: arcDatum.startAngle,\n endAngle: arcDatum.endAngle,\n fill: color,\n stroke: '#ffffff',\n strokeWidth: 2,\n data: slice.originalRow as Record<string, unknown>,\n aria,\n });\n }\n\n return marks;\n}\n","/**\n * Pie/donut chart label computation.\n *\n * Produces leader-line labels positioned outside each arc slice.\n * Labels are placed at the midpoint of each arc's angle, extended\n * outward from the centroid. Collision detection resolves overlaps.\n *\n * Respects the spec's label density setting:\n * - 'all': show every label, skip collision detection\n * - 'auto': existing behavior (collision detection)\n * - 'endpoints': first and last slices only\n * - 'none': return empty array\n */\n\nimport type {\n ArcMark,\n LabelCandidate,\n LabelDensity,\n Rect,\n ResolvedLabel,\n} from '@opendata-ai/openchart-core';\nimport { estimateTextWidth, resolveCollisions } from '@opendata-ai/openchart-core';\nimport { filterByDensity } from '../_shared/density-filter';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst LABEL_FONT_SIZE = 10;\nconst LABEL_FONT_WEIGHT = 500;\nconst LEADER_LINE_OFFSET = 12;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute leader-line labels for pie/donut arc marks.\n *\n * Each label is positioned outward from the arc centroid with a connector\n * line from the centroid to the label. Labels go through collision\n * detection to avoid overlap.\n */\nexport function computePieLabels(\n marks: ArcMark[],\n _chartArea: Rect,\n density: LabelDensity = 'auto',\n _textFill = '#333333',\n): ResolvedLabel[] {\n if (marks.length === 0) return [];\n\n // Get the pie center from the first mark's center property\n // (read before filtering — 'endpoints' still needs the original center)\n const centerX = marks[0].center.x;\n const centerY = marks[0].center.y;\n\n const targetMarks = filterByDensity(marks, density);\n if (targetMarks.length === 0) return [];\n\n const candidates: LabelCandidate[] = [];\n const targetMarkIndices: number[] = [];\n\n for (let mi = 0; mi < targetMarks.length; mi++) {\n const mark = targetMarks[mi];\n // Extract the label text (category name) from the aria label.\n // Format is \"Category: value (percent%)\". Split on the first colon\n // to handle category names that might contain colons.\n const ariaLabel = mark.aria.label;\n const firstColon = ariaLabel.indexOf(':');\n const labelText = firstColon >= 0 ? ariaLabel.slice(0, firstColon).trim() : '';\n if (!labelText) continue;\n\n const textWidth = estimateTextWidth(labelText, LABEL_FONT_SIZE, LABEL_FONT_WEIGHT);\n const textHeight = LABEL_FONT_SIZE * 1.2;\n\n // Position label outward from centroid\n const midAngle = (mark.startAngle + mark.endAngle) / 2;\n const labelRadius = mark.outerRadius + LEADER_LINE_OFFSET;\n\n const labelX = centerX + Math.sin(midAngle) * labelRadius;\n const labelY = centerY - Math.cos(midAngle) * labelRadius;\n\n // Determine text anchor based on which side of the pie the label is on\n const isRight = Math.sin(midAngle) > 0;\n\n candidates.push({\n text: labelText,\n anchorX: isRight ? labelX : labelX - textWidth,\n anchorY: labelY - textHeight / 2,\n width: textWidth,\n height: textHeight,\n priority: 'data',\n style: {\n fontFamily: 'system-ui, -apple-system, sans-serif',\n fontSize: LABEL_FONT_SIZE,\n fontWeight: LABEL_FONT_WEIGHT,\n fill: _textFill,\n lineHeight: 1.2,\n textAnchor: isRight ? 'start' : 'end',\n dominantBaseline: 'central',\n },\n });\n\n targetMarkIndices.push(mi);\n }\n\n if (candidates.length === 0) return [];\n\n // 'all': skip collision detection, mark everything visible\n let resolved: ResolvedLabel[];\n if (density === 'all') {\n resolved = candidates.map((c) => ({\n text: c.text,\n x: c.anchorX,\n y: c.anchorY,\n style: c.style,\n visible: true,\n }));\n } else {\n // Run collision detection\n resolved = resolveCollisions(candidates);\n }\n\n // Add connector lines from centroid to label\n for (let i = 0; i < resolved.length && i < targetMarks.length; i++) {\n const label = resolved[i];\n const mark = targetMarks[i];\n\n if (label.visible) {\n label.connector = {\n from: { x: label.x, y: label.y },\n to: { x: mark.centroid.x, y: mark.centroid.y },\n stroke: _textFill,\n style: 'straight',\n };\n }\n }\n\n return resolved;\n}\n","/**\n * Pie and donut chart module.\n *\n * Exports pie and donut chart renderers and computation functions.\n */\n\nimport type { Mark } from '@opendata-ai/openchart-core';\nimport type { ChartRenderer } from '../registry';\nimport { computePieMarks } from './compute';\nimport { computePieLabels } from './labels';\n\n// ---------------------------------------------------------------------------\n// Pie chart renderer\n// ---------------------------------------------------------------------------\n\nexport const pieRenderer: ChartRenderer = (spec, scales, chartArea, strategy, theme) => {\n const marks = computePieMarks(spec, scales, chartArea, strategy, false);\n\n // Compute and attach labels (respects spec.labels.density)\n const labels = computePieLabels(marks, chartArea, spec.labels.density, theme.colors.text);\n for (let i = 0; i < marks.length && i < labels.length; i++) {\n marks[i].label = labels[i];\n }\n\n return marks as Mark[];\n};\n\n// ---------------------------------------------------------------------------\n// Donut chart renderer\n// ---------------------------------------------------------------------------\n\nexport const donutRenderer: ChartRenderer = (spec, scales, chartArea, strategy, theme) => {\n const marks = computePieMarks(spec, scales, chartArea, strategy, true);\n\n // Compute and attach labels (respects spec.labels.density)\n const labels = computePieLabels(marks, chartArea, spec.labels.density, theme.colors.text);\n for (let i = 0; i < marks.length && i < labels.length; i++) {\n marks[i].label = labels[i];\n }\n\n return marks as Mark[];\n};\n\n// ---------------------------------------------------------------------------\n// Public exports\n// ---------------------------------------------------------------------------\n\nexport { computePieMarks } from './compute';\nexport { computePieLabels } from './labels';\n","/**\n * Chart renderer registry.\n *\n * Each chart type (line, bar, column, scatter, pie, donut, dot) registers\n * a renderer that produces marks from normalized specs and resolved scales.\n * The registry pattern decouples chart-type logic from the compile pipeline.\n */\n\nimport type { LayoutStrategy, Mark, Rect, ResolvedTheme } from '@opendata-ai/openchart-core';\n\nimport type { NormalizedChartSpec } from '../compiler/types';\nimport type { ResolvedScales } from '../layout/scales';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A chart renderer function.\n *\n * Takes a normalized spec, resolved scales, chart area, layout strategy,\n * and the resolved theme for theme-aware styling (e.g. label colors).\n * Returns an array of marks to render.\n */\nexport type ChartRenderer = (\n spec: NormalizedChartSpec,\n scales: ResolvedScales,\n chartArea: Rect,\n strategy: LayoutStrategy,\n theme: ResolvedTheme,\n) => Mark[];\n\n// ---------------------------------------------------------------------------\n// Registry\n// ---------------------------------------------------------------------------\n\nconst renderers = new Map<string, ChartRenderer>();\n\n/**\n * Register a chart renderer for a specific chart type.\n *\n * @param type - Chart type string (e.g. \"line\", \"bar\").\n * @param renderer - The renderer function.\n */\nexport function registerChartRenderer(type: string, renderer: ChartRenderer): void {\n renderers.set(type, renderer);\n}\n\n/**\n * Get the registered chart renderer for a type.\n *\n * @param type - Chart type string.\n * @returns The renderer, or undefined if no renderer is registered.\n */\nexport function getChartRenderer(type: string): ChartRenderer | undefined {\n return renderers.get(type);\n}\n\n/**\n * Clear all registered renderers. Useful for testing.\n *\n * Note: the built-in renderers (line, bar, column, ...) register as a\n * side-effect of importing `./builtin`. Once cleared, they do not come\n * back on their own — subsequent `compileChart(...)` calls will return\n * empty marks. Tests that call `clearRenderers()` should follow up with\n * `registerBuiltinRenderers()` from `./builtin` to restore the defaults.\n */\nexport function clearRenderers(): void {\n renderers.clear();\n}\n","/**\n * Rule mark renderer.\n *\n * Computes RuleMarkLayout marks from a normalized chart spec.\n * Rules are line segments, typically used for reference lines as data marks.\n * Supports x, y, x2, y2 encoding channels for start/end positioning.\n */\n\nimport type { Encoding, Mark, MarkAria, Rect, RuleMarkLayout } from '@opendata-ai/openchart-core';\nimport { getRepresentativeColor } from '@opendata-ai/openchart-core';\n\nimport type { NormalizedChartSpec } from '../../compiler/types';\nimport type { ResolvedScales } from '../../layout/scales';\nimport type { ChartRenderer } from '../registry';\nimport { getColor, scaleValue } from '../utils';\n\n/**\n * Compute rule marks from spec data and resolved scales.\n *\n * Positioning logic:\n * - x only: vertical line spanning full chart height\n * - y only: horizontal line spanning full chart width\n * - x + x2: horizontal segment at the y position (or spanning full height)\n * - y + y2: vertical segment at the x position (or spanning full width)\n * - x + y + x2 + y2: arbitrary line segment\n */\nexport function computeRuleMarks(\n spec: NormalizedChartSpec,\n scales: ResolvedScales,\n chartArea: Rect,\n): RuleMarkLayout[] {\n const encoding = spec.encoding as Encoding;\n const xChannel = encoding.x;\n const yChannel = encoding.y;\n const x2Channel = encoding.x2;\n const y2Channel = encoding.y2;\n const colorEncoding = encoding.color && 'field' in encoding.color ? encoding.color : undefined;\n const colorField = colorEncoding?.field;\n\n const marks: RuleMarkLayout[] = [];\n\n for (const row of spec.data) {\n let x1 = chartArea.x;\n let y1 = chartArea.y;\n let x2 = chartArea.x + chartArea.width;\n let y2 = chartArea.y + chartArea.height;\n\n // Resolve x position\n if (xChannel && scales.x) {\n const xVal = scaleValue(scales.x.scale, scales.x.type, row[xChannel.field]);\n if (xVal == null) continue;\n x1 = xVal;\n x2 = xVal; // default: vertical line (same x)\n }\n\n // Resolve y position\n if (yChannel && scales.y) {\n const yVal = scaleValue(scales.y.scale, scales.y.type, row[yChannel.field]);\n if (yVal == null) continue;\n y1 = yVal;\n y2 = yVal; // default: horizontal line (same y)\n }\n\n // If x is set but not y, span full height (vertical line)\n if (xChannel && !yChannel) {\n y1 = chartArea.y;\n y2 = chartArea.y + chartArea.height;\n }\n\n // If y is set but not x, span full width (horizontal line)\n if (yChannel && !xChannel) {\n x1 = chartArea.x;\n x2 = chartArea.x + chartArea.width;\n }\n\n // Resolve x2 if present\n if (x2Channel && scales.x) {\n const x2Val = scaleValue(scales.x.scale, scales.x.type, row[x2Channel.field]);\n if (x2Val != null) x2 = x2Val;\n }\n\n // Resolve y2 if present\n if (y2Channel && scales.y) {\n const y2Val = scaleValue(scales.y.scale, scales.y.type, row[y2Channel.field]);\n if (y2Val != null) y2 = y2Val;\n }\n\n const color = getRepresentativeColor(\n colorField\n ? getColor(scales, String(row[colorField] ?? '__default__'))\n : getColor(scales, '__default__'),\n );\n\n const strokeDashEncoding =\n encoding.strokeDash && 'field' in encoding.strokeDash ? encoding.strokeDash : undefined;\n const strokeDasharray = strokeDashEncoding\n ? String(row[strokeDashEncoding.field] ?? '')\n : undefined;\n\n const aria: MarkAria = {\n label: `Rule from (${Math.round(x1)}, ${Math.round(y1)}) to (${Math.round(x2)}, ${Math.round(y2)})`,\n };\n\n marks.push({\n type: 'rule',\n x1,\n y1,\n x2,\n y2,\n stroke: color,\n strokeWidth: 1,\n strokeDasharray: strokeDasharray || undefined,\n opacity:\n encoding.opacity && 'field' in encoding.opacity\n ? Math.max(0, Math.min(1, Number(row[encoding.opacity.field]) || 1))\n : undefined,\n data: row as Record<string, unknown>,\n aria,\n });\n }\n\n return marks;\n}\n\n/**\n * Rule chart renderer.\n */\nexport const ruleRenderer: ChartRenderer = (spec, scales, chartArea, _strategy, _theme) => {\n return computeRuleMarks(spec, scales, chartArea) as Mark[];\n};\n","export default function ascending(a, b) {\n return a == null || b == null ? NaN : a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n}\n","export default function descending(a, b) {\n return a == null || b == null ? NaN\n : b < a ? -1\n : b > a ? 1\n : b >= a ? 0\n : NaN;\n}\n","import ascending from \"./ascending.js\";\nimport descending from \"./descending.js\";\n\nexport default function bisector(f) {\n let compare1, compare2, delta;\n\n // If an accessor is specified, promote it to a comparator. In this case we\n // can test whether the search value is (self-) comparable. We can’t do this\n // for a comparator (except for specific, known comparators) because we can’t\n // tell if the comparator is symmetric, and an asymmetric comparator can’t be\n // used to test whether a single value is comparable.\n if (f.length !== 2) {\n compare1 = ascending;\n compare2 = (d, x) => ascending(f(d), x);\n delta = (d, x) => f(d) - x;\n } else {\n compare1 = f === ascending || f === descending ? f : zero;\n compare2 = f;\n delta = f;\n }\n\n function left(a, x, lo = 0, hi = a.length) {\n if (lo < hi) {\n if (compare1(x, x) !== 0) return hi;\n do {\n const mid = (lo + hi) >>> 1;\n if (compare2(a[mid], x) < 0) lo = mid + 1;\n else hi = mid;\n } while (lo < hi);\n }\n return lo;\n }\n\n function right(a, x, lo = 0, hi = a.length) {\n if (lo < hi) {\n if (compare1(x, x) !== 0) return hi;\n do {\n const mid = (lo + hi) >>> 1;\n if (compare2(a[mid], x) <= 0) lo = mid + 1;\n else hi = mid;\n } while (lo < hi);\n }\n return lo;\n }\n\n function center(a, x, lo = 0, hi = a.length) {\n const i = left(a, x, lo, hi - 1);\n return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i;\n }\n\n return {left, center, right};\n}\n\nfunction zero() {\n return 0;\n}\n","export default function number(x) {\n return x === null ? NaN : +x;\n}\n\nexport function* numbers(values, valueof) {\n if (valueof === undefined) {\n for (let value of values) {\n if (value != null && (value = +value) >= value) {\n yield value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null && (value = +value) >= value) {\n yield value;\n }\n }\n }\n}\n","import ascending from \"./ascending.js\";\nimport bisector from \"./bisector.js\";\nimport number from \"./number.js\";\n\nconst ascendingBisect = bisector(ascending);\nexport const bisectRight = ascendingBisect.right;\nexport const bisectLeft = ascendingBisect.left;\nexport const bisectCenter = bisector(number).center;\nexport default bisectRight;\n","export default function extent(values, valueof) {\n let min;\n let max;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null) {\n if (min === undefined) {\n if (value >= value) min = max = value;\n } else {\n if (min > value) min = value;\n if (max < value) max = value;\n }\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null) {\n if (min === undefined) {\n if (value >= value) min = max = value;\n } else {\n if (min > value) min = value;\n if (max < value) max = value;\n }\n }\n }\n }\n return [min, max];\n}\n","export class InternMap extends Map {\n constructor(entries, key = keyof) {\n super();\n Object.defineProperties(this, {_intern: {value: new Map()}, _key: {value: key}});\n if (entries != null) for (const [key, value] of entries) this.set(key, value);\n }\n get(key) {\n return super.get(intern_get(this, key));\n }\n has(key) {\n return super.has(intern_get(this, key));\n }\n set(key, value) {\n return super.set(intern_set(this, key), value);\n }\n delete(key) {\n return super.delete(intern_delete(this, key));\n }\n}\n\nexport class InternSet extends Set {\n constructor(values, key = keyof) {\n super();\n Object.defineProperties(this, {_intern: {value: new Map()}, _key: {value: key}});\n if (values != null) for (const value of values) this.add(value);\n }\n has(value) {\n return super.has(intern_get(this, value));\n }\n add(value) {\n return super.add(intern_set(this, value));\n }\n delete(value) {\n return super.delete(intern_delete(this, value));\n }\n}\n\nfunction intern_get({_intern, _key}, value) {\n const key = _key(value);\n return _intern.has(key) ? _intern.get(key) : value;\n}\n\nfunction intern_set({_intern, _key}, value) {\n const key = _key(value);\n if (_intern.has(key)) return _intern.get(key);\n _intern.set(key, value);\n return value;\n}\n\nfunction intern_delete({_intern, _key}, value) {\n const key = _key(value);\n if (_intern.has(key)) {\n value = _intern.get(key);\n _intern.delete(key);\n }\n return value;\n}\n\nfunction keyof(value) {\n return value !== null && typeof value === \"object\" ? value.valueOf() : value;\n}\n","const e10 = Math.sqrt(50),\n e5 = Math.sqrt(10),\n e2 = Math.sqrt(2);\n\nfunction tickSpec(start, stop, count) {\n const step = (stop - start) / Math.max(0, count),\n power = Math.floor(Math.log10(step)),\n error = step / Math.pow(10, power),\n factor = error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1;\n let i1, i2, inc;\n if (power < 0) {\n inc = Math.pow(10, -power) / factor;\n i1 = Math.round(start * inc);\n i2 = Math.round(stop * inc);\n if (i1 / inc < start) ++i1;\n if (i2 / inc > stop) --i2;\n inc = -inc;\n } else {\n inc = Math.pow(10, power) * factor;\n i1 = Math.round(start / inc);\n i2 = Math.round(stop / inc);\n if (i1 * inc < start) ++i1;\n if (i2 * inc > stop) --i2;\n }\n if (i2 < i1 && 0.5 <= count && count < 2) return tickSpec(start, stop, count * 2);\n return [i1, i2, inc];\n}\n\nexport default function ticks(start, stop, count) {\n stop = +stop, start = +start, count = +count;\n if (!(count > 0)) return [];\n if (start === stop) return [start];\n const reverse = stop < start, [i1, i2, inc] = reverse ? tickSpec(stop, start, count) : tickSpec(start, stop, count);\n if (!(i2 >= i1)) return [];\n const n = i2 - i1 + 1, ticks = new Array(n);\n if (reverse) {\n if (inc < 0) for (let i = 0; i < n; ++i) ticks[i] = (i2 - i) / -inc;\n else for (let i = 0; i < n; ++i) ticks[i] = (i2 - i) * inc;\n } else {\n if (inc < 0) for (let i = 0; i < n; ++i) ticks[i] = (i1 + i) / -inc;\n else for (let i = 0; i < n; ++i) ticks[i] = (i1 + i) * inc;\n }\n return ticks;\n}\n\nexport function tickIncrement(start, stop, count) {\n stop = +stop, start = +start, count = +count;\n return tickSpec(start, stop, count)[2];\n}\n\nexport function tickStep(start, stop, count) {\n stop = +stop, start = +start, count = +count;\n const reverse = stop < start, inc = reverse ? tickIncrement(stop, start, count) : tickIncrement(start, stop, count);\n return (reverse ? -1 : 1) * (inc < 0 ? 1 / -inc : inc);\n}\n","export default function max(values, valueof) {\n let max;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n }\n return max;\n}\n","export default function min(values, valueof) {\n let min;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n }\n return min;\n}\n","import max from \"./max.js\";\nimport maxIndex from \"./maxIndex.js\";\nimport min from \"./min.js\";\nimport minIndex from \"./minIndex.js\";\nimport quickselect from \"./quickselect.js\";\nimport number, {numbers} from \"./number.js\";\nimport {ascendingDefined} from \"./sort.js\";\nimport greatest from \"./greatest.js\";\n\nexport default function quantile(values, p, valueof) {\n values = Float64Array.from(numbers(values, valueof));\n if (!(n = values.length) || isNaN(p = +p)) return;\n if (p <= 0 || n < 2) return min(values);\n if (p >= 1) return max(values);\n var n,\n i = (n - 1) * p,\n i0 = Math.floor(i),\n value0 = max(quickselect(values, i0).subarray(0, i0 + 1)),\n value1 = min(values.subarray(i0 + 1));\n return value0 + (value1 - value0) * (i - i0);\n}\n\nexport function quantileSorted(values, p, valueof = number) {\n if (!(n = values.length) || isNaN(p = +p)) return;\n if (p <= 0 || n < 2) return +valueof(values[0], 0, values);\n if (p >= 1) return +valueof(values[n - 1], n - 1, values);\n var n,\n i = (n - 1) * p,\n i0 = Math.floor(i),\n value0 = +valueof(values[i0], i0, values),\n value1 = +valueof(values[i0 + 1], i0 + 1, values);\n return value0 + (value1 - value0) * (i - i0);\n}\n\nexport function quantileIndex(values, p, valueof = number) {\n if (isNaN(p = +p)) return;\n numbers = Float64Array.from(values, (_, i) => number(valueof(values[i], i, values)));\n if (p <= 0) return minIndex(numbers);\n if (p >= 1) return maxIndex(numbers);\n var numbers,\n index = Uint32Array.from(values, (_, i) => i),\n j = numbers.length - 1,\n i = Math.floor(j * p);\n quickselect(index, i, 0, j, (i, j) => ascendingDefined(numbers[i], numbers[j]));\n i = greatest(index.subarray(0, i + 1), (i) => numbers[i]);\n return i >= 0 ? i : -1;\n}\n","export default function range(start, stop, step) {\n start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;\n\n var i = -1,\n n = Math.max(0, Math.ceil((stop - start) / step)) | 0,\n range = new Array(n);\n\n while (++i < n) {\n range[i] = start + i * step;\n }\n\n return range;\n}\n","export function initRange(domain, range) {\n switch (arguments.length) {\n case 0: break;\n case 1: this.range(domain); break;\n default: this.range(range).domain(domain); break;\n }\n return this;\n}\n\nexport function initInterpolator(domain, interpolator) {\n switch (arguments.length) {\n case 0: break;\n case 1: {\n if (typeof domain === \"function\") this.interpolator(domain);\n else this.range(domain);\n break;\n }\n default: {\n this.domain(domain);\n if (typeof interpolator === \"function\") this.interpolator(interpolator);\n else this.range(interpolator);\n break;\n }\n }\n return this;\n}\n","import {InternMap} from \"d3-array\";\nimport {initRange} from \"./init.js\";\n\nexport const implicit = Symbol(\"implicit\");\n\nexport default function ordinal() {\n var index = new InternMap(),\n domain = [],\n range = [],\n unknown = implicit;\n\n function scale(d) {\n let i = index.get(d);\n if (i === undefined) {\n if (unknown !== implicit) return unknown;\n index.set(d, i = domain.push(d) - 1);\n }\n return range[i % range.length];\n }\n\n scale.domain = function(_) {\n if (!arguments.length) return domain.slice();\n domain = [], index = new InternMap();\n for (const value of _) {\n if (index.has(value)) continue;\n index.set(value, domain.push(value) - 1);\n }\n return scale;\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = Array.from(_), scale) : range.slice();\n };\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n scale.copy = function() {\n return ordinal(domain, range).unknown(unknown);\n };\n\n initRange.apply(scale, arguments);\n\n return scale;\n}\n","import {range as sequence} from \"d3-array\";\nimport {initRange} from \"./init.js\";\nimport ordinal from \"./ordinal.js\";\n\nexport default function band() {\n var scale = ordinal().unknown(undefined),\n domain = scale.domain,\n ordinalRange = scale.range,\n r0 = 0,\n r1 = 1,\n step,\n bandwidth,\n round = false,\n paddingInner = 0,\n paddingOuter = 0,\n align = 0.5;\n\n delete scale.unknown;\n\n function rescale() {\n var n = domain().length,\n reverse = r1 < r0,\n start = reverse ? r1 : r0,\n stop = reverse ? r0 : r1;\n step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);\n if (round) step = Math.floor(step);\n start += (stop - start - step * (n - paddingInner)) * align;\n bandwidth = step * (1 - paddingInner);\n if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);\n var values = sequence(n).map(function(i) { return start + step * i; });\n return ordinalRange(reverse ? values.reverse() : values);\n }\n\n scale.domain = function(_) {\n return arguments.length ? (domain(_), rescale()) : domain();\n };\n\n scale.range = function(_) {\n return arguments.length ? ([r0, r1] = _, r0 = +r0, r1 = +r1, rescale()) : [r0, r1];\n };\n\n scale.rangeRound = function(_) {\n return [r0, r1] = _, r0 = +r0, r1 = +r1, round = true, rescale();\n };\n\n scale.bandwidth = function() {\n return bandwidth;\n };\n\n scale.step = function() {\n return step;\n };\n\n scale.round = function(_) {\n return arguments.length ? (round = !!_, rescale()) : round;\n };\n\n scale.padding = function(_) {\n return arguments.length ? (paddingInner = Math.min(1, paddingOuter = +_), rescale()) : paddingInner;\n };\n\n scale.paddingInner = function(_) {\n return arguments.length ? (paddingInner = Math.min(1, _), rescale()) : paddingInner;\n };\n\n scale.paddingOuter = function(_) {\n return arguments.length ? (paddingOuter = +_, rescale()) : paddingOuter;\n };\n\n scale.align = function(_) {\n return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;\n };\n\n scale.copy = function() {\n return band(domain(), [r0, r1])\n .round(round)\n .paddingInner(paddingInner)\n .paddingOuter(paddingOuter)\n .align(align);\n };\n\n return initRange.apply(rescale(), arguments);\n}\n\nfunction pointish(scale) {\n var copy = scale.copy;\n\n scale.padding = scale.paddingOuter;\n delete scale.paddingInner;\n delete scale.paddingOuter;\n\n scale.copy = function() {\n return pointish(copy());\n };\n\n return scale;\n}\n\nexport function point() {\n return pointish(band.apply(null, arguments).paddingInner(1));\n}\n","export default function(constructor, factory, prototype) {\n constructor.prototype = factory.prototype = prototype;\n prototype.constructor = constructor;\n}\n\nexport function extend(parent, definition) {\n var prototype = Object.create(parent.prototype);\n for (var key in definition) prototype[key] = definition[key];\n return prototype;\n}\n","import define, {extend} from \"./define.js\";\n\nexport function Color() {}\n\nexport var darker = 0.7;\nexport var brighter = 1 / darker;\n\nvar reI = \"\\\\s*([+-]?\\\\d+)\\\\s*\",\n reN = \"\\\\s*([+-]?(?:\\\\d*\\\\.)?\\\\d+(?:[eE][+-]?\\\\d+)?)\\\\s*\",\n reP = \"\\\\s*([+-]?(?:\\\\d*\\\\.)?\\\\d+(?:[eE][+-]?\\\\d+)?)%\\\\s*\",\n reHex = /^#([0-9a-f]{3,8})$/,\n reRgbInteger = new RegExp(`^rgb\\\\(${reI},${reI},${reI}\\\\)$`),\n reRgbPercent = new RegExp(`^rgb\\\\(${reP},${reP},${reP}\\\\)$`),\n reRgbaInteger = new RegExp(`^rgba\\\\(${reI},${reI},${reI},${reN}\\\\)$`),\n reRgbaPercent = new RegExp(`^rgba\\\\(${reP},${reP},${reP},${reN}\\\\)$`),\n reHslPercent = new RegExp(`^hsl\\\\(${reN},${reP},${reP}\\\\)$`),\n reHslaPercent = new RegExp(`^hsla\\\\(${reN},${reP},${reP},${reN}\\\\)$`);\n\nvar named = {\n aliceblue: 0xf0f8ff,\n antiquewhite: 0xfaebd7,\n aqua: 0x00ffff,\n aquamarine: 0x7fffd4,\n azure: 0xf0ffff,\n beige: 0xf5f5dc,\n bisque: 0xffe4c4,\n black: 0x000000,\n blanchedalmond: 0xffebcd,\n blue: 0x0000ff,\n blueviolet: 0x8a2be2,\n brown: 0xa52a2a,\n burlywood: 0xdeb887,\n cadetblue: 0x5f9ea0,\n chartreuse: 0x7fff00,\n chocolate: 0xd2691e,\n coral: 0xff7f50,\n cornflowerblue: 0x6495ed,\n cornsilk: 0xfff8dc,\n crimson: 0xdc143c,\n cyan: 0x00ffff,\n darkblue: 0x00008b,\n darkcyan: 0x008b8b,\n darkgoldenrod: 0xb8860b,\n darkgray: 0xa9a9a9,\n darkgreen: 0x006400,\n darkgrey: 0xa9a9a9,\n darkkhaki: 0xbdb76b,\n darkmagenta: 0x8b008b,\n darkolivegreen: 0x556b2f,\n darkorange: 0xff8c00,\n darkorchid: 0x9932cc,\n darkred: 0x8b0000,\n darksalmon: 0xe9967a,\n darkseagreen: 0x8fbc8f,\n darkslateblue: 0x483d8b,\n darkslategray: 0x2f4f4f,\n darkslategrey: 0x2f4f4f,\n darkturquoise: 0x00ced1,\n darkviolet: 0x9400d3,\n deeppink: 0xff1493,\n deepskyblue: 0x00bfff,\n dimgray: 0x696969,\n dimgrey: 0x696969,\n dodgerblue: 0x1e90ff,\n firebrick: 0xb22222,\n floralwhite: 0xfffaf0,\n forestgreen: 0x228b22,\n fuchsia: 0xff00ff,\n gainsboro: 0xdcdcdc,\n ghostwhite: 0xf8f8ff,\n gold: 0xffd700,\n goldenrod: 0xdaa520,\n gray: 0x808080,\n green: 0x008000,\n greenyellow: 0xadff2f,\n grey: 0x808080,\n honeydew: 0xf0fff0,\n hotpink: 0xff69b4,\n indianred: 0xcd5c5c,\n indigo: 0x4b0082,\n ivory: 0xfffff0,\n khaki: 0xf0e68c,\n lavender: 0xe6e6fa,\n lavenderblush: 0xfff0f5,\n lawngreen: 0x7cfc00,\n lemonchiffon: 0xfffacd,\n lightblue: 0xadd8e6,\n lightcoral: 0xf08080,\n lightcyan: 0xe0ffff,\n lightgoldenrodyellow: 0xfafad2,\n lightgray: 0xd3d3d3,\n lightgreen: 0x90ee90,\n lightgrey: 0xd3d3d3,\n lightpink: 0xffb6c1,\n lightsalmon: 0xffa07a,\n lightseagreen: 0x20b2aa,\n lightskyblue: 0x87cefa,\n lightslategray: 0x778899,\n lightslategrey: 0x778899,\n lightsteelblue: 0xb0c4de,\n lightyellow: 0xffffe0,\n lime: 0x00ff00,\n limegreen: 0x32cd32,\n linen: 0xfaf0e6,\n magenta: 0xff00ff,\n maroon: 0x800000,\n mediumaquamarine: 0x66cdaa,\n mediumblue: 0x0000cd,\n mediumorchid: 0xba55d3,\n mediumpurple: 0x9370db,\n mediumseagreen: 0x3cb371,\n mediumslateblue: 0x7b68ee,\n mediumspringgreen: 0x00fa9a,\n mediumturquoise: 0x48d1cc,\n mediumvioletred: 0xc71585,\n midnightblue: 0x191970,\n mintcream: 0xf5fffa,\n mistyrose: 0xffe4e1,\n moccasin: 0xffe4b5,\n navajowhite: 0xffdead,\n navy: 0x000080,\n oldlace: 0xfdf5e6,\n olive: 0x808000,\n olivedrab: 0x6b8e23,\n orange: 0xffa500,\n orangered: 0xff4500,\n orchid: 0xda70d6,\n palegoldenrod: 0xeee8aa,\n palegreen: 0x98fb98,\n paleturquoise: 0xafeeee,\n palevioletred: 0xdb7093,\n papayawhip: 0xffefd5,\n peachpuff: 0xffdab9,\n peru: 0xcd853f,\n pink: 0xffc0cb,\n plum: 0xdda0dd,\n powderblue: 0xb0e0e6,\n purple: 0x800080,\n rebeccapurple: 0x663399,\n red: 0xff0000,\n rosybrown: 0xbc8f8f,\n royalblue: 0x4169e1,\n saddlebrown: 0x8b4513,\n salmon: 0xfa8072,\n sandybrown: 0xf4a460,\n seagreen: 0x2e8b57,\n seashell: 0xfff5ee,\n sienna: 0xa0522d,\n silver: 0xc0c0c0,\n skyblue: 0x87ceeb,\n slateblue: 0x6a5acd,\n slategray: 0x708090,\n slategrey: 0x708090,\n snow: 0xfffafa,\n springgreen: 0x00ff7f,\n steelblue: 0x4682b4,\n tan: 0xd2b48c,\n teal: 0x008080,\n thistle: 0xd8bfd8,\n tomato: 0xff6347,\n turquoise: 0x40e0d0,\n violet: 0xee82ee,\n wheat: 0xf5deb3,\n white: 0xffffff,\n whitesmoke: 0xf5f5f5,\n yellow: 0xffff00,\n yellowgreen: 0x9acd32\n};\n\ndefine(Color, color, {\n copy(channels) {\n return Object.assign(new this.constructor, this, channels);\n },\n displayable() {\n return this.rgb().displayable();\n },\n hex: color_formatHex, // Deprecated! Use color.formatHex.\n formatHex: color_formatHex,\n formatHex8: color_formatHex8,\n formatHsl: color_formatHsl,\n formatRgb: color_formatRgb,\n toString: color_formatRgb\n});\n\nfunction color_formatHex() {\n return this.rgb().formatHex();\n}\n\nfunction color_formatHex8() {\n return this.rgb().formatHex8();\n}\n\nfunction color_formatHsl() {\n return hslConvert(this).formatHsl();\n}\n\nfunction color_formatRgb() {\n return this.rgb().formatRgb();\n}\n\nexport default function color(format) {\n var m, l;\n format = (format + \"\").trim().toLowerCase();\n return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000\n : l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00\n : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000\n : l === 4 ? rgba((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000\n : null) // invalid hex\n : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)\n : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)\n : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)\n : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)\n : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)\n : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)\n : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins\n : format === \"transparent\" ? new Rgb(NaN, NaN, NaN, 0)\n : null;\n}\n\nfunction rgbn(n) {\n return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);\n}\n\nfunction rgba(r, g, b, a) {\n if (a <= 0) r = g = b = NaN;\n return new Rgb(r, g, b, a);\n}\n\nexport function rgbConvert(o) {\n if (!(o instanceof Color)) o = color(o);\n if (!o) return new Rgb;\n o = o.rgb();\n return new Rgb(o.r, o.g, o.b, o.opacity);\n}\n\nexport function rgb(r, g, b, opacity) {\n return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);\n}\n\nexport function Rgb(r, g, b, opacity) {\n this.r = +r;\n this.g = +g;\n this.b = +b;\n this.opacity = +opacity;\n}\n\ndefine(Rgb, rgb, extend(Color, {\n brighter(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n },\n darker(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n },\n rgb() {\n return this;\n },\n clamp() {\n return new Rgb(clampi(this.r), clampi(this.g), clampi(this.b), clampa(this.opacity));\n },\n displayable() {\n return (-0.5 <= this.r && this.r < 255.5)\n && (-0.5 <= this.g && this.g < 255.5)\n && (-0.5 <= this.b && this.b < 255.5)\n && (0 <= this.opacity && this.opacity <= 1);\n },\n hex: rgb_formatHex, // Deprecated! Use color.formatHex.\n formatHex: rgb_formatHex,\n formatHex8: rgb_formatHex8,\n formatRgb: rgb_formatRgb,\n toString: rgb_formatRgb\n}));\n\nfunction rgb_formatHex() {\n return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}`;\n}\n\nfunction rgb_formatHex8() {\n return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}${hex((isNaN(this.opacity) ? 1 : this.opacity) * 255)}`;\n}\n\nfunction rgb_formatRgb() {\n const a = clampa(this.opacity);\n return `${a === 1 ? \"rgb(\" : \"rgba(\"}${clampi(this.r)}, ${clampi(this.g)}, ${clampi(this.b)}${a === 1 ? \")\" : `, ${a})`}`;\n}\n\nfunction clampa(opacity) {\n return isNaN(opacity) ? 1 : Math.max(0, Math.min(1, opacity));\n}\n\nfunction clampi(value) {\n return Math.max(0, Math.min(255, Math.round(value) || 0));\n}\n\nfunction hex(value) {\n value = clampi(value);\n return (value < 16 ? \"0\" : \"\") + value.toString(16);\n}\n\nfunction hsla(h, s, l, a) {\n if (a <= 0) h = s = l = NaN;\n else if (l <= 0 || l >= 1) h = s = NaN;\n else if (s <= 0) h = NaN;\n return new Hsl(h, s, l, a);\n}\n\nexport function hslConvert(o) {\n if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);\n if (!(o instanceof Color)) o = color(o);\n if (!o) return new Hsl;\n if (o instanceof Hsl) return o;\n o = o.rgb();\n var r = o.r / 255,\n g = o.g / 255,\n b = o.b / 255,\n min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n h = NaN,\n s = max - min,\n l = (max + min) / 2;\n if (s) {\n if (r === max) h = (g - b) / s + (g < b) * 6;\n else if (g === max) h = (b - r) / s + 2;\n else h = (r - g) / s + 4;\n s /= l < 0.5 ? max + min : 2 - max - min;\n h *= 60;\n } else {\n s = l > 0 && l < 1 ? 0 : h;\n }\n return new Hsl(h, s, l, o.opacity);\n}\n\nexport function hsl(h, s, l, opacity) {\n return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);\n}\n\nfunction Hsl(h, s, l, opacity) {\n this.h = +h;\n this.s = +s;\n this.l = +l;\n this.opacity = +opacity;\n}\n\ndefine(Hsl, hsl, extend(Color, {\n brighter(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Hsl(this.h, this.s, this.l * k, this.opacity);\n },\n darker(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Hsl(this.h, this.s, this.l * k, this.opacity);\n },\n rgb() {\n var h = this.h % 360 + (this.h < 0) * 360,\n s = isNaN(h) || isNaN(this.s) ? 0 : this.s,\n l = this.l,\n m2 = l + (l < 0.5 ? l : 1 - l) * s,\n m1 = 2 * l - m2;\n return new Rgb(\n hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),\n hsl2rgb(h, m1, m2),\n hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),\n this.opacity\n );\n },\n clamp() {\n return new Hsl(clamph(this.h), clampt(this.s), clampt(this.l), clampa(this.opacity));\n },\n displayable() {\n return (0 <= this.s && this.s <= 1 || isNaN(this.s))\n && (0 <= this.l && this.l <= 1)\n && (0 <= this.opacity && this.opacity <= 1);\n },\n formatHsl() {\n const a = clampa(this.opacity);\n return `${a === 1 ? \"hsl(\" : \"hsla(\"}${clamph(this.h)}, ${clampt(this.s) * 100}%, ${clampt(this.l) * 100}%${a === 1 ? \")\" : `, ${a})`}`;\n }\n}));\n\nfunction clamph(value) {\n value = (value || 0) % 360;\n return value < 0 ? value + 360 : value;\n}\n\nfunction clampt(value) {\n return Math.max(0, Math.min(1, value || 0));\n}\n\n/* From FvD 13.37, CSS Color Module Level 3 */\nfunction hsl2rgb(h, m1, m2) {\n return (h < 60 ? m1 + (m2 - m1) * h / 60\n : h < 180 ? m2\n : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60\n : m1) * 255;\n}\n","export function basis(t1, v0, v1, v2, v3) {\n var t2 = t1 * t1, t3 = t2 * t1;\n return ((1 - 3 * t1 + 3 * t2 - t3) * v0\n + (4 - 6 * t2 + 3 * t3) * v1\n + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2\n + t3 * v3) / 6;\n}\n\nexport default function(values) {\n var n = values.length - 1;\n return function(t) {\n var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),\n v1 = values[i],\n v2 = values[i + 1],\n v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,\n v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;\n return basis((t - i / n) * n, v0, v1, v2, v3);\n };\n}\n","import {basis} from \"./basis.js\";\n\nexport default function(values) {\n var n = values.length;\n return function(t) {\n var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),\n v0 = values[(i + n - 1) % n],\n v1 = values[i % n],\n v2 = values[(i + 1) % n],\n v3 = values[(i + 2) % n];\n return basis((t - i / n) * n, v0, v1, v2, v3);\n };\n}\n","export default x => () => x;\n","import constant from \"./constant.js\";\n\nfunction linear(a, d) {\n return function(t) {\n return a + t * d;\n };\n}\n\nfunction exponential(a, b, y) {\n return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {\n return Math.pow(a + t * b, y);\n };\n}\n\nexport function hue(a, b) {\n var d = b - a;\n return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant(isNaN(a) ? b : a);\n}\n\nexport function gamma(y) {\n return (y = +y) === 1 ? nogamma : function(a, b) {\n return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a);\n };\n}\n\nexport default function nogamma(a, b) {\n var d = b - a;\n return d ? linear(a, d) : constant(isNaN(a) ? b : a);\n}\n","import {rgb as colorRgb} from \"d3-color\";\nimport basis from \"./basis.js\";\nimport basisClosed from \"./basisClosed.js\";\nimport nogamma, {gamma} from \"./color.js\";\n\nexport default (function rgbGamma(y) {\n var color = gamma(y);\n\n function rgb(start, end) {\n var r = color((start = colorRgb(start)).r, (end = colorRgb(end)).r),\n g = color(start.g, end.g),\n b = color(start.b, end.b),\n opacity = nogamma(start.opacity, end.opacity);\n return function(t) {\n start.r = r(t);\n start.g = g(t);\n start.b = b(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n\n rgb.gamma = rgbGamma;\n\n return rgb;\n})(1);\n\nfunction rgbSpline(spline) {\n return function(colors) {\n var n = colors.length,\n r = new Array(n),\n g = new Array(n),\n b = new Array(n),\n i, color;\n for (i = 0; i < n; ++i) {\n color = colorRgb(colors[i]);\n r[i] = color.r || 0;\n g[i] = color.g || 0;\n b[i] = color.b || 0;\n }\n r = spline(r);\n g = spline(g);\n b = spline(b);\n color.opacity = 1;\n return function(t) {\n color.r = r(t);\n color.g = g(t);\n color.b = b(t);\n return color + \"\";\n };\n };\n}\n\nexport var rgbBasis = rgbSpline(basis);\nexport var rgbBasisClosed = rgbSpline(basisClosed);\n","export default function(a, b) {\n if (!b) b = [];\n var n = a ? Math.min(b.length, a.length) : 0,\n c = b.slice(),\n i;\n return function(t) {\n for (i = 0; i < n; ++i) c[i] = a[i] * (1 - t) + b[i] * t;\n return c;\n };\n}\n\nexport function isNumberArray(x) {\n return ArrayBuffer.isView(x) && !(x instanceof DataView);\n}\n","import value from \"./value.js\";\nimport numberArray, {isNumberArray} from \"./numberArray.js\";\n\nexport default function(a, b) {\n return (isNumberArray(b) ? numberArray : genericArray)(a, b);\n}\n\nexport function genericArray(a, b) {\n var nb = b ? b.length : 0,\n na = a ? Math.min(nb, a.length) : 0,\n x = new Array(na),\n c = new Array(nb),\n i;\n\n for (i = 0; i < na; ++i) x[i] = value(a[i], b[i]);\n for (; i < nb; ++i) c[i] = b[i];\n\n return function(t) {\n for (i = 0; i < na; ++i) c[i] = x[i](t);\n return c;\n };\n}\n","export default function(a, b) {\n var d = new Date;\n return a = +a, b = +b, function(t) {\n return d.setTime(a * (1 - t) + b * t), d;\n };\n}\n","export default function(a, b) {\n return a = +a, b = +b, function(t) {\n return a * (1 - t) + b * t;\n };\n}\n","import value from \"./value.js\";\n\nexport default function(a, b) {\n var i = {},\n c = {},\n k;\n\n if (a === null || typeof a !== \"object\") a = {};\n if (b === null || typeof b !== \"object\") b = {};\n\n for (k in b) {\n if (k in a) {\n i[k] = value(a[k], b[k]);\n } else {\n c[k] = b[k];\n }\n }\n\n return function(t) {\n for (k in i) c[k] = i[k](t);\n return c;\n };\n}\n","import number from \"./number.js\";\n\nvar reA = /[-+]?(?:\\d+\\.?\\d*|\\.?\\d+)(?:[eE][-+]?\\d+)?/g,\n reB = new RegExp(reA.source, \"g\");\n\nfunction zero(b) {\n return function() {\n return b;\n };\n}\n\nfunction one(b) {\n return function(t) {\n return b(t) + \"\";\n };\n}\n\nexport default function(a, b) {\n var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b\n am, // current match in a\n bm, // current match in b\n bs, // string preceding current number in b, if any\n i = -1, // index in s\n s = [], // string constants and placeholders\n q = []; // number interpolators\n\n // Coerce inputs to strings.\n a = a + \"\", b = b + \"\";\n\n // Interpolate pairs of numbers in a & b.\n while ((am = reA.exec(a))\n && (bm = reB.exec(b))) {\n if ((bs = bm.index) > bi) { // a string precedes the next number in b\n bs = b.slice(bi, bs);\n if (s[i]) s[i] += bs; // coalesce with previous string\n else s[++i] = bs;\n }\n if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match\n if (s[i]) s[i] += bm; // coalesce with previous string\n else s[++i] = bm;\n } else { // interpolate non-matching numbers\n s[++i] = null;\n q.push({i: i, x: number(am, bm)});\n }\n bi = reB.lastIndex;\n }\n\n // Add remains of b.\n if (bi < b.length) {\n bs = b.slice(bi);\n if (s[i]) s[i] += bs; // coalesce with previous string\n else s[++i] = bs;\n }\n\n // Special optimization for only a single match.\n // Otherwise, interpolate each of the numbers and rejoin the string.\n return s.length < 2 ? (q[0]\n ? one(q[0].x)\n : zero(b))\n : (b = q.length, function(t) {\n for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);\n return s.join(\"\");\n });\n}\n","import {color} from \"d3-color\";\nimport rgb from \"./rgb.js\";\nimport {genericArray} from \"./array.js\";\nimport date from \"./date.js\";\nimport number from \"./number.js\";\nimport object from \"./object.js\";\nimport string from \"./string.js\";\nimport constant from \"./constant.js\";\nimport numberArray, {isNumberArray} from \"./numberArray.js\";\n\nexport default function(a, b) {\n var t = typeof b, c;\n return b == null || t === \"boolean\" ? constant(b)\n : (t === \"number\" ? number\n : t === \"string\" ? ((c = color(b)) ? (b = c, rgb) : string)\n : b instanceof color ? rgb\n : b instanceof Date ? date\n : isNumberArray(b) ? numberArray\n : Array.isArray(b) ? genericArray\n : typeof b.valueOf !== \"function\" && typeof b.toString !== \"function\" || isNaN(b) ? object\n : number)(a, b);\n}\n","export default function(a, b) {\n return a = +a, b = +b, function(t) {\n return Math.round(a * (1 - t) + b * t);\n };\n}\n","export default function constants(x) {\n return function() {\n return x;\n };\n}\n","export default function number(x) {\n return +x;\n}\n","import {bisect} from \"d3-array\";\nimport {interpolate as interpolateValue, interpolateNumber, interpolateRound} from \"d3-interpolate\";\nimport constant from \"./constant.js\";\nimport number from \"./number.js\";\n\nvar unit = [0, 1];\n\nexport function identity(x) {\n return x;\n}\n\nfunction normalize(a, b) {\n return (b -= (a = +a))\n ? function(x) { return (x - a) / b; }\n : constant(isNaN(b) ? NaN : 0.5);\n}\n\nfunction clamper(a, b) {\n var t;\n if (a > b) t = a, a = b, b = t;\n return function(x) { return Math.max(a, Math.min(b, x)); };\n}\n\n// normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].\n// interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b].\nfunction bimap(domain, range, interpolate) {\n var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1];\n if (d1 < d0) d0 = normalize(d1, d0), r0 = interpolate(r1, r0);\n else d0 = normalize(d0, d1), r0 = interpolate(r0, r1);\n return function(x) { return r0(d0(x)); };\n}\n\nfunction polymap(domain, range, interpolate) {\n var j = Math.min(domain.length, range.length) - 1,\n d = new Array(j),\n r = new Array(j),\n i = -1;\n\n // Reverse descending domains.\n if (domain[j] < domain[0]) {\n domain = domain.slice().reverse();\n range = range.slice().reverse();\n }\n\n while (++i < j) {\n d[i] = normalize(domain[i], domain[i + 1]);\n r[i] = interpolate(range[i], range[i + 1]);\n }\n\n return function(x) {\n var i = bisect(domain, x, 1, j) - 1;\n return r[i](d[i](x));\n };\n}\n\nexport function copy(source, target) {\n return target\n .domain(source.domain())\n .range(source.range())\n .interpolate(source.interpolate())\n .clamp(source.clamp())\n .unknown(source.unknown());\n}\n\nexport function transformer() {\n var domain = unit,\n range = unit,\n interpolate = interpolateValue,\n transform,\n untransform,\n unknown,\n clamp = identity,\n piecewise,\n output,\n input;\n\n function rescale() {\n var n = Math.min(domain.length, range.length);\n if (clamp !== identity) clamp = clamper(domain[0], domain[n - 1]);\n piecewise = n > 2 ? polymap : bimap;\n output = input = null;\n return scale;\n }\n\n function scale(x) {\n return x == null || isNaN(x = +x) ? unknown : (output || (output = piecewise(domain.map(transform), range, interpolate)))(transform(clamp(x)));\n }\n\n scale.invert = function(y) {\n return clamp(untransform((input || (input = piecewise(range, domain.map(transform), interpolateNumber)))(y)));\n };\n\n scale.domain = function(_) {\n return arguments.length ? (domain = Array.from(_, number), rescale()) : domain.slice();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = Array.from(_), rescale()) : range.slice();\n };\n\n scale.rangeRound = function(_) {\n return range = Array.from(_), interpolate = interpolateRound, rescale();\n };\n\n scale.clamp = function(_) {\n return arguments.length ? (clamp = _ ? true : identity, rescale()) : clamp !== identity;\n };\n\n scale.interpolate = function(_) {\n return arguments.length ? (interpolate = _, rescale()) : interpolate;\n };\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n return function(t, u) {\n transform = t, untransform = u;\n return rescale();\n };\n}\n\nexport default function continuous() {\n return transformer()(identity, identity);\n}\n","export default function(x) {\n return Math.abs(x = Math.round(x)) >= 1e21\n ? x.toLocaleString(\"en\").replace(/,/g, \"\")\n : x.toString(10);\n}\n\n// Computes the decimal coefficient and exponent of the specified number x with\n// significant digits p, where x is positive and p is in [1, 21] or undefined.\n// For example, formatDecimalParts(1.23) returns [\"123\", 0].\nexport function formatDecimalParts(x, p) {\n if (!isFinite(x) || x === 0) return null; // NaN, ±Infinity, ±0\n var i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf(\"e\"), coefficient = x.slice(0, i);\n\n // The string returned by toExponential either has the form \\d\\.\\d+e[-+]\\d+\n // (e.g., 1.2e+3) or the form \\de[-+]\\d+ (e.g., 1e+3).\n return [\n coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,\n +x.slice(i + 1)\n ];\n}\n","import {formatDecimalParts} from \"./formatDecimal.js\";\n\nexport default function(x) {\n return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN;\n}\n","export default function(grouping, thousands) {\n return function(value, width) {\n var i = value.length,\n t = [],\n j = 0,\n g = grouping[0],\n length = 0;\n\n while (i > 0 && g > 0) {\n if (length + g + 1 > width) g = Math.max(1, width - length);\n t.push(value.substring(i -= g, i + g));\n if ((length += g + 1) > width) break;\n g = grouping[j = (j + 1) % grouping.length];\n }\n\n return t.reverse().join(thousands);\n };\n}\n","export default function(numerals) {\n return function(value) {\n return value.replace(/[0-9]/g, function(i) {\n return numerals[+i];\n });\n };\n}\n","// [[fill]align][sign][symbol][0][width][,][.precision][~][type]\nvar re = /^(?:(.)?([<>=^]))?([+\\-( ])?([$#])?(0)?(\\d+)?(,)?(\\.\\d+)?(~)?([a-z%])?$/i;\n\nexport default function formatSpecifier(specifier) {\n if (!(match = re.exec(specifier))) throw new Error(\"invalid format: \" + specifier);\n var match;\n return new FormatSpecifier({\n fill: match[1],\n align: match[2],\n sign: match[3],\n symbol: match[4],\n zero: match[5],\n width: match[6],\n comma: match[7],\n precision: match[8] && match[8].slice(1),\n trim: match[9],\n type: match[10]\n });\n}\n\nformatSpecifier.prototype = FormatSpecifier.prototype; // instanceof\n\nexport function FormatSpecifier(specifier) {\n this.fill = specifier.fill === undefined ? \" \" : specifier.fill + \"\";\n this.align = specifier.align === undefined ? \">\" : specifier.align + \"\";\n this.sign = specifier.sign === undefined ? \"-\" : specifier.sign + \"\";\n this.symbol = specifier.symbol === undefined ? \"\" : specifier.symbol + \"\";\n this.zero = !!specifier.zero;\n this.width = specifier.width === undefined ? undefined : +specifier.width;\n this.comma = !!specifier.comma;\n this.precision = specifier.precision === undefined ? undefined : +specifier.precision;\n this.trim = !!specifier.trim;\n this.type = specifier.type === undefined ? \"\" : specifier.type + \"\";\n}\n\nFormatSpecifier.prototype.toString = function() {\n return this.fill\n + this.align\n + this.sign\n + this.symbol\n + (this.zero ? \"0\" : \"\")\n + (this.width === undefined ? \"\" : Math.max(1, this.width | 0))\n + (this.comma ? \",\" : \"\")\n + (this.precision === undefined ? \"\" : \".\" + Math.max(0, this.precision | 0))\n + (this.trim ? \"~\" : \"\")\n + this.type;\n};\n","// Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k.\nexport default function(s) {\n out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) {\n switch (s[i]) {\n case \".\": i0 = i1 = i; break;\n case \"0\": if (i0 === 0) i0 = i; i1 = i; break;\n default: if (!+s[i]) break out; if (i0 > 0) i0 = 0; break;\n }\n }\n return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s;\n}\n","import {formatDecimalParts} from \"./formatDecimal.js\";\n\nexport var prefixExponent;\n\nexport default function(x, p) {\n var d = formatDecimalParts(x, p);\n if (!d) return prefixExponent = undefined, x.toPrecision(p);\n var coefficient = d[0],\n exponent = d[1],\n i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,\n n = coefficient.length;\n return i === n ? coefficient\n : i > n ? coefficient + new Array(i - n + 1).join(\"0\")\n : i > 0 ? coefficient.slice(0, i) + \".\" + coefficient.slice(i)\n : \"0.\" + new Array(1 - i).join(\"0\") + formatDecimalParts(x, Math.max(0, p + i - 1))[0]; // less than 1y!\n}\n","import {formatDecimalParts} from \"./formatDecimal.js\";\n\nexport default function(x, p) {\n var d = formatDecimalParts(x, p);\n if (!d) return x + \"\";\n var coefficient = d[0],\n exponent = d[1];\n return exponent < 0 ? \"0.\" + new Array(-exponent).join(\"0\") + coefficient\n : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + \".\" + coefficient.slice(exponent + 1)\n : coefficient + new Array(exponent - coefficient.length + 2).join(\"0\");\n}\n","import formatDecimal from \"./formatDecimal.js\";\nimport formatPrefixAuto from \"./formatPrefixAuto.js\";\nimport formatRounded from \"./formatRounded.js\";\n\nexport default {\n \"%\": (x, p) => (x * 100).toFixed(p),\n \"b\": (x) => Math.round(x).toString(2),\n \"c\": (x) => x + \"\",\n \"d\": formatDecimal,\n \"e\": (x, p) => x.toExponential(p),\n \"f\": (x, p) => x.toFixed(p),\n \"g\": (x, p) => x.toPrecision(p),\n \"o\": (x) => Math.round(x).toString(8),\n \"p\": (x, p) => formatRounded(x * 100, p),\n \"r\": formatRounded,\n \"s\": formatPrefixAuto,\n \"X\": (x) => Math.round(x).toString(16).toUpperCase(),\n \"x\": (x) => Math.round(x).toString(16)\n};\n","export default function(x) {\n return x;\n}\n","import exponent from \"./exponent.js\";\nimport formatGroup from \"./formatGroup.js\";\nimport formatNumerals from \"./formatNumerals.js\";\nimport formatSpecifier from \"./formatSpecifier.js\";\nimport formatTrim from \"./formatTrim.js\";\nimport formatTypes from \"./formatTypes.js\";\nimport {prefixExponent} from \"./formatPrefixAuto.js\";\nimport identity from \"./identity.js\";\n\nvar map = Array.prototype.map,\n prefixes = [\"y\",\"z\",\"a\",\"f\",\"p\",\"n\",\"µ\",\"m\",\"\",\"k\",\"M\",\"G\",\"T\",\"P\",\"E\",\"Z\",\"Y\"];\n\nexport default function(locale) {\n var group = locale.grouping === undefined || locale.thousands === undefined ? identity : formatGroup(map.call(locale.grouping, Number), locale.thousands + \"\"),\n currencyPrefix = locale.currency === undefined ? \"\" : locale.currency[0] + \"\",\n currencySuffix = locale.currency === undefined ? \"\" : locale.currency[1] + \"\",\n decimal = locale.decimal === undefined ? \".\" : locale.decimal + \"\",\n numerals = locale.numerals === undefined ? identity : formatNumerals(map.call(locale.numerals, String)),\n percent = locale.percent === undefined ? \"%\" : locale.percent + \"\",\n minus = locale.minus === undefined ? \"−\" : locale.minus + \"\",\n nan = locale.nan === undefined ? \"NaN\" : locale.nan + \"\";\n\n function newFormat(specifier, options) {\n specifier = formatSpecifier(specifier);\n\n var fill = specifier.fill,\n align = specifier.align,\n sign = specifier.sign,\n symbol = specifier.symbol,\n zero = specifier.zero,\n width = specifier.width,\n comma = specifier.comma,\n precision = specifier.precision,\n trim = specifier.trim,\n type = specifier.type;\n\n // The \"n\" type is an alias for \",g\".\n if (type === \"n\") comma = true, type = \"g\";\n\n // The \"\" type, and any invalid type, is an alias for \".12~g\".\n else if (!formatTypes[type]) precision === undefined && (precision = 12), trim = true, type = \"g\";\n\n // If zero fill is specified, padding goes after sign and before digits.\n if (zero || (fill === \"0\" && align === \"=\")) zero = true, fill = \"0\", align = \"=\";\n\n // Compute the prefix and suffix.\n // For SI-prefix, the suffix is lazily computed.\n var prefix = (options && options.prefix !== undefined ? options.prefix : \"\") + (symbol === \"$\" ? currencyPrefix : symbol === \"#\" && /[boxX]/.test(type) ? \"0\" + type.toLowerCase() : \"\"),\n suffix = (symbol === \"$\" ? currencySuffix : /[%p]/.test(type) ? percent : \"\") + (options && options.suffix !== undefined ? options.suffix : \"\");\n\n // What format function should we use?\n // Is this an integer type?\n // Can this type generate exponential notation?\n var formatType = formatTypes[type],\n maybeSuffix = /[defgprs%]/.test(type);\n\n // Set the default precision if not specified,\n // or clamp the specified precision to the supported range.\n // For significant precision, it must be in [1, 21].\n // For fixed precision, it must be in [0, 20].\n precision = precision === undefined ? 6\n : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))\n : Math.max(0, Math.min(20, precision));\n\n function format(value) {\n var valuePrefix = prefix,\n valueSuffix = suffix,\n i, n, c;\n\n if (type === \"c\") {\n valueSuffix = formatType(value) + valueSuffix;\n value = \"\";\n } else {\n value = +value;\n\n // Determine the sign. -0 is not less than 0, but 1 / -0 is!\n var valueNegative = value < 0 || 1 / value < 0;\n\n // Perform the initial formatting.\n value = isNaN(value) ? nan : formatType(Math.abs(value), precision);\n\n // Trim insignificant zeros.\n if (trim) value = formatTrim(value);\n\n // If a negative value rounds to zero after formatting, and no explicit positive sign is requested, hide the sign.\n if (valueNegative && +value === 0 && sign !== \"+\") valueNegative = false;\n\n // Compute the prefix and suffix.\n valuePrefix = (valueNegative ? (sign === \"(\" ? sign : minus) : sign === \"-\" || sign === \"(\" ? \"\" : sign) + valuePrefix;\n valueSuffix = (type === \"s\" && !isNaN(value) && prefixExponent !== undefined ? prefixes[8 + prefixExponent / 3] : \"\") + valueSuffix + (valueNegative && sign === \"(\" ? \")\" : \"\");\n\n // Break the formatted value into the integer “value” part that can be\n // grouped, and fractional or exponential “suffix” part that is not.\n if (maybeSuffix) {\n i = -1, n = value.length;\n while (++i < n) {\n if (c = value.charCodeAt(i), 48 > c || c > 57) {\n valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;\n value = value.slice(0, i);\n break;\n }\n }\n }\n }\n\n // If the fill character is not \"0\", grouping is applied before padding.\n if (comma && !zero) value = group(value, Infinity);\n\n // Compute the padding.\n var length = valuePrefix.length + value.length + valueSuffix.length,\n padding = length < width ? new Array(width - length + 1).join(fill) : \"\";\n\n // If the fill character is \"0\", grouping is applied after padding.\n if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = \"\";\n\n // Reconstruct the final output based on the desired alignment.\n switch (align) {\n case \"<\": value = valuePrefix + value + valueSuffix + padding; break;\n case \"=\": value = valuePrefix + padding + value + valueSuffix; break;\n case \"^\": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;\n default: value = padding + valuePrefix + value + valueSuffix; break;\n }\n\n return numerals(value);\n }\n\n format.toString = function() {\n return specifier + \"\";\n };\n\n return format;\n }\n\n function formatPrefix(specifier, value) {\n var e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3,\n k = Math.pow(10, -e),\n f = newFormat((specifier = formatSpecifier(specifier), specifier.type = \"f\", specifier), {suffix: prefixes[8 + e / 3]});\n return function(value) {\n return f(k * value);\n };\n }\n\n return {\n format: newFormat,\n formatPrefix: formatPrefix\n };\n}\n","import formatLocale from \"./locale.js\";\n\nvar locale;\nexport var format;\nexport var formatPrefix;\n\ndefaultLocale({\n thousands: \",\",\n grouping: [3],\n currency: [\"$\", \"\"]\n});\n\nexport default function defaultLocale(definition) {\n locale = formatLocale(definition);\n format = locale.format;\n formatPrefix = locale.formatPrefix;\n return locale;\n}\n","import exponent from \"./exponent.js\";\n\nexport default function(step) {\n return Math.max(0, -exponent(Math.abs(step)));\n}\n","import exponent from \"./exponent.js\";\n\nexport default function(step, value) {\n return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step)));\n}\n","import exponent from \"./exponent.js\";\n\nexport default function(step, max) {\n step = Math.abs(step), max = Math.abs(max) - step;\n return Math.max(0, exponent(max) - exponent(step)) + 1;\n}\n","import {tickStep} from \"d3-array\";\nimport {format, formatPrefix, formatSpecifier, precisionFixed, precisionPrefix, precisionRound} from \"d3-format\";\n\nexport default function tickFormat(start, stop, count, specifier) {\n var step = tickStep(start, stop, count),\n precision;\n specifier = formatSpecifier(specifier == null ? \",f\" : specifier);\n switch (specifier.type) {\n case \"s\": {\n var value = Math.max(Math.abs(start), Math.abs(stop));\n if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;\n return formatPrefix(specifier, value);\n }\n case \"\":\n case \"e\":\n case \"g\":\n case \"p\":\n case \"r\": {\n if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === \"e\");\n break;\n }\n case \"f\":\n case \"%\": {\n if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === \"%\") * 2;\n break;\n }\n }\n return format(specifier);\n}\n","import {ticks, tickIncrement} from \"d3-array\";\nimport continuous, {copy} from \"./continuous.js\";\nimport {initRange} from \"./init.js\";\nimport tickFormat from \"./tickFormat.js\";\n\nexport function linearish(scale) {\n var domain = scale.domain;\n\n scale.ticks = function(count) {\n var d = domain();\n return ticks(d[0], d[d.length - 1], count == null ? 10 : count);\n };\n\n scale.tickFormat = function(count, specifier) {\n var d = domain();\n return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier);\n };\n\n scale.nice = function(count) {\n if (count == null) count = 10;\n\n var d = domain();\n var i0 = 0;\n var i1 = d.length - 1;\n var start = d[i0];\n var stop = d[i1];\n var prestep;\n var step;\n var maxIter = 10;\n\n if (stop < start) {\n step = start, start = stop, stop = step;\n step = i0, i0 = i1, i1 = step;\n }\n \n while (maxIter-- > 0) {\n step = tickIncrement(start, stop, count);\n if (step === prestep) {\n d[i0] = start\n d[i1] = stop\n return domain(d);\n } else if (step > 0) {\n start = Math.floor(start / step) * step;\n stop = Math.ceil(stop / step) * step;\n } else if (step < 0) {\n start = Math.ceil(start * step) / step;\n stop = Math.floor(stop * step) / step;\n } else {\n break;\n }\n prestep = step;\n }\n\n return scale;\n };\n\n return scale;\n}\n\nexport default function linear() {\n var scale = continuous();\n\n scale.copy = function() {\n return copy(scale, linear());\n };\n\n initRange.apply(scale, arguments);\n\n return linearish(scale);\n}\n","export default function nice(domain, interval) {\n domain = domain.slice();\n\n var i0 = 0,\n i1 = domain.length - 1,\n x0 = domain[i0],\n x1 = domain[i1],\n t;\n\n if (x1 < x0) {\n t = i0, i0 = i1, i1 = t;\n t = x0, x0 = x1, x1 = t;\n }\n\n domain[i0] = interval.floor(x0);\n domain[i1] = interval.ceil(x1);\n return domain;\n}\n","import {ticks} from \"d3-array\";\nimport {format, formatSpecifier} from \"d3-format\";\nimport nice from \"./nice.js\";\nimport {copy, transformer} from \"./continuous.js\";\nimport {initRange} from \"./init.js\";\n\nfunction transformLog(x) {\n return Math.log(x);\n}\n\nfunction transformExp(x) {\n return Math.exp(x);\n}\n\nfunction transformLogn(x) {\n return -Math.log(-x);\n}\n\nfunction transformExpn(x) {\n return -Math.exp(-x);\n}\n\nfunction pow10(x) {\n return isFinite(x) ? +(\"1e\" + x) : x < 0 ? 0 : x;\n}\n\nfunction powp(base) {\n return base === 10 ? pow10\n : base === Math.E ? Math.exp\n : x => Math.pow(base, x);\n}\n\nfunction logp(base) {\n return base === Math.E ? Math.log\n : base === 10 && Math.log10\n || base === 2 && Math.log2\n || (base = Math.log(base), x => Math.log(x) / base);\n}\n\nfunction reflect(f) {\n return (x, k) => -f(-x, k);\n}\n\nexport function loggish(transform) {\n const scale = transform(transformLog, transformExp);\n const domain = scale.domain;\n let base = 10;\n let logs;\n let pows;\n\n function rescale() {\n logs = logp(base), pows = powp(base);\n if (domain()[0] < 0) {\n logs = reflect(logs), pows = reflect(pows);\n transform(transformLogn, transformExpn);\n } else {\n transform(transformLog, transformExp);\n }\n return scale;\n }\n\n scale.base = function(_) {\n return arguments.length ? (base = +_, rescale()) : base;\n };\n\n scale.domain = function(_) {\n return arguments.length ? (domain(_), rescale()) : domain();\n };\n\n scale.ticks = count => {\n const d = domain();\n let u = d[0];\n let v = d[d.length - 1];\n const r = v < u;\n\n if (r) ([u, v] = [v, u]);\n\n let i = logs(u);\n let j = logs(v);\n let k;\n let t;\n const n = count == null ? 10 : +count;\n let z = [];\n\n if (!(base % 1) && j - i < n) {\n i = Math.floor(i), j = Math.ceil(j);\n if (u > 0) for (; i <= j; ++i) {\n for (k = 1; k < base; ++k) {\n t = i < 0 ? k / pows(-i) : k * pows(i);\n if (t < u) continue;\n if (t > v) break;\n z.push(t);\n }\n } else for (; i <= j; ++i) {\n for (k = base - 1; k >= 1; --k) {\n t = i > 0 ? k / pows(-i) : k * pows(i);\n if (t < u) continue;\n if (t > v) break;\n z.push(t);\n }\n }\n if (z.length * 2 < n) z = ticks(u, v, n);\n } else {\n z = ticks(i, j, Math.min(j - i, n)).map(pows);\n }\n return r ? z.reverse() : z;\n };\n\n scale.tickFormat = (count, specifier) => {\n if (count == null) count = 10;\n if (specifier == null) specifier = base === 10 ? \"s\" : \",\";\n if (typeof specifier !== \"function\") {\n if (!(base % 1) && (specifier = formatSpecifier(specifier)).precision == null) specifier.trim = true;\n specifier = format(specifier);\n }\n if (count === Infinity) return specifier;\n const k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?\n return d => {\n let i = d / pows(Math.round(logs(d)));\n if (i * base < base - 0.5) i *= base;\n return i <= k ? specifier(d) : \"\";\n };\n };\n\n scale.nice = () => {\n return domain(nice(domain(), {\n floor: x => pows(Math.floor(logs(x))),\n ceil: x => pows(Math.ceil(logs(x)))\n }));\n };\n\n return scale;\n}\n\nexport default function log() {\n const scale = loggish(transformer()).domain([1, 10]);\n scale.copy = () => copy(scale, log()).base(scale.base());\n initRange.apply(scale, arguments);\n return scale;\n}\n","import {linearish} from \"./linear.js\";\nimport {copy, transformer} from \"./continuous.js\";\nimport {initRange} from \"./init.js\";\n\nfunction transformSymlog(c) {\n return function(x) {\n return Math.sign(x) * Math.log1p(Math.abs(x / c));\n };\n}\n\nfunction transformSymexp(c) {\n return function(x) {\n return Math.sign(x) * Math.expm1(Math.abs(x)) * c;\n };\n}\n\nexport function symlogish(transform) {\n var c = 1, scale = transform(transformSymlog(c), transformSymexp(c));\n\n scale.constant = function(_) {\n return arguments.length ? transform(transformSymlog(c = +_), transformSymexp(c)) : c;\n };\n\n return linearish(scale);\n}\n\nexport default function symlog() {\n var scale = symlogish(transformer());\n\n scale.copy = function() {\n return copy(scale, symlog()).constant(scale.constant());\n };\n\n return initRange.apply(scale, arguments);\n}\n","import {linearish} from \"./linear.js\";\nimport {copy, identity, transformer} from \"./continuous.js\";\nimport {initRange} from \"./init.js\";\n\nfunction transformPow(exponent) {\n return function(x) {\n return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);\n };\n}\n\nfunction transformSqrt(x) {\n return x < 0 ? -Math.sqrt(-x) : Math.sqrt(x);\n}\n\nfunction transformSquare(x) {\n return x < 0 ? -x * x : x * x;\n}\n\nexport function powish(transform) {\n var scale = transform(identity, identity),\n exponent = 1;\n\n function rescale() {\n return exponent === 1 ? transform(identity, identity)\n : exponent === 0.5 ? transform(transformSqrt, transformSquare)\n : transform(transformPow(exponent), transformPow(1 / exponent));\n }\n\n scale.exponent = function(_) {\n return arguments.length ? (exponent = +_, rescale()) : exponent;\n };\n\n return linearish(scale);\n}\n\nexport default function pow() {\n var scale = powish(transformer());\n\n scale.copy = function() {\n return copy(scale, pow()).exponent(scale.exponent());\n };\n\n initRange.apply(scale, arguments);\n\n return scale;\n}\n\nexport function sqrt() {\n return pow.apply(null, arguments).exponent(0.5);\n}\n","import {ascending, bisect, quantileSorted as threshold} from \"d3-array\";\nimport {initRange} from \"./init.js\";\n\nexport default function quantile() {\n var domain = [],\n range = [],\n thresholds = [],\n unknown;\n\n function rescale() {\n var i = 0, n = Math.max(1, range.length);\n thresholds = new Array(n - 1);\n while (++i < n) thresholds[i - 1] = threshold(domain, i / n);\n return scale;\n }\n\n function scale(x) {\n return x == null || isNaN(x = +x) ? unknown : range[bisect(thresholds, x)];\n }\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return i < 0 ? [NaN, NaN] : [\n i > 0 ? thresholds[i - 1] : domain[0],\n i < thresholds.length ? thresholds[i] : domain[domain.length - 1]\n ];\n };\n\n scale.domain = function(_) {\n if (!arguments.length) return domain.slice();\n domain = [];\n for (let d of _) if (d != null && !isNaN(d = +d)) domain.push(d);\n domain.sort(ascending);\n return rescale();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = Array.from(_), rescale()) : range.slice();\n };\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n scale.quantiles = function() {\n return thresholds.slice();\n };\n\n scale.copy = function() {\n return quantile()\n .domain(domain)\n .range(range)\n .unknown(unknown);\n };\n\n return initRange.apply(scale, arguments);\n}\n","import {bisect} from \"d3-array\";\nimport {linearish} from \"./linear.js\";\nimport {initRange} from \"./init.js\";\n\nexport default function quantize() {\n var x0 = 0,\n x1 = 1,\n n = 1,\n domain = [0.5],\n range = [0, 1],\n unknown;\n\n function scale(x) {\n return x != null && x <= x ? range[bisect(domain, x, 0, n)] : unknown;\n }\n\n function rescale() {\n var i = -1;\n domain = new Array(n);\n while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);\n return scale;\n }\n\n scale.domain = function(_) {\n return arguments.length ? ([x0, x1] = _, x0 = +x0, x1 = +x1, rescale()) : [x0, x1];\n };\n\n scale.range = function(_) {\n return arguments.length ? (n = (range = Array.from(_)).length - 1, rescale()) : range.slice();\n };\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return i < 0 ? [NaN, NaN]\n : i < 1 ? [x0, domain[0]]\n : i >= n ? [domain[n - 1], x1]\n : [domain[i - 1], domain[i]];\n };\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : scale;\n };\n\n scale.thresholds = function() {\n return domain.slice();\n };\n\n scale.copy = function() {\n return quantize()\n .domain([x0, x1])\n .range(range)\n .unknown(unknown);\n };\n\n return initRange.apply(linearish(scale), arguments);\n}\n","import {bisect} from \"d3-array\";\nimport {initRange} from \"./init.js\";\n\nexport default function threshold() {\n var domain = [0.5],\n range = [0, 1],\n unknown,\n n = 1;\n\n function scale(x) {\n return x != null && x <= x ? range[bisect(domain, x, 0, n)] : unknown;\n }\n\n scale.domain = function(_) {\n return arguments.length ? (domain = Array.from(_), n = Math.min(domain.length, range.length - 1), scale) : domain.slice();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = Array.from(_), n = Math.min(domain.length, range.length - 1), scale) : range.slice();\n };\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return [domain[i - 1], domain[i]];\n };\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n scale.copy = function() {\n return threshold()\n .domain(domain)\n .range(range)\n .unknown(unknown);\n };\n\n return initRange.apply(scale, arguments);\n}\n","const t0 = new Date, t1 = new Date;\n\nexport function timeInterval(floori, offseti, count, field) {\n\n function interval(date) {\n return floori(date = arguments.length === 0 ? new Date : new Date(+date)), date;\n }\n\n interval.floor = (date) => {\n return floori(date = new Date(+date)), date;\n };\n\n interval.ceil = (date) => {\n return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;\n };\n\n interval.round = (date) => {\n const d0 = interval(date), d1 = interval.ceil(date);\n return date - d0 < d1 - date ? d0 : d1;\n };\n\n interval.offset = (date, step) => {\n return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;\n };\n\n interval.range = (start, stop, step) => {\n const range = [];\n start = interval.ceil(start);\n step = step == null ? 1 : Math.floor(step);\n if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date\n let previous;\n do range.push(previous = new Date(+start)), offseti(start, step), floori(start);\n while (previous < start && start < stop);\n return range;\n };\n\n interval.filter = (test) => {\n return timeInterval((date) => {\n if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);\n }, (date, step) => {\n if (date >= date) {\n if (step < 0) while (++step <= 0) {\n while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty\n } else while (--step >= 0) {\n while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty\n }\n }\n });\n };\n\n if (count) {\n interval.count = (start, end) => {\n t0.setTime(+start), t1.setTime(+end);\n floori(t0), floori(t1);\n return Math.floor(count(t0, t1));\n };\n\n interval.every = (step) => {\n step = Math.floor(step);\n return !isFinite(step) || !(step > 0) ? null\n : !(step > 1) ? interval\n : interval.filter(field\n ? (d) => field(d) % step === 0\n : (d) => interval.count(0, d) % step === 0);\n };\n }\n\n return interval;\n}\n","import {timeInterval} from \"./interval.js\";\n\nexport const millisecond = timeInterval(() => {\n // noop\n}, (date, step) => {\n date.setTime(+date + step);\n}, (start, end) => {\n return end - start;\n});\n\n// An optimized implementation for this simple case.\nmillisecond.every = (k) => {\n k = Math.floor(k);\n if (!isFinite(k) || !(k > 0)) return null;\n if (!(k > 1)) return millisecond;\n return timeInterval((date) => {\n date.setTime(Math.floor(date / k) * k);\n }, (date, step) => {\n date.setTime(+date + step * k);\n }, (start, end) => {\n return (end - start) / k;\n });\n};\n\nexport const milliseconds = millisecond.range;\n","export const durationSecond = 1000;\nexport const durationMinute = durationSecond * 60;\nexport const durationHour = durationMinute * 60;\nexport const durationDay = durationHour * 24;\nexport const durationWeek = durationDay * 7;\nexport const durationMonth = durationDay * 30;\nexport const durationYear = durationDay * 365;\n","import {timeInterval} from \"./interval.js\";\nimport {durationSecond} from \"./duration.js\";\n\nexport const second = timeInterval((date) => {\n date.setTime(date - date.getMilliseconds());\n}, (date, step) => {\n date.setTime(+date + step * durationSecond);\n}, (start, end) => {\n return (end - start) / durationSecond;\n}, (date) => {\n return date.getUTCSeconds();\n});\n\nexport const seconds = second.range;\n","import {timeInterval} from \"./interval.js\";\nimport {durationMinute, durationSecond} from \"./duration.js\";\n\nexport const timeMinute = timeInterval((date) => {\n date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond);\n}, (date, step) => {\n date.setTime(+date + step * durationMinute);\n}, (start, end) => {\n return (end - start) / durationMinute;\n}, (date) => {\n return date.getMinutes();\n});\n\nexport const timeMinutes = timeMinute.range;\n\nexport const utcMinute = timeInterval((date) => {\n date.setUTCSeconds(0, 0);\n}, (date, step) => {\n date.setTime(+date + step * durationMinute);\n}, (start, end) => {\n return (end - start) / durationMinute;\n}, (date) => {\n return date.getUTCMinutes();\n});\n\nexport const utcMinutes = utcMinute.range;\n","import {timeInterval} from \"./interval.js\";\nimport {durationHour, durationMinute, durationSecond} from \"./duration.js\";\n\nexport const timeHour = timeInterval((date) => {\n date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond - date.getMinutes() * durationMinute);\n}, (date, step) => {\n date.setTime(+date + step * durationHour);\n}, (start, end) => {\n return (end - start) / durationHour;\n}, (date) => {\n return date.getHours();\n});\n\nexport const timeHours = timeHour.range;\n\nexport const utcHour = timeInterval((date) => {\n date.setUTCMinutes(0, 0, 0);\n}, (date, step) => {\n date.setTime(+date + step * durationHour);\n}, (start, end) => {\n return (end - start) / durationHour;\n}, (date) => {\n return date.getUTCHours();\n});\n\nexport const utcHours = utcHour.range;\n","import {timeInterval} from \"./interval.js\";\nimport {durationDay, durationMinute} from \"./duration.js\";\n\nexport const timeDay = timeInterval(\n date => date.setHours(0, 0, 0, 0),\n (date, step) => date.setDate(date.getDate() + step),\n (start, end) => (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay,\n date => date.getDate() - 1\n);\n\nexport const timeDays = timeDay.range;\n\nexport const utcDay = timeInterval((date) => {\n date.setUTCHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setUTCDate(date.getUTCDate() + step);\n}, (start, end) => {\n return (end - start) / durationDay;\n}, (date) => {\n return date.getUTCDate() - 1;\n});\n\nexport const utcDays = utcDay.range;\n\nexport const unixDay = timeInterval((date) => {\n date.setUTCHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setUTCDate(date.getUTCDate() + step);\n}, (start, end) => {\n return (end - start) / durationDay;\n}, (date) => {\n return Math.floor(date / durationDay);\n});\n\nexport const unixDays = unixDay.range;\n","import {timeInterval} from \"./interval.js\";\nimport {durationMinute, durationWeek} from \"./duration.js\";\n\nfunction timeWeekday(i) {\n return timeInterval((date) => {\n date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);\n date.setHours(0, 0, 0, 0);\n }, (date, step) => {\n date.setDate(date.getDate() + step * 7);\n }, (start, end) => {\n return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek;\n });\n}\n\nexport const timeSunday = timeWeekday(0);\nexport const timeMonday = timeWeekday(1);\nexport const timeTuesday = timeWeekday(2);\nexport const timeWednesday = timeWeekday(3);\nexport const timeThursday = timeWeekday(4);\nexport const timeFriday = timeWeekday(5);\nexport const timeSaturday = timeWeekday(6);\n\nexport const timeSundays = timeSunday.range;\nexport const timeMondays = timeMonday.range;\nexport const timeTuesdays = timeTuesday.range;\nexport const timeWednesdays = timeWednesday.range;\nexport const timeThursdays = timeThursday.range;\nexport const timeFridays = timeFriday.range;\nexport const timeSaturdays = timeSaturday.range;\n\nfunction utcWeekday(i) {\n return timeInterval((date) => {\n date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);\n date.setUTCHours(0, 0, 0, 0);\n }, (date, step) => {\n date.setUTCDate(date.getUTCDate() + step * 7);\n }, (start, end) => {\n return (end - start) / durationWeek;\n });\n}\n\nexport const utcSunday = utcWeekday(0);\nexport const utcMonday = utcWeekday(1);\nexport const utcTuesday = utcWeekday(2);\nexport const utcWednesday = utcWeekday(3);\nexport const utcThursday = utcWeekday(4);\nexport const utcFriday = utcWeekday(5);\nexport const utcSaturday = utcWeekday(6);\n\nexport const utcSundays = utcSunday.range;\nexport const utcMondays = utcMonday.range;\nexport const utcTuesdays = utcTuesday.range;\nexport const utcWednesdays = utcWednesday.range;\nexport const utcThursdays = utcThursday.range;\nexport const utcFridays = utcFriday.range;\nexport const utcSaturdays = utcSaturday.range;\n","import {timeInterval} from \"./interval.js\";\n\nexport const timeMonth = timeInterval((date) => {\n date.setDate(1);\n date.setHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setMonth(date.getMonth() + step);\n}, (start, end) => {\n return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;\n}, (date) => {\n return date.getMonth();\n});\n\nexport const timeMonths = timeMonth.range;\n\nexport const utcMonth = timeInterval((date) => {\n date.setUTCDate(1);\n date.setUTCHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setUTCMonth(date.getUTCMonth() + step);\n}, (start, end) => {\n return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;\n}, (date) => {\n return date.getUTCMonth();\n});\n\nexport const utcMonths = utcMonth.range;\n","import {timeInterval} from \"./interval.js\";\n\nexport const timeYear = timeInterval((date) => {\n date.setMonth(0, 1);\n date.setHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setFullYear(date.getFullYear() + step);\n}, (start, end) => {\n return end.getFullYear() - start.getFullYear();\n}, (date) => {\n return date.getFullYear();\n});\n\n// An optimized implementation for this simple case.\ntimeYear.every = (k) => {\n return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : timeInterval((date) => {\n date.setFullYear(Math.floor(date.getFullYear() / k) * k);\n date.setMonth(0, 1);\n date.setHours(0, 0, 0, 0);\n }, (date, step) => {\n date.setFullYear(date.getFullYear() + step * k);\n });\n};\n\nexport const timeYears = timeYear.range;\n\nexport const utcYear = timeInterval((date) => {\n date.setUTCMonth(0, 1);\n date.setUTCHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setUTCFullYear(date.getUTCFullYear() + step);\n}, (start, end) => {\n return end.getUTCFullYear() - start.getUTCFullYear();\n}, (date) => {\n return date.getUTCFullYear();\n});\n\n// An optimized implementation for this simple case.\nutcYear.every = (k) => {\n return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : timeInterval((date) => {\n date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);\n date.setUTCMonth(0, 1);\n date.setUTCHours(0, 0, 0, 0);\n }, (date, step) => {\n date.setUTCFullYear(date.getUTCFullYear() + step * k);\n });\n};\n\nexport const utcYears = utcYear.range;\n","import {bisector, tickStep} from \"d3-array\";\nimport {durationDay, durationHour, durationMinute, durationMonth, durationSecond, durationWeek, durationYear} from \"./duration.js\";\nimport {millisecond} from \"./millisecond.js\";\nimport {second} from \"./second.js\";\nimport {timeMinute, utcMinute} from \"./minute.js\";\nimport {timeHour, utcHour} from \"./hour.js\";\nimport {timeDay, unixDay} from \"./day.js\";\nimport {timeSunday, utcSunday} from \"./week.js\";\nimport {timeMonth, utcMonth} from \"./month.js\";\nimport {timeYear, utcYear} from \"./year.js\";\n\nfunction ticker(year, month, week, day, hour, minute) {\n\n const tickIntervals = [\n [second, 1, durationSecond],\n [second, 5, 5 * durationSecond],\n [second, 15, 15 * durationSecond],\n [second, 30, 30 * durationSecond],\n [minute, 1, durationMinute],\n [minute, 5, 5 * durationMinute],\n [minute, 15, 15 * durationMinute],\n [minute, 30, 30 * durationMinute],\n [ hour, 1, durationHour ],\n [ hour, 3, 3 * durationHour ],\n [ hour, 6, 6 * durationHour ],\n [ hour, 12, 12 * durationHour ],\n [ day, 1, durationDay ],\n [ day, 2, 2 * durationDay ],\n [ week, 1, durationWeek ],\n [ month, 1, durationMonth ],\n [ month, 3, 3 * durationMonth ],\n [ year, 1, durationYear ]\n ];\n\n function ticks(start, stop, count) {\n const reverse = stop < start;\n if (reverse) [start, stop] = [stop, start];\n const interval = count && typeof count.range === \"function\" ? count : tickInterval(start, stop, count);\n const ticks = interval ? interval.range(start, +stop + 1) : []; // inclusive stop\n return reverse ? ticks.reverse() : ticks;\n }\n\n function tickInterval(start, stop, count) {\n const target = Math.abs(stop - start) / count;\n const i = bisector(([,, step]) => step).right(tickIntervals, target);\n if (i === tickIntervals.length) return year.every(tickStep(start / durationYear, stop / durationYear, count));\n if (i === 0) return millisecond.every(Math.max(tickStep(start, stop, count), 1));\n const [t, step] = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];\n return t.every(step);\n }\n\n return [ticks, tickInterval];\n}\n\nconst [utcTicks, utcTickInterval] = ticker(utcYear, utcMonth, utcSunday, unixDay, utcHour, utcMinute);\nconst [timeTicks, timeTickInterval] = ticker(timeYear, timeMonth, timeSunday, timeDay, timeHour, timeMinute);\n\nexport {utcTicks, utcTickInterval, timeTicks, timeTickInterval};\n","import {\n timeDay,\n timeSunday,\n timeMonday,\n timeThursday,\n timeYear,\n utcDay,\n utcSunday,\n utcMonday,\n utcThursday,\n utcYear\n} from \"d3-time\";\n\nfunction localDate(d) {\n if (0 <= d.y && d.y < 100) {\n var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);\n date.setFullYear(d.y);\n return date;\n }\n return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);\n}\n\nfunction utcDate(d) {\n if (0 <= d.y && d.y < 100) {\n var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));\n date.setUTCFullYear(d.y);\n return date;\n }\n return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));\n}\n\nfunction newDate(y, m, d) {\n return {y: y, m: m, d: d, H: 0, M: 0, S: 0, L: 0};\n}\n\nexport default function formatLocale(locale) {\n var locale_dateTime = locale.dateTime,\n locale_date = locale.date,\n locale_time = locale.time,\n locale_periods = locale.periods,\n locale_weekdays = locale.days,\n locale_shortWeekdays = locale.shortDays,\n locale_months = locale.months,\n locale_shortMonths = locale.shortMonths;\n\n var periodRe = formatRe(locale_periods),\n periodLookup = formatLookup(locale_periods),\n weekdayRe = formatRe(locale_weekdays),\n weekdayLookup = formatLookup(locale_weekdays),\n shortWeekdayRe = formatRe(locale_shortWeekdays),\n shortWeekdayLookup = formatLookup(locale_shortWeekdays),\n monthRe = formatRe(locale_months),\n monthLookup = formatLookup(locale_months),\n shortMonthRe = formatRe(locale_shortMonths),\n shortMonthLookup = formatLookup(locale_shortMonths);\n\n var formats = {\n \"a\": formatShortWeekday,\n \"A\": formatWeekday,\n \"b\": formatShortMonth,\n \"B\": formatMonth,\n \"c\": null,\n \"d\": formatDayOfMonth,\n \"e\": formatDayOfMonth,\n \"f\": formatMicroseconds,\n \"g\": formatYearISO,\n \"G\": formatFullYearISO,\n \"H\": formatHour24,\n \"I\": formatHour12,\n \"j\": formatDayOfYear,\n \"L\": formatMilliseconds,\n \"m\": formatMonthNumber,\n \"M\": formatMinutes,\n \"p\": formatPeriod,\n \"q\": formatQuarter,\n \"Q\": formatUnixTimestamp,\n \"s\": formatUnixTimestampSeconds,\n \"S\": formatSeconds,\n \"u\": formatWeekdayNumberMonday,\n \"U\": formatWeekNumberSunday,\n \"V\": formatWeekNumberISO,\n \"w\": formatWeekdayNumberSunday,\n \"W\": formatWeekNumberMonday,\n \"x\": null,\n \"X\": null,\n \"y\": formatYear,\n \"Y\": formatFullYear,\n \"Z\": formatZone,\n \"%\": formatLiteralPercent\n };\n\n var utcFormats = {\n \"a\": formatUTCShortWeekday,\n \"A\": formatUTCWeekday,\n \"b\": formatUTCShortMonth,\n \"B\": formatUTCMonth,\n \"c\": null,\n \"d\": formatUTCDayOfMonth,\n \"e\": formatUTCDayOfMonth,\n \"f\": formatUTCMicroseconds,\n \"g\": formatUTCYearISO,\n \"G\": formatUTCFullYearISO,\n \"H\": formatUTCHour24,\n \"I\": formatUTCHour12,\n \"j\": formatUTCDayOfYear,\n \"L\": formatUTCMilliseconds,\n \"m\": formatUTCMonthNumber,\n \"M\": formatUTCMinutes,\n \"p\": formatUTCPeriod,\n \"q\": formatUTCQuarter,\n \"Q\": formatUnixTimestamp,\n \"s\": formatUnixTimestampSeconds,\n \"S\": formatUTCSeconds,\n \"u\": formatUTCWeekdayNumberMonday,\n \"U\": formatUTCWeekNumberSunday,\n \"V\": formatUTCWeekNumberISO,\n \"w\": formatUTCWeekdayNumberSunday,\n \"W\": formatUTCWeekNumberMonday,\n \"x\": null,\n \"X\": null,\n \"y\": formatUTCYear,\n \"Y\": formatUTCFullYear,\n \"Z\": formatUTCZone,\n \"%\": formatLiteralPercent\n };\n\n var parses = {\n \"a\": parseShortWeekday,\n \"A\": parseWeekday,\n \"b\": parseShortMonth,\n \"B\": parseMonth,\n \"c\": parseLocaleDateTime,\n \"d\": parseDayOfMonth,\n \"e\": parseDayOfMonth,\n \"f\": parseMicroseconds,\n \"g\": parseYear,\n \"G\": parseFullYear,\n \"H\": parseHour24,\n \"I\": parseHour24,\n \"j\": parseDayOfYear,\n \"L\": parseMilliseconds,\n \"m\": parseMonthNumber,\n \"M\": parseMinutes,\n \"p\": parsePeriod,\n \"q\": parseQuarter,\n \"Q\": parseUnixTimestamp,\n \"s\": parseUnixTimestampSeconds,\n \"S\": parseSeconds,\n \"u\": parseWeekdayNumberMonday,\n \"U\": parseWeekNumberSunday,\n \"V\": parseWeekNumberISO,\n \"w\": parseWeekdayNumberSunday,\n \"W\": parseWeekNumberMonday,\n \"x\": parseLocaleDate,\n \"X\": parseLocaleTime,\n \"y\": parseYear,\n \"Y\": parseFullYear,\n \"Z\": parseZone,\n \"%\": parseLiteralPercent\n };\n\n // These recursive directive definitions must be deferred.\n formats.x = newFormat(locale_date, formats);\n formats.X = newFormat(locale_time, formats);\n formats.c = newFormat(locale_dateTime, formats);\n utcFormats.x = newFormat(locale_date, utcFormats);\n utcFormats.X = newFormat(locale_time, utcFormats);\n utcFormats.c = newFormat(locale_dateTime, utcFormats);\n\n function newFormat(specifier, formats) {\n return function(date) {\n var string = [],\n i = -1,\n j = 0,\n n = specifier.length,\n c,\n pad,\n format;\n\n if (!(date instanceof Date)) date = new Date(+date);\n\n while (++i < n) {\n if (specifier.charCodeAt(i) === 37) {\n string.push(specifier.slice(j, i));\n if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);\n else pad = c === \"e\" ? \" \" : \"0\";\n if (format = formats[c]) c = format(date, pad);\n string.push(c);\n j = i + 1;\n }\n }\n\n string.push(specifier.slice(j, i));\n return string.join(\"\");\n };\n }\n\n function newParse(specifier, Z) {\n return function(string) {\n var d = newDate(1900, undefined, 1),\n i = parseSpecifier(d, specifier, string += \"\", 0),\n week, day;\n if (i != string.length) return null;\n\n // If a UNIX timestamp is specified, return it.\n if (\"Q\" in d) return new Date(d.Q);\n if (\"s\" in d) return new Date(d.s * 1000 + (\"L\" in d ? d.L : 0));\n\n // If this is utcParse, never use the local timezone.\n if (Z && !(\"Z\" in d)) d.Z = 0;\n\n // The am-pm flag is 0 for AM, and 1 for PM.\n if (\"p\" in d) d.H = d.H % 12 + d.p * 12;\n\n // If the month was not specified, inherit from the quarter.\n if (d.m === undefined) d.m = \"q\" in d ? d.q : 0;\n\n // Convert day-of-week and week-of-year to day-of-year.\n if (\"V\" in d) {\n if (d.V < 1 || d.V > 53) return null;\n if (!(\"w\" in d)) d.w = 1;\n if (\"Z\" in d) {\n week = utcDate(newDate(d.y, 0, 1)), day = week.getUTCDay();\n week = day > 4 || day === 0 ? utcMonday.ceil(week) : utcMonday(week);\n week = utcDay.offset(week, (d.V - 1) * 7);\n d.y = week.getUTCFullYear();\n d.m = week.getUTCMonth();\n d.d = week.getUTCDate() + (d.w + 6) % 7;\n } else {\n week = localDate(newDate(d.y, 0, 1)), day = week.getDay();\n week = day > 4 || day === 0 ? timeMonday.ceil(week) : timeMonday(week);\n week = timeDay.offset(week, (d.V - 1) * 7);\n d.y = week.getFullYear();\n d.m = week.getMonth();\n d.d = week.getDate() + (d.w + 6) % 7;\n }\n } else if (\"W\" in d || \"U\" in d) {\n if (!(\"w\" in d)) d.w = \"u\" in d ? d.u % 7 : \"W\" in d ? 1 : 0;\n day = \"Z\" in d ? utcDate(newDate(d.y, 0, 1)).getUTCDay() : localDate(newDate(d.y, 0, 1)).getDay();\n d.m = 0;\n d.d = \"W\" in d ? (d.w + 6) % 7 + d.W * 7 - (day + 5) % 7 : d.w + d.U * 7 - (day + 6) % 7;\n }\n\n // If a time zone is specified, all fields are interpreted as UTC and then\n // offset according to the specified time zone.\n if (\"Z\" in d) {\n d.H += d.Z / 100 | 0;\n d.M += d.Z % 100;\n return utcDate(d);\n }\n\n // Otherwise, all fields are in local time.\n return localDate(d);\n };\n }\n\n function parseSpecifier(d, specifier, string, j) {\n var i = 0,\n n = specifier.length,\n m = string.length,\n c,\n parse;\n\n while (i < n) {\n if (j >= m) return -1;\n c = specifier.charCodeAt(i++);\n if (c === 37) {\n c = specifier.charAt(i++);\n parse = parses[c in pads ? specifier.charAt(i++) : c];\n if (!parse || ((j = parse(d, string, j)) < 0)) return -1;\n } else if (c != string.charCodeAt(j++)) {\n return -1;\n }\n }\n\n return j;\n }\n\n function parsePeriod(d, string, i) {\n var n = periodRe.exec(string.slice(i));\n return n ? (d.p = periodLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseShortWeekday(d, string, i) {\n var n = shortWeekdayRe.exec(string.slice(i));\n return n ? (d.w = shortWeekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseWeekday(d, string, i) {\n var n = weekdayRe.exec(string.slice(i));\n return n ? (d.w = weekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseShortMonth(d, string, i) {\n var n = shortMonthRe.exec(string.slice(i));\n return n ? (d.m = shortMonthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseMonth(d, string, i) {\n var n = monthRe.exec(string.slice(i));\n return n ? (d.m = monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseLocaleDateTime(d, string, i) {\n return parseSpecifier(d, locale_dateTime, string, i);\n }\n\n function parseLocaleDate(d, string, i) {\n return parseSpecifier(d, locale_date, string, i);\n }\n\n function parseLocaleTime(d, string, i) {\n return parseSpecifier(d, locale_time, string, i);\n }\n\n function formatShortWeekday(d) {\n return locale_shortWeekdays[d.getDay()];\n }\n\n function formatWeekday(d) {\n return locale_weekdays[d.getDay()];\n }\n\n function formatShortMonth(d) {\n return locale_shortMonths[d.getMonth()];\n }\n\n function formatMonth(d) {\n return locale_months[d.getMonth()];\n }\n\n function formatPeriod(d) {\n return locale_periods[+(d.getHours() >= 12)];\n }\n\n function formatQuarter(d) {\n return 1 + ~~(d.getMonth() / 3);\n }\n\n function formatUTCShortWeekday(d) {\n return locale_shortWeekdays[d.getUTCDay()];\n }\n\n function formatUTCWeekday(d) {\n return locale_weekdays[d.getUTCDay()];\n }\n\n function formatUTCShortMonth(d) {\n return locale_shortMonths[d.getUTCMonth()];\n }\n\n function formatUTCMonth(d) {\n return locale_months[d.getUTCMonth()];\n }\n\n function formatUTCPeriod(d) {\n return locale_periods[+(d.getUTCHours() >= 12)];\n }\n\n function formatUTCQuarter(d) {\n return 1 + ~~(d.getUTCMonth() / 3);\n }\n\n return {\n format: function(specifier) {\n var f = newFormat(specifier += \"\", formats);\n f.toString = function() { return specifier; };\n return f;\n },\n parse: function(specifier) {\n var p = newParse(specifier += \"\", false);\n p.toString = function() { return specifier; };\n return p;\n },\n utcFormat: function(specifier) {\n var f = newFormat(specifier += \"\", utcFormats);\n f.toString = function() { return specifier; };\n return f;\n },\n utcParse: function(specifier) {\n var p = newParse(specifier += \"\", true);\n p.toString = function() { return specifier; };\n return p;\n }\n };\n}\n\nvar pads = {\"-\": \"\", \"_\": \" \", \"0\": \"0\"},\n numberRe = /^\\s*\\d+/, // note: ignores next directive\n percentRe = /^%/,\n requoteRe = /[\\\\^$*+?|[\\]().{}]/g;\n\nfunction pad(value, fill, width) {\n var sign = value < 0 ? \"-\" : \"\",\n string = (sign ? -value : value) + \"\",\n length = string.length;\n return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);\n}\n\nfunction requote(s) {\n return s.replace(requoteRe, \"\\\\$&\");\n}\n\nfunction formatRe(names) {\n return new RegExp(\"^(?:\" + names.map(requote).join(\"|\") + \")\", \"i\");\n}\n\nfunction formatLookup(names) {\n return new Map(names.map((name, i) => [name.toLowerCase(), i]));\n}\n\nfunction parseWeekdayNumberSunday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.w = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekdayNumberMonday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.u = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberSunday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.U = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberISO(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.V = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberMonday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.W = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseFullYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 4));\n return n ? (d.y = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;\n}\n\nfunction parseZone(d, string, i) {\n var n = /^(Z)|([+-]\\d\\d)(?::?(\\d\\d))?/.exec(string.slice(i, i + 6));\n return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || \"00\")), i + n[0].length) : -1;\n}\n\nfunction parseQuarter(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.q = n[0] * 3 - 3, i + n[0].length) : -1;\n}\n\nfunction parseMonthNumber(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.m = n[0] - 1, i + n[0].length) : -1;\n}\n\nfunction parseDayOfMonth(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseDayOfYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 3));\n return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseHour24(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.H = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMinutes(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.M = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseSeconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.S = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMilliseconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 3));\n return n ? (d.L = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMicroseconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 6));\n return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1;\n}\n\nfunction parseLiteralPercent(d, string, i) {\n var n = percentRe.exec(string.slice(i, i + 1));\n return n ? i + n[0].length : -1;\n}\n\nfunction parseUnixTimestamp(d, string, i) {\n var n = numberRe.exec(string.slice(i));\n return n ? (d.Q = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseUnixTimestampSeconds(d, string, i) {\n var n = numberRe.exec(string.slice(i));\n return n ? (d.s = +n[0], i + n[0].length) : -1;\n}\n\nfunction formatDayOfMonth(d, p) {\n return pad(d.getDate(), p, 2);\n}\n\nfunction formatHour24(d, p) {\n return pad(d.getHours(), p, 2);\n}\n\nfunction formatHour12(d, p) {\n return pad(d.getHours() % 12 || 12, p, 2);\n}\n\nfunction formatDayOfYear(d, p) {\n return pad(1 + timeDay.count(timeYear(d), d), p, 3);\n}\n\nfunction formatMilliseconds(d, p) {\n return pad(d.getMilliseconds(), p, 3);\n}\n\nfunction formatMicroseconds(d, p) {\n return formatMilliseconds(d, p) + \"000\";\n}\n\nfunction formatMonthNumber(d, p) {\n return pad(d.getMonth() + 1, p, 2);\n}\n\nfunction formatMinutes(d, p) {\n return pad(d.getMinutes(), p, 2);\n}\n\nfunction formatSeconds(d, p) {\n return pad(d.getSeconds(), p, 2);\n}\n\nfunction formatWeekdayNumberMonday(d) {\n var day = d.getDay();\n return day === 0 ? 7 : day;\n}\n\nfunction formatWeekNumberSunday(d, p) {\n return pad(timeSunday.count(timeYear(d) - 1, d), p, 2);\n}\n\nfunction dISO(d) {\n var day = d.getDay();\n return (day >= 4 || day === 0) ? timeThursday(d) : timeThursday.ceil(d);\n}\n\nfunction formatWeekNumberISO(d, p) {\n d = dISO(d);\n return pad(timeThursday.count(timeYear(d), d) + (timeYear(d).getDay() === 4), p, 2);\n}\n\nfunction formatWeekdayNumberSunday(d) {\n return d.getDay();\n}\n\nfunction formatWeekNumberMonday(d, p) {\n return pad(timeMonday.count(timeYear(d) - 1, d), p, 2);\n}\n\nfunction formatYear(d, p) {\n return pad(d.getFullYear() % 100, p, 2);\n}\n\nfunction formatYearISO(d, p) {\n d = dISO(d);\n return pad(d.getFullYear() % 100, p, 2);\n}\n\nfunction formatFullYear(d, p) {\n return pad(d.getFullYear() % 10000, p, 4);\n}\n\nfunction formatFullYearISO(d, p) {\n var day = d.getDay();\n d = (day >= 4 || day === 0) ? timeThursday(d) : timeThursday.ceil(d);\n return pad(d.getFullYear() % 10000, p, 4);\n}\n\nfunction formatZone(d) {\n var z = d.getTimezoneOffset();\n return (z > 0 ? \"-\" : (z *= -1, \"+\"))\n + pad(z / 60 | 0, \"0\", 2)\n + pad(z % 60, \"0\", 2);\n}\n\nfunction formatUTCDayOfMonth(d, p) {\n return pad(d.getUTCDate(), p, 2);\n}\n\nfunction formatUTCHour24(d, p) {\n return pad(d.getUTCHours(), p, 2);\n}\n\nfunction formatUTCHour12(d, p) {\n return pad(d.getUTCHours() % 12 || 12, p, 2);\n}\n\nfunction formatUTCDayOfYear(d, p) {\n return pad(1 + utcDay.count(utcYear(d), d), p, 3);\n}\n\nfunction formatUTCMilliseconds(d, p) {\n return pad(d.getUTCMilliseconds(), p, 3);\n}\n\nfunction formatUTCMicroseconds(d, p) {\n return formatUTCMilliseconds(d, p) + \"000\";\n}\n\nfunction formatUTCMonthNumber(d, p) {\n return pad(d.getUTCMonth() + 1, p, 2);\n}\n\nfunction formatUTCMinutes(d, p) {\n return pad(d.getUTCMinutes(), p, 2);\n}\n\nfunction formatUTCSeconds(d, p) {\n return pad(d.getUTCSeconds(), p, 2);\n}\n\nfunction formatUTCWeekdayNumberMonday(d) {\n var dow = d.getUTCDay();\n return dow === 0 ? 7 : dow;\n}\n\nfunction formatUTCWeekNumberSunday(d, p) {\n return pad(utcSunday.count(utcYear(d) - 1, d), p, 2);\n}\n\nfunction UTCdISO(d) {\n var day = d.getUTCDay();\n return (day >= 4 || day === 0) ? utcThursday(d) : utcThursday.ceil(d);\n}\n\nfunction formatUTCWeekNumberISO(d, p) {\n d = UTCdISO(d);\n return pad(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2);\n}\n\nfunction formatUTCWeekdayNumberSunday(d) {\n return d.getUTCDay();\n}\n\nfunction formatUTCWeekNumberMonday(d, p) {\n return pad(utcMonday.count(utcYear(d) - 1, d), p, 2);\n}\n\nfunction formatUTCYear(d, p) {\n return pad(d.getUTCFullYear() % 100, p, 2);\n}\n\nfunction formatUTCYearISO(d, p) {\n d = UTCdISO(d);\n return pad(d.getUTCFullYear() % 100, p, 2);\n}\n\nfunction formatUTCFullYear(d, p) {\n return pad(d.getUTCFullYear() % 10000, p, 4);\n}\n\nfunction formatUTCFullYearISO(d, p) {\n var day = d.getUTCDay();\n d = (day >= 4 || day === 0) ? utcThursday(d) : utcThursday.ceil(d);\n return pad(d.getUTCFullYear() % 10000, p, 4);\n}\n\nfunction formatUTCZone() {\n return \"+0000\";\n}\n\nfunction formatLiteralPercent() {\n return \"%\";\n}\n\nfunction formatUnixTimestamp(d) {\n return +d;\n}\n\nfunction formatUnixTimestampSeconds(d) {\n return Math.floor(+d / 1000);\n}\n","import formatLocale from \"./locale.js\";\n\nvar locale;\nexport var timeFormat;\nexport var timeParse;\nexport var utcFormat;\nexport var utcParse;\n\ndefaultLocale({\n dateTime: \"%x, %X\",\n date: \"%-m/%-d/%Y\",\n time: \"%-I:%M:%S %p\",\n periods: [\"AM\", \"PM\"],\n days: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n shortDays: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n months: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"],\n shortMonths: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\n});\n\nexport default function defaultLocale(definition) {\n locale = formatLocale(definition);\n timeFormat = locale.format;\n timeParse = locale.parse;\n utcFormat = locale.utcFormat;\n utcParse = locale.utcParse;\n return locale;\n}\n","import {timeYear, timeMonth, timeWeek, timeDay, timeHour, timeMinute, timeSecond, timeTicks, timeTickInterval} from \"d3-time\";\nimport {timeFormat} from \"d3-time-format\";\nimport continuous, {copy} from \"./continuous.js\";\nimport {initRange} from \"./init.js\";\nimport nice from \"./nice.js\";\n\nfunction date(t) {\n return new Date(t);\n}\n\nfunction number(t) {\n return t instanceof Date ? +t : +new Date(+t);\n}\n\nexport function calendar(ticks, tickInterval, year, month, week, day, hour, minute, second, format) {\n var scale = continuous(),\n invert = scale.invert,\n domain = scale.domain;\n\n var formatMillisecond = format(\".%L\"),\n formatSecond = format(\":%S\"),\n formatMinute = format(\"%I:%M\"),\n formatHour = format(\"%I %p\"),\n formatDay = format(\"%a %d\"),\n formatWeek = format(\"%b %d\"),\n formatMonth = format(\"%B\"),\n formatYear = format(\"%Y\");\n\n function tickFormat(date) {\n return (second(date) < date ? formatMillisecond\n : minute(date) < date ? formatSecond\n : hour(date) < date ? formatMinute\n : day(date) < date ? formatHour\n : month(date) < date ? (week(date) < date ? formatDay : formatWeek)\n : year(date) < date ? formatMonth\n : formatYear)(date);\n }\n\n scale.invert = function(y) {\n return new Date(invert(y));\n };\n\n scale.domain = function(_) {\n return arguments.length ? domain(Array.from(_, number)) : domain().map(date);\n };\n\n scale.ticks = function(interval) {\n var d = domain();\n return ticks(d[0], d[d.length - 1], interval == null ? 10 : interval);\n };\n\n scale.tickFormat = function(count, specifier) {\n return specifier == null ? tickFormat : format(specifier);\n };\n\n scale.nice = function(interval) {\n var d = domain();\n if (!interval || typeof interval.range !== \"function\") interval = tickInterval(d[0], d[d.length - 1], interval == null ? 10 : interval);\n return interval ? domain(nice(d, interval)) : scale;\n };\n\n scale.copy = function() {\n return copy(scale, calendar(ticks, tickInterval, year, month, week, day, hour, minute, second, format));\n };\n\n return scale;\n}\n\nexport default function time() {\n return initRange.apply(calendar(timeTicks, timeTickInterval, timeYear, timeMonth, timeWeek, timeDay, timeHour, timeMinute, timeSecond, timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]), arguments);\n}\n","import {utcYear, utcMonth, utcWeek, utcDay, utcHour, utcMinute, utcSecond, utcTicks, utcTickInterval} from \"d3-time\";\nimport {utcFormat} from \"d3-time-format\";\nimport {calendar} from \"./time.js\";\nimport {initRange} from \"./init.js\";\n\nexport default function utcTime() {\n return initRange.apply(calendar(utcTicks, utcTickInterval, utcYear, utcMonth, utcWeek, utcDay, utcHour, utcMinute, utcSecond, utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]), arguments);\n}\n","import {interpolate, interpolateRound} from \"d3-interpolate\";\nimport {identity} from \"./continuous.js\";\nimport {initInterpolator} from \"./init.js\";\nimport {linearish} from \"./linear.js\";\nimport {loggish} from \"./log.js\";\nimport {symlogish} from \"./symlog.js\";\nimport {powish} from \"./pow.js\";\n\nfunction transformer() {\n var x0 = 0,\n x1 = 1,\n t0,\n t1,\n k10,\n transform,\n interpolator = identity,\n clamp = false,\n unknown;\n\n function scale(x) {\n return x == null || isNaN(x = +x) ? unknown : interpolator(k10 === 0 ? 0.5 : (x = (transform(x) - t0) * k10, clamp ? Math.max(0, Math.min(1, x)) : x));\n }\n\n scale.domain = function(_) {\n return arguments.length ? ([x0, x1] = _, t0 = transform(x0 = +x0), t1 = transform(x1 = +x1), k10 = t0 === t1 ? 0 : 1 / (t1 - t0), scale) : [x0, x1];\n };\n\n scale.clamp = function(_) {\n return arguments.length ? (clamp = !!_, scale) : clamp;\n };\n\n scale.interpolator = function(_) {\n return arguments.length ? (interpolator = _, scale) : interpolator;\n };\n\n function range(interpolate) {\n return function(_) {\n var r0, r1;\n return arguments.length ? ([r0, r1] = _, interpolator = interpolate(r0, r1), scale) : [interpolator(0), interpolator(1)];\n };\n }\n\n scale.range = range(interpolate);\n\n scale.rangeRound = range(interpolateRound);\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n return function(t) {\n transform = t, t0 = t(x0), t1 = t(x1), k10 = t0 === t1 ? 0 : 1 / (t1 - t0);\n return scale;\n };\n}\n\nexport function copy(source, target) {\n return target\n .domain(source.domain())\n .interpolator(source.interpolator())\n .clamp(source.clamp())\n .unknown(source.unknown());\n}\n\nexport default function sequential() {\n var scale = linearish(transformer()(identity));\n\n scale.copy = function() {\n return copy(scale, sequential());\n };\n\n return initInterpolator.apply(scale, arguments);\n}\n\nexport function sequentialLog() {\n var scale = loggish(transformer()).domain([1, 10]);\n\n scale.copy = function() {\n return copy(scale, sequentialLog()).base(scale.base());\n };\n\n return initInterpolator.apply(scale, arguments);\n}\n\nexport function sequentialSymlog() {\n var scale = symlogish(transformer());\n\n scale.copy = function() {\n return copy(scale, sequentialSymlog()).constant(scale.constant());\n };\n\n return initInterpolator.apply(scale, arguments);\n}\n\nexport function sequentialPow() {\n var scale = powish(transformer());\n\n scale.copy = function() {\n return copy(scale, sequentialPow()).exponent(scale.exponent());\n };\n\n return initInterpolator.apply(scale, arguments);\n}\n\nexport function sequentialSqrt() {\n return sequentialPow.apply(null, arguments).exponent(0.5);\n}\n","/**\n * Scatter / bubble chart mark computation.\n *\n * Takes a normalized chart spec with resolved scales and produces\n * PointMark[] for rendering scatter plots. Axes can be any field type.\n * Optional size encoding produces area-proportional bubbles via sqrt\n * scaling, and color encoding groups points by category.\n */\n\nimport type {\n Encoding,\n FieldType,\n GradientDef,\n LayoutStrategy,\n MarkAria,\n PointMark,\n Rect,\n} from '@opendata-ai/openchart-core';\nimport { max, min } from 'd3-array';\nimport type { ScaleBand, ScaleLinear, ScalePoint, ScaleTime } from 'd3-scale';\nimport { scaleSqrt } from 'd3-scale';\n\nimport type { NormalizedChartSpec } from '../../compiler/types';\nimport type { ResolvedScales } from '../../layout/scales';\nimport { getColor, getSequentialColor } from '../utils';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_POINT_RADIUS = 5;\nconst MIN_BUBBLE_RADIUS = 3;\nconst MAX_BUBBLE_RADIUS = 30;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Resolve a data value to a pixel position based on channel type and scale. */\nfunction resolvePosition(\n value: unknown,\n channelType: FieldType,\n scale:\n | ScaleLinear<number, number>\n | ScaleTime<number, number>\n | ScaleBand<string>\n | ScalePoint<string>,\n): number | undefined {\n switch (channelType) {\n case 'nominal':\n case 'ordinal': {\n const s = String(value);\n if ('bandwidth' in scale && typeof scale.bandwidth === 'function') {\n const bw = (scale as ScaleBand<string>).bandwidth();\n const pos = (scale as ScaleBand<string>)(s);\n if (pos === undefined) return undefined;\n // ScalePoint has bandwidth() === 0; ScaleBand has > 0.\n return bw > 0 ? pos + bw / 2 : pos;\n }\n return (scale as ScalePoint<string>)(s);\n }\n case 'temporal': {\n const px = (scale as ScaleTime<number, number>)(new Date(value as string | number));\n return Number.isNaN(px) ? undefined : px;\n }\n default: {\n const num = Number(value);\n if (!Number.isFinite(num)) return undefined;\n return (scale as ScaleLinear<number, number>)(num);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute scatter/bubble marks from a normalized chart spec.\n *\n * Axes accept any field type: quantitative (linear), temporal (time),\n * nominal/ordinal (band or point scale). Optional size encoding maps a\n * data field to point radius using sqrt scale (area-proportional).\n * Optional color encoding groups points by category with distinct colors.\n */\nexport function computeScatterMarks(\n spec: NormalizedChartSpec,\n scales: ResolvedScales,\n _chartArea: Rect,\n _strategy: LayoutStrategy,\n): PointMark[] {\n const encoding = spec.encoding as Encoding;\n const xChannel = encoding.x;\n const yChannel = encoding.y;\n\n if (!xChannel || !yChannel || !scales.x || !scales.y) {\n return [];\n }\n\n const xScale = scales.x.scale as\n | ScaleLinear<number, number>\n | ScaleTime<number, number>\n | ScaleBand<string>\n | ScalePoint<string>;\n const yScale = scales.y.scale as\n | ScaleLinear<number, number>\n | ScaleTime<number, number>\n | ScaleBand<string>\n | ScalePoint<string>;\n const xType = xChannel.type;\n const yType = yChannel.type;\n\n const colorEnc = encoding.color && 'field' in encoding.color ? encoding.color : undefined;\n const isSequentialColor = colorEnc?.type === 'quantitative';\n const colorField = colorEnc?.field;\n const sizeField = encoding.size && 'field' in encoding.size ? encoding.size.field : undefined;\n\n // Build a size scale for bubble variant\n let sizeScale: ((v: number) => number) | undefined;\n if (sizeField) {\n const sizeValues = spec.data.map((d) => Number(d[sizeField])).filter((v) => Number.isFinite(v));\n\n const sizeMin = min(sizeValues) ?? 0;\n const sizeMax = max(sizeValues) ?? 1;\n\n sizeScale = scaleSqrt()\n .domain([sizeMin, sizeMax])\n .range([MIN_BUBBLE_RADIUS, MAX_BUBBLE_RADIUS]);\n }\n\n const marks: PointMark[] = [];\n\n for (const row of spec.data) {\n const rawX = row[xChannel.field];\n const rawY = row[yChannel.field];\n\n const cx = resolvePosition(rawX, xType, xScale);\n const cy = resolvePosition(rawY, yType, yScale);\n\n if (cx === undefined || cy === undefined) continue;\n\n const category = colorField && !isSequentialColor ? String(row[colorField] ?? '') : undefined;\n let color: string | GradientDef;\n if (isSequentialColor && colorField) {\n const val = Number(row[colorField]);\n color = Number.isFinite(val)\n ? getSequentialColor(scales, val)\n : getColor(scales, '__default__');\n } else {\n color = getColor(scales, category ?? '__default__');\n }\n\n let radius = DEFAULT_POINT_RADIUS;\n if (sizeScale && sizeField) {\n const sizeVal = Number(row[sizeField]);\n if (Number.isFinite(sizeVal)) {\n radius = sizeScale(sizeVal);\n }\n }\n\n const labelParts = [`${xChannel.field}=${rawX}`, `${yChannel.field}=${rawY}`];\n if (category) labelParts.push(`${colorField}=${category}`);\n if (sizeField && row[sizeField] != null) {\n labelParts.push(`${sizeField}=${row[sizeField]}`);\n }\n\n const aria: MarkAria = {\n label: `Data point: ${labelParts.join(', ')}`,\n };\n\n marks.push({\n type: 'point',\n cx,\n cy,\n r: radius,\n fill: color,\n stroke: '#ffffff',\n strokeWidth: 1,\n fillOpacity: 0.7,\n data: row as Record<string, unknown>,\n aria,\n });\n }\n\n return marks;\n}\n","/**\n * Trend line computation for scatter plots.\n *\n * Computes a simple linear regression (least squares) over the\n * point marks and returns a LineMark representing the best-fit line.\n */\n\nimport type { LineMark, MarkAria, PointMark } from '@opendata-ai/openchart-core';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst TRENDLINE_COLOR = '#666666';\nconst TRENDLINE_STROKE_WIDTH = 1.5;\nconst TRENDLINE_DASH = '6 4';\n\n// ---------------------------------------------------------------------------\n// Linear regression\n// ---------------------------------------------------------------------------\n\n/**\n * Compute slope and intercept for a simple linear regression.\n * Returns null if there aren't enough points or variance is zero.\n */\nfunction linearRegression(\n points: { x: number; y: number }[],\n): { slope: number; intercept: number } | null {\n const n = points.length;\n if (n < 2) return null;\n\n let sumX = 0;\n let sumY = 0;\n let sumXY = 0;\n let sumXX = 0;\n\n for (const p of points) {\n sumX += p.x;\n sumY += p.y;\n sumXY += p.x * p.y;\n sumXX += p.x * p.x;\n }\n\n const denominator = n * sumXX - sumX * sumX;\n if (denominator === 0) return null;\n\n const slope = (n * sumXY - sumX * sumY) / denominator;\n const intercept = (sumY - slope * sumX) / n;\n\n return { slope, intercept };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute a trend line (linear regression) over scatter point marks.\n *\n * Returns a single LineMark spanning the x-range of the data points,\n * rendered as a dashed line. Returns null if regression can't be computed.\n */\nexport function computeTrendLine(marks: PointMark[]): LineMark | null {\n if (marks.length < 2) return null;\n\n const points = marks.map((m) => ({ x: m.cx, y: m.cy }));\n const result = linearRegression(points);\n if (!result) return null;\n\n const { slope, intercept } = result;\n\n // Find x range from marks\n let minX = Infinity;\n let maxX = -Infinity;\n for (const m of marks) {\n if (m.cx < minX) minX = m.cx;\n if (m.cx > maxX) maxX = m.cx;\n }\n\n // Compute y values at the endpoints\n const y1 = slope * minX + intercept;\n const y2 = slope * maxX + intercept;\n\n const aria: MarkAria = {\n label: `Trend line: linear regression`,\n };\n\n return {\n type: 'line',\n points: [\n { x: minX, y: y1 },\n { x: maxX, y: y2 },\n ],\n stroke: TRENDLINE_COLOR,\n strokeWidth: TRENDLINE_STROKE_WIDTH,\n strokeDasharray: TRENDLINE_DASH,\n data: [],\n aria,\n };\n}\n","/**\n * Scatter / bubble chart module.\n *\n * Exports the scatter chart renderer and computation functions.\n */\n\nimport type { Mark } from '@opendata-ai/openchart-core';\nimport type { ChartRenderer } from '../registry';\nimport { computeScatterMarks } from './compute';\nimport { computeTrendLine } from './trendline';\n\n// ---------------------------------------------------------------------------\n// Scatter chart renderer\n// ---------------------------------------------------------------------------\n\n/**\n * Scatter chart renderer.\n *\n * Produces point marks for each data point, optionally with size encoding\n * for bubbles and a trend line overlay.\n */\nexport const scatterRenderer: ChartRenderer = (spec, scales, chartArea, strategy, _theme) => {\n const pointMarks = computeScatterMarks(spec, scales, chartArea, strategy);\n const marks: Mark[] = [...pointMarks];\n\n // Add trend line if there are enough points\n const trendLine = computeTrendLine(pointMarks);\n if (trendLine) {\n // Trend line goes behind points\n marks.unshift(trendLine);\n }\n\n return marks;\n};\n\n// ---------------------------------------------------------------------------\n// Public exports\n// ---------------------------------------------------------------------------\n\nexport { computeScatterMarks } from './compute';\nexport { computeTrendLine } from './trendline';\n","/**\n * Text mark renderer.\n *\n * Computes TextMarkLayout marks from a normalized chart spec.\n * Positions text at data coordinates using x/y encoding channels,\n * with content from the text encoding channel.\n */\n\nimport type { Encoding, Mark, MarkAria, TextMarkLayout } from '@opendata-ai/openchart-core';\nimport { getRepresentativeColor } from '@opendata-ai/openchart-core';\n\nimport type { NormalizedChartSpec } from '../../compiler/types';\nimport type { ResolvedScales } from '../../layout/scales';\nimport type { ChartRenderer } from '../registry';\nimport { getColor, scaleValue } from '../utils';\n\n/**\n * Compute text marks from spec data and resolved scales.\n */\nexport function computeTextMarks(\n spec: NormalizedChartSpec,\n scales: ResolvedScales,\n): TextMarkLayout[] {\n const encoding = spec.encoding as Encoding;\n const xChannel = encoding.x;\n const yChannel = encoding.y;\n const textChannel = encoding.text;\n\n if (!textChannel || !('field' in textChannel)) return [];\n\n const marks: TextMarkLayout[] = [];\n const colorEncoding = encoding.color && 'field' in encoding.color ? encoding.color : undefined;\n const colorField = colorEncoding?.field;\n const sizeEncoding = encoding.size && 'field' in encoding.size ? encoding.size : undefined;\n\n for (const row of spec.data) {\n // Resolve x position (center of chart if no x encoding)\n let x = 0;\n if (xChannel && scales.x) {\n const xVal = scaleValue(scales.x.scale, scales.x.type, row[xChannel.field]);\n if (xVal == null) continue;\n x = xVal;\n }\n\n // Resolve y position (center of chart if no y encoding)\n let y = 0;\n if (yChannel && scales.y) {\n const yVal = scaleValue(scales.y.scale, scales.y.type, row[yChannel.field]);\n if (yVal == null) continue;\n y = yVal;\n }\n\n const text = String(row[textChannel.field] ?? '');\n if (!text) continue;\n\n const color = getRepresentativeColor(\n colorField\n ? getColor(scales, String(row[colorField] ?? '__default__'))\n : getColor(scales, '__default__'),\n );\n\n const fontSize = sizeEncoding\n ? Math.max(8, Math.min(48, Number(row[sizeEncoding.field]) || 12))\n : 12;\n\n const aria: MarkAria = {\n label: text,\n };\n\n marks.push({\n type: 'textMark',\n x,\n y,\n text,\n fill: color,\n fontSize,\n textAnchor: 'middle',\n angle:\n encoding.angle && 'field' in encoding.angle\n ? Number(row[encoding.angle.field]) || 0\n : undefined,\n data: row as Record<string, unknown>,\n aria,\n });\n }\n\n return marks;\n}\n\n/**\n * Text chart renderer.\n */\nexport const textRenderer: ChartRenderer = (spec, scales, _chartArea, _strategy, _theme) => {\n return computeTextMarks(spec, scales) as Mark[];\n};\n","/**\n * Tick mark renderer.\n *\n * Computes TickMarkLayout marks from a normalized chart spec.\n * Ticks are short line segments used for strip/rug plots.\n * Each data point produces a small tick perpendicular to the data axis.\n */\n\nimport type { Encoding, Mark, MarkAria, Rect, TickMarkLayout } from '@opendata-ai/openchart-core';\nimport { getRepresentativeColor } from '@opendata-ai/openchart-core';\n\nimport type { NormalizedChartSpec } from '../../compiler/types';\nimport type { ResolvedScales } from '../../layout/scales';\nimport type { ChartRenderer } from '../registry';\nimport { getColor, scaleValue } from '../utils';\n\n/** Default tick length in pixels. */\nconst DEFAULT_TICK_LENGTH = 18;\n\n/**\n * Compute tick marks from spec data and resolved scales.\n *\n * Orientation is inferred from the encoding:\n * - If x is quantitative and y is categorical (or vice versa), ticks are\n * perpendicular to the quantitative axis.\n * - Default: vertical ticks (short vertical lines at each x position).\n */\nexport function computeTickMarks(\n spec: NormalizedChartSpec,\n scales: ResolvedScales,\n _chartArea: Rect,\n): TickMarkLayout[] {\n const encoding = spec.encoding as Encoding;\n const xChannel = encoding.x;\n const yChannel = encoding.y;\n\n if (!xChannel || !yChannel || !scales.x || !scales.y) return [];\n\n const colorEncoding = encoding.color && 'field' in encoding.color ? encoding.color : undefined;\n const colorField = colorEncoding?.field;\n const marks: TickMarkLayout[] = [];\n\n // Determine orientation: ticks are perpendicular to the quantitative axis\n const isHorizontal = xChannel.type === 'quantitative' && yChannel.type !== 'quantitative';\n const orient: 'horizontal' | 'vertical' = isHorizontal ? 'horizontal' : 'vertical';\n\n for (const row of spec.data) {\n const xVal = scaleValue(scales.x.scale, scales.x.type, row[xChannel.field]);\n const yVal = scaleValue(scales.y.scale, scales.y.type, row[yChannel.field]);\n if (xVal == null || yVal == null) continue;\n\n const color = getRepresentativeColor(\n colorField\n ? getColor(scales, String(row[colorField] ?? '__default__'))\n : getColor(scales, '__default__'),\n );\n\n const aria: MarkAria = {\n label: `${row[xChannel.field]}, ${row[yChannel.field]}`,\n };\n\n marks.push({\n type: 'tick',\n x: xVal,\n y: yVal,\n length: DEFAULT_TICK_LENGTH,\n orient,\n stroke: color,\n strokeWidth: 1,\n opacity:\n encoding.opacity && 'field' in encoding.opacity\n ? Math.max(0, Math.min(1, Number(row[encoding.opacity.field]) || 1))\n : undefined,\n data: row as Record<string, unknown>,\n aria,\n });\n }\n\n return marks;\n}\n\n/**\n * Tick chart renderer.\n */\nexport const tickRenderer: ChartRenderer = (spec, scales, chartArea, _strategy, _theme) => {\n return computeTickMarks(spec, scales, chartArea) as Mark[];\n};\n","/**\n * Built-in chart renderer registration.\n *\n * Each chart type (line, bar, column, scatter, pie, etc.) has a renderer that\n * produces marks from a normalized spec. This module wires them into the\n * registry. Importing it is a side effect: the built-ins register as soon as\n * it's loaded.\n *\n * Tests that call `clearRenderers()` can call `registerBuiltinRenderers()` to\n * restore the default set rather than leaving the registry empty for later\n * tests in the same process.\n */\n\nimport { barRenderer } from './bar';\nimport { columnRenderer } from './column';\nimport { dotRenderer } from './dot';\nimport { areaRenderer, lineRenderer } from './line';\nimport { donutRenderer, pieRenderer } from './pie';\nimport { type ChartRenderer, registerChartRenderer } from './registry';\nimport { ruleRenderer } from './rule';\nimport { scatterRenderer } from './scatter';\nimport { textRenderer } from './text';\nimport { tickRenderer } from './tick';\n\n// Mark type mapping from old chart types:\n// - 'bar' -> barRenderer (horizontal bars, old 'bar')\n// - 'bar:vertical' is handled by columnRenderer (old 'column')\n// - 'arc' -> pieRenderer (old 'pie'); donutRenderer is also registered\n// - 'point' -> scatterRenderer (old 'scatter')\n// - 'circle' -> dotRenderer (old 'dot')\n// - 'line' and 'area' unchanged\n// - 'text', 'rule', 'tick' are new Vega-Lite mark types\n//\n// For 'bar', orientation is resolved at compile time to dispatch to the right\n// renderer. We register both barRenderer and columnRenderer; the compile\n// function picks based on orientation.\nconst builtinRenderers: Record<string, ChartRenderer> = {\n line: lineRenderer,\n area: areaRenderer,\n bar: barRenderer, // horizontal bars\n 'bar:vertical': columnRenderer, // vertical bars (old 'column')\n point: scatterRenderer, // old 'scatter'\n arc: pieRenderer, // old 'pie' (donut handled via innerRadius)\n 'arc:donut': donutRenderer, // old 'donut'\n circle: dotRenderer, // old 'dot'\n lollipop: dotRenderer, // semantic alias for dot/circle\n text: textRenderer,\n rule: ruleRenderer,\n tick: tickRenderer,\n rect: columnRenderer, // rect uses column renderer (RectMark output) as baseline for heatmaps\n};\n\n/**\n * Register all built-in chart renderers. Called once on module load; also\n * exported so tests that clear the registry can restore the defaults.\n */\nexport function registerBuiltinRenderers(): void {\n for (const [type, renderer] of Object.entries(builtinRenderers)) {\n registerChartRenderer(type, renderer);\n }\n}\n\n// Side effect: register on first import.\nregisterBuiltinRenderers();\n","/**\n * Mark post-processing: obstacle computation, renderer dispatch, and\n * animation index assignment. These are mark-type-aware operations that\n * run after the chart renderer has produced marks.\n */\n\nimport type {\n Encoding,\n Mark,\n MarkDef,\n PointMark,\n Rect,\n RectMark,\n ResolvedAnimation,\n} from '@opendata-ai/openchart-core';\nimport type { ResolvedScales } from '../layout/scales';\n\n// ---------------------------------------------------------------------------\n// Mark obstacles for annotation collision avoidance\n// ---------------------------------------------------------------------------\n\n/**\n * Compute bounding rects from marks to use as obstacles for annotation nudging.\n *\n * For band-scale charts (bar, dot): groups marks by band row and returns\n * a single obstacle per row spanning the full band height and x-range.\n *\n * For other charts (column, scatter): returns individual mark bounds so\n * annotations avoid overlapping any visible data mark.\n */\nexport function computeMarkObstacles(marks: Mark[], scales: ResolvedScales): Rect[] {\n // Band-scale y-axis: group marks by row for efficient obstacle computation\n if (scales.y?.type === 'band') {\n return computeBandRowObstacles(marks, scales);\n }\n\n // All other charts: use individual rect/point mark bounds as obstacles\n const obstacles: Rect[] = [];\n for (const mark of marks) {\n if (mark.type === 'rect') {\n const rm = mark as RectMark;\n obstacles.push({ x: rm.x, y: rm.y, width: rm.width, height: rm.height });\n } else if (mark.type === 'point') {\n const pm = mark as PointMark;\n obstacles.push({\n x: pm.cx - pm.r,\n y: pm.cy - pm.r,\n width: pm.r * 2,\n height: pm.r * 2,\n });\n }\n }\n return obstacles;\n}\n\n/** Group band-scale marks by row, returning one obstacle per band. */\nfunction computeBandRowObstacles(marks: Mark[], scales: ResolvedScales): Rect[] {\n const rows = new Map<number, { minX: number; maxX: number; bandY: number }>();\n\n for (const mark of marks) {\n let cy: number;\n let left: number;\n let right: number;\n\n if (mark.type === 'point') {\n const pm = mark as PointMark;\n cy = pm.cy;\n left = pm.cx - pm.r;\n right = pm.cx + pm.r;\n } else if (mark.type === 'rect') {\n const rm = mark as RectMark;\n cy = rm.y + rm.height / 2;\n left = rm.x;\n right = rm.x + rm.width;\n } else {\n continue;\n }\n\n // Round cy to group marks on the same band\n const key = Math.round(cy);\n const existing = rows.get(key);\n if (existing) {\n existing.minX = Math.min(existing.minX, left);\n existing.maxX = Math.max(existing.maxX, right);\n } else {\n rows.set(key, { minX: left, maxX: right, bandY: cy });\n }\n }\n\n // Get bandwidth from the band scale\n const bandScale = scales.y!.scale as { bandwidth?: () => number };\n const bandwidth = bandScale.bandwidth?.() ?? 0;\n if (bandwidth === 0) return [];\n\n const obstacles: Rect[] = [];\n for (const { minX, maxX, bandY } of rows.values()) {\n obstacles.push({\n x: minX,\n y: bandY - bandwidth / 2,\n width: maxX - minX,\n height: bandwidth,\n });\n }\n\n return obstacles;\n}\n\n// ---------------------------------------------------------------------------\n// Renderer key dispatch\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the renderer key from mark type, encoding, and mark definition.\n *\n * - 'bar' -> 'bar' (horizontal) or 'bar:vertical' based on encoding axis types\n * - 'arc' -> 'arc' (pie) or 'arc:donut' based on innerRadius\n * - All other mark types pass through unchanged\n */\nexport function resolveRendererKey(\n markType: string,\n encoding: Partial<Encoding>,\n markDef: Partial<MarkDef>,\n): string {\n if (markType === 'bar') {\n const xType = encoding.x?.type;\n const yType = encoding.y?.type;\n const isVertical =\n (xType === 'nominal' || xType === 'ordinal' || xType === 'temporal') &&\n yType === 'quantitative';\n if (isVertical) {\n return 'bar:vertical';\n }\n } else if (markType === 'arc') {\n const innerRadius = markDef.innerRadius;\n if (innerRadius && innerRadius > 0) {\n return 'arc:donut';\n }\n }\n return markType;\n}\n\n// ---------------------------------------------------------------------------\n// Animation index assignment\n// ---------------------------------------------------------------------------\n\n/** Extract the primary quantitative value from a mark for value-based stagger ordering. */\nfunction getMarkPrimaryValue(mark: Mark): number {\n switch (mark.type) {\n case 'rect':\n return mark.height; // bar height is the primary value encoding\n case 'point':\n return mark.cy; // y position for scatter\n case 'arc':\n return mark.endAngle - mark.startAngle; // arc angle extent\n case 'line':\n case 'area':\n return 0; // series marks don't have individual values\n default:\n return 0;\n }\n}\n\n/**\n * Assign animation indices to marks for stagger ordering.\n *\n * Two phases:\n * 1. Value-based stagger: sorts marks by primary value, assigns sequential indices.\n * Skips stacked rects since they get group-based indices in phase 2.\n * 2. Stack-based stagger: groups marks by stackGroup, assigns the same index to\n * all segments in a group, and computes stackPos (segment position: 0, 1, 2...).\n * This intentionally overwrites any value-based indices for stacked marks.\n */\nexport function assignAnimationIndices(\n marks: Mark[],\n animation: ResolvedAnimation | undefined,\n): void {\n if (!animation?.enabled) return;\n\n // Phase 1: Value-based stagger ordering. Skip stacked rects\n // since they get group-based indices below (avoids wasted work that gets overwritten).\n if (animation.staggerOrder === 'value') {\n const indexed = marks.map((m, i) => ({ mark: m, idx: i }));\n indexed.sort((a, b) => {\n const av = getMarkPrimaryValue(a.mark);\n const bv = getMarkPrimaryValue(b.mark);\n return av - bv;\n });\n for (let i = 0; i < indexed.length; i++) {\n const m = indexed[i].mark;\n if (m.type === 'rect' && (m as RectMark).stackGroup) continue;\n m.animationIndex = i;\n }\n }\n\n // Phase 2: For stacked bars/columns, assign the same animationIndex to all segments\n // sharing a stackGroup so they animate as one contiguous bar per category.\n // Also compute stackPos (segment position within each group: 0, 1, 2...)\n // so the renderer can chain segment animations sequentially.\n const groupIndexMap = new Map<string, number>();\n const groupStackPos = new Map<string, number>();\n let nextGroupIndex = 0;\n for (const mark of marks) {\n if (mark.type === 'rect' && (mark as RectMark).stackGroup) {\n const rect = mark as RectMark;\n const group = rect.stackGroup!;\n if (!groupIndexMap.has(group)) {\n groupIndexMap.set(group, nextGroupIndex++);\n }\n rect.animationIndex = groupIndexMap.get(group)!;\n const pos = groupStackPos.get(group) ?? 0;\n rect.stackPos = pos;\n groupStackPos.set(group, pos + 1);\n }\n }\n}\n","/**\n * Apply the theme palette as the color scale range when no explicit range was provided.\n *\n * Sequential scales take the first/last stops of the first sequential palette\n * (or the categorical endpoints as a fallback). Categorical scales get the\n * full categorical palette. A user-provided `encoding.color.scale.range`\n * always wins.\n */\n\nimport type { Encoding, ResolvedTheme } from '@opendata-ai/openchart-core';\nimport type { ScaleLinear, ScaleOrdinal } from 'd3-scale';\nimport type { ResolvedScales } from '../layout/scales';\n\n/** Mutates `scales.color.scale.range` in place when no explicit palette was set. */\nexport function applyColorScaleRange(\n scales: ResolvedScales,\n encoding: Encoding,\n theme: ResolvedTheme,\n): void {\n if (!scales.color) return;\n\n const hasExplicitRange = !!(\n encoding.color &&\n 'field' in encoding.color &&\n (encoding.color.scale?.range as string[] | undefined)?.length\n );\n if (hasExplicitRange) return;\n\n if (scales.color.type === 'sequential') {\n const seqStops = Object.values(theme.colors.sequential)[0] ?? theme.colors.categorical;\n (scales.color.scale as unknown as ScaleLinear<string, string>).range([\n seqStops[0],\n seqStops[seqStops.length - 1],\n ]);\n } else {\n (scales.color.scale as ScaleOrdinal<string, string>).range(theme.colors.categorical);\n }\n}\n","/**\n * Data filter for clipped scale domains.\n *\n * When an x or y encoding declares `scale.clip: true` with a numeric\n * [lo, hi] domain, rows whose field value falls outside that range are\n * dropped before scales and marks are computed. Pure and side-effect free.\n */\n\nimport type { DataRow, Encoding } from '@opendata-ai/openchart-core';\n\n/**\n * Return a new data array with rows outside any clipped scale domain removed.\n *\n * Only inspects the `x` and `y` channels. Non-numeric domains and channels\n * without `scale.clip` are passed through unchanged.\n */\nexport function filterClippedDomains(data: DataRow[], encoding: Encoding): DataRow[] {\n let result = data;\n for (const channel of ['x', 'y'] as const) {\n const enc = encoding[channel];\n if (!enc?.scale?.clip || !enc.scale.domain) continue;\n const domain = enc.scale.domain;\n const field = enc.field;\n if (Array.isArray(domain) && domain.length === 2 && typeof domain[0] === 'number') {\n const [lo, hi] = domain as [number, number];\n result = result.filter((row) => {\n const v = Number(row[field]);\n return Number.isFinite(v) && v >= lo && v <= hi;\n });\n }\n }\n return result;\n}\n","/**\n * Compute the brand watermark obstacle rect.\n *\n * The watermark is right-aligned on the same baseline as the first bottom\n * chrome element (source, byline, or footer), offset below the chart area\n * by the x-axis extent (tick labels + axis title). Returns null when the\n * watermark is disabled so callers can skip obstacle collection entirely.\n */\n\nimport type { Rect, ResolvedTheme } from '@opendata-ai/openchart-core';\nimport { BRAND_RESERVE_WIDTH } from '@opendata-ai/openchart-core';\nimport type { AxesResult } from '../layout/axes';\nimport type { LayoutDimensions } from '../layout/dimensions';\n\n/** Height of the watermark element used for obstacle avoidance. */\nconst WATERMARK_HEIGHT = 30;\n\n/** Vertical padding below the x-axis label when an axis title is present. */\nconst X_AXIS_EXTENT_WITH_LABEL = 48;\n\n/** Vertical padding below the x-axis ticks when no axis title is present. */\nconst X_AXIS_EXTENT_TICKS_ONLY = 26;\n\n/**\n * Compute the rect occupied by the watermark, or null when it is disabled.\n *\n * @param dims - Layout dimensions (for total width and chrome positions).\n * @param watermark - Whether the watermark is enabled for this chart.\n * @param axes - Computed axes (the x-axis determines how far below the chart the watermark sits).\n * @param theme - Resolved theme (padding + fallback spacing).\n */\nexport function computeWatermarkObstacle(\n dims: LayoutDimensions,\n watermark: boolean,\n axes: AxesResult,\n theme: ResolvedTheme,\n): Rect | null {\n if (!watermark) return null;\n\n const chartArea = dims.chartArea;\n const brandPadding = theme.spacing.padding;\n const brandX = dims.total.width - brandPadding - BRAND_RESERVE_WIDTH;\n const xAxisExtent = axes.x?.label\n ? X_AXIS_EXTENT_WITH_LABEL\n : axes.x\n ? X_AXIS_EXTENT_TICKS_ONLY\n : 0;\n const firstBottomChrome = dims.chrome.source ?? dims.chrome.byline ?? dims.chrome.footer;\n const brandY = firstBottomChrome\n ? chartArea.y + chartArea.height + xAxisExtent + firstBottomChrome.y\n : chartArea.y + chartArea.height + xAxisExtent + theme.spacing.chartToFooter;\n\n return { x: brandX, y: brandY, width: BRAND_RESERVE_WIDTH, height: WATERMARK_HEIGHT };\n}\n","/**\n * Animation resolver: normalizes AnimationSpec into fully resolved config.\n *\n * Handles the shorthand forms:\n * - true -> { enter: true } -> full defaults\n * - { enter: { duration: 800 } } -> merge with defaults\n * - false/undefined -> undefined (no animation)\n */\n\nimport type {\n AnimationConfig,\n AnimationEase,\n AnimationPhaseConfig,\n AnimationSpec,\n AnimationStagger,\n ResolvedAnimation,\n} from '@opendata-ai/openchart-core';\n\n/** Default values for entrance animation. */\nconst ENTER_DEFAULTS = {\n duration: 500,\n ease: 'smooth' as AnimationEase,\n staggerDelay: 80,\n staggerOrder: 'index' as const,\n annotationDelay: 200,\n} as const;\n\n/** Maximum total stagger time in ms. Prevents 200-bar charts from taking 6s. */\nconst MAX_TOTAL_STAGGER_MS = 2000;\n\n/**\n * Resolve an AnimationSpec into a fully resolved config with all defaults filled.\n * Returns undefined if animation is disabled (false or omitted).\n */\nexport function resolveAnimation(spec: AnimationSpec | undefined): ResolvedAnimation | undefined {\n if (spec === undefined || spec === false) return undefined;\n\n // true -> default enter animation\n if (spec === true) {\n return {\n enabled: true,\n duration: ENTER_DEFAULTS.duration,\n ease: ENTER_DEFAULTS.ease,\n staggerDelay: ENTER_DEFAULTS.staggerDelay,\n staggerOrder: ENTER_DEFAULTS.staggerOrder,\n annotationDelay: ENTER_DEFAULTS.annotationDelay,\n };\n }\n\n // AnimationConfig object\n const config = spec as AnimationConfig;\n\n // If no enter phase specified or enter is false, no animation\n if (config.enter === false || (config.enter === undefined && !hasAnyPhase(config))) {\n return undefined;\n }\n\n const enterConfig = resolvePhaseConfig(config.enter);\n\n return {\n enabled: true,\n duration: enterConfig.duration,\n ease: enterConfig.ease,\n staggerDelay: enterConfig.staggerDelay,\n staggerOrder: enterConfig.staggerOrder,\n annotationDelay: config.annotationDelay ?? ENTER_DEFAULTS.annotationDelay,\n };\n}\n\n/**\n * Clamp stagger delay so total stagger time doesn't exceed MAX_TOTAL_STAGGER_MS.\n */\nexport function clampStaggerDelay(delay: number, elementCount: number): number {\n if (elementCount <= 1) return 0;\n return Math.min(delay, MAX_TOTAL_STAGGER_MS / elementCount);\n}\n\nfunction hasAnyPhase(config: AnimationConfig): boolean {\n return config.enter !== undefined || config.update !== undefined || config.exit !== undefined;\n}\n\ninterface ResolvedPhase {\n duration: number;\n ease: AnimationEase;\n staggerDelay: number;\n staggerOrder: 'index' | 'value' | 'reverse';\n}\n\nfunction resolvePhaseConfig(phase: AnimationPhaseConfig | boolean | undefined): ResolvedPhase {\n if (phase === undefined || phase === true) {\n return {\n duration: ENTER_DEFAULTS.duration,\n ease: ENTER_DEFAULTS.ease,\n staggerDelay: ENTER_DEFAULTS.staggerDelay,\n staggerOrder: ENTER_DEFAULTS.staggerOrder,\n };\n }\n\n const cfg = phase as AnimationPhaseConfig;\n const stagger = resolveStagger(cfg.stagger);\n\n return {\n duration: cfg.duration ?? ENTER_DEFAULTS.duration,\n ease: cfg.ease ?? ENTER_DEFAULTS.ease,\n staggerDelay: stagger.delay,\n staggerOrder: stagger.order,\n };\n}\n\nfunction resolveStagger(stagger: AnimationStagger | boolean | undefined): {\n delay: number;\n order: 'index' | 'value' | 'reverse';\n} {\n if (stagger === false) return { delay: 0, order: 'index' };\n if (stagger === undefined || stagger === true) {\n return { delay: ENTER_DEFAULTS.staggerDelay, order: ENTER_DEFAULTS.staggerOrder };\n }\n return {\n delay: stagger.delay ?? ENTER_DEFAULTS.staggerDelay,\n order: stagger.order ?? ENTER_DEFAULTS.staggerOrder,\n };\n}\n","/**\n * Spec normalization: fill in defaults and infer types.\n *\n * Takes a validated VizSpec and produces a NormalizedSpec where:\n * - All optional fields have sensible defaults\n * - Chrome strings are converted to ChromeText objects\n * - Encoding types are inferred from data if not specified\n * - Annotations have default styles\n */\n\nimport type {\n Annotation,\n ChartSpec,\n Chrome,\n ChromeText,\n DataRow,\n Encoding,\n FieldType,\n GraphSpec,\n LayerSpec,\n SankeySpec,\n TableSpec,\n VizSpec,\n} from '@opendata-ai/openchart-core';\nimport {\n isChartSpec,\n isGraphSpec,\n isLayerSpec,\n isSankeySpec,\n isTableSpec,\n resolveMarkDef,\n resolveMarkType,\n} from '@opendata-ai/openchart-core';\nimport type { NormalizedSankeySpec } from '../sankey/types';\nimport type {\n NormalizedChartSpec,\n NormalizedChrome,\n NormalizedGraphSpec,\n NormalizedSpec,\n NormalizedTableSpec,\n} from './types';\n\n// ---------------------------------------------------------------------------\n// Chrome normalization\n// ---------------------------------------------------------------------------\n\n/** Convert a string | ChromeText | undefined to ChromeText | undefined. */\nfunction normalizeChromeField(value: string | ChromeText | undefined): ChromeText | undefined {\n if (value === undefined) return undefined;\n if (typeof value === 'string') return { text: value };\n return value;\n}\n\n/** Normalize all chrome fields from strings to ChromeText objects. */\nfunction normalizeChrome(chrome: Chrome | undefined): NormalizedChrome {\n if (!chrome) return {};\n return {\n title: normalizeChromeField(chrome.title),\n subtitle: normalizeChromeField(chrome.subtitle),\n source: normalizeChromeField(chrome.source),\n byline: normalizeChromeField(chrome.byline),\n footer: normalizeChromeField(chrome.footer),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Type inference\n// ---------------------------------------------------------------------------\n\n/** Sample values from a data column and infer the field type. */\nfunction inferFieldType(data: DataRow[], field: string): FieldType {\n // Sample up to 50 rows for more reliable inference on mixed/messy data\n const sampleSize = Math.min(50, data.length);\n let numericCount = 0;\n let dateCount = 0;\n let totalNonNull = 0;\n\n for (let i = 0; i < sampleSize; i++) {\n const value = data[i][field];\n if (value == null) continue;\n totalNonNull++;\n\n // Check numeric\n if (typeof value === 'number' && Number.isFinite(value)) {\n numericCount++;\n continue;\n }\n\n // Check date-like strings\n if (typeof value === 'string') {\n // Try as number first\n const num = Number(value);\n if (!Number.isNaN(num) && Number.isFinite(num) && value.trim() !== '') {\n numericCount++;\n continue;\n }\n\n // Try as date\n const date = new Date(value);\n if (!Number.isNaN(date.getTime())) {\n dateCount++;\n continue;\n }\n }\n\n if (value instanceof Date && !Number.isNaN(value.getTime())) {\n dateCount++;\n }\n }\n\n if (totalNonNull === 0) return 'nominal';\n\n // If >80% of sampled values are dates, it's temporal\n if (dateCount / totalNonNull > 0.8) return 'temporal';\n // If >80% are numeric, it's quantitative\n if (numericCount / totalNonNull > 0.8) return 'quantitative';\n // Otherwise it's nominal\n return 'nominal';\n}\n\n/** Infer types for encoding channels that don't have one specified. */\nfunction inferEncodingTypes(encoding: Encoding, data: DataRow[], warnings: string[]): Encoding {\n const result = { ...encoding };\n\n for (const channel of ['x', 'y', 'color', 'size', 'detail'] as const) {\n const spec = result[channel];\n if (!spec) continue;\n\n // Skip conditional value definitions - they don't have field/type at the top level\n if ('condition' in spec) continue;\n\n if (!spec.type) {\n const inferred = inferFieldType(data, spec.field);\n (result as Record<string, unknown>)[channel] = { ...spec, type: inferred };\n warnings.push(\n `Inferred encoding.${channel}.type as \"${inferred}\" from data values for field \"${spec.field}\"`,\n );\n } else {\n // Check for potential mismatches and warn\n const actualType = inferFieldType(data, spec.field);\n if (spec.type === 'nominal' && actualType === 'temporal') {\n warnings.push(`Field \"${spec.field}\" looks temporal but was declared as nominal`);\n }\n if (spec.type === 'nominal' && actualType === 'quantitative') {\n warnings.push(`Field \"${spec.field}\" looks quantitative but was declared as nominal`);\n }\n }\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Annotation normalization\n// ---------------------------------------------------------------------------\n\n/** Apply default styles to annotations that don't have them. */\nfunction normalizeAnnotations(annotations: Annotation[] | undefined): Annotation[] {\n if (!annotations || annotations.length === 0) return [];\n\n return annotations.map((ann) => {\n switch (ann.type) {\n case 'text':\n return {\n ...ann,\n fontSize: ann.fontSize ?? 12,\n fontWeight: ann.fontWeight ?? 400,\n opacity: ann.opacity ?? 1,\n };\n case 'range':\n return {\n ...ann,\n opacity: ann.opacity ?? 0.1,\n fill: ann.fill ?? '#000000',\n };\n case 'refline':\n return {\n ...ann,\n style: ann.style ?? 'dashed',\n strokeWidth: ann.strokeWidth ?? 1,\n stroke: ann.stroke ?? '#666666',\n opacity: ann.opacity ?? 0.8,\n };\n default:\n return ann;\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Spec-level normalization\n// ---------------------------------------------------------------------------\n\nfunction normalizeChartSpec(spec: ChartSpec, warnings: string[]): NormalizedChartSpec {\n const encoding = inferEncodingTypes(spec.encoding, spec.data, warnings);\n const markType = resolveMarkType(spec.mark);\n const markDef = resolveMarkDef(spec.mark);\n\n return {\n markType,\n markDef,\n data: spec.data,\n encoding,\n chrome: normalizeChrome(spec.chrome),\n annotations: normalizeAnnotations(spec.annotations),\n labels: {\n density: spec.labels?.density ?? 'auto',\n format: spec.labels?.format ?? '',\n prefix: spec.labels?.prefix ?? '',\n offsets: spec.labels?.offsets,\n },\n legend: spec.legend,\n responsive: spec.responsive ?? true,\n theme: spec.theme ?? {},\n darkMode: spec.darkMode ?? 'off',\n hiddenSeries: spec.hiddenSeries ?? [],\n seriesStyles: spec.seriesStyles ?? {},\n watermark: spec.watermark ?? true,\n };\n}\n\nfunction normalizeTableSpec(spec: TableSpec, _warnings: string[]): NormalizedTableSpec {\n return {\n type: 'table',\n data: spec.data,\n columns: spec.columns,\n rowKey: spec.rowKey,\n chrome: normalizeChrome(spec.chrome),\n theme: spec.theme ?? {},\n darkMode: spec.darkMode ?? 'off',\n search: spec.search ?? false,\n pagination: spec.pagination ?? false,\n stickyFirstColumn: spec.stickyFirstColumn ?? false,\n compact: spec.compact ?? false,\n responsive: spec.responsive ?? true,\n animation: spec.animation,\n watermark: spec.watermark ?? true,\n };\n}\n\nfunction normalizeSankeySpec(spec: SankeySpec, _warnings: string[]): NormalizedSankeySpec {\n return {\n type: 'sankey',\n data: spec.data,\n encoding: spec.encoding,\n nodeWidth: spec.nodeWidth ?? 12,\n nodePadding: spec.nodePadding ?? 16,\n nodeAlign: spec.nodeAlign ?? 'justify',\n iterations: spec.iterations ?? 6,\n linkStyle: spec.linkStyle ?? 'gradient',\n nodeLabelAlign: spec.nodeLabelAlign ?? 'auto',\n nodeSort: spec.nodeSort,\n chrome: normalizeChrome(spec.chrome),\n legend: spec.legend,\n theme: spec.theme ?? {},\n darkMode: spec.darkMode ?? 'off',\n animation: spec.animation,\n valueFormat: spec.valueFormat,\n linkOpacity: spec.linkOpacity,\n watermark: spec.watermark ?? true,\n };\n}\n\nfunction normalizeGraphSpec(spec: GraphSpec, _warnings: string[]): NormalizedGraphSpec {\n // Default layout with chargeStrength and linkDistance\n const defaultLayout = {\n type: 'force' as const,\n chargeStrength: -300,\n linkDistance: 30,\n };\n const layout = spec.layout\n ? {\n ...defaultLayout,\n ...spec.layout,\n }\n : defaultLayout;\n\n return {\n type: 'graph',\n nodes: spec.nodes,\n edges: spec.edges,\n encoding: spec.encoding ?? {},\n layout,\n nodeOverrides: spec.nodeOverrides,\n chrome: normalizeChrome(spec.chrome),\n annotations: normalizeAnnotations(spec.annotations),\n theme: spec.theme ?? {},\n darkMode: spec.darkMode ?? 'off',\n watermark: spec.watermark ?? true,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize a validated VizSpec, filling in all defaults.\n *\n * @param spec - A validated VizSpec (must pass validateSpec first).\n * @param warnings - Mutable array to collect non-fatal warnings.\n * @returns A NormalizedSpec with all optionals filled.\n */\nexport function normalizeSpec(spec: VizSpec, warnings: string[] = []): NormalizedSpec {\n if (isLayerSpec(spec)) {\n // For LayerSpec, we flatten and normalize the first leaf to get a valid NormalizedChartSpec.\n // The actual layer compilation happens in compileLayer, not here.\n // This path exists so the generic compile() pipeline doesn't reject layer specs.\n const leaves = flattenLayers(spec);\n if (leaves.length === 0) {\n throw new Error('LayerSpec has no leaf chart specs after flattening');\n }\n return normalizeChartSpec(leaves[0], warnings);\n }\n if (isChartSpec(spec)) {\n return normalizeChartSpec(spec, warnings);\n }\n if (isTableSpec(spec)) {\n return normalizeTableSpec(spec, warnings);\n }\n if (isGraphSpec(spec)) {\n return normalizeGraphSpec(spec, warnings);\n }\n if (isSankeySpec(spec)) {\n return normalizeSankeySpec(spec, warnings);\n }\n // Should never happen after validation\n throw new Error(\n `Unknown spec shape. Expected mark (chart), layer, type: 'table', type: 'graph', or type: 'sankey'.`,\n );\n}\n\n// ---------------------------------------------------------------------------\n// Layer flattening (used by compileLayer in compile.ts)\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively flatten a LayerSpec into leaf ChartSpecs.\n * Merges parent data, encoding, and transforms down to children.\n */\nexport function flattenLayers(\n spec: LayerSpec,\n parentData?: DataRow[],\n parentEncoding?: Encoding,\n parentTransforms?: import('@opendata-ai/openchart-core').Transform[],\n parentWatermark?: boolean,\n): ChartSpec[] {\n const resolvedData = spec.data ?? parentData;\n const resolvedEncoding: Encoding | undefined =\n parentEncoding && spec.encoding\n ? { ...parentEncoding, ...spec.encoding }\n : (spec.encoding ?? parentEncoding);\n const resolvedTransforms = [...(parentTransforms ?? []), ...(spec.transform ?? [])];\n // Layer-level watermark propagates to children (child can still override)\n const resolvedWatermark = spec.watermark ?? parentWatermark;\n\n const leaves: ChartSpec[] = [];\n\n for (const child of spec.layer) {\n if (isLayerSpec(child)) {\n // Nested layer: recurse with merged context\n leaves.push(\n ...flattenLayers(\n child,\n resolvedData,\n resolvedEncoding,\n resolvedTransforms,\n resolvedWatermark,\n ),\n );\n } else {\n // Leaf ChartSpec: merge inherited properties\n const mergedData = child.data ?? resolvedData ?? [];\n const mergedEncoding = resolvedEncoding\n ? { ...resolvedEncoding, ...child.encoding }\n : child.encoding;\n const mergedTransforms = [...resolvedTransforms, ...(child.transform ?? [])];\n\n leaves.push({\n ...child,\n data: mergedData,\n encoding: mergedEncoding,\n transform: mergedTransforms.length > 0 ? mergedTransforms : undefined,\n // Inherit parent watermark if child doesn't explicitly set one\n ...(child.watermark === undefined && resolvedWatermark !== undefined\n ? { watermark: resolvedWatermark }\n : {}),\n });\n }\n }\n\n return leaves;\n}\n","/**\n * Runtime spec validation.\n *\n * TypeScript catches compile-time errors for specs written in code.\n * This module catches runtime errors for specs coming from JSON, APIs,\n * or Claude-generated output where the TypeScript compiler can't help.\n *\n * Every error includes a machine-readable code and an actionable suggestion\n * so consumers (and LLMs) can fix issues programmatically.\n */\n\nimport {\n type FieldType,\n MARK_ENCODING_RULES,\n MARK_TYPES,\n type MarkType,\n type VizSpec,\n} from '@opendata-ai/openchart-core';\n\nimport type { ValidationError, ValidationResult } from './types';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst VALID_FIELD_TYPES = new Set<string>(['quantitative', 'temporal', 'nominal', 'ordinal']);\n\nconst VALID_DARK_MODES = new Set<string>(['auto', 'force', 'off']);\n\n/** Check if a value looks like a parseable date. */\nfunction isParseableDate(value: unknown): boolean {\n if (value instanceof Date) return !Number.isNaN(value.getTime());\n if (typeof value === 'string') {\n const d = new Date(value);\n return !Number.isNaN(d.getTime());\n }\n if (typeof value === 'number') return true;\n return false;\n}\n\n/** Check if a value is numeric. */\nfunction isNumeric(value: unknown): boolean {\n if (typeof value === 'number') return Number.isFinite(value);\n if (typeof value === 'string') {\n const n = Number(value);\n return !Number.isNaN(n) && Number.isFinite(n);\n }\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Chart validation\n// ---------------------------------------------------------------------------\n\nfunction validateChartSpec(spec: Record<string, unknown>, errors: ValidationError[]): void {\n const markType =\n typeof spec.mark === 'string' ? spec.mark : (spec.mark as Record<string, unknown>)?.type;\n\n // Check data\n if (!Array.isArray(spec.data)) {\n errors.push({\n message: 'Spec error: \"data\" must be an array',\n path: 'data',\n code: 'INVALID_TYPE',\n suggestion: 'Provide data as an array of objects, e.g. data: [{ x: 1, y: 2 }]',\n });\n return; // Can't validate further without data\n }\n\n if (spec.data.length === 0) {\n errors.push({\n message: 'Spec error: \"data\" must be a non-empty array',\n path: 'data',\n code: 'EMPTY_DATA',\n suggestion: 'Add at least one data row, e.g. data: [{ x: 1, y: 2 }]',\n });\n return;\n }\n\n // Validate data entries are objects\n const firstRow = spec.data[0] as unknown;\n if (typeof firstRow !== 'object' || firstRow === null || Array.isArray(firstRow)) {\n errors.push({\n message: 'Spec error: each item in \"data\" must be a plain object',\n path: 'data[0]',\n code: 'INVALID_TYPE',\n suggestion:\n 'Each data item should be an object with key-value pairs, e.g. { name: \"Alice\", value: 10 }',\n });\n return;\n }\n\n // Check encoding exists\n if (!spec.encoding || typeof spec.encoding !== 'object') {\n const rules = MARK_ENCODING_RULES[markType as MarkType];\n const requiredChannels = Object.entries(rules)\n .filter(([, rule]) => rule.required)\n .map(([ch]) => ch);\n errors.push({\n message: `Spec error: ${markType} chart requires an \"encoding\" object`,\n path: 'encoding',\n code: 'MISSING_FIELD',\n suggestion: `Add an encoding object with required channels: ${requiredChannels.join(', ')}. Example: encoding: { ${requiredChannels.map((ch) => `${ch}: { field: \"...\", type: \"...\" }`).join(', ')} }`,\n });\n return;\n }\n\n const rules = MARK_ENCODING_RULES[markType as MarkType];\n const encoding = spec.encoding as Record<string, unknown>;\n const dataColumns = new Set(Object.keys(firstRow as Record<string, unknown>));\n const availableColumns = [...dataColumns].join(', ');\n\n // Validate required channels\n for (const [channel, rule] of Object.entries(rules)) {\n if (rule.required && !encoding[channel]) {\n const allowedTypes = rule.allowedTypes.join(' or ');\n errors.push({\n message: `Spec error: ${markType} chart requires encoding.${channel} but none was provided`,\n path: `encoding.${channel}`,\n code: 'MISSING_FIELD',\n suggestion: `Add encoding.${channel} with a field from your data (${availableColumns}) and type (${allowedTypes}). Example: ${channel}: { field: \"${[...dataColumns][0] ?? 'myField'}\", type: \"${rule.allowedTypes[0]}\" }`,\n });\n }\n }\n\n // Collect fields that transforms will create, so we don't reject them\n const transformFields = new Set<string>();\n if (Array.isArray(spec.transform)) {\n for (const t of spec.transform as Record<string, unknown>[]) {\n if (typeof t.as === 'string') transformFields.add(t.as);\n if (Array.isArray(t.as)) {\n for (const f of t.as) {\n if (typeof f === 'string') transformFields.add(f);\n }\n }\n }\n }\n\n // Validate provided channels\n for (const [channel, channelSpec] of Object.entries(encoding)) {\n if (!channelSpec || typeof channelSpec !== 'object') continue;\n\n // Tooltip can be an array of encoding channels\n if (channel === 'tooltip' && Array.isArray(channelSpec)) {\n for (let i = 0; i < channelSpec.length; i++) {\n const elem = channelSpec[i] as Record<string, unknown> | null;\n if (!elem || typeof elem !== 'object') continue;\n if (!elem.field || typeof elem.field !== 'string') {\n errors.push({\n message: `Spec error: encoding.tooltip[${i}] must have a \"field\" string`,\n path: `encoding.tooltip[${i}].field`,\n code: 'MISSING_FIELD',\n suggestion: `Add a field name from your data columns: ${availableColumns}`,\n });\n continue;\n }\n if (!dataColumns.has(elem.field) && !transformFields.has(elem.field)) {\n errors.push({\n message: `Spec error: encoding.tooltip[${i}].field \"${elem.field}\" does not exist in data. Available columns: ${availableColumns}`,\n path: `encoding.tooltip[${i}].field`,\n code: 'DATA_FIELD_MISSING',\n suggestion: `Use one of the available data columns: ${availableColumns}`,\n });\n }\n if (elem.type && !VALID_FIELD_TYPES.has(elem.type as string)) {\n errors.push({\n message: `Spec error: encoding.tooltip[${i}].type \"${elem.type}\" is not valid. Must be one of: ${[...VALID_FIELD_TYPES].join(', ')}`,\n path: `encoding.tooltip[${i}].type`,\n code: 'INVALID_VALUE',\n suggestion: `Use one of: ${[...VALID_FIELD_TYPES].join(', ')}`,\n });\n }\n }\n continue;\n }\n\n const channelObj = channelSpec as Record<string, unknown>;\n const channelRule = rules[channel as keyof typeof rules];\n\n // Skip ConditionalValueDef channels (they have 'condition' instead of 'field')\n if ('condition' in channelObj) continue;\n\n // Check field exists\n if (!channelObj.field || typeof channelObj.field !== 'string') {\n errors.push({\n message: `Spec error: encoding.${channel} must have a \"field\" string`,\n path: `encoding.${channel}.field`,\n code: 'MISSING_FIELD',\n suggestion: `For constant colors, use mark.fill (e.g., mark: { type: \"bar\", fill: \"#1b7fa3\" }) instead of encoding.${channel}. Encoding channels require a data field: ${availableColumns}`,\n });\n continue;\n }\n\n // Check field references a column in data (or will be created by a transform)\n if (!dataColumns.has(channelObj.field) && !transformFields.has(channelObj.field)) {\n errors.push({\n message: `Spec error: encoding.${channel}.field \"${channelObj.field}\" does not exist in data. Available columns: ${availableColumns}`,\n path: `encoding.${channel}.field`,\n code: 'DATA_FIELD_MISSING',\n suggestion: `Use one of the available data columns: ${availableColumns}`,\n });\n }\n\n // Check field type is valid\n if (channelObj.type && !VALID_FIELD_TYPES.has(channelObj.type as string)) {\n errors.push({\n message: `Spec error: encoding.${channel}.type \"${channelObj.type}\" is not valid. Must be one of: ${[...VALID_FIELD_TYPES].join(', ')}`,\n path: `encoding.${channel}.type`,\n code: 'INVALID_VALUE',\n suggestion: `Use one of: ${[...VALID_FIELD_TYPES].join(', ')}`,\n });\n }\n\n // Check field type is allowed for this channel\n if (channelRule && channelObj.type && channelRule.allowedTypes.length > 0) {\n if (!channelRule.allowedTypes.includes(channelObj.type as FieldType)) {\n errors.push({\n message: `Spec error: encoding.${channel} for ${markType} chart does not accept type \"${channelObj.type}\". Allowed types: ${channelRule.allowedTypes.join(', ')}`,\n path: `encoding.${channel}.type`,\n code: 'ENCODING_MISMATCH',\n suggestion: `Change encoding.${channel}.type to one of: ${channelRule.allowedTypes.join(', ')}`,\n });\n }\n }\n\n // Check field values match declared type\n if (channelObj.type && channelObj.field && dataColumns.has(channelObj.field as string)) {\n const data = spec.data as Record<string, unknown>[];\n const fieldName = channelObj.field as string;\n const fieldType = channelObj.type as string;\n // Sample up to 5 values for type checking\n const sampleSize = Math.min(5, data.length);\n\n if (fieldType === 'temporal') {\n let nonDateCount = 0;\n for (let i = 0; i < sampleSize; i++) {\n const val = data[i][fieldName];\n if (val != null && !isParseableDate(val)) {\n nonDateCount++;\n }\n }\n if (nonDateCount > 0) {\n errors.push({\n message: `Spec error: encoding.${channel}.field \"${fieldName}\" is declared as temporal but contains non-date values`,\n path: `encoding.${channel}`,\n code: 'ENCODING_MISMATCH',\n suggestion: `Either change the type to \"nominal\" or ensure \"${fieldName}\" values are parseable dates (ISO 8601 strings like \"2024-01-15\" or Date objects)`,\n });\n }\n }\n\n if (fieldType === 'quantitative') {\n let nonNumericCount = 0;\n for (let i = 0; i < sampleSize; i++) {\n const val = data[i][fieldName];\n if (val != null && !isNumeric(val)) {\n nonNumericCount++;\n }\n }\n if (nonNumericCount > 0) {\n errors.push({\n message: `Spec error: encoding.${channel}.field \"${fieldName}\" is declared as quantitative but contains non-numeric values`,\n path: `encoding.${channel}`,\n code: 'ENCODING_MISMATCH',\n suggestion: `Either change the type to \"nominal\" or ensure \"${fieldName}\" values are numbers`,\n });\n }\n }\n }\n }\n\n // Validate darkMode if provided\n if (spec.darkMode !== undefined && !VALID_DARK_MODES.has(spec.darkMode as string)) {\n errors.push({\n message: `Spec error: darkMode must be \"auto\", \"force\", or \"off\"`,\n path: 'darkMode',\n code: 'INVALID_VALUE',\n suggestion:\n 'Use one of: \"auto\" (system preference), \"force\" (always dark), or \"off\" (always light)',\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Table validation\n// ---------------------------------------------------------------------------\n\nfunction validateTableSpec(spec: Record<string, unknown>, errors: ValidationError[]): void {\n if (!Array.isArray(spec.data)) {\n errors.push({\n message: 'Spec error: \"data\" must be an array',\n path: 'data',\n code: 'INVALID_TYPE',\n suggestion: 'Provide data as an array of objects, e.g. data: [{ name: \"Alice\", age: 30 }]',\n });\n return;\n }\n\n if (spec.data.length === 0) {\n errors.push({\n message: 'Spec error: \"data\" must be a non-empty array',\n path: 'data',\n code: 'EMPTY_DATA',\n suggestion: 'Add at least one data row to the data array',\n });\n return;\n }\n\n if (!Array.isArray(spec.columns)) {\n errors.push({\n message: 'Spec error: table spec requires a \"columns\" array',\n path: 'columns',\n code: 'MISSING_FIELD',\n suggestion:\n 'Add a columns array defining which data fields to display, e.g. columns: [{ key: \"name\" }, { key: \"age\" }]',\n });\n return;\n }\n\n const data = spec.data as Record<string, unknown>[];\n const firstRow = data[0];\n if (typeof firstRow !== 'object' || firstRow === null || Array.isArray(firstRow)) {\n errors.push({\n message: 'Spec error: each item in \"data\" must be a plain object',\n path: 'data[0]',\n code: 'INVALID_TYPE',\n suggestion:\n 'Each data item should be an object with key-value pairs, e.g. { name: \"Alice\", age: 30 }',\n });\n return;\n }\n\n const dataColumns = new Set(Object.keys(firstRow as Record<string, unknown>));\n const availableColumns = [...dataColumns].join(', ');\n const columns = spec.columns as Record<string, unknown>[];\n\n for (let i = 0; i < columns.length; i++) {\n const col = columns[i];\n if (!col || typeof col !== 'object') {\n errors.push({\n message: `Spec error: columns[${i}] must be an object`,\n path: `columns[${i}]`,\n code: 'INVALID_TYPE',\n suggestion: 'Each column entry should be an object, e.g. { key: \"fieldName\" }',\n });\n continue;\n }\n\n // Check key exists\n if (!col.key || typeof col.key !== 'string') {\n errors.push({\n message: `Spec error: columns[${i}] must have a \"key\" string`,\n path: `columns[${i}].key`,\n code: 'MISSING_FIELD',\n suggestion: `Add a key referencing a data field. Available columns: ${availableColumns}`,\n });\n continue;\n }\n\n // Check key references a field in data\n if (!dataColumns.has(col.key as string)) {\n errors.push({\n message: `Spec error: columns[${i}].key \"${col.key}\" does not exist in data. Available columns: ${availableColumns}`,\n path: `columns[${i}].key`,\n code: 'DATA_FIELD_MISSING',\n suggestion: `Use one of the available data columns: ${availableColumns}`,\n });\n }\n\n // Check at most one visual enhancement\n const visuals = ['heatmap', 'bar', 'sparkline', 'image', 'flag', 'categoryColors'].filter(\n (v) => col[v] != null && col[v] !== false,\n );\n if (visuals.length > 1) {\n errors.push({\n message: `Spec error: columns[${i}] has multiple visual features (${visuals.join(', ')}). Only one is allowed per column.`,\n path: `columns[${i}]`,\n code: 'INVALID_VALUE',\n suggestion: `Keep only one visual feature per column. Remove all but one of: ${visuals.join(', ')}`,\n });\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Graph validation\n// ---------------------------------------------------------------------------\n\nfunction validateGraphSpec(spec: Record<string, unknown>, errors: ValidationError[]): void {\n // Validate nodes array exists and is non-empty\n if (!Array.isArray(spec.nodes)) {\n errors.push({\n message: 'Spec error: graph spec requires a \"nodes\" array',\n path: 'nodes',\n code: 'MISSING_FIELD',\n suggestion:\n 'Add a nodes array with objects that have an \"id\" field, e.g. nodes: [{ id: \"a\" }, { id: \"b\" }]',\n });\n return; // Can't validate further without nodes\n }\n\n if (spec.nodes.length === 0) {\n errors.push({\n message: 'Spec error: \"nodes\" must be a non-empty array',\n path: 'nodes',\n code: 'EMPTY_DATA',\n suggestion: 'Add at least one node, e.g. nodes: [{ id: \"a\" }]',\n });\n return;\n }\n\n // Validate each node has a string id\n const nodeIds = new Set<string>();\n const nodes = spec.nodes as Record<string, unknown>[];\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n if (!node || typeof node !== 'object') {\n errors.push({\n message: `Spec error: nodes[${i}] must be an object`,\n path: `nodes[${i}]`,\n code: 'INVALID_TYPE',\n suggestion: 'Each node must be an object with at least an \"id\" field, e.g. { id: \"a\" }',\n });\n continue;\n }\n if (typeof node.id !== 'string' || node.id === '') {\n errors.push({\n message: `Spec error: nodes[${i}] must have a non-empty string \"id\" field`,\n path: `nodes[${i}].id`,\n code: 'MISSING_FIELD',\n suggestion: 'Add a string id to the node, e.g. { id: \"node1\" }',\n });\n } else {\n nodeIds.add(node.id);\n }\n }\n\n // Validate edges array exists\n if (!Array.isArray(spec.edges)) {\n errors.push({\n message: 'Spec error: graph spec requires an \"edges\" array',\n path: 'edges',\n code: 'MISSING_FIELD',\n suggestion: 'Add an edges array (can be empty), e.g. edges: [{ source: \"a\", target: \"b\" }]',\n });\n return;\n }\n\n // Validate each edge has string source and target that reference existing nodes\n const edges = spec.edges as Record<string, unknown>[];\n for (let i = 0; i < edges.length; i++) {\n const edge = edges[i];\n if (!edge || typeof edge !== 'object') {\n errors.push({\n message: `Spec error: edges[${i}] must be an object`,\n path: `edges[${i}]`,\n code: 'INVALID_TYPE',\n suggestion:\n 'Each edge must be an object with \"source\" and \"target\" fields, e.g. { source: \"a\", target: \"b\" }',\n });\n continue;\n }\n\n if (typeof edge.source !== 'string' || edge.source === '') {\n errors.push({\n message: `Spec error: edges[${i}] must have a non-empty string \"source\" field`,\n path: `edges[${i}].source`,\n code: 'MISSING_FIELD',\n suggestion: 'Add a source node id, e.g. { source: \"a\", target: \"b\" }',\n });\n } else if (nodeIds.size > 0 && !nodeIds.has(edge.source)) {\n errors.push({\n message: `Spec error: edges[${i}].source \"${edge.source}\" does not reference an existing node id`,\n path: `edges[${i}].source`,\n code: 'DATA_FIELD_MISSING',\n suggestion: `Use one of the existing node ids: ${[...nodeIds].slice(0, 5).join(', ')}${nodeIds.size > 5 ? '...' : ''}`,\n });\n }\n\n if (typeof edge.target !== 'string' || edge.target === '') {\n errors.push({\n message: `Spec error: edges[${i}] must have a non-empty string \"target\" field`,\n path: `edges[${i}].target`,\n code: 'MISSING_FIELD',\n suggestion: 'Add a target node id, e.g. { source: \"a\", target: \"b\" }',\n });\n } else if (nodeIds.size > 0 && !nodeIds.has(edge.target)) {\n errors.push({\n message: `Spec error: edges[${i}].target \"${edge.target}\" does not reference an existing node id`,\n path: `edges[${i}].target`,\n code: 'DATA_FIELD_MISSING',\n suggestion: `Use one of the existing node ids: ${[...nodeIds].slice(0, 5).join(', ')}${nodeIds.size > 5 ? '...' : ''}`,\n });\n }\n }\n\n // Validate encoding fields exist on at least the first node/edge\n if (spec.encoding && typeof spec.encoding === 'object') {\n const encoding = spec.encoding as Record<string, unknown>;\n const firstNode = nodes[0] as Record<string, unknown>;\n const firstEdge = edges.length > 0 ? (edges[0] as Record<string, unknown>) : null;\n const nodeFields = firstNode ? new Set(Object.keys(firstNode)) : new Set<string>();\n const edgeFields = firstEdge ? new Set(Object.keys(firstEdge)) : new Set<string>();\n\n const nodeChannels = ['nodeColor', 'nodeSize', 'nodeLabel'] as const;\n for (const channel of nodeChannels) {\n const ch = encoding[channel] as Record<string, unknown> | undefined;\n if (ch?.field && typeof ch.field === 'string' && !nodeFields.has(ch.field)) {\n errors.push({\n message: `Spec error: encoding.${channel}.field \"${ch.field}\" does not exist on nodes. Available fields: ${[...nodeFields].join(', ')}`,\n path: `encoding.${channel}.field`,\n code: 'DATA_FIELD_MISSING',\n suggestion: `Use one of the node fields: ${[...nodeFields].join(', ')}`,\n });\n }\n }\n\n const edgeChannels = ['edgeColor', 'edgeWidth'] as const;\n for (const channel of edgeChannels) {\n const ch = encoding[channel] as Record<string, unknown> | undefined;\n if (ch?.field && typeof ch.field === 'string' && firstEdge && !edgeFields.has(ch.field)) {\n errors.push({\n message: `Spec error: encoding.${channel}.field \"${ch.field}\" does not exist on edges. Available fields: ${[...edgeFields].join(', ')}`,\n path: `encoding.${channel}.field`,\n code: 'DATA_FIELD_MISSING',\n suggestion: `Use one of the edge fields: ${[...edgeFields].join(', ')}`,\n });\n }\n }\n }\n\n // Validate layout type if specified\n if (spec.layout && typeof spec.layout === 'object') {\n const layout = spec.layout as Record<string, unknown>;\n if (layout.type && layout.type !== 'force') {\n errors.push({\n message: `Spec error: layout.type \"${layout.type}\" is not supported. Only \"force\" is currently supported`,\n path: 'layout.type',\n code: 'INVALID_VALUE',\n suggestion:\n 'Use layout.type: \"force\" or omit the layout field to use the default force layout',\n });\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Sankey validation\n// ---------------------------------------------------------------------------\n\nfunction validateSankeySpec(spec: Record<string, unknown>, errors: ValidationError[]): void {\n // Validate data\n if (!Array.isArray(spec.data)) {\n errors.push({\n message: 'Spec error: sankey spec requires a \"data\" array',\n path: 'data',\n code: 'INVALID_TYPE',\n suggestion:\n 'Provide data as an array of objects, e.g. data: [{ source: \"A\", target: \"B\", value: 10 }]',\n });\n return;\n }\n\n if (spec.data.length === 0) {\n errors.push({\n message: 'Spec error: \"data\" must be a non-empty array',\n path: 'data',\n code: 'EMPTY_DATA',\n suggestion: 'Add at least one data row, e.g. data: [{ source: \"A\", target: \"B\", value: 10 }]',\n });\n return;\n }\n\n const firstRow = spec.data[0] as unknown;\n if (typeof firstRow !== 'object' || firstRow === null || Array.isArray(firstRow)) {\n errors.push({\n message: 'Spec error: each item in \"data\" must be a plain object',\n path: 'data[0]',\n code: 'INVALID_TYPE',\n suggestion:\n 'Each data item should be an object, e.g. { source: \"A\", target: \"B\", value: 10 }',\n });\n return;\n }\n\n // Validate encoding\n if (!spec.encoding || typeof spec.encoding !== 'object') {\n errors.push({\n message:\n 'Spec error: sankey spec requires an \"encoding\" object with source, target, and value channels',\n path: 'encoding',\n code: 'MISSING_FIELD',\n suggestion:\n 'Add an encoding object, e.g. encoding: { source: { field: \"source\", type: \"nominal\" }, target: { field: \"target\", type: \"nominal\" }, value: { field: \"value\", type: \"quantitative\" } }',\n });\n return;\n }\n\n const encoding = spec.encoding as Record<string, unknown>;\n const dataColumns = new Set(Object.keys(firstRow as Record<string, unknown>));\n const availableColumns = [...dataColumns].join(', ');\n\n // Required channels\n for (const channel of ['source', 'target', 'value'] as const) {\n const ch = encoding[channel] as Record<string, unknown> | undefined;\n if (!ch || typeof ch !== 'object') {\n errors.push({\n message: `Spec error: sankey encoding requires \"${channel}\" channel`,\n path: `encoding.${channel}`,\n code: 'MISSING_FIELD',\n suggestion: `Add encoding.${channel} with a field from your data (${availableColumns}). Example: ${channel}: { field: \"${[...dataColumns][0] ?? 'myField'}\", type: \"${channel === 'value' ? 'quantitative' : 'nominal'}\" }`,\n });\n continue;\n }\n\n if (!ch.field || typeof ch.field !== 'string') {\n errors.push({\n message: `Spec error: encoding.${channel} must have a \"field\" string`,\n path: `encoding.${channel}.field`,\n code: 'MISSING_FIELD',\n suggestion: `Add a field name from your data columns: ${availableColumns}`,\n });\n continue;\n }\n\n if (!dataColumns.has(ch.field as string)) {\n errors.push({\n message: `Spec error: encoding.${channel}.field \"${ch.field}\" does not exist in data. Available columns: ${availableColumns}`,\n path: `encoding.${channel}.field`,\n code: 'DATA_FIELD_MISSING',\n suggestion: `Use one of the available data columns: ${availableColumns}`,\n });\n }\n }\n\n // Validate darkMode if provided\n if (spec.darkMode !== undefined && !VALID_DARK_MODES.has(spec.darkMode as string)) {\n errors.push({\n message: 'Spec error: darkMode must be \"auto\", \"force\", or \"off\"',\n path: 'darkMode',\n code: 'INVALID_VALUE',\n suggestion:\n 'Use one of: \"auto\" (system preference), \"force\" (always dark), or \"off\" (always light)',\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Layer validation\n// ---------------------------------------------------------------------------\n\nfunction validateLayerSpec(spec: Record<string, unknown>, errors: ValidationError[]): void {\n const layer = spec.layer as unknown[];\n\n if (layer.length === 0) {\n errors.push({\n message: 'Spec error: \"layer\" must be a non-empty array',\n path: 'layer',\n code: 'EMPTY_DATA',\n suggestion: 'Add at least one layer with a mark and encoding',\n });\n return;\n }\n\n for (let i = 0; i < layer.length; i++) {\n const child = layer[i];\n if (!child || typeof child !== 'object' || Array.isArray(child)) {\n errors.push({\n message: `Spec error: layer[${i}] must be an object`,\n path: `layer[${i}]`,\n code: 'INVALID_TYPE',\n suggestion:\n 'Each layer must be a chart spec (with mark) or a nested layer spec (with layer)',\n });\n continue;\n }\n\n const childObj = child as Record<string, unknown>;\n const isNestedLayer = 'layer' in childObj && Array.isArray(childObj.layer);\n const isChildChart = 'mark' in childObj;\n\n if (!isNestedLayer && !isChildChart) {\n errors.push({\n message: `Spec error: layer[${i}] must have a \"mark\" field or a \"layer\" array`,\n path: `layer[${i}]`,\n code: 'MISSING_FIELD',\n suggestion:\n 'Each layer must be a chart spec (with mark + encoding) or a nested layer spec (with layer array)',\n });\n continue;\n }\n\n if (isNestedLayer) {\n validateLayerSpec(childObj, errors);\n } else if (isChildChart) {\n // Validate mark type\n const mark = childObj.mark;\n let markValue: string | undefined;\n if (typeof mark === 'string') {\n markValue = mark;\n } else if (mark && typeof mark === 'object' && !Array.isArray(mark)) {\n markValue = (mark as Record<string, unknown>).type as string | undefined;\n }\n\n if (!markValue || !MARK_TYPES.has(markValue)) {\n errors.push({\n message: `Spec error: layer[${i}].mark \"${markValue ?? String(mark)}\" is not a valid mark type`,\n path: `layer[${i}].mark`,\n code: 'INVALID_VALUE',\n suggestion: `Change mark to one of: ${[...MARK_TYPES].join(', ')}`,\n });\n continue;\n }\n\n // Child layers can inherit data and encoding from parent, so only validate\n // if the child has its own data (or the parent provides shared data).\n const hasOwnData = Array.isArray(childObj.data) && (childObj.data as unknown[]).length > 0;\n const parentHasData = Array.isArray(spec.data) && (spec.data as unknown[]).length > 0;\n\n if (hasOwnData || parentHasData) {\n // Build a merged spec for validation purposes\n const mergedForValidation = { ...childObj };\n if (!hasOwnData && parentHasData) {\n mergedForValidation.data = spec.data;\n }\n // Merge encoding: parent fields are inherited unless child overrides\n if (spec.encoding && typeof spec.encoding === 'object') {\n mergedForValidation.encoding = {\n ...(spec.encoding as Record<string, unknown>),\n ...((childObj.encoding as Record<string, unknown>) ?? {}),\n };\n }\n if (mergedForValidation.data && mergedForValidation.encoding) {\n validateChartSpec(mergedForValidation, errors);\n }\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Validate a spec at runtime.\n *\n * Checks structure, required fields, encoding rules, data shape, and\n * field type compatibility. Returns structured errors with machine-readable\n * codes and actionable suggestions for each problem found.\n */\nexport function validateSpec(spec: unknown): ValidationResult {\n const errors: ValidationError[] = [];\n\n // Basic shape check\n if (!spec || typeof spec !== 'object' || Array.isArray(spec)) {\n return {\n valid: false,\n errors: [\n {\n message: 'Spec error: spec must be a non-null object',\n code: 'INVALID_TYPE',\n suggestion:\n 'Pass a spec object with at least a \"mark\" field for charts, e.g. { mark: \"line\", data: [...], encoding: {...} }',\n },\n ],\n normalized: null,\n };\n }\n\n const obj = spec as Record<string, unknown>;\n\n // Determine spec type via structural discrimination:\n // - Layer specs have a 'layer' array\n // - Chart specs have a 'mark' field (string or object with type property)\n // - Table specs have type: 'table'\n // - Graph specs have type: 'graph'\n const hasLayer = 'layer' in obj && Array.isArray(obj.layer);\n const hasMark = 'mark' in obj;\n const isTable = obj.type === 'table';\n const isGraph = obj.type === 'graph';\n const isSankey = obj.type === 'sankey';\n const isLayer = hasLayer && !isTable && !isGraph && !isSankey;\n const isChart = hasMark && !hasLayer && !isTable && !isGraph && !isSankey;\n\n if (!isChart && !isTable && !isGraph && !isSankey && !isLayer) {\n return {\n valid: false,\n errors: [\n {\n message:\n 'Spec error: spec must have a \"mark\" field for charts, a \"layer\" array for layered charts, or a \"type\" field for tables/graphs/sankey',\n path: 'mark',\n code: 'MISSING_FIELD',\n suggestion: `Add a \"mark\" field for charts (e.g. mark: \"bar\"), a \"layer\" array for layered charts, or a \"type\" field for tables/graphs/sankey (type: \"table\", type: \"graph\", or type: \"sankey\"). Valid mark types: ${[...MARK_TYPES].join(', ')}`,\n },\n ],\n normalized: null,\n };\n }\n\n // For layer specs, validate each child layer recursively\n if (isLayer) {\n validateLayerSpec(obj, errors);\n }\n\n // For chart specs, validate the mark field\n if (isChart) {\n const mark = obj.mark;\n let markValue: string | undefined;\n\n if (typeof mark === 'string') {\n markValue = mark;\n } else if (mark && typeof mark === 'object' && !Array.isArray(mark)) {\n markValue = (mark as Record<string, unknown>).type as string | undefined;\n }\n\n if (!markValue || !MARK_TYPES.has(markValue)) {\n return {\n valid: false,\n errors: [\n {\n message: `Spec error: \"${markValue ?? String(mark)}\" is not a valid mark type. Valid mark types: ${[...MARK_TYPES].join(', ')}`,\n path: 'mark',\n code: 'INVALID_VALUE',\n suggestion: `Change mark to one of: ${[...MARK_TYPES].join(', ')}`,\n },\n ],\n normalized: null,\n };\n }\n\n validateChartSpec(obj, errors);\n } else if (isTable) {\n validateTableSpec(obj, errors);\n } else if (isGraph) {\n validateGraphSpec(obj, errors);\n } else if (isSankey) {\n validateSankeySpec(obj, errors);\n }\n\n if (errors.length > 0) {\n return { valid: false, errors, normalized: null };\n }\n\n return {\n valid: true,\n errors: [],\n normalized: spec as VizSpec,\n };\n}\n","/**\n * Spec compiler: validate -> normalize pipeline.\n *\n * This is the first stage of the engine: take raw user input (possibly JSON\n * from an API or Claude), validate it, fill in defaults, and produce a\n * NormalizedSpec that the rest of the engine can work with safely.\n */\n\nimport { normalizeSpec } from './normalize';\nimport type { CompileResult } from './types';\nimport { validateSpec } from './validate';\n\n/**\n * Compile a raw spec through the validate -> normalize pipeline.\n *\n * @param spec - Raw spec input (unknown type, could be anything).\n * @returns CompileResult with the normalized spec and any warnings.\n * @throws Error if the spec is invalid.\n */\nexport function compile(spec: unknown): CompileResult {\n const validation = validateSpec(spec);\n\n if (!validation.valid || !validation.normalized) {\n const errorMessages = validation.errors.map((e) => e.message).join('\\n');\n throw new Error(`Invalid spec:\\n${errorMessages}`);\n }\n\n const warnings: string[] = [];\n const normalized = normalizeSpec(validation.normalized, warnings);\n\n return { spec: normalized, warnings };\n}\n\nexport { flattenLayers, normalizeSpec } from './normalize';\nexport type {\n CompileResult,\n NormalizedChartSpec,\n NormalizedChrome,\n NormalizedGraphSpec,\n NormalizedSpec,\n NormalizedTableSpec,\n ValidationError,\n ValidationErrorCode,\n ValidationResult,\n} from './types';\n// Re-export everything\nexport { validateSpec } from './validate';\n","/**\n * Graph compilation pipeline.\n *\n * Takes a raw graph spec (unknown shape), validates, normalizes, resolves\n * encoding channels to visual properties, assigns communities, builds\n * legend/tooltips/a11y, and returns a GraphCompilation.\n *\n * The pipeline mirrors compileChart's structure:\n * validate -> normalize -> resolve theme -> resolve visuals ->\n * community assignment -> legend -> tooltips -> a11y -> return\n *\n * Key difference from charts: the output does NOT include x/y positions.\n * The force simulation in the adapter handles layout at runtime.\n */\n\nimport type {\n CompileOptions,\n LegendEntry,\n LegendLayout,\n ResolvedTheme,\n TextStyle,\n TooltipContent,\n TooltipField,\n} from '@opendata-ai/openchart-core';\nimport { adaptTheme, computeChrome, resolveTheme } from '@opendata-ai/openchart-core';\n\nimport { compile as compileSpec } from '../compiler/index';\nimport type { NormalizedGraphSpec } from '../compiler/types';\nimport { applyCommunityColors, assignCommunities, buildCommunityColorMap } from './community';\nimport { resolveEdgeVisuals, resolveNodeVisuals } from './encoding';\nimport type { CompiledGraphNode, GraphCompilation, SimulationConfig } from './types';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst SWATCH_SIZE = 12;\nconst SWATCH_GAP = 6;\nconst ENTRY_GAP = 16;\n\n// ---------------------------------------------------------------------------\n// Legend builder\n// ---------------------------------------------------------------------------\n\n/**\n * Build a legend from community assignments or nodeColor encoding.\n *\n * Built manually instead of reusing computeLegend (which assumes chart\n * encoding channels). Returns entries with color swatches and labels.\n * Position is placeholder (adapter determines actual placement).\n */\nfunction buildGraphLegend(\n nodes: CompiledGraphNode[],\n communityColorMap: Map<string, string>,\n hasCommunities: boolean,\n theme: ResolvedTheme,\n nodeColorField?: string,\n): LegendLayout {\n const labelStyle: TextStyle = {\n fontFamily: theme.fonts.family,\n fontSize: theme.fonts.sizes.small,\n fontWeight: theme.fonts.weights.normal,\n fill: theme.colors.text,\n lineHeight: 1.3,\n };\n\n let entries: LegendEntry[];\n\n if (hasCommunities && communityColorMap.size > 0) {\n // One entry per community\n entries = [...communityColorMap.entries()].map(([label, color]) => ({\n label,\n color,\n shape: 'circle' as const,\n active: true,\n }));\n } else {\n // Build legend from nodeColor encoding: group by the color field value\n // so each legend entry shows the categorical value (e.g. \"Dataset\", \"bls\")\n // rather than an arbitrary node label.\n const categoryColors = new Map<string, string>();\n for (const node of nodes) {\n const category = nodeColorField\n ? String(node.data[nodeColorField] ?? node.label ?? node.id)\n : (node.label ?? node.id);\n if (!categoryColors.has(category)) {\n categoryColors.set(category, node.fill);\n }\n }\n\n // Only show legend if there are multiple categories\n if (categoryColors.size <= 1) {\n entries = [];\n } else {\n entries = [...categoryColors.entries()].map(([label, color]) => ({\n label,\n color,\n shape: 'circle' as const,\n active: true,\n }));\n }\n }\n\n return {\n position: 'top',\n entries,\n bounds: { x: 0, y: 0, width: 0, height: 0 },\n labelStyle,\n swatchSize: SWATCH_SIZE,\n swatchGap: SWATCH_GAP,\n entryGap: ENTRY_GAP,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Tooltip builder\n// ---------------------------------------------------------------------------\n\n/**\n * Build tooltip descriptors for each node.\n *\n * Keyed by node id. Shows all data fields, label, and community.\n */\nfunction buildGraphTooltips(nodes: CompiledGraphNode[]): Map<string, TooltipContent> {\n const descriptors = new Map<string, TooltipContent>();\n\n for (const node of nodes) {\n const fields: TooltipField[] = [];\n\n // Add community if present\n if (node.community != null) {\n fields.push({\n label: 'Community',\n value: node.community,\n color: node.fill,\n });\n }\n\n // Add all data fields (excluding id since it's the title)\n for (const [key, value] of Object.entries(node.data)) {\n if (key === 'id') continue;\n if (value == null) continue;\n\n fields.push({\n label: key,\n value: typeof value === 'number' ? value.toLocaleString() : String(value),\n });\n }\n\n descriptors.set(node.id, {\n title: node.label ?? node.id,\n fields,\n });\n }\n\n return descriptors;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a graph spec into a GraphCompilation.\n *\n * Pipeline:\n * 1. Validate + normalize via the shared compiler pipeline\n * 2. Resolve theme (merge spec + options, apply dark mode)\n * 3. Resolve node visuals (size, color, label, stroke)\n * 4. Assign communities if layout.clustering is set\n * 5. Apply community colors (override nodeColor)\n * 6. Resolve edge visuals (width, color)\n * 7. Build legend from communities or nodeColor\n * 8. Build tooltip descriptors for each node\n * 9. Build a11y metadata\n * 10. Build simulation config from spec layout\n * 11. Build chrome from spec + theme\n * 12. Return GraphCompilation\n *\n * @param spec - Raw graph spec (validated at runtime).\n * @param options - Compile options (width, height, theme, darkMode).\n * @returns GraphCompilation with resolved visual properties.\n * @throws Error if spec is invalid or not a graph type.\n */\nexport function compileGraph(spec: unknown, options: CompileOptions): GraphCompilation {\n // 1. Validate + normalize\n const { spec: normalized } = compileSpec(spec);\n\n if (!('type' in normalized) || normalized.type !== 'graph') {\n throw new Error(\n 'compileGraph received a non-graph spec. Use compileChart or compileTable instead.',\n );\n }\n\n const graphSpec = normalized as NormalizedGraphSpec;\n\n // Resolve watermark: explicit spec value wins, then options fallback, then default true.\n const rawWatermark = (spec as Record<string, unknown>).watermark;\n const watermark = rawWatermark !== undefined ? graphSpec.watermark : (options.watermark ?? true);\n\n // 2. Resolve theme\n const mergedThemeConfig = options.theme\n ? { ...graphSpec.theme, ...options.theme }\n : graphSpec.theme;\n let theme: ResolvedTheme = resolveTheme(mergedThemeConfig);\n if (options.darkMode) {\n theme = adaptTheme(theme);\n }\n\n // 3. Resolve node visuals\n const compiledNodes = resolveNodeVisuals(\n graphSpec.nodes,\n graphSpec.encoding,\n graphSpec.edges,\n theme,\n graphSpec.nodeOverrides,\n );\n\n // 4. Assign communities (for force simulation grouping)\n const clusteringField = graphSpec.layout.clustering?.field;\n const hasCommunities = !!clusteringField;\n assignCommunities(compiledNodes, clusteringField);\n\n // 5. Apply community colors only when no explicit nodeColor encoding is set.\n // When the consumer specifies nodeColor (e.g. by nodeType or provider), that\n // encoding should drive both fill colors and legend entries.\n const hasNodeColorEncoding = !!graphSpec.encoding.nodeColor?.field;\n let communityColorMap = new Map<string, string>();\n if (hasCommunities && !hasNodeColorEncoding) {\n communityColorMap = buildCommunityColorMap(compiledNodes, theme);\n applyCommunityColors(compiledNodes, communityColorMap);\n }\n\n // 6. Resolve edge visuals\n const compiledEdges = resolveEdgeVisuals(graphSpec.edges, graphSpec.encoding, theme);\n\n // 7. Build legend (use nodeColor encoding colors when present, community otherwise)\n const useCommunitiesForLegend = hasCommunities && !hasNodeColorEncoding;\n const legend = buildGraphLegend(\n compiledNodes,\n communityColorMap,\n useCommunitiesForLegend,\n theme,\n graphSpec.encoding.nodeColor?.field,\n );\n\n // 8. Build tooltips\n const tooltipDescriptors = buildGraphTooltips(compiledNodes);\n\n // 9. Build a11y metadata\n const communityCount = communityColorMap.size;\n const altParts = [\n `Network graph with ${compiledNodes.length} nodes and ${compiledEdges.length} edges`,\n ];\n if (communityCount > 0) {\n altParts.push(`organized into ${communityCount} communities`);\n }\n const a11y = {\n altText: altParts.join(', '),\n dataTableFallback: compiledNodes.map((n) => [n.id, n.community ?? '', n.label ?? '']),\n role: 'img',\n keyboardNavigable: compiledNodes.length > 0,\n };\n\n // 10. Build simulation config\n const collisionPadding = graphSpec.layout.collisionPadding ?? 2;\n const maxRadius =\n compiledNodes.length > 0\n ? Math.max(...compiledNodes.map((n) => n.radius))\n : DEFAULT_COLLISION_PADDING;\n const simulationConfig: SimulationConfig = {\n chargeStrength: graphSpec.layout.chargeStrength ?? -300,\n linkDistance: graphSpec.layout.linkDistance ?? 30,\n clustering: clusteringField ? { field: clusteringField, strength: 0.5 } : null,\n alphaDecay: 0.0228,\n velocityDecay: 0.4,\n collisionRadius: maxRadius + collisionPadding,\n collisionPadding,\n linkStrength: graphSpec.layout.linkStrength,\n centerForce: graphSpec.layout.centerForce,\n };\n\n // 11. Build chrome\n const chrome = computeChrome(\n {\n title: graphSpec.chrome.title,\n subtitle: graphSpec.chrome.subtitle,\n source: graphSpec.chrome.source,\n byline: graphSpec.chrome.byline,\n footer: graphSpec.chrome.footer,\n },\n theme,\n options.width,\n options.measureText,\n 'full',\n undefined,\n watermark,\n );\n\n // 12. Return compilation\n return {\n nodes: compiledNodes,\n edges: compiledEdges,\n legend,\n chrome,\n tooltipDescriptors,\n a11y,\n theme,\n dimensions: {\n width: options.width,\n height: options.height,\n },\n simulationConfig,\n watermark,\n };\n}\n\n/** Default padding for collision radius when there are no nodes. */\nconst DEFAULT_COLLISION_PADDING = 5;\n","/**\n * Graph encoding resolution.\n *\n * Maps graph encoding channels (nodeSize, nodeColor, edgeWidth, edgeColor,\n * nodeLabel) to computed visual properties on nodes and edges. Uses d3 scales\n * the same way scatter/bubble charts do: scaleSqrt for size, scaleOrdinal\n * for categorical color, scaleLinear for quantitative color.\n */\n\nimport type {\n GraphEdge,\n GraphEncoding,\n GraphNode,\n NodeOverride,\n ResolvedTheme,\n} from '@opendata-ai/openchart-core';\nimport { max, min } from 'd3-array';\nimport { scaleLinear, scaleOrdinal, scaleSqrt } from 'd3-scale';\n\nimport type { CompiledGraphEdge, CompiledGraphNode } from './types';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_NODE_RADIUS = 5;\nconst MIN_NODE_RADIUS = 3;\nconst MAX_NODE_RADIUS = 12;\n\nconst DEFAULT_EDGE_WIDTH = 1;\nconst MIN_EDGE_WIDTH = 0.5;\nconst MAX_EDGE_WIDTH = 4;\n\nconst DEFAULT_STROKE_WIDTH = 1;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Darken a hex color by a percentage.\n *\n * Doesn't use d3-color (engine doesn't depend on it). Operates directly\n * on hex RGB channels. Falls back to the original color on parse failure.\n */\nexport function darkenColor(hex: string, amount: number = 0.2): string {\n // Strip # prefix\n const clean = hex.replace(/^#/, '');\n if (clean.length !== 6 && clean.length !== 3) return hex;\n\n // Expand shorthand\n const full =\n clean.length === 3\n ? clean\n .split('')\n .map((c) => c + c)\n .join('')\n : clean;\n\n const r = Math.max(0, Math.round(parseInt(full.substring(0, 2), 16) * (1 - amount)));\n const g = Math.max(0, Math.round(parseInt(full.substring(2, 4), 16) * (1 - amount)));\n const b = Math.max(0, Math.round(parseInt(full.substring(4, 6), 16) * (1 - amount)));\n\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;\n}\n\n/**\n * Apply opacity to a hex color, returning an rgba string.\n */\nfunction hexWithOpacity(hex: string, opacity: number): string {\n const clean = hex.replace(/^#/, '');\n if (clean.length !== 6 && clean.length !== 3) {\n // Non-hex input: return as-is with opacity via CSS\n return hex;\n }\n\n const full =\n clean.length === 3\n ? clean\n .split('')\n .map((c) => c + c)\n .join('')\n : clean;\n\n const r = parseInt(full.substring(0, 2), 16);\n const g = parseInt(full.substring(2, 4), 16);\n const b = parseInt(full.substring(4, 6), 16);\n\n return `rgba(${r}, ${g}, ${b}, ${opacity})`;\n}\n\n/**\n * Compute the degree of each node (number of edges touching it).\n */\nfunction computeDegrees(nodes: GraphNode[], edges: GraphEdge[]): Map<string, number> {\n const degrees = new Map<string, number>();\n for (const node of nodes) {\n degrees.set(node.id, 0);\n }\n for (const edge of edges) {\n degrees.set(edge.source, (degrees.get(edge.source) ?? 0) + 1);\n degrees.set(edge.target, (degrees.get(edge.target) ?? 0) + 1);\n }\n return degrees;\n}\n\n// ---------------------------------------------------------------------------\n// Node visual resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve visual properties for all graph nodes.\n *\n * Applies nodeSize, nodeColor, and nodeLabel encoding channels from the\n * spec to produce CompiledGraphNode objects with computed fill, radius,\n * stroke, label, and label priority.\n */\nexport function resolveNodeVisuals(\n nodes: GraphNode[],\n encoding: GraphEncoding,\n edges: GraphEdge[],\n theme: ResolvedTheme,\n nodeOverrides?: Record<string, NodeOverride>,\n): CompiledGraphNode[] {\n const degrees = computeDegrees(nodes, edges);\n const maxDegree = Math.max(1, ...degrees.values());\n\n // Build node size scale\n let sizeScale: ((v: number) => number) | undefined;\n if (encoding.nodeSize?.field) {\n const field = encoding.nodeSize.field;\n const values = nodes.map((n) => Number(n[field])).filter((v) => Number.isFinite(v));\n\n const sizeMin = min(values) ?? 0;\n const sizeMax = max(values) ?? 1;\n\n sizeScale = scaleSqrt().domain([sizeMin, sizeMax]).range([MIN_NODE_RADIUS, MAX_NODE_RADIUS]);\n }\n\n // Build node color scale\n let colorFn: ((node: GraphNode) => string) | undefined;\n if (encoding.nodeColor?.field) {\n const field = encoding.nodeColor.field;\n const fieldType = encoding.nodeColor.type ?? 'nominal';\n const scaleConfig = encoding.nodeColor.scale;\n\n if (fieldType === 'quantitative') {\n const values = nodes.map((n) => Number(n[field])).filter((v) => Number.isFinite(v));\n const colorMin = min(values) ?? 0;\n const colorMax = max(values) ?? 1;\n\n // Use first sequential palette\n const seqPalettes = Object.values(theme.colors.sequential);\n const palette = seqPalettes.length > 0 ? seqPalettes[0] : ['#ccc', '#333'];\n\n const domain =\n scaleConfig?.domain && scaleConfig.domain.length === 2\n ? (scaleConfig.domain as [number, number])\n : [colorMin, colorMax];\n const range =\n scaleConfig?.range && scaleConfig.range.length >= 2\n ? (scaleConfig.range as string[])\n : [palette[0], palette[palette.length - 1]];\n\n const colorScale = scaleLinear<string>().domain(domain).range(range);\n\n colorFn = (node: GraphNode) => {\n const val = Number(node[field]);\n return Number.isFinite(val) ? colorScale(val) : theme.colors.categorical[0];\n };\n } else {\n // nominal/ordinal\n const domain =\n scaleConfig?.domain && Array.isArray(scaleConfig.domain)\n ? (scaleConfig.domain as string[])\n : [...new Set(nodes.map((n) => String(n[field] ?? '')))];\n const range =\n scaleConfig?.range && scaleConfig.range.length > 0\n ? (scaleConfig.range as string[])\n : theme.colors.categorical;\n\n const ordinalScale = scaleOrdinal<string>().domain(domain).range(range);\n\n colorFn = (node: GraphNode) => ordinalScale(String(node[field] ?? ''));\n }\n }\n\n const defaultColor = theme.colors.categorical[0];\n\n return nodes.map((node) => {\n // Radius\n let radius = DEFAULT_NODE_RADIUS;\n if (sizeScale && encoding.nodeSize?.field) {\n const val = Number(node[encoding.nodeSize.field]);\n if (Number.isFinite(val)) {\n radius = sizeScale(val);\n }\n }\n\n // Color\n const fill = colorFn ? colorFn(node) : defaultColor;\n\n // Stroke: darken fill by 20%\n const stroke = darkenColor(fill);\n\n // Label\n let label: string | undefined;\n if (encoding.nodeLabel?.field) {\n const labelVal = node[encoding.nodeLabel.field];\n label = labelVal != null ? String(labelVal) : undefined;\n } else {\n label = node.id;\n }\n\n // Label priority: degree / maxDegree (0 to 1)\n const degree = degrees.get(node.id) ?? 0;\n const labelPriority = maxDegree > 0 ? degree / maxDegree : 0;\n\n // Data: spread all original node fields\n const { id: _id, ...rest } = node;\n const data: Record<string, unknown> = { id: node.id, ...rest };\n\n // Apply per-node overrides if present\n const override = nodeOverrides?.[node.id];\n const finalFill = override?.fill ?? fill;\n const finalRadius = override?.radius ?? radius;\n const finalStrokeWidth = override?.strokeWidth ?? DEFAULT_STROKE_WIDTH;\n const finalStroke = override?.stroke ?? stroke;\n const finalLabelPriority = override?.alwaysShowLabel ? Infinity : labelPriority;\n\n return {\n id: node.id,\n radius: finalRadius,\n fill: finalFill,\n stroke: finalStroke,\n strokeWidth: finalStrokeWidth,\n label,\n labelPriority: finalLabelPriority,\n community: undefined,\n data,\n };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Edge visual resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve visual properties for all graph edges.\n *\n * Applies edgeWidth and edgeColor encoding channels to produce\n * CompiledGraphEdge objects with computed stroke, strokeWidth, and style.\n */\nexport function resolveEdgeVisuals(\n edges: GraphEdge[],\n encoding: GraphEncoding,\n theme: ResolvedTheme,\n): CompiledGraphEdge[] {\n // Edge width scale\n let widthScale: ((v: number) => number) | undefined;\n if (encoding.edgeWidth?.field) {\n const field = encoding.edgeWidth.field;\n const values = edges.map((e) => Number(e[field])).filter((v) => Number.isFinite(v));\n\n const widthMin = min(values) ?? 0;\n const widthMax = max(values) ?? 1;\n\n widthScale = scaleLinear().domain([widthMin, widthMax]).range([MIN_EDGE_WIDTH, MAX_EDGE_WIDTH]);\n }\n\n // Edge color scale\n let edgeColorFn: ((edge: GraphEdge) => string) | undefined;\n if (encoding.edgeColor?.field) {\n const field = encoding.edgeColor.field;\n const fieldType = encoding.edgeColor.type ?? 'nominal';\n const scaleConfig = encoding.edgeColor.scale;\n\n if (fieldType === 'quantitative') {\n const values = edges.map((e) => Number(e[field])).filter((v) => Number.isFinite(v));\n const colorMin = min(values) ?? 0;\n const colorMax = max(values) ?? 1;\n\n const seqPalettes = Object.values(theme.colors.sequential);\n const palette = seqPalettes.length > 0 ? seqPalettes[0] : ['#ccc', '#333'];\n\n const domain =\n scaleConfig?.domain && scaleConfig.domain.length === 2\n ? (scaleConfig.domain as [number, number])\n : [colorMin, colorMax];\n const range =\n scaleConfig?.range && scaleConfig.range.length >= 2\n ? (scaleConfig.range as string[])\n : [palette[0], palette[palette.length - 1]];\n\n const colorScale = scaleLinear<string>().domain(domain).range(range);\n\n edgeColorFn = (edge: GraphEdge) => {\n const val = Number(edge[field]);\n return Number.isFinite(val) ? colorScale(val) : hexWithOpacity(theme.colors.axis, 0.4);\n };\n } else {\n const domain =\n scaleConfig?.domain && Array.isArray(scaleConfig.domain)\n ? (scaleConfig.domain as string[])\n : [...new Set(edges.map((e) => String(e[field] ?? '')))];\n const range =\n scaleConfig?.range && scaleConfig.range.length > 0\n ? (scaleConfig.range as string[])\n : theme.colors.categorical;\n\n const ordinalScale = scaleOrdinal<string>().domain(domain).range(range);\n\n edgeColorFn = (edge: GraphEdge) => ordinalScale(String(edge[field] ?? ''));\n }\n }\n\n const defaultEdgeColor = hexWithOpacity(theme.colors.axis, 0.4);\n\n // Edge style mapping (ordinal: map unique field values to solid/dashed/dotted)\n const EDGE_STYLES: Array<'solid' | 'dashed' | 'dotted'> = ['solid', 'dashed', 'dotted'];\n let styleFn: ((edge: GraphEdge) => 'solid' | 'dashed' | 'dotted') | undefined;\n if (encoding.edgeStyle?.field) {\n const field = encoding.edgeStyle.field;\n const uniqueValues = [...new Set(edges.map((e) => String(e[field] ?? '')))];\n const styleMap = new Map<string, 'solid' | 'dashed' | 'dotted'>();\n for (let i = 0; i < uniqueValues.length; i++) {\n styleMap.set(uniqueValues[i], EDGE_STYLES[i % EDGE_STYLES.length]);\n }\n styleFn = (edge: GraphEdge) => styleMap.get(String(edge[field] ?? '')) ?? 'solid';\n }\n\n return edges.map((edge) => {\n const { source, target, ...rest } = edge;\n\n let strokeWidth = DEFAULT_EDGE_WIDTH;\n if (widthScale && encoding.edgeWidth?.field) {\n const val = Number(edge[encoding.edgeWidth.field]);\n if (Number.isFinite(val)) {\n strokeWidth = widthScale(val);\n }\n }\n\n const stroke = edgeColorFn ? edgeColorFn(edge) : defaultEdgeColor;\n const style = styleFn ? styleFn(edge) : ('solid' as const);\n\n return {\n source,\n target,\n stroke,\n strokeWidth,\n style,\n data: { source, target, ...rest } as Record<string, unknown>,\n };\n });\n}\n","/**\n * Community assignment and color mapping for graph clustering.\n *\n * When a graph spec has layout.clustering.field, nodes are grouped into\n * communities based on their data values for that field. Each community\n * gets a color from the theme's categorical palette. Community colors\n * override nodeColor encoding when clustering is active.\n */\n\nimport type { ResolvedTheme } from '@opendata-ai/openchart-core';\nimport { darkenColor } from './encoding';\nimport type { CompiledGraphNode } from './types';\n\n// ---------------------------------------------------------------------------\n// Community assignment\n// ---------------------------------------------------------------------------\n\n/**\n * Assign community labels to compiled nodes based on a clustering field.\n *\n * Reads node.data[clusteringField] as the community label. If the field\n * is missing on a node, community remains undefined.\n *\n * Mutates nodes in-place for efficiency (no copy needed since we just\n * built them in the compilation pipeline).\n */\nexport function assignCommunities(\n nodes: CompiledGraphNode[],\n clusteringField: string | undefined,\n): void {\n if (!clusteringField) return;\n\n for (const node of nodes) {\n const value = node.data[clusteringField];\n node.community = value != null ? String(value) : undefined;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Community color mapping\n// ---------------------------------------------------------------------------\n\n/**\n * Build a map from community label to color.\n *\n * Collects unique community values (in order of first appearance),\n * then assigns theme categorical colors round-robin.\n */\nexport function buildCommunityColorMap(\n nodes: CompiledGraphNode[],\n theme: ResolvedTheme,\n): Map<string, string> {\n const colorMap = new Map<string, string>();\n const palette = theme.colors.categorical;\n let colorIndex = 0;\n\n for (const node of nodes) {\n if (node.community != null && !colorMap.has(node.community)) {\n colorMap.set(node.community, palette[colorIndex % palette.length]);\n colorIndex++;\n }\n }\n\n return colorMap;\n}\n\n// ---------------------------------------------------------------------------\n// Apply community colors\n// ---------------------------------------------------------------------------\n\n/**\n * Override node fill and stroke colors with community colors.\n *\n * Only affects nodes that have a community assignment. Nodes without\n * a community keep their existing fill/stroke from encoding resolution.\n *\n * Mutates nodes in-place.\n */\nexport function applyCommunityColors(\n nodes: CompiledGraphNode[],\n colorMap: Map<string, string>,\n): void {\n for (const node of nodes) {\n if (node.community != null) {\n const communityColor = colorMap.get(node.community);\n if (communityColor) {\n node.fill = communityColor;\n node.stroke = darkenColor(communityColor);\n }\n }\n }\n}\n","/**\n * Tick label overlap detection and density thinning.\n *\n * Horizontal orientation (x-axis): checks label width against adjacent\n * positions. Vertical orientation (y-axis): checks font-based label height\n * against adjacent positions, ignoring text width so wide numeric labels\n * don't trigger aggressive thinning.\n */\n\nimport type { AxisTick, MeasureTextFn } from '@opendata-ai/openchart-core';\nimport { estimateTextWidth } from '@opendata-ai/openchart-core';\n\n/**\n * Minimum gap between adjacent tick labels as a multiple of font size.\n * At the default 12px axis font, this yields ~12px of breathing room.\n */\nconst MIN_TICK_GAP_FACTOR = 1.0;\n\n/** Always show at least this many ticks, even if they overlap. */\nconst MIN_TICK_COUNT = 2;\n\n/** Measure a single label's width using real measurement or heuristic fallback. */\nexport function measureLabel(\n text: string,\n fontSize: number,\n fontWeight: number,\n measureText?: MeasureTextFn,\n): number {\n return measureText\n ? measureText(text, fontSize, fontWeight).width\n : estimateTextWidth(text, fontSize, fontWeight);\n}\n\n/** Check whether any adjacent tick labels overlap along the axis direction. */\nexport function ticksOverlap(\n ticks: AxisTick[],\n fontSize: number,\n fontWeight: number,\n measureText?: MeasureTextFn,\n orientation: 'horizontal' | 'vertical' = 'horizontal',\n): boolean {\n if (ticks.length < 2) return false;\n const minGap = fontSize * MIN_TICK_GAP_FACTOR;\n\n if (orientation === 'vertical') {\n // Y-axis: labels are stacked vertically. Check if vertical extent\n // (based on font height) overlaps between adjacent ticks.\n // Positions decrease going up in SVG coords, so sort ascending.\n const sorted = [...ticks].sort((a, b) => a.position - b.position);\n const labelHeight = fontSize * 1.2; // lineHeight\n for (let i = 0; i < sorted.length - 1; i++) {\n const aBottom = sorted[i].position + labelHeight / 2;\n const bTop = sorted[i + 1].position - labelHeight / 2;\n if (aBottom + minGap > bTop) return true;\n }\n return false;\n }\n\n for (let i = 0; i < ticks.length - 1; i++) {\n const aWidth = measureLabel(ticks[i].label, fontSize, fontWeight, measureText);\n const bWidth = measureLabel(ticks[i + 1].label, fontSize, fontWeight, measureText);\n const aRight = ticks[i].position + aWidth / 2;\n const bLeft = ticks[i + 1].position - bWidth / 2;\n if (aRight + minGap > bLeft) return true;\n }\n return false;\n}\n\n/**\n * Thin a tick array by removing every other tick until labels don't overlap.\n * Always keeps first and last tick. O(log n) iterations max.\n * Returns the original array if no thinning is needed.\n */\nexport function thinTicksUntilFit(\n ticks: AxisTick[],\n fontSize: number,\n fontWeight: number,\n measureText?: MeasureTextFn,\n orientation: 'horizontal' | 'vertical' = 'horizontal',\n): AxisTick[] {\n if (!ticksOverlap(ticks, fontSize, fontWeight, measureText, orientation)) return ticks;\n\n let current = ticks;\n while (current.length > MIN_TICK_COUNT) {\n // Keep first, last, and every other tick in between\n const thinned = [current[0]];\n for (let i = 2; i < current.length - 1; i += 2) {\n thinned.push(current[i]);\n }\n if (current.length > 1) thinned.push(current[current.length - 1]);\n current = thinned;\n\n if (!ticksOverlap(current, fontSize, fontWeight, measureText, orientation)) break;\n }\n return current;\n}\n","/**\n * Tick generation: produces raw AxisTick[] from a resolved scale.\n *\n * Pure with respect to layout dimensions — positions come from the scale,\n * not from the chart area. Density thinning lives in ./thinning.ts.\n */\n\nimport type { AxisLabelDensity, AxisTick } from '@opendata-ai/openchart-core';\nimport {\n abbreviateNumber,\n buildD3Formatter,\n buildTemporalFormatter,\n formatDate,\n formatNumber,\n} from '@opendata-ai/openchart-core';\nimport type { ScaleBand } from 'd3-scale';\nimport type { D3CategoricalScale, D3ContinuousScale, ResolvedScale } from '../scales';\n\n/**\n * Target pixels-per-tick for continuous axes. The target count is computed as\n * `axisLength / PX_PER_TICK[density]` and then clamped into the count range.\n *\n * Rationale:\n * - Observable Plot uses 50px/tick on y, 80px/tick on x as its baseline.\n * - ONS editorial guidance recommends 6-10 y-gridlines at desktop, 3-6 mobile.\n * - The Economist / FT / NYT typically show 4-6 labeled y-ticks on finished charts.\n *\n * Y gets tighter spacing than X because vertical label extent is the font height\n * (~14px) versus horizontal label extent which can be 60-100px for dates/abbreviated\n * numbers. X uses wider spacing so labels don't need aggressive rotation or thinning.\n *\n * \"full\" is the publication-ready default; \"reduced\" and \"minimal\" step down as the\n * responsive breakpoint system shifts to smaller containers.\n *\n * @internal — these are tuning constants, not part of the configuration API.\n * Consumers should configure tick density through `axis.tickCount` on the spec.\n */\nconst Y_PX_PER_TICK: Record<AxisLabelDensity, number> = {\n full: 55,\n reduced: 90,\n minimal: 140,\n};\n\nconst X_PX_PER_TICK: Record<AxisLabelDensity, number> = {\n full: 110,\n reduced: 160,\n minimal: 220,\n};\n\n/**\n * Count clamps per density. The lower bound keeps a chart from collapsing to\n * a single label on very short axes; the upper bound stops tall/wide charts\n * from growing a ladder of ticks past the point of editorial usefulness.\n *\n * The upper bound is deliberately <=6 for y on standard tiers: D3's\n * `scale.ticks(n)` only produces \"nice\" step sizes (1, 2, 5 × 10^k), and for\n * many domains the jump from step=10 to step=5 happens between count 6 and 7.\n * Requesting 7 can give back 10, which reads as visually dense. Capping at 6\n * keeps the editorial ~5 gridline average regardless of domain shape.\n *\n * @internal — see PX_PER_TICK comment.\n */\nconst Y_TICK_COUNT_RANGE: Record<AxisLabelDensity, [number, number]> = {\n full: [4, 6],\n reduced: [3, 5],\n minimal: [2, 3],\n};\n\nconst X_TICK_COUNT_RANGE: Record<AxisLabelDensity, [number, number]> = {\n full: [3, 6],\n reduced: [3, 5],\n minimal: [2, 3],\n};\n\n/**\n * Fallback tick counts for callers that don't have an axis length handy\n * (categorical band-scale thinning uses this as a cap, and `continuousTicks`\n * uses it when no `targetCount` is provided).\n *\n * @internal\n */\nconst TICK_COUNTS: Record<AxisLabelDensity, number> = {\n full: 7,\n reduced: 5,\n minimal: 3,\n};\n\n/**\n * Compute a target tick count for a continuous axis from its pixel length and\n * density tier. Uses the Plot-style pixels-per-tick heuristic, then clamps\n * into the density's count range.\n */\nexport function targetTickCount(\n axisLength: number,\n density: AxisLabelDensity,\n orientation: 'x' | 'y',\n): number {\n const pxPerTick = orientation === 'y' ? Y_PX_PER_TICK[density] : X_PX_PER_TICK[density];\n const [min, max] =\n orientation === 'y' ? Y_TICK_COUNT_RANGE[density] : X_TICK_COUNT_RANGE[density];\n const raw = Math.round(axisLength / pxPerTick);\n return Math.max(min, Math.min(max, raw));\n}\n\n/** Set of continuous numeric scale types that should format as numbers. */\nconst NUMERIC_SCALE_TYPES = new Set([\n 'linear',\n 'log',\n 'pow',\n 'sqrt',\n 'symlog',\n 'quantile',\n 'quantize',\n 'threshold',\n]);\n\n/** Set of temporal scale types. */\nconst TEMPORAL_SCALE_TYPES = new Set(['time', 'utc']);\n\n/** Format a tick value based on the scale type. */\nfunction formatTickLabel(value: unknown, resolvedScale: ResolvedScale): string {\n const formatStr = resolvedScale.channel.axis?.format;\n\n if (TEMPORAL_SCALE_TYPES.has(resolvedScale.type)) {\n const temporalFmt = buildTemporalFormatter(formatStr);\n if (temporalFmt) return temporalFmt(value as Date);\n const useUtc = resolvedScale.type === 'utc';\n return formatDate(value as Date, undefined, undefined, useUtc);\n }\n\n if (NUMERIC_SCALE_TYPES.has(resolvedScale.type)) {\n const num = value as number;\n if (formatStr) {\n const fmt = buildD3Formatter(formatStr);\n if (fmt) return fmt(num);\n }\n // Abbreviate large numbers for axis labels\n if (Math.abs(num) >= 1000) return abbreviateNumber(num);\n return formatNumber(num);\n }\n\n return String(value);\n}\n\n/**\n * Generate ticks for a continuous scale (linear, time, log, pow, sqrt, symlog).\n *\n * `targetCount` lets callers that know the axis pixel length pass a\n * density-appropriate count (see `targetTickCount`). When omitted, falls back\n * to the coarse `TICK_COUNTS` tier, which is only used by tests and callers\n * that don't have an axis length.\n */\nexport function continuousTicks(\n resolvedScale: ResolvedScale,\n density: AxisLabelDensity,\n targetCount?: number,\n): AxisTick[] {\n const scale = resolvedScale.scale as D3ContinuousScale;\n\n // Discretizing scales (quantile, quantize, threshold) don't have .ticks().\n // Use their domain thresholds as ticks instead.\n if (!('ticks' in scale) || typeof scale.ticks !== 'function') {\n const domain = scale.domain() as unknown[];\n return domain.map((value: unknown) => ({\n value,\n position: (scale as D3ContinuousScale)(value as number & Date) as number,\n label: formatTickLabel(value, resolvedScale),\n }));\n }\n\n const explicitCount = resolvedScale.channel.axis?.tickCount;\n const count = explicitCount ?? targetCount ?? TICK_COUNTS[density];\n return buildContinuousTicks(resolvedScale, count);\n}\n\n/**\n * Build positioned, labeled ticks for a continuous scale at an exact count.\n * Exposed so callers that need to re-request ticks at a lower count (for\n * overlap-driven density adaptation) can regenerate without manual pruning.\n * D3's `scale.ticks(n)` always returns evenly-spaced round values, so\n * requesting a smaller `n` never produces squished neighbors — unlike\n * \"keep first+last, drop middle\" pruning which can stack the last tick\n * next to an endpoint and cascade to 2 ticks.\n */\nexport function buildContinuousTicks(resolvedScale: ResolvedScale, count: number): AxisTick[] {\n const scale = resolvedScale.scale as D3ContinuousScale;\n if (!('ticks' in scale) || typeof scale.ticks !== 'function') {\n return continuousTicks(resolvedScale, 'full');\n }\n const raw: unknown[] = scale.ticks(count);\n return raw.map((value: unknown) => ({\n value,\n position: scale(value as number & Date) as number,\n label: formatTickLabel(value, resolvedScale),\n }));\n}\n\n/** True if this scale supports regenerating ticks at an arbitrary count. */\nexport function scaleSupportsTickCount(resolvedScale: ResolvedScale): boolean {\n const scale = resolvedScale.scale as D3ContinuousScale;\n return 'ticks' in scale && typeof scale.ticks === 'function';\n}\n\n/** Generate ticks for a band/point/ordinal scale. */\nexport function categoricalTicks(\n resolvedScale: ResolvedScale,\n density: AxisLabelDensity,\n): AxisTick[] {\n const scale = resolvedScale.scale as D3CategoricalScale;\n const domain: string[] = scale.domain();\n const explicitTickCount = resolvedScale.channel.axis?.tickCount;\n const maxTicks = explicitTickCount ?? TICK_COUNTS[density];\n\n // Band scales (bar charts) show all category labels by default.\n // Only thin when there's an explicit tickCount override or for point/ordinal scales.\n let selectedValues = domain;\n if ((resolvedScale.type !== 'band' || explicitTickCount) && domain.length > maxTicks) {\n const step = Math.ceil(domain.length / maxTicks);\n selectedValues = domain.filter((_: string, i: number) => i % step === 0);\n }\n\n const ticks = selectedValues.map((value: string) => {\n // Band scales: use the center of the band\n const bandScale = resolvedScale.type === 'band' ? (scale as ScaleBand<string>) : null;\n const pos = bandScale\n ? (bandScale(value) ?? 0) + bandScale.bandwidth() / 2\n : ((scale(value) as number | undefined) ?? 0);\n\n return {\n value,\n position: pos,\n label: value,\n };\n });\n\n return ticks;\n}\n\n/** Resolve explicit tick values from axis config into positioned ticks. */\nexport function resolveExplicitTicks(values: unknown[], resolvedScale: ResolvedScale): AxisTick[] {\n const scale = resolvedScale.scale;\n return values.map((value) => {\n let position: number;\n if (TEMPORAL_SCALE_TYPES.has(resolvedScale.type)) {\n const d = value instanceof Date ? value : new Date(String(value));\n position = (scale as D3ContinuousScale)(d as number & Date) as number;\n } else if (\n resolvedScale.type === 'band' ||\n resolvedScale.type === 'point' ||\n resolvedScale.type === 'ordinal'\n ) {\n const s = String(value);\n const bandScale = resolvedScale.type === 'band' ? (scale as ScaleBand<string>) : null;\n position = bandScale\n ? (bandScale(s) ?? 0) + bandScale.bandwidth() / 2\n : ((scale(s as string & number) as number | undefined) ?? 0);\n } else {\n position = (scale as D3ContinuousScale)(value as number & Date) as number;\n }\n return {\n value,\n position,\n label: formatTickLabel(value, resolvedScale),\n };\n });\n}\n","/**\n * Axis computation: tick positions, labels, and axis lines.\n *\n * Generates ticks manually (no d3-axis) so we have full control over\n * responsive tick density and formatting. Tick generation and label\n * thinning live in sibling modules under ./axes/.\n */\n\nimport type {\n AxisLabelDensity,\n AxisLayout,\n AxisTick,\n Gridline,\n LayoutStrategy,\n MeasureTextFn,\n Rect,\n ResolvedTheme,\n TextStyle,\n} from '@opendata-ai/openchart-core';\nimport type { ScaleBand } from 'd3-scale';\nimport { measureLabel, thinTicksUntilFit, ticksOverlap } from './axes/thinning';\nimport {\n buildContinuousTicks,\n categoricalTicks,\n continuousTicks,\n resolveExplicitTicks,\n scaleSupportsTickCount,\n targetTickCount,\n} from './axes/ticks';\nimport type { ResolvedScales } from './scales';\n\n// Re-export pure helpers so external consumers (and tests) continue to import\n// them from './layout/axes'.\nexport { thinTicksUntilFit, ticksOverlap } from './axes/thinning';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/**\n * Height thresholds for reducing y-axis tick density.\n * Below these pixel heights, we step down the density regardless of the\n * width-based strategy. This prevents overlapping y-axis labels in short\n * containers like thumbnail previews.\n */\nconst HEIGHT_MINIMAL_THRESHOLD = 120;\nconst HEIGHT_REDUCED_THRESHOLD = 200;\n\n/**\n * Width thresholds for reducing x-axis tick density.\n * Mirrors the height logic for the x-axis: narrow containers get fewer ticks.\n */\nconst WIDTH_MINIMAL_THRESHOLD = 150;\nconst WIDTH_REDUCED_THRESHOLD = 300;\n\n/** Ordered densities from most to fewest ticks. */\nconst DENSITY_ORDER: AxisLabelDensity[] = ['full', 'reduced', 'minimal'];\n\n/**\n * Compute effective axis tick density by considering available space.\n *\n * The width-based breakpoint system sets a base density, but it doesn't know\n * about the actual chart area dimensions (which shrink after chrome/legend\n * allocation). This function steps density down further when the axis\n * dimension is too small for the requested tick count.\n *\n * @param baseDensity - The density from the responsive layout strategy.\n * @param axisLength - Available pixels along this axis (height for y, width for x).\n * @param minimalThreshold - Below this pixel size, force minimal density.\n * @param reducedThreshold - Below this pixel size, cap at reduced density.\n * @returns The effective density, never looser than the base.\n */\nexport function effectiveDensity(\n baseDensity: AxisLabelDensity,\n axisLength: number,\n minimalThreshold: number,\n reducedThreshold: number,\n): AxisLabelDensity {\n let density = baseDensity;\n\n if (axisLength < minimalThreshold) {\n density = 'minimal';\n } else if (axisLength < reducedThreshold) {\n // Don't increase density beyond what the base strategy allows.\n // If base is already 'minimal', keep it.\n const baseIdx = DENSITY_ORDER.indexOf(baseDensity);\n const reducedIdx = DENSITY_ORDER.indexOf('reduced');\n density = DENSITY_ORDER[Math.max(baseIdx, reducedIdx)];\n }\n\n return density;\n}\n\n/**\n * Floor tick count for continuous axes when the axis is long enough to show\n * more than a min/max pair. Keeps the editorial ~5 target when possible.\n * Very short axes bypass this floor and can legitimately fall to 2.\n */\nconst CONTINUOUS_TICK_FLOOR = 4;\n\n/**\n * How much D3 is allowed to overshoot what we asked for before we treat the\n * output as \"too dense\" and step down. D3's `scale.ticks(n)` only produces\n * nice step sizes (1, 2, 5 × 10^k, or calendar units for time), so a request\n * for n=6 can come back with 12 quarterly dates or 10 step-5 values. Accepting\n * up to 1.5× target catches the obvious overshoots without trimming acceptable\n * ones.\n *\n * The reference point stays fixed to the initial requested count even as we\n * iterate downward — we're measuring \"did this candidate land near the target\n * the caller actually wanted?\", not \"is the candidate near what we just asked\n * for on this iteration?\". If a candidate at n=3 returns 8 ticks, it's still\n * a 1.3× overshoot of the target-6, which is fine.\n */\nconst OVERSHOOT_TOLERANCE = 1.5;\n\n/**\n * Fit continuous ticks by re-requesting progressively fewer ticks from the\n * scale. D3's `scale.ticks(n)` always returns evenly-spaced round values, so\n * stepping `n` down keeps spacing uniform — unlike middle-pruning which can\n * strand the last tick next to an endpoint and cascade to 2 ticks.\n *\n * Two conditions trigger a step-down:\n * 1. The label heuristic detects overlap at the initial count.\n * 2. D3 overshot the requested count by more than OVERSHOOT_TOLERANCE.\n * (Time scales jump between calendar units; linear scales jump between\n * nice step sizes. Either can return 2× what we asked for.)\n *\n * Falls back to overlap-safe thinning on the best-so-far candidate if no\n * count produces a clean fit. The fallback starts from the smallest candidate\n * that still meets the floor, so `thinTicksUntilFit` never receives the\n * overshot initial set (which was the bug this function exists to avoid).\n */\nfunction fitContinuousTicks(\n scale: ResolvedScales['x' | 'y'],\n initialTicks: AxisTick[],\n initialCount: number,\n fontSize: number,\n fontWeight: number,\n axisLength: number,\n orientation: 'horizontal' | 'vertical',\n measureText?: MeasureTextFn,\n): AxisTick[] {\n if (!scale || !scaleSupportsTickCount(scale)) return initialTicks;\n\n const tolerance = initialCount * OVERSHOOT_TOLERANCE;\n const overshoots = initialTicks.length > tolerance;\n const overlaps = ticksOverlap(initialTicks, fontSize, fontWeight, measureText, orientation);\n if (!overshoots && !overlaps) return initialTicks;\n\n // Enforce the floor only when the axis is long enough to fit that many\n // labels without overlap. Very short axes can fall below.\n const minThreshold =\n orientation === 'vertical' ? HEIGHT_MINIMAL_THRESHOLD : WIDTH_MINIMAL_THRESHOLD;\n const floor = axisLength >= minThreshold ? CONTINUOUS_TICK_FLOOR : 2;\n\n // Track the smallest candidate that meets the floor. If no candidate fits\n // cleanly, we thin this instead of the overshot `initialTicks` so the\n // fallback doesn't reintroduce the cascading-to-2-ticks bug.\n let bestWithinFloor: AxisTick[] | undefined;\n for (let n = initialCount - 1; n >= 2; n--) {\n const candidate = buildContinuousTicks(scale, n);\n const candidateOvershoots = candidate.length > tolerance;\n const candidateOverlaps = ticksOverlap(\n candidate,\n fontSize,\n fontWeight,\n measureText,\n orientation,\n );\n if (!candidateOvershoots && !candidateOverlaps) {\n return candidate;\n }\n if (candidate.length >= floor) bestWithinFloor = candidate;\n }\n\n // No candidate fit cleanly. Thin whatever most recently met the floor; if\n // nothing did, synthesize a floor-count set directly from the scale so we\n // never hand the overshot initialTicks to the middle-pruning thinner.\n const fallback = bestWithinFloor ?? buildContinuousTicks(scale, floor);\n return thinTicksUntilFit(fallback, fontSize, fontWeight, measureText, orientation);\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/** Output of computeAxes. */\nexport interface AxesResult {\n x?: AxisLayout;\n y?: AxisLayout;\n}\n\n/**\n * Compute axis layouts with tick positions, labels, and axis lines.\n *\n * @param scales - Resolved scales from computeScales.\n * @param chartArea - The chart drawing area.\n * @param strategy - Responsive layout strategy.\n * @param theme - Resolved theme for styling.\n * @param measureText - Optional real text measurement from the adapter.\n */\nexport function computeAxes(\n scales: ResolvedScales,\n chartArea: Rect,\n strategy: LayoutStrategy,\n theme: ResolvedTheme,\n measureText?: MeasureTextFn,\n): AxesResult {\n const result: AxesResult = {};\n const baseDensity = strategy.axisLabelDensity;\n\n // Compute per-axis density based on available space.\n // Y-axis density adapts to chart height; X-axis density adapts to chart width.\n const yDensity = effectiveDensity(\n baseDensity,\n chartArea.height,\n HEIGHT_MINIMAL_THRESHOLD,\n HEIGHT_REDUCED_THRESHOLD,\n );\n const xDensity = effectiveDensity(\n baseDensity,\n chartArea.width,\n WIDTH_MINIMAL_THRESHOLD,\n WIDTH_REDUCED_THRESHOLD,\n );\n\n const tickLabelStyle: TextStyle = {\n fontFamily: theme.fonts.family,\n fontSize: theme.fonts.sizes.axisTick,\n fontWeight: theme.fonts.weights.normal,\n fill: theme.colors.axis,\n lineHeight: 1.2,\n fontVariant: 'tabular-nums',\n };\n\n const axisLabelStyle: TextStyle = {\n fontFamily: theme.fonts.family,\n fontSize: theme.fonts.sizes.body,\n fontWeight: theme.fonts.weights.medium,\n fill: theme.colors.text,\n lineHeight: 1.3,\n };\n\n const { fontSize } = tickLabelStyle;\n const { fontWeight } = tickLabelStyle;\n\n if (scales.x) {\n const axisConfig = scales.x.channel.axis;\n const isContinuousX =\n scales.x.type !== 'band' && scales.x.type !== 'point' && scales.x.type !== 'ordinal';\n\n const xTargetCount = isContinuousX\n ? targetTickCount(chartArea.width, xDensity, 'x')\n : undefined;\n\n // Use explicit tick values from axis config if provided\n let allTicks: AxisTick[];\n if (axisConfig?.values) {\n allTicks = resolveExplicitTicks(axisConfig.values, scales.x);\n } else if (!isContinuousX) {\n allTicks = categoricalTicks(scales.x, xDensity);\n } else {\n allTicks = continuousTicks(scales.x, xDensity, xTargetCount);\n }\n\n // Gridlines use the full tick set so they remain visible even when labels\n // are thinned to prevent overlap.\n const gridlines: Gridline[] = allTicks.map((t) => ({\n position: t.position,\n major: true,\n }));\n\n // Thin tick labels to prevent overlap (skip for band scales which use\n // auto-rotation, and when the user set an explicit tickCount or values).\n const shouldThin = scales.x.type !== 'band' && !axisConfig?.tickCount && !axisConfig?.values;\n let ticks: AxisTick[];\n if (!shouldThin) {\n ticks = allTicks;\n } else if (isContinuousX) {\n // Continuous x-axis: re-request ticks at a lower count on overlap so\n // time-scale quartile/monthly jumps don't leave a too-dense axis.\n ticks = fitContinuousTicks(\n scales.x,\n allTicks,\n xTargetCount ?? allTicks.length,\n fontSize,\n fontWeight,\n chartArea.width,\n 'horizontal',\n measureText,\n );\n } else {\n ticks = thinTicksUntilFit(allTicks, fontSize, fontWeight, measureText);\n }\n\n // Auto-rotate labels when band scale labels would overlap.\n // Uses max label width (not average) since one long label is enough to overlap.\n let tickAngle = axisConfig?.labelAngle;\n if (tickAngle === undefined && scales.x.type === 'band' && ticks.length > 1) {\n const bandwidth = (scales.x.scale as ScaleBand<string>).bandwidth();\n let maxLabelWidth = 0;\n for (const t of ticks) {\n const w = measureLabel(t.label, fontSize, fontWeight, measureText);\n if (w > maxLabelWidth) maxLabelWidth = w;\n }\n // If the widest label exceeds 85% of the bandwidth, rotate to avoid overlap\n if (maxLabelWidth > bandwidth * 0.85) {\n tickAngle = -45;\n }\n }\n\n const axisTitle = axisConfig?.title;\n\n result.x = {\n ticks,\n gridlines: axisConfig?.grid ? gridlines : [],\n label: axisTitle,\n labelStyle: axisLabelStyle,\n tickLabelStyle,\n tickAngle,\n start: { x: chartArea.x, y: chartArea.y + chartArea.height },\n end: { x: chartArea.x + chartArea.width, y: chartArea.y + chartArea.height },\n orient: axisConfig?.orient,\n domainLine: axisConfig?.domain,\n tickMarks: axisConfig?.ticks,\n offset: axisConfig?.offset,\n titlePadding: axisConfig?.titlePadding,\n labelPadding: axisConfig?.labelPadding,\n labelOverlap: axisConfig?.labelOverlap,\n labelFlush: axisConfig?.labelFlush,\n };\n }\n\n if (scales.y) {\n const axisConfig = scales.y.channel.axis;\n const isContinuousY =\n scales.y.type !== 'band' && scales.y.type !== 'point' && scales.y.type !== 'ordinal';\n\n // Target count from pixels-per-tick when we have a continuous y-axis.\n const yTargetCount = isContinuousY\n ? targetTickCount(chartArea.height, yDensity, 'y')\n : undefined;\n\n // Use explicit tick values from axis config if provided\n let allTicks: AxisTick[];\n if (axisConfig?.values) {\n allTicks = resolveExplicitTicks(axisConfig.values, scales.y);\n } else if (!isContinuousY) {\n allTicks = categoricalTicks(scales.y, yDensity);\n } else {\n allTicks = continuousTicks(scales.y, yDensity, yTargetCount);\n }\n\n // Thin tick labels to prevent overlap (skip for band scales, explicit tickCount, and values).\n const shouldThin = scales.y.type !== 'band' && !axisConfig?.tickCount && !axisConfig?.values;\n let ticks: AxisTick[];\n if (!shouldThin) {\n ticks = allTicks;\n } else if (isContinuousY) {\n // Continuous y-axis: re-request ticks at a lower count on overlap so\n // spacing stays uniform and we don't collapse to min/max.\n ticks = fitContinuousTicks(\n scales.y,\n allTicks,\n yTargetCount ?? allTicks.length,\n fontSize,\n fontWeight,\n chartArea.height,\n 'vertical',\n measureText,\n );\n } else {\n ticks = thinTicksUntilFit(allTicks, fontSize, fontWeight, measureText, 'vertical');\n }\n\n // Gridlines match the tick set so every gridline has a label.\n const gridlines: Gridline[] = ticks.map((t) => ({\n position: t.position,\n major: true,\n }));\n\n const axisTitle = axisConfig?.title;\n const tickAngle = axisConfig?.labelAngle;\n\n result.y = {\n ticks,\n // Y-axis gridlines are shown by default (standard editorial practice)\n gridlines,\n label: axisTitle,\n labelStyle: axisLabelStyle,\n tickLabelStyle,\n tickAngle,\n start: { x: chartArea.x, y: chartArea.y },\n end: { x: chartArea.x, y: chartArea.y + chartArea.height },\n orient: axisConfig?.orient,\n domainLine: axisConfig?.domain,\n tickMarks: axisConfig?.ticks,\n offset: axisConfig?.offset,\n titlePadding: axisConfig?.titlePadding,\n labelPadding: axisConfig?.labelPadding,\n labelOverlap: axisConfig?.labelOverlap,\n labelFlush: axisConfig?.labelFlush,\n };\n }\n\n return result;\n}\n","/**\n * Dimension computation for the chart layout.\n *\n * Takes the normalized spec + compile options + legend layout and produces\n * LayoutDimensions with the total area, chrome layout, chart drawing area,\n * and margins. The chart area is what's left after subtracting chrome,\n * legend space, and axis margins.\n *\n * Padding and chrome scale down at smaller container sizes to maximize\n * the usable chart area. When the chart area is still too small after\n * scaling, chrome is progressively stripped as a fallback.\n */\n\nimport type {\n CompileOptions,\n Encoding,\n LayoutStrategy,\n LegendLayout,\n Margins,\n Rect,\n ResolvedChrome,\n ResolvedTheme,\n} from '@opendata-ai/openchart-core';\nimport { computeChrome, estimateTextWidth } from '@opendata-ai/openchart-core';\nimport { format as d3Format } from 'd3-format';\n\nimport type { NormalizedChartSpec, NormalizedChrome } from '../compiler/types';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** The complete dimension layout for a chart. */\nexport interface LayoutDimensions {\n /** Total available space. */\n total: Rect;\n /** Resolved chrome (title, subtitle, source, etc.). */\n chrome: ResolvedChrome;\n /** The chart drawing area (after subtracting chrome, legend, margins). */\n chartArea: Rect;\n /** Margins around the chart area. */\n margins: Margins;\n /** Resolved theme used for this layout. */\n theme: ResolvedTheme;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Convert NormalizedChrome back to a Chrome-compatible shape for computeChrome. */\nfunction chromeToInput(chrome: NormalizedChrome): import('@opendata-ai/openchart-core').Chrome {\n return {\n title: chrome.title,\n subtitle: chrome.subtitle,\n source: chrome.source,\n byline: chrome.byline,\n footer: chrome.footer,\n };\n}\n\n/**\n * Scale padding based on the smaller container dimension.\n * At >= 500px, padding is unchanged. At <= 200px, padding is halved (min 4px).\n * Linear interpolation between 200-500px.\n */\nfunction scalePadding(basePadding: number, width: number, height: number): number {\n const minDim = Math.min(width, height);\n if (minDim >= 500) return basePadding;\n if (minDim <= 200) return Math.max(Math.round(basePadding * 0.5), 4);\n const t = (minDim - 200) / 300;\n return Math.max(Math.round(basePadding * (0.5 + t * 0.5)), 4);\n}\n\n/** Minimum chart area dimensions before guardrails kick in. */\nconst MIN_CHART_WIDTH = 60;\nconst MIN_CHART_HEIGHT = 40;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute chart dimensions, reserving space for chrome, legend, and axes.\n *\n * @param spec - Normalized chart spec.\n * @param options - Compile options (width, height, theme, darkMode).\n * @param legendLayout - Pre-computed legend layout (used to reserve space).\n * @param theme - Already-resolved theme (resolved once in compileChart).\n * @param strategy - Responsive layout strategy (controls chrome mode).\n * @returns LayoutDimensions with chart area rect.\n */\nexport function computeDimensions(\n spec: NormalizedChartSpec,\n options: CompileOptions,\n legendLayout: LegendLayout,\n theme: ResolvedTheme,\n strategy?: LayoutStrategy,\n watermark: boolean = true,\n): LayoutDimensions {\n const { width, height } = options;\n\n const padding = scalePadding(theme.spacing.padding, width, height);\n const axisMargin = theme.spacing.axisMargin;\n const chromeMode = strategy?.chromeMode ?? 'full';\n\n // Compute chrome with mode and scaled padding\n const chrome = computeChrome(\n chromeToInput(spec.chrome),\n theme,\n width,\n options.measureText,\n chromeMode,\n padding,\n watermark,\n );\n\n // Start with the total rect\n const total: Rect = { x: 0, y: 0, width, height };\n\n // Radial charts (arc) don't have axes, so skip axis space\n const isRadial = spec.markType === 'arc';\n const encoding = spec.encoding as Encoding;\n\n // Estimate x-axis height below chart area: tick labels sit 14px below,\n // axis title sits 35px below. These extend past the chart area bottom\n // and source/footer chrome must be positioned below them.\n const xAxis = encoding.x?.axis as (Record<string, unknown> & { labelAngle?: number }) | undefined;\n const hasXAxisLabel = !!xAxis?.title;\n const xTickAngle = xAxis?.labelAngle;\n\n let xAxisHeight: number;\n if (isRadial) {\n xAxisHeight = 0;\n } else if (xTickAngle && Math.abs(xTickAngle) > 10) {\n // Rotated labels: estimate height from the longest label text.\n // At -90 degrees, the label height = text width. At -45, it's width * sin(45).\n const angleRad = Math.abs(xTickAngle) * (Math.PI / 180);\n const xField = encoding.x?.field;\n let maxLabelWidth = 40; // fallback\n if (xField) {\n for (const row of spec.data) {\n const label = String(row[xField] ?? '');\n const w = estimateTextWidth(label, theme.fonts.sizes.axisTick, theme.fonts.weights.normal);\n if (w > maxLabelWidth) maxLabelWidth = w;\n }\n }\n // Rotated label height: width * sin(angle), plus a small gap\n const rotatedHeight = maxLabelWidth * Math.sin(angleRad) + 6;\n // Cap at a reasonable max to avoid absurd margins\n const labelHeight = Math.min(rotatedHeight, 120);\n xAxisHeight = hasXAxisLabel ? labelHeight + 20 : labelHeight;\n } else {\n xAxisHeight = hasXAxisLabel ? 48 : 26;\n }\n\n // Build margins: padding + chrome + axis space.\n // For radial charts (arc/donut), axes don't exist, so axisMargin is only\n // added when there's actual chrome content that needs separation from the\n // chart area. When chrome is empty the margin is just padding.\n const topAxisGap = isRadial && chrome.topHeight === 0 ? 0 : axisMargin;\n const margins: Margins = {\n top: padding + chrome.topHeight + topAxisGap,\n right: padding + (isRadial ? padding : axisMargin),\n bottom: padding + chrome.bottomHeight + xAxisHeight,\n left: padding + (isRadial ? padding : axisMargin),\n };\n\n // Dynamic right margin for line/area end-of-line labels.\n // Only reserve space when labels will actually render (density != 'none').\n const labelDensity = spec.labels.density;\n if ((spec.markType === 'line' || spec.markType === 'area') && labelDensity !== 'none') {\n // Estimate label width from longest series name (color encoding domain)\n const colorEnc = encoding.color;\n const colorField = colorEnc && 'field' in colorEnc ? colorEnc.field : undefined;\n if (colorField) {\n let maxLabelWidth = 0;\n const seen = new Set<string>();\n for (const row of spec.data) {\n const label = String(row[colorField] ?? '');\n if (!seen.has(label)) {\n seen.add(label);\n const w = estimateTextWidth(label, 11, 600);\n if (w > maxLabelWidth) maxLabelWidth = w;\n }\n }\n if (maxLabelWidth > 0) {\n margins.right = Math.max(margins.right, padding + maxLabelWidth + 8);\n }\n }\n }\n\n // Reserve right margin for text annotations near the chart's right edge.\n // Without this, annotation text at the last data point clips outside the SVG.\n // Account for anchor direction and offset.dx to avoid over-reserving space.\n // Skip when annotations are hidden (tooltip-only at compact breakpoints).\n if (\n strategy?.annotationPosition !== 'tooltip-only' &&\n spec.annotations.length > 0 &&\n encoding.x\n ) {\n const xField = encoding.x.field;\n // Find the maximum x value in the data\n let maxX: string | number | undefined;\n for (const row of spec.data) {\n const v = row[xField];\n if (v != null && (maxX == null || String(v) >= String(maxX))) maxX = v as string | number;\n }\n if (maxX != null) {\n const maxXStr = String(maxX);\n for (const ann of spec.annotations) {\n if (ann.type === 'text' && String(ann.x) === maxXStr) {\n const textWidth = estimateTextWidth(ann.text, ann.fontSize ?? 11, ann.fontWeight ?? 600);\n const dx = ann.offset?.dx ?? 0;\n // How much text extends right of the anchor point depends on alignment:\n // - anchor \"right\" or \"left\": text is off to one side, full width extends\n // - anchor \"top\"/\"bottom\"/\"auto\"/undefined: text is centered, half extends right\n const anchor = ann.anchor ?? 'auto';\n const baseRightExtent =\n anchor === 'left'\n ? textWidth\n : // text is to the right of anchor\n anchor === 'right'\n ? 0\n : // text is to the left of anchor\n textWidth / 2; // centered (top/bottom/auto)\n const rightOverflow = Math.max(0, baseRightExtent + dx);\n if (rightOverflow > 0) {\n margins.right = Math.max(margins.right, padding + rightOverflow + 12);\n }\n }\n }\n }\n }\n\n // Dynamic left margin for y-axis labels\n if (encoding.y && !isRadial) {\n if (\n spec.markType === 'bar' ||\n spec.markType === 'circle' ||\n spec.markType === 'lollipop' ||\n encoding.y.type === 'nominal' ||\n encoding.y.type === 'ordinal'\n ) {\n // Category labels on the left for bar/dot charts\n const yField = encoding.y.field;\n let maxLabelWidth = 0;\n for (const row of spec.data) {\n const label = String(row[yField] ?? '');\n const w = estimateTextWidth(label, theme.fonts.sizes.axisTick, theme.fonts.weights.normal);\n if (w > maxLabelWidth) maxLabelWidth = w;\n }\n if (maxLabelWidth > 0) {\n margins.left = Math.max(margins.left, padding + maxLabelWidth + 12);\n }\n } else if (encoding.y.type === 'quantitative' || encoding.y.type === 'temporal') {\n // Numeric tick labels on the left. Estimate width from the data range.\n const yField = encoding.y.field;\n const yAxisFormat = (encoding.y.axis as Record<string, unknown> | undefined)?.format as\n | string\n | undefined;\n let maxAbsVal = 0;\n for (const row of spec.data) {\n const v = Number(row[yField]);\n if (Number.isFinite(v) && Math.abs(v) > maxAbsVal) maxAbsVal = Math.abs(v);\n }\n\n let sampleLabel: string;\n if (yAxisFormat) {\n // Use the actual d3-format to produce a realistic label estimate\n try {\n const fmt = d3Format(yAxisFormat);\n sampleLabel = fmt(maxAbsVal);\n } catch {\n sampleLabel = String(maxAbsVal);\n }\n } else {\n // Fallback: estimate from magnitude\n if (maxAbsVal >= 1_000_000_000) sampleLabel = '1.5B';\n else if (maxAbsVal >= 1_000_000) sampleLabel = '1.5M';\n else if (maxAbsVal >= 1_000) sampleLabel = '1.5K';\n else if (maxAbsVal >= 100) sampleLabel = '100';\n else if (maxAbsVal >= 10) sampleLabel = '10';\n else sampleLabel = '0.0';\n }\n // Account for negative sign\n const negPrefix = spec.data.some((r) => Number(r[yField]) < 0) ? '-' : '';\n const labelEst = negPrefix + sampleLabel;\n const labelWidth = estimateTextWidth(\n labelEst,\n theme.fonts.sizes.axisTick,\n theme.fonts.weights.normal,\n );\n // 6px gap between label and chart area edge\n margins.left = Math.max(margins.left, padding + labelWidth + 10);\n }\n }\n\n // Rotated y-axis label needs extra left margin (rendered at area.x - 45 in SVG)\n const yAxis = encoding.y?.axis as Record<string, unknown> | undefined;\n if (yAxis && (yAxis.title || yAxis.label) && !isRadial) {\n const rotatedLabelMargin = 45 + Math.ceil(theme.fonts.sizes.body / 2) + 4;\n margins.left = Math.max(margins.left, padding + rotatedLabelMargin);\n }\n\n // Reserve legend space\n if (legendLayout.entries.length > 0) {\n if (legendLayout.position === 'right' || legendLayout.position === 'bottom-right') {\n margins.right += legendLayout.bounds.width + 8;\n } else if (legendLayout.position === 'top') {\n margins.top += legendLayout.bounds.height + 4;\n } else if (legendLayout.position === 'bottom') {\n margins.bottom += legendLayout.bounds.height + 4;\n }\n }\n\n // Chart area is what's left after margins\n let chartArea: Rect = {\n x: margins.left,\n y: margins.top,\n width: Math.max(0, width - margins.left - margins.right),\n height: Math.max(0, height - margins.top - margins.bottom),\n };\n\n // Guardrail: if chart area is too small, progressively strip chrome\n if (\n (chartArea.width < MIN_CHART_WIDTH || chartArea.height < MIN_CHART_HEIGHT) &&\n chromeMode !== 'hidden'\n ) {\n // Try compact first, then hidden\n const fallbackMode = chromeMode === 'full' ? 'compact' : 'hidden';\n const fallbackChrome = computeChrome(\n chromeToInput(spec.chrome),\n theme,\n width,\n options.measureText,\n fallbackMode as 'compact' | 'hidden',\n padding,\n watermark,\n );\n\n // Recalculate top/bottom margins with stripped chrome\n const fallbackTopAxisGap = isRadial && fallbackChrome.topHeight === 0 ? 0 : axisMargin;\n const newTop = padding + fallbackChrome.topHeight + fallbackTopAxisGap;\n const topDelta = margins.top - newTop;\n const newBottom = padding + fallbackChrome.bottomHeight + xAxisHeight;\n const bottomDelta = margins.bottom - newBottom;\n\n if (topDelta > 0 || bottomDelta > 0) {\n margins.top =\n newTop +\n (legendLayout.entries.length > 0 && legendLayout.position === 'top'\n ? legendLayout.bounds.height + 4\n : 0);\n margins.bottom = newBottom;\n\n chartArea = {\n x: margins.left,\n y: margins.top,\n width: Math.max(0, width - margins.left - margins.right),\n height: Math.max(0, height - margins.top - margins.bottom),\n };\n\n return { total, chrome: fallbackChrome, chartArea, margins, theme };\n }\n }\n\n return { total, chrome, chartArea, margins, theme };\n}\n","/**\n * Gridline computation.\n *\n * Produces horizontal gridlines at y-axis tick positions and optional\n * vertical gridlines at x-axis tick positions.\n */\n\nimport type { Rect } from '@opendata-ai/openchart-core';\nimport type { AxesResult } from './axes';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** A single gridline with start/end positions. */\nexport interface GridlineSpec {\n /** Start x. */\n x1: number;\n /** Start y. */\n y1: number;\n /** End x. */\n x2: number;\n /** End y. */\n y2: number;\n /** Whether this is a major gridline. */\n major: boolean;\n}\n\n/** Complete gridline layout. */\nexport interface GridlineLayout {\n horizontal: GridlineSpec[];\n vertical: GridlineSpec[];\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute gridlines from axis layouts.\n *\n * Horizontal gridlines span the chart width at y-axis tick positions.\n * Vertical gridlines span the chart height at x-axis tick positions.\n *\n * @param axes - Computed axis layouts.\n * @param chartArea - The chart drawing area.\n * @param showVertical - Whether to include vertical gridlines (default: false).\n */\nexport function computeGridlines(\n axes: AxesResult,\n chartArea: Rect,\n showVertical = false,\n): GridlineLayout {\n const horizontal: GridlineSpec[] = [];\n const vertical: GridlineSpec[] = [];\n\n // Horizontal gridlines at y-axis ticks\n if (axes.y) {\n for (const gridline of axes.y.gridlines) {\n horizontal.push({\n x1: chartArea.x,\n y1: gridline.position,\n x2: chartArea.x + chartArea.width,\n y2: gridline.position,\n major: gridline.major,\n });\n }\n }\n\n // Vertical gridlines at x-axis ticks (off by default)\n if (showVertical && axes.x) {\n for (const gridline of axes.x.gridlines) {\n vertical.push({\n x1: gridline.position,\n y1: chartArea.y,\n x2: gridline.position,\n y2: chartArea.y + chartArea.height,\n major: gridline.major,\n });\n }\n }\n\n return { horizontal, vertical };\n}\n","/**\n * Scale computation from encoding spec + data.\n *\n * Creates D3 scales that map data values to pixel positions.\n * Temporal -> scaleTime(), quantitative -> scaleLinear(),\n * nominal/ordinal -> scaleBand() or scaleOrdinal(), depending on context.\n */\n\nimport type {\n DataRow,\n Encoding,\n EncodingChannel,\n Rect,\n ScaleType,\n} from '@opendata-ai/openchart-core';\nimport { extent, max, min } from 'd3-array';\nimport type {\n ScaleBand,\n ScaleLinear,\n ScaleLogarithmic,\n ScaleOrdinal,\n ScalePoint,\n ScalePower,\n ScaleQuantile,\n ScaleQuantize,\n ScaleSymLog,\n ScaleThreshold,\n ScaleTime,\n} from 'd3-scale';\nimport {\n scaleBand,\n scaleLinear,\n scaleLog,\n scaleOrdinal,\n scalePoint,\n scalePow,\n scaleQuantile,\n scaleQuantize,\n scaleSqrt,\n scaleSymlog,\n scaleThreshold,\n scaleTime,\n scaleUtc,\n} from 'd3-scale';\n\nimport type { NormalizedChartSpec } from '../compiler/types';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Continuous D3 scales (linear, time, log, pow, sqrt, symlog) that support .ticks() and .nice(). */\nexport type D3ContinuousScale =\n | ScaleLinear<number, number>\n | ScaleTime<number, number>\n | ScaleLogarithmic<number, number>\n | ScalePower<number, number>\n | ScaleSymLog<number, number>;\n\n/** Discretizing D3 scales (quantile, quantize, threshold). */\nexport type D3DiscretizingScale =\n | ScaleQuantile<number>\n | ScaleQuantize<number>\n | ScaleThreshold<number, number>;\n\n/** Categorical D3 scales (band, point, ordinal) that support .domain() as string[]. */\nexport type D3CategoricalScale =\n | ScaleBand<string>\n | ScalePoint<string>\n | ScaleOrdinal<string, string>;\n\n/** Union of all D3 scale types used by the engine. */\nexport type D3Scale = D3ContinuousScale | D3CategoricalScale | D3DiscretizingScale;\n\n/** A sequential color scale mapping numbers to color strings. */\nexport type D3SequentialColorScale = ScaleLinear<string, string>;\n\n/** All resolved scale type identifiers. */\nexport type ResolvedScaleType = ScaleType | 'sequential';\n\n/**\n * A resolved scale wrapping a d3 scale with type metadata.\n * We need to carry the scale type around so axes and marks know\n * how to interpret the domain/range. Consumers use the `type` discriminant\n * to determine which D3 methods are available on the scale.\n */\nexport interface ResolvedScale {\n /** The d3 scale function. Maps domain value -> pixel position or color. */\n scale: D3Scale;\n /** The scale type for downstream use. */\n type: ResolvedScaleType;\n /** The encoding channel this scale was derived from. */\n channel: EncodingChannel;\n}\n\n/** All resolved scales for a chart. */\nexport interface ResolvedScales {\n x?: ResolvedScale;\n y?: ResolvedScale;\n color?: ResolvedScale;\n size?: ResolvedScale;\n /** Default color for single-series charts (first categorical palette color or markDef.fill gradient). */\n defaultColor?: string | import('@opendata-ai/openchart-core').GradientDef;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Extract all non-null values for a field from data. */\nfunction fieldValues(data: DataRow[], field: string): unknown[] {\n return data.map((d) => d[field]).filter((v) => v != null);\n}\n\n/** Parse values to dates. */\nfunction parseDates(values: unknown[]): Date[] {\n return values\n .map((v) => (v instanceof Date ? v : new Date(String(v))))\n .filter((d) => !Number.isNaN(d.getTime()));\n}\n\n/** Parse values to numbers. */\nfunction parseNumbers(values: unknown[]): number[] {\n return values\n .map((v) => (typeof v === 'number' ? v : Number(v)))\n .filter((n) => Number.isFinite(n));\n}\n\n/** Get unique string values preserving order. */\nfunction uniqueStrings(values: unknown[]): string[] {\n const seen = new Set<string>();\n const result: string[] = [];\n for (const v of values) {\n const s = String(v);\n if (!seen.has(s)) {\n seen.add(s);\n result.push(s);\n }\n }\n return result;\n}\n\n/**\n * Apply sort order to categorical domain values.\n * - 'ascending': sort alphabetically/numerically ascending\n * - 'descending': sort descending\n * - null | undefined: preserve data order (no sorting)\n */\nfunction applyCategoricalSort(\n values: string[],\n sort: 'ascending' | 'descending' | null | undefined,\n): string[] {\n if (!sort) return values;\n\n const sorted = [...values].sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));\n if (sort === 'descending') sorted.reverse();\n return sorted;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers: apply common scale config\n// ---------------------------------------------------------------------------\n\n/** Apply clamp and reverse config to a continuous scale. */\nfunction applyContinuousConfig(\n scale: { clamp(v: boolean): unknown; range(): number[]; range(r: number[]): unknown },\n channel: EncodingChannel,\n): void {\n if (channel.scale?.clamp) {\n scale.clamp(true);\n }\n if (channel.scale?.reverse) {\n const [r0, r1] = scale.range() as number[];\n scale.range([r1, r0]);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Scale builders\n// ---------------------------------------------------------------------------\n\nfunction buildTimeScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseDates(fieldValues(data, channel.field));\n const domain = channel.scale?.domain\n ? [new Date(channel.scale.domain[0] as string), new Date(channel.scale.domain[1] as string)]\n : (extent(values) as [Date, Date]);\n\n const scale = scaleTime().domain(domain).range([rangeStart, rangeEnd]);\n\n // Temporal scales default to nice: false because date data typically starts\n // at clean boundaries and nice() rounds the domain outward, creating visible\n // gaps (e.g. data starting 2018-01-01 gets rounded to 2017-01-01).\n // Users can opt in with scale: { nice: true }.\n if (!channel.scale?.domain && channel.scale?.nice === true) {\n scale.nice();\n }\n applyContinuousConfig(scale, channel);\n\n return { scale, type: 'time', channel };\n}\n\nfunction buildUtcScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseDates(fieldValues(data, channel.field));\n const domain = channel.scale?.domain\n ? [new Date(channel.scale.domain[0] as string), new Date(channel.scale.domain[1] as string)]\n : (extent(values) as [Date, Date]);\n\n const scale = scaleUtc().domain(domain).range([rangeStart, rangeEnd]);\n\n // Temporal scales default to nice: false (see buildTimeScale comment).\n if (!channel.scale?.domain && channel.scale?.nice === true) {\n scale.nice();\n }\n applyContinuousConfig(scale, channel);\n\n return { scale, type: 'utc', channel };\n}\n\nfunction buildLinearScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseNumbers(fieldValues(data, channel.field));\n\n let domainMin: number;\n let domainMax: number;\n\n if (channel.scale?.domain) {\n const [d0, d1] = channel.scale.domain as [number, number];\n domainMin = d0;\n domainMax = d1;\n } else {\n domainMin = min(values) ?? 0;\n domainMax = max(values) ?? 1;\n\n // Include zero by default for quantitative scales\n if (channel.scale?.zero !== false) {\n domainMin = Math.min(0, domainMin);\n domainMax = Math.max(0, domainMax);\n }\n }\n\n const scale = scaleLinear().domain([domainMin, domainMax]).range([rangeStart, rangeEnd]);\n\n if (!channel.scale?.domain && channel.scale?.nice !== false) {\n scale.nice();\n }\n applyContinuousConfig(scale, channel);\n\n return { scale, type: 'linear', channel };\n}\n\nfunction buildLogScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseNumbers(fieldValues(data, channel.field)).filter((v) => v > 0);\n const domainMin = channel.scale?.domain\n ? (channel.scale.domain as [number, number])[0]\n : (min(values) ?? 1);\n const domainMax = channel.scale?.domain\n ? (channel.scale.domain as [number, number])[1]\n : (max(values) ?? 10);\n\n const scale = scaleLog().domain([domainMin, domainMax]).range([rangeStart, rangeEnd]);\n\n if (channel.scale?.base !== undefined) {\n scale.base(channel.scale.base);\n }\n if (!channel.scale?.domain && channel.scale?.nice !== false) {\n scale.nice();\n }\n applyContinuousConfig(scale, channel);\n\n return { scale, type: 'log', channel };\n}\n\nfunction buildPowScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseNumbers(fieldValues(data, channel.field));\n\n let domainMin: number;\n let domainMax: number;\n\n if (channel.scale?.domain) {\n [domainMin, domainMax] = channel.scale.domain as [number, number];\n } else {\n domainMin = min(values) ?? 0;\n domainMax = max(values) ?? 1;\n if (channel.scale?.zero !== false) {\n domainMin = Math.min(0, domainMin);\n domainMax = Math.max(0, domainMax);\n }\n }\n\n const scale = scalePow().domain([domainMin, domainMax]).range([rangeStart, rangeEnd]);\n\n if (channel.scale?.exponent !== undefined) {\n scale.exponent(channel.scale.exponent);\n }\n if (!channel.scale?.domain && channel.scale?.nice !== false) {\n scale.nice();\n }\n applyContinuousConfig(scale, channel);\n\n return { scale, type: 'pow', channel };\n}\n\nfunction buildSqrtScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseNumbers(fieldValues(data, channel.field));\n\n let domainMin: number;\n let domainMax: number;\n\n if (channel.scale?.domain) {\n [domainMin, domainMax] = channel.scale.domain as [number, number];\n } else {\n domainMin = min(values) ?? 0;\n domainMax = max(values) ?? 1;\n if (channel.scale?.zero !== false) {\n domainMin = Math.min(0, domainMin);\n domainMax = Math.max(0, domainMax);\n }\n }\n\n const scale = scaleSqrt().domain([domainMin, domainMax]).range([rangeStart, rangeEnd]);\n\n if (!channel.scale?.domain && channel.scale?.nice !== false) {\n scale.nice();\n }\n applyContinuousConfig(scale, channel);\n\n return { scale, type: 'sqrt', channel };\n}\n\nfunction buildSymlogScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseNumbers(fieldValues(data, channel.field));\n\n let domainMin: number;\n let domainMax: number;\n\n if (channel.scale?.domain) {\n [domainMin, domainMax] = channel.scale.domain as [number, number];\n } else {\n domainMin = min(values) ?? 0;\n domainMax = max(values) ?? 1;\n if (channel.scale?.zero !== false) {\n domainMin = Math.min(0, domainMin);\n domainMax = Math.max(0, domainMax);\n }\n }\n\n const scale = scaleSymlog().domain([domainMin, domainMax]).range([rangeStart, rangeEnd]);\n\n if (channel.scale?.constant !== undefined) {\n scale.constant(channel.scale.constant);\n }\n if (!channel.scale?.domain && channel.scale?.nice !== false) {\n scale.nice();\n }\n applyContinuousConfig(scale, channel);\n\n return { scale, type: 'symlog', channel };\n}\n\nfunction buildQuantileScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseNumbers(fieldValues(data, channel.field));\n const range = channel.scale?.range\n ? (channel.scale.range as number[])\n : evenRange(rangeStart, rangeEnd, 4);\n\n const scale = scaleQuantile<number>().domain(values).range(range);\n\n return { scale: scale as unknown as D3Scale, type: 'quantile', channel };\n}\n\nfunction buildQuantizeScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = parseNumbers(fieldValues(data, channel.field));\n const domainMin = channel.scale?.domain\n ? (channel.scale.domain as [number, number])[0]\n : (min(values) ?? 0);\n const domainMax = channel.scale?.domain\n ? (channel.scale.domain as [number, number])[1]\n : (max(values) ?? 1);\n const range = channel.scale?.range\n ? (channel.scale.range as number[])\n : evenRange(rangeStart, rangeEnd, 4);\n\n const scale = scaleQuantize<number>().domain([domainMin, domainMax]).range(range);\n\n return { scale: scale as unknown as D3Scale, type: 'quantize', channel };\n}\n\nfunction buildThresholdScale(\n channel: EncodingChannel,\n _data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n // Threshold scales require explicit domain breakpoints\n const domainBreaks = channel.scale?.domain ? (channel.scale.domain as number[]) : [0.5];\n const range = channel.scale?.range\n ? (channel.scale.range as number[])\n : evenRange(rangeStart, rangeEnd, domainBreaks.length + 1);\n\n const scale = scaleThreshold<number, number>().domain(domainBreaks).range(range);\n\n return { scale: scale as unknown as D3Scale, type: 'threshold', channel };\n}\n\n/** Generate an evenly-spaced range of `count` values between start and end. */\nfunction evenRange(start: number, end: number, count: number): number[] {\n if (count <= 1) return [start];\n const step = (end - start) / (count - 1);\n return Array.from({ length: count }, (_, i) => start + step * i);\n}\n\nfunction buildBandScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = channel.scale?.domain\n ? (channel.scale.domain as string[])\n : applyCategoricalSort(uniqueStrings(fieldValues(data, channel.field)), channel.sort);\n\n const padding = channel.scale?.padding ?? 0.35;\n const scale = scaleBand().domain(values).range([rangeStart, rangeEnd]).padding(padding);\n\n if (channel.scale?.paddingInner !== undefined) {\n scale.paddingInner(channel.scale.paddingInner);\n }\n if (channel.scale?.paddingOuter !== undefined) {\n scale.paddingOuter(channel.scale.paddingOuter);\n }\n if (channel.scale?.reverse) {\n const [r0, r1] = scale.range();\n scale.range([r1, r0]);\n }\n\n return { scale, type: 'band', channel };\n}\n\nfunction buildPointScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n): ResolvedScale {\n const values = channel.scale?.domain\n ? (channel.scale.domain as string[])\n : applyCategoricalSort(uniqueStrings(fieldValues(data, channel.field)), channel.sort);\n\n const padding = channel.scale?.padding ?? 0.5;\n const scale = scalePoint().domain(values).range([rangeStart, rangeEnd]).padding(padding);\n\n if (channel.scale?.reverse) {\n const [r0, r1] = scale.range();\n scale.range([r1, r0]);\n }\n\n return { scale, type: 'point', channel };\n}\n\nfunction buildOrdinalColorScale(\n channel: EncodingChannel,\n data: DataRow[],\n palette: string[],\n): ResolvedScale {\n // Use explicit domain if provided, otherwise derive from data\n const explicitDomain = channel.scale?.domain as string[] | undefined;\n const values = explicitDomain\n ? explicitDomain.map(String)\n : applyCategoricalSort(uniqueStrings(fieldValues(data, channel.field)), channel.sort);\n\n // Use explicit range if provided, otherwise fall back to theme palette\n const explicitRange = channel.scale?.range as string[] | undefined;\n const colors = explicitRange ?? palette;\n\n const scale = scaleOrdinal<string>().domain(values).range(colors);\n\n return { scale, type: 'ordinal', channel };\n}\n\nfunction buildSequentialColorScale(\n channel: EncodingChannel,\n data: DataRow[],\n palette: string[],\n): ResolvedScale {\n const values = parseNumbers(fieldValues(data, channel.field));\n const domainMin = min(values) ?? 0;\n const domainMax = max(values) ?? 1;\n\n // Use explicit range if provided, otherwise fall back to theme palette endpoints\n const explicitRange = channel.scale?.range as string[] | undefined;\n const colors = explicitRange ?? palette;\n\n const scale = scaleLinear<string>()\n .domain([domainMin, domainMax])\n .range([colors[0], colors[colors.length - 1]])\n .clamp(true);\n\n // Cast: sequential color scale (number -> string) is structurally incompatible\n // with D3Scale (number -> number), but is only ever accessed via scales.color\n // where consumers already cast appropriately.\n return { scale: scale as unknown as D3Scale, type: 'sequential', channel };\n}\n\n// ---------------------------------------------------------------------------\n// Positional scale selection\n// ---------------------------------------------------------------------------\n\n/**\n * Choose the right scale type for a positional channel (x or y).\n * Respects explicit scale.type overrides from the spec.\n */\nfunction buildPositionalScale(\n channel: EncodingChannel,\n data: DataRow[],\n rangeStart: number,\n rangeEnd: number,\n chartType: string,\n axis: 'x' | 'y',\n): ResolvedScale {\n // Explicit scale type override\n if (channel.scale?.type) {\n switch (channel.scale.type) {\n case 'time':\n return buildTimeScale(channel, data, rangeStart, rangeEnd);\n case 'utc':\n return buildUtcScale(channel, data, rangeStart, rangeEnd);\n case 'linear':\n return buildLinearScale(channel, data, rangeStart, rangeEnd);\n case 'log':\n return buildLogScale(channel, data, rangeStart, rangeEnd);\n case 'pow':\n return buildPowScale(channel, data, rangeStart, rangeEnd);\n case 'sqrt':\n return buildSqrtScale(channel, data, rangeStart, rangeEnd);\n case 'symlog':\n return buildSymlogScale(channel, data, rangeStart, rangeEnd);\n case 'quantile':\n return buildQuantileScale(channel, data, rangeStart, rangeEnd);\n case 'quantize':\n return buildQuantizeScale(channel, data, rangeStart, rangeEnd);\n case 'threshold':\n return buildThresholdScale(channel, data, rangeStart, rangeEnd);\n case 'band':\n return buildBandScale(channel, data, rangeStart, rangeEnd);\n case 'point':\n return buildPointScale(channel, data, rangeStart, rangeEnd);\n case 'ordinal':\n return buildBandScale(channel, data, rangeStart, rangeEnd);\n }\n }\n\n // Infer from field type\n switch (channel.type) {\n case 'temporal':\n return buildTimeScale(channel, data, rangeStart, rangeEnd);\n case 'quantitative':\n return buildLinearScale(channel, data, rangeStart, rangeEnd);\n case 'nominal':\n case 'ordinal':\n // Bar charts use band scales for their categorical axis (both orientations)\n if (\n chartType === 'bar' ||\n ((chartType === 'circle' || chartType === 'lollipop') && axis === 'y')\n ) {\n return buildBandScale(channel, data, rangeStart, rangeEnd);\n }\n return buildPointScale(channel, data, rangeStart, rangeEnd);\n default:\n return buildLinearScale(channel, data, rangeStart, rangeEnd);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute D3 scales from encoding channels and data.\n *\n * @param spec - Normalized chart spec.\n * @param chartArea - The computed chart drawing area.\n * @param data - Data rows.\n * @returns ResolvedScales with d3 scale instances.\n */\nexport function computeScales(\n spec: NormalizedChartSpec,\n chartArea: Rect,\n data: DataRow[],\n): ResolvedScales {\n const result: ResolvedScales = {};\n const encoding = spec.encoding as Encoding;\n\n // Scatter/bubble charts should NOT include zero by default (tight domain fits data range)\n if (spec.markType === 'point') {\n if (encoding.x?.type === 'quantitative' && encoding.x.scale?.zero === undefined) {\n if (!encoding.x.scale) {\n (encoding.x as { scale?: Record<string, unknown> }).scale = { zero: false };\n } else {\n (encoding.x.scale as Record<string, unknown>).zero = false;\n }\n }\n if (encoding.y?.type === 'quantitative' && encoding.y.scale?.zero === undefined) {\n if (!encoding.y.scale) {\n (encoding.y as { scale?: Record<string, unknown> }).scale = { zero: false };\n } else {\n (encoding.y.scale as Record<string, unknown>).zero = false;\n }\n }\n }\n\n if (encoding.x) {\n // For stacked bars, the x-domain needs the max category sum, not max individual value.\n // Without this, stacked bars would clip past the chart area.\n let xData = data;\n let xChannel = encoding.x;\n const xStackDisabled = encoding.x.stack === null || encoding.x.stack === false;\n if (\n spec.markType === 'bar' &&\n encoding.color &&\n encoding.x.type === 'quantitative' &&\n !xStackDisabled\n ) {\n if (encoding.x.stack === 'normalize') {\n // Normalize: domain is [0, 1]\n xChannel = { ...encoding.x, scale: { ...encoding.x.scale, domain: [0, 1], nice: false } };\n } else if (encoding.x.stack === 'center') {\n // Center: compute max half-sum for symmetric domain\n const yField = encoding.y?.field;\n const xField = encoding.x.field;\n if (yField) {\n const sums = new Map<string, number>();\n for (const row of data) {\n const cat = String(row[yField] ?? '');\n const val = Number(row[xField] ?? 0);\n if (Number.isFinite(val) && val > 0) {\n sums.set(cat, (sums.get(cat) ?? 0) + val);\n }\n }\n const maxSum = Math.max(...sums.values(), 0);\n const half = maxSum / 2;\n xChannel = {\n ...encoding.x,\n scale: { ...encoding.x.scale, domain: [-half, half], zero: true },\n };\n }\n } else {\n // Zero (default): domain extends to max category sum\n const yField = encoding.y?.field;\n const xField = encoding.x.field;\n if (yField) {\n const sums = new Map<string, number>();\n for (const row of data) {\n const cat = String(row[yField] ?? '');\n const val = Number(row[xField] ?? 0);\n if (Number.isFinite(val) && val > 0) {\n sums.set(cat, (sums.get(cat) ?? 0) + val);\n }\n }\n const maxSum = Math.max(...sums.values(), 0);\n // Create a synthetic row with the max stack sum so buildLinearScale sees it\n xData = [...data, { [xField]: maxSum } as DataRow];\n }\n }\n }\n\n result.x = buildPositionalScale(\n xChannel,\n xData,\n chartArea.x,\n chartArea.x + chartArea.width,\n spec.markType,\n 'x',\n );\n }\n\n if (encoding.y) {\n // For stacked vertical bars and stacked areas, the y-domain needs the max\n // category sum, not the max individual value. Without this, stacked marks\n // would clip above the chart area.\n // Vertical bar = x is categorical and y is quantitative (old 'column' chart type).\n let yData = data;\n let yChannel = encoding.y;\n const isVerticalBar =\n spec.markType === 'bar' &&\n (encoding.x?.type === 'nominal' || encoding.x?.type === 'ordinal') &&\n encoding.y.type === 'quantitative';\n const yStackDisabled = encoding.y.stack === null || encoding.y.stack === false;\n if (\n (isVerticalBar || spec.markType === 'area') &&\n encoding.color &&\n encoding.y.type === 'quantitative' &&\n !yStackDisabled\n ) {\n if (encoding.y.stack === 'normalize') {\n // Normalize: domain is [0, 1] (VL convention)\n yChannel = { ...encoding.y, scale: { ...encoding.y.scale, domain: [0, 1], nice: false } };\n } else if (encoding.y.stack === 'center') {\n // Center: compute max half-sum for symmetric domain\n const xField = encoding.x?.field;\n const yField = encoding.y.field;\n if (xField) {\n const sums = new Map<string, number>();\n for (const row of data) {\n const cat = String(row[xField] ?? '');\n const val = Number(row[yField] ?? 0);\n if (Number.isFinite(val) && val > 0) {\n sums.set(cat, (sums.get(cat) ?? 0) + val);\n }\n }\n const maxSum = Math.max(...sums.values(), 0);\n const half = maxSum / 2;\n yChannel = {\n ...encoding.y,\n scale: { ...encoding.y.scale, domain: [-half, half], zero: true },\n };\n }\n } else {\n // Zero (default): domain extends to max category sum\n const xField = encoding.x?.field;\n const yField = encoding.y.field;\n if (xField) {\n const sums = new Map<string, number>();\n for (const row of data) {\n const cat = String(row[xField] ?? '');\n const val = Number(row[yField] ?? 0);\n if (Number.isFinite(val) && val > 0) {\n sums.set(cat, (sums.get(cat) ?? 0) + val);\n }\n }\n const maxSum = Math.max(...sums.values(), 0);\n // Create a synthetic row with the max stack sum so buildLinearScale sees it\n yData = [...data, { [yField]: maxSum } as DataRow];\n }\n }\n }\n\n // Y axis: range is inverted (SVG y goes down, data y goes up)\n result.y = buildPositionalScale(\n yChannel,\n yData,\n chartArea.y + chartArea.height,\n chartArea.y,\n spec.markType,\n 'y',\n );\n }\n\n if (encoding.color) {\n const defaultPalette = [\n '#1b7fa3',\n '#c44e52',\n '#6a9f58',\n '#d47215',\n '#507e79',\n '#9a6a8d',\n '#c4636b',\n '#9c755f',\n '#a88f22',\n '#858078',\n ];\n\n // Only build color scales for field-based encodings, not conditional value defs\n if ('field' in encoding.color) {\n if (encoding.color.type === 'quantitative') {\n // Sequential color scale for value-based coloring\n result.color = buildSequentialColorScale(encoding.color, data, defaultPalette);\n } else {\n // Categorical color scale for nominal/ordinal grouping\n result.color = buildOrdinalColorScale(encoding.color, data, defaultPalette);\n }\n }\n }\n\n return result;\n}\n","/**\n * Legend computation.\n *\n * Derives legend entries from the color encoding's unique values in data,\n * computes position based on layout strategy, and returns a LegendLayout\n * that dimensions.ts uses to reserve space in the chart area.\n *\n * The legend is computed early (before marks) so the chartArea accounts\n * for legend space. Entries come from data + encoding, not marks.\n *\n * Overflow protection: when there are too many entries for the available\n * space, entries are truncated and a \"+N more\" indicator is appended.\n */\n\nimport type {\n LayoutStrategy,\n LegendEntry,\n LegendLayout,\n Rect,\n ResolvedTheme,\n TextStyle,\n} from '@opendata-ai/openchart-core';\nimport { BRAND_RESERVE_WIDTH, estimateTextWidth } from '@opendata-ai/openchart-core';\n\nimport type { NormalizedChartSpec } from '../compiler/types';\nimport { ENTRY_GAP, measureLegendWrap, SWATCH_GAP, SWATCH_SIZE } from './wrap';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst LEGEND_PADDING = 8;\nconst LEGEND_RIGHT_WIDTH = 120;\n\n/** Max fraction of chart area height for right-positioned legends. */\nconst RIGHT_LEGEND_MAX_HEIGHT_RATIO = 0.4;\n\n/** Max number of rows for top-positioned legends before truncation. */\nconst TOP_LEGEND_MAX_ROWS = 2;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Determine the swatch shape based on mark type. */\nfunction swatchShapeForType(markType: string): LegendEntry['shape'] {\n switch (markType) {\n case 'line':\n return 'line';\n case 'point':\n case 'circle':\n case 'lollipop':\n return 'circle';\n default:\n return 'square';\n }\n}\n\n/** Extract unique color values from data based on the color encoding. */\nfunction extractColorEntries(spec: NormalizedChartSpec, theme: ResolvedTheme): LegendEntry[] {\n const colorEnc = spec.encoding.color;\n if (!colorEnc) return [];\n\n // Conditional color definitions don't produce legend entries\n if ('condition' in colorEnc) return [];\n\n // Sequential (quantitative) color doesn't produce discrete legend entries\n if (colorEnc.type === 'quantitative') return [];\n\n const uniqueValues = [...new Set(spec.data.map((d) => String(d[colorEnc.field])))];\n const explicitDomain = colorEnc.scale?.domain as string[] | undefined;\n const explicitRange = colorEnc.scale?.range as string[] | undefined;\n const palette = explicitRange ?? theme.colors.categorical;\n const shape = swatchShapeForType(spec.markType);\n\n return uniqueValues.map((value, i) => {\n // When explicit domain+range are provided, look up the color by domain index\n // so legend colors match the mark colors exactly.\n let colorIndex = i;\n if (explicitDomain && explicitRange) {\n const domainIdx = explicitDomain.indexOf(value);\n if (domainIdx >= 0) colorIndex = domainIdx;\n }\n return {\n label: value,\n color: palette[colorIndex % palette.length],\n shape,\n active: true,\n };\n });\n}\n\n/**\n * Truncate entries and add a \"+N more\" indicator if needed.\n */\nfunction truncateEntries(entries: LegendEntry[], maxCount: number): LegendEntry[] {\n if (maxCount >= entries.length || maxCount <= 0) return entries;\n\n const truncated = entries.slice(0, maxCount);\n const remaining = entries.length - maxCount;\n truncated.push({\n label: `+${remaining} more`,\n color: '#999999',\n shape: 'square',\n active: false,\n overflow: true,\n });\n\n return truncated;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute legend layout for a chart spec.\n *\n * @param spec - Normalized chart spec.\n * @param strategy - Responsive layout strategy.\n * @param theme - Resolved theme.\n * @param chartArea - The available chart area (before legend space is reserved).\n * @returns LegendLayout with position, entries, and bounds.\n */\nexport function computeLegend(\n spec: NormalizedChartSpec,\n strategy: LayoutStrategy,\n theme: ResolvedTheme,\n chartArea: Rect,\n watermark: boolean = true,\n): LegendLayout {\n // Legend explicitly hidden via show: false, or height strategy says no legend\n if (spec.legend?.show === false || strategy.legendMaxHeight === 0) {\n return {\n position: 'top',\n entries: [],\n bounds: { x: 0, y: 0, width: 0, height: 0 },\n labelStyle: {\n fontFamily: theme.fonts.family,\n fontSize: theme.fonts.sizes.small,\n fontWeight: theme.fonts.weights.normal,\n fill: theme.colors.text,\n lineHeight: 1.3,\n },\n swatchSize: SWATCH_SIZE,\n swatchGap: SWATCH_GAP,\n entryGap: ENTRY_GAP,\n };\n }\n\n let entries = extractColorEntries(spec, theme);\n\n // Auto-suppress legend when endpoint labels identify series on line/area charts.\n // Guards: keep legend at compact breakpoints (labels hidden), for stacked areas\n // (endpoint labels overlap), and when user explicitly forces legend on.\n const isLineOrArea = spec.markType === 'line' || spec.markType === 'area';\n const hasLabels = spec.labels.density !== 'none';\n const labelsWillRender = strategy.labelMode !== 'none';\n const hasColorEncoding = spec.encoding.color != null;\n const legendNotForced = spec.legend?.show !== true;\n\n if (isLineOrArea && hasLabels && labelsWillRender && hasColorEncoding && legendNotForced) {\n const isArea = spec.markType === 'area';\n const quantChannel =\n spec.encoding.y?.type === 'quantitative' ? spec.encoding.y : spec.encoding.x;\n const stackValue = quantChannel?.stack;\n const isStacked = stackValue !== null && stackValue !== false;\n\n if (!isArea || !isStacked) {\n entries = [];\n }\n }\n\n const labelStyle: TextStyle = {\n fontFamily: theme.fonts.family,\n fontSize: theme.fonts.sizes.small,\n fontWeight: theme.fonts.weights.normal,\n fill: theme.colors.text,\n lineHeight: 1.3,\n };\n\n // Resolve position: spec-level override wins, then responsive strategy\n const resolvedPosition =\n spec.legend?.position ?? (strategy.legendPosition === 'right' ? 'right' : 'top');\n\n // No entries = empty legend with no space\n if (entries.length === 0) {\n return {\n position: resolvedPosition,\n entries: [],\n bounds: { x: 0, y: 0, width: 0, height: 0 },\n labelStyle,\n swatchSize: SWATCH_SIZE,\n swatchGap: SWATCH_GAP,\n entryGap: ENTRY_GAP,\n };\n }\n\n if (resolvedPosition === 'right' || resolvedPosition === 'bottom-right') {\n // Right-positioned legend: vertical stack\n const maxLabelWidth = Math.max(\n ...entries.map((e) => estimateTextWidth(e.label, labelStyle.fontSize, labelStyle.fontWeight)),\n );\n const legendWidth = Math.min(\n LEGEND_RIGHT_WIDTH,\n SWATCH_SIZE + SWATCH_GAP + maxLabelWidth + LEGEND_PADDING * 2,\n );\n const entryHeight = Math.max(SWATCH_SIZE, labelStyle.fontSize * labelStyle.lineHeight);\n\n // Apply max height ratio (default 40% of chart area, strategy can override)\n const maxHeightRatio =\n strategy.legendMaxHeight > 0 ? strategy.legendMaxHeight : RIGHT_LEGEND_MAX_HEIGHT_RATIO;\n const maxLegendHeight = chartArea.height * maxHeightRatio;\n\n // Calculate how many entries fit\n const maxFromSpace = Math.max(\n 1,\n Math.floor((maxLegendHeight - LEGEND_PADDING * 2) / (entryHeight + 4)),\n );\n // symbolLimit overrides the space-based limit when explicitly set (minimum 1)\n const maxEntries =\n spec.legend?.symbolLimit != null ? Math.max(1, spec.legend.symbolLimit) : maxFromSpace;\n if (entries.length > maxEntries) {\n entries = truncateEntries(entries, maxEntries);\n }\n\n const legendHeight =\n entries.length * entryHeight + (entries.length - 1) * 4 + LEGEND_PADDING * 2;\n const clampedHeight = Math.min(legendHeight, chartArea.height);\n\n // bottom-right anchors to the bottom of the chart area\n const legendY =\n resolvedPosition === 'bottom-right'\n ? chartArea.y + chartArea.height - clampedHeight\n : chartArea.y;\n\n // Apply user-provided legend offset\n const offsetDx = spec.legend?.offset?.dx ?? 0;\n const offsetDy = spec.legend?.offset?.dy ?? 0;\n\n return {\n position: resolvedPosition,\n entries,\n bounds: {\n x: chartArea.x + chartArea.width - legendWidth + offsetDx,\n y: legendY + offsetDy,\n width: legendWidth,\n height: clampedHeight,\n },\n labelStyle,\n swatchSize: SWATCH_SIZE,\n swatchGap: SWATCH_GAP,\n entryGap: 4,\n };\n }\n\n // Top/bottom-positioned legend: horizontal flow with overflow protection.\n // Reserve space on the right for bottom legends so they don't overlap the brand\n // watermark. Top legends don't need this since the brand renders at the bottom.\n const reserveBrand = watermark && resolvedPosition === 'bottom';\n const availableWidth =\n chartArea.width - LEGEND_PADDING * 2 - (reserveBrand ? BRAND_RESERVE_WIDTH : 0);\n\n // Apply symbolLimit first if set (minimum 1), then fit remaining entries to available rows.\n if (spec.legend?.symbolLimit != null) {\n const limit = Math.max(1, spec.legend.symbolLimit);\n if (limit < entries.length) {\n entries = truncateEntries(entries, limit);\n }\n }\n\n // Resolve max rows: explicit maxRows wins, then columns-derived, then default.\n const maxRows =\n spec.legend?.maxRows != null\n ? Math.max(1, spec.legend.maxRows)\n : spec.legend?.columns != null\n ? Math.ceil(entries.length / spec.legend.columns)\n : TOP_LEGEND_MAX_ROWS;\n const { fittingCount } = measureLegendWrap(entries, availableWidth, labelStyle, maxRows);\n\n if (fittingCount < entries.length) {\n entries = truncateEntries(entries, fittingCount);\n }\n\n const totalWidth = entries.reduce((sum, entry) => {\n const labelWidth = estimateTextWidth(entry.label, labelStyle.fontSize, labelStyle.fontWeight);\n return sum + SWATCH_SIZE + SWATCH_GAP + labelWidth + ENTRY_GAP;\n }, 0);\n\n // Calculate actual row count for height (recompute after truncation).\n const { rowCount } = measureLegendWrap(entries, availableWidth, labelStyle);\n\n const rowHeight = SWATCH_SIZE + 4;\n const legendHeight = rowCount * rowHeight + LEGEND_PADDING * 2;\n\n // Apply user-provided legend offset\n const offsetDx = spec.legend?.offset?.dx ?? 0;\n const offsetDy = spec.legend?.offset?.dy ?? 0;\n\n return {\n position: resolvedPosition,\n entries,\n bounds: {\n x: chartArea.x + offsetDx,\n y:\n (resolvedPosition === 'bottom'\n ? chartArea.y + chartArea.height - legendHeight\n : chartArea.y) + offsetDy,\n width: Math.min(totalWidth, availableWidth),\n height: legendHeight,\n },\n labelStyle,\n swatchSize: SWATCH_SIZE,\n swatchGap: SWATCH_GAP,\n entryGap: ENTRY_GAP,\n };\n}\n","/**\n * Legend row-wrap geometry.\n *\n * Shared helper for measuring how legend entries flow across horizontal rows\n * when wrapped at a max width. Both the main legend compute and the sankey\n * legend compile use this to size their legends — the main legend uses\n * `fittingCount` for truncation decisions, while sankey uses `rowCount` to\n * reserve vertical height.\n *\n * The geometry matches the existing layout exactly: each entry occupies\n * SWATCH_SIZE + SWATCH_GAP + labelWidth + ENTRY_GAP pixels, a new row is\n * started when the accumulated row width plus the next entry would exceed\n * maxWidth (and the current row is non-empty), and rowWidths captures the\n * in-row accumulated width at the point of wrapping.\n */\n\nimport type { LegendEntry, TextStyle } from '@opendata-ai/openchart-core';\nimport { estimateTextWidth } from '@opendata-ai/openchart-core';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n//\n// Single source of truth for legend row geometry. Both compute.ts and the\n// sankey compile site import these so the wrap math here can never drift from\n// the layout math at the call sites.\n\nexport const SWATCH_SIZE = 12;\nexport const SWATCH_GAP = 6;\nexport const ENTRY_GAP = 16;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport interface LegendWrapResult {\n /** Total number of rows the entries occupy when wrapped at maxWidth. */\n rowCount: number;\n /** Entries that fit within maxRows (for truncation). Equals entries.length when maxRows is not set or all entries fit. */\n fittingCount: number;\n /** Width (in px) of each row — callers can use for alignment. */\n rowWidths: number[];\n}\n\n/**\n * Measure how legend entries wrap across rows at a given max width.\n *\n * @param entries - Legend entries to measure.\n * @param maxWidth - Maximum width (in px) available for a single row.\n * @param labelStyle - Text style used to estimate label widths.\n * @param maxRows - Optional cap used only for the `fittingCount` truncation decision. When provided, `fittingCount` will be the index of the first entry that would spill onto a row beyond `maxRows`. `rowCount` is always the real row count regardless of this cap.\n */\nexport function measureLegendWrap(\n entries: LegendEntry[],\n maxWidth: number,\n labelStyle: TextStyle,\n maxRows?: number,\n): LegendWrapResult {\n if (entries.length === 0) {\n return { rowCount: 0, fittingCount: 0, rowWidths: [] };\n }\n\n let rowCount = 1;\n let rowWidth = 0;\n const rowWidths: number[] = [];\n let fittingCount = entries.length;\n let fittingCountLocked = false;\n\n for (let i = 0; i < entries.length; i++) {\n const labelWidth = estimateTextWidth(\n entries[i].label,\n labelStyle.fontSize,\n labelStyle.fontWeight,\n );\n const entryWidth = SWATCH_SIZE + SWATCH_GAP + labelWidth + ENTRY_GAP;\n\n if (rowWidth + entryWidth > maxWidth && rowWidth > 0) {\n rowWidths.push(rowWidth);\n rowCount++;\n rowWidth = entryWidth;\n if (!fittingCountLocked && maxRows != null && rowCount > maxRows) {\n fittingCount = i;\n fittingCountLocked = true;\n }\n } else {\n rowWidth += entryWidth;\n }\n }\n\n // Flush the final row width so rowWidths has one entry per row.\n rowWidths.push(rowWidth);\n\n return { rowCount, fittingCount, rowWidths };\n}\n","/**\n * Sankey diagram compilation pipeline.\n *\n * Takes a raw sankey spec (unknown shape), validates, normalizes, resolves\n * theme, computes chrome, runs d3-sankey layout, builds marks with colors\n * and labels, and returns a SankeyLayout.\n *\n * Pipeline:\n * validate -> normalize -> resolve theme -> dark mode adapt ->\n * compute chrome -> compute drawing area -> d3-sankey layout ->\n * build node marks -> build link marks -> legend -> tooltips ->\n * a11y -> animation -> return SankeyLayout\n */\n\nimport type {\n CompileOptions,\n LegendEntry,\n LegendLayout,\n Rect,\n ResolvedAnimation,\n ResolvedTheme,\n SankeyLayout,\n SankeyLinkMark,\n SankeyNodeMark,\n TextStyle,\n TooltipContent,\n TooltipField,\n} from '@opendata-ai/openchart-core';\nimport {\n adaptTheme,\n buildD3Formatter,\n computeChrome,\n estimateTextWidth,\n formatNumber,\n resolveTheme,\n} from '@opendata-ai/openchart-core';\n\nimport { resolveAnimation } from '../compiler/animation';\nimport { compile as compileSpec } from '../compiler/index';\nimport { ENTRY_GAP, measureLegendWrap, SWATCH_GAP, SWATCH_SIZE } from '../legend/wrap';\nimport { type ComputedNode, computeSankeyLayout, generateLinkPath } from './layout';\nimport type { NormalizedSankeySpec } from './types';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst LABEL_GAP = 6;\nconst LINK_OPACITY_LIGHT = 0.5;\nconst LINK_OPACITY_DARK = 0.75;\nconst NODE_CORNER_RADIUS = 2;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Assign a color from the categorical palette, cycling through it. */\nfunction pickColor(palette: string[], index: number): string {\n return palette[index % palette.length];\n}\n\n/**\n * Build a color map for nodes.\n * If encoding.color is specified, groups by that field's value.\n * Otherwise, assigns by unique node ID cycling the palette.\n * Accepts any array with `id` field (works with ComputedNode[] or plain objects).\n */\nfunction buildNodeColorMap(\n nodes: Array<{ id: string }>,\n palette: string[],\n colorField: string | undefined,\n data: Record<string, unknown>[],\n sourceField: string,\n targetField: string,\n): Map<string, string> {\n const colorMap = new Map<string, string>();\n\n if (colorField) {\n // Build a mapping from node ID to color category value\n const nodeCategoryMap = new Map<string, string>();\n for (const row of data) {\n const src = String(row[sourceField]);\n const tgt = String(row[targetField]);\n const cat = String(row[colorField]);\n if (!nodeCategoryMap.has(src)) nodeCategoryMap.set(src, cat);\n if (!nodeCategoryMap.has(tgt)) nodeCategoryMap.set(tgt, cat);\n }\n\n // Assign colors by unique category\n const categoryIndex = new Map<string, number>();\n let nextIdx = 0;\n for (const node of nodes) {\n const category = nodeCategoryMap.get(node.id) ?? node.id;\n if (!categoryIndex.has(category)) {\n categoryIndex.set(category, nextIdx++);\n }\n colorMap.set(node.id, pickColor(palette, categoryIndex.get(category)!));\n }\n } else {\n // Default: assign colors cycling through palette by node order\n for (let i = 0; i < nodes.length; i++) {\n colorMap.set(nodes[i].id, pickColor(palette, i));\n }\n }\n\n return colorMap;\n}\n\n/**\n * Get colors for a link based on the linkStyle strategy.\n */\nfunction getLinkColors(\n linkStyle: string,\n sourceColor: string,\n targetColor: string,\n neutralColor: string,\n): { sourceColor: string; targetColor: string } {\n switch (linkStyle) {\n case 'source':\n return { sourceColor, targetColor: sourceColor };\n case 'target':\n return { sourceColor: targetColor, targetColor };\n case 'neutral':\n return { sourceColor: neutralColor, targetColor: neutralColor };\n default:\n return { sourceColor, targetColor };\n }\n}\n\n/**\n * Determine label position for a node based on its column depth.\n * Default ('auto'): leftmost/middle columns label right, rightmost column labels left.\n * 'right': all labels to the right. 'left': all labels to the left.\n */\nfunction computeNodeLabel(\n node: ComputedNode,\n maxDepth: number,\n theme: ResolvedTheme,\n nodeWidth: number,\n nodeLabelAlign: 'auto' | 'left' | 'right' = 'auto',\n containerWidth?: number,\n padding?: number,\n): SankeyNodeMark['label'] {\n const depth = node.depth ?? 0;\n\n // Determine which side to place the label\n let placeLeft: boolean;\n if (nodeLabelAlign === 'left') {\n placeLeft = true;\n } else if (nodeLabelAlign === 'right') {\n placeLeft = false;\n } else {\n // 'auto': rightmost column goes left, everything else goes right\n placeLeft = depth === maxDepth;\n }\n\n const style: TextStyle = {\n fontFamily: theme.fonts.family,\n fontSize: theme.fonts.sizes.small,\n fontWeight: theme.fonts.weights.normal,\n fill: theme.colors.text,\n lineHeight: 1.3,\n };\n\n const x0 = node.x0 ?? 0;\n const x1 = node.x1 ?? nodeWidth;\n const y0 = node.y0 ?? 0;\n const y1 = node.y1 ?? 0;\n const midY = (y0 + y1) / 2;\n\n // Compute maxWidth: space from label position to the container edge\n const pad = padding ?? 0;\n let maxWidth: number | undefined;\n if (containerWidth !== undefined) {\n if (placeLeft) {\n // Label goes left from x0: available space is from left padding to x0\n maxWidth = x0 - LABEL_GAP - pad;\n } else {\n // Label goes right from x1: available space is from x1 to right edge\n maxWidth = containerWidth - pad - (x1 + LABEL_GAP);\n }\n if (maxWidth !== undefined && maxWidth < 0) maxWidth = 0;\n }\n\n if (placeLeft) {\n return {\n text: node.label ?? node.id,\n x: x0 - LABEL_GAP,\n y: midY,\n style: { ...style, textAnchor: 'end', dominantBaseline: 'central' },\n visible: true,\n maxWidth,\n };\n }\n\n return {\n text: node.label ?? node.id,\n x: x1 + LABEL_GAP,\n y: midY,\n style: { ...style, textAnchor: 'start', dominantBaseline: 'central' },\n visible: true,\n maxWidth,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a sankey spec into a SankeyLayout.\n *\n * @param spec - Raw sankey spec (validated at runtime).\n * @param options - Compile options (width, height, theme, darkMode).\n * @returns SankeyLayout with all computed positions and visual properties.\n * @throws Error if spec is invalid or not a sankey type.\n */\nexport function compileSankey(spec: unknown, options: CompileOptions): SankeyLayout {\n // 1. Validate + normalize via the shared compiler pipeline\n const { spec: normalized } = compileSpec(spec);\n\n if (!('type' in normalized) || normalized.type !== 'sankey') {\n throw new Error(\n 'compileSankey received a non-sankey spec. Use compileChart, compileTable, or compileGraph instead.',\n );\n }\n\n const sankeySpec = normalized as NormalizedSankeySpec;\n\n // Resolve watermark: explicit spec value wins, then options fallback, then default true.\n const rawWatermark = (spec as Record<string, unknown>).watermark;\n const watermark = rawWatermark !== undefined ? sankeySpec.watermark : (options.watermark ?? true);\n\n // 2. Resolve theme\n const mergedThemeConfig = options.theme\n ? { ...sankeySpec.theme, ...options.theme }\n : sankeySpec.theme;\n const lightTheme: ResolvedTheme = resolveTheme(mergedThemeConfig);\n let theme: ResolvedTheme = lightTheme;\n if (options.darkMode) {\n theme = adaptTheme(theme);\n // Sankey nodes and link gradients need vivid colors that stand out on dark\n // backgrounds. The adapted palette preserves contrast ratios designed for\n // text, but those contrast-matched colors are too dark for filled shapes.\n // Use the original light-theme categorical palette for node/link colors.\n theme = {\n ...theme,\n colors: { ...theme.colors, categorical: lightTheme.colors.categorical },\n };\n }\n\n // 3. Compute chrome\n const chrome = computeChrome(\n {\n title: sankeySpec.chrome.title,\n subtitle: sankeySpec.chrome.subtitle,\n source: sankeySpec.chrome.source,\n byline: sankeySpec.chrome.byline,\n footer: sankeySpec.chrome.footer,\n },\n theme,\n options.width,\n options.measureText,\n 'full',\n undefined,\n watermark,\n );\n\n // 4. Compute drawing area (total space minus chrome)\n const padding = theme.spacing.padding;\n const fullArea: Rect = {\n x: padding,\n y: padding + chrome.topHeight,\n width: options.width - padding * 2,\n height: options.height - chrome.topHeight - chrome.bottomHeight - padding * 2,\n };\n\n // Guard against negative dimensions\n if (fullArea.width <= 0 || fullArea.height <= 0) {\n return emptyLayout(fullArea, chrome, theme, options, watermark);\n }\n\n // 5. Extract encoding fields\n const sourceField = sankeySpec.encoding.source.field;\n const targetField = sankeySpec.encoding.target.field;\n const valueField = sankeySpec.encoding.value.field;\n const colorField = sankeySpec.encoding.color?.field;\n\n // 5b. Pre-compute legend to reserve vertical space\n // We need the color map first, so build a temporary one from raw data\n const tempNodeIds = new Set<string>();\n for (const row of sankeySpec.data) {\n tempNodeIds.add(String(row[sourceField]));\n tempNodeIds.add(String(row[targetField]));\n }\n const tempColorMap = buildNodeColorMap(\n [...tempNodeIds].map((id) => ({ id })),\n theme.colors.categorical,\n colorField,\n sankeySpec.data,\n sourceField,\n targetField,\n );\n const legend = buildSankeyLegend(\n tempColorMap,\n colorField,\n sankeySpec.data,\n sourceField,\n targetField,\n theme,\n fullArea,\n );\n\n // Reserve legend space by shrinking the drawing area\n const legendGap = legend.entries.length > 0 ? 4 : 0;\n const area: Rect = {\n x: fullArea.x,\n y: fullArea.y + legend.bounds.height + legendGap,\n width: fullArea.width,\n height: fullArea.height - legend.bounds.height - legendGap,\n };\n\n if (area.height <= 0) {\n return emptyLayout(area, chrome, theme, options, watermark);\n }\n\n // 6. Run d3-sankey layout (may re-run once if labels overflow)\n const labelFontSize = theme.fonts.sizes.small;\n const labelFontWeight = theme.fonts.weights.normal;\n const nodeWidth = sankeySpec.nodeWidth ?? 12;\n\n let layoutArea: Rect = { ...area };\n let { nodes, links } = computeSankeyLayout(\n sankeySpec.data,\n sourceField,\n targetField,\n valueField,\n layoutArea,\n sankeySpec.nodeWidth,\n sankeySpec.nodePadding,\n sankeySpec.nodeAlign,\n sankeySpec.iterations,\n sankeySpec.nodeSort,\n );\n\n // 6b. Check if any right-side node labels overflow the right edge.\n const nodeLabelAlign = sankeySpec.nodeLabelAlign ?? 'auto';\n const maxDepthFirst = nodes.reduce((max, n) => Math.max(max, n.depth ?? 0), 0);\n const rightEdge = area.x + area.width;\n let maxOverflow = 0;\n for (const node of nodes) {\n const depth = node.depth ?? 0;\n // Skip nodes whose labels go left (they can't overflow the right edge)\n const labelsLeft =\n nodeLabelAlign === 'left' || (nodeLabelAlign === 'auto' && depth === maxDepthFirst);\n if (labelsLeft) continue;\n const labelX = (node.x1 ?? nodeWidth) + LABEL_GAP;\n const labelText = node.label ?? node.id;\n const labelWidth = estimateTextWidth(labelText, labelFontSize, labelFontWeight);\n const overflow = labelX + labelWidth - rightEdge;\n if (overflow > maxOverflow) maxOverflow = overflow;\n }\n\n // Re-run layout with tighter width if labels would clip\n if (maxOverflow > 0) {\n const margin = Math.ceil(maxOverflow) + 4; // small extra buffer\n layoutArea = {\n x: area.x,\n y: area.y,\n width: Math.max(area.width - margin, 40),\n height: area.height,\n };\n ({ nodes, links } = computeSankeyLayout(\n sankeySpec.data,\n sourceField,\n targetField,\n valueField,\n layoutArea,\n sankeySpec.nodeWidth,\n sankeySpec.nodePadding,\n sankeySpec.nodeAlign,\n sankeySpec.iterations,\n sankeySpec.nodeSort,\n ));\n }\n\n // 7. Build node color map\n const nodeColorMap = buildNodeColorMap(\n nodes,\n theme.colors.categorical,\n colorField,\n sankeySpec.data,\n sourceField,\n targetField,\n );\n\n // 8. Compute max depth for label positioning\n const maxDepth = nodes.reduce((max, n) => Math.max(max, n.depth ?? 0), 0);\n\n // 9. Build SankeyNodeMark[]\n const nodeMarks: SankeyNodeMark[] = nodes.map((node) => {\n const fill = nodeColorMap.get(node.id) ?? theme.colors.categorical[0];\n const depth = node.depth ?? 0;\n\n return {\n type: 'sankeyNode' as const,\n x: node.x0 ?? 0,\n y: node.y0 ?? 0,\n width: (node.x1 ?? 0) - (node.x0 ?? 0),\n height: (node.y1 ?? 0) - (node.y0 ?? 0),\n fill,\n cornerRadius: NODE_CORNER_RADIUS,\n label: computeNodeLabel(\n node,\n maxDepth,\n theme,\n sankeySpec.nodeWidth,\n nodeLabelAlign,\n options.width,\n padding,\n ),\n nodeId: node.id,\n value: node.value ?? 0,\n depth,\n data: { id: node.id, label: node.label },\n aria: {\n role: 'img',\n label: `${node.label}: ${formatFlowValue(node.value ?? 0, sankeySpec.valueFormat)}`,\n },\n animationIndex: 0, // Reassigned below after sorting by depth\n };\n });\n\n // 10. Assign node animation indices by column (left-to-right, top-to-bottom within column)\n nodeMarks.sort((a, b) => a.depth - b.depth || a.y - b.y);\n for (let i = 0; i < nodeMarks.length; i++) {\n nodeMarks[i].animationIndex = i;\n }\n\n // 11. Build SankeyLinkMark[]\n const neutralColor = theme.colors.gridline;\n const linkMarks: SankeyLinkMark[] = links.map((link, i) => {\n const sourceNode = link.source as ComputedNode;\n const targetNode = link.target as ComputedNode;\n const srcColor = nodeColorMap.get(sourceNode.id) ?? theme.colors.categorical[0];\n const tgtColor = nodeColorMap.get(targetNode.id) ?? theme.colors.categorical[0];\n const colors = getLinkColors(sankeySpec.linkStyle, srcColor, tgtColor, neutralColor);\n\n return {\n type: 'sankeyLink' as const,\n path: generateLinkPath(link),\n sourceColor: colors.sourceColor,\n targetColor: colors.targetColor,\n fillOpacity:\n sankeySpec.linkOpacity ?? (options.darkMode ? LINK_OPACITY_DARK : LINK_OPACITY_LIGHT),\n sourceId: sourceNode.id,\n targetId: targetNode.id,\n width: link.width ?? 0,\n value: link.value,\n data: (link as unknown as { data: Record<string, unknown> }).data ?? {},\n aria: {\n role: 'img',\n label: `${sourceNode.label} to ${targetNode.label}: ${formatFlowValue(link.value, sankeySpec.valueFormat)}`,\n },\n // Links animate after nodes\n animationIndex: nodeMarks.length + i,\n };\n });\n\n // 12. Rebuild legend with final color map (temp map may differ in node order)\n const finalLegend = buildSankeyLegend(\n nodeColorMap,\n colorField,\n sankeySpec.data,\n sourceField,\n targetField,\n theme,\n fullArea,\n );\n\n // 13. Build tooltip descriptors\n const tooltipDescriptors = buildTooltipDescriptors(nodeMarks, linkMarks, sankeySpec.valueFormat);\n\n // 14. Build a11y metadata\n const a11y = {\n altText: `Sankey diagram with ${nodeMarks.length} nodes and ${linkMarks.length} links`,\n dataTableFallback: linkMarks.map((l) => [l.sourceId, l.targetId, String(l.value)]),\n role: 'img',\n keyboardNavigable: nodeMarks.length > 0,\n };\n\n // 15. Resolve animation\n const resolvedAnimation: ResolvedAnimation | undefined = resolveAnimation(sankeySpec.animation);\n\n return {\n area,\n chrome,\n nodes: nodeMarks,\n links: linkMarks,\n legend: finalLegend,\n tooltipDescriptors,\n a11y,\n theme,\n dimensions: {\n width: options.width,\n height: options.height,\n },\n animation: resolvedAnimation,\n watermark,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Legend builder\n// ---------------------------------------------------------------------------\n\nfunction buildSankeyLegend(\n nodeColorMap: Map<string, string>,\n colorField: string | undefined,\n data: Record<string, unknown>[],\n sourceField: string,\n targetField: string,\n theme: ResolvedTheme,\n area: Rect,\n): LegendLayout {\n const labelStyle: TextStyle = {\n fontFamily: theme.fonts.family,\n fontSize: theme.fonts.sizes.small,\n fontWeight: theme.fonts.weights.normal,\n fill: theme.colors.text,\n lineHeight: 1.3,\n };\n\n let entries: LegendEntry[];\n\n if (colorField) {\n // Group by color field value for legend entries\n const categoryColors = new Map<string, string>();\n const nodeCategoryMap = new Map<string, string>();\n for (const row of data) {\n const src = String(row[sourceField]);\n const tgt = String(row[targetField]);\n const cat = String(row[colorField]);\n if (!nodeCategoryMap.has(src)) nodeCategoryMap.set(src, cat);\n if (!nodeCategoryMap.has(tgt)) nodeCategoryMap.set(tgt, cat);\n }\n for (const [nodeId, category] of nodeCategoryMap) {\n if (!categoryColors.has(category)) {\n categoryColors.set(category, nodeColorMap.get(nodeId) ?? theme.colors.categorical[0]);\n }\n }\n\n entries = [...categoryColors.entries()].map(([label, color]) => ({\n label,\n color,\n shape: 'square' as const,\n active: true,\n }));\n } else {\n // No color encoding: no legend needed (nodes are individually colored)\n entries = [];\n }\n\n // Compute bounds for horizontal top legend\n let bounds = { x: 0, y: 0, width: 0, height: 0 };\n\n if (entries.length > 0) {\n const ROW_HEIGHT = SWATCH_SIZE + 4;\n const availableWidth = area.width;\n\n // Compute row count via shared wrap geometry, then cap at 2 rows.\n const { rowCount } = measureLegendWrap(entries, availableWidth, labelStyle);\n const cappedRowCount = Math.min(rowCount, 2);\n const legendHeight = cappedRowCount * ROW_HEIGHT;\n\n bounds = {\n x: area.x,\n y: area.y,\n width: availableWidth,\n height: legendHeight,\n };\n }\n\n return {\n position: 'top',\n entries,\n bounds,\n labelStyle,\n swatchSize: SWATCH_SIZE,\n swatchGap: SWATCH_GAP,\n entryGap: ENTRY_GAP,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Tooltip builder\n// ---------------------------------------------------------------------------\n\nfunction formatFlowValue(value: number, valueFormat?: string): string {\n if (valueFormat) {\n const fmt = buildD3Formatter(valueFormat);\n if (fmt) return fmt(value);\n }\n return formatNumber(value);\n}\n\nfunction buildTooltipDescriptors(\n nodes: SankeyNodeMark[],\n links: SankeyLinkMark[],\n valueFormat?: string,\n): Map<string, TooltipContent> {\n const descriptors = new Map<string, TooltipContent>();\n\n // Node tooltips: keyed by \"node-{nodeId}\" to match renderer data-mark-id\n for (const node of nodes) {\n const fields: TooltipField[] = [\n {\n label: 'Total flow',\n value: formatFlowValue(node.value, valueFormat),\n },\n ];\n descriptors.set(`node-${node.nodeId}`, {\n title: node.label.text,\n fields,\n });\n }\n\n // Link tooltips: keyed by \"link-{sourceId}-{targetId}\" to match renderer data-mark-id\n for (let i = 0; i < links.length; i++) {\n const link = links[i];\n const fields: TooltipField[] = [\n {\n label: 'Flow',\n value: formatFlowValue(link.value, valueFormat),\n },\n ];\n descriptors.set(`link-${link.sourceId}-${link.targetId}-${i}`, {\n title: `${link.sourceId} \\u2192 ${link.targetId}`,\n fields,\n });\n }\n\n return descriptors;\n}\n\n// ---------------------------------------------------------------------------\n// Empty layout fallback\n// ---------------------------------------------------------------------------\n\nfunction emptyLayout(\n area: Rect,\n chrome: ReturnType<typeof computeChrome>,\n theme: ResolvedTheme,\n options: CompileOptions,\n watermark: boolean,\n): SankeyLayout {\n return {\n area,\n chrome,\n nodes: [],\n links: [],\n legend: {\n position: 'top',\n entries: [],\n bounds: { x: 0, y: 0, width: 0, height: 0 },\n labelStyle: {\n fontFamily: theme.fonts.family,\n fontSize: theme.fonts.sizes.small,\n fontWeight: theme.fonts.weights.normal,\n fill: theme.colors.text,\n lineHeight: 1.3,\n },\n swatchSize: SWATCH_SIZE,\n swatchGap: SWATCH_GAP,\n entryGap: ENTRY_GAP,\n },\n tooltipDescriptors: new Map(),\n a11y: {\n altText: 'Empty sankey diagram',\n dataTableFallback: [],\n role: 'img',\n keyboardNavigable: false,\n },\n theme,\n dimensions: {\n width: options.width,\n height: options.height,\n },\n watermark,\n };\n}\n","export default function max(values, valueof) {\n let max;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n }\n return max;\n}\n","export default function min(values, valueof) {\n let min;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n }\n return min;\n}\n","export default function sum(values, valueof) {\n let sum = 0;\n if (valueof === undefined) {\n for (let value of values) {\n if (value = +value) {\n sum += value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if (value = +valueof(value, ++index, values)) {\n sum += value;\n }\n }\n }\n return sum;\n}\n","import {min} from \"d3-array\";\n\nfunction targetDepth(d) {\n return d.target.depth;\n}\n\nexport function left(node) {\n return node.depth;\n}\n\nexport function right(node, n) {\n return n - 1 - node.height;\n}\n\nexport function justify(node, n) {\n return node.sourceLinks.length ? node.depth : n - 1;\n}\n\nexport function center(node) {\n return node.targetLinks.length ? node.depth\n : node.sourceLinks.length ? min(node.sourceLinks, targetDepth) - 1\n : 0;\n}\n","export default function constant(x) {\n return function() {\n return x;\n };\n}\n","import {max, min, sum} from \"d3-array\";\nimport {justify} from \"./align.js\";\nimport constant from \"./constant.js\";\n\nfunction ascendingSourceBreadth(a, b) {\n return ascendingBreadth(a.source, b.source) || a.index - b.index;\n}\n\nfunction ascendingTargetBreadth(a, b) {\n return ascendingBreadth(a.target, b.target) || a.index - b.index;\n}\n\nfunction ascendingBreadth(a, b) {\n return a.y0 - b.y0;\n}\n\nfunction value(d) {\n return d.value;\n}\n\nfunction defaultId(d) {\n return d.index;\n}\n\nfunction defaultNodes(graph) {\n return graph.nodes;\n}\n\nfunction defaultLinks(graph) {\n return graph.links;\n}\n\nfunction find(nodeById, id) {\n const node = nodeById.get(id);\n if (!node) throw new Error(\"missing: \" + id);\n return node;\n}\n\nfunction computeLinkBreadths({nodes}) {\n for (const node of nodes) {\n let y0 = node.y0;\n let y1 = y0;\n for (const link of node.sourceLinks) {\n link.y0 = y0 + link.width / 2;\n y0 += link.width;\n }\n for (const link of node.targetLinks) {\n link.y1 = y1 + link.width / 2;\n y1 += link.width;\n }\n }\n}\n\nexport default function Sankey() {\n let x0 = 0, y0 = 0, x1 = 1, y1 = 1; // extent\n let dx = 24; // nodeWidth\n let dy = 8, py; // nodePadding\n let id = defaultId;\n let align = justify;\n let sort;\n let linkSort;\n let nodes = defaultNodes;\n let links = defaultLinks;\n let iterations = 6;\n\n function sankey() {\n const graph = {nodes: nodes.apply(null, arguments), links: links.apply(null, arguments)};\n computeNodeLinks(graph);\n computeNodeValues(graph);\n computeNodeDepths(graph);\n computeNodeHeights(graph);\n computeNodeBreadths(graph);\n computeLinkBreadths(graph);\n return graph;\n }\n\n sankey.update = function(graph) {\n computeLinkBreadths(graph);\n return graph;\n };\n\n sankey.nodeId = function(_) {\n return arguments.length ? (id = typeof _ === \"function\" ? _ : constant(_), sankey) : id;\n };\n\n sankey.nodeAlign = function(_) {\n return arguments.length ? (align = typeof _ === \"function\" ? _ : constant(_), sankey) : align;\n };\n\n sankey.nodeSort = function(_) {\n return arguments.length ? (sort = _, sankey) : sort;\n };\n\n sankey.nodeWidth = function(_) {\n return arguments.length ? (dx = +_, sankey) : dx;\n };\n\n sankey.nodePadding = function(_) {\n return arguments.length ? (dy = py = +_, sankey) : dy;\n };\n\n sankey.nodes = function(_) {\n return arguments.length ? (nodes = typeof _ === \"function\" ? _ : constant(_), sankey) : nodes;\n };\n\n sankey.links = function(_) {\n return arguments.length ? (links = typeof _ === \"function\" ? _ : constant(_), sankey) : links;\n };\n\n sankey.linkSort = function(_) {\n return arguments.length ? (linkSort = _, sankey) : linkSort;\n };\n\n sankey.size = function(_) {\n return arguments.length ? (x0 = y0 = 0, x1 = +_[0], y1 = +_[1], sankey) : [x1 - x0, y1 - y0];\n };\n\n sankey.extent = function(_) {\n return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], sankey) : [[x0, y0], [x1, y1]];\n };\n\n sankey.iterations = function(_) {\n return arguments.length ? (iterations = +_, sankey) : iterations;\n };\n\n function computeNodeLinks({nodes, links}) {\n for (const [i, node] of nodes.entries()) {\n node.index = i;\n node.sourceLinks = [];\n node.targetLinks = [];\n }\n const nodeById = new Map(nodes.map((d, i) => [id(d, i, nodes), d]));\n for (const [i, link] of links.entries()) {\n link.index = i;\n let {source, target} = link;\n if (typeof source !== \"object\") source = link.source = find(nodeById, source);\n if (typeof target !== \"object\") target = link.target = find(nodeById, target);\n source.sourceLinks.push(link);\n target.targetLinks.push(link);\n }\n if (linkSort != null) {\n for (const {sourceLinks, targetLinks} of nodes) {\n sourceLinks.sort(linkSort);\n targetLinks.sort(linkSort);\n }\n }\n }\n\n function computeNodeValues({nodes}) {\n for (const node of nodes) {\n node.value = node.fixedValue === undefined\n ? Math.max(sum(node.sourceLinks, value), sum(node.targetLinks, value))\n : node.fixedValue;\n }\n }\n\n function computeNodeDepths({nodes}) {\n const n = nodes.length;\n let current = new Set(nodes);\n let next = new Set;\n let x = 0;\n while (current.size) {\n for (const node of current) {\n node.depth = x;\n for (const {target} of node.sourceLinks) {\n next.add(target);\n }\n }\n if (++x > n) throw new Error(\"circular link\");\n current = next;\n next = new Set;\n }\n }\n\n function computeNodeHeights({nodes}) {\n const n = nodes.length;\n let current = new Set(nodes);\n let next = new Set;\n let x = 0;\n while (current.size) {\n for (const node of current) {\n node.height = x;\n for (const {source} of node.targetLinks) {\n next.add(source);\n }\n }\n if (++x > n) throw new Error(\"circular link\");\n current = next;\n next = new Set;\n }\n }\n\n function computeNodeLayers({nodes}) {\n const x = max(nodes, d => d.depth) + 1;\n const kx = (x1 - x0 - dx) / (x - 1);\n const columns = new Array(x);\n for (const node of nodes) {\n const i = Math.max(0, Math.min(x - 1, Math.floor(align.call(null, node, x))));\n node.layer = i;\n node.x0 = x0 + i * kx;\n node.x1 = node.x0 + dx;\n if (columns[i]) columns[i].push(node);\n else columns[i] = [node];\n }\n if (sort) for (const column of columns) {\n column.sort(sort);\n }\n return columns;\n }\n\n function initializeNodeBreadths(columns) {\n const ky = min(columns, c => (y1 - y0 - (c.length - 1) * py) / sum(c, value));\n for (const nodes of columns) {\n let y = y0;\n for (const node of nodes) {\n node.y0 = y;\n node.y1 = y + node.value * ky;\n y = node.y1 + py;\n for (const link of node.sourceLinks) {\n link.width = link.value * ky;\n }\n }\n y = (y1 - y + py) / (nodes.length + 1);\n for (let i = 0; i < nodes.length; ++i) {\n const node = nodes[i];\n node.y0 += y * (i + 1);\n node.y1 += y * (i + 1);\n }\n reorderLinks(nodes);\n }\n }\n\n function computeNodeBreadths(graph) {\n const columns = computeNodeLayers(graph);\n py = Math.min(dy, (y1 - y0) / (max(columns, c => c.length) - 1));\n initializeNodeBreadths(columns);\n for (let i = 0; i < iterations; ++i) {\n const alpha = Math.pow(0.99, i);\n const beta = Math.max(1 - alpha, (i + 1) / iterations);\n relaxRightToLeft(columns, alpha, beta);\n relaxLeftToRight(columns, alpha, beta);\n }\n }\n\n // Reposition each node based on its incoming (target) links.\n function relaxLeftToRight(columns, alpha, beta) {\n for (let i = 1, n = columns.length; i < n; ++i) {\n const column = columns[i];\n for (const target of column) {\n let y = 0;\n let w = 0;\n for (const {source, value} of target.targetLinks) {\n let v = value * (target.layer - source.layer);\n y += targetTop(source, target) * v;\n w += v;\n }\n if (!(w > 0)) continue;\n let dy = (y / w - target.y0) * alpha;\n target.y0 += dy;\n target.y1 += dy;\n reorderNodeLinks(target);\n }\n if (sort === undefined) column.sort(ascendingBreadth);\n resolveCollisions(column, beta);\n }\n }\n\n // Reposition each node based on its outgoing (source) links.\n function relaxRightToLeft(columns, alpha, beta) {\n for (let n = columns.length, i = n - 2; i >= 0; --i) {\n const column = columns[i];\n for (const source of column) {\n let y = 0;\n let w = 0;\n for (const {target, value} of source.sourceLinks) {\n let v = value * (target.layer - source.layer);\n y += sourceTop(source, target) * v;\n w += v;\n }\n if (!(w > 0)) continue;\n let dy = (y / w - source.y0) * alpha;\n source.y0 += dy;\n source.y1 += dy;\n reorderNodeLinks(source);\n }\n if (sort === undefined) column.sort(ascendingBreadth);\n resolveCollisions(column, beta);\n }\n }\n\n function resolveCollisions(nodes, alpha) {\n const i = nodes.length >> 1;\n const subject = nodes[i];\n resolveCollisionsBottomToTop(nodes, subject.y0 - py, i - 1, alpha);\n resolveCollisionsTopToBottom(nodes, subject.y1 + py, i + 1, alpha);\n resolveCollisionsBottomToTop(nodes, y1, nodes.length - 1, alpha);\n resolveCollisionsTopToBottom(nodes, y0, 0, alpha);\n }\n\n // Push any overlapping nodes down.\n function resolveCollisionsTopToBottom(nodes, y, i, alpha) {\n for (; i < nodes.length; ++i) {\n const node = nodes[i];\n const dy = (y - node.y0) * alpha;\n if (dy > 1e-6) node.y0 += dy, node.y1 += dy;\n y = node.y1 + py;\n }\n }\n\n // Push any overlapping nodes up.\n function resolveCollisionsBottomToTop(nodes, y, i, alpha) {\n for (; i >= 0; --i) {\n const node = nodes[i];\n const dy = (node.y1 - y) * alpha;\n if (dy > 1e-6) node.y0 -= dy, node.y1 -= dy;\n y = node.y0 - py;\n }\n }\n\n function reorderNodeLinks({sourceLinks, targetLinks}) {\n if (linkSort === undefined) {\n for (const {source: {sourceLinks}} of targetLinks) {\n sourceLinks.sort(ascendingTargetBreadth);\n }\n for (const {target: {targetLinks}} of sourceLinks) {\n targetLinks.sort(ascendingSourceBreadth);\n }\n }\n }\n\n function reorderLinks(nodes) {\n if (linkSort === undefined) {\n for (const {sourceLinks, targetLinks} of nodes) {\n sourceLinks.sort(ascendingTargetBreadth);\n targetLinks.sort(ascendingSourceBreadth);\n }\n }\n }\n\n // Returns the target.y0 that would produce an ideal link from source to target.\n function targetTop(source, target) {\n let y = source.y0 - (source.sourceLinks.length - 1) * py / 2;\n for (const {target: node, width} of source.sourceLinks) {\n if (node === target) break;\n y += width + py;\n }\n for (const {source: node, width} of target.targetLinks) {\n if (node === source) break;\n y -= width;\n }\n return y;\n }\n\n // Returns the source.y0 that would produce an ideal link from source to target.\n function sourceTop(source, target) {\n let y = target.y0 - (target.targetLinks.length - 1) * py / 2;\n for (const {source: node, width} of target.targetLinks) {\n if (node === source) break;\n y += width + py;\n }\n for (const {target: node, width} of source.sourceLinks) {\n if (node === target) break;\n y -= width;\n }\n return y;\n }\n\n return sankey;\n}\n","/**\n * d3-sankey layout wrapper.\n *\n * Extracts unique nodes from tabular data rows, configures the d3-sankey\n * generator, and returns computed node/link positions. Clones input data\n * before passing to d3-sankey since it mutates objects in place.\n */\n\nimport type { Rect, SankeyNodeAlign } from '@opendata-ai/openchart-core';\nimport type { SankeyExtraProperties, SankeyGraph, SankeyLink, SankeyNode } from 'd3-sankey';\nimport { sankey, sankeyCenter, sankeyJustify, sankeyLeft, sankeyRight } from 'd3-sankey';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Extra properties carried on our sankey nodes. */\ninterface NodeExtra extends SankeyExtraProperties {\n id: string;\n label: string;\n}\n\n/** Extra properties carried on our sankey links. */\ninterface LinkExtra extends SankeyExtraProperties {\n /** Original data row for this link. */\n data: Record<string, unknown>;\n}\n\nexport type ComputedNode = SankeyNode<NodeExtra, LinkExtra>;\nexport type ComputedLink = SankeyLink<NodeExtra, LinkExtra>;\n\nexport interface SankeyLayoutResult {\n nodes: ComputedNode[];\n links: ComputedLink[];\n}\n\n// ---------------------------------------------------------------------------\n// Alignment resolver\n// ---------------------------------------------------------------------------\n\nconst ALIGN_MAP: Record<SankeyNodeAlign, typeof sankeyJustify> = {\n justify: sankeyJustify,\n left: sankeyLeft,\n right: sankeyRight,\n center: sankeyCenter,\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Run the d3-sankey layout algorithm on tabular flow data.\n *\n * @param data - Array of data rows (each row is a source-target-value flow).\n * @param sourceField - Field name for the source node.\n * @param targetField - Field name for the target node.\n * @param valueField - Field name for the flow value.\n * @param area - Drawing area rect (after chrome subtracted).\n * @param nodeWidth - Width of node rectangles in px.\n * @param nodePadding - Vertical padding between nodes in px.\n * @param nodeAlign - Node alignment strategy.\n * @param iterations - Number of layout relaxation iterations.\n * @returns Computed node and link positions.\n */\nexport function computeSankeyLayout(\n data: Record<string, unknown>[],\n sourceField: string,\n targetField: string,\n valueField: string,\n area: Rect,\n nodeWidth: number,\n nodePadding: number,\n nodeAlign: SankeyNodeAlign,\n iterations: number,\n nodeSort?: string[],\n): SankeyLayoutResult {\n // Extract unique node IDs from source and target columns\n const nodeSet = new Set<string>();\n for (const row of data) {\n nodeSet.add(String(row[sourceField]));\n nodeSet.add(String(row[targetField]));\n }\n\n // Build node and link arrays (cloned so d3-sankey mutations don't affect input)\n const nodes: Array<{ id: string; label: string }> = [...nodeSet].map((id) => ({\n id,\n label: id,\n }));\n\n const links: Array<{\n source: string;\n target: string;\n value: number;\n data: Record<string, unknown>;\n }> = data.map((row) => ({\n source: String(row[sourceField]),\n target: String(row[targetField]),\n value: Number(row[valueField]) || 0,\n data: { ...row },\n }));\n\n // Configure and run d3-sankey\n const alignFn = ALIGN_MAP[nodeAlign] ?? sankeyJustify;\n\n const generator = sankey<SankeyGraph<NodeExtra, LinkExtra>, NodeExtra, LinkExtra>()\n .nodeId((d) => d.id)\n .nodeAlign(alignFn as unknown as (node: SankeyNode<NodeExtra, LinkExtra>, n: number) => number)\n .nodeWidth(nodeWidth)\n .nodePadding(nodePadding)\n .extent([\n [area.x, area.y],\n [area.x + area.width, area.y + area.height],\n ])\n .iterations(iterations);\n\n // Apply explicit node ordering when provided.\n // Builds a comparator from the ordered ID array so d3-sankey places nodes\n // top-to-bottom within each column according to the spec's nodeSort.\n if (nodeSort && nodeSort.length > 0) {\n const orderMap = new Map(nodeSort.map((id, i) => [id, i]));\n const fallback = nodeSort.length;\n generator.nodeSort(\n (a: SankeyNode<NodeExtra, LinkExtra>, b: SankeyNode<NodeExtra, LinkExtra>) =>\n (orderMap.get((a as unknown as NodeExtra).id) ?? fallback) -\n (orderMap.get((b as unknown as NodeExtra).id) ?? fallback),\n );\n }\n\n const graph = generator({\n nodes: nodes as unknown as Array<SankeyNode<NodeExtra, LinkExtra>>,\n links: links as unknown as Array<SankeyLink<NodeExtra, LinkExtra>>,\n });\n\n return {\n nodes: graph.nodes,\n links: graph.links,\n };\n}\n\n/**\n * Generate a filled ribbon SVG path for a sankey link.\n *\n * d3-sankey's sankeyLinkHorizontal() only produces a stroke centerline.\n * This generates a closed area path with two cubic bezier edges (top and\n * bottom) forming a ribbon whose width is proportional to flow value.\n *\n * The link object from d3-sankey provides:\n * - y0: center y at source side\n * - y1: center y at target side\n * - width: thickness of the ribbon\n * - source.x1: right edge of source node\n * - target.x0: left edge of target node\n */\nexport function generateLinkPath(link: ComputedLink): string {\n const source = link.source as ComputedNode;\n const target = link.target as ComputedNode;\n\n const x0 = source.x1 ?? 0;\n const x1 = target.x0 ?? 0;\n const y0 = link.y0 ?? 0;\n const y1 = link.y1 ?? 0;\n const halfWidth0 = (link.width ?? 0) / 2;\n const halfWidth1 = halfWidth0;\n\n // Control point x at the horizontal midpoint for smooth S-curves\n const mx = (x0 + x1) / 2;\n\n // Top edge: left-to-right\n const topY0 = y0 - halfWidth0;\n const topY1 = y1 - halfWidth1;\n\n // Bottom edge: right-to-left\n const botY0 = y0 + halfWidth0;\n const botY1 = y1 + halfWidth1;\n\n return [\n `M${x0},${topY0}`,\n `C${mx},${topY0} ${mx},${topY1} ${x1},${topY1}`,\n `L${x1},${botY1}`,\n `C${mx},${botY1} ${mx},${botY0} ${x0},${botY0}`,\n 'Z',\n ].join(' ');\n}\n","/**\n * Table compilation pipeline.\n *\n * Takes a NormalizedTableSpec and produces a fully resolved TableLayout:\n * resolve columns -> build search index -> sort data -> filter by search ->\n * paginate -> format visible cells -> apply visual enhancements -> return\n */\n\nimport type {\n CellStyle,\n ColumnConfig,\n CompileTableOptions,\n PaginationState,\n ResolvedColumn,\n ResolvedTheme,\n TableCell,\n TableLayout,\n TableRow,\n} from '@opendata-ai/openchart-core';\nimport { computeChrome, estimateTextWidth } from '@opendata-ai/openchart-core';\n\nimport { resolveAnimation } from '../compiler/animation';\nimport type { NormalizedTableSpec } from '../compiler/types';\nimport { computeBarCell, computeColumnMax, computeColumnMin } from './bar-column';\nimport { computeCategoryColors } from './category-colors';\nimport { formatCell } from './format-cells';\nimport { computeHeatmapColors } from './heatmap';\nimport { paginateData } from './pagination';\nimport { buildSearchIndex, filterBySearch } from './search';\nimport { sortData } from './sort';\nimport { computeSparklineForRow, type SparklineData } from './sparkline';\n\n// ---------------------------------------------------------------------------\n// Column resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Determine the cell type for a column based on its config.\n * Precedence: sparkline > bar > heatmap > image > flag > categoryColors > text\n */\nfunction determineCellType(col: ColumnConfig): ResolvedColumn['cellType'] {\n if (col.sparkline) return 'sparkline';\n if (col.bar) return 'bar';\n if (col.heatmap) return 'heatmap';\n if (col.image) return 'image';\n if (col.flag) return 'flag';\n if (col.categoryColors) return 'category';\n return 'text';\n}\n\n/**\n * Infer alignment for a column.\n * Explicit align wins. Otherwise: right for numeric data, left for everything else.\n */\nfunction inferAlignment(\n col: ColumnConfig,\n data: Record<string, unknown>[],\n): 'left' | 'center' | 'right' {\n if (col.align) return col.align;\n\n // Check first non-null value in the data\n for (const row of data) {\n const val = row[col.key];\n if (val != null) {\n return typeof val === 'number' ? 'right' : 'left';\n }\n }\n return 'left';\n}\n\n/**\n * Estimate the needed width for a column by measuring header and data values.\n * Samples up to 100 rows for estimation.\n */\nfunction estimateColumnWidth(\n col: ColumnConfig,\n data: Record<string, unknown>[],\n fontSize: number,\n): number {\n const MIN_WIDTH = 60;\n const PADDING = 24; // cell padding\n\n // Visual columns get fixed widths (they render graphics, not text)\n if (col.sparkline) return 140;\n if (col.image) return (col.image.width ?? 24) + PADDING;\n if (col.flag) return 60;\n\n // Header width\n const label = col.label ?? col.key;\n const headerWidth = estimateTextWidth(label, fontSize, 600) + PADDING;\n\n // Sample data values\n const sampleSize = Math.min(100, data.length);\n let maxDataWidth = 0;\n\n for (let i = 0; i < sampleSize; i++) {\n const val = data[i][col.key];\n const text = val == null ? '' : String(val);\n const width = estimateTextWidth(text, fontSize, 400) + PADDING;\n if (width > maxDataWidth) maxDataWidth = width;\n }\n\n return Math.max(MIN_WIDTH, headerWidth, maxDataWidth);\n}\n\n/**\n * Resolve all columns: compute widths, types, alignment.\n */\nfunction resolveColumns(\n columns: ColumnConfig[],\n data: Record<string, unknown>[],\n totalWidth: number,\n theme: ResolvedTheme,\n): ResolvedColumn[] {\n const fontSize = theme.fonts.sizes.body;\n\n // Compute natural widths and identify fixed-width visual columns.\n // Visual columns (sparkline, image, flag) get fixed sizes; only text\n // columns participate in proportional scaling to fill the container.\n const isFixed = columns.map((col) => !!(col.sparkline || col.image || col.flag));\n\n const naturalWidths = columns.map((col) => {\n if (col.width) {\n // Parse explicit width\n if (col.width.endsWith('px')) {\n return parseInt(col.width, 10) || 100;\n }\n if (col.width.endsWith('%')) {\n return (parseFloat(col.width) / 100) * totalWidth || 100;\n }\n return parseInt(col.width, 10) || 100;\n }\n return estimateColumnWidth(col, data, fontSize);\n });\n\n // Fixed columns keep their natural width; remaining space goes to text columns\n const fixedTotal = naturalWidths.reduce((sum, w, i) => sum + (isFixed[i] ? w : 0), 0);\n const flexTotal = naturalWidths.reduce((sum, w, i) => sum + (isFixed[i] ? 0 : w), 0);\n const remainingWidth = totalWidth - fixedTotal;\n const flexScale = flexTotal > 0 && remainingWidth > 0 ? remainingWidth / flexTotal : 1;\n\n return columns.map((col, i) => ({\n key: col.key,\n label: col.label ?? col.key,\n width: Math.max(60, isFixed[i] ? naturalWidths[i] : Math.round(naturalWidths[i] * flexScale)),\n sortable: col.sortable ?? true,\n align: inferAlignment(col, data),\n cellType: determineCellType(col),\n }));\n}\n\n// ---------------------------------------------------------------------------\n// Cell building\n// ---------------------------------------------------------------------------\n\n/**\n * Build a fully resolved TableCell from a data value and column config.\n */\nfunction buildCell(\n value: unknown,\n column: ColumnConfig,\n resolvedColumn: ResolvedColumn,\n heatmapStyle: CellStyle | undefined,\n categoryStyle: CellStyle | undefined,\n barData:\n | { barPercent: number; barOffset: number; barColor: string; isNegative: boolean }\n | undefined,\n sparklineData: SparklineData | null,\n): TableCell {\n const base = formatCell(value, column);\n\n // Apply font variant for number columns\n if (typeof value === 'number') {\n base.style = { ...base.style, fontVariant: 'tabular-nums' };\n }\n\n const cellType = resolvedColumn.cellType;\n\n switch (cellType) {\n case 'heatmap': {\n const merged = heatmapStyle ? { ...base.style, ...heatmapStyle } : base.style;\n return {\n ...base,\n cellType: 'heatmap',\n style: merged,\n };\n }\n case 'category': {\n const merged = categoryStyle ? { ...base.style, ...categoryStyle } : base.style;\n return {\n ...base,\n cellType: 'category',\n style: merged,\n };\n }\n case 'bar': {\n return {\n ...base,\n cellType: 'bar',\n barWidth: barData?.barPercent ?? 0,\n barOffset: barData?.barOffset ?? 0,\n barColor: barData?.barColor ?? '#ccc',\n isNegative: barData?.isNegative ?? false,\n };\n }\n case 'sparkline': {\n return {\n ...base,\n cellType: 'sparkline',\n sparklineData,\n };\n }\n case 'image': {\n const src = typeof value === 'string' ? value : '';\n const imgConfig = column.image ?? {};\n return {\n ...base,\n cellType: 'image',\n src,\n imageWidth: imgConfig.width ?? 24,\n imageHeight: imgConfig.height ?? 24,\n rounded: imgConfig.rounded ?? false,\n };\n }\n case 'flag': {\n const code = typeof value === 'string' ? value : '';\n return {\n ...base,\n cellType: 'flag',\n countryCode: code,\n };\n }\n default: {\n return {\n ...base,\n cellType: 'text',\n };\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main pipeline\n// ---------------------------------------------------------------------------\n\n/**\n * Compile a normalized table spec into a TableLayout.\n *\n * Pipeline:\n * 1. Resolve columns (widths, types, alignment)\n * 2. Build search index\n * 3. Sort data\n * 4. Filter by search\n * 5. Paginate\n * 6. Format visible cells and apply visual enhancements\n * 7. Return TableLayout\n */\nexport function compileTableLayout(\n spec: NormalizedTableSpec,\n options: CompileTableOptions,\n theme: ResolvedTheme,\n): TableLayout {\n const data = spec.data;\n const darkMode = theme.isDark;\n\n // 1. Resolve columns\n const resolvedColumns = resolveColumns(spec.columns, data, options.width, theme);\n\n // 2. Build search index (over full dataset, using original indices)\n const searchIndex = spec.search\n ? buildSearchIndex(data, spec.columns)\n : new Map<number, string>();\n\n // 3. Track original indices through the pipeline\n let currentData = data;\n let originalIndices = data.map((_, i) => i);\n\n // 4. Sort\n if (options.sort) {\n const sorted = sortData(currentData, options.sort);\n // Map sorted originalIndices back through our current index mapping\n originalIndices = sorted.originalIndices.map((i) => originalIndices[i]);\n currentData = sorted.data;\n }\n\n // 5. Filter by search\n if (spec.search && options.search) {\n const filtered = filterBySearch(currentData, options.search, searchIndex, originalIndices);\n currentData = filtered.data;\n originalIndices = filtered.indices;\n }\n\n const totalFiltered = currentData.length;\n\n // 6. Paginate\n let pageSize = 0;\n let currentPage = 0;\n let paginationState: PaginationState | undefined;\n\n if (spec.pagination) {\n pageSize =\n options.pageSize ?? (typeof spec.pagination === 'object' ? spec.pagination.pageSize : 25);\n currentPage = options.page ?? 0;\n const paginated = paginateData(currentData, currentPage, pageSize);\n\n // Slice indices too\n const start = paginated.page * pageSize;\n const end = start + paginated.rows.length;\n const pageIndices = originalIndices.slice(start, end);\n\n currentData = paginated.rows;\n originalIndices = pageIndices;\n\n paginationState = {\n page: paginated.page,\n pageSize,\n totalRows: paginated.totalRows,\n totalPages: paginated.totalPages,\n };\n }\n\n // 7. Pre-compute visual enhancements for visible data columns\n // We need heatmap/category colors computed over the FULL dataset, then\n // applied only to visible rows.\n const heatmapMaps = new Map<string, Map<number, CellStyle>>();\n const categoryMaps = new Map<string, Map<number, CellStyle>>();\n const barMaxes = new Map<string, number>();\n const barMins = new Map<string, number>();\n\n for (let c = 0; c < spec.columns.length; c++) {\n const col = spec.columns[c];\n const resolved = resolvedColumns[c];\n\n if (resolved.cellType === 'heatmap' && col.heatmap) {\n heatmapMaps.set(col.key, computeHeatmapColors(data, col, theme, darkMode));\n }\n if (resolved.cellType === 'category' && col.categoryColors) {\n categoryMaps.set(col.key, computeCategoryColors(data, col, theme, darkMode));\n }\n if (resolved.cellType === 'bar' && col.bar) {\n barMaxes.set(col.key, computeColumnMax(data, col.key));\n barMins.set(col.key, computeColumnMin(data, col.key));\n }\n }\n\n // 8. Build rows from visible data\n const rows: TableRow[] = currentData.map((row, i) => {\n const origIdx = originalIndices[i];\n const rowId = spec.rowKey ? String(row[spec.rowKey] ?? origIdx) : String(origIdx);\n\n const cells: TableCell[] = spec.columns.map((col, c) => {\n const resolved = resolvedColumns[c];\n const value = row[col.key];\n\n // Lookup visual enhancement data\n const heatmapStyle = heatmapMaps.get(col.key)?.get(origIdx);\n const categoryStyle = categoryMaps.get(col.key)?.get(origIdx);\n\n let barData:\n | { barPercent: number; barOffset: number; barColor: string; isNegative: boolean }\n | undefined;\n if (resolved.cellType === 'bar' && col.bar && typeof value === 'number') {\n barData = computeBarCell(\n value,\n col.bar,\n barMaxes.get(col.key) ?? 0,\n barMins.get(col.key) ?? 0,\n theme,\n darkMode,\n );\n }\n\n let sparklineData: SparklineData | null = null;\n if (resolved.cellType === 'sparkline' && col.sparkline) {\n sparklineData = computeSparklineForRow(row, col.key, col.sparkline, theme, darkMode);\n }\n\n return buildCell(value, col, resolved, heatmapStyle, categoryStyle, barData, sparklineData);\n });\n\n return { id: rowId, cells, data: row };\n });\n\n // 9. Compute chrome\n const watermark = spec.watermark;\n const chrome = computeChrome(\n {\n title: spec.chrome.title,\n subtitle: spec.chrome.subtitle,\n source: spec.chrome.source,\n byline: spec.chrome.byline,\n footer: spec.chrome.footer,\n },\n theme,\n options.width,\n options.measureText,\n 'full',\n undefined,\n watermark,\n );\n\n // 10. Build a11y\n const titleText = spec.chrome.title?.text ?? '';\n const caption = titleText ? `Table: ${titleText}` : `Data table with ${data.length} rows`;\n\n return {\n chrome,\n columns: resolvedColumns,\n rows,\n sort: options.sort,\n pagination: paginationState,\n search: {\n enabled: spec.search,\n placeholder: 'Search...',\n query: options.search ?? '',\n },\n stickyFirstColumn: spec.stickyFirstColumn,\n compact: spec.compact,\n a11y: {\n caption,\n summary: `${resolvedColumns.length} columns, ${totalFiltered} rows`,\n },\n theme,\n animation: resolveAnimation(spec.animation),\n watermark,\n };\n}\n","/**\n * Bar column computation for inline bar visualization in table cells.\n *\n * Computes bar width as a proportion of the max value.\n * Supports negative values with bidirectional bars.\n */\n\nimport type { BarColumnConfig, ResolvedTheme } from '@opendata-ai/openchart-core';\n\nconst NEGATIVE_BAR_COLOR = '#c44e52';\n\n/**\n * Compute the bar percentage, offset, and color for a single cell value.\n *\n * barPercent is 0-1. barOffset is 0-1 (left edge position).\n * When the column has negative values, bars extend bidirectionally from a zero line.\n */\nexport function computeBarCell(\n value: number,\n config: BarColumnConfig,\n columnMax: number,\n columnMin: number,\n theme: ResolvedTheme,\n _darkMode: boolean,\n): { barPercent: number; barOffset: number; barColor: string; isNegative: boolean } {\n const barColor = config.color ?? theme.colors.categorical[0];\n const hasNegatives = columnMin < 0;\n\n if (!Number.isFinite(value)) {\n return { barPercent: 0, barOffset: 0, barColor, isNegative: false };\n }\n\n if (!hasNegatives) {\n // Positive-only column: simple left-to-right bars\n const maxValue = config.maxValue ?? columnMax;\n if (maxValue <= 0) {\n return { barPercent: 0, barOffset: 0, barColor, isNegative: false };\n }\n const barPercent = Math.max(0, Math.min(1, value / maxValue));\n return { barPercent, barOffset: 0, barColor, isNegative: false };\n }\n\n // Bidirectional: zero line position proportional to data range\n const maxPos = config.maxValue ?? columnMax;\n const absMin = Math.abs(columnMin);\n const totalRange = maxPos + absMin;\n if (totalRange === 0) {\n return { barPercent: 0, barOffset: 0, barColor, isNegative: false };\n }\n\n const zeroPos = absMin / totalRange;\n\n if (value >= 0) {\n const barPercent = value / totalRange;\n return { barPercent, barOffset: zeroPos, barColor, isNegative: false };\n }\n\n // Negative value: red bar extending left from zero\n const barPercent = Math.abs(value) / totalRange;\n return {\n barPercent,\n barOffset: zeroPos - barPercent,\n barColor: config.color ?? NEGATIVE_BAR_COLOR,\n isNegative: true,\n };\n}\n\n/**\n * Compute the column max and min from data for bar scaling.\n */\nexport function computeColumnMax(data: Record<string, unknown>[], key: string): number {\n let max = 0;\n for (const row of data) {\n const val = row[key];\n if (typeof val === 'number' && Number.isFinite(val) && val > max) {\n max = val;\n }\n }\n return max;\n}\n\n/**\n * Compute the column minimum from data (for negative bar support).\n */\nexport function computeColumnMin(data: Record<string, unknown>[], key: string): number {\n let min = 0;\n for (const row of data) {\n const val = row[key];\n if (typeof val === 'number' && Number.isFinite(val) && val < min) {\n min = val;\n }\n }\n return min;\n}\n","/**\n * Category color assignment for table columns.\n *\n * Maps categorical values to colors using explicit mappings or\n * theme categorical palette, with AA-contrast text colors.\n */\n\nimport type { CellStyle, ColumnConfig, ResolvedTheme } from '@opendata-ai/openchart-core';\nimport { adaptColorForDarkMode } from '@opendata-ai/openchart-core';\nimport { accessibleTextColor } from './utils';\n\n/**\n * Compute category-colored cell styles for a column.\n *\n * Uses column.categoryColors for explicit value-to-color mappings.\n * Unmapped values get colors from the theme's categorical palette.\n *\n * Returns a Map keyed by original data index with background and text colors.\n */\nexport function computeCategoryColors(\n data: Record<string, unknown>[],\n column: ColumnConfig,\n theme: ResolvedTheme,\n darkMode: boolean,\n): Map<number, CellStyle> {\n const result = new Map<number, CellStyle>();\n const explicitMap = column.categoryColors;\n if (!explicitMap) return result;\n\n const categoricalPalette = theme.colors.categorical;\n let nextPaletteIndex = 0;\n const autoAssigned = new Map<string, string>();\n const lightBg = '#ffffff';\n const darkBg = theme.colors.background;\n\n for (let i = 0; i < data.length; i++) {\n const raw = data[i][column.key];\n if (raw == null) continue;\n\n const key = String(raw);\n let bg: string;\n let isExplicit = false;\n\n if (explicitMap[key] != null) {\n if (explicitMap[key] === 'transparent' || explicitMap[key] === 'none') {\n // Skip transparent/none — let the cell inherit default table styling\n continue;\n }\n bg = explicitMap[key];\n isExplicit = true;\n } else if (column.autoAssign) {\n // Auto-assign from palette only when explicitly opted in\n if (autoAssigned.has(key)) {\n bg = autoAssigned.get(key)!;\n } else {\n bg = categoricalPalette[nextPaletteIndex % categoricalPalette.length];\n nextPaletteIndex++;\n autoAssigned.set(key, bg);\n }\n } else {\n // Default: skip unmapped values (no color assigned)\n continue;\n }\n\n // Dark mode adaptation (skip for explicit user-provided colors)\n if (darkMode && !isExplicit) {\n bg = adaptColorForDarkMode(bg, lightBg, darkBg);\n }\n\n const textColor = accessibleTextColor(bg);\n result.set(i, {\n backgroundColor: bg,\n color: textColor,\n });\n }\n\n return result;\n}\n","/**\n * Shared utilities for table column computations.\n */\n\nimport { contrastRatio } from '@opendata-ai/openchart-core';\n\n/**\n * Pick a text color (black or white) that meets better contrast against the background.\n */\nexport function accessibleTextColor(bg: string): string {\n const white = '#ffffff';\n const black = '#000000';\n const whiteRatio = contrastRatio(white, bg);\n const blackRatio = contrastRatio(black, bg);\n return whiteRatio >= blackRatio ? white : black;\n}\n","/**\n * Cell value formatting for table columns.\n *\n * Handles number formatting (d3-format), date formatting, and\n * null/undefined values. Produces the formattedValue string and\n * base style for each cell.\n */\n\nimport type { CellStyle, ColumnConfig, TableCellBase } from '@opendata-ai/openchart-core';\nimport { buildD3Formatter, formatDate, formatNumber } from '@opendata-ai/openchart-core';\n\n/**\n * Check if a value is numeric (finite number or parseable numeric string).\n */\nfunction isNumericValue(value: unknown): value is number {\n if (typeof value === 'number') return Number.isFinite(value);\n return false;\n}\n\n/**\n * Check if a value is a date.\n */\nfunction isDateValue(value: unknown): boolean {\n if (value instanceof Date) return !Number.isNaN(value.getTime());\n return false;\n}\n\n/**\n * Format a raw cell value into a display string with styling.\n *\n * Formatting precedence:\n * 1. null/undefined -> \"\"\n * 2. column.format (d3-format string) for numbers\n * 3. Auto-format: numbers via formatNumber, dates via formatDate\n * 4. Fallback: String(value)\n */\nexport function formatCell(value: unknown, column: ColumnConfig): TableCellBase {\n const style: CellStyle = {};\n\n // Null/undefined -> empty\n if (value == null) {\n return {\n value,\n formattedValue: '',\n style,\n };\n }\n\n // If column has a d3-format string and value is numeric\n if (column.format && isNumericValue(value)) {\n const formatter = buildD3Formatter(column.format);\n if (formatter) {\n return {\n value,\n formattedValue: formatter(value),\n style,\n };\n }\n }\n\n // Auto-format numbers\n if (isNumericValue(value)) {\n return {\n value,\n formattedValue: formatNumber(value),\n style,\n };\n }\n\n // Auto-format dates\n if (isDateValue(value)) {\n return {\n value,\n formattedValue: formatDate(value as Date),\n style,\n };\n }\n\n // String and everything else\n return {\n value,\n formattedValue: String(value),\n style,\n };\n}\n\n/**\n * Format a value into a string for search indexing.\n * Uses d3-format for numeric columns, otherwise String().\n */\nexport function formatValueForSearch(value: unknown, column: ColumnConfig): string {\n if (value == null) return '';\n\n if (column.format && isNumericValue(value)) {\n const formatter = buildD3Formatter(column.format);\n if (formatter) {\n return formatter(value);\n }\n }\n\n if (isNumericValue(value)) {\n return formatNumber(value);\n }\n\n return String(value);\n}\n","/**\n * Heatmap coloring for table columns.\n *\n * Colors cell backgrounds using sequential or diverging color scales,\n * then picks an accessible text color for each background.\n */\n\nimport type { CellStyle, ColumnConfig, ResolvedTheme } from '@opendata-ai/openchart-core';\nimport { adaptColorForDarkMode } from '@opendata-ai/openchart-core';\nimport { interpolateRgb } from 'd3-interpolate';\nimport { scaleSequential } from 'd3-scale';\nimport { accessibleTextColor } from './utils';\n\n/**\n * Build an interpolator from an array of color stops.\n * Uses d3-interpolate for smooth color transitions.\n */\nfunction interpolatorFromStops(stops: string[]): (t: number) => string {\n if (stops.length === 0) return () => '#ffffff';\n if (stops.length === 1) return () => stops[0];\n\n return (t: number) => {\n const clamped = Math.max(0, Math.min(1, t));\n const segment = clamped * (stops.length - 1);\n const lo = Math.floor(segment);\n const hi = Math.min(lo + 1, stops.length - 1);\n const frac = segment - lo;\n return interpolateRgb(stops[lo], stops[hi])(frac);\n };\n}\n\n/**\n * Resolve palette from column config or theme.\n *\n * - If palette is an array of color stops, use directly\n * - If palette is a string name, look it up in theme sequential then diverging\n * - If no palette specified, use the first sequential palette from the theme\n */\nfunction resolvePalette(palette: string | string[] | undefined, theme: ResolvedTheme): string[] {\n if (Array.isArray(palette)) return palette;\n\n const seqPalettes = theme.colors.sequential;\n const divPalettes = theme.colors.diverging;\n\n if (typeof palette === 'string') {\n if (seqPalettes[palette]) return seqPalettes[palette];\n if (divPalettes[palette]) return divPalettes[palette];\n }\n\n // Default: first sequential palette\n const firstSeqKey = Object.keys(seqPalettes)[0];\n return firstSeqKey ? seqPalettes[firstSeqKey] : ['#deebf7', '#08519c'];\n}\n\n/**\n * Compute heatmap cell styles for a column.\n *\n * Returns a Map keyed by original data index with background and text colors.\n */\nexport function computeHeatmapColors(\n data: Record<string, unknown>[],\n column: ColumnConfig,\n theme: ResolvedTheme,\n darkMode: boolean,\n): Map<number, CellStyle> {\n const result = new Map<number, CellStyle>();\n const config = column.heatmap;\n if (!config) return result;\n\n // Determine which field provides the color values\n const colorField = config.colorByField ?? column.key;\n\n // Extract numeric values and compute domain\n const numericValues: { index: number; value: number }[] = [];\n for (let i = 0; i < data.length; i++) {\n const raw = data[i][colorField];\n if (typeof raw === 'number' && Number.isFinite(raw)) {\n numericValues.push({ index: i, value: raw });\n }\n }\n\n if (numericValues.length === 0) return result;\n\n // Domain: from config or data min/max\n let domain: [number, number];\n if (config.domain) {\n domain = config.domain;\n } else {\n let min = Infinity;\n let max = -Infinity;\n for (const { value } of numericValues) {\n if (value < min) min = value;\n if (value > max) max = value;\n }\n domain = [min, max];\n }\n\n // Resolve palette and build scale\n let stops = resolvePalette(config.palette, theme);\n if (darkMode) {\n const lightBg = '#ffffff';\n const darkBg = theme.colors.background;\n stops = stops.map((c) => adaptColorForDarkMode(c, lightBg, darkBg));\n }\n\n const interpolator = interpolatorFromStops(stops);\n const scale = scaleSequential(interpolator).domain(domain).clamp(true);\n\n // Apply to each row\n for (const { index, value } of numericValues) {\n const bg = scale(value);\n const textColor = accessibleTextColor(bg);\n\n result.set(index, {\n backgroundColor: bg,\n color: textColor,\n });\n }\n\n return result;\n}\n","/**\n * Table pagination: slice data into pages.\n */\n\n/**\n * Paginate data rows.\n *\n * Returns the current page's rows along with pagination metadata.\n * Page is 0-indexed and clamped to valid range.\n * If pageSize is 0 or negative, pagination is disabled (returns all rows).\n */\nexport function paginateData(\n data: Record<string, unknown>[],\n page: number,\n pageSize: number,\n): {\n rows: Record<string, unknown>[];\n totalRows: number;\n totalPages: number;\n page: number;\n} {\n const totalRows = data.length;\n\n // Disabled pagination\n if (pageSize <= 0) {\n return {\n rows: data,\n totalRows,\n totalPages: 1,\n page: 0,\n };\n }\n\n const totalPages = Math.max(1, Math.ceil(totalRows / pageSize));\n // Clamp page to valid range\n const clampedPage = Math.max(0, Math.min(page, totalPages - 1));\n const start = clampedPage * pageSize;\n const end = Math.min(start + pageSize, totalRows);\n\n return {\n rows: data.slice(start, end),\n totalRows,\n totalPages,\n page: clampedPage,\n };\n}\n","/**\n * Table search: build a search index and filter rows by query.\n *\n * The search index concatenates formatted cell values per row so\n * substring matching works across all columns.\n */\n\nimport type { ColumnConfig } from '@opendata-ai/openchart-core';\nimport { formatValueForSearch } from './format-cells';\n\n/**\n * Build a search index mapping original data indices to searchable strings.\n * Each row's searchable string is the concatenation of all column values,\n * separated by spaces, lowercased.\n */\nexport function buildSearchIndex(\n data: Record<string, unknown>[],\n columns: ColumnConfig[],\n): Map<number, string> {\n const index = new Map<number, string>();\n\n for (let i = 0; i < data.length; i++) {\n const row = data[i];\n const parts: string[] = [];\n\n for (const col of columns) {\n parts.push(formatValueForSearch(row[col.key], col));\n }\n\n index.set(i, parts.join(' ').toLowerCase());\n }\n\n return index;\n}\n\n/**\n * Filter data by a search query using the pre-built search index.\n *\n * Returns the filtered data and the original indices of matching rows.\n * Empty query returns all data.\n */\nexport function filterBySearch(\n data: Record<string, unknown>[],\n query: string,\n searchIndex: Map<number, string>,\n originalIndices: number[],\n): { data: Record<string, unknown>[]; indices: number[] } {\n if (!query || query.trim() === '') {\n return { data, indices: originalIndices };\n }\n\n const lowerQuery = query.toLowerCase();\n const filteredData: Record<string, unknown>[] = [];\n const filteredIndices: number[] = [];\n\n for (let i = 0; i < data.length; i++) {\n const originalIdx = originalIndices[i];\n const searchText = searchIndex.get(originalIdx);\n if (searchText?.includes(lowerQuery)) {\n filteredData.push(data[i]);\n filteredIndices.push(originalIdx);\n }\n }\n\n return { data: filteredData, indices: filteredIndices };\n}\n","/**\n * Stable sort for table data.\n *\n * Sorts data by a column key with type-aware comparison:\n * - Numbers: numeric comparison\n * - Strings: localeCompare\n * - Dates: timestamp comparison\n * - Nulls: always sorted last regardless of direction\n */\n\nimport type { SortState } from '@opendata-ai/openchart-core';\n\n/** Result of sorting: sorted data rows with their original indices preserved. */\nexport interface SortResult {\n data: Record<string, unknown>[];\n originalIndices: number[];\n}\n\n/**\n * Sort data rows by the specified column.\n * Returns a new array (no mutation). Stable sort preserves\n * original order for rows with equal values.\n *\n * Also returns the original indices so callers can track\n * which row came from where (needed for heatmap/category color lookups).\n */\nexport function sortData(data: Record<string, unknown>[], sort: SortState): SortResult {\n const { column, direction } = sort;\n const multiplier = direction === 'asc' ? 1 : -1;\n\n // Create index-value pairs for stable sort\n const indexed = data.map((row, i) => ({ row, index: i }));\n\n indexed.sort((a, b) => {\n const aVal = a.row[column];\n const bVal = b.row[column];\n\n // Nulls always last\n const aNull = aVal == null;\n const bNull = bVal == null;\n if (aNull && bNull) return a.index - b.index; // preserve order\n if (aNull) return 1;\n if (bNull) return -1;\n\n let cmp = 0;\n\n // Number comparison\n if (typeof aVal === 'number' && typeof bVal === 'number') {\n cmp = aVal - bVal;\n }\n // Date comparison\n else if (aVal instanceof Date && bVal instanceof Date) {\n cmp = aVal.getTime() - bVal.getTime();\n }\n // String comparison (or mixed types)\n else {\n cmp = String(aVal).localeCompare(String(bVal));\n }\n\n // Stable sort: fall back to original index for equal values\n if (cmp === 0) return a.index - b.index;\n return cmp * multiplier;\n });\n\n return {\n data: indexed.map((item) => item.row),\n originalIndices: indexed.map((item) => item.index),\n };\n}\n","/**\n * Sparkline computation for inline mini-charts in table cells.\n *\n * Produces normalized data points (0-1 range) for sparkline rendering.\n * The adapter handles the actual drawing.\n */\n\nimport type {\n ResolvedTheme,\n SparklineColumnConfig,\n SparklineData,\n} from '@opendata-ai/openchart-core';\n\nexport type { SparklineData };\n\n/**\n * Extract numeric values from a row for sparkline rendering.\n *\n * If valuesField is specified, reads an array from that field.\n * Otherwise uses the column's own key (expects an array value).\n */\nfunction extractValues(\n row: Record<string, unknown>,\n columnKey: string,\n config: SparklineColumnConfig,\n): number[] {\n const field = config.valuesField ?? columnKey;\n const raw = row[field];\n\n if (!Array.isArray(raw)) return [];\n\n return raw\n .map((v) => (typeof v === 'number' && Number.isFinite(v) ? v : null))\n .filter((v): v is number => v !== null);\n}\n\n/**\n * Compute sparkline data for a single row.\n *\n * Normalizes values to 0-1 range. Returns null if no valid values.\n */\nexport function computeSparkline(\n values: number[],\n config: SparklineColumnConfig,\n theme: ResolvedTheme,\n _darkMode: boolean,\n): SparklineData | null {\n if (values.length === 0) return null;\n\n const type = config.type ?? 'line';\n const color = config.color ?? theme.colors.categorical[0];\n\n let min = Infinity;\n let max = -Infinity;\n for (const v of values) {\n if (v < min) min = v;\n if (v > max) max = v;\n }\n\n const range = max - min;\n const normalize = (v: number): number => (range === 0 ? 0.5 : (v - min) / range);\n\n const startValue = values[0];\n const endValue = values[values.length - 1];\n\n if (type === 'line') {\n const points = values.map((v, i) => ({\n x: values.length === 1 ? 0.5 : i / (values.length - 1),\n y: normalize(v),\n }));\n\n return {\n type,\n points,\n bars: [],\n color,\n count: values.length,\n startValue,\n endValue,\n };\n }\n\n // Bar (horizontal) or column (vertical): normalized as proportions\n const bars = values.map(normalize);\n const points = values.map((v, i) => ({\n x: values.length === 1 ? 0.5 : i / (values.length - 1),\n y: normalize(v),\n }));\n\n return {\n type,\n points,\n bars,\n color,\n count: values.length,\n startValue,\n endValue,\n };\n}\n\n/**\n * Extract values and compute sparkline data for a cell.\n */\nexport function computeSparklineForRow(\n row: Record<string, unknown>,\n columnKey: string,\n config: SparklineColumnConfig,\n theme: ResolvedTheme,\n darkMode: boolean,\n): SparklineData | null {\n const values = extractValues(row, columnKey, config);\n return computeSparkline(values, config, theme, darkMode);\n}\n","/**\n * Tooltip descriptor computation.\n *\n * Generates a Map of mark-id -> TooltipContent from the spec encoding and marks.\n * Each mark gets a tooltip that shows relevant field values formatted for display.\n * The mark-id keys match the data-mark-id attributes set by the SVG renderer.\n */\n\nimport type {\n ArcMark,\n AreaMark,\n DataRow,\n Encoding,\n EncodingChannel,\n LineMark,\n Mark,\n PointMark,\n RectMark,\n TooltipContent,\n TooltipField,\n} from '@opendata-ai/openchart-core';\nimport {\n buildTemporalFormatter,\n formatDate,\n formatNumber,\n getRepresentativeColor,\n} from '@opendata-ai/openchart-core';\nimport { format as d3Format } from 'd3-format';\n\nimport type { NormalizedChartSpec } from '../compiler/types';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Format a raw data value for tooltip display. */\nfunction formatValue(value: unknown, fieldType?: string, format?: string): string {\n if (value == null) return '';\n\n if (fieldType === 'temporal' || value instanceof Date) {\n const temporalFmt = buildTemporalFormatter(format);\n if (temporalFmt) return temporalFmt(value as Date | string | number);\n return formatDate(value as Date | string | number);\n }\n\n if (typeof value === 'number') {\n if (format) {\n try {\n return d3Format(format)(value);\n } catch {\n return formatNumber(value);\n }\n }\n return formatNumber(value);\n }\n\n return String(value);\n}\n\n/** Resolve the display label for an encoding channel: title > axis.title > field name. */\nfunction resolveLabel(ch: EncodingChannel): string {\n return ch.title ?? ch.axis?.title ?? ch.field;\n}\n\n/** Resolve the format string for an encoding channel: format > axis.format. */\nfunction resolveFormat(ch: EncodingChannel): string | undefined {\n return ch.format ?? ch.axis?.format;\n}\n\n/** Build tooltip fields from explicit tooltip encoding channels. */\nfunction buildExplicitTooltipFields(row: DataRow, channels: EncodingChannel[]): TooltipField[] {\n return channels.map((ch) => ({\n label: resolveLabel(ch),\n value: formatValue(row[ch.field], ch.type, resolveFormat(ch)),\n }));\n}\n\n/** Build tooltip fields from a data row based on the spec encoding. */\nfunction buildFields(row: DataRow, encoding: Encoding, color?: string): TooltipField[] {\n if (encoding.tooltip) {\n const channels = Array.isArray(encoding.tooltip) ? encoding.tooltip : [encoding.tooltip];\n return buildExplicitTooltipFields(row, channels);\n }\n\n const fields: TooltipField[] = [];\n\n // Color/series field (e.g. \"Source: Coal\") so the user knows which series\n if (encoding.color && 'field' in encoding.color) {\n fields.push({\n label: resolveLabel(encoding.color),\n value: formatValue(\n row[encoding.color.field],\n encoding.color.type,\n resolveFormat(encoding.color),\n ),\n color,\n });\n }\n\n // Y-axis value (the \"main\" value in most charts)\n if (encoding.y) {\n fields.push({\n label: resolveLabel(encoding.y),\n value: formatValue(row[encoding.y.field], encoding.y.type, resolveFormat(encoding.y)),\n color: encoding.color ? undefined : color,\n });\n }\n\n // X-axis value (often the category or date)\n if (encoding.x) {\n fields.push({\n label: resolveLabel(encoding.x),\n value: formatValue(row[encoding.x.field], encoding.x.type, resolveFormat(encoding.x)),\n });\n }\n\n // Size (for scatter/bubble) - skip conditional size definitions\n if (encoding.size && 'field' in encoding.size) {\n fields.push({\n label: resolveLabel(encoding.size),\n value: formatValue(\n row[encoding.size.field],\n encoding.size.type,\n resolveFormat(encoding.size),\n ),\n });\n }\n\n return fields;\n}\n\n/** Determine the title for a tooltip based on encoding. */\nfunction getTooltipTitle(row: DataRow, encoding: Encoding): string | undefined {\n // Detail channel provides an explicit label (e.g. district name in scatter)\n if (encoding.detail) {\n return String(row[encoding.detail.field] ?? '');\n }\n\n // For charts with a temporal x-axis, use the date as the title\n if (encoding.x?.type === 'temporal') {\n return formatValue(row[encoding.x.field], 'temporal');\n }\n\n // For nominal x, use the category\n if (encoding.x?.type === 'nominal' || encoding.x?.type === 'ordinal') {\n return String(row[encoding.x.field] ?? '');\n }\n\n // For nominal y (e.g. horizontal bar charts), use the category\n if (encoding.y?.type === 'nominal' || encoding.y?.type === 'ordinal') {\n return String(row[encoding.y.field] ?? '');\n }\n\n // For scatter/bubble (both axes quantitative), find a name-like string field\n // in the data row that isn't already used by an encoding channel\n if (encoding.x?.type === 'quantitative' && encoding.y?.type === 'quantitative') {\n const encodedFields = new Set(\n [encoding.x, encoding.y, encoding.color, encoding.size, encoding.detail]\n .filter((ch): ch is EncodingChannel => !!ch && 'field' in ch)\n .map((ch) => ch.field),\n );\n for (const [key, value] of Object.entries(row)) {\n if (!encodedFields.has(key) && typeof value === 'string') {\n return value;\n }\n }\n }\n\n // For color-encoded series, use the series name (skip conditional defs)\n if (encoding.color && 'field' in encoding.color) {\n return String(row[encoding.color.field] ?? '');\n }\n\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Per-mark-type tooltip generation\n// ---------------------------------------------------------------------------\n\nfunction tooltipsForLine(\n mark: LineMark,\n encoding: Encoding,\n _markIndex: number,\n): Array<[string, TooltipContent]> {\n // Populate tooltip content on each dataPoint for voronoi overlay lookup.\n // Line marks don't emit per-mark tooltip descriptors (the overlay handles it).\n if (mark.dataPoints) {\n for (const dp of mark.dataPoints) {\n dp.tooltip = {\n title: getTooltipTitle(dp.datum, encoding),\n fields: buildFields(dp.datum, encoding, mark.stroke),\n };\n }\n }\n return [];\n}\n\nfunction tooltipsForPoint(\n mark: PointMark,\n encoding: Encoding,\n markIndex: number,\n): Array<[string, TooltipContent]> {\n const title = getTooltipTitle(mark.data, encoding);\n const fields = buildFields(mark.data, encoding, getRepresentativeColor(mark.fill));\n\n return [[`point-${markIndex}`, { title, fields }]];\n}\n\nfunction tooltipsForRect(\n mark: RectMark,\n encoding: Encoding,\n markIndex: number,\n): Array<[string, TooltipContent]> {\n const title = getTooltipTitle(mark.data, encoding);\n const fields = buildFields(mark.data, encoding, getRepresentativeColor(mark.fill));\n\n return [[`rect-${markIndex}`, { title, fields }]];\n}\n\nfunction tooltipsForArc(\n mark: ArcMark,\n encoding: Encoding,\n markIndex: number,\n): Array<[string, TooltipContent]> {\n const row = mark.data;\n const fields: TooltipField[] = [];\n\n // For pie/donut, show the category and its value\n const colorEnc = encoding.color && 'field' in encoding.color ? encoding.color : undefined;\n if (colorEnc) {\n const categoryName = String(row[colorEnc.field] ?? '');\n if (encoding.y) {\n fields.push({\n label: categoryName,\n value: formatValue(row[encoding.y.field], encoding.y.type, resolveFormat(encoding.y)),\n color: getRepresentativeColor(mark.fill),\n });\n }\n } else if (encoding.y) {\n fields.push({\n label: resolveLabel(encoding.y),\n value: formatValue(row[encoding.y.field], encoding.y.type, resolveFormat(encoding.y)),\n color: getRepresentativeColor(mark.fill),\n });\n }\n\n const title = colorEnc ? String(row[colorEnc.field] ?? '') : undefined;\n\n return [[`arc-${markIndex}`, { title, fields }]];\n}\n\nfunction tooltipsForArea(\n mark: AreaMark,\n encoding: Encoding,\n _markIndex: number,\n): Array<[string, TooltipContent]> {\n // Populate tooltip content on each dataPoint for voronoi overlay lookup.\n // Area marks don't emit per-mark tooltip descriptors (the overlay handles it).\n if (mark.dataPoints) {\n for (const dp of mark.dataPoints) {\n dp.tooltip = {\n title: getTooltipTitle(dp.datum, encoding),\n fields: buildFields(dp.datum, encoding, getRepresentativeColor(mark.fill)),\n };\n }\n }\n return [];\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compute tooltip descriptors for all marks in the layout.\n *\n * Returns a Map keyed by data-mark-id (matching the SVG attribute)\n * to TooltipContent objects. The vanilla adapter uses this to show\n * tooltips on hover/tap/keyboard focus.\n */\nexport function computeTooltipDescriptors(\n spec: NormalizedChartSpec,\n marks: Mark[],\n): Map<string, TooltipContent> {\n const encoding = spec.encoding as Encoding;\n const descriptors = new Map<string, TooltipContent>();\n\n for (let i = 0; i < marks.length; i++) {\n const mark = marks[i];\n let entries: Array<[string, TooltipContent]> = [];\n\n switch (mark.type) {\n case 'line':\n entries = tooltipsForLine(mark, encoding, i);\n break;\n case 'area':\n entries = tooltipsForArea(mark, encoding, i);\n break;\n case 'point':\n entries = tooltipsForPoint(mark, encoding, i);\n break;\n case 'rect':\n entries = tooltipsForRect(mark, encoding, i);\n break;\n case 'arc':\n entries = tooltipsForArc(mark, encoding, i);\n break;\n }\n\n for (const [key, content] of entries) {\n descriptors.set(key, content);\n }\n }\n\n return descriptors;\n}\n","/**\n * Aggregate transform: groups rows and computes summary statistics.\n *\n * Follows Vega-Lite aggregate transform conventions.\n * Groups input data by the specified fields, then applies aggregate\n * operations (sum, mean, count, etc.) to produce one row per group.\n */\n\nimport type { AggregateOp, AggregateTransform, DataRow } from '@opendata-ai/openchart-core';\n\n/**\n * Compute a single aggregate operation over an array of numeric values.\n */\nfunction computeAggregate(op: AggregateOp, values: number[]): number {\n if (values.length === 0) return 0;\n\n switch (op) {\n case 'count':\n return values.length;\n case 'sum':\n return values.reduce((a, b) => a + b, 0);\n case 'mean': {\n const sum = values.reduce((a, b) => a + b, 0);\n return sum / values.length;\n }\n case 'median': {\n const sorted = [...values].sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];\n }\n case 'min':\n return Math.min(...values);\n case 'max':\n return Math.max(...values);\n case 'variance': {\n if (values.length < 2) return 0;\n const mean = values.reduce((a, b) => a + b, 0) / values.length;\n return values.reduce((a, v) => a + (v - mean) ** 2, 0) / values.length;\n }\n case 'stdev': {\n if (values.length < 2) return 0;\n const m = values.reduce((a, b) => a + b, 0) / values.length;\n return Math.sqrt(values.reduce((a, v) => a + (v - m) ** 2, 0) / values.length);\n }\n case 'q1': {\n const s = [...values].sort((a, b) => a - b);\n const i = (s.length - 1) * 0.25;\n const lo = Math.floor(i);\n const frac = i - lo;\n return s[lo] + frac * ((s[lo + 1] ?? s[lo]) - s[lo]);\n }\n case 'q3': {\n const s = [...values].sort((a, b) => a - b);\n const i = (s.length - 1) * 0.75;\n const lo = Math.floor(i);\n const frac = i - lo;\n return s[lo] + frac * ((s[lo + 1] ?? s[lo]) - s[lo]);\n }\n default:\n return 0;\n }\n}\n\n/**\n * Build a composite group key from a row's groupby field values.\n */\nfunction groupKey(row: DataRow, groupby: string[]): string {\n return groupby.map((f) => String(row[f] ?? '')).join('\\x00');\n}\n\n/**\n * Apply an aggregate transform to data rows.\n *\n * Groups rows by the groupby fields, then computes each aggregate\n * operation within each group. Returns one row per group containing\n * the groupby field values plus computed aggregate fields.\n *\n * @param data - Input rows.\n * @param transform - Aggregate transform definition.\n * @returns Aggregated rows (one per group).\n */\nexport function runAggregate(data: DataRow[], transform: AggregateTransform): DataRow[] {\n const { aggregate, groupby } = transform;\n\n // Group rows by the groupby fields\n const groups = new Map<string, DataRow[]>();\n for (const row of data) {\n const key = groupKey(row, groupby);\n const existing = groups.get(key);\n if (existing) {\n existing.push(row);\n } else {\n groups.set(key, [row]);\n }\n }\n\n // Compute aggregates for each group\n const result: DataRow[] = [];\n for (const rows of groups.values()) {\n // Start with groupby field values from the first row in the group\n const outRow: DataRow = {};\n for (const field of groupby) {\n outRow[field] = rows[0][field];\n }\n\n // Compute each aggregate operation\n for (const agg of aggregate) {\n // distinct counts unique raw values (not just numeric)\n if (agg.op === 'distinct') {\n outRow[agg.as] = new Set(rows.map((r) => r[agg.field])).size;\n continue;\n }\n\n const values = rows\n .map((r) => {\n // For count, the field value doesn't matter, just count rows\n if (agg.op === 'count') return 1;\n const v = Number(r[agg.field]);\n return Number.isFinite(v) ? v : NaN;\n })\n .filter((v) => !Number.isNaN(v));\n\n outRow[agg.as] = computeAggregate(agg.op, values);\n }\n\n result.push(outRow);\n }\n\n return result;\n}\n","/**\n * Bin transform: discretizes a continuous field into bins.\n *\n * Adds bin start (and optionally bin end) fields to each row.\n */\n\nimport type { BinParams, BinTransform, DataRow } from '@opendata-ai/openchart-core';\n\n/**\n * Compute a nice step size for binning.\n */\nfunction computeStep(extent: [number, number], maxbins: number, nice: boolean): number {\n const span = extent[1] - extent[0];\n if (span === 0) return 1;\n\n let step = span / maxbins;\n\n if (nice) {\n // Round to a nice step: 1, 2, 5, 10, 20, 50, etc.\n const magnitude = 10 ** Math.floor(Math.log10(step));\n const residual = step / magnitude;\n\n if (residual <= 1.5) {\n step = magnitude;\n } else if (residual <= 3.5) {\n step = 2 * magnitude;\n } else if (residual <= 7.5) {\n step = 5 * magnitude;\n } else {\n step = 10 * magnitude;\n }\n }\n\n return step;\n}\n\n/**\n * Apply a bin transform to data rows.\n *\n * Adds one or two fields to each row:\n * - If `as` is a string: adds `as` with the bin start value.\n * - If `as` is [start, end]: adds both bin start and bin end fields.\n *\n * @param data - Input rows.\n * @param transform - Bin transform definition.\n * @returns New rows with binned field(s) added.\n */\nexport function runBin(data: DataRow[], transform: BinTransform): DataRow[] {\n const params: BinParams = transform.bin === true ? {} : transform.bin;\n const maxbins = params.maxbins ?? 10;\n const nice = params.nice ?? true;\n const field = transform.field;\n\n // Compute extent from data if not provided\n let extent = params.extent;\n if (!extent) {\n let min = Infinity;\n let max = -Infinity;\n for (const row of data) {\n const v = Number(row[field]);\n if (Number.isFinite(v)) {\n if (v < min) min = v;\n if (v > max) max = v;\n }\n }\n extent = [min === Infinity ? 0 : min, max === -Infinity ? 0 : max];\n }\n\n const step = params.step ?? computeStep(extent, maxbins, nice);\n const [startAs, endAs] = Array.isArray(transform.as) ? transform.as : [transform.as, undefined];\n\n return data.map((row) => {\n const v = Number(row[field]);\n const newRow = { ...row };\n\n if (!Number.isFinite(v)) {\n newRow[startAs] = null;\n if (endAs) newRow[endAs] = null;\n } else {\n const binStart = Math.floor((v - extent![0]) / step) * step + extent![0];\n newRow[startAs] = binStart;\n if (endAs) newRow[endAs] = binStart + step;\n }\n\n return newRow;\n });\n}\n","/**\n * Calculate transform: adds a computed field to each row.\n *\n * Supports arithmetic operations on fields and constant values.\n */\n\nimport type { CalculateExpression, CalculateTransform, DataRow } from '@opendata-ai/openchart-core';\n\n/**\n * Evaluate a calculate expression against a datum.\n */\nfunction evaluateExpression(datum: DataRow, expr: CalculateExpression): number {\n const fieldValue = Number(datum[expr.field]);\n\n // Unary operations (single field)\n switch (expr.op) {\n case 'abs':\n return Math.abs(fieldValue);\n case 'round':\n return Math.round(fieldValue);\n case 'floor':\n return Math.floor(fieldValue);\n case 'ceil':\n return Math.ceil(fieldValue);\n case 'log':\n return Math.log(fieldValue);\n case 'sqrt':\n return Math.sqrt(fieldValue);\n }\n\n // Binary operations (field + field2 or field + value)\n const operand = expr.field2 !== undefined ? Number(datum[expr.field2]) : (expr.value ?? 0);\n\n switch (expr.op) {\n case '+':\n return fieldValue + operand;\n case '-':\n return fieldValue - operand;\n case '*':\n return fieldValue * operand;\n case '/':\n return operand === 0 ? NaN : fieldValue / operand;\n }\n}\n\n/**\n * Apply a calculate transform to data rows.\n *\n * Adds a new field with the computed value to each row.\n *\n * @param data - Input rows.\n * @param transform - Calculate transform definition.\n * @returns New rows with the calculated field added.\n */\nexport function runCalculate(data: DataRow[], transform: CalculateTransform): DataRow[] {\n return data.map((row) => ({\n ...row,\n [transform.as]: evaluateExpression(row, transform.calculate),\n }));\n}\n","/**\n * Filter transform: removes rows that don't match a predicate.\n */\n\nimport type { DataRow, FilterPredicate } from '@opendata-ai/openchart-core';\nimport { evaluatePredicate } from './predicates';\n\n/**\n * Filter data rows by a predicate.\n *\n * @param data - Input rows.\n * @param predicate - Filter predicate to evaluate per row.\n * @returns Rows that pass the predicate.\n */\nexport function runFilter(data: DataRow[], predicate: FilterPredicate): DataRow[] {\n return data.filter((datum) => evaluatePredicate(datum, predicate));\n}\n","/**\n * Fold transform: unpivots wide-format data into long format.\n *\n * Follows Vega-Lite fold transform conventions.\n * For each input row, creates N new rows (one per fold field),\n * copying all non-fold fields and adding key/value columns.\n */\n\nimport type { DataRow, FoldTransform } from '@opendata-ai/openchart-core';\n\n/**\n * Apply a fold transform to data rows.\n *\n * For each input row, creates one output row per fold field. Each output\n * row contains all fields from the original row (except the fold fields),\n * plus a key field (the fold field name) and a value field (the fold field value).\n *\n * @param data - Input rows.\n * @param transform - Fold transform definition.\n * @returns Folded rows (N rows per input row, where N = fold fields count).\n */\nexport function runFold(data: DataRow[], transform: FoldTransform): DataRow[] {\n const { fold } = transform;\n const [keyAs, valueAs] = transform.as ?? ['key', 'value'];\n const foldSet = new Set(fold);\n\n const result: DataRow[] = [];\n\n for (const row of data) {\n // Copy all non-fold fields\n const base: DataRow = {};\n for (const [k, v] of Object.entries(row)) {\n if (!foldSet.has(k)) {\n base[k] = v;\n }\n }\n\n // Create one row per fold field\n for (const field of fold) {\n result.push({\n ...base,\n [keyAs]: field,\n [valueAs]: row[field],\n });\n }\n }\n\n return result;\n}\n","/**\n * Time unit transform: extracts temporal components from date fields.\n *\n * Follows Vega-Lite time unit conventions.\n */\n\nimport type { DataRow, TimeUnit, TimeUnitTransform } from '@opendata-ai/openchart-core';\n\n/**\n * Extract a time unit value from a Date object.\n */\nfunction extractTimeUnit(date: Date, unit: TimeUnit): number | string {\n switch (unit) {\n case 'year':\n return date.getFullYear();\n case 'quarter':\n return Math.floor(date.getMonth() / 3) + 1;\n case 'month':\n return date.getMonth(); // 0-indexed like JS Date\n case 'week': {\n // ISO week number\n const d = new Date(date.getTime());\n d.setHours(0, 0, 0, 0);\n d.setDate(d.getDate() + 3 - ((d.getDay() + 6) % 7));\n const yearStart = new Date(d.getFullYear(), 0, 1);\n return Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);\n }\n case 'day':\n return date.getDay(); // 0 = Sunday\n case 'dayofyear': {\n const start = new Date(date.getFullYear(), 0, 0);\n const diff = date.getTime() - start.getTime();\n return Math.floor(diff / 86400000);\n }\n case 'date':\n return date.getDate(); // 1-31\n case 'hours':\n return date.getHours();\n case 'minutes':\n return date.getMinutes();\n case 'seconds':\n return date.getSeconds();\n case 'milliseconds':\n return date.getMilliseconds();\n // Compound units\n case 'yearmonth':\n return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;\n case 'yearmonthdate':\n return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;\n case 'monthdate':\n return `${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;\n case 'hoursminutes':\n return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;\n }\n}\n\n/**\n * Parse a value into a Date object.\n * Handles Date objects, ISO strings, and numeric timestamps.\n */\nfunction toDate(value: unknown): Date | null {\n if (value instanceof Date) return value;\n if (typeof value === 'string' || typeof value === 'number') {\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n return null;\n}\n\n/**\n * Apply a time unit transform to data rows.\n *\n * Parses the field as a date and extracts the specified time unit,\n * storing the result in a new field.\n *\n * @param data - Input rows.\n * @param transform - Time unit transform definition.\n * @returns New rows with the time unit field added.\n */\nexport function runTimeUnit(data: DataRow[], transform: TimeUnitTransform): DataRow[] {\n return data.map((row) => {\n const date = toDate(row[transform.field]);\n return {\n ...row,\n [transform.as]: date ? extractTimeUnit(date, transform.timeUnit) : null,\n };\n });\n}\n","/**\n * Data transform pipeline.\n *\n * Runs an ordered sequence of transforms (filter, bin, calculate, timeUnit)\n * against a data array. Each transform produces a new array, feeding into\n * the next transform in sequence.\n */\n\nimport type { DataRow, Transform } from '@opendata-ai/openchart-core';\nimport { runAggregate } from './aggregate';\nimport { runBin } from './bin';\nimport { runCalculate } from './calculate';\nimport { runFilter } from './filter';\nimport { runFold } from './fold';\nimport { runTimeUnit } from './timeunit';\n\nexport { runAggregate } from './aggregate';\nexport { runBin } from './bin';\nexport { runCalculate } from './calculate';\nexport { isConditionalValueDef, resolveConditionalValue } from './conditional';\nexport { runFilter } from './filter';\nexport { runFold } from './fold';\nexport { evaluatePredicate } from './predicates';\nexport { runTimeUnit } from './timeunit';\n\n/**\n * Run a sequence of transforms against a data array.\n *\n * Each transform is applied in order, producing a new data array\n * that feeds into the next transform. The original data is not mutated.\n *\n * @param data - Input data rows.\n * @param transforms - Ordered array of transform definitions.\n * @returns Transformed data rows.\n */\nexport function runTransforms(data: DataRow[], transforms: Transform[]): DataRow[] {\n let result = data;\n\n for (const transform of transforms) {\n if ('filter' in transform) {\n result = runFilter(result, transform.filter);\n } else if ('bin' in transform) {\n result = runBin(result, transform);\n } else if ('calculate' in transform) {\n result = runCalculate(result, transform);\n } else if ('timeUnit' in transform) {\n result = runTimeUnit(result, transform);\n } else if ('aggregate' in transform) {\n result = runAggregate(result, transform);\n } else if ('fold' in transform) {\n result = runFold(result, transform);\n }\n }\n\n return result;\n}\n"],"mappings":";AAgCA;AAAA,EACE,cAAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAAC;AAAA,OACK;;;AC9BP,SAAS,uBAAuB;;;ACVzB,IAAM,+BAA+B;AAGrC,IAAM,iCAAiC;AAGvC,IAAM,sBAAsB;AAG5B,IAAM,qBAAqB;AAG3B,IAAM,wBAAwB;AAG9B,IAAM,uBAAuB;AAG7B,IAAM,kBAAkB;AACxB,IAAM,iBAAiB;AACvB,IAAM,uBAAuB;AAC7B,IAAM,sBAAsB;AAG5B,IAAM,gBAAgB;AAGtB,IAAM,gBAAgB;AAGtB,IAAM,eAAe;;;ACrB5B,SAAS,yBAAyB;AAY3B,SAAS,kBACd,QACA,QACA,MACA,UACA,YACM;AACN,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,QAAM,cAAc,MAAM,SAAS;AACnC,QAAM,WAAW,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,kBAAkB,MAAM,UAAU,UAAU,CAAC,CAAC;AAC/F,QAAM,cAAc,MAAM,SAAS,WAAW;AAC9C,QAAMC,KAAI,cAAc,SAAS,WAAW,IAAI;AAEhD,SAAO;AAAA,IACL,GAAAA;AAAA,IACA,GAAG,SAAS;AAAA,IACZ,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AACF;AAMO,SAAS,oBACd,QACA,KACA,IACA,WAC4B;AAC5B,MAAI,CAAC,UAAU,WAAW,QAAQ;AAEhC,UAAM,cAAc,KAAK,UAAU,IAAI,UAAU,SAAS;AAC1D,WAAO,cACH,EAAE,IAAI,eAAe,IAAI,cAAc,IACvC,EAAE,IAAI,eAAe,IAAI,CAAC,cAAc;AAAA,EAC9C;AAEA,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,EAAE,IAAI,GAAG,IAAI,CAAC,cAAc;AAAA,IACrC,KAAK;AACH,aAAO,EAAE,IAAI,GAAG,IAAI,cAAc;AAAA,IACpC,KAAK;AACH,aAAO,EAAE,IAAI,CAAC,eAAe,IAAI,EAAE;AAAA,IACrC,KAAK;AACH,aAAO,EAAE,IAAI,eAAe,IAAI,EAAE;AAAA,EACtC;AACF;AAGO,SAAS,YACd,MACA,QAC4B;AAC5B,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO;AAAA,IACL,IAAI,KAAK,MAAM,OAAO,MAAM;AAAA,IAC5B,IAAI,KAAK,MAAM,OAAO,MAAM;AAAA,EAC9B;AACF;AAOO,SAAS,uBACd,QACA,QACA,MACA,UACA,YACA,SACA,SACA,gBAC0B;AAC1B,QAAM,MAAM,kBAAkB,QAAQ,QAAQ,MAAM,UAAU,UAAU;AACxE,QAAM,aAAa,IAAI,IAAI,IAAI,QAAQ;AACvC,QAAM,aAAa,IAAI,IAAI,IAAI,SAAS;AAGxC,MAAI,mBAAmB,SAAS;AAC9B,WAAO;AAAA,MACL,GAAG,IAAI,IAAI,IAAI;AAAA,MACf,GAAG;AAAA,IACL;AAAA,EACF;AAKA,QAAM,QAAQ,IAAI,QAAQ,KAAK;AAC/B,QAAM,QAAQ,IAAI,SAAS,KAAK;AAChC,QAAM,OAAO,UAAU,cAAc;AACrC,QAAM,OAAO,UAAU,cAAc;AAErC,MAAI,KAAK,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,GAAG;AAElC,WAAO,MAAM,IACT,EAAE,GAAG,YAAY,GAAG,IAAI,EAAE,IAC1B,EAAE,GAAG,YAAY,GAAG,IAAI,IAAI,IAAI,OAAO;AAAA,EAC7C;AAEA,SAAO,MAAM,IACT,EAAE,GAAG,IAAI,GAAG,GAAG,WAAW,IAC1B,EAAE,GAAG,IAAI,IAAI,IAAI,OAAO,GAAG,WAAW;AAC5C;AAGO,SAAS,oBAAoB,OAA4B;AAC9D,QAAM,WAAW,MAAM,MAAM,YAAY;AACzC,QAAM,aAAa,MAAM,MAAM,cAAc;AAC7C,SAAO,kBAAkB,MAAM,GAAG,MAAM,GAAG,MAAM,MAAM,UAAU,UAAU;AAC7E;AAOO,SAAS,mBACd,OACA,SACA,SAC4B;AAC5B,QAAM,YAAY,MAAM;AACxB,MAAI,CAAC,UAAW,QAAO;AAEvB,QAAM,WAAW,MAAM,MAAM,YAAY;AACzC,QAAM,aAAa,MAAM,MAAM,cAAc;AAC7C,QAAM,YAAY,UAAU,UAAU,UAAW,UAAqB;AACtE,QAAM,UAAU;AAAA,IACd,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO,EAAE,GAAG,WAAW,MAAM,QAAQ;AACvC;;;ACzJO,SAAS,oBACd,UACA,QACA,YACe;AACf,MAAI,OAAO,SAAS,EAAG,QAAO;AAC9B,QAAM,OAAO,OAAO,IAAI,MAAM;AAC9B,MAAI,CAAC,KAAK,MAAM,OAAO,QAAQ,EAAG,QAAO;AAGzC,QAAM,SAAS,KAAK,IAAI,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;AAGtE,MAAI,QAAQ;AACZ,MAAI,QAAQ,OAAO,SAAS;AAC5B,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,QAAI,OAAO,CAAC,EAAE,KAAK,SAAU,SAAQ;AACrC,QAAI,OAAO,CAAC,EAAE,KAAK,UAAU;AAC3B,cAAQ;AACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAAW,WAAW,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC;AACnD,QAAM,WAAW,WAAW,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC;AACnD,MAAI,UAAU,MAAO,QAAO;AAC5B,QAAM,KAAK,WAAW,OAAO,KAAK,EAAE,MAAM,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,EAAE;AAC1E,SAAO,WAAW,KAAK,WAAW;AACpC;AAGO,SAAS,gBACdC,QACA,OACe;AACf,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,IAAI,MAAM;AAChB,QAAM,OAAO,MAAM;AAEnB,MAAI,SAAS,QAAQ;AACnB,UAAMC,QAAO,IAAI,KAAK,OAAOD,MAAK,CAAC;AACnC,QAAI,OAAO,MAAMC,MAAK,QAAQ,CAAC,EAAG,QAAO;AACzC,WAAQ,EAAgCA,KAAI;AAAA,EAC9C;AAEA,MAAI,SAAS,YAAY,SAAS,OAAO;AACvC,UAAM,MAAM,OAAOD,WAAU,WAAWA,SAAQ,OAAOA,MAAK;AAC5D,QAAI,CAAC,OAAO,SAAS,GAAG,EAAG,QAAO;AAClC,WAAQ,EAAkC,GAAG;AAAA,EAC/C;AAEA,MAAI,SAAS,QAAQ;AACnB,UAAM,YAAY;AAClB,UAAME,YAAW,OAAOF,MAAK;AAC7B,UAAM,MAAM,UAAUE,SAAQ;AAC9B,QAAI,QAAQ,OAAW,QAAO,OAAO,UAAU,YAAY,KAAK,KAAK;AAErE,UAAM,KAAK,UAAU,YAAY,KAAK;AACtC,WAAO;AAAA,MACL,OAAOA,SAAQ;AAAA,MACf,UAAU,OAAO;AAAA,MACjB,CAAC,WAAW,UAAU,KAAK,KAAK,KAAK,KAAK;AAAA,IAC5C;AAAA,EACF;AAGA,QAAM,WAAW,OAAOF,MAAK;AAC7B,QAAM,eAAgB,EAAwC,QAAQ;AACtE,MAAI,iBAAiB,OAAW,QAAO;AAEvC,MAAI,SAAS,WAAW,SAAS,WAAW;AAC1C,UAAM,SAAU,EAA6B,OAAO;AACpD,WAAO;AAAA,MACL,OAAO,QAAQ;AAAA,MACf;AAAA,MACA,CAAC,UAAW,EAA4B,KAAK,KAAK;AAAA,IACpD;AAAA,EACF;AAEA,SAAO;AACT;;;AHvEO,SAAS,wBACd,YACA,WACA,SACgD;AAChD,QAAM,aAA6D,CAAC;AAEpE,aAAW,OAAO,WAAW;AAE3B,UAAM,UAAU,IAAI,IAAI,IAAI,SAAS,UAAU,WAAW;AAC1D,eAAW,KAAK,EAAE,IAAI,GAAG,IAAI,SAAS,UAAU,KAAK,IAAI,OAAO,EAAE,CAAC;AAGnE,UAAM,UAAU,IAAI,IAAI,WAAW,WAAW,IAAI,WAAW;AAC7D,eAAW,KAAK,EAAE,IAAI,GAAG,IAAI,SAAS,UAAU,KAAK,IAAI,OAAO,EAAE,CAAC;AAGnE,UAAM,SAAS,IAAI,IAAI,WAAW,WAAW,IAAI,WAAW;AAC5D,eAAW,KAAK,EAAE,IAAI,QAAQ,IAAI,GAAG,UAAU,KAAK,IAAI,MAAM,EAAE,CAAC;AAGjE,UAAM,UAAU,IAAI,IAAI,IAAI,QAAQ,UAAU,WAAW;AACzD,eAAW,KAAK,EAAE,IAAI,SAAS,IAAI,GAAG,UAAU,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EACrE;AAEA,aAAW,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AACjD,SAAO;AACT;AAOO,SAAS,6BACd,YACA,oBACA,QACA,WACA,WACS;AACT,MAAI,WAAW,SAAS,UAAU,CAAC,WAAW,MAAO,QAAO;AAE5D,QAAM,cAAc,oBAAoB,WAAW,KAAK;AACxD,QAAM,eAAe,UAAU;AAAA,IAC7B,CAAC,QAAQ,IAAI,QAAQ,KAAK,IAAI,SAAS,KAAK,gBAAgB,aAAa,GAAG;AAAA,EAC9E;AAEA,MAAI,aAAa,WAAW,EAAG,QAAO;AAGtC,QAAM,KAAK,gBAAgB,mBAAmB,GAAG,OAAO,CAAC;AACzD,QAAM,KAAK,gBAAgB,mBAAmB,GAAG,OAAO,CAAC;AACzD,MAAI,OAAO,QAAQ,OAAO,KAAM,QAAO;AAEvC,QAAM,aAAa,wBAAwB,aAAa,cAAc,aAAa;AACnF,QAAM,WAAW,YAAY,SAAS,KAAK,IAAI,GAAG,WAAW,MAAM,KAAK,MAAM,IAAI,EAAE,MAAM;AAE1F,aAAW,EAAE,IAAI,GAAG,KAAK,YAAY;AACnC,UAAM,YAAY,WAAW,MAAM,IAAI;AACvC,UAAM,YAAY,WAAW,MAAM,IAAI;AAEvC,UAAM,iBAAgC;AAAA,MACpC,GAAG,WAAW;AAAA,MACd,GAAG;AAAA,MACH,GAAG;AAAA,MACH,WAAW,mBAAmB,EAAE,GAAG,WAAW,OAAO,GAAG,WAAW,GAAG,UAAU,GAAG,IAAI,EAAE;AAAA,IAC3F;AAEA,UAAM,kBAAkB,oBAAoB,cAAc;AAG1D,UAAM,gBAAgB,UAAU;AAAA,MAC9B,CAAC,QAAQ,IAAI,QAAQ,KAAK,IAAI,SAAS,KAAK,gBAAgB,iBAAiB,GAAG;AAAA,IAClF;AACA,QAAI,cAAe;AAKnB,UAAM,eAAe,gBAAgB,IAAI,gBAAgB,QAAQ;AACjE,UAAM,eAAe,gBAAgB,IAAI,gBAAgB,SAAS;AAIlE,UAAM,WACJ,gBAAgB,UAAU,KAC1B,gBAAgB,UAAU,IAAI,UAAU,QAAQ,MAChD,gBAAgB,UAAU,IAAI,YAC9B,gBAAgB,UAAU,IAAI,UAAU,SAAS,WAAW;AAE9D,QAAI,UAAU;AACZ,iBAAW,QAAQ;AACnB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAUO,SAAS,4BACd,aACA,eACA,QACA,WACM;AACN,QAAM,eAAuB,CAAC;AAE9B,WAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;AAC3C,UAAM,aAAa,YAAY,CAAC;AAChC,QAAI,WAAW,SAAS,UAAU,CAAC,WAAW,OAAO;AACnD;AAAA,IACF;AAEA,UAAM,SAAS,oBAAoB,WAAW,KAAK;AAGnD,UAAM,kBAAkB,aAAa;AAAA,MACnC,CAAC,OAAO,GAAG,QAAQ,KAAK,GAAG,SAAS,KAAK,gBAAgB,QAAQ,EAAE;AAAA,IACrE;AAEA,QAAI,gBAAgB,SAAS,GAAG;AAE9B,YAAM,eAAe,cAAc,CAAC;AAEpC,UAAI,cAAc,SAAS,QAAQ;AACjC,cAAM,KAAK,gBAAgB,aAAa,GAAG,OAAO,CAAC;AACnD,cAAM,KAAK,gBAAgB,aAAa,GAAG,OAAO,CAAC;AAEnD,YAAI,OAAO,QAAQ,OAAO,MAAM;AAC9B,gBAAM,aAAa,wBAAwB,QAAQ,iBAAiB,aAAa;AACjF,gBAAM,WAAW,OAAO,SAAS,KAAK,IAAI,GAAG,WAAW,MAAM,KAAK,MAAM,IAAI,EAAE,MAAM;AAErF,qBAAW,EAAE,IAAI,GAAG,KAAK,YAAY;AACnC,kBAAM,YAAY,WAAW,MAAM,IAAI;AACvC,kBAAM,YAAY,WAAW,MAAM,IAAI;AAEvC,kBAAM,iBAAgC;AAAA,cACpC,GAAG,WAAW;AAAA,cACd,GAAG;AAAA,cACH,GAAG;AAAA,YACL;AACA,kBAAM,kBAAkB,oBAAoB,cAAc;AAG1D,kBAAM,gBAAgB,aAAa;AAAA,cACjC,CAAC,OAAO,GAAG,QAAQ,KAAK,GAAG,SAAS,KAAK,gBAAgB,iBAAiB,EAAE;AAAA,YAC9E;AACA,gBAAI,cAAe;AAGnB,kBAAM,eAAe,gBAAgB,IAAI,gBAAgB,QAAQ;AACjE,kBAAM,eAAe,gBAAgB,IAAI,gBAAgB,SAAS;AAClE,kBAAM,WACJ,gBAAgB,UAAU,KAC1B,gBAAgB,UAAU,IAAI,UAAU,QAAQ,MAChD,gBAAgB,UAAU,IAAI,YAC9B,gBAAgB,UAAU,IAAI,UAAU,SAAS;AAEnD,gBAAI,UAAU;AACZ,yBAAW,QAAQ;AAAA,gBACjB,GAAG,WAAW;AAAA,gBACd,GAAG;AAAA,gBACH,GAAG;AAAA,gBACH,WAAW;AAAA,kBACT,EAAE,GAAG,WAAW,OAAO,GAAG,WAAW,GAAG,UAAU;AAAA,kBAClD;AAAA,kBACA;AAAA,gBACF;AAAA,cACF;AACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,iBAAa,KAAK,oBAAoB,WAAW,KAAK,CAAC;AAAA,EACzD;AACF;AAQO,SAAS,yBACd,aACA,UACA,WACM;AACN,aAAW,cAAc,aAAa;AACpC,QAAI,WAAW,SAAS,UAAU,CAAC,WAAW,MAAO;AAErD,UAAM,SAAS,oBAAoB,WAAW,KAAK;AACnD,QAAI,KAAK;AACT,QAAI,KAAK;AAGT,QAAI,OAAO,IAAI,OAAO,QAAQ,WAAW,cAAc;AACrD,WAAK,WAAW,gBAAgB,OAAO,IAAI,OAAO;AAAA,IACpD;AAEA,QAAI,OAAO,IAAI,KAAK,cAAc;AAChC,WAAK,eAAe,OAAO;AAAA,IAC7B;AAEA,QAAI,OAAO,IAAI,cAAc;AAC3B,WAAK,eAAe,OAAO;AAAA,IAC7B;AAEA,QAAI,OAAO,IAAI,OAAO,SAAS,KAAK,YAAY,cAAc;AAC5D,WAAK,YAAY,gBAAgB,OAAO,IAAI,OAAO;AAAA,IACrD;AAEA,QAAI,OAAO,KAAK,OAAO,EAAG;AAE1B,UAAM,OAAO,WAAW,MAAM,IAAI;AAClC,UAAM,OAAO,WAAW,MAAM,IAAI;AAElC,UAAM,YAAY,WAAW,MAAM;AACnC,eAAW,QAAQ;AAAA,MACjB,GAAG,WAAW;AAAA,MACd,GAAG;AAAA,MACH,GAAG;AAAA,MACH,WAAW,YACP;AAAA,QACE,EAAE,GAAG,WAAW,OAAO,GAAG,MAAM,GAAG,KAAK;AAAA,QACxC,UAAU,GAAG;AAAA,QACb,UAAU,GAAG;AAAA,MACf,IACA;AAAA,IACN;AAAA,EACF;AACF;;;AIpPO,SAAS,yBACd,UACA,YACA,MACA,QACW;AACX,QAAM,cAAc,SAAS,iBAAiB;AAC9C,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,UAAU,YAAY;AAAA,IACtB,YAAY,cAAc;AAAA,IAC1B,MAAM,QAAQ;AAAA,IACd,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AACF;AAEO,SAAS,sBACd,YACA,QACA,WACA,QAC2B;AAC3B,QAAM,KAAK,gBAAgB,WAAW,GAAG,OAAO,CAAC;AACjD,QAAM,KAAK,gBAAgB,WAAW,GAAG,OAAO,CAAC;AAEjD,MAAI,OAAO,QAAQ,OAAO,KAAM,QAAO;AAEvC,QAAM,kBAAkB,SAAS,iBAAiB;AAElD,QAAM,aAAa;AAAA,IACjB,WAAW;AAAA,IACX,WAAW;AAAA,IACX,WAAW,QAAQ;AAAA,IACnB;AAAA,EACF;AAGA,QAAM,cAAc,oBAAoB,WAAW,QAAQ,IAAI,IAAI,SAAS;AAC5E,QAAM,aAAa,YAAY,aAAa,WAAW,MAAM;AAE7D,QAAM,SAAS,KAAK,WAAW;AAC/B,QAAM,SAAS,KAAK,WAAW;AAG/B,QAAM,gBAAgB,WAAW,cAAc;AAC/C,QAAM,iBAAiB,WAAW,cAAc,UAAU,UAAU;AAGpE,QAAM,WAAW,WAAW,YAAY;AACxC,QAAM,aAAa,WAAW,cAAc;AAC5C,QAAM,EAAE,GAAG,gBAAgB,GAAG,eAAe,IAAI;AAAA,IAC/C;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,QAAM,WAAW,EAAE,GAAG,gBAAgB,GAAG,eAAe;AACxD,QAAM,SAAS,EAAE,GAAG,IAAI,GAAG,GAAG;AAC9B,QAAM,eAAe;AAAA,IACnB,GAAG,SAAS,KAAK,WAAW,iBAAiB,MAAM,MAAM;AAAA,IACzD,GAAG,SAAS,KAAK,WAAW,iBAAiB,MAAM,MAAM;AAAA,EAC3D;AACA,QAAM,gBAAgB;AAAA,IACpB,GAAG,OAAO,KAAK,WAAW,iBAAiB,IAAI,MAAM;AAAA,IACrD,GAAG,OAAO,KAAK,WAAW,iBAAiB,IAAI,MAAM;AAAA,EACvD;AAIA,QAAM,MAAM;AACZ,QAAM,MAAM,cAAc,IAAI,aAAa;AAC3C,QAAM,MAAM,cAAc,IAAI,aAAa;AAC3C,QAAM,OAAO,KAAK,KAAK,MAAM,MAAM,MAAM,GAAG;AAC5C,QAAM,aACJ,OAAO,MAAM,IACT,EAAE,GAAG,cAAc,IAAK,MAAM,OAAQ,KAAK,GAAG,cAAc,IAAK,MAAM,OAAQ,IAAI,IACnF;AAEN,QAAM,QAAuB;AAAA,IAC3B,MAAM,WAAW;AAAA,IACjB,GAAG;AAAA,IACH,GAAG;AAAA,IACH,OAAO;AAAA,IACP,SAAS;AAAA,IACT,WAAW,gBACP;AAAA,MACE,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,QAAQ,WAAW,UAAU;AAAA,MAC7B,OAAO;AAAA,IACT,IACA;AAAA,IACJ,YAAY,WAAW;AAAA,EACzB;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,IAAI,WAAW;AAAA,IACf;AAAA,IACA,QAAQ,WAAW;AAAA,IACnB,MAAM,WAAW;AAAA,IACjB,SAAS,WAAW;AAAA,IACpB,QAAQ,WAAW;AAAA,EACrB;AACF;;;ACrHO,SAAS,uBACd,YACA,QACA,WACA,QAC2B;AAC3B,MAAIG,KAAI,UAAU;AAClB,MAAIC,KAAI,UAAU;AAClB,MAAI,QAAQ,UAAU;AACtB,MAAI,SAAS,UAAU;AAGvB,MAAI,WAAW,OAAO,UAAa,WAAW,OAAO,QAAW;AAC9D,UAAM,OAAO,gBAAgB,WAAW,IAAI,OAAO,CAAC;AACpD,UAAM,OAAO,gBAAgB,WAAW,IAAI,OAAO,CAAC;AACpD,QAAI,SAAS,QAAQ,SAAS,KAAM,QAAO;AAE3C,IAAAD,KAAI,KAAK,IAAI,MAAM,IAAI;AACvB,YAAQ,KAAK,IAAI,OAAO,IAAI;AAAA,EAC9B;AAGA,MAAI,WAAW,OAAO,UAAa,WAAW,OAAO,QAAW;AAC9D,UAAM,OAAO,gBAAgB,WAAW,IAAI,OAAO,CAAC;AACpD,UAAM,OAAO,gBAAgB,WAAW,IAAI,OAAO,CAAC;AACpD,QAAI,SAAS,QAAQ,SAAS,KAAM,QAAO;AAE3C,IAAAC,KAAI,KAAK,IAAI,MAAM,IAAI;AACvB,aAAS,KAAK,IAAI,OAAO,IAAI;AAAA,EAC/B;AAEA,QAAM,OAAa,EAAE,GAAAD,IAAG,GAAAC,IAAG,OAAO,OAAO;AAQzC,MAAI;AACJ,MAAI,WAAW,OAAO;AACpB,UAAM,SAAS,WAAW,eAAe;AACzC,UAAM,WAAW,WAAW,SAAS,WAAW,YAAY,WAAW;AACvE,UAAM,SAAS,WAAW,IAAI,WAAW,UAAU,KAAK;AACxD,UAAM,SAAS;AACf,UAAM,aAAa,YAAY,EAAE,IAAI,QAAQ,IAAI,OAAO,GAAG,WAAW,WAAW;AAEjF,UAAM,QAAQ,yBAAyB,IAAI,KAAK,QAAW,MAAM;AACjE,QAAI,UAAU;AACZ,YAAM,aAAa;AAAA,IACrB,WAAW,WAAW,SAAS;AAC7B,YAAM,aAAa;AAAA,IACrB;AAIA,UAAM,QAAQ,WAAWD,KAAI,QAAQ,IAAI,WAAW,UAAUA,KAAI,QAAQA;AAE1E,YAAQ;AAAA,MACN,MAAM,WAAW;AAAA,MACjB,GAAG,QAAQ,WAAW;AAAA,MACtB,GAAGC,KAAI,WAAW;AAAA,MAClB;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF;AAGA,QAAM,iBAAiB,SAAS,MAAM;AAEtC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,IAAI,WAAW;AAAA,IACf;AAAA,IACA;AAAA,IACA,MAAM,WAAW,QAAQ;AAAA,IACzB,SAAS,WAAW,WAAW;AAAA,IAC/B,QAAQ,WAAW;AAAA,IACnB,QAAQ,WAAW;AAAA,EACrB;AACF;;;AC/EO,SAAS,yBACd,YACA,QACA,WACA,QAC2B;AAC3B,MAAI;AACJ,MAAI;AAEJ,MAAI,WAAW,MAAM,QAAW;AAE9B,UAAM,MAAM,gBAAgB,WAAW,GAAG,OAAO,CAAC;AAClD,QAAI,QAAQ,KAAM,QAAO;AAEzB,YAAQ,EAAE,GAAG,UAAU,GAAG,GAAG,IAAI;AACjC,UAAM,EAAE,GAAG,UAAU,IAAI,UAAU,OAAO,GAAG,IAAI;AAAA,EACnD,WAAW,WAAW,MAAM,QAAW;AAErC,UAAM,MAAM,gBAAgB,WAAW,GAAG,OAAO,CAAC;AAClD,QAAI,QAAQ,KAAM,QAAO;AAEzB,YAAQ,EAAE,GAAG,KAAK,GAAG,UAAU,EAAE;AACjC,UAAM,EAAE,GAAG,KAAK,GAAG,UAAU,IAAI,UAAU,OAAO;AAAA,EACpD,OAAO;AACL,WAAO;AAAA,EACT;AAGA,MAAI;AACJ,MAAI,WAAW,UAAU,YAAY,WAAW,UAAU,QAAW;AACnE,sBAAkB;AAAA,EACpB,WAAW,WAAW,UAAU,UAAU;AACxC,sBAAkB;AAAA,EACpB;AAaA,MAAI;AACJ,MAAI,WAAW,OAAO;AACpB,UAAM,eAAe,WAAW,MAAM;AACtC,UAAM,SAAS,WAAW,gBAAgB,eAAe,QAAQ;AAEjE,QAAI;AACJ,QAAI;AACJ,QAAI;AACJ,QAAI;AACJ,QAAI;AAEJ,QAAI,cAAc;AAChB,UAAI,WAAW,QAAQ;AACrB,iBAAS;AACT,iBAAS;AACT,iBAAS,MAAM;AACf,iBAAS,MAAM;AACf,qBAAa;AAAA,MACf,WAAW,WAAW,UAAU;AAC9B,iBAAS;AACT,iBAAS;AACT,iBAAS,IAAI;AACb,iBAAS,IAAI;AACb,qBAAa;AAAA,MACf,OAAO;AAEL,iBAAS;AACT,iBAAS;AACT,iBAAS,IAAI;AACb,iBAAS,IAAI;AACb,qBAAa;AAAA,MACf;AAAA,IACF,OAAO;AAEL,UAAI,WAAW,SAAS;AACtB,iBAAS;AACT,iBAAS;AACT,iBAAS,MAAM;AACf,iBAAS,MAAM;AACf,qBAAa;AAAA,MACf,WAAW,WAAW,UAAU;AAC9B,iBAAS;AACT,iBAAS;AACT,iBAAS,MAAM;AACf,iBAAS,IAAI;AACb,qBAAa;AAAA,MACf,OAAO;AAEL,iBAAS;AACT,iBAAS;AACT,iBAAS,MAAM;AACf,iBAAS,MAAM;AACf,qBAAa;AAAA,MACf;AAAA,IACF;AAEA,UAAM,aAAa,YAAY,EAAE,IAAI,QAAQ,IAAI,OAAO,GAAG,WAAW,WAAW;AAEjF,UAAMC,iBAAgB,SAAS,sBAAsB;AACrD,UAAM,QAAQ,yBAAyB,IAAI,KAAK,WAAW,UAAUA,gBAAe,MAAM;AAC1F,UAAM,aAAa;AAEnB,YAAQ;AAAA,MACN,MAAM,WAAW;AAAA,MACjB,GAAG,SAAS,WAAW;AAAA,MACvB,GAAG,SAAS,WAAW;AAAA,MACvB;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF;AAEA,QAAM,gBAAgB,SAAS,sBAAsB;AAErD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,IAAI,WAAW;AAAA,IACf,MAAM,EAAE,OAAO,IAAI;AAAA,IACnB;AAAA,IACA,QAAQ,WAAW,UAAU;AAAA,IAC7B;AAAA,IACA,aAAa,WAAW,eAAe;AAAA,IACvC,QAAQ,WAAW;AAAA,EACrB;AACF;;;AC7GO,SAAS,mBACd,MACA,QACA,WACA,UACA,SAAS,OACT,YAAoB,CAAC,GACrB,eACsB;AAEtB,MAAI,SAAS,uBAAuB,gBAAgB;AAClD,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,cAAoC,CAAC;AAE3C,aAAW,cAAc,KAAK,aAAa;AACzC,QAAI,WAAsC;AAE1C,YAAQ,WAAW,MAAM;AAAA,MACvB,KAAK;AACH,mBAAW,sBAAsB,YAAY,QAAQ,WAAW,MAAM;AACtE;AAAA,MACF,KAAK;AACH,mBAAW,uBAAuB,YAAY,QAAQ,WAAW,MAAM;AACvE;AAAA,MACF,KAAK;AACH,mBAAW,yBAAyB,YAAY,QAAQ,WAAW,MAAM;AACzE;AAAA,IACJ;AAEA,QAAI,UAAU;AAEZ,UAAI,WAAW,SAAS,UAAU,UAAU,SAAS,GAAG;AACtD,qCAA6B,UAAU,YAAY,QAAQ,WAAW,SAAS;AAAA,MACjF;AACA,kBAAY,KAAK,QAAQ;AAAA,IAC3B;AAAA,EACF;AAGA,8BAA4B,aAAa,KAAK,aAAa,QAAQ,SAAS;AAG5E,MAAI,eAAe;AACjB,6BAAyB,aAAa,cAAc,OAAO,cAAc,MAAM;AAAA,EACjF;AAGA,cAAY,KAAK,CAAC,GAAG,OAAO,EAAE,UAAU,MAAM,EAAE,UAAU,EAAE;AAE5D,SAAO;AACT;;;ACvEA,SAAS,qBAAqB;;;ACP9B,SAAS,iBAAiB,MAA+C;AACvE,SAAO,WAAW;AACpB;AAKA,SAAS,uBAAuB,OAAgB,MAA+B;AAC7E,QAAMC,SAAQ,MAAM,KAAK,KAAK;AAG9B,MAAI,KAAK,UAAU,QAAW;AAC5B,UAAM,UAAUA,WAAU,QAAQA,WAAU,UAAa,CAAC,OAAO,MAAMA,MAAK;AAC5E,WAAO,KAAK,QAAQ,UAAU,CAAC;AAAA,EACjC;AAIA,MAAI,KAAK,UAAU,QAAW;AAE5B,WAAOA,UAAS,KAAK;AAAA,EACvB;AAGA,QAAM,WAAW,OAAOA,MAAK;AAE7B,MAAI,KAAK,OAAO,QAAW;AACzB,WAAO,WAAW,KAAK;AAAA,EACzB;AACA,MAAI,KAAK,QAAQ,QAAW;AAC1B,WAAO,YAAY,KAAK;AAAA,EAC1B;AACA,MAAI,KAAK,OAAO,QAAW;AACzB,WAAO,WAAW,KAAK;AAAA,EACzB;AACA,MAAI,KAAK,QAAQ,QAAW;AAC1B,WAAO,YAAY,KAAK;AAAA,EAC1B;AAGA,MAAI,KAAK,UAAU,QAAW;AAC5B,UAAM,CAACC,MAAKC,IAAG,IAAI,KAAK;AACxB,WAAO,YAAYD,QAAO,YAAYC;AAAA,EACxC;AAGA,MAAI,KAAK,UAAU,QAAW;AAE5B,WAAO,KAAK,MAAM,KAAK,CAAC,MAAM,KAAKF,MAAK;AAAA,EAC1C;AAGA,SAAO;AACT;AASO,SAAS,kBAAkB,OAAgB,WAAqC;AACrF,MAAI,iBAAiB,SAAS,GAAG;AAC/B,WAAO,uBAAuB,OAAO,SAAS;AAAA,EAChD;AAEA,MAAI,SAAS,WAAW;AACtB,WAAO,UAAU,IAAI,MAAM,CAAC,MAAM,kBAAkB,OAAO,CAAC,CAAC;AAAA,EAC/D;AAEA,MAAI,QAAQ,WAAW;AACrB,WAAO,UAAU,GAAG,KAAK,CAAC,MAAM,kBAAkB,OAAO,CAAC,CAAC;AAAA,EAC7D;AAEA,MAAI,SAAS,WAAW;AACtB,WAAO,CAAC,kBAAkB,OAAO,UAAU,GAAG;AAAA,EAChD;AAEA,SAAO;AACT;;;ACvEO,SAAS,wBAAwB,OAAgB,YAA0C;AAChG,QAAM,aAAa,MAAM,QAAQ,WAAW,SAAS,IACjD,WAAW,YACX,CAAC,WAAW,SAAS;AAEzB,aAAW,QAAQ,YAAY;AAC7B,QAAI,kBAAkB,OAAO,KAAK,IAAI,GAAG;AAEvC,UAAI,KAAK,UAAU,QAAW;AAC5B,eAAO,MAAM,KAAK,KAAK;AAAA,MACzB;AACA,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AAGA,SAAO,WAAW;AACpB;AAKO,SAAS,sBAAsB,KAA0C;AAC9E,SAAO,QAAQ,QAAQ,OAAO,QAAQ,YAAY,eAAgB;AACpE;;;ACrCA,SAAS,kBAAkB,oBAAoB;AAGxC,SAAS,iBAAiBG,QAAuB;AACtD,MAAI,KAAK,IAAIA,MAAK,KAAK,IAAM,QAAO,iBAAiBA,MAAK;AAC1D,SAAO,aAAaA,MAAK;AAC3B;;;ACEO,IAAM,gBAAgB;AAetB,SAAS,WAAW,OAAgB,WAAmBC,QAA+B;AAC3F,MAAIA,UAAS,KAAM,QAAO;AAE1B,MAAI,cAAc,UAAU,cAAc,OAAO;AAC/C,UAAMC,QAAOD,kBAAiB,OAAOA,SAAQ,IAAI,KAAK,OAAOA,MAAK,CAAC;AACnE,QAAI,OAAO,MAAMC,MAAK,QAAQ,CAAC,EAAG,QAAO;AACzC,WAAQ,MAAoCA,KAAI;AAAA,EAClD;AAGA,MAAI,cAAc,WAAW,cAAc,UAAU,cAAc,WAAW;AAC5E,UAAM,SAAU,MAAiD,OAAOD,MAAK,CAAC;AAC9E,WAAO,UAAU;AAAA,EACnB;AAEA,QAAM,MAAM,OAAOA,WAAU,WAAWA,SAAQ,OAAOA,MAAK;AAC5D,MAAI,CAAC,OAAO,SAAS,GAAG,EAAG,QAAO;AAClC,SAAQ,MAAsC,GAAG;AACnD;AAYO,SAAS,aAAa,MAAiB,OAAmD;AAC/F,QAAM,SAAS,oBAAI,IAAuB;AAE1C,MAAI,CAAC,OAAO;AACV,WAAO,IAAI,eAAe,IAAI;AAC9B,WAAO;AAAA,EACT;AAEA,aAAW,OAAO,MAAM;AACtB,UAAM,MAAM,OAAO,IAAI,KAAK,KAAK,aAAa;AAC9C,UAAM,WAAW,OAAO,IAAI,GAAG;AAC/B,QAAI,UAAU;AACZ,eAAS,KAAK,GAAG;AAAA,IACnB,OAAO;AACL,aAAO,IAAI,KAAK,CAAC,GAAG,CAAC;AAAA,IACvB;AAAA,EACF;AAEA,SAAO;AACT;AAcO,SAAS,YAAY,MAAiB,OAA0B;AACrE,MAAI,KAAK,UAAU,EAAG,QAAO,CAAC,GAAG,IAAI;AAErC,SAAO,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM;AAC9B,UAAM,OAAO,EAAE,KAAK;AACpB,UAAM,OAAO,EAAE,KAAK;AAGpB,QAAI,QAAQ,QAAQ,QAAQ,KAAM,QAAO;AACzC,QAAI,QAAQ,KAAM,QAAO;AACzB,QAAI,QAAQ,KAAM,QAAO;AAGzB,QAAI,OAAO,SAAS,YAAY,OAAO,SAAS,UAAU;AACxD,aAAO,OAAO;AAAA,IAChB;AAGA,QAAI,gBAAgB,QAAQ,gBAAgB,MAAM;AAChD,aAAO,KAAK,QAAQ,IAAI,KAAK,QAAQ;AAAA,IACvC;AAGA,UAAM,OAAO,OAAO,IAAI;AACxB,UAAM,OAAO,OAAO,IAAI;AAExB,UAAM,OAAO,OAAO,IAAI;AACxB,UAAM,OAAO,OAAO,IAAI;AACxB,QAAI,OAAO,SAAS,IAAI,KAAK,OAAO,SAAS,IAAI,GAAG;AAClD,aAAO,OAAO;AAAA,IAChB;AAEA,WAAO,KAAK,cAAc,IAAI;AAAA,EAChC,CAAC;AACH;AAYO,SAAS,SACd,QACA,KACA,QACA,WAAmB,eACG;AACtB,MAAI,OAAO,SAAS,QAAQ,eAAe;AACzC,UAAM,aAAa,OAAO,MAAM;AAChC,WAAO,WAAW,GAAG;AAAA,EACvB;AACA,SAAO,OAAO,gBAAgB;AAChC;AAMO,SAAS,mBACd,QACAA,QACA,WAAmB,eACG;AACtB,MAAI,OAAO,OAAO,SAAS,cAAc;AACvC,UAAM,aAAa,OAAO,MAAM;AAChC,WAAO,WAAWA,MAAK;AAAA,EACzB;AACA,SAAO,OAAO,gBAAgB;AAChC;;;AJnIA,SAAS,+BAA+B,MAAgC;AACtE,MAAI,KAAK,aAAa,SAAU,QAAO;AACvC,QAAM,KAAK;AAGX,QAAM,qBACH,GAAG,OAAO,UAAa,GAAG,OAAO,OACjC,GAAG,OAAO,UAAa,GAAG,OAAO,OACjC,GAAG,OAAO,UAAa,GAAG,OAAO,OACjC,GAAG,OAAO,UAAa,GAAG,OAAO;AACpC,MAAI,CAAC,kBAAmB,QAAO;AAC/B,SAAO,EAAE,GAAG,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE;AAC7C;AAMA,IAAM,gBAAgB;AAaf,SAAS,gBACd,MACA,QACA,YACA,WACY;AACZ,QAAM,WAAW,KAAK;AACtB,QAAM,WAAW,SAAS;AAC1B,QAAM,WAAW,SAAS;AAE1B,MAAI,CAAC,YAAY,CAAC,YAAY,CAAC,OAAO,KAAK,CAAC,OAAO,GAAG;AACpD,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,SAAS,OAAO,EAAE;AACxB,QAAM,SAAS,OAAO,EAAE;AAGxB,MAAI,OAAO,OAAO,cAAc,YAAY;AAC1C,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,YAAY,OAAO,UAAU;AACnC,QAAM,WAAW,OAAO,CAAC;AACzB,QAAM,WAAW,SAAS,SAAS,WAAW,SAAS,QAAQ,SAAS,QAAQ;AAChF,QAAM,mBACJ,SAAS,SAAS,sBAAsB,SAAS,KAAK,IACjD,SAAS,QACV;AACN,QAAM,aAAa,UAAU;AAC7B,QAAM,oBAAoB,UAAU,SAAS;AAG7C,MAAI,CAAC,cAAc,mBAAmB;AACpC,WAAO;AAAA,MACL,KAAK;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,QAAM,iBAAiB,aAAa,KAAK,MAAM,SAAS,KAAK;AAC7D,QAAM,gBAAgB,MAAM,KAAK,eAAe,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC;AAExF,MAAI,eAAe;AACjB,UAAM,gBAAgB,SAAS,UAAU,QAAQ,SAAS,UAAU;AAEpE,QAAI,eAAe;AACjB,aAAO;AAAA,QACL,KAAK;AAAA,QACL,SAAS;AAAA,QACT,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YACJ,SAAS,UAAU,cACf,cACA,SAAS,UAAU,WACjB,WACA;AAER,WAAO;AAAA,MACL,KAAK;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,SAAS;AAAA,IACT,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGA,SAAS,mBACP,MACA,YACA,eACA,YACA,QACA,QACA,WACA,WACA,QACA,YAA6C,QACjC;AACZ,QAAM,QAAoB,CAAC;AAC3B,QAAM,iBAAiB,aAAa,MAAM,aAAa;AAEvD,aAAW,CAAC,UAAU,IAAI,KAAK,gBAAgB;AAC7C,UAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAI,UAAU,OAAW;AAGzB,QAAI,gBAAgB;AACpB,eAAW,OAAO,MAAM;AACtB,YAAM,IAAI,OAAO,IAAI,UAAU,KAAK,CAAC;AACrC,UAAI,OAAO,SAAS,CAAC,KAAK,IAAI,EAAG,kBAAiB;AAAA,IACpD;AAGA,QAAI,kBAAkB,cAAc,WAAW,CAAC,gBAAgB,IAAI;AAEpE,eAAW,OAAO,MAAM;AACtB,YAAME,YAAW,OAAO,IAAI,UAAU,KAAK,EAAE;AAC7C,YAAM,WAAW,OAAO,IAAI,UAAU,KAAK,CAAC;AAE5C,UAAI,CAAC,OAAO,SAAS,QAAQ,KAAK,YAAY,EAAG;AAGjD,YAAMC,SACJ,cAAc,eAAe,gBAAgB,IAAI,WAAW,gBAAgB;AAE9E,YAAMC,SAAQ,SAAS,QAAQF,SAAQ;AAEvC,YAAM,QAAQ,OAAO,eAAe;AACpC,YAAM,SAAS,OAAO,kBAAkBC,MAAK;AAC7C,YAAM,WAAW,KAAK,IAAI,KAAK,IAAI,SAAS,KAAK,GAAG,aAAa;AAEjE,YAAM,OAAiB;AAAA,QACrB,OAAO,GAAG,QAAQ,KAAKD,SAAQ,KAAK,iBAAiB,QAAQ,CAAC;AAAA,MAChE;AAEA,YAAM,KAAK;AAAA,QACT,MAAM;AAAA,QACN,GAAG,KAAK,IAAI,OAAO,MAAM;AAAA,QACzB,GAAG;AAAA,QACH,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,MAAM,cAAcE,MAAK,IAAI,+BAA+BA,MAAK,IAAIA;AAAA,QACrE,cAAc;AAAA,QACd,MAAM;AAAA,QACN;AAAA,QACA,QAAQ;AAAA,QACR,YAAY;AAAA,MACd,CAAC;AAED,yBAAmBD;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AACT;AAGA,SAAS,mBACP,MACA,YACA,eACA,YACA,QACA,QACA,WACA,UACA,QACY;AACZ,QAAM,QAAoB,CAAC;AAC3B,QAAM,iBAAiB,aAAa,MAAM,aAAa;AAGvD,QAAM,gBAAgB,oBAAI,IAAoB;AAC9C,aAAW,OAAO,MAAM;AACtB,UAAM,MAAM,OAAO,IAAI,UAAU,KAAK,EAAE;AACxC,QAAI,CAAC,cAAc,IAAI,GAAG,GAAG;AAC3B,oBAAc,IAAI,KAAK,cAAc,IAAI;AAAA,IAC3C;AAAA,EACF;AACA,QAAM,aAAa,cAAc;AACjC,MAAI,eAAe,EAAG,QAAO;AAG7B,QAAM,MAAM,KAAK,IAAI,GAAG,YAAY,IAAI;AACxC,QAAM,gBAAgB,KAAK,KAAK,YAAY,OAAO,aAAa,MAAM,YAAY,aAAa;AAE/F,aAAW,CAAC,UAAU,IAAI,KAAK,gBAAgB;AAC7C,UAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAI,UAAU,OAAW;AAEzB,eAAW,OAAO,MAAM;AACtB,YAAMD,YAAW,OAAO,IAAI,UAAU,KAAK,EAAE;AAC7C,YAAMC,SAAQ,OAAO,IAAI,UAAU,KAAK,CAAC;AACzC,UAAI,CAAC,OAAO,SAASA,MAAK,EAAG;AAE7B,YAAM,aAAa,cAAc,IAAID,SAAQ,KAAK;AAClD,YAAME,SAAQ,SAAS,QAAQF,SAAQ;AACvC,YAAM,OAAOC,UAAS,IAAI,WAAW,OAAOA,MAAK;AACjD,YAAM,WAAW,KAAK,IAAI,KAAK,IAAI,OAAOA,MAAK,IAAI,QAAQ,GAAG,aAAa;AAC3E,YAAM,OAAO,QAAQ,cAAc,gBAAgB;AAEnD,YAAM,OAAiB;AAAA,QACrB,OAAO,GAAG,QAAQ,KAAKD,SAAQ,KAAK,iBAAiBC,MAAK,CAAC;AAAA,MAC7D;AAEA,YAAM,KAAK;AAAA,QACT,MAAM;AAAA,QACN,GAAG;AAAA,QACH,GAAG;AAAA,QACH,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,MAAM,cAAcC,MAAK,IAAI,+BAA+BA,MAAK,IAAIA;AAAA,QACrE,cAAc;AAAA,QACd,MAAM;AAAA,QACN;AAAA,QACA,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAIA,SAAS,mBACP,MACA,YACA,eACA,YACA,QACA,QACA,WACA,UACA,QACY;AACZ,QAAM,QAAoB,CAAC;AAE3B,aAAW,OAAO,MAAM;AACtB,UAAM,WAAW,OAAO,IAAI,aAAa,KAAK,EAAE;AAChD,UAAMD,SAAQ,OAAO,IAAI,UAAU,KAAK,CAAC;AACzC,QAAI,CAAC,OAAO,SAASA,MAAK,EAAG;AAE7B,UAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAI,UAAU,OAAW;AAEzB,UAAMD,YAAW,OAAO,IAAI,UAAU,KAAK,EAAE;AAC7C,UAAME,SAAQ,SAAS,QAAQF,SAAQ;AACvC,UAAM,OAAOC,UAAS,IAAI,WAAW,OAAOA,MAAK;AACjD,UAAM,WAAW,KAAK,IAAI,KAAK,IAAI,OAAOA,MAAK,IAAI,QAAQ,GAAG,aAAa;AAE3E,UAAM,OAAiB;AAAA,MACrB,OAAO,GAAG,QAAQ,KAAKD,SAAQ,KAAK,iBAAiBC,MAAK,CAAC;AAAA,IAC7D;AAEA,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,GAAG;AAAA,MACH,GAAG;AAAA,MACH,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,MAAM,cAAcC,MAAK,IAAI,+BAA+BA,MAAK,IAAIA;AAAA,MACrE,cAAc;AAAA,MACd,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAGA,SAAS,kBACP,MACA,YACA,eACA,QACA,QACA,WACA,UACA,QACA,kBAAkB,OAClB,kBACY;AACZ,QAAM,QAAoB,CAAC;AAE3B,aAAW,OAAO,MAAM;AACtB,UAAM,WAAW,OAAO,IAAI,aAAa,KAAK,EAAE;AAChD,UAAMD,SAAQ,OAAO,IAAI,UAAU,KAAK,CAAC;AACzC,QAAI,CAAC,OAAO,SAASA,MAAK,EAAG;AAE7B,UAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAI,UAAU,OAAW;AAEzB,QAAIC;AACJ,QAAI,kBAAkB;AACpB,YAAM,WAAW,wBAAwB,KAAK,gBAAgB;AAC9D,UAAI,YAAY,MAAM;AACpB,QAAAA,SAAQ,cAAc,QAAQ,IAAI,WAAW,OAAO,QAAQ;AAAA,MAC9D,OAAO;AACL,QAAAA,SAAQ,SAAS,QAAQ,aAAa;AAAA,MACxC;AAAA,IACF,WAAW,iBAAiB;AAC1B,MAAAA,SAAQ,mBAAmB,QAAQD,MAAK;AAAA,IAC1C,OAAO;AACL,MAAAC,SAAQ,SAAS,QAAQ,aAAa;AAAA,IACxC;AACA,UAAM,OAAOD,UAAS,IAAI,WAAW,OAAOA,MAAK;AACjD,UAAM,WAAW,KAAK,IAAI,KAAK,IAAI,OAAOA,MAAK,IAAI,QAAQ,GAAG,aAAa;AAE3E,UAAM,OAAiB;AAAA,MACrB,OAAO,GAAG,QAAQ,KAAK,iBAAiBA,MAAK,CAAC;AAAA,IAChD;AAEA,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,GAAG;AAAA,MACH,GAAG;AAAA,MACH,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,MAAM,cAAcC,MAAK,IAAI,+BAA+BA,MAAK,IAAIA;AAAA,MACrE,cAAc;AAAA,MACd,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AK7YA;AAAA,EACE;AAAA,EACA,qBAAAC;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACLA,SAAS,gBAAmB,OAAY,SAA4B;AACzE,MAAI,YAAY,OAAQ,QAAO,CAAC;AAChC,MAAI,YAAY,eAAe,MAAM,SAAS,GAAG;AAC/C,WAAO,CAAC,MAAM,CAAC,GAAG,MAAM,MAAM,SAAS,CAAC,CAAC;AAAA,EAC3C;AACA,SAAO;AACT;;;ADQA,IAAM,qBAA6C;AAAA,EACjD,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAOA,SAAS,mBAAmB,KAAqB;AAE/C,QAAM,UAAU,IAAI,KAAK,EAAE,QAAQ,WAAW,GAAG;AACjD,MAAI,CAAC,QAAS,QAAO;AAGrB,QAAM,OAAO,QAAQ,QAAQ,SAAS,CAAC,EAAE,YAAY;AACrD,QAAM,aAAa,mBAAmB,IAAI;AAC1C,MAAI,YAAY;AACd,UAAM,UAAU,QAAQ,MAAM,GAAG,EAAE,EAAE,QAAQ,MAAM,EAAE;AACrD,UAAM,IAAI,OAAO,OAAO;AACxB,WAAO,OAAO,MAAM,CAAC,IAAI,MAAM,IAAI;AAAA,EACrC;AAGA,MAAI,SAAS,KAAK;AAChB,WAAO,OAAO,QAAQ,MAAM,GAAG,EAAE,EAAE,QAAQ,MAAM,EAAE,CAAC;AAAA,EACtD;AAGA,SAAO,OAAO,QAAQ,QAAQ,MAAM,EAAE,CAAC;AACzC;AAMA,IAAM,kBAAkB;AACxB,IAAM,oBAAoB;AAC1B,IAAM,gBAAgB;AACtB,IAAM,6BAA6B;AAa5B,SAAS,iBACd,OACA,YACA,UAAwB,QACxB,aACA,aACA,YACiB;AACjB,QAAM,cAAc,gBAAgB,OAAO,OAAO;AAElD,QAAM,aAA+B,CAAC;AAGtC,QAAM,gBAA2B,CAAC;AAElC,QAAM,YAAY,iBAAiB,WAAW;AAE9C,aAAW,QAAQ,aAAa;AAI9B,QAAI;AACJ,UAAM,SAAS,cAAc,OAAO,OAAO,KAAK,KAAK,UAAU,CAAC,IAAI;AAEpE,QAAI,aAAa,OAAO,SAAS,MAAM,GAAG;AACxC,kBAAY,UAAU,MAAM;AAAA,IAC9B,WAAW,OAAO,SAAS,MAAM,GAAG;AAClC,kBAAY,iBAAiB,MAAM;AAAA,IACrC,OAAO;AAEL,YAAM,YAAY,KAAK,KAAK;AAC5B,YAAM,YAAY,UAAU,YAAY,GAAG;AAC3C,YAAM,WAAW,aAAa,IAAI,UAAU,MAAM,YAAY,CAAC,EAAE,KAAK,IAAI;AAC1E,UAAI,CAAC,SAAU;AACf,UAAI,WAAW;AACb,cAAM,MAAM,mBAAmB,QAAQ;AACvC,oBAAY,CAAC,OAAO,MAAM,GAAG,IAAI,UAAU,GAAG,IAAI;AAAA,MACpD,OAAO;AACL,oBAAY;AAAA,MACd;AAAA,IACF;AACA,QAAI,YAAa,aAAY,cAAc;AAE3C,UAAM,YAAYC,mBAAkB,WAAW,iBAAiB,iBAAiB;AACjF,UAAM,aAAa,kBAAkB;AAGrC,UAAM,YAAY,KAAK,iBAAiB;AAGxC,UAAM,WAAW,KAAK,SAAS;AAE/B,QAAI;AACJ,QAAI;AACJ,QAAI;AAEJ,QAAI,aAAa,UAAU;AAEzB,gBAAU,KAAK,IAAI,KAAK,QAAQ;AAChC,aAAO;AACP,mBAAa;AAAA,IACf,WAAW,UAAU;AAEnB,gBAAU,KAAK,IAAI,KAAK,QAAQ;AAChC,aAAO;AACP,mBAAa;AAAA,IACf,OAAO;AAEL,gBAAU,KAAK,IAAI,KAAK,QAAQ;AAChC,aAAO,uBAAuB,KAAK,IAAI;AACvC,mBAAa;AAAA,IACf;AAIA,UAAM,UAAU,KAAK,IAAI,KAAK,SAAS;AAGvC,UAAM,OAAO,EAAE,aAAa,YAAY,KAAK,QAAQ,IAAI;AAEzD,kBAAc,KAAK,IAAI;AACvB,eAAW,KAAK;AAAA,MACd,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,OAAO;AAAA,QACL,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,YAAY;AAAA,QACZ;AAAA,QACA,YAAY;AAAA,QACZ;AAAA,QACA,kBAAkB;AAAA,MACpB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,WAAW,WAAW,EAAG,QAAO,CAAC;AAIrC,MAAI,YAAY,OAAO;AACrB,WAAO,WAAW,IAAI,CAAC,GAAG,OAAO;AAAA,MAC/B,MAAM,EAAE;AAAA,MACR,GAAG,EAAE;AAAA,MACL,GAAG,EAAE;AAAA,MACL,OAAO,EAAE;AAAA,MACT,SAAS,cAAc,CAAC,MAAM;AAAA,IAChC,EAAE;AAAA,EACJ;AAIA,QAAM,oBAAsC,CAAC;AAC7C,QAAM,mBAAmB,oBAAI,IAAY;AACzC,WAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,QAAI,cAAc,CAAC,MAAM,OAAO;AAC9B,uBAAiB,IAAI,CAAC;AAAA,IACxB,OAAO;AACL,wBAAkB,KAAK,WAAW,CAAC,CAAC;AAAA,IACtC;AAAA,EACF;AAEA,QAAM,WAAW,kBAAkB,iBAAiB;AAGpD,QAAM,UAA2B,CAAC;AAClC,MAAI,cAAc;AAClB,WAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,QAAI,iBAAiB,IAAI,CAAC,GAAG;AAC3B,cAAQ,KAAK;AAAA,QACX,MAAM,WAAW,CAAC,EAAE;AAAA,QACpB,GAAG,WAAW,CAAC,EAAE;AAAA,QACjB,GAAG,WAAW,CAAC,EAAE;AAAA,QACjB,OAAO,WAAW,CAAC,EAAE;AAAA,QACrB,SAAS;AAAA,MACX,CAAC;AAAA,IACH,OAAO;AACL,cAAQ,KAAK,SAAS,aAAa,CAAC;AAAA,IACtC;AAAA,EACF;AAEA,SAAO;AACT;;;AE3NO,IAAM,cAA6B,CAAC,MAAM,QAAQ,WAAW,UAAU,WAAW;AACvF,QAAM,QAAQ,gBAAgB,MAAM,QAAQ,WAAW,QAAQ;AAG/D,QAAM,aACJ,KAAK,UAAU,KAAK,WAAW,KAAK,SAAS,IAAI,KAAK,SAAS,EAAE,QAAQ;AAC3E,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA,KAAK,OAAO;AAAA,IACZ,KAAK,OAAO;AAAA,IACZ,KAAK,OAAO;AAAA,IACZ;AAAA,EACF;AACA,WAAS,IAAI,GAAG,IAAI,MAAM,UAAU,IAAI,OAAO,QAAQ,KAAK;AAC1D,UAAM,CAAC,EAAE,QAAQ,OAAO,CAAC;AAAA,EAC3B;AAEA,SAAO;AACT;;;ACZA,SAAS,iBAAAC,sBAAqB;AAY9B,IAAM,oBAAoB;AAanB,SAAS,mBACd,MACA,QACA,YACA,WACY;AACZ,QAAM,WAAW,KAAK;AACtB,QAAM,WAAW,SAAS;AAC1B,QAAM,WAAW,SAAS;AAE1B,MAAI,CAAC,YAAY,CAAC,YAAY,CAAC,OAAO,KAAK,CAAC,OAAO,GAAG;AACpD,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,SAAS,OAAO,EAAE;AACxB,QAAM,SAAS,OAAO,EAAE;AAGxB,MAAI,OAAO,OAAO,cAAc,YAAY;AAC1C,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,YAAY,OAAO,UAAU;AACnC,QAAM,WAAW,OAAO,CAAC;AACzB,QAAM,WAAW,SAAS,SAAS,WAAW,SAAS,QAAQ,SAAS,QAAQ;AAChF,QAAM,mBACJ,SAAS,SAAS,sBAAsB,SAAS,KAAK,IACjD,SAAS,QACV;AACN,QAAM,aAAa,UAAU;AAE7B,QAAM,oBAAoB,UAAU,SAAS;AAG7C,MAAI,cAAc,CAAC,mBAAmB;AAEpC,UAAM,iBAAiB,aAAa,KAAK,MAAM,SAAS,KAAK;AAC7D,UAAM,gBAAgB,MAAM,KAAK,eAAe,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC;AAExF,QAAI,eAAe;AACjB,YAAM,gBAAgB,SAAS,UAAU,QAAQ,SAAS,UAAU;AAEpE,UAAI,eAAe;AACjB,eAAO;AAAA,UACL,KAAK;AAAA,UACL,SAAS;AAAA,UACT,SAAS;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAEA,YAAM,YACJ,SAAS,UAAU,cACf,cACA,SAAS,UAAU,WACjB,WACA;AAER,aAAO;AAAA,QACL,KAAK;AAAA,QACL,SAAS;AAAA,QACT,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,WAAO;AAAA,MACL,KAAK;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,SAAS;AAAA,IACT,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGA,SAAS,qBACP,MACA,eACA,YACA,QACA,QACA,WACA,UACA,QACA,kBAAkB,OAClB,kBACY;AACZ,QAAM,QAAoB,CAAC;AAE3B,aAAW,OAAO,MAAM;AACtB,UAAM,WAAW,OAAO,IAAI,aAAa,KAAK,EAAE;AAChD,UAAMC,SAAQ,OAAO,IAAI,UAAU,KAAK,CAAC;AACzC,QAAI,CAAC,OAAO,SAASA,MAAK,EAAG;AAE7B,UAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAI,UAAU,OAAW;AAEzB,QAAIC;AACJ,QAAI,kBAAkB;AACpB,YAAM,WAAW,wBAAwB,KAAK,gBAAgB;AAC9D,UAAI,YAAY,MAAM;AACpB,QAAAA,SAAQC,eAAc,QAAQ,IAAI,WAAW,OAAO,QAAQ;AAAA,MAC9D,OAAO;AACL,QAAAD,SAAQ,SAAS,QAAQ,aAAa;AAAA,MACxC;AAAA,IACF,WAAW,iBAAiB;AAC1B,MAAAA,SAAQ,mBAAmB,QAAQD,MAAK;AAAA,IAC1C,OAAO;AACL,MAAAC,SAAQ,SAAS,QAAQ,aAAa;AAAA,IACxC;AACA,UAAM,OAAO,OAAOD,MAAK;AACzB,UAAM,eAAe,KAAK,IAAI,KAAK,IAAI,WAAW,IAAI,GAAG,iBAAiB;AAI1E,UAAMG,KAAIH,UAAS,IAAI,OAAO;AAE9B,UAAM,OAAiB;AAAA,MACrB,OAAO,GAAG,QAAQ,KAAK,iBAAiBA,MAAK,CAAC;AAAA,IAChD;AAEA,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,GAAG;AAAA,MACH,GAAAG;AAAA,MACA,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,MAAMF;AAAA,MACN,cAAc;AAAA,MACd,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAIA,SAAS,sBACP,MACA,eACA,YACA,YACA,QACA,QACA,WACA,UACA,QACY;AACZ,QAAM,QAAoB,CAAC;AAE3B,aAAW,OAAO,MAAM;AACtB,UAAM,WAAW,OAAO,IAAI,aAAa,KAAK,EAAE;AAChD,UAAMD,SAAQ,OAAO,IAAI,UAAU,KAAK,CAAC;AACzC,QAAI,CAAC,OAAO,SAASA,MAAK,EAAG;AAE7B,UAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAI,UAAU,OAAW;AAEzB,UAAMI,YAAW,OAAO,IAAI,UAAU,KAAK,EAAE;AAC7C,UAAMH,SAAQ,SAAS,QAAQG,SAAQ;AACvC,UAAM,OAAO,OAAOJ,MAAK;AACzB,UAAM,eAAe,KAAK,IAAI,KAAK,IAAI,WAAW,IAAI,GAAG,iBAAiB;AAE1E,UAAMG,KAAIH,UAAS,IAAI,OAAO;AAE9B,UAAM,OAAiB;AAAA,MACrB,OAAO,GAAG,QAAQ,KAAKI,SAAQ,KAAK,iBAAiBJ,MAAK,CAAC;AAAA,IAC7D;AAEA,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,GAAG;AAAA,MACH,GAAAG;AAAA,MACA,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,MAAMF;AAAA,MACN,cAAc;AAAA,MACd,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAGA,SAAS,sBACP,MACA,eACA,YACA,YACA,QACA,QACA,WACA,UACA,QACY;AACZ,QAAM,QAAoB,CAAC;AAC3B,QAAM,iBAAiB,aAAa,MAAM,aAAa;AAGvD,QAAM,gBAAgB,oBAAI,IAAoB;AAC9C,aAAW,OAAO,MAAM;AACtB,UAAM,MAAM,OAAO,IAAI,UAAU,KAAK,EAAE;AACxC,QAAI,CAAC,cAAc,IAAI,GAAG,GAAG;AAC3B,oBAAc,IAAI,KAAK,cAAc,IAAI;AAAA,IAC3C;AAAA,EACF;AACA,QAAM,aAAa,cAAc;AACjC,MAAI,eAAe,EAAG,QAAO;AAG7B,QAAM,MAAM,KAAK,IAAI,GAAG,YAAY,IAAI;AACxC,QAAM,eAAe,KAAK;AAAA,KACvB,YAAY,OAAO,aAAa,MAAM;AAAA,IACvC;AAAA,EACF;AAEA,aAAW,CAAC,UAAU,IAAI,KAAK,gBAAgB;AAC7C,UAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAI,UAAU,OAAW;AAEzB,eAAW,OAAO,MAAM;AACtB,YAAMG,YAAW,OAAO,IAAI,UAAU,KAAK,EAAE;AAC7C,YAAMJ,SAAQ,OAAO,IAAI,UAAU,KAAK,CAAC;AACzC,UAAI,CAAC,OAAO,SAASA,MAAK,EAAG;AAE7B,YAAM,aAAa,cAAc,IAAII,SAAQ,KAAK;AAClD,YAAMH,SAAQ,SAAS,QAAQG,SAAQ;AACvC,YAAM,OAAO,OAAOJ,MAAK;AACzB,YAAM,eAAe,KAAK,IAAI,KAAK,IAAI,WAAW,IAAI,GAAG,iBAAiB;AAC1E,YAAMG,KAAIH,UAAS,IAAI,OAAO;AAC9B,YAAM,OAAO,QAAQ,cAAc,eAAe;AAElD,YAAM,OAAiB;AAAA,QACrB,OAAO,GAAG,QAAQ,KAAKI,SAAQ,KAAK,iBAAiBJ,MAAK,CAAC;AAAA,MAC7D;AAEA,YAAM,KAAK;AAAA,QACT,MAAM;AAAA,QACN,GAAG;AAAA,QACH,GAAAG;AAAA,QACA,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,MAAMF;AAAA,QACN,cAAc;AAAA,QACd,MAAM;AAAA,QACN;AAAA,QACA,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAGA,SAAS,sBACP,MACA,eACA,YACA,YACA,QACA,QACA,WACA,WACA,QACA,YAA6C,QACjC;AACZ,QAAM,QAAoB,CAAC;AAC3B,QAAM,iBAAiB,aAAa,MAAM,aAAa;AAEvD,aAAW,CAAC,UAAU,IAAI,KAAK,gBAAgB;AAC7C,UAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAI,UAAU,OAAW;AAGzB,QAAI,gBAAgB;AACpB,eAAW,OAAO,MAAM;AACtB,YAAM,IAAI,OAAO,IAAI,UAAU,KAAK,CAAC;AACrC,UAAI,OAAO,SAAS,CAAC,KAAK,IAAI,EAAG,kBAAiB;AAAA,IACpD;AAGA,QAAI,kBAAkB,cAAc,WAAW,CAAC,gBAAgB,IAAI;AAEpE,eAAW,OAAO,MAAM;AACtB,YAAMG,YAAW,OAAO,IAAI,UAAU,KAAK,EAAE;AAC7C,YAAM,WAAW,OAAO,IAAI,UAAU,KAAK,CAAC;AAG5C,UAAI,CAAC,OAAO,SAAS,QAAQ,KAAK,YAAY,EAAG;AAGjD,YAAMJ,SACJ,cAAc,eAAe,gBAAgB,IAAI,WAAW,gBAAgB;AAE9E,YAAMC,SAAQ,SAAS,QAAQG,SAAQ;AAEvC,YAAM,OAAO,OAAO,kBAAkBJ,MAAK;AAC3C,YAAM,UAAU,OAAO,eAAe;AACtC,YAAM,eAAe,KAAK,IAAI,KAAK,IAAI,UAAU,IAAI,GAAG,iBAAiB;AAEzE,YAAM,OAAiB;AAAA,QACrB,OAAO,GAAG,QAAQ,KAAKI,SAAQ,KAAK,iBAAiB,QAAQ,CAAC;AAAA,MAChE;AAEA,YAAM,KAAK;AAAA,QACT,MAAM;AAAA,QACN,GAAG;AAAA,QACH,GAAG,KAAK,IAAI,MAAM,OAAO;AAAA,QACzB,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,MAAMH;AAAA,QACN,cAAc;AAAA,QACd,MAAM;AAAA,QACN;AAAA,QACA,QAAQ;AAAA,QACR,YAAY;AAAA,MACd,CAAC;AAED,yBAAmBD;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AACT;;;ACrYA;AAAA,EACE,oBAAAK;AAAA,EACA,qBAAAC;AAAA,EACA,0BAAAC;AAAA,EACA,qBAAAC;AAAA,OACK;AAQP,IAAMC,mBAAkB;AACxB,IAAMC,qBAAoB;AAC1B,IAAM,iBAAiB;AAWhB,SAAS,oBACd,OACA,YACA,UAAwB,QACxB,aACA,aACA,YACiB;AACjB,QAAM,cAAc,gBAAgB,OAAO,OAAO;AAElD,QAAM,YAAYC,kBAAiB,WAAW;AAE9C,QAAM,aAA+B,CAAC;AAEtC,aAAW,QAAQ,aAAa;AAI9B,QAAI;AACJ,UAAM,SAAS,cAAc,OAAO,OAAO,KAAK,KAAK,UAAU,CAAC,IAAI;AAEpE,QAAI,aAAa,OAAO,SAAS,MAAM,GAAG;AACxC,kBAAY,UAAU,MAAM;AAAA,IAC9B,WAAW,OAAO,SAAS,MAAM,GAAG;AAClC,kBAAY,iBAAiB,MAAM;AAAA,IACrC,OAAO;AAEL,YAAM,YAAY,KAAK,KAAK;AAC5B,YAAM,YAAY,UAAU,YAAY,GAAG;AAC3C,YAAM,WAAW,aAAa,IAAI,UAAU,MAAM,YAAY,CAAC,EAAE,KAAK,IAAI;AAC1E,UAAI,CAAC,SAAU;AACf,UAAI,WAAW;AACb,cAAM,MAAM,OAAO,SAAS,QAAQ,aAAa,EAAE,CAAC;AACpD,oBAAY,CAAC,OAAO,MAAM,GAAG,IAAI,UAAU,GAAG,IAAI;AAAA,MACpD,OAAO;AACL,oBAAY;AAAA,MACd;AAAA,IACF;AACA,QAAI,YAAa,aAAY,cAAc;AAE3C,UAAM,eAAe,WAAW,SAAS;AACzC,UAAM,aAAa,OAAO,SAAS,YAAY,KAAK,eAAe;AAEnE,UAAM,YAAYC,mBAAkB,WAAWH,kBAAiBC,kBAAiB;AACjF,UAAM,aAAaD,mBAAkB;AAIrC,UAAM,UAAU,KAAK,IAAI,KAAK,QAAQ;AACtC,UAAM,UAAU,aACZ,KAAK,IAAI,KAAK,SAAS,iBACvB,KAAK,IAAI,iBAAiB;AAE9B,eAAW,KAAK;AAAA,MACd,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,OAAO;AAAA,QACL,YAAY;AAAA,QACZ,UAAUA;AAAA,QACV,YAAYC;AAAA,QACZ,MAAMG,wBAAuB,KAAK,IAAI;AAAA,QACtC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,kBAAkB,aAAa,YAAY;AAAA,MAC7C;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,WAAW,WAAW,EAAG,QAAO,CAAC;AAGrC,MAAI,YAAY,OAAO;AACrB,WAAO,WAAW,IAAI,CAAC,OAAO;AAAA,MAC5B,MAAM,EAAE;AAAA,MACR,GAAG,EAAE;AAAA,MACL,GAAG,EAAE;AAAA,MACL,OAAO,EAAE;AAAA,MACT,SAAS;AAAA,IACX,EAAE;AAAA,EACJ;AAEA,SAAOC,mBAAkB,UAAU;AACrC;;;ACpHO,IAAM,iBAAgC,CAAC,MAAM,QAAQ,WAAW,UAAU,WAAW;AAC1F,QAAM,QAAQ,mBAAmB,MAAM,QAAQ,WAAW,QAAQ;AAGlE,QAAM,aACJ,KAAK,UAAU,KAAK,WAAW,KAAK,SAAS,IAAI,KAAK,SAAS,EAAE,QAAQ;AAC3E,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA,KAAK,OAAO;AAAA,IACZ,KAAK,OAAO;AAAA,IACZ,KAAK,OAAO;AAAA,IACZ;AAAA,EACF;AACA,WAAS,IAAI,GAAG,IAAI,MAAM,UAAU,IAAI,OAAO,QAAQ,KAAK;AAC1D,UAAM,CAAC,EAAE,QAAQ,OAAO,CAAC;AAAA,EAC3B;AAEA,SAAO;AACT;;;ACJA,IAAM,aAAa;AACnB,IAAM,aAAa;AACnB,IAAM,aAAa;AAcZ,SAAS,gBACd,MACA,QACA,YACA,WAC0B;AAC1B,QAAM,WAAW,KAAK;AACtB,QAAM,WAAW,SAAS;AAC1B,QAAM,WAAW,SAAS;AAE1B,MAAI,CAAC,YAAY,CAAC,YAAY,CAAC,OAAO,KAAK,CAAC,OAAO,GAAG;AACpD,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,SAAS,OAAO,EAAE;AACxB,QAAM,SAAS,OAAO,EAAE;AAGxB,MAAI,OAAO,OAAO,cAAc,YAAY;AAC1C,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,YAAY,OAAO,UAAU;AACnC,QAAM,WAAW,OAAO,CAAC;AACzB,QAAM,WAAW,SAAS,SAAS,WAAW,SAAS,QAAQ,SAAS,QAAQ;AAChF,QAAM,oBAAoB,UAAU,SAAS;AAC7C,QAAM,aAAa,oBAAoB,SAAY,UAAU;AAG7D,MAAI,YAAY;AACd,WAAO;AAAA,MACL,KAAK;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,SAAS;AAAA,IACT,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAOA,SAAS,qBACP,MACA,YACA,eACA,YACA,QACA,QACA,WACA,QAC0B;AAC1B,QAAM,QAAkC,CAAC;AACzC,QAAM,iBAAiB,aAAa,CAAC,GAAG,IAAI,GAAG,aAAa;AAE5D,aAAW,CAAC,UAAU,IAAI,KAAK,gBAAgB;AAC7C,UAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAI,UAAU,OAAW;AAEzB,UAAM,KAAK,QAAQ,YAAY;AAG/B,UAAM,UAAoB,CAAC;AAC3B,eAAW,OAAO,MAAM;AACtB,YAAMC,SAAQ,OAAO,IAAI,UAAU,KAAK,CAAC;AACzC,UAAI,OAAO,SAASA,MAAK,EAAG,SAAQ,KAAKA,MAAK;AAAA,IAChD;AAEA,QAAI,QAAQ,WAAW,EAAG;AAE1B,UAAM,SAAS,KAAK,IAAI,GAAG,OAAO;AAClC,UAAM,SAAS,KAAK,IAAI,GAAG,OAAO;AAClC,UAAM,QAAQ,OAAO,MAAM;AAC3B,UAAM,SAAS,OAAO,MAAM;AAC5B,UAAM,WAAW,KAAK,IAAI,SAAS,KAAK;AAGxC,QAAI,WAAW,GAAG;AAChB,YAAM,WAAqB;AAAA,QACzB,OAAO,aAAa,QAAQ,KAAK,MAAM,OAAO,MAAM;AAAA,MACtD;AAEA,YAAM,KAAK;AAAA,QACT,MAAM;AAAA,QACN,GAAG,KAAK,IAAI,OAAO,MAAM;AAAA,QACzB,GAAG,KAAK,aAAa;AAAA,QACrB,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,MAAM,KAAK,CAAC;AAAA,QACZ,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAGA,eAAW,OAAO,MAAM;AACtB,YAAMA,SAAQ,OAAO,IAAI,UAAU,KAAK,CAAC;AACzC,UAAI,CAAC,OAAO,SAASA,MAAK,EAAG;AAE7B,YAAM,KAAK,OAAOA,MAAK;AACvB,YAAM,gBAAgB,OAAO,IAAI,UAAU,KAAK,EAAE;AAClD,YAAMC,SAAQ,SAAS,QAAQ,aAAa;AAE5C,YAAM,UAAoB;AAAA,QACxB,OAAO,GAAG,QAAQ,KAAK,aAAa,KAAKD,MAAK;AAAA,MAChD;AAEA,YAAM,KAAK;AAAA,QACT,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,GAAG;AAAA,QACH,MAAMC;AAAA,QACN,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,MAAM;AAAA,QACN,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAOA,SAAS,qBACP,MACA,YACA,eACA,QACA,QACA,WACA,UACA,QACA,oBAAoB,OACM;AAC1B,QAAM,QAAkC,CAAC;AAEzC,aAAW,OAAO,MAAM;AACtB,UAAM,WAAW,OAAO,IAAI,aAAa,KAAK,EAAE;AAChD,UAAMD,SAAQ,OAAO,IAAI,UAAU,KAAK,CAAC;AACzC,QAAI,CAAC,OAAO,SAASA,MAAK,EAAG;AAE7B,UAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAI,UAAU,OAAW;AAEzB,UAAM,KAAK,OAAOA,MAAK;AACvB,UAAM,KAAK,QAAQ,YAAY;AAE/B,UAAMC,SAAQ,oBACV,mBAAmB,QAAQD,MAAK,IAChC,SAAS,QAAQ,aAAa;AAGlC,UAAM,QAAQ,KAAK,IAAI,UAAU,EAAE;AACnC,UAAM,YAAY,KAAK,IAAI,KAAK,QAAQ;AAExC,QAAI,YAAY,GAAG;AACjB,YAAM,WAAqB;AAAA,QACzB,OAAO,YAAY,QAAQ;AAAA,MAC7B;AAEA,YAAM,KAAK;AAAA,QACT,MAAM;AAAA,QACN,GAAG;AAAA,QACH,GAAG,KAAK,aAAa;AAAA,QACrB,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAGA,UAAM,UAAoB;AAAA,MACxB,OAAO,GAAG,QAAQ,KAAKA,MAAK;AAAA,IAC9B;AAEA,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,GAAG;AAAA,MACH,MAAMC;AAAA,MACN,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;ACnPA;AAAA,EACE,oBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,0BAAAC;AAAA,EACA,qBAAAC;AAAA,OACK;AAQP,IAAMC,mBAAkB;AACxB,IAAMC,qBAAoB;AAC1B,IAAM,iBAAiB;AAWhB,SAAS,iBACd,OACA,YACA,UAAwB,QACxB,aACA,aACA,YACiB;AACjB,QAAM,cAAc,gBAAgB,OAAO,OAAO;AAElD,QAAM,YAAYC,kBAAiB,WAAW;AAC9C,QAAM,aAA+B,CAAC;AAEtC,aAAW,QAAQ,aAAa;AAI9B,QAAI;AACJ,UAAM,SAAS,cAAc,OAAO,OAAO,KAAK,KAAK,UAAU,CAAC,IAAI;AAEpE,QAAI,aAAa,OAAO,SAAS,MAAM,GAAG;AACxC,kBAAY,UAAU,MAAM;AAAA,IAC9B,WAAW,OAAO,SAAS,MAAM,GAAG;AAClC,kBAAY,iBAAiB,MAAM;AAAA,IACrC,OAAO;AAEL,YAAM,YAAY,KAAK,KAAK;AAC5B,YAAM,YAAY,UAAU,YAAY,GAAG;AAC3C,kBAAY,aAAa,IAAI,UAAU,MAAM,YAAY,CAAC,EAAE,KAAK,IAAI;AACrE,UAAI,CAAC,UAAW;AAChB,UAAI,WAAW;AACb,cAAM,MAAM,OAAO,UAAU,QAAQ,aAAa,EAAE,CAAC;AACrD,YAAI,CAAC,OAAO,MAAM,GAAG,EAAG,aAAY,UAAU,GAAG;AAAA,MACnD;AAAA,IACF;AACA,QAAI,YAAa,aAAY,cAAc;AAE3C,UAAM,YAAYC,mBAAkB,WAAWH,kBAAiBC,kBAAiB;AACjF,UAAM,aAAaD,mBAAkB;AAErC,eAAW,KAAK;AAAA,MACd,MAAM;AAAA,MACN,SAAS,KAAK,KAAK,KAAK,IAAI;AAAA,MAC5B,SAAS,KAAK,KAAK,aAAa;AAAA,MAChC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,OAAO;AAAA,QACL,YAAY;AAAA,QACZ,UAAUA;AAAA,QACV,YAAYC;AAAA,QACZ,MAAMG,wBAAuB,KAAK,IAAI;AAAA,QACtC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,kBAAkB;AAAA,MACpB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,WAAW,WAAW,EAAG,QAAO,CAAC;AAGrC,MAAI,YAAY,OAAO;AACrB,WAAO,WAAW,IAAI,CAAC,OAAO;AAAA,MAC5B,MAAM,EAAE;AAAA,MACR,GAAG,EAAE;AAAA,MACL,GAAG,EAAE;AAAA,MACL,OAAO,EAAE;AAAA,MACT,SAAS;AAAA,IACX,EAAE;AAAA,EACJ;AAEA,SAAOC,mBAAkB,UAAU;AACrC;;;ACjGO,IAAM,cAA6B,CAAC,MAAM,QAAQ,WAAW,UAAU,WAAW;AACvF,QAAM,QAAQ,gBAAgB,MAAM,QAAQ,WAAW,QAAQ;AAG/D,QAAM,aAAa,MAAM,OAAO,CAAC,MAAsB,EAAE,SAAS,OAAO;AAGzE,QAAM,aACJ,KAAK,UAAU,KAAK,WAAW,KAAK,SAAS,IAAI,KAAK,SAAS,EAAE,QAAQ;AAC3E,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA,KAAK,OAAO;AAAA,IACZ,KAAK,OAAO;AAAA,IACZ,KAAK,OAAO;AAAA,IACZ;AAAA,EACF;AACA,MAAI,WAAW;AACf,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,WAAW,WAAW,OAAO,QAAQ;AACrD,WAAK,QAAQ,OAAO,QAAQ;AAC5B;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;ACxCA,SAAS,0BAAAC,+BAA8B;;;ACEvC,SAAS,0BAAAC,+BAA8B;;;ACTxB,SAAR,iBAAiBC,IAAG;AACzB,SAAO,SAASC,YAAW;AACzB,WAAOD;AAAA,EACT;AACF;;;ACJO,IAAM,MAAM,KAAK;AACjB,IAAM,QAAQ,KAAK;AACnB,IAAM,MAAM,KAAK;AACjB,IAAM,MAAM,KAAK;AACjB,IAAM,MAAM,KAAK;AACjB,IAAM,MAAM,KAAK;AACjB,IAAM,OAAO,KAAK;AAElB,IAAM,UAAU;AAChB,IAAM,KAAK,KAAK;AAChB,IAAM,SAAS,KAAK;AACpB,IAAM,MAAM,IAAI;AAEhB,SAAS,KAAKE,IAAG;AACtB,SAAOA,KAAI,IAAI,IAAIA,KAAI,KAAK,KAAK,KAAK,KAAKA,EAAC;AAC9C;AAEO,SAAS,KAAKA,IAAG;AACtB,SAAOA,MAAK,IAAI,SAASA,MAAK,KAAK,CAAC,SAAS,KAAK,KAAKA,EAAC;AAC1D;;;ACnBA,IAAMC,MAAK,KAAK;AAAhB,IACIC,OAAM,IAAID;AADd,IAEIE,WAAU;AAFd,IAGI,aAAaD,OAAMC;AAEvB,SAAS,OAAO,SAAS;AACvB,OAAK,KAAK,QAAQ,CAAC;AACnB,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAAI,GAAG,EAAE,GAAG;AAC9C,SAAK,KAAK,UAAU,CAAC,IAAI,QAAQ,CAAC;AAAA,EACpC;AACF;AAEA,SAAS,YAAY,QAAQ;AAC3B,MAAI,IAAI,KAAK,MAAM,MAAM;AACzB,MAAI,EAAE,KAAK,GAAI,OAAM,IAAI,MAAM,mBAAmB,MAAM,EAAE;AAC1D,MAAI,IAAI,GAAI,QAAO;AACnB,QAAM,IAAI,MAAM;AAChB,SAAO,SAAS,SAAS;AACvB,SAAK,KAAK,QAAQ,CAAC;AACnB,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAAI,GAAG,EAAE,GAAG;AAC9C,WAAK,KAAK,KAAK,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC;AAAA,IACxD;AAAA,EACF;AACF;AAEO,IAAM,OAAN,MAAW;AAAA,EAChB,YAAY,QAAQ;AAClB,SAAK,MAAM,KAAK;AAAA,IAChB,KAAK,MAAM,KAAK,MAAM;AACtB,SAAK,IAAI;AACT,SAAK,UAAU,UAAU,OAAO,SAAS,YAAY,MAAM;AAAA,EAC7D;AAAA,EACA,OAAOC,IAAGC,IAAG;AACX,SAAK,WAAW,KAAK,MAAM,KAAK,MAAM,CAACD,EAAC,IAAI,KAAK,MAAM,KAAK,MAAM,CAACC,EAAC;AAAA,EACtE;AAAA,EACA,YAAY;AACV,QAAI,KAAK,QAAQ,MAAM;AACrB,WAAK,MAAM,KAAK,KAAK,KAAK,MAAM,KAAK;AACrC,WAAK;AAAA,IACP;AAAA,EACF;AAAA,EACA,OAAOD,IAAGC,IAAG;AACX,SAAK,WAAW,KAAK,MAAM,CAACD,EAAC,IAAI,KAAK,MAAM,CAACC,EAAC;AAAA,EAChD;AAAA,EACA,iBAAiB,IAAI,IAAID,IAAGC,IAAG;AAC7B,SAAK,WAAW,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,KAAK,MAAM,CAACD,EAAC,IAAI,KAAK,MAAM,CAACC,EAAC;AAAA,EAC9D;AAAA,EACA,cAAc,IAAI,IAAI,IAAI,IAAID,IAAGC,IAAG;AAClC,SAAK,WAAW,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,KAAK,MAAM,CAACD,EAAC,IAAI,KAAK,MAAM,CAACC,EAAC;AAAA,EAC5E;AAAA,EACA,MAAM,IAAI,IAAI,IAAI,IAAI,GAAG;AACvB,SAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC;AAG7C,QAAI,IAAI,EAAG,OAAM,IAAI,MAAM,oBAAoB,CAAC,EAAE;AAElD,QAAI,KAAK,KAAK,KACV,KAAK,KAAK,KACV,MAAM,KAAK,IACX,MAAM,KAAK,IACX,MAAM,KAAK,IACX,MAAM,KAAK,IACX,QAAQ,MAAM,MAAM,MAAM;AAG9B,QAAI,KAAK,QAAQ,MAAM;AACrB,WAAK,WAAW,KAAK,MAAM,EAAE,IAAI,KAAK,MAAM,EAAE;AAAA,IAChD,WAGS,EAAE,QAAQF,UAAS;AAAA,aAKnB,EAAE,KAAK,IAAI,MAAM,MAAM,MAAM,GAAG,IAAIA,aAAY,CAAC,GAAG;AAC3D,WAAK,WAAW,KAAK,MAAM,EAAE,IAAI,KAAK,MAAM,EAAE;AAAA,IAChD,OAGK;AACH,UAAI,MAAM,KAAK,IACX,MAAM,KAAK,IACX,QAAQ,MAAM,MAAM,MAAM,KAC1B,QAAQ,MAAM,MAAM,MAAM,KAC1B,MAAM,KAAK,KAAK,KAAK,GACrB,MAAM,KAAK,KAAK,KAAK,GACrB,IAAI,IAAI,KAAK,KAAKF,MAAK,KAAK,MAAM,QAAQ,QAAQ,UAAU,IAAI,MAAM,IAAI,KAAK,CAAC,GAChF,MAAM,IAAI,KACV,MAAM,IAAI;AAGd,UAAI,KAAK,IAAI,MAAM,CAAC,IAAIE,UAAS;AAC/B,aAAK,WAAW,KAAK,MAAM,GAAG,IAAI,KAAK,MAAM,GAAG;AAAA,MAClD;AAEA,WAAK,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,MAAM,MAAM,IAAI,IAAI,KAAK,MAAM,KAAK,MAAM,GAAG,IAAI,KAAK,MAAM,KAAK,MAAM,GAAG;AAAA,IAClH;AAAA,EACF;AAAA,EACA,IAAIC,IAAGC,IAAG,GAAG,IAAI,IAAI,KAAK;AACxB,IAAAD,KAAI,CAACA,IAAGC,KAAI,CAACA,IAAG,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;AAGhC,QAAI,IAAI,EAAG,OAAM,IAAI,MAAM,oBAAoB,CAAC,EAAE;AAElD,QAAI,KAAK,IAAI,KAAK,IAAI,EAAE,GACpB,KAAK,IAAI,KAAK,IAAI,EAAE,GACpB,KAAKD,KAAI,IACT,KAAKC,KAAI,IACT,KAAK,IAAI,KACT,KAAK,MAAM,KAAK,KAAK,KAAK;AAG9B,QAAI,KAAK,QAAQ,MAAM;AACrB,WAAK,WAAW,EAAE,IAAI,EAAE;AAAA,IAC1B,WAGS,KAAK,IAAI,KAAK,MAAM,EAAE,IAAIF,YAAW,KAAK,IAAI,KAAK,MAAM,EAAE,IAAIA,UAAS;AAC/E,WAAK,WAAW,EAAE,IAAI,EAAE;AAAA,IAC1B;AAGA,QAAI,CAAC,EAAG;AAGR,QAAI,KAAK,EAAG,MAAK,KAAKD,OAAMA;AAG5B,QAAI,KAAK,YAAY;AACnB,WAAK,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAIE,KAAI,EAAE,IAAIC,KAAI,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,KAAK,MAAM,EAAE,IAAI,KAAK,MAAM,EAAE;AAAA,IAC5G,WAGS,KAAKF,UAAS;AACrB,WAAK,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,MAAMF,IAAG,IAAI,EAAE,IAAI,KAAK,MAAMG,KAAI,IAAI,KAAK,IAAI,EAAE,CAAC,IAAI,KAAK,MAAMC,KAAI,IAAI,KAAK,IAAI,EAAE,CAAC;AAAA,IACrH;AAAA,EACF;AAAA,EACA,KAAKD,IAAGC,IAAG,GAAG,GAAG;AACf,SAAK,WAAW,KAAK,MAAM,KAAK,MAAM,CAACD,EAAC,IAAI,KAAK,MAAM,KAAK,MAAM,CAACC,EAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAAA,EAC5F;AAAA,EACA,WAAW;AACT,WAAO,KAAK;AAAA,EACd;AACF;AAEO,SAAS,OAAO;AACrB,SAAO,IAAI;AACb;AAGA,KAAK,YAAY,KAAK;;;ACrJf,SAAS,SAAS,OAAO;AAC9B,MAAI,SAAS;AAEb,QAAM,SAAS,SAAS,GAAG;AACzB,QAAI,CAAC,UAAU,OAAQ,QAAO;AAC9B,QAAI,KAAK,MAAM;AACb,eAAS;AAAA,IACX,OAAO;AACL,YAAM,IAAI,KAAK,MAAM,CAAC;AACtB,UAAI,EAAE,KAAK,GAAI,OAAM,IAAI,WAAW,mBAAmB,CAAC,EAAE;AAC1D,eAAS;AAAA,IACX;AACA,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,IAAI,KAAK,MAAM;AAC9B;;;ACdA,SAAS,eAAe,GAAG;AACzB,SAAO,EAAE;AACX;AAEA,SAAS,eAAe,GAAG;AACzB,SAAO,EAAE;AACX;AAEA,SAAS,cAAc,GAAG;AACxB,SAAO,EAAE;AACX;AAEA,SAAS,YAAY,GAAG;AACtB,SAAO,EAAE;AACX;AAEA,SAAS,YAAY,GAAG;AACtB,SAAO,KAAK,EAAE;AAChB;AAEA,SAAS,UAAU,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;AACjD,MAAI,MAAM,KAAK,IAAI,MAAM,KAAK,IAC1B,MAAM,KAAK,IAAI,MAAM,KAAK,IAC1B,IAAI,MAAM,MAAM,MAAM;AAC1B,MAAI,IAAI,IAAI,QAAS;AACrB,OAAK,OAAO,KAAK,MAAM,OAAO,KAAK,OAAO;AAC1C,SAAO,CAAC,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG;AACpC;AAIA,SAAS,eAAe,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;AAClD,MAAI,MAAM,KAAK,IACX,MAAM,KAAK,IACX,MAAM,KAAK,KAAK,CAAC,MAAM,KAAK,MAAM,MAAM,MAAM,GAAG,GACjD,KAAK,KAAK,KACV,KAAK,CAAC,KAAK,KACX,MAAM,KAAK,IACX,MAAM,KAAK,IACX,MAAM,KAAK,IACX,MAAM,KAAK,IACX,OAAO,MAAM,OAAO,GACpB,OAAO,MAAM,OAAO,GACpB,KAAK,MAAM,KACX,KAAK,MAAM,KACX,KAAK,KAAK,KAAK,KAAK,IACpB,IAAI,KAAK,IACT,IAAI,MAAM,MAAM,MAAM,KACtB,KAAK,KAAK,IAAI,KAAK,KAAK,KAAK,IAAI,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,GACvD,OAAO,IAAI,KAAK,KAAK,KAAK,IAC1B,OAAO,CAAC,IAAI,KAAK,KAAK,KAAK,IAC3B,OAAO,IAAI,KAAK,KAAK,KAAK,IAC1B,OAAO,CAAC,IAAI,KAAK,KAAK,KAAK,IAC3B,MAAM,MAAM,KACZ,MAAM,MAAM,KACZ,MAAM,MAAM,KACZ,MAAM,MAAM;AAIhB,MAAI,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAK,OAAM,KAAK,MAAM;AAEpE,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,OAAO,KAAK,IAAI;AAAA,IACrB,KAAK,OAAO,KAAK,IAAI;AAAA,EACvB;AACF;AAEe,SAAR,cAAmB;AACxB,MAAI,cAAc,gBACd,cAAc,gBACd,eAAe,iBAAS,CAAC,GACzB,YAAY,MACZ,aAAa,eACb,WAAW,aACX,WAAW,aACX,UAAU,MACVC,QAAO,SAAS,GAAG;AAEvB,WAAS,MAAM;AACb,QAAI,QACA,GACA,KAAK,CAAC,YAAY,MAAM,MAAM,SAAS,GACvC,KAAK,CAAC,YAAY,MAAM,MAAM,SAAS,GACvC,KAAK,WAAW,MAAM,MAAM,SAAS,IAAI,QACzC,KAAK,SAAS,MAAM,MAAM,SAAS,IAAI,QACvC,KAAK,IAAI,KAAK,EAAE,GAChB,KAAK,KAAK;AAEd,QAAI,CAAC,QAAS,WAAU,SAASA,MAAK;AAGtC,QAAI,KAAK,GAAI,KAAI,IAAI,KAAK,IAAI,KAAK;AAGnC,QAAI,EAAE,KAAK,SAAU,SAAQ,OAAO,GAAG,CAAC;AAAA,aAG/B,KAAK,MAAM,SAAS;AAC3B,cAAQ,OAAO,KAAK,IAAI,EAAE,GAAG,KAAK,IAAI,EAAE,CAAC;AACzC,cAAQ,IAAI,GAAG,GAAG,IAAI,IAAI,IAAI,CAAC,EAAE;AACjC,UAAI,KAAK,SAAS;AAChB,gBAAQ,OAAO,KAAK,IAAI,EAAE,GAAG,KAAK,IAAI,EAAE,CAAC;AACzC,gBAAQ,IAAI,GAAG,GAAG,IAAI,IAAI,IAAI,EAAE;AAAA,MAClC;AAAA,IACF,OAGK;AACH,UAAI,MAAM,IACN,MAAM,IACN,MAAM,IACN,MAAM,IACN,MAAM,IACN,MAAM,IACN,KAAK,SAAS,MAAM,MAAM,SAAS,IAAI,GACvC,KAAM,KAAK,YAAa,YAAY,CAAC,UAAU,MAAM,MAAM,SAAS,IAAI,KAAK,KAAK,KAAK,KAAK,EAAE,IAC9F,KAAK,IAAI,IAAI,KAAK,EAAE,IAAI,GAAG,CAAC,aAAa,MAAM,MAAM,SAAS,CAAC,GAC/D,MAAM,IACN,MAAM,IACNC,KACAC;AAGJ,UAAI,KAAK,SAAS;AAChB,YAAI,KAAK,KAAK,KAAK,KAAK,IAAI,EAAE,CAAC,GAC3B,KAAK,KAAK,KAAK,KAAK,IAAI,EAAE,CAAC;AAC/B,aAAK,OAAO,KAAK,KAAK,QAAS,OAAO,KAAK,IAAI,IAAK,OAAO,IAAI,OAAO;AAAA,YACjE,OAAM,GAAG,MAAM,OAAO,KAAK,MAAM;AACtC,aAAK,OAAO,KAAK,KAAK,QAAS,OAAO,KAAK,IAAI,IAAK,OAAO,IAAI,OAAO;AAAA,YACjE,OAAM,GAAG,MAAM,OAAO,KAAK,MAAM;AAAA,MACxC;AAEA,UAAI,MAAM,KAAK,IAAI,GAAG,GAClB,MAAM,KAAK,IAAI,GAAG,GAClB,MAAM,KAAK,IAAI,GAAG,GAClB,MAAM,KAAK,IAAI,GAAG;AAGtB,UAAI,KAAK,SAAS;AAChB,YAAI,MAAM,KAAK,IAAI,GAAG,GAClB,MAAM,KAAK,IAAI,GAAG,GAClB,MAAM,KAAK,IAAI,GAAG,GAClB,MAAM,KAAK,IAAI,GAAG,GAClB;AAKJ,YAAI,KAAK,IAAI;AACX,cAAI,KAAK,UAAU,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,GAAG;AAC1D,gBAAI,KAAK,MAAM,GAAG,CAAC,GACf,KAAK,MAAM,GAAG,CAAC,GACf,KAAK,MAAM,GAAG,CAAC,GACf,KAAK,MAAM,GAAG,CAAC,GACf,KAAK,IAAI,IAAI,MAAM,KAAK,KAAK,KAAK,OAAO,KAAK,KAAK,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,KAAK,KAAK,EAAE,EAAE,IAAI,CAAC,GAChG,KAAK,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;AAC3C,kBAAM,IAAI,KAAK,KAAK,OAAO,KAAK,EAAE;AAClC,kBAAM,IAAI,KAAK,KAAK,OAAO,KAAK,EAAE;AAAA,UACpC,OAAO;AACL,kBAAM,MAAM;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAGA,UAAI,EAAE,MAAM,SAAU,SAAQ,OAAO,KAAK,GAAG;AAAA,eAGpC,MAAM,SAAS;AACtB,QAAAD,MAAK,eAAe,KAAK,KAAK,KAAK,KAAK,IAAI,KAAK,EAAE;AACnD,QAAAC,MAAK,eAAe,KAAK,KAAK,KAAK,KAAK,IAAI,KAAK,EAAE;AAEnD,gBAAQ,OAAOD,IAAG,KAAKA,IAAG,KAAKA,IAAG,KAAKA,IAAG,GAAG;AAG7C,YAAI,MAAM,GAAI,SAAQ,IAAIA,IAAG,IAAIA,IAAG,IAAI,KAAK,MAAMA,IAAG,KAAKA,IAAG,GAAG,GAAG,MAAMC,IAAG,KAAKA,IAAG,GAAG,GAAG,CAAC,EAAE;AAAA,aAGzF;AACH,kBAAQ,IAAID,IAAG,IAAIA,IAAG,IAAI,KAAK,MAAMA,IAAG,KAAKA,IAAG,GAAG,GAAG,MAAMA,IAAG,KAAKA,IAAG,GAAG,GAAG,CAAC,EAAE;AAChF,kBAAQ,IAAI,GAAG,GAAG,IAAI,MAAMA,IAAG,KAAKA,IAAG,KAAKA,IAAG,KAAKA,IAAG,GAAG,GAAG,MAAMC,IAAG,KAAKA,IAAG,KAAKA,IAAG,KAAKA,IAAG,GAAG,GAAG,CAAC,EAAE;AACvG,kBAAQ,IAAIA,IAAG,IAAIA,IAAG,IAAI,KAAK,MAAMA,IAAG,KAAKA,IAAG,GAAG,GAAG,MAAMA,IAAG,KAAKA,IAAG,GAAG,GAAG,CAAC,EAAE;AAAA,QAClF;AAAA,MACF,MAGK,SAAQ,OAAO,KAAK,GAAG,GAAG,QAAQ,IAAI,GAAG,GAAG,IAAI,KAAK,KAAK,CAAC,EAAE;AAIlE,UAAI,EAAE,KAAK,YAAY,EAAE,MAAM,SAAU,SAAQ,OAAO,KAAK,GAAG;AAAA,eAGvD,MAAM,SAAS;AACtB,QAAAD,MAAK,eAAe,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE;AACpD,QAAAC,MAAK,eAAe,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE;AAEpD,gBAAQ,OAAOD,IAAG,KAAKA,IAAG,KAAKA,IAAG,KAAKA,IAAG,GAAG;AAG7C,YAAI,MAAM,GAAI,SAAQ,IAAIA,IAAG,IAAIA,IAAG,IAAI,KAAK,MAAMA,IAAG,KAAKA,IAAG,GAAG,GAAG,MAAMC,IAAG,KAAKA,IAAG,GAAG,GAAG,CAAC,EAAE;AAAA,aAGzF;AACH,kBAAQ,IAAID,IAAG,IAAIA,IAAG,IAAI,KAAK,MAAMA,IAAG,KAAKA,IAAG,GAAG,GAAG,MAAMA,IAAG,KAAKA,IAAG,GAAG,GAAG,CAAC,EAAE;AAChF,kBAAQ,IAAI,GAAG,GAAG,IAAI,MAAMA,IAAG,KAAKA,IAAG,KAAKA,IAAG,KAAKA,IAAG,GAAG,GAAG,MAAMC,IAAG,KAAKA,IAAG,KAAKA,IAAG,KAAKA,IAAG,GAAG,GAAG,EAAE;AACtG,kBAAQ,IAAIA,IAAG,IAAIA,IAAG,IAAI,KAAK,MAAMA,IAAG,KAAKA,IAAG,GAAG,GAAG,MAAMA,IAAG,KAAKA,IAAG,GAAG,GAAG,CAAC,EAAE;AAAA,QAClF;AAAA,MACF,MAGK,SAAQ,IAAI,GAAG,GAAG,IAAI,KAAK,KAAK,EAAE;AAAA,IACzC;AAEA,YAAQ,UAAU;AAElB,QAAI,OAAQ,QAAO,UAAU,MAAM,SAAS,MAAM;AAAA,EACpD;AAEA,MAAI,WAAW,WAAW;AACxB,QAAI,KAAK,CAAC,YAAY,MAAM,MAAM,SAAS,IAAI,CAAC,YAAY,MAAM,MAAM,SAAS,KAAK,GAClF,KAAK,CAAC,WAAW,MAAM,MAAM,SAAS,IAAI,CAAC,SAAS,MAAM,MAAM,SAAS,KAAK,IAAI,KAAK;AAC3F,WAAO,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;AAAA,EAChC;AAEA,MAAI,cAAc,SAAS,GAAG;AAC5B,WAAO,UAAU,UAAU,cAAc,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,OAAO;AAAA,EAC9F;AAEA,MAAI,cAAc,SAAS,GAAG;AAC5B,WAAO,UAAU,UAAU,cAAc,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,OAAO;AAAA,EAC9F;AAEA,MAAI,eAAe,SAAS,GAAG;AAC7B,WAAO,UAAU,UAAU,eAAe,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,OAAO;AAAA,EAC/F;AAEA,MAAI,YAAY,SAAS,GAAG;AAC1B,WAAO,UAAU,UAAU,YAAY,KAAK,OAAO,OAAO,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,OAAO;AAAA,EAC/G;AAEA,MAAI,aAAa,SAAS,GAAG;AAC3B,WAAO,UAAU,UAAU,aAAa,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,OAAO;AAAA,EAC7F;AAEA,MAAI,WAAW,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,WAAW,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,OAAO;AAAA,EAC3F;AAEA,MAAI,WAAW,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,WAAW,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,OAAO;AAAA,EAC3F;AAEA,MAAI,UAAU,SAAS,GAAG;AACxB,WAAO,UAAU,UAAW,UAAU,KAAK,OAAO,OAAO,GAAI,OAAO;AAAA,EACtE;AAEA,SAAO;AACT;;;AC3QO,IAAI,QAAQ,MAAM,UAAU;AAEpB,SAAR,cAAiBC,IAAG;AACzB,SAAO,OAAOA,OAAM,YAAY,YAAYA,KACxCA,KACA,MAAM,KAAKA,EAAC;AAClB;;;ACNA,SAAS,OAAO,SAAS;AACvB,OAAK,WAAW;AAClB;AAEA,OAAO,YAAY;AAAA,EACjB,WAAW,WAAW;AACpB,SAAK,QAAQ;AAAA,EACf;AAAA,EACA,SAAS,WAAW;AAClB,SAAK,QAAQ;AAAA,EACf;AAAA,EACA,WAAW,WAAW;AACpB,SAAK,SAAS;AAAA,EAChB;AAAA,EACA,SAAS,WAAW;AAClB,QAAI,KAAK,SAAU,KAAK,UAAU,KAAK,KAAK,WAAW,EAAI,MAAK,SAAS,UAAU;AACnF,SAAK,QAAQ,IAAI,KAAK;AAAA,EACxB;AAAA,EACA,OAAO,SAASC,IAAGC,IAAG;AACpB,IAAAD,KAAI,CAACA,IAAGC,KAAI,CAACA;AACb,YAAQ,KAAK,QAAQ;AAAA,MACnB,KAAK;AAAG,aAAK,SAAS;AAAG,aAAK,QAAQ,KAAK,SAAS,OAAOD,IAAGC,EAAC,IAAI,KAAK,SAAS,OAAOD,IAAGC,EAAC;AAAG;AAAA,MAC/F,KAAK;AAAG,aAAK,SAAS;AAAA;AAAA,MACtB;AAAS,aAAK,SAAS,OAAOD,IAAGC,EAAC;AAAG;AAAA,IACvC;AAAA,EACF;AACF;AAEe,SAAR,eAAiB,SAAS;AAC/B,SAAO,IAAI,OAAO,OAAO;AAC3B;;;AC9BO,SAAS,EAAE,GAAG;AACnB,SAAO,EAAE,CAAC;AACZ;AAEO,SAAS,EAAE,GAAG;AACnB,SAAO,EAAE,CAAC;AACZ;;;ACAe,SAAR,aAAiBC,IAAGC,IAAG;AAC5B,MAAI,UAAU,iBAAS,IAAI,GACvB,UAAU,MACV,QAAQ,gBACR,SAAS,MACTC,QAAO,SAAS,IAAI;AAExB,EAAAF,KAAI,OAAOA,OAAM,aAAaA,KAAKA,OAAM,SAAa,IAAS,iBAASA,EAAC;AACzE,EAAAC,KAAI,OAAOA,OAAM,aAAaA,KAAKA,OAAM,SAAa,IAAS,iBAASA,EAAC;AAEzE,WAAS,KAAK,MAAM;AAClB,QAAI,GACA,KAAK,OAAO,cAAM,IAAI,GAAG,QACzB,GACA,WAAW,OACX;AAEJ,QAAI,WAAW,KAAM,UAAS,MAAM,SAASC,MAAK,CAAC;AAEnD,SAAK,IAAI,GAAG,KAAK,GAAG,EAAE,GAAG;AACvB,UAAI,EAAE,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,GAAG,IAAI,OAAO,UAAU;AAC1D,YAAI,WAAW,CAAC,SAAU,QAAO,UAAU;AAAA,YACtC,QAAO,QAAQ;AAAA,MACtB;AACA,UAAI,SAAU,QAAO,MAAM,CAACF,GAAE,GAAG,GAAG,IAAI,GAAG,CAACC,GAAE,GAAG,GAAG,IAAI,CAAC;AAAA,IAC3D;AAEA,QAAI,OAAQ,QAAO,SAAS,MAAM,SAAS,MAAM;AAAA,EACnD;AAEA,OAAK,IAAI,SAAS,GAAG;AACnB,WAAO,UAAU,UAAUD,KAAI,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,QAAQA;AAAA,EACrF;AAEA,OAAK,IAAI,SAAS,GAAG;AACnB,WAAO,UAAU,UAAUC,KAAI,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,QAAQA;AAAA,EACrF;AAEA,OAAK,UAAU,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,UAAU,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,CAAC,GAAG,QAAQ;AAAA,EAC5F;AAEA,OAAK,QAAQ,SAAS,GAAG;AACvB,WAAO,UAAU,UAAU,QAAQ,GAAG,WAAW,SAAS,SAAS,MAAM,OAAO,IAAI,QAAQ;AAAA,EAC9F;AAEA,OAAK,UAAU,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,KAAK,OAAO,UAAU,SAAS,OAAO,SAAS,MAAM,UAAU,CAAC,GAAG,QAAQ;AAAA,EACxG;AAEA,SAAO;AACT;;;AClDe,SAAR,aAAiB,IAAI,IAAI,IAAI;AAClC,MAAI,KAAK,MACL,UAAU,iBAAS,IAAI,GACvB,UAAU,MACV,QAAQ,gBACR,SAAS,MACTE,QAAO,SAAS,IAAI;AAExB,OAAK,OAAO,OAAO,aAAa,KAAM,OAAO,SAAa,IAAS,iBAAS,CAAC,EAAE;AAC/E,OAAK,OAAO,OAAO,aAAa,KAAM,OAAO,SAAa,iBAAS,CAAC,IAAI,iBAAS,CAAC,EAAE;AACpF,OAAK,OAAO,OAAO,aAAa,KAAM,OAAO,SAAa,IAAS,iBAAS,CAAC,EAAE;AAE/E,WAAS,KAAK,MAAM;AAClB,QAAI,GACA,GACA,GACA,KAAK,OAAO,cAAM,IAAI,GAAG,QACzB,GACA,WAAW,OACX,QACA,MAAM,IAAI,MAAM,CAAC,GACjB,MAAM,IAAI,MAAM,CAAC;AAErB,QAAI,WAAW,KAAM,UAAS,MAAM,SAASA,MAAK,CAAC;AAEnD,SAAK,IAAI,GAAG,KAAK,GAAG,EAAE,GAAG;AACvB,UAAI,EAAE,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,GAAG,IAAI,OAAO,UAAU;AAC1D,YAAI,WAAW,CAAC,UAAU;AACxB,cAAI;AACJ,iBAAO,UAAU;AACjB,iBAAO,UAAU;AAAA,QACnB,OAAO;AACL,iBAAO,QAAQ;AACf,iBAAO,UAAU;AACjB,eAAK,IAAI,IAAI,GAAG,KAAK,GAAG,EAAE,GAAG;AAC3B,mBAAO,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AAAA,UAC7B;AACA,iBAAO,QAAQ;AACf,iBAAO,QAAQ;AAAA,QACjB;AAAA,MACF;AACA,UAAI,UAAU;AACZ,YAAI,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,IAAI;AACjD,eAAO,MAAM,KAAK,CAAC,GAAG,GAAG,GAAG,IAAI,IAAI,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,GAAG,IAAI,IAAI,IAAI,CAAC,CAAC;AAAA,MAC3E;AAAA,IACF;AAEA,QAAI,OAAQ,QAAO,SAAS,MAAM,SAAS,MAAM;AAAA,EACnD;AAEA,WAAS,WAAW;AAClB,WAAO,aAAK,EAAE,QAAQ,OAAO,EAAE,MAAM,KAAK,EAAE,QAAQ,OAAO;AAAA,EAC7D;AAEA,OAAK,IAAI,SAAS,GAAG;AACnB,WAAO,UAAU,UAAU,KAAK,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,KAAK,MAAM,QAAQ;AAAA,EACjG;AAEA,OAAK,KAAK,SAAS,GAAG;AACpB,WAAO,UAAU,UAAU,KAAK,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,QAAQ;AAAA,EACtF;AAEA,OAAK,KAAK,SAAS,GAAG;AACpB,WAAO,UAAU,UAAU,KAAK,KAAK,OAAO,OAAO,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,QAAQ;AAAA,EACzG;AAEA,OAAK,IAAI,SAAS,GAAG;AACnB,WAAO,UAAU,UAAU,KAAK,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,KAAK,MAAM,QAAQ;AAAA,EACjG;AAEA,OAAK,KAAK,SAAS,GAAG;AACpB,WAAO,UAAU,UAAU,KAAK,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,QAAQ;AAAA,EACtF;AAEA,OAAK,KAAK,SAAS,GAAG;AACpB,WAAO,UAAU,UAAU,KAAK,KAAK,OAAO,OAAO,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,QAAQ;AAAA,EACzG;AAEA,OAAK,SACL,KAAK,SAAS,WAAW;AACvB,WAAO,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;AAAA,EAC9B;AAEA,OAAK,SAAS,WAAW;AACvB,WAAO,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;AAAA,EAC9B;AAEA,OAAK,SAAS,WAAW;AACvB,WAAO,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;AAAA,EAC9B;AAEA,OAAK,UAAU,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,UAAU,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,CAAC,GAAG,QAAQ;AAAA,EAC5F;AAEA,OAAK,QAAQ,SAAS,GAAG;AACvB,WAAO,UAAU,UAAU,QAAQ,GAAG,WAAW,SAAS,SAAS,MAAM,OAAO,IAAI,QAAQ;AAAA,EAC9F;AAEA,OAAK,UAAU,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,KAAK,OAAO,UAAU,SAAS,OAAO,SAAS,MAAM,UAAU,CAAC,GAAG,QAAQ;AAAA,EACxG;AAEA,SAAO;AACT;;;AC/Ge,SAAR,mBAAiB,GAAG,GAAG;AAC5B,SAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI;AAC/C;;;ACFe,SAAR,iBAAiB,GAAG;AACzB,SAAO;AACT;;;ACIe,SAAR,cAAmB;AACxB,MAAIC,SAAQ,kBACR,aAAa,oBACb,OAAO,MACP,aAAa,iBAAS,CAAC,GACvB,WAAW,iBAAS,GAAG,GACvB,WAAW,iBAAS,CAAC;AAEzB,WAAS,IAAI,MAAM;AACjB,QAAI,GACA,KAAK,OAAO,cAAM,IAAI,GAAG,QACzB,GACA,GACAC,OAAM,GACN,QAAQ,IAAI,MAAM,CAAC,GACnB,OAAO,IAAI,MAAM,CAAC,GAClB,KAAK,CAAC,WAAW,MAAM,MAAM,SAAS,GACtC,KAAK,KAAK,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,SAAS,MAAM,MAAM,SAAS,IAAI,EAAE,CAAC,GACvE,IACA,IAAI,KAAK,IAAI,KAAK,IAAI,EAAE,IAAI,GAAG,SAAS,MAAM,MAAM,SAAS,CAAC,GAC9D,KAAK,KAAK,KAAK,IAAI,KAAK,IACxB;AAEJ,SAAK,IAAI,GAAG,IAAI,GAAG,EAAE,GAAG;AACtB,WAAK,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,CAACD,OAAM,KAAK,CAAC,GAAG,GAAG,IAAI,KAAK,GAAG;AAC3D,QAAAC,QAAO;AAAA,MACT;AAAA,IACF;AAGA,QAAI,cAAc,KAAM,OAAM,KAAK,SAASC,IAAGC,IAAG;AAAE,aAAO,WAAW,KAAKD,EAAC,GAAG,KAAKC,EAAC,CAAC;AAAA,IAAG,CAAC;AAAA,aACjF,QAAQ,KAAM,OAAM,KAAK,SAASD,IAAGC,IAAG;AAAE,aAAO,KAAK,KAAKD,EAAC,GAAG,KAAKC,EAAC,CAAC;AAAA,IAAG,CAAC;AAGnF,SAAK,IAAI,GAAG,IAAIF,QAAO,KAAK,IAAI,MAAMA,OAAM,GAAG,IAAI,GAAG,EAAE,GAAG,KAAK,IAAI;AAClE,UAAI,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI;AAAA,QACvE,MAAM,KAAK,CAAC;AAAA,QACZ,OAAO;AAAA,QACP,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,SAAS,GAAG;AACtB,WAAO,UAAU,UAAUD,SAAQ,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,OAAOA;AAAA,EACxF;AAEA,MAAI,aAAa,SAAS,GAAG;AAC3B,WAAO,UAAU,UAAU,aAAa,GAAG,OAAO,MAAM,OAAO;AAAA,EACjE;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,WAAO,UAAU,UAAU,OAAO,GAAG,aAAa,MAAM,OAAO;AAAA,EACjE;AAEA,MAAI,aAAa,SAAS,GAAG;AAC3B,WAAO,UAAU,UAAU,aAAa,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,OAAO;AAAA,EAC7F;AAEA,MAAI,WAAW,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,WAAW,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,OAAO;AAAA,EAC3F;AAEA,MAAI,WAAW,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,WAAW,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,OAAO;AAAA,EAC3F;AAEA,SAAO;AACT;;;AC/EO,SAAS,MAAM,MAAMI,IAAGC,IAAG;AAChC,OAAK,SAAS;AAAA,KACX,IAAI,KAAK,MAAM,KAAK,OAAO;AAAA,KAC3B,IAAI,KAAK,MAAM,KAAK,OAAO;AAAA,KAC3B,KAAK,MAAM,IAAI,KAAK,OAAO;AAAA,KAC3B,KAAK,MAAM,IAAI,KAAK,OAAO;AAAA,KAC3B,KAAK,MAAM,IAAI,KAAK,MAAMD,MAAK;AAAA,KAC/B,KAAK,MAAM,IAAI,KAAK,MAAMC,MAAK;AAAA,EAClC;AACF;AAEO,SAAS,MAAM,SAAS;AAC7B,OAAK,WAAW;AAClB;AAEA,MAAM,YAAY;AAAA,EAChB,WAAW,WAAW;AACpB,SAAK,QAAQ;AAAA,EACf;AAAA,EACA,SAAS,WAAW;AAClB,SAAK,QAAQ;AAAA,EACf;AAAA,EACA,WAAW,WAAW;AACpB,SAAK,MAAM,KAAK,MAChB,KAAK,MAAM,KAAK,MAAM;AACtB,SAAK,SAAS;AAAA,EAChB;AAAA,EACA,SAAS,WAAW;AAClB,YAAQ,KAAK,QAAQ;AAAA,MACnB,KAAK;AAAG,cAAM,MAAM,KAAK,KAAK,KAAK,GAAG;AAAA;AAAA,MACtC,KAAK;AAAG,aAAK,SAAS,OAAO,KAAK,KAAK,KAAK,GAAG;AAAG;AAAA,IACpD;AACA,QAAI,KAAK,SAAU,KAAK,UAAU,KAAK,KAAK,WAAW,EAAI,MAAK,SAAS,UAAU;AACnF,SAAK,QAAQ,IAAI,KAAK;AAAA,EACxB;AAAA,EACA,OAAO,SAASD,IAAGC,IAAG;AACpB,IAAAD,KAAI,CAACA,IAAGC,KAAI,CAACA;AACb,YAAQ,KAAK,QAAQ;AAAA,MACnB,KAAK;AAAG,aAAK,SAAS;AAAG,aAAK,QAAQ,KAAK,SAAS,OAAOD,IAAGC,EAAC,IAAI,KAAK,SAAS,OAAOD,IAAGC,EAAC;AAAG;AAAA,MAC/F,KAAK;AAAG,aAAK,SAAS;AAAG;AAAA,MACzB,KAAK;AAAG,aAAK,SAAS;AAAG,aAAK,SAAS,QAAQ,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,IAAI,KAAK,MAAM,KAAK,OAAO,CAAC;AAAA;AAAA,MAC1G;AAAS,cAAM,MAAMD,IAAGC,EAAC;AAAG;AAAA,IAC9B;AACA,SAAK,MAAM,KAAK,KAAK,KAAK,MAAMD;AAChC,SAAK,MAAM,KAAK,KAAK,KAAK,MAAMC;AAAA,EAClC;AACF;AAEe,SAAR,cAAiB,SAAS;AAC/B,SAAO,IAAI,MAAM,OAAO;AAC1B;;;AClDO,SAASC,OAAM,MAAMC,IAAGC,IAAG;AAChC,OAAK,SAAS;AAAA,IACZ,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK;AAAA,IACtC,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK;AAAA,IACtC,KAAK,MAAM,KAAK,MAAM,KAAK,MAAMD;AAAA,IACjC,KAAK,MAAM,KAAK,MAAM,KAAK,MAAMC;AAAA,IACjC,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AACF;AAEO,SAAS,SAAS,SAAS,SAAS;AACzC,OAAK,WAAW;AAChB,OAAK,MAAM,IAAI,WAAW;AAC5B;AAEA,SAAS,YAAY;AAAA,EACnB,WAAW,WAAW;AACpB,SAAK,QAAQ;AAAA,EACf;AAAA,EACA,SAAS,WAAW;AAClB,SAAK,QAAQ;AAAA,EACf;AAAA,EACA,WAAW,WAAW;AACpB,SAAK,MAAM,KAAK,MAAM,KAAK,MAC3B,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM;AACjC,SAAK,SAAS;AAAA,EAChB;AAAA,EACA,SAAS,WAAW;AAClB,YAAQ,KAAK,QAAQ;AAAA,MACnB,KAAK;AAAG,aAAK,SAAS,OAAO,KAAK,KAAK,KAAK,GAAG;AAAG;AAAA,MAClD,KAAK;AAAG,QAAAF,OAAM,MAAM,KAAK,KAAK,KAAK,GAAG;AAAG;AAAA,IAC3C;AACA,QAAI,KAAK,SAAU,KAAK,UAAU,KAAK,KAAK,WAAW,EAAI,MAAK,SAAS,UAAU;AACnF,SAAK,QAAQ,IAAI,KAAK;AAAA,EACxB;AAAA,EACA,OAAO,SAASC,IAAGC,IAAG;AACpB,IAAAD,KAAI,CAACA,IAAGC,KAAI,CAACA;AACb,YAAQ,KAAK,QAAQ;AAAA,MACnB,KAAK;AAAG,aAAK,SAAS;AAAG,aAAK,QAAQ,KAAK,SAAS,OAAOD,IAAGC,EAAC,IAAI,KAAK,SAAS,OAAOD,IAAGC,EAAC;AAAG;AAAA,MAC/F,KAAK;AAAG,aAAK,SAAS;AAAG,aAAK,MAAMD,IAAG,KAAK,MAAMC;AAAG;AAAA,MACrD,KAAK;AAAG,aAAK,SAAS;AAAA;AAAA,MACtB;AAAS,QAAAF,OAAM,MAAMC,IAAGC,EAAC;AAAG;AAAA,IAC9B;AACA,SAAK,MAAM,KAAK,KAAK,KAAK,MAAM,KAAK,KAAK,KAAK,MAAMD;AACrD,SAAK,MAAM,KAAK,KAAK,KAAK,MAAM,KAAK,KAAK,KAAK,MAAMC;AAAA,EACvD;AACF;AAEA,IAAO,oBAAS,SAAS,OAAO,SAAS;AAEvC,WAAS,SAAS,SAAS;AACzB,WAAO,IAAI,SAAS,SAAS,OAAO;AAAA,EACtC;AAEA,WAAS,UAAU,SAASC,UAAS;AACnC,WAAO,OAAO,CAACA,QAAO;AAAA,EACxB;AAEA,SAAO;AACT,GAAG,CAAC;;;AC5DJ,SAAS,KAAKC,IAAG;AACf,SAAOA,KAAI,IAAI,KAAK;AACtB;AAMA,SAAS,OAAO,MAAM,IAAI,IAAI;AAC5B,MAAI,KAAK,KAAK,MAAM,KAAK,KACrB,KAAK,KAAK,KAAK,KACf,MAAM,KAAK,MAAM,KAAK,QAAQ,MAAM,KAAK,KAAK,KAC9C,MAAM,KAAK,KAAK,QAAQ,MAAM,KAAK,KAAK,KACxC,KAAK,KAAK,KAAK,KAAK,OAAO,KAAK;AACpC,UAAQ,KAAK,EAAE,IAAI,KAAK,EAAE,KAAK,KAAK,IAAI,KAAK,IAAI,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,KAAK;AAC5F;AAGA,SAAS,OAAO,MAAM,GAAG;AACvB,MAAI,IAAI,KAAK,MAAM,KAAK;AACxB,SAAO,KAAK,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,KAAK,IAAI;AACvD;AAKA,SAASC,OAAM,MAAMC,KAAIC,KAAI;AAC3B,MAAI,KAAK,KAAK,KACV,KAAK,KAAK,KACV,KAAK,KAAK,KACV,KAAK,KAAK,KACV,MAAM,KAAK,MAAM;AACrB,OAAK,SAAS,cAAc,KAAK,IAAI,KAAK,KAAKD,KAAI,KAAK,IAAI,KAAK,KAAKC,KAAI,IAAI,EAAE;AAClF;AAEA,SAAS,UAAU,SAAS;AAC1B,OAAK,WAAW;AAClB;AAEA,UAAU,YAAY;AAAA,EACpB,WAAW,WAAW;AACpB,SAAK,QAAQ;AAAA,EACf;AAAA,EACA,SAAS,WAAW;AAClB,SAAK,QAAQ;AAAA,EACf;AAAA,EACA,WAAW,WAAW;AACpB,SAAK,MAAM,KAAK,MAChB,KAAK,MAAM,KAAK,MAChB,KAAK,MAAM;AACX,SAAK,SAAS;AAAA,EAChB;AAAA,EACA,SAAS,WAAW;AAClB,YAAQ,KAAK,QAAQ;AAAA,MACnB,KAAK;AAAG,aAAK,SAAS,OAAO,KAAK,KAAK,KAAK,GAAG;AAAG;AAAA,MAClD,KAAK;AAAG,QAAAF,OAAM,MAAM,KAAK,KAAK,OAAO,MAAM,KAAK,GAAG,CAAC;AAAG;AAAA,IACzD;AACA,QAAI,KAAK,SAAU,KAAK,UAAU,KAAK,KAAK,WAAW,EAAI,MAAK,SAAS,UAAU;AACnF,SAAK,QAAQ,IAAI,KAAK;AAAA,EACxB;AAAA,EACA,OAAO,SAASD,IAAGI,IAAG;AACpB,QAAID,MAAK;AAET,IAAAH,KAAI,CAACA,IAAGI,KAAI,CAACA;AACb,QAAIJ,OAAM,KAAK,OAAOI,OAAM,KAAK,IAAK;AACtC,YAAQ,KAAK,QAAQ;AAAA,MACnB,KAAK;AAAG,aAAK,SAAS;AAAG,aAAK,QAAQ,KAAK,SAAS,OAAOJ,IAAGI,EAAC,IAAI,KAAK,SAAS,OAAOJ,IAAGI,EAAC;AAAG;AAAA,MAC/F,KAAK;AAAG,aAAK,SAAS;AAAG;AAAA,MACzB,KAAK;AAAG,aAAK,SAAS;AAAG,QAAAH,OAAM,MAAM,OAAO,MAAME,MAAK,OAAO,MAAMH,IAAGI,EAAC,CAAC,GAAGD,GAAE;AAAG;AAAA,MACjF;AAAS,QAAAF,OAAM,MAAM,KAAK,KAAKE,MAAK,OAAO,MAAMH,IAAGI,EAAC,CAAC;AAAG;AAAA,IAC3D;AAEA,SAAK,MAAM,KAAK,KAAK,KAAK,MAAMJ;AAChC,SAAK,MAAM,KAAK,KAAK,KAAK,MAAMI;AAChC,SAAK,MAAMD;AAAA,EACb;AACF;AAEA,SAAS,UAAU,SAAS;AAC1B,OAAK,WAAW,IAAI,eAAe,OAAO;AAC5C;AAAA,CAEC,UAAU,YAAY,OAAO,OAAO,UAAU,SAAS,GAAG,QAAQ,SAASH,IAAGI,IAAG;AAChF,YAAU,UAAU,MAAM,KAAK,MAAMA,IAAGJ,EAAC;AAC3C;AAEA,SAAS,eAAe,SAAS;AAC/B,OAAK,WAAW;AAClB;AAEA,eAAe,YAAY;AAAA,EACzB,QAAQ,SAASA,IAAGI,IAAG;AAAE,SAAK,SAAS,OAAOA,IAAGJ,EAAC;AAAA,EAAG;AAAA,EACrD,WAAW,WAAW;AAAE,SAAK,SAAS,UAAU;AAAA,EAAG;AAAA,EACnD,QAAQ,SAASA,IAAGI,IAAG;AAAE,SAAK,SAAS,OAAOA,IAAGJ,EAAC;AAAA,EAAG;AAAA,EACrD,eAAe,SAAS,IAAI,IAAI,IAAI,IAAIA,IAAGI,IAAG;AAAE,SAAK,SAAS,cAAc,IAAI,IAAI,IAAI,IAAIA,IAAGJ,EAAC;AAAA,EAAG;AACrG;AAEO,SAAS,UAAU,SAAS;AACjC,SAAO,IAAI,UAAU,OAAO;AAC9B;;;ACnGA,SAAS,QAAQ,SAAS;AACxB,OAAK,WAAW;AAClB;AAEA,QAAQ,YAAY;AAAA,EAClB,WAAW,WAAW;AACpB,SAAK,QAAQ;AAAA,EACf;AAAA,EACA,SAAS,WAAW;AAClB,SAAK,QAAQ;AAAA,EACf;AAAA,EACA,WAAW,WAAW;AACpB,SAAK,KAAK,CAAC;AACX,SAAK,KAAK,CAAC;AAAA,EACb;AAAA,EACA,SAAS,WAAW;AAClB,QAAIK,KAAI,KAAK,IACTC,KAAI,KAAK,IACT,IAAID,GAAE;AAEV,QAAI,GAAG;AACL,WAAK,QAAQ,KAAK,SAAS,OAAOA,GAAE,CAAC,GAAGC,GAAE,CAAC,CAAC,IAAI,KAAK,SAAS,OAAOD,GAAE,CAAC,GAAGC,GAAE,CAAC,CAAC;AAC/E,UAAI,MAAM,GAAG;AACX,aAAK,SAAS,OAAOD,GAAE,CAAC,GAAGC,GAAE,CAAC,CAAC;AAAA,MACjC,OAAO;AACL,YAAI,KAAK,cAAcD,EAAC,GACpB,KAAK,cAAcC,EAAC;AACxB,iBAAS,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,EAAE,IAAI,EAAE,IAAI;AAC3C,eAAK,SAAS,cAAc,GAAG,CAAC,EAAE,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,GAAGD,GAAE,EAAE,GAAGC,GAAE,EAAE,CAAC;AAAA,QACtF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAK,SAAU,KAAK,UAAU,KAAK,MAAM,EAAI,MAAK,SAAS,UAAU;AACzE,SAAK,QAAQ,IAAI,KAAK;AACtB,SAAK,KAAK,KAAK,KAAK;AAAA,EACtB;AAAA,EACA,OAAO,SAASD,IAAGC,IAAG;AACpB,SAAK,GAAG,KAAK,CAACD,EAAC;AACf,SAAK,GAAG,KAAK,CAACC,EAAC;AAAA,EACjB;AACF;AAGA,SAAS,cAAcD,IAAG;AACxB,MAAI,GACA,IAAIA,GAAE,SAAS,GACf,GACA,IAAI,IAAI,MAAM,CAAC,GACf,IAAI,IAAI,MAAM,CAAC,GACf,IAAI,IAAI,MAAM,CAAC;AACnB,IAAE,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,IAAIA,GAAE,CAAC,IAAI,IAAIA,GAAE,CAAC;AACzC,OAAK,IAAI,GAAG,IAAI,IAAI,GAAG,EAAE,EAAG,GAAE,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,IAAIA,GAAE,CAAC,IAAI,IAAIA,GAAE,IAAI,CAAC;AAC7E,IAAE,IAAI,CAAC,IAAI,GAAG,EAAE,IAAI,CAAC,IAAI,GAAG,EAAE,IAAI,CAAC,IAAI,IAAIA,GAAE,IAAI,CAAC,IAAIA,GAAE,CAAC;AACzD,OAAK,IAAI,GAAG,IAAI,GAAG,EAAE,EAAG,KAAI,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE,IAAI,CAAC;AAC3E,IAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;AAC7B,OAAK,IAAI,IAAI,GAAG,KAAK,GAAG,EAAE,EAAG,GAAE,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;AAC3D,IAAE,IAAI,CAAC,KAAKA,GAAE,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK;AAC/B,OAAK,IAAI,GAAG,IAAI,IAAI,GAAG,EAAE,EAAG,GAAE,CAAC,IAAI,IAAIA,GAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;AACzD,SAAO,CAAC,GAAG,CAAC;AACd;AAEe,SAAR,gBAAiB,SAAS;AAC/B,SAAO,IAAI,QAAQ,OAAO;AAC5B;;;AChEA,SAAS,KAAK,SAAS,GAAG;AACxB,OAAK,WAAW;AAChB,OAAK,KAAK;AACZ;AAEA,KAAK,YAAY;AAAA,EACf,WAAW,WAAW;AACpB,SAAK,QAAQ;AAAA,EACf;AAAA,EACA,SAAS,WAAW;AAClB,SAAK,QAAQ;AAAA,EACf;AAAA,EACA,WAAW,WAAW;AACpB,SAAK,KAAK,KAAK,KAAK;AACpB,SAAK,SAAS;AAAA,EAChB;AAAA,EACA,SAAS,WAAW;AAClB,QAAI,IAAI,KAAK,MAAM,KAAK,KAAK,KAAK,KAAK,WAAW,EAAG,MAAK,SAAS,OAAO,KAAK,IAAI,KAAK,EAAE;AAC1F,QAAI,KAAK,SAAU,KAAK,UAAU,KAAK,KAAK,WAAW,EAAI,MAAK,SAAS,UAAU;AACnF,QAAI,KAAK,SAAS,EAAG,MAAK,KAAK,IAAI,KAAK,IAAI,KAAK,QAAQ,IAAI,KAAK;AAAA,EACpE;AAAA,EACA,OAAO,SAASE,IAAGC,IAAG;AACpB,IAAAD,KAAI,CAACA,IAAGC,KAAI,CAACA;AACb,YAAQ,KAAK,QAAQ;AAAA,MACnB,KAAK;AAAG,aAAK,SAAS;AAAG,aAAK,QAAQ,KAAK,SAAS,OAAOD,IAAGC,EAAC,IAAI,KAAK,SAAS,OAAOD,IAAGC,EAAC;AAAG;AAAA,MAC/F,KAAK;AAAG,aAAK,SAAS;AAAA;AAAA,MACtB,SAAS;AACP,YAAI,KAAK,MAAM,GAAG;AAChB,eAAK,SAAS,OAAO,KAAK,IAAIA,EAAC;AAC/B,eAAK,SAAS,OAAOD,IAAGC,EAAC;AAAA,QAC3B,OAAO;AACL,cAAI,KAAK,KAAK,MAAM,IAAI,KAAK,MAAMD,KAAI,KAAK;AAC5C,eAAK,SAAS,OAAO,IAAI,KAAK,EAAE;AAChC,eAAK,SAAS,OAAO,IAAIC,EAAC;AAAA,QAC5B;AACA;AAAA,MACF;AAAA,IACF;AACA,SAAK,KAAKD,IAAG,KAAK,KAAKC;AAAA,EACzB;AACF;AAEe,SAAR,aAAiB,SAAS;AAC/B,SAAO,IAAI,KAAK,SAAS,GAAG;AAC9B;AAEO,SAAS,WAAW,SAAS;AAClC,SAAO,IAAI,KAAK,SAAS,CAAC;AAC5B;AAEO,SAAS,UAAU,SAAS;AACjC,SAAO,IAAI,KAAK,SAAS,CAAC;AAC5B;;;ACpDe,SAAR,aAAiB,QAAQ,OAAO;AACrC,MAAI,GAAG,IAAI,OAAO,UAAU,GAAI;AAChC,WAAS,IAAI,GAAG,GAAG,IAAI,KAAK,OAAO,MAAM,CAAC,CAAC,GAAG,GAAG,IAAI,GAAG,QAAQ,IAAI,GAAG,EAAE,GAAG;AAC1E,SAAK,IAAI,KAAK,OAAO,MAAM,CAAC,CAAC;AAC7B,SAAK,IAAI,GAAG,IAAI,GAAG,EAAE,GAAG;AACtB,SAAG,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;AAAA,IAC7D;AAAA,EACF;AACF;;;ACRe,SAARC,cAAiB,QAAQ;AAC9B,MAAI,IAAI,OAAO,QAAQ,IAAI,IAAI,MAAM,CAAC;AACtC,SAAO,EAAE,KAAK,EAAG,GAAE,CAAC,IAAI;AACxB,SAAO;AACT;;;ACCA,SAAS,WAAW,GAAG,KAAK;AAC1B,SAAO,EAAE,GAAG;AACd;AAEA,SAAS,YAAY,KAAK;AACxB,QAAM,SAAS,CAAC;AAChB,SAAO,MAAM;AACb,SAAO;AACT;AAEe,SAAR,gBAAmB;AACxB,MAAI,OAAO,iBAAS,CAAC,CAAC,GAClB,QAAQC,eACR,SAAS,cACTC,SAAQ;AAEZ,WAAS,MAAM,MAAM;AACnB,QAAI,KAAK,MAAM,KAAK,KAAK,MAAM,MAAM,SAAS,GAAG,WAAW,GACxD,GAAG,IAAI,GAAG,QAAQ,IAAI,IACtB;AAEJ,eAAW,KAAK,MAAM;AACpB,WAAK,IAAI,GAAG,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG;AAC3B,SAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAACA,OAAM,GAAG,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,OAAO;AAAA,MACzD;AAAA,IACF;AAEA,SAAK,IAAI,GAAG,KAAK,cAAM,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,EAAE,GAAG;AAC7C,SAAG,GAAG,CAAC,CAAC,EAAE,QAAQ;AAAA,IACpB;AAEA,WAAO,IAAI,EAAE;AACb,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,SAAS,GAAG;AACvB,WAAO,UAAU,UAAU,OAAO,OAAO,MAAM,aAAa,IAAI,iBAAS,MAAM,KAAK,CAAC,CAAC,GAAG,SAAS;AAAA,EACpG;AAEA,QAAM,QAAQ,SAAS,GAAG;AACxB,WAAO,UAAU,UAAUA,SAAQ,OAAO,MAAM,aAAa,IAAI,iBAAS,CAAC,CAAC,GAAG,SAASA;AAAA,EAC1F;AAEA,QAAM,QAAQ,SAAS,GAAG;AACxB,WAAO,UAAU,UAAU,QAAQ,KAAK,OAAOD,gBAAY,OAAO,MAAM,aAAa,IAAI,iBAAS,MAAM,KAAK,CAAC,CAAC,GAAG,SAAS;AAAA,EAC7H;AAEA,QAAM,SAAS,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,SAAS,KAAK,OAAO,eAAa,GAAG,SAAS;AAAA,EAC3E;AAEA,SAAO;AACT;;;ACvDe,SAAR,eAAiB,QAAQ,OAAO;AACrC,MAAI,GAAG,IAAI,OAAO,UAAU,GAAI;AAChC,WAAS,GAAG,GAAG,IAAI,GAAG,IAAI,OAAO,CAAC,EAAE,QAAQE,IAAG,IAAI,GAAG,EAAE,GAAG;AACzD,SAAKA,KAAI,IAAI,GAAG,IAAI,GAAG,EAAE,EAAG,CAAAA,MAAK,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK;AACpD,QAAIA,GAAG,MAAK,IAAI,GAAG,IAAI,GAAG,EAAE,EAAG,QAAO,CAAC,EAAE,CAAC,EAAE,CAAC,KAAKA;AAAA,EACpD;AACA,eAAK,QAAQ,KAAK;AACpB;;;ACPe,SAAR,mBAAiB,QAAQ,OAAO;AACrC,MAAI,GAAG,IAAI,OAAO,UAAU,GAAI;AAChC,WAAS,IAAI,GAAG,KAAK,OAAO,MAAM,CAAC,CAAC,GAAG,GAAG,IAAI,GAAG,QAAQ,IAAI,GAAG,EAAE,GAAG;AACnE,aAAS,IAAI,GAAGC,KAAI,GAAG,IAAI,GAAG,EAAE,EAAG,CAAAA,MAAK,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK;AAC3D,OAAG,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,IAAI,CAACA,KAAI;AAAA,EAC9B;AACA,eAAK,QAAQ,KAAK;AACpB;;;ACYA,IAAM,YAAuE;AAAA,EAC3E,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,MAAM;AAAA,EACN,eAAe;AAAA,EACf,cAAc;AAAA,EACd,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AACX;AAMO,SAAS,aAAa,aAAoD;AAC/E,MAAI,CAAC,YAAa,QAAO;AACzB,SAAO,UAAU,WAAW,KAAK;AACnC;;;AxBTA,IAAM,uBAAuB;AAM7B,SAAS,kBACP,MACA,QACA,YACY;AACZ,QAAM,WAAW,KAAK;AACtB,QAAM,WAAW,SAAS;AAC1B,QAAM,WAAW,SAAS;AAE1B,MAAI,CAAC,YAAY,CAAC,YAAY,CAAC,OAAO,KAAK,CAAC,OAAO,EAAG,QAAO,CAAC;AAE9D,QAAM,SAAS,OAAO,EAAE;AAGxB,QAAM,SAAS,OAAO,OAAO;AAC7B,QAAM,YAAY,OAAO,KAAK,IAAI,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;AAGvD,QAAM,aAAa,SAAS,SAAS,WAAW,SAAS,QAAQ,SAAS,MAAM,QAAQ;AACxF,QAAM,SAAS,oBAAI,IAAuB;AAE1C,MAAI,CAAC,YAAY;AACf,WAAO,IAAI,eAAe,KAAK,IAAI;AAAA,EACrC,OAAO;AACL,eAAW,OAAO,KAAK,MAAM;AAC3B,YAAM,MAAM,OAAO,IAAI,UAAU,KAAK,aAAa;AACnD,YAAM,WAAW,OAAO,IAAI,GAAG;AAC/B,UAAI,UAAU;AACZ,iBAAS,KAAK,GAAG;AAAA,MACnB,OAAO;AACL,eAAO,IAAI,KAAK,CAAC,GAAG,CAAC;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAoB,CAAC;AAE3B,aAAW,CAAC,WAAW,IAAI,KAAK,QAAQ;AACtC,UAAMC,SAAQ,SAAS,QAAQ,SAAS;AAIxC,UAAM,aACJ,SAAS,SAAS,aAAa,SAAS,SAAS,YAC7C,OACA,YAAY,MAAM,SAAS,KAAK;AAGtC,UAAM,cAA4E,CAAC;AAEnF,eAAW,OAAO,YAAY;AAC5B,YAAM,OAAO,WAAW,OAAO,EAAE,OAAO,OAAO,EAAE,MAAM,IAAI,SAAS,KAAK,CAAC;AAC1E,YAAM,OAAO,WAAW,OAAO,EAAE,OAAO,OAAO,EAAE,MAAM,IAAI,SAAS,KAAK,CAAC;AAE1E,UAAI,SAAS,QAAQ,SAAS,KAAM;AAEpC,kBAAY,KAAK;AAAA,QACf,GAAG;AAAA,QACH,MAAM;AAAA,QACN,SAAS;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACH;AAEA,QAAI,YAAY,WAAW,EAAG;AAG9B,UAAM,QAAQ,aAAa,KAAK,QAAQ,WAAW;AACnD,UAAM,gBAAgB,aAAmD,EACtE,EAAE,CAAC,MAAM,EAAE,CAAC,EACZ,GAAG,CAAC,MAAM,EAAE,OAAO,EACnB,GAAG,CAAC,MAAM,EAAE,IAAI,EAChB,MAAM,KAAK;AAEd,UAAM,UAAU,cAAc,WAAW,KAAK;AAG9C,UAAM,mBAAmB,aAAkC,EACxD,EAAE,CAAC,MAAM,EAAE,CAAC,EACZ,EAAE,CAAC,MAAM,EAAE,IAAI,EACf,MAAM,KAAK;AACd,UAAM,aAAa,iBAAiB,WAAW,KAAK;AAEpD,UAAM,YAAY,YAAY,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE;AAChE,UAAM,eAAe,YAAY,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,QAAQ,EAAE;AAEtE,UAAM,YACJ,cAAc,gBACV,aAAa,YAAY,MAAM,iBAC/B,GAAG,SAAS,eAAe,YAAY,MAAM;AAEnD,UAAM,OAAiB,EAAE,OAAO,UAAU;AAE1C,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN,SAAS;AAAA,MACT,MAAMA;AAAA,MACN,aAAa;AAAA,MACb,QAAQC,wBAAuBD,MAAK;AAAA,MACpC,aAAa;AAAA,MACb,WAAW,cAAc,gBAAgB,SAAY;AAAA,MACrD,MAAM,YAAY,IAAI,CAAC,MAAM,EAAE,GAAG;AAAA,MAClC,YAAY,YAAY,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,MAAM,OAAO,EAAE,IAAI,EAAE;AAAA,MACxE;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAMA,SAAS,mBACP,MACA,QACA,WACY;AACZ,QAAM,WAAW,KAAK;AACtB,QAAM,WAAW,SAAS;AAC1B,QAAM,WAAW,SAAS;AAC1B,QAAM,aAAa,SAAS,SAAS,WAAW,SAAS,QAAQ,SAAS,MAAM,QAAQ;AAExF,MAAI,CAAC,YAAY,CAAC,YAAY,CAAC,OAAO,KAAK,CAAC,OAAO,KAAK,CAAC,YAAY;AAEnE,WAAO,kBAAkB,MAAM,QAAQ,SAAS;AAAA,EAClD;AAIA,QAAM,aACJ,SAAS,SAAS,aAAa,SAAS,SAAS,YAC7C,KAAK,OACL,YAAY,KAAK,MAAM,SAAS,KAAK;AAK3C,QAAM,aAAa,oBAAI,IAAY;AACnC,QAAM,YAAY,oBAAI,IAAY;AAClC,QAAM,gBAAgB,oBAAI,IAAqB;AAC/C,QAAM,UAAU,oBAAI,IAAuB;AAE3C,aAAW,OAAO,YAAY;AAC5B,UAAM,OAAO,OAAO,IAAI,SAAS,KAAK,CAAC;AACvC,UAAM,SAAS,OAAO,IAAI,UAAU,CAAC;AACrC,eAAW,IAAI,MAAM;AACrB,cAAU,IAAI,IAAI;AAClB,kBAAc,IAAI,GAAG,IAAI,KAAK,MAAM,IAAI,GAAG;AAE3C,UAAM,WAAW,QAAQ,IAAI,IAAI;AACjC,QAAI,UAAU;AACZ,eAAS,KAAK,GAAG;AAAA,IACnB,OAAO;AACL,cAAQ,IAAI,MAAM,CAAC,GAAG,CAAC;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,OAAO,MAAM,KAAK,UAAU;AAClC,QAAM,UAAU,MAAM,KAAK,SAAS;AAGpC,QAAM,YAAuC,QAAQ,IAAI,CAAC,SAAS;AACjE,UAAM,QAAiC,EAAE,OAAO,KAAK;AACrD,eAAW,OAAO,MAAM;AACtB,YAAM,GAAG,IAAI;AAAA,IACf;AAEA,UAAM,QAAQ,QAAQ,IAAI,IAAI;AAC9B,QAAI,OAAO;AACT,iBAAW,OAAO,OAAO;AACvB,cAAM,SAAS,OAAO,IAAI,UAAU,CAAC;AACrC,cAAM,MAAM,IAAI,IAAI,SAAS,KAAK,KAAK;AAAA,MACzC;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AAGD,QAAM,YAAY,SAAS;AAC3B,QAAM,WACJ,cAAc,cACV,iBACA,cAAc,WACZ,qBACA;AAGR,QAAM,iBAAiB,cAA+B,EACnD,KAAK,IAAI,EACT,MAAME,aAAc,EACpB,OAAO,QAAQ;AAElB,QAAM,cAAc,eAAe,SAAS;AAC5C,QAAM,SAAS,OAAO,EAAE;AACxB,QAAM,QAAoB,CAAC;AAE3B,aAAW,SAAS,aAAa;AAC/B,UAAM,YAAY,MAAM;AACxB,UAAMF,SAAQ,SAAS,QAAQ,SAAS;AAExC,UAAM,cAA8D,CAAC;AAErE,eAAW,KAAK,OAAO;AACrB,YAAM,OAAO,WAAW,OAAO,EAAE,OAAO,OAAO,EAAE,MAAM,EAAE,KAAK,KAAK;AAEnE,UAAI,SAAS,KAAM;AAEnB,YAAM,OAAO,OAAO,EAAE,CAAC,CAAW;AAClC,YAAM,UAAU,OAAO,EAAE,CAAC,CAAW;AAErC,kBAAY,KAAK,EAAE,GAAG,MAAM,MAAM,QAAQ,CAAC;AAAA,IAC7C;AAEA,QAAI,YAAY,WAAW,EAAG;AAE9B,UAAM,aAAa,aAAa,KAAK,QAAQ,WAAW;AACxD,UAAM,gBAAgB,aAAmD,EACtE,EAAE,CAAC,MAAM,EAAE,CAAC,EACZ,GAAG,CAAC,MAAM,EAAE,OAAO,EACnB,GAAG,CAAC,MAAM,EAAE,IAAI,EAChB,MAAM,UAAU;AAEnB,UAAM,UAAU,cAAc,WAAW,KAAK;AAE9C,UAAM,mBAAmB,aAAkC,EACxD,EAAE,CAAC,MAAM,EAAE,CAAC,EACZ,EAAE,CAAC,MAAM,EAAE,IAAI,EACf,MAAM,UAAU;AACnB,UAAM,aAAa,iBAAiB,WAAW,KAAK;AAEpD,UAAM,YAAY,YAAY,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE;AAChE,UAAM,eAAe,YAAY,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,QAAQ,EAAE;AAEtE,UAAM,OAAiB;AAAA,MACrB,OAAO,GAAG,SAAS,uBAAuB,YAAY,MAAM;AAAA,IAC9D;AAEA,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN,SAAS;AAAA,MACT,MAAMA;AAAA,MACN,aAAa;AAAA;AAAA,MACb,QAAQC,wBAAuBD,MAAK;AAAA,MACpC,aAAa;AAAA,MACb;AAAA,MACA,MAAM,MAAM,IAAI,CAAC,MAAM;AACrB,cAAM,OAAO,OAAO,EAAE,KAAK,KAAK;AAChC,eAAQ,cAAc,IAAI,GAAG,IAAI,KAAK,SAAS,EAAE,KAAK,EAAE;AAAA,MAC1D,CAAC;AAAA,MACD,YAAY,YAAY,IAAI,CAAC,GAAG,QAAQ;AACtC,cAAM,OAAO,OAAO,MAAM,GAAG,GAAG,KAAK,KAAK;AAC1C,cAAM,QAAS,cAAc,IAAI,GAAG,IAAI,KAAK,SAAS,EAAE,KACtD,MAAM,GAAG,GAAG,QACZ,CAAC;AACH,eAAO,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,MAAM,MAAM;AAAA,MACpC,CAAC;AAAA,MACD;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAYO,SAAS,iBACd,MACA,QACA,WACY;AACZ,QAAM,WAAW,KAAK;AACtB,QAAM,WAAW,CAAC,CAAC,SAAS;AAE5B,MAAI,UAAU;AACZ,WAAO,mBAAmB,MAAM,QAAQ,SAAS;AAAA,EACnD;AAEA,SAAO,kBAAkB,MAAM,QAAQ,SAAS;AAClD;;;AyBvTA,SAAS,0BAAAG,+BAA8B;AAavC,IAAM,uBAAuB;AAG7B,IAAM,uBAAuB;AAatB,SAAS,iBACd,MACA,QACA,YACA,WAC0B;AAC1B,QAAM,WAAW,KAAK;AACtB,QAAM,WAAW,SAAS;AAC1B,QAAM,WAAW,SAAS;AAE1B,MAAI,CAAC,YAAY,CAAC,YAAY,CAAC,OAAO,KAAK,CAAC,OAAO,GAAG;AACpD,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,WAAW,SAAS,SAAS,WAAW,SAAS,QAAQ,SAAS,QAAQ;AAChF,QAAM,oBAAoB,UAAU,SAAS;AAE7C,QAAM,aAAa,oBAAoB,SAAY,UAAU;AAC7D,QAAM,uBAAuB,oBAAoB,SAAS,QAAQ;AAClE,QAAM,SAAS,aAAa,KAAK,MAAM,UAAU;AACjD,QAAM,QAAkC,CAAC;AAEzC,aAAW,CAAC,WAAW,IAAI,KAAK,QAAQ;AAEtC,UAAMC,SAA8B,oBAChC,mBAAmB,QAAQ,aAAa,MAAM,oBAAqB,CAAC,IACpE,SAAS,QAAQ,SAAS;AAC9B,UAAM,cAAcC,wBAAuBD,MAAK;AAKhD,UAAM,aACJ,SAAS,SAAS,aAAa,SAAS,SAAS,YAC7C,OACA,YAAY,MAAM,SAAS,KAAK;AAItC,UAAM,iBAIA,CAAC;AAGP,UAAM,WAAyC,CAAC;AAChD,QAAI,iBAA6C,CAAC;AAElD,eAAW,OAAO,YAAY;AAC5B,YAAM,OAAO,WAAW,OAAO,EAAE,OAAO,OAAO,EAAE,MAAM,IAAI,SAAS,KAAK,CAAC;AAC1E,YAAM,OAAO,WAAW,OAAO,EAAE,OAAO,OAAO,EAAE,MAAM,IAAI,SAAS,KAAK,CAAC;AAE1E,UAAI,SAAS,QAAQ,SAAS,MAAM;AAElC,YAAI,eAAe,SAAS,GAAG;AAC7B,mBAAS,KAAK,cAAc;AAC5B,2BAAiB,CAAC;AAAA,QACpB;AACA;AAAA,MACF;AAEA,YAAME,SAAQ,EAAE,GAAG,MAAM,GAAG,KAAK;AACjC,qBAAe,KAAKA,MAAK;AACzB,qBAAe,KAAK,EAAE,GAAGA,QAAO,IAAI,CAAC;AAAA,IACvC;AAGA,QAAI,eAAe,SAAS,GAAG;AAC7B,eAAS,KAAK,cAAc;AAAA,IAC9B;AAGA,UAAM,QAAQ,aAAa,KAAK,QAAQ,WAAW;AACnD,UAAM,gBAAgB,aAA+B,EAClD,EAAE,CAAC,MAAM,EAAE,CAAC,EACZ,EAAE,CAAC,MAAM,EAAE,CAAC,EACZ,MAAM,KAAK;AAKd,UAAM,YAAwC,CAAC;AAC/C,UAAM,YAAsB,CAAC;AAE7B,eAAW,WAAW,UAAU;AAC9B,UAAI,QAAQ,WAAW,EAAG;AAC1B,YAAM,UAAU,cAAc,OAAO;AACrC,UAAI,SAAS;AACX,kBAAU,KAAK,OAAO;AAAA,MACxB;AACA,gBAAU,KAAK,GAAG,OAAO;AAAA,IAC3B;AAGA,QAAI,UAAU,WAAW,EAAG;AAE5B,UAAM,YACJ,cAAc,gBACV,aAAa,UAAU,MAAM,iBAC7B,GAAG,SAAS,eAAe,UAAU,MAAM;AAEjD,UAAM,OAAiB;AAAA,MACrB,OAAO;AAAA,IACT;AAKA,UAAM,eAAe,UAAU,KAAK,GAAG;AAGvC,UAAM,iBAAiB,cAAc,gBAAgB,SAAY;AACjE,UAAM,gBAAgB,iBAAiB,KAAK,eAAe,cAAc,IAAI;AAG7E,QAAI;AACJ,QAAI,eAAe,cAAc,SAAU,mBAAkB;AAAA,aACpD,eAAe,cAAc,SAAU,mBAAkB;AAKlE,UAAM,WAAqB;AAAA,MACzB,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,aAAa,eAAe,eAAe;AAAA,MAC3C;AAAA,MACA,SAAS,eAAe;AAAA,MACxB,WAAW;AAAA,MACX,MAAM,eAAe,IAAI,CAAC,MAAM,EAAE,GAAG;AAAA,MACrC,YAAY,eAAe,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE;AAAA,MACxE;AAAA,IACF;AAEA,UAAM,KAAK,QAAQ;AAInB,UAAM,YAAY,KAAK,QAAQ;AAC/B,UAAM,aAAa,cAAc,QAAQ,cAAc,iBAAiB;AAExE,QAAI,YAAY;AACd,YAAM,gBAAgB,cAAc;AAEpC,YAAM,mBAAmB,eAAe,eAAe;AAEvD,eAAS,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK;AAC9C,cAAM,IAAI,eAAe,CAAC;AAC1B,cAAM,UAAU,oBAAoB,CAAC;AAErC,YAAI,aAAaF;AACjB,YAAI,mBAAmB;AACrB,gBAAM,MAAM,OAAO,EAAE,IAAI,oBAAqB,CAAC;AAC/C,uBAAa,OAAO,SAAS,GAAG,IAAI,mBAAmB,QAAQ,GAAG,IAAIA;AAAA,QACxE;AACA,cAAM,YAAuB;AAAA,UAC3B,MAAM;AAAA,UACN,IAAI,EAAE;AAAA,UACN,IAAI,EAAE;AAAA,UACN,GAAG,UAAU,uBAAuB;AAAA,UACpC,MAAM;AAAA,UACN,QAAQ,UAAU,YAAY;AAAA,UAC9B,aAAa,UAAU,MAAM;AAAA,UAC7B,aAAa,gBAAgB,IAAI;AAAA,UACjC,MAAM,EAAE;AAAA,UACR,MAAM;AAAA,YACJ,OAAO,eAAe,SAAS,KAAK,IAAI,OAAO,EAAE,IAAI,SAAS,KAAK,CAAC,CAAC,KAAK,SAAS,KAAK,IAAI,OAAO,EAAE,IAAI,SAAS,KAAK,CAAC,CAAC;AAAA,UAC3H;AAAA,QACF;AACA,cAAM,KAAK,SAAS;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAOA,SAAS,aAAa,MAAiB,OAAuB;AAC5D,QAAM,SAAS,KAAK,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,OAAO,OAAO,QAAQ;AACvE,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAM,SAAS,OAAO,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAC1C,SAAO,OAAO,KAAK,MAAM,OAAO,SAAS,CAAC,CAAC;AAC7C;;;ACzNA;AAAA,EACE;AAAA,EACA,qBAAAG;AAAA,EACA,qBAAAC;AAAA,OACK;AAOP,IAAMC,mBAAkB;AAGxB,IAAMC,qBAAoB;AAG1B,IAAMC,kBAAiB;AAsBhB,SAAS,kBACd,OACA,UACA,UAAwB,QACxB,cAC4B;AAC5B,QAAM,SAAS,oBAAI,IAA2B;AAG9C,MAAI,YAAY,OAAQ,QAAO;AAG/B,MAAI,SAAS,cAAc,QAAQ;AACjC,WAAO;AAAA,EACT;AAEA,QAAM,aAA+B,CAAC;AACtC,QAAM,cAAwB,CAAC;AAE/B,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,OAAO,WAAW,EAAG;AAE9B,UAAM,YAAY,KAAK,aAAa;AACpC,QAAI,CAAC,UAAW;AAEhB,UAAM,YAAY,KAAK,OAAO,KAAK,OAAO,SAAS,CAAC;AACpD,UAAM,YAAYJ,mBAAkB,WAAWE,kBAAiBC,kBAAiB;AACjF,UAAM,aAAaD,mBAAkB;AAErC,eAAW,KAAK;AAAA,MACd,MAAM;AAAA,MACN,SAAS,UAAU,IAAIE;AAAA,MACvB,SAAS,UAAU,IAAI,aAAa;AAAA,MACpC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,OAAO;AAAA,QACL,YAAY;AAAA,QACZ,UAAUF;AAAA,QACV,YAAYC;AAAA,QACZ,MAAM,KAAK;AAAA,QACX,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,kBAAkB;AAAA,MACpB;AAAA,IACF,CAAC;AAED,gBAAY,KAAK,SAAS;AAAA,EAC5B;AAEA,MAAI,WAAW,WAAW,EAAG,QAAO;AAGpC,MAAI,YAAY,OAAO;AACrB,aAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,YAAM,IAAI,WAAW,CAAC;AACtB,YAAM,YAAY,YAAY,CAAC;AAC/B,YAAM,aAAa,eAAe,SAAS;AAC3C,aAAO,IAAI,WAAW;AAAA,QACpB,MAAM,EAAE;AAAA,QACR,GAAG,EAAE,WAAW,YAAY,MAAM;AAAA,QAClC,GAAG,EAAE,WAAW,YAAY,MAAM;AAAA,QAClC,OAAO,EAAE;AAAA,QACT,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAMA,QAAM,WAAWF,mBAAkB,YAAY,0BAA0B;AACzE,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAM,YAAY,YAAY,CAAC;AAC/B,UAAM,QAAQ,SAAS,CAAC;AAExB,UAAM,aAAa,eAAe,SAAS;AAC3C,QAAI,YAAY;AACd,YAAM,KAAK,WAAW,MAAM;AAC5B,YAAM,KAAK,WAAW,MAAM;AAAA,IAC9B;AACA,WAAO,IAAI,WAAW,KAAK;AAAA,EAC7B;AAEA,SAAO;AACT;;;A3B5HO,IAAM,eAA8B,CAAC,MAAM,QAAQ,WAAW,UAAU,WAAW;AACxF,QAAM,QAAQ,iBAAiB,MAAM,QAAQ,WAAW,QAAQ;AAGhE,QAAM,YAAY,MAAM,OAAO,CAAC,MAAqB,EAAE,SAAS,MAAM;AAGtE,QAAM,WAAW,kBAAkB,WAAW,UAAU,KAAK,OAAO,SAAS,KAAK,OAAO,OAAO;AAChG,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,UAAU,KAAK,WAAW;AAC1C,YAAM,QAAQ,SAAS,IAAI,KAAK,SAAS;AACzC,UAAI,OAAO;AACT,aAAK,QAAQ;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAaO,IAAM,eAA8B,CAAC,MAAM,QAAQ,WAAW,UAAU,WAAW;AACxF,QAAM,QAAQ,iBAAiB,MAAM,QAAQ,SAAS;AAEtD,QAAM,WAAW,KAAK;AACtB,QAAM,WAAW,CAAC,EAAE,SAAS,SAAS,WAAW,SAAS;AAI1D,QAAM,QAAQ,WACV,eAAe,KAAK,IACpB,iBAAiB,MAAM,QAAQ,WAAW,QAAQ;AAGtD,SAAO,CAAC,GAAG,OAAO,GAAG,KAAK;AAC5B;AAUA,SAAS,eAAe,OAA+B;AACrD,SAAO,MAAM,IAAI,CAAC,OAAO;AAAA,IACvB,MAAM;AAAA,IACN,QAAQ,EAAE;AAAA,IACV,MAAM,EAAE;AAAA,IACR,QAAQI,wBAAuB,EAAE,IAAI;AAAA,IACrC,aAAa,EAAE,eAAe;AAAA,IAC9B,WAAW,EAAE;AAAA,IACb,MAAM,EAAE;AAAA,IACR,YAAY,EAAE;AAAA,IACd,MAAM,EAAE,OAAO,GAAG,EAAE,aAAa,QAAQ,eAAe,EAAE,UAAU,MAAM,eAAe;AAAA,EAC3F,EAAE;AACJ;;;A4BxEA,SAAS,kBAAkB,iBAAAC,sBAAqB;AAahD,IAAM,wBAAwB;AAG9B,IAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAiBA,SAAS,iBAAiB,QAAqBC,YAAgC;AAC7E,QAAM,QAAQ,OAAO,OAAO,CAACC,MAAK,MAAMA,OAAM,EAAE,OAAO,CAAC;AACxD,MAAI,UAAU,EAAG,QAAO;AAExB,QAAM,MAAmB,CAAC;AAC1B,MAAI,aAAa;AAEjB,aAAWC,UAAS,QAAQ;AAC1B,QAAIA,OAAM,QAAQ,QAAQF,YAAW;AACnC,oBAAcE,OAAM;AAAA,IACtB,OAAO;AACL,UAAI,KAAKA,MAAK;AAAA,IAChB;AAAA,EACF;AAEA,MAAI,aAAa,GAAG;AAClB,QAAI,KAAK;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,aAAa,EAAE,OAAO,SAAS,OAAO,WAAW;AAAA,IACnD,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAeO,SAAS,gBACd,MACA,QACA,WACA,WACA,UAAU,OACC;AACX,QAAM,WAAW,KAAK;AAItB,QAAM,eAAe,SAAS,KAAK,SAAS;AAC5C,QAAM,gBACJ,SAAS,SAAS,WAAW,SAAS,QAAQ,SAAS,MAAM,QAAQ;AACvE,QAAM,mBACJ,SAAS,SAAS,iBAAiB,SAAS,KAAK,IAC5C,SAAS,QACV;AAEN,MAAI,CAAC,aAAc,QAAO,CAAC;AAG3B,MAAI,SAAsB,CAAC;AAE3B,MAAI,eAAe;AAEjB,UAAM,iBAAiB,oBAAI,IAAoB;AAC/C,UAAM,eAAe,oBAAI,IAAqB;AAE9C,eAAW,OAAO,KAAK,MAAM;AAC3B,YAAM,MAAM,OAAO,IAAI,aAAa,KAAK,EAAE;AAC3C,YAAM,MAAM,OAAO,IAAI,aAAa,KAAK,KAAK,CAAC;AAC/C,UAAI,CAAC,OAAO,SAAS,GAAG,KAAK,MAAM,EAAG;AAEtC,qBAAe,IAAI,MAAM,eAAe,IAAI,GAAG,KAAK,KAAK,GAAG;AAC5D,UAAI,CAAC,aAAa,IAAI,GAAG,GAAG;AAC1B,qBAAa,IAAI,KAAK,GAAG;AAAA,MAC3B;AAAA,IACF;AAEA,eAAW,CAAC,OAAOC,MAAK,KAAK,gBAAgB;AAC3C,aAAO,KAAK;AAAA,QACV;AAAA,QACA,OAAAA;AAAA,QACA,aAAa,aAAa,IAAI,KAAK,KAAK;AAAA,UACtC,CAAC,aAAa,GAAG;AAAA,UACjB,CAAC,aAAa,KAAK,GAAGA;AAAA,QACxB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,OAAO;AAEL,aAAS,IAAI,GAAG,IAAI,KAAK,KAAK,QAAQ,KAAK;AACzC,YAAM,MAAM,KAAK,KAAK,CAAC;AACvB,YAAM,MAAM,OAAO,IAAI,aAAa,KAAK,KAAK,CAAC;AAC/C,UAAI,CAAC,OAAO,SAAS,GAAG,KAAK,MAAM,EAAG;AAGtC,YAAM,QAAQ,OAAO,IAAI,SAAS,IAAI,QAAQ,IAAI,YAAY,SAAS,IAAI,CAAC,EAAE;AAE9E,aAAO,KAAK,EAAE,OAAO,OAAO,KAAK,aAAa,IAAI,CAAC;AAAA,IACrD;AAAA,EACF;AAEA,MAAI,OAAO,WAAW,EAAG,QAAO,CAAC;AAGjC,SAAO,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAGvC,WAAS,iBAAiB,QAAQ,qBAAqB;AAGvD,QAAM,eAAe,YAAiB,EACnC,MAAM,CAAC,MAAM,EAAE,KAAK,EACpB,KAAK,IAAI,EACT,SAAS,IAAI;AAEhB,QAAM,OAAO,aAAa,MAAM;AAGhC,QAAM,UAAU,UAAU,IAAI,UAAU,QAAQ;AAChD,QAAM,UAAU,UAAU,IAAI,UAAU,SAAS;AACjD,QAAM,cAAe,KAAK,IAAI,UAAU,OAAO,UAAU,MAAM,IAAI,IAAK;AACxE,QAAM,cAAc,UAAU,cAAc,MAAM;AAElD,QAAM,eAAe,YAA8B,EAChD,YAAY,WAAW,EACvB,YAAY,WAAW;AAG1B,QAAM,QAAmB,CAAC;AAC1B,QAAMC,UAAS,EAAE,GAAG,SAAS,GAAG,QAAQ;AACxC,QAAM,QAAQ,OAAO,OAAO,CAACH,MAAK,MAAMA,OAAM,EAAE,OAAO,CAAC;AAExD,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,WAAW,KAAK,CAAC;AACvB,UAAMC,SAAQ,SAAS;AAGvB,QAAIG;AACJ,QAAI,kBAAkB;AACpB,YAAM,WAAW;AAAA,QACfH,OAAM;AAAA,QACN;AAAA,MACF;AACA,UAAI,YAAY,MAAM;AACpB,QAAAG,SAAQC,eAAc,QAAQ,IAAI,WAAW,OAAO,QAAQ;AAAA,MAC9D,WAAW,OAAO,SAAS,eAAe;AACxC,cAAM,aAAa,OAAO,MAAM;AAChC,QAAAD,SAAQ,WAAWH,OAAM,KAAK;AAAA,MAChC,OAAO;AACL,QAAAG,SAAQ,gBAAgB,IAAI,gBAAgB,MAAM;AAAA,MACpD;AAAA,IACF,WAAW,OAAO,SAAS,eAAe;AACxC,YAAM,aAAa,OAAO,MAAM;AAChC,MAAAA,SAAQ,WAAWH,OAAM,KAAK;AAAA,IAChC,OAAO;AACL,MAAAG,SAAQ,gBAAgB,IAAI,gBAAgB,MAAM;AAAA,IACpD;AAGA,UAAME,QAAO,aAAa,QAAQ,KAAK;AAGvC,UAAM,iBAAiB,aAAa,SAAS,QAAQ;AAErD,UAAM,aAAa,QAAQ,KAAML,OAAM,QAAQ,QAAS,KAAK,QAAQ,CAAC,IAAI;AAE1E,UAAM,OAAiB;AAAA,MACrB,OAAO,GAAGA,OAAM,KAAK,KAAKA,OAAM,KAAK,KAAK,UAAU;AAAA,IACtD;AAEA,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,MAAAK;AAAA,MACA,UAAU;AAAA,QACR,GAAG,eAAe,CAAC,IAAI;AAAA,QACvB,GAAG,eAAe,CAAC,IAAI;AAAA,MACzB;AAAA,MACA,QAAAH;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,SAAS;AAAA,MACrB,UAAU,SAAS;AAAA,MACnB,MAAMC;AAAA,MACN,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,MAAMH,OAAM;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AC1OA,SAAS,qBAAAM,oBAAmB,qBAAAC,0BAAyB;AAOrD,IAAMC,mBAAkB;AACxB,IAAMC,qBAAoB;AAC1B,IAAM,qBAAqB;AAapB,SAAS,iBACd,OACA,YACA,UAAwB,QACxB,YAAY,WACK;AACjB,MAAI,MAAM,WAAW,EAAG,QAAO,CAAC;AAIhC,QAAM,UAAU,MAAM,CAAC,EAAE,OAAO;AAChC,QAAM,UAAU,MAAM,CAAC,EAAE,OAAO;AAEhC,QAAM,cAAc,gBAAgB,OAAO,OAAO;AAClD,MAAI,YAAY,WAAW,EAAG,QAAO,CAAC;AAEtC,QAAM,aAA+B,CAAC;AACtC,QAAM,oBAA8B,CAAC;AAErC,WAAS,KAAK,GAAG,KAAK,YAAY,QAAQ,MAAM;AAC9C,UAAM,OAAO,YAAY,EAAE;AAI3B,UAAM,YAAY,KAAK,KAAK;AAC5B,UAAM,aAAa,UAAU,QAAQ,GAAG;AACxC,UAAM,YAAY,cAAc,IAAI,UAAU,MAAM,GAAG,UAAU,EAAE,KAAK,IAAI;AAC5E,QAAI,CAAC,UAAW;AAEhB,UAAM,YAAYC,mBAAkB,WAAWF,kBAAiBC,kBAAiB;AACjF,UAAM,aAAaD,mBAAkB;AAGrC,UAAM,YAAY,KAAK,aAAa,KAAK,YAAY;AACrD,UAAM,cAAc,KAAK,cAAc;AAEvC,UAAM,SAAS,UAAU,KAAK,IAAI,QAAQ,IAAI;AAC9C,UAAM,SAAS,UAAU,KAAK,IAAI,QAAQ,IAAI;AAG9C,UAAM,UAAU,KAAK,IAAI,QAAQ,IAAI;AAErC,eAAW,KAAK;AAAA,MACd,MAAM;AAAA,MACN,SAAS,UAAU,SAAS,SAAS;AAAA,MACrC,SAAS,SAAS,aAAa;AAAA,MAC/B,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,OAAO;AAAA,QACL,YAAY;AAAA,QACZ,UAAUA;AAAA,QACV,YAAYC;AAAA,QACZ,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,YAAY,UAAU,UAAU;AAAA,QAChC,kBAAkB;AAAA,MACpB;AAAA,IACF,CAAC;AAED,sBAAkB,KAAK,EAAE;AAAA,EAC3B;AAEA,MAAI,WAAW,WAAW,EAAG,QAAO,CAAC;AAGrC,MAAI;AACJ,MAAI,YAAY,OAAO;AACrB,eAAW,WAAW,IAAI,CAAC,OAAO;AAAA,MAChC,MAAM,EAAE;AAAA,MACR,GAAG,EAAE;AAAA,MACL,GAAG,EAAE;AAAA,MACL,OAAO,EAAE;AAAA,MACT,SAAS;AAAA,IACX,EAAE;AAAA,EACJ,OAAO;AAEL,eAAWE,mBAAkB,UAAU;AAAA,EACzC;AAGA,WAAS,IAAI,GAAG,IAAI,SAAS,UAAU,IAAI,YAAY,QAAQ,KAAK;AAClE,UAAM,QAAQ,SAAS,CAAC;AACxB,UAAM,OAAO,YAAY,CAAC;AAE1B,QAAI,MAAM,SAAS;AACjB,YAAM,YAAY;AAAA,QAChB,MAAM,EAAE,GAAG,MAAM,GAAG,GAAG,MAAM,EAAE;AAAA,QAC/B,IAAI,EAAE,GAAG,KAAK,SAAS,GAAG,GAAG,KAAK,SAAS,EAAE;AAAA,QAC7C,QAAQ;AAAA,QACR,OAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AC5HO,IAAM,cAA6B,CAAC,MAAM,QAAQ,WAAW,UAAU,UAAU;AACtF,QAAM,QAAQ,gBAAgB,MAAM,QAAQ,WAAW,UAAU,KAAK;AAGtE,QAAM,SAAS,iBAAiB,OAAO,WAAW,KAAK,OAAO,SAAS,MAAM,OAAO,IAAI;AACxF,WAAS,IAAI,GAAG,IAAI,MAAM,UAAU,IAAI,OAAO,QAAQ,KAAK;AAC1D,UAAM,CAAC,EAAE,QAAQ,OAAO,CAAC;AAAA,EAC3B;AAEA,SAAO;AACT;AAMO,IAAM,gBAA+B,CAAC,MAAM,QAAQ,WAAW,UAAU,UAAU;AACxF,QAAM,QAAQ,gBAAgB,MAAM,QAAQ,WAAW,UAAU,IAAI;AAGrE,QAAM,SAAS,iBAAiB,OAAO,WAAW,KAAK,OAAO,SAAS,MAAM,OAAO,IAAI;AACxF,WAAS,IAAI,GAAG,IAAI,MAAM,UAAU,IAAI,OAAO,QAAQ,KAAK;AAC1D,UAAM,CAAC,EAAE,QAAQ,OAAO,CAAC;AAAA,EAC3B;AAEA,SAAO;AACT;;;ACLA,IAAM,YAAY,oBAAI,IAA2B;AAQ1C,SAAS,sBAAsB,MAAc,UAA+B;AACjF,YAAU,IAAI,MAAM,QAAQ;AAC9B;AAQO,SAAS,iBAAiB,MAAyC;AACxE,SAAO,UAAU,IAAI,IAAI;AAC3B;AAWO,SAAS,iBAAuB;AACrC,YAAU,MAAM;AAClB;;;AC5DA,SAAS,0BAAAC,+BAA8B;AAiBhC,SAAS,iBACd,MACA,QACA,WACkB;AAClB,QAAM,WAAW,KAAK;AACtB,QAAM,WAAW,SAAS;AAC1B,QAAM,WAAW,SAAS;AAC1B,QAAM,YAAY,SAAS;AAC3B,QAAM,YAAY,SAAS;AAC3B,QAAM,gBAAgB,SAAS,SAAS,WAAW,SAAS,QAAQ,SAAS,QAAQ;AACrF,QAAM,aAAa,eAAe;AAElC,QAAM,QAA0B,CAAC;AAEjC,aAAW,OAAO,KAAK,MAAM;AAC3B,QAAI,KAAK,UAAU;AACnB,QAAI,KAAK,UAAU;AACnB,QAAI,KAAK,UAAU,IAAI,UAAU;AACjC,QAAI,KAAK,UAAU,IAAI,UAAU;AAGjC,QAAI,YAAY,OAAO,GAAG;AACxB,YAAM,OAAO,WAAW,OAAO,EAAE,OAAO,OAAO,EAAE,MAAM,IAAI,SAAS,KAAK,CAAC;AAC1E,UAAI,QAAQ,KAAM;AAClB,WAAK;AACL,WAAK;AAAA,IACP;AAGA,QAAI,YAAY,OAAO,GAAG;AACxB,YAAM,OAAO,WAAW,OAAO,EAAE,OAAO,OAAO,EAAE,MAAM,IAAI,SAAS,KAAK,CAAC;AAC1E,UAAI,QAAQ,KAAM;AAClB,WAAK;AACL,WAAK;AAAA,IACP;AAGA,QAAI,YAAY,CAAC,UAAU;AACzB,WAAK,UAAU;AACf,WAAK,UAAU,IAAI,UAAU;AAAA,IAC/B;AAGA,QAAI,YAAY,CAAC,UAAU;AACzB,WAAK,UAAU;AACf,WAAK,UAAU,IAAI,UAAU;AAAA,IAC/B;AAGA,QAAI,aAAa,OAAO,GAAG;AACzB,YAAM,QAAQ,WAAW,OAAO,EAAE,OAAO,OAAO,EAAE,MAAM,IAAI,UAAU,KAAK,CAAC;AAC5E,UAAI,SAAS,KAAM,MAAK;AAAA,IAC1B;AAGA,QAAI,aAAa,OAAO,GAAG;AACzB,YAAM,QAAQ,WAAW,OAAO,EAAE,OAAO,OAAO,EAAE,MAAM,IAAI,UAAU,KAAK,CAAC;AAC5E,UAAI,SAAS,KAAM,MAAK;AAAA,IAC1B;AAEA,UAAMC,SAAQC;AAAA,MACZ,aACI,SAAS,QAAQ,OAAO,IAAI,UAAU,KAAK,aAAa,CAAC,IACzD,SAAS,QAAQ,aAAa;AAAA,IACpC;AAEA,UAAM,qBACJ,SAAS,cAAc,WAAW,SAAS,aAAa,SAAS,aAAa;AAChF,UAAM,kBAAkB,qBACpB,OAAO,IAAI,mBAAmB,KAAK,KAAK,EAAE,IAC1C;AAEJ,UAAM,OAAiB;AAAA,MACrB,OAAO,cAAc,KAAK,MAAM,EAAE,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;AAAA,IAClG;AAEA,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQD;AAAA,MACR,aAAa;AAAA,MACb,iBAAiB,mBAAmB;AAAA,MACpC,SACE,SAAS,WAAW,WAAW,SAAS,UACpC,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,IAAI,SAAS,QAAQ,KAAK,CAAC,KAAK,CAAC,CAAC,IACjE;AAAA,MACN,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAKO,IAAM,eAA8B,CAAC,MAAM,QAAQ,WAAW,WAAW,WAAW;AACzF,SAAO,iBAAiB,MAAM,QAAQ,SAAS;AACjD;;;ACjIe,SAAR,UAA2B,GAAG,GAAG;AACtC,SAAO,KAAK,QAAQ,KAAK,OAAO,MAAM,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI;AAC9E;;;ACFe,SAAR,WAA4B,GAAG,GAAG;AACvC,SAAO,KAAK,QAAQ,KAAK,OAAO,MAC5B,IAAI,IAAI,KACR,IAAI,IAAI,IACR,KAAK,IAAI,IACT;AACN;;;ACHe,SAAR,SAA0B,GAAG;AAClC,MAAI,UAAU,UAAU;AAOxB,MAAI,EAAE,WAAW,GAAG;AAClB,eAAW;AACX,eAAW,CAAC,GAAGE,OAAM,UAAU,EAAE,CAAC,GAAGA,EAAC;AACtC,YAAQ,CAAC,GAAGA,OAAM,EAAE,CAAC,IAAIA;AAAA,EAC3B,OAAO;AACL,eAAW,MAAM,aAAa,MAAM,aAAa,IAAI;AACrD,eAAW;AACX,YAAQ;AAAA,EACV;AAEA,WAASC,MAAK,GAAGD,IAAG,KAAK,GAAG,KAAK,EAAE,QAAQ;AACzC,QAAI,KAAK,IAAI;AACX,UAAI,SAASA,IAAGA,EAAC,MAAM,EAAG,QAAO;AACjC,SAAG;AACD,cAAM,MAAO,KAAK,OAAQ;AAC1B,YAAI,SAAS,EAAE,GAAG,GAAGA,EAAC,IAAI,EAAG,MAAK,MAAM;AAAA,YACnC,MAAK;AAAA,MACZ,SAAS,KAAK;AAAA,IAChB;AACA,WAAO;AAAA,EACT;AAEA,WAASE,OAAM,GAAGF,IAAG,KAAK,GAAG,KAAK,EAAE,QAAQ;AAC1C,QAAI,KAAK,IAAI;AACX,UAAI,SAASA,IAAGA,EAAC,MAAM,EAAG,QAAO;AACjC,SAAG;AACD,cAAM,MAAO,KAAK,OAAQ;AAC1B,YAAI,SAAS,EAAE,GAAG,GAAGA,EAAC,KAAK,EAAG,MAAK,MAAM;AAAA,YACpC,MAAK;AAAA,MACZ,SAAS,KAAK;AAAA,IAChB;AACA,WAAO;AAAA,EACT;AAEA,WAASG,QAAO,GAAGH,IAAG,KAAK,GAAG,KAAK,EAAE,QAAQ;AAC3C,UAAM,IAAIC,MAAK,GAAGD,IAAG,IAAI,KAAK,CAAC;AAC/B,WAAO,IAAI,MAAM,MAAM,EAAE,IAAI,CAAC,GAAGA,EAAC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAGA,EAAC,IAAI,IAAI,IAAI;AAAA,EAClE;AAEA,SAAO,EAAC,MAAAC,OAAM,QAAAE,SAAQ,OAAAD,OAAK;AAC7B;AAEA,SAAS,OAAO;AACd,SAAO;AACT;;;ACvDe,SAAR,OAAwBE,IAAG;AAChC,SAAOA,OAAM,OAAO,MAAM,CAACA;AAC7B;;;ACEA,IAAM,kBAAkB,SAAS,SAAS;AACnC,IAAM,cAAc,gBAAgB;AACpC,IAAM,aAAa,gBAAgB;AACnC,IAAM,eAAe,SAAS,MAAM,EAAE;AAC7C,IAAO,iBAAQ;;;ACRA,SAAR,OAAwB,QAAQ,SAAS;AAC9C,MAAIC;AACJ,MAAIC;AACJ,MAAI,YAAY,QAAW;AACzB,eAAWC,UAAS,QAAQ;AAC1B,UAAIA,UAAS,MAAM;AACjB,YAAIF,SAAQ,QAAW;AACrB,cAAIE,UAASA,OAAO,CAAAF,OAAMC,OAAMC;AAAA,QAClC,OAAO;AACL,cAAIF,OAAME,OAAO,CAAAF,OAAME;AACvB,cAAID,OAAMC,OAAO,CAAAD,OAAMC;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AACL,QAAI,QAAQ;AACZ,aAASA,UAAS,QAAQ;AACxB,WAAKA,SAAQ,QAAQA,QAAO,EAAE,OAAO,MAAM,MAAM,MAAM;AACrD,YAAIF,SAAQ,QAAW;AACrB,cAAIE,UAASA,OAAO,CAAAF,OAAMC,OAAMC;AAAA,QAClC,OAAO;AACL,cAAIF,OAAME,OAAO,CAAAF,OAAME;AACvB,cAAID,OAAMC,OAAO,CAAAD,OAAMC;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAACF,MAAKC,IAAG;AAClB;;;AC5BO,IAAM,YAAN,cAAwB,IAAI;AAAA,EACjC,YAAY,SAAS,MAAM,OAAO;AAChC,UAAM;AACN,WAAO,iBAAiB,MAAM,EAAC,SAAS,EAAC,OAAO,oBAAI,IAAI,EAAC,GAAG,MAAM,EAAC,OAAO,IAAG,EAAC,CAAC;AAC/E,QAAI,WAAW,KAAM,YAAW,CAACE,MAAKC,MAAK,KAAK,QAAS,MAAK,IAAID,MAAKC,MAAK;AAAA,EAC9E;AAAA,EACA,IAAI,KAAK;AACP,WAAO,MAAM,IAAI,WAAW,MAAM,GAAG,CAAC;AAAA,EACxC;AAAA,EACA,IAAI,KAAK;AACP,WAAO,MAAM,IAAI,WAAW,MAAM,GAAG,CAAC;AAAA,EACxC;AAAA,EACA,IAAI,KAAKA,QAAO;AACd,WAAO,MAAM,IAAI,WAAW,MAAM,GAAG,GAAGA,MAAK;AAAA,EAC/C;AAAA,EACA,OAAO,KAAK;AACV,WAAO,MAAM,OAAO,cAAc,MAAM,GAAG,CAAC;AAAA,EAC9C;AACF;AAmBA,SAAS,WAAW,EAAC,SAAS,KAAI,GAAGC,QAAO;AAC1C,QAAM,MAAM,KAAKA,MAAK;AACtB,SAAO,QAAQ,IAAI,GAAG,IAAI,QAAQ,IAAI,GAAG,IAAIA;AAC/C;AAEA,SAAS,WAAW,EAAC,SAAS,KAAI,GAAGA,QAAO;AAC1C,QAAM,MAAM,KAAKA,MAAK;AACtB,MAAI,QAAQ,IAAI,GAAG,EAAG,QAAO,QAAQ,IAAI,GAAG;AAC5C,UAAQ,IAAI,KAAKA,MAAK;AACtB,SAAOA;AACT;AAEA,SAAS,cAAc,EAAC,SAAS,KAAI,GAAGA,QAAO;AAC7C,QAAM,MAAM,KAAKA,MAAK;AACtB,MAAI,QAAQ,IAAI,GAAG,GAAG;AACpB,IAAAA,SAAQ,QAAQ,IAAI,GAAG;AACvB,YAAQ,OAAO,GAAG;AAAA,EACpB;AACA,SAAOA;AACT;AAEA,SAAS,MAAMA,QAAO;AACpB,SAAOA,WAAU,QAAQ,OAAOA,WAAU,WAAWA,OAAM,QAAQ,IAAIA;AACzE;;;AC5DA,IAAM,MAAM,KAAK,KAAK,EAAE;AAAxB,IACI,KAAK,KAAK,KAAK,EAAE;AADrB,IAEI,KAAK,KAAK,KAAK,CAAC;AAEpB,SAAS,SAAS,OAAO,MAAM,OAAO;AACpC,QAAM,QAAQ,OAAO,SAAS,KAAK,IAAI,GAAG,KAAK,GAC3C,QAAQ,KAAK,MAAM,KAAK,MAAM,IAAI,CAAC,GACnC,QAAQ,OAAO,KAAK,IAAI,IAAI,KAAK,GACjC,SAAS,SAAS,MAAM,KAAK,SAAS,KAAK,IAAI,SAAS,KAAK,IAAI;AACrE,MAAI,IAAI,IAAI;AACZ,MAAI,QAAQ,GAAG;AACb,UAAM,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI;AAC7B,SAAK,KAAK,MAAM,QAAQ,GAAG;AAC3B,SAAK,KAAK,MAAM,OAAO,GAAG;AAC1B,QAAI,KAAK,MAAM,MAAO,GAAE;AACxB,QAAI,KAAK,MAAM,KAAM,GAAE;AACvB,UAAM,CAAC;AAAA,EACT,OAAO;AACL,UAAM,KAAK,IAAI,IAAI,KAAK,IAAI;AAC5B,SAAK,KAAK,MAAM,QAAQ,GAAG;AAC3B,SAAK,KAAK,MAAM,OAAO,GAAG;AAC1B,QAAI,KAAK,MAAM,MAAO,GAAE;AACxB,QAAI,KAAK,MAAM,KAAM,GAAE;AAAA,EACzB;AACA,MAAI,KAAK,MAAM,OAAO,SAAS,QAAQ,EAAG,QAAO,SAAS,OAAO,MAAM,QAAQ,CAAC;AAChF,SAAO,CAAC,IAAI,IAAI,GAAG;AACrB;AAEe,SAAR,MAAuB,OAAO,MAAM,OAAO;AAChD,SAAO,CAAC,MAAM,QAAQ,CAAC,OAAO,QAAQ,CAAC;AACvC,MAAI,EAAE,QAAQ,GAAI,QAAO,CAAC;AAC1B,MAAI,UAAU,KAAM,QAAO,CAAC,KAAK;AACjC,QAAM,UAAU,OAAO,OAAO,CAAC,IAAI,IAAI,GAAG,IAAI,UAAU,SAAS,MAAM,OAAO,KAAK,IAAI,SAAS,OAAO,MAAM,KAAK;AAClH,MAAI,EAAE,MAAM,IAAK,QAAO,CAAC;AACzB,QAAM,IAAI,KAAK,KAAK,GAAGC,SAAQ,IAAI,MAAM,CAAC;AAC1C,MAAI,SAAS;AACX,QAAI,MAAM,EAAG,UAAS,IAAI,GAAG,IAAI,GAAG,EAAE,EAAG,CAAAA,OAAM,CAAC,KAAK,KAAK,KAAK,CAAC;AAAA,QAC3D,UAAS,IAAI,GAAG,IAAI,GAAG,EAAE,EAAG,CAAAA,OAAM,CAAC,KAAK,KAAK,KAAK;AAAA,EACzD,OAAO;AACL,QAAI,MAAM,EAAG,UAAS,IAAI,GAAG,IAAI,GAAG,EAAE,EAAG,CAAAA,OAAM,CAAC,KAAK,KAAK,KAAK,CAAC;AAAA,QAC3D,UAAS,IAAI,GAAG,IAAI,GAAG,EAAE,EAAG,CAAAA,OAAM,CAAC,KAAK,KAAK,KAAK;AAAA,EACzD;AACA,SAAOA;AACT;AAEO,SAAS,cAAc,OAAO,MAAM,OAAO;AAChD,SAAO,CAAC,MAAM,QAAQ,CAAC,OAAO,QAAQ,CAAC;AACvC,SAAO,SAAS,OAAO,MAAM,KAAK,EAAE,CAAC;AACvC;AAEO,SAAS,SAAS,OAAO,MAAM,OAAO;AAC3C,SAAO,CAAC,MAAM,QAAQ,CAAC,OAAO,QAAQ,CAAC;AACvC,QAAM,UAAU,OAAO,OAAO,MAAM,UAAU,cAAc,MAAM,OAAO,KAAK,IAAI,cAAc,OAAO,MAAM,KAAK;AAClH,UAAQ,UAAU,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,MAAM;AACpD;;;ACtDe,SAARC,KAAqB,QAAQ,SAAS;AAC3C,MAAIA;AACJ,MAAI,YAAY,QAAW;AACzB,eAAWC,UAAS,QAAQ;AAC1B,UAAIA,UAAS,SACLD,OAAMC,UAAUD,SAAQ,UAAaC,UAASA,SAAS;AAC7D,QAAAD,OAAMC;AAAA,MACR;AAAA,IACF;AAAA,EACF,OAAO;AACL,QAAI,QAAQ;AACZ,aAASA,UAAS,QAAQ;AACxB,WAAKA,SAAQ,QAAQA,QAAO,EAAE,OAAO,MAAM,MAAM,SACzCD,OAAMC,UAAUD,SAAQ,UAAaC,UAASA,SAAS;AAC7D,QAAAD,OAAMC;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAOD;AACT;;;ACnBe,SAARE,KAAqB,QAAQ,SAAS;AAC3C,MAAIA;AACJ,MAAI,YAAY,QAAW;AACzB,eAAWC,UAAS,QAAQ;AAC1B,UAAIA,UAAS,SACLD,OAAMC,UAAUD,SAAQ,UAAaC,UAASA,SAAS;AAC7D,QAAAD,OAAMC;AAAA,MACR;AAAA,IACF;AAAA,EACF,OAAO;AACL,QAAI,QAAQ;AACZ,aAASA,UAAS,QAAQ;AACxB,WAAKA,SAAQ,QAAQA,QAAO,EAAE,OAAO,MAAM,MAAM,SACzCD,OAAMC,UAAUD,SAAQ,UAAaC,UAASA,SAAS;AAC7D,QAAAD,OAAMC;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAOD;AACT;;;ACGO,SAAS,eAAe,QAAQ,GAAG,UAAU,QAAQ;AAC1D,MAAI,EAAE,IAAI,OAAO,WAAW,MAAM,IAAI,CAAC,CAAC,EAAG;AAC3C,MAAI,KAAK,KAAK,IAAI,EAAG,QAAO,CAAC,QAAQ,OAAO,CAAC,GAAG,GAAG,MAAM;AACzD,MAAI,KAAK,EAAG,QAAO,CAAC,QAAQ,OAAO,IAAI,CAAC,GAAG,IAAI,GAAG,MAAM;AACxD,MAAI,GACA,KAAK,IAAI,KAAK,GACd,KAAK,KAAK,MAAM,CAAC,GACjB,SAAS,CAAC,QAAQ,OAAO,EAAE,GAAG,IAAI,MAAM,GACxC,SAAS,CAAC,QAAQ,OAAO,KAAK,CAAC,GAAG,KAAK,GAAG,MAAM;AACpD,SAAO,UAAU,SAAS,WAAW,IAAI;AAC3C;;;AChCe,SAAR,MAAuB,OAAO,MAAM,MAAM;AAC/C,UAAQ,CAAC,OAAO,OAAO,CAAC,MAAM,QAAQ,IAAI,UAAU,UAAU,KAAK,OAAO,OAAO,QAAQ,GAAG,KAAK,IAAI,IAAI,IAAI,CAAC;AAE9G,MAAI,IAAI,IACJ,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,SAAS,IAAI,CAAC,IAAI,GACpDE,SAAQ,IAAI,MAAM,CAAC;AAEvB,SAAO,EAAE,IAAI,GAAG;AACd,IAAAA,OAAM,CAAC,IAAI,QAAQ,IAAI;AAAA,EACzB;AAEA,SAAOA;AACT;;;ACZO,SAAS,UAAU,QAAQC,QAAO;AACvC,UAAQ,UAAU,QAAQ;AAAA,IACxB,KAAK;AAAG;AAAA,IACR,KAAK;AAAG,WAAK,MAAM,MAAM;AAAG;AAAA,IAC5B;AAAS,WAAK,MAAMA,MAAK,EAAE,OAAO,MAAM;AAAG;AAAA,EAC7C;AACA,SAAO;AACT;AAEO,SAAS,iBAAiB,QAAQ,cAAc;AACrD,UAAQ,UAAU,QAAQ;AAAA,IACxB,KAAK;AAAG;AAAA,IACR,KAAK,GAAG;AACN,UAAI,OAAO,WAAW,WAAY,MAAK,aAAa,MAAM;AAAA,UACrD,MAAK,MAAM,MAAM;AACtB;AAAA,IACF;AAAA,IACA,SAAS;AACP,WAAK,OAAO,MAAM;AAClB,UAAI,OAAO,iBAAiB,WAAY,MAAK,aAAa,YAAY;AAAA,UACjE,MAAK,MAAM,YAAY;AAC5B;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACtBO,IAAM,WAAW,uBAAO,UAAU;AAE1B,SAAR,UAA2B;AAChC,MAAI,QAAQ,IAAI,UAAU,GACtB,SAAS,CAAC,GACVC,SAAQ,CAAC,GACT,UAAU;AAEd,WAAS,MAAM,GAAG;AAChB,QAAI,IAAI,MAAM,IAAI,CAAC;AACnB,QAAI,MAAM,QAAW;AACnB,UAAI,YAAY,SAAU,QAAO;AACjC,YAAM,IAAI,GAAG,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC;AAAA,IACrC;AACA,WAAOA,OAAM,IAAIA,OAAM,MAAM;AAAA,EAC/B;AAEA,QAAM,SAAS,SAAS,GAAG;AACzB,QAAI,CAAC,UAAU,OAAQ,QAAO,OAAO,MAAM;AAC3C,aAAS,CAAC,GAAG,QAAQ,IAAI,UAAU;AACnC,eAAWC,UAAS,GAAG;AACrB,UAAI,MAAM,IAAIA,MAAK,EAAG;AACtB,YAAM,IAAIA,QAAO,OAAO,KAAKA,MAAK,IAAI,CAAC;AAAA,IACzC;AACA,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,SAAS,GAAG;AACxB,WAAO,UAAU,UAAUD,SAAQ,MAAM,KAAK,CAAC,GAAG,SAASA,OAAM,MAAM;AAAA,EACzE;AAEA,QAAM,UAAU,SAAS,GAAG;AAC1B,WAAO,UAAU,UAAU,UAAU,GAAG,SAAS;AAAA,EACnD;AAEA,QAAM,OAAO,WAAW;AACtB,WAAO,QAAQ,QAAQA,MAAK,EAAE,QAAQ,OAAO;AAAA,EAC/C;AAEA,YAAU,MAAM,OAAO,SAAS;AAEhC,SAAO;AACT;;;ACzCe,SAAR,OAAwB;AAC7B,MAAI,QAAQ,QAAQ,EAAE,QAAQ,MAAS,GACnC,SAAS,MAAM,QACf,eAAe,MAAM,OACrB,KAAK,GACL,KAAK,GACL,MACA,WACA,QAAQ,OACR,eAAe,GACf,eAAe,GACf,QAAQ;AAEZ,SAAO,MAAM;AAEb,WAAS,UAAU;AACjB,QAAI,IAAI,OAAO,EAAE,QACb,UAAU,KAAK,IACf,QAAQ,UAAU,KAAK,IACvB,OAAO,UAAU,KAAK;AAC1B,YAAQ,OAAO,SAAS,KAAK,IAAI,GAAG,IAAI,eAAe,eAAe,CAAC;AACvE,QAAI,MAAO,QAAO,KAAK,MAAM,IAAI;AACjC,cAAU,OAAO,QAAQ,QAAQ,IAAI,iBAAiB;AACtD,gBAAY,QAAQ,IAAI;AACxB,QAAI,MAAO,SAAQ,KAAK,MAAM,KAAK,GAAG,YAAY,KAAK,MAAM,SAAS;AACtE,QAAI,SAAS,MAAS,CAAC,EAAE,IAAI,SAAS,GAAG;AAAE,aAAO,QAAQ,OAAO;AAAA,IAAG,CAAC;AACrE,WAAO,aAAa,UAAU,OAAO,QAAQ,IAAI,MAAM;AAAA,EACzD;AAEA,QAAM,SAAS,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,OAAO,CAAC,GAAG,QAAQ,KAAK,OAAO;AAAA,EAC5D;AAEA,QAAM,QAAQ,SAAS,GAAG;AACxB,WAAO,UAAU,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC,IAAI,EAAE;AAAA,EACnF;AAEA,QAAM,aAAa,SAAS,GAAG;AAC7B,WAAO,CAAC,IAAI,EAAE,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,QAAQ,MAAM,QAAQ;AAAA,EACjE;AAEA,QAAM,YAAY,WAAW;AAC3B,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,WAAW;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,SAAS,GAAG;AACxB,WAAO,UAAU,UAAU,QAAQ,CAAC,CAAC,GAAG,QAAQ,KAAK;AAAA,EACvD;AAEA,QAAM,UAAU,SAAS,GAAG;AAC1B,WAAO,UAAU,UAAU,eAAe,KAAK,IAAI,GAAG,eAAe,CAAC,CAAC,GAAG,QAAQ,KAAK;AAAA,EACzF;AAEA,QAAM,eAAe,SAAS,GAAG;AAC/B,WAAO,UAAU,UAAU,eAAe,KAAK,IAAI,GAAG,CAAC,GAAG,QAAQ,KAAK;AAAA,EACzE;AAEA,QAAM,eAAe,SAAS,GAAG;AAC/B,WAAO,UAAU,UAAU,eAAe,CAAC,GAAG,QAAQ,KAAK;AAAA,EAC7D;AAEA,QAAM,QAAQ,SAAS,GAAG;AACxB,WAAO,UAAU,UAAU,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,KAAK;AAAA,EAC/E;AAEA,QAAM,OAAO,WAAW;AACtB,WAAO,KAAK,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,EACzB,MAAM,KAAK,EACX,aAAa,YAAY,EACzB,aAAa,YAAY,EACzB,MAAM,KAAK;AAAA,EAClB;AAEA,SAAO,UAAU,MAAM,QAAQ,GAAG,SAAS;AAC7C;AAEA,SAAS,SAAS,OAAO;AACvB,MAAIE,QAAO,MAAM;AAEjB,QAAM,UAAU,MAAM;AACtB,SAAO,MAAM;AACb,SAAO,MAAM;AAEb,QAAM,OAAO,WAAW;AACtB,WAAO,SAASA,MAAK,CAAC;AAAA,EACxB;AAEA,SAAO;AACT;AAEO,SAASC,SAAQ;AACtB,SAAO,SAAS,KAAK,MAAM,MAAM,SAAS,EAAE,aAAa,CAAC,CAAC;AAC7D;;;ACpGe,SAAR,eAAiB,aAAa,SAAS,WAAW;AACvD,cAAY,YAAY,QAAQ,YAAY;AAC5C,YAAU,cAAc;AAC1B;AAEO,SAAS,OAAO,QAAQ,YAAY;AACzC,MAAI,YAAY,OAAO,OAAO,OAAO,SAAS;AAC9C,WAAS,OAAO,WAAY,WAAU,GAAG,IAAI,WAAW,GAAG;AAC3D,SAAO;AACT;;;ACPO,SAAS,QAAQ;AAAC;AAElB,IAAI,SAAS;AACb,IAAI,WAAW,IAAI;AAE1B,IAAI,MAAM;AAAV,IACI,MAAM;AADV,IAEI,MAAM;AAFV,IAGI,QAAQ;AAHZ,IAII,eAAe,IAAI,OAAO,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM;AAJ/D,IAKI,eAAe,IAAI,OAAO,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM;AAL/D,IAMI,gBAAgB,IAAI,OAAO,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM;AANxE,IAOI,gBAAgB,IAAI,OAAO,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM;AAPxE,IAQI,eAAe,IAAI,OAAO,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM;AAR/D,IASI,gBAAgB,IAAI,OAAO,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM;AAExE,IAAI,QAAQ;AAAA,EACV,WAAW;AAAA,EACX,cAAc;AAAA,EACd,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,WAAW;AAAA,EACX,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,SAAS;AAAA,EACT,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU;AAAA,EACV,eAAe;AAAA,EACf,UAAU;AAAA,EACV,WAAW;AAAA,EACX,UAAU;AAAA,EACV,WAAW;AAAA,EACX,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS;AAAA,EACT,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,aAAa;AAAA,EACb,aAAa;AAAA,EACb,SAAS;AAAA,EACT,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,WAAW;AAAA,EACX,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,EACT,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,OAAO;AAAA,EACP,UAAU;AAAA,EACV,eAAe;AAAA,EACf,WAAW;AAAA,EACX,cAAc;AAAA,EACd,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,sBAAsB;AAAA,EACtB,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,WAAW;AAAA,EACX,aAAa;AAAA,EACb,eAAe;AAAA,EACf,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,MAAM;AAAA,EACN,WAAW;AAAA,EACX,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU;AAAA,EACV,aAAa;AAAA,EACb,MAAM;AAAA,EACN,SAAS;AAAA,EACT,OAAO;AAAA,EACP,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,WAAW;AAAA,EACX,eAAe;AAAA,EACf,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,KAAK;AAAA,EACL,WAAW;AAAA,EACX,WAAW;AAAA,EACX,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,MAAM;AAAA,EACN,aAAa;AAAA,EACb,WAAW;AAAA,EACX,KAAK;AAAA,EACL,MAAM;AAAA,EACN,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,aAAa;AACf;AAEA,eAAO,OAAO,OAAO;AAAA,EACnB,KAAK,UAAU;AACb,WAAO,OAAO,OAAO,IAAI,KAAK,eAAa,MAAM,QAAQ;AAAA,EAC3D;AAAA,EACA,cAAc;AACZ,WAAO,KAAK,IAAI,EAAE,YAAY;AAAA,EAChC;AAAA,EACA,KAAK;AAAA;AAAA,EACL,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU;AACZ,CAAC;AAED,SAAS,kBAAkB;AACzB,SAAO,KAAK,IAAI,EAAE,UAAU;AAC9B;AAEA,SAAS,mBAAmB;AAC1B,SAAO,KAAK,IAAI,EAAE,WAAW;AAC/B;AAEA,SAAS,kBAAkB;AACzB,SAAO,WAAW,IAAI,EAAE,UAAU;AACpC;AAEA,SAAS,kBAAkB;AACzB,SAAO,KAAK,IAAI,EAAE,UAAU;AAC9B;AAEe,SAAR,MAAuBC,SAAQ;AACpC,MAAI,GAAG;AACP,EAAAA,WAAUA,UAAS,IAAI,KAAK,EAAE,YAAY;AAC1C,UAAQ,IAAI,MAAM,KAAKA,OAAM,MAAM,IAAI,EAAE,CAAC,EAAE,QAAQ,IAAI,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,IACtF,MAAM,IAAI,IAAI,IAAK,KAAK,IAAI,KAAQ,KAAK,IAAI,KAAQ,KAAK,IAAI,KAAQ,IAAI,MAAS,IAAI,OAAQ,IAAM,IAAI,IAAM,CAAC,IAChH,MAAM,IAAI,KAAK,KAAK,KAAK,KAAM,KAAK,KAAK,KAAM,KAAK,IAAI,MAAO,IAAI,OAAQ,GAAI,IAC/E,MAAM,IAAI,KAAM,KAAK,KAAK,KAAQ,KAAK,IAAI,KAAQ,KAAK,IAAI,KAAQ,KAAK,IAAI,KAAQ,KAAK,IAAI,KAAQ,IAAI,OAAU,IAAI,OAAQ,IAAM,IAAI,MAAQ,GAAI,IACtJ,SACC,IAAI,aAAa,KAAKA,OAAM,KAAK,IAAI,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAC5D,IAAI,aAAa,KAAKA,OAAM,KAAK,IAAI,IAAI,EAAE,CAAC,IAAI,MAAM,KAAK,EAAE,CAAC,IAAI,MAAM,KAAK,EAAE,CAAC,IAAI,MAAM,KAAK,CAAC,KAChG,IAAI,cAAc,KAAKA,OAAM,KAAK,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,KAC7D,IAAI,cAAc,KAAKA,OAAM,KAAK,KAAK,EAAE,CAAC,IAAI,MAAM,KAAK,EAAE,CAAC,IAAI,MAAM,KAAK,EAAE,CAAC,IAAI,MAAM,KAAK,EAAE,CAAC,CAAC,KACjG,IAAI,aAAa,KAAKA,OAAM,KAAK,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,KAAK,CAAC,KACrE,IAAI,cAAc,KAAKA,OAAM,KAAK,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,IAC1E,MAAM,eAAeA,OAAM,IAAI,KAAK,MAAMA,OAAM,CAAC,IACjDA,YAAW,gBAAgB,IAAI,IAAI,KAAK,KAAK,KAAK,CAAC,IACnD;AACR;AAEA,SAAS,KAAK,GAAG;AACf,SAAO,IAAI,IAAI,KAAK,KAAK,KAAM,KAAK,IAAI,KAAM,IAAI,KAAM,CAAC;AAC3D;AAEA,SAAS,KAAK,GAAG,GAAG,GAAG,GAAG;AACxB,MAAI,KAAK,EAAG,KAAI,IAAI,IAAI;AACxB,SAAO,IAAI,IAAI,GAAG,GAAG,GAAG,CAAC;AAC3B;AAEO,SAAS,WAAW,GAAG;AAC5B,MAAI,EAAE,aAAa,OAAQ,KAAI,MAAM,CAAC;AACtC,MAAI,CAAC,EAAG,QAAO,IAAI;AACnB,MAAI,EAAE,IAAI;AACV,SAAO,IAAI,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO;AACzC;AAEO,SAAS,IAAI,GAAG,GAAG,GAAG,SAAS;AACpC,SAAO,UAAU,WAAW,IAAI,WAAW,CAAC,IAAI,IAAI,IAAI,GAAG,GAAG,GAAG,WAAW,OAAO,IAAI,OAAO;AAChG;AAEO,SAAS,IAAI,GAAG,GAAG,GAAG,SAAS;AACpC,OAAK,IAAI,CAAC;AACV,OAAK,IAAI,CAAC;AACV,OAAK,IAAI,CAAC;AACV,OAAK,UAAU,CAAC;AAClB;AAEA,eAAO,KAAK,KAAK,OAAO,OAAO;AAAA,EAC7B,SAAS,GAAG;AACV,QAAI,KAAK,OAAO,WAAW,KAAK,IAAI,UAAU,CAAC;AAC/C,WAAO,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,OAAO;AAAA,EACjE;AAAA,EACA,OAAO,GAAG;AACR,QAAI,KAAK,OAAO,SAAS,KAAK,IAAI,QAAQ,CAAC;AAC3C,WAAO,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,OAAO;AAAA,EACjE;AAAA,EACA,MAAM;AACJ,WAAO;AAAA,EACT;AAAA,EACA,QAAQ;AACN,WAAO,IAAI,IAAI,OAAO,KAAK,CAAC,GAAG,OAAO,KAAK,CAAC,GAAG,OAAO,KAAK,CAAC,GAAG,OAAO,KAAK,OAAO,CAAC;AAAA,EACrF;AAAA,EACA,cAAc;AACZ,WAAQ,QAAQ,KAAK,KAAK,KAAK,IAAI,UAC3B,QAAQ,KAAK,KAAK,KAAK,IAAI,WAC3B,QAAQ,KAAK,KAAK,KAAK,IAAI,WAC3B,KAAK,KAAK,WAAW,KAAK,WAAW;AAAA,EAC/C;AAAA,EACA,KAAK;AAAA;AAAA,EACL,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,UAAU;AACZ,CAAC,CAAC;AAEF,SAAS,gBAAgB;AACvB,SAAO,IAAI,IAAI,KAAK,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC;AACpD;AAEA,SAAS,iBAAiB;AACxB,SAAO,IAAI,IAAI,KAAK,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC,GAAG,KAAK,MAAM,KAAK,OAAO,IAAI,IAAI,KAAK,WAAW,GAAG,CAAC;AAC1G;AAEA,SAAS,gBAAgB;AACvB,QAAM,IAAI,OAAO,KAAK,OAAO;AAC7B,SAAO,GAAG,MAAM,IAAI,SAAS,OAAO,GAAG,OAAO,KAAK,CAAC,CAAC,KAAK,OAAO,KAAK,CAAC,CAAC,KAAK,OAAO,KAAK,CAAC,CAAC,GAAG,MAAM,IAAI,MAAM,KAAK,CAAC,GAAG;AACzH;AAEA,SAAS,OAAO,SAAS;AACvB,SAAO,MAAM,OAAO,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC;AAC9D;AAEA,SAAS,OAAOC,QAAO;AACrB,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAMA,MAAK,KAAK,CAAC,CAAC;AAC1D;AAEA,SAAS,IAAIA,QAAO;AAClB,EAAAA,SAAQ,OAAOA,MAAK;AACpB,UAAQA,SAAQ,KAAK,MAAM,MAAMA,OAAM,SAAS,EAAE;AACpD;AAEA,SAAS,KAAK,GAAG,GAAG,GAAG,GAAG;AACxB,MAAI,KAAK,EAAG,KAAI,IAAI,IAAI;AAAA,WACf,KAAK,KAAK,KAAK,EAAG,KAAI,IAAI;AAAA,WAC1B,KAAK,EAAG,KAAI;AACrB,SAAO,IAAI,IAAI,GAAG,GAAG,GAAG,CAAC;AAC3B;AAEO,SAAS,WAAW,GAAG;AAC5B,MAAI,aAAa,IAAK,QAAO,IAAI,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO;AAC7D,MAAI,EAAE,aAAa,OAAQ,KAAI,MAAM,CAAC;AACtC,MAAI,CAAC,EAAG,QAAO,IAAI;AACnB,MAAI,aAAa,IAAK,QAAO;AAC7B,MAAI,EAAE,IAAI;AACV,MAAI,IAAI,EAAE,IAAI,KACV,IAAI,EAAE,IAAI,KACV,IAAI,EAAE,IAAI,KACVC,OAAM,KAAK,IAAI,GAAG,GAAG,CAAC,GACtBC,OAAM,KAAK,IAAI,GAAG,GAAG,CAAC,GACtB,IAAI,KACJ,IAAIA,OAAMD,MACV,KAAKC,OAAMD,QAAO;AACtB,MAAI,GAAG;AACL,QAAI,MAAMC,KAAK,MAAK,IAAI,KAAK,KAAK,IAAI,KAAK;AAAA,aAClC,MAAMA,KAAK,MAAK,IAAI,KAAK,IAAI;AAAA,QACjC,MAAK,IAAI,KAAK,IAAI;AACvB,SAAK,IAAI,MAAMA,OAAMD,OAAM,IAAIC,OAAMD;AACrC,SAAK;AAAA,EACP,OAAO;AACL,QAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AAAA,EAC3B;AACA,SAAO,IAAI,IAAI,GAAG,GAAG,GAAG,EAAE,OAAO;AACnC;AAEO,SAAS,IAAI,GAAG,GAAG,GAAG,SAAS;AACpC,SAAO,UAAU,WAAW,IAAI,WAAW,CAAC,IAAI,IAAI,IAAI,GAAG,GAAG,GAAG,WAAW,OAAO,IAAI,OAAO;AAChG;AAEA,SAAS,IAAI,GAAG,GAAG,GAAG,SAAS;AAC7B,OAAK,IAAI,CAAC;AACV,OAAK,IAAI,CAAC;AACV,OAAK,IAAI,CAAC;AACV,OAAK,UAAU,CAAC;AAClB;AAEA,eAAO,KAAK,KAAK,OAAO,OAAO;AAAA,EAC7B,SAAS,GAAG;AACV,QAAI,KAAK,OAAO,WAAW,KAAK,IAAI,UAAU,CAAC;AAC/C,WAAO,IAAI,IAAI,KAAK,GAAG,KAAK,GAAG,KAAK,IAAI,GAAG,KAAK,OAAO;AAAA,EACzD;AAAA,EACA,OAAO,GAAG;AACR,QAAI,KAAK,OAAO,SAAS,KAAK,IAAI,QAAQ,CAAC;AAC3C,WAAO,IAAI,IAAI,KAAK,GAAG,KAAK,GAAG,KAAK,IAAI,GAAG,KAAK,OAAO;AAAA,EACzD;AAAA,EACA,MAAM;AACJ,QAAI,IAAI,KAAK,IAAI,OAAO,KAAK,IAAI,KAAK,KAClC,IAAI,MAAM,CAAC,KAAK,MAAM,KAAK,CAAC,IAAI,IAAI,KAAK,GACzC,IAAI,KAAK,GACT,KAAK,KAAK,IAAI,MAAM,IAAI,IAAI,KAAK,GACjC,KAAK,IAAI,IAAI;AACjB,WAAO,IAAI;AAAA,MACT,QAAQ,KAAK,MAAM,IAAI,MAAM,IAAI,KAAK,IAAI,EAAE;AAAA,MAC5C,QAAQ,GAAG,IAAI,EAAE;AAAA,MACjB,QAAQ,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,IAAI,EAAE;AAAA,MAC3C,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EACA,QAAQ;AACN,WAAO,IAAI,IAAI,OAAO,KAAK,CAAC,GAAG,OAAO,KAAK,CAAC,GAAG,OAAO,KAAK,CAAC,GAAG,OAAO,KAAK,OAAO,CAAC;AAAA,EACrF;AAAA,EACA,cAAc;AACZ,YAAQ,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MAAM,KAAK,CAAC,OAC1C,KAAK,KAAK,KAAK,KAAK,KAAK,OACzB,KAAK,KAAK,WAAW,KAAK,WAAW;AAAA,EAC/C;AAAA,EACA,YAAY;AACV,UAAM,IAAI,OAAO,KAAK,OAAO;AAC7B,WAAO,GAAG,MAAM,IAAI,SAAS,OAAO,GAAG,OAAO,KAAK,CAAC,CAAC,KAAK,OAAO,KAAK,CAAC,IAAI,GAAG,MAAM,OAAO,KAAK,CAAC,IAAI,GAAG,IAAI,MAAM,IAAI,MAAM,KAAK,CAAC,GAAG;AAAA,EACvI;AACF,CAAC,CAAC;AAEF,SAAS,OAAOD,QAAO;AACrB,EAAAA,UAASA,UAAS,KAAK;AACvB,SAAOA,SAAQ,IAAIA,SAAQ,MAAMA;AACnC;AAEA,SAAS,OAAOA,QAAO;AACrB,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGA,UAAS,CAAC,CAAC;AAC5C;AAGA,SAAS,QAAQ,GAAG,IAAI,IAAI;AAC1B,UAAQ,IAAI,KAAK,MAAM,KAAK,MAAM,IAAI,KAChC,IAAI,MAAM,KACV,IAAI,MAAM,MAAM,KAAK,OAAO,MAAM,KAAK,KACvC,MAAM;AACd;;;AC3YO,SAAS,MAAMG,KAAI,IAAI,IAAI,IAAI,IAAI;AACxC,MAAI,KAAKA,MAAKA,KAAI,KAAK,KAAKA;AAC5B,WAAS,IAAI,IAAIA,MAAK,IAAI,KAAK,MAAM,MAC9B,IAAI,IAAI,KAAK,IAAI,MAAM,MACvB,IAAI,IAAIA,MAAK,IAAI,KAAK,IAAI,MAAM,KACjC,KAAK,MAAM;AACnB;AAEe,SAARC,eAAiB,QAAQ;AAC9B,MAAI,IAAI,OAAO,SAAS;AACxB,SAAO,SAAS,GAAG;AACjB,QAAI,IAAI,KAAK,IAAK,IAAI,IAAK,KAAK,KAAK,IAAI,GAAG,IAAI,KAAK,KAAK,MAAM,IAAI,CAAC,GACjE,KAAK,OAAO,CAAC,GACb,KAAK,OAAO,IAAI,CAAC,GACjB,KAAK,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,IAAI,KAAK,IACtC,KAAK,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,IAAI,KAAK;AAC9C,WAAO,OAAO,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,IAAI,EAAE;AAAA,EAC9C;AACF;;;AChBe,SAAR,oBAAiB,QAAQ;AAC9B,MAAI,IAAI,OAAO;AACf,SAAO,SAAS,GAAG;AACjB,QAAI,IAAI,KAAK,QAAQ,KAAK,KAAK,IAAI,EAAE,IAAI,KAAK,CAAC,GAC3C,KAAK,QAAQ,IAAI,IAAI,KAAK,CAAC,GAC3B,KAAK,OAAO,IAAI,CAAC,GACjB,KAAK,QAAQ,IAAI,KAAK,CAAC,GACvB,KAAK,QAAQ,IAAI,KAAK,CAAC;AAC3B,WAAO,OAAO,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,IAAI,EAAE;AAAA,EAC9C;AACF;;;ACZA,IAAOC,oBAAQ,CAAAC,OAAK,MAAMA;;;ACE1B,SAAS,OAAO,GAAG,GAAG;AACpB,SAAO,SAAS,GAAG;AACjB,WAAO,IAAI,IAAI;AAAA,EACjB;AACF;AAEA,SAAS,YAAY,GAAG,GAAGC,IAAG;AAC5B,SAAO,IAAI,KAAK,IAAI,GAAGA,EAAC,GAAG,IAAI,KAAK,IAAI,GAAGA,EAAC,IAAI,GAAGA,KAAI,IAAIA,IAAG,SAAS,GAAG;AACxE,WAAO,KAAK,IAAI,IAAI,IAAI,GAAGA,EAAC;AAAA,EAC9B;AACF;AAOO,SAAS,MAAMC,IAAG;AACvB,UAAQA,KAAI,CAACA,QAAO,IAAI,UAAU,SAAS,GAAG,GAAG;AAC/C,WAAO,IAAI,IAAI,YAAY,GAAG,GAAGA,EAAC,IAAIC,kBAAS,MAAM,CAAC,IAAI,IAAI,CAAC;AAAA,EACjE;AACF;AAEe,SAAR,QAAyB,GAAG,GAAG;AACpC,MAAI,IAAI,IAAI;AACZ,SAAO,IAAI,OAAO,GAAG,CAAC,IAAIA,kBAAS,MAAM,CAAC,IAAI,IAAI,CAAC;AACrD;;;ACvBA,IAAO,eAAS,SAAS,SAASC,IAAG;AACnC,MAAIC,SAAQ,MAAMD,EAAC;AAEnB,WAASE,KAAI,OAAO,KAAK;AACvB,QAAI,IAAID,QAAO,QAAQ,IAAS,KAAK,GAAG,IAAI,MAAM,IAAS,GAAG,GAAG,CAAC,GAC9D,IAAIA,OAAM,MAAM,GAAG,IAAI,CAAC,GACxB,IAAIA,OAAM,MAAM,GAAG,IAAI,CAAC,GACxB,UAAU,QAAQ,MAAM,SAAS,IAAI,OAAO;AAChD,WAAO,SAAS,GAAG;AACjB,YAAM,IAAI,EAAE,CAAC;AACb,YAAM,IAAI,EAAE,CAAC;AACb,YAAM,IAAI,EAAE,CAAC;AACb,YAAM,UAAU,QAAQ,CAAC;AACzB,aAAO,QAAQ;AAAA,IACjB;AAAA,EACF;AAEA,EAAAC,KAAI,QAAQ;AAEZ,SAAOA;AACT,GAAG,CAAC;AAEJ,SAAS,UAAU,QAAQ;AACzB,SAAO,SAAS,QAAQ;AACtB,QAAI,IAAI,OAAO,QACX,IAAI,IAAI,MAAM,CAAC,GACf,IAAI,IAAI,MAAM,CAAC,GACf,IAAI,IAAI,MAAM,CAAC,GACf,GAAGD;AACP,SAAK,IAAI,GAAG,IAAI,GAAG,EAAE,GAAG;AACtB,MAAAA,SAAQ,IAAS,OAAO,CAAC,CAAC;AAC1B,QAAE,CAAC,IAAIA,OAAM,KAAK;AAClB,QAAE,CAAC,IAAIA,OAAM,KAAK;AAClB,QAAE,CAAC,IAAIA,OAAM,KAAK;AAAA,IACpB;AACA,QAAI,OAAO,CAAC;AACZ,QAAI,OAAO,CAAC;AACZ,QAAI,OAAO,CAAC;AACZ,IAAAA,OAAM,UAAU;AAChB,WAAO,SAAS,GAAG;AACjB,MAAAA,OAAM,IAAI,EAAE,CAAC;AACb,MAAAA,OAAM,IAAI,EAAE,CAAC;AACb,MAAAA,OAAM,IAAI,EAAE,CAAC;AACb,aAAOA,SAAQ;AAAA,IACjB;AAAA,EACF;AACF;AAEO,IAAI,WAAW,UAAUE,cAAK;AAC9B,IAAI,iBAAiB,UAAU,mBAAW;;;ACtDlC,SAAR,oBAAiB,GAAG,GAAG;AAC5B,MAAI,CAAC,EAAG,KAAI,CAAC;AACb,MAAI,IAAI,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM,IAAI,GACvC,IAAI,EAAE,MAAM,GACZ;AACJ,SAAO,SAAS,GAAG;AACjB,SAAK,IAAI,GAAG,IAAI,GAAG,EAAE,EAAG,GAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC,IAAI;AACvD,WAAO;AAAA,EACT;AACF;AAEO,SAAS,cAAcC,IAAG;AAC/B,SAAO,YAAY,OAAOA,EAAC,KAAK,EAAEA,cAAa;AACjD;;;ACNO,SAAS,aAAa,GAAG,GAAG;AACjC,MAAI,KAAK,IAAI,EAAE,SAAS,GACpB,KAAK,IAAI,KAAK,IAAI,IAAI,EAAE,MAAM,IAAI,GAClCC,KAAI,IAAI,MAAM,EAAE,GAChB,IAAI,IAAI,MAAM,EAAE,GAChB;AAEJ,OAAK,IAAI,GAAG,IAAI,IAAI,EAAE,EAAG,CAAAA,GAAE,CAAC,IAAI,cAAM,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AAChD,SAAO,IAAI,IAAI,EAAE,EAAG,GAAE,CAAC,IAAI,EAAE,CAAC;AAE9B,SAAO,SAAS,GAAG;AACjB,SAAK,IAAI,GAAG,IAAI,IAAI,EAAE,EAAG,GAAE,CAAC,IAAIA,GAAE,CAAC,EAAE,CAAC;AACtC,WAAO;AAAA,EACT;AACF;;;ACrBe,SAAR,aAAiB,GAAG,GAAG;AAC5B,MAAI,IAAI,oBAAI;AACZ,SAAO,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,SAAS,GAAG;AACjC,WAAO,EAAE,QAAQ,KAAK,IAAI,KAAK,IAAI,CAAC,GAAG;AAAA,EACzC;AACF;;;ACLe,SAAR,eAAiB,GAAG,GAAG;AAC5B,SAAO,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,SAAS,GAAG;AACjC,WAAO,KAAK,IAAI,KAAK,IAAI;AAAA,EAC3B;AACF;;;ACFe,SAAR,eAAiB,GAAG,GAAG;AAC5B,MAAI,IAAI,CAAC,GACL,IAAI,CAAC,GACL;AAEJ,MAAI,MAAM,QAAQ,OAAO,MAAM,SAAU,KAAI,CAAC;AAC9C,MAAI,MAAM,QAAQ,OAAO,MAAM,SAAU,KAAI,CAAC;AAE9C,OAAK,KAAK,GAAG;AACX,QAAI,KAAK,GAAG;AACV,QAAE,CAAC,IAAI,cAAM,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AAAA,IACzB,OAAO;AACL,QAAE,CAAC,IAAI,EAAE,CAAC;AAAA,IACZ;AAAA,EACF;AAEA,SAAO,SAAS,GAAG;AACjB,SAAK,KAAK,EAAG,GAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;AAC1B,WAAO;AAAA,EACT;AACF;;;ACpBA,IAAI,MAAM;AAAV,IACI,MAAM,IAAI,OAAO,IAAI,QAAQ,GAAG;AAEpC,SAASC,MAAK,GAAG;AACf,SAAO,WAAW;AAChB,WAAO;AAAA,EACT;AACF;AAEA,SAAS,IAAI,GAAG;AACd,SAAO,SAAS,GAAG;AACjB,WAAO,EAAE,CAAC,IAAI;AAAA,EAChB;AACF;AAEe,SAAR,eAAiB,GAAG,GAAG;AAC5B,MAAI,KAAK,IAAI,YAAY,IAAI,YAAY,GACrC,IACA,IACA,IACA,IAAI,IACJ,IAAI,CAAC,GACL,IAAI,CAAC;AAGT,MAAI,IAAI,IAAI,IAAI,IAAI;AAGpB,UAAQ,KAAK,IAAI,KAAK,CAAC,OACf,KAAK,IAAI,KAAK,CAAC,IAAI;AACzB,SAAK,KAAK,GAAG,SAAS,IAAI;AACxB,WAAK,EAAE,MAAM,IAAI,EAAE;AACnB,UAAI,EAAE,CAAC,EAAG,GAAE,CAAC,KAAK;AAAA,UACb,GAAE,EAAE,CAAC,IAAI;AAAA,IAChB;AACA,SAAK,KAAK,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,IAAI;AACjC,UAAI,EAAE,CAAC,EAAG,GAAE,CAAC,KAAK;AAAA,UACb,GAAE,EAAE,CAAC,IAAI;AAAA,IAChB,OAAO;AACL,QAAE,EAAE,CAAC,IAAI;AACT,QAAE,KAAK,EAAC,GAAM,GAAG,eAAO,IAAI,EAAE,EAAC,CAAC;AAAA,IAClC;AACA,SAAK,IAAI;AAAA,EACX;AAGA,MAAI,KAAK,EAAE,QAAQ;AACjB,SAAK,EAAE,MAAM,EAAE;AACf,QAAI,EAAE,CAAC,EAAG,GAAE,CAAC,KAAK;AAAA,QACb,GAAE,EAAE,CAAC,IAAI;AAAA,EAChB;AAIA,SAAO,EAAE,SAAS,IAAK,EAAE,CAAC,IACpB,IAAI,EAAE,CAAC,EAAE,CAAC,IACVA,MAAK,CAAC,KACL,IAAI,EAAE,QAAQ,SAAS,GAAG;AACzB,aAASC,KAAI,GAAG,GAAGA,KAAI,GAAG,EAAEA,GAAG,IAAG,IAAI,EAAEA,EAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;AACtD,WAAO,EAAE,KAAK,EAAE;AAAA,EAClB;AACR;;;ACrDe,SAAR,cAAiB,GAAG,GAAG;AAC5B,MAAI,IAAI,OAAO,GAAG;AAClB,SAAO,KAAK,QAAQ,MAAM,YAAYC,kBAAS,CAAC,KACzC,MAAM,WAAW,iBAClB,MAAM,YAAa,IAAI,MAAM,CAAC,MAAM,IAAI,GAAG,eAAO,iBAClD,aAAa,QAAQ,cACrB,aAAa,OAAO,eACpB,cAAc,CAAC,IAAI,sBACnB,MAAM,QAAQ,CAAC,IAAI,eACnB,OAAO,EAAE,YAAY,cAAc,OAAO,EAAE,aAAa,cAAc,MAAM,CAAC,IAAI,iBAClF,gBAAQ,GAAG,CAAC;AACpB;;;ACrBe,SAAR,cAAiB,GAAG,GAAG;AAC5B,SAAO,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,SAAS,GAAG;AACjC,WAAO,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;AAAA,EACvC;AACF;;;ACJe,SAAR,UAA2BC,IAAG;AACnC,SAAO,WAAW;AAChB,WAAOA;AAAA,EACT;AACF;;;ACJe,SAARC,QAAwBC,IAAG;AAChC,SAAO,CAACA;AACV;;;ACGA,IAAI,OAAO,CAAC,GAAG,CAAC;AAET,SAAS,SAASC,IAAG;AAC1B,SAAOA;AACT;AAEA,SAAS,UAAU,GAAG,GAAG;AACvB,UAAQ,KAAM,IAAI,CAAC,KACb,SAASA,IAAG;AAAE,YAAQA,KAAI,KAAK;AAAA,EAAG,IAClC,UAAS,MAAM,CAAC,IAAI,MAAM,GAAG;AACrC;AAEA,SAAS,QAAQ,GAAG,GAAG;AACrB,MAAI;AACJ,MAAI,IAAI,EAAG,KAAI,GAAG,IAAI,GAAG,IAAI;AAC7B,SAAO,SAASA,IAAG;AAAE,WAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGA,EAAC,CAAC;AAAA,EAAG;AAC3D;AAIA,SAAS,MAAM,QAAQC,QAAO,aAAa;AACzC,MAAI,KAAK,OAAO,CAAC,GAAG,KAAK,OAAO,CAAC,GAAG,KAAKA,OAAM,CAAC,GAAG,KAAKA,OAAM,CAAC;AAC/D,MAAI,KAAK,GAAI,MAAK,UAAU,IAAI,EAAE,GAAG,KAAK,YAAY,IAAI,EAAE;AAAA,MACvD,MAAK,UAAU,IAAI,EAAE,GAAG,KAAK,YAAY,IAAI,EAAE;AACpD,SAAO,SAASD,IAAG;AAAE,WAAO,GAAG,GAAGA,EAAC,CAAC;AAAA,EAAG;AACzC;AAEA,SAAS,QAAQ,QAAQC,QAAO,aAAa;AAC3C,MAAI,IAAI,KAAK,IAAI,OAAO,QAAQA,OAAM,MAAM,IAAI,GAC5C,IAAI,IAAI,MAAM,CAAC,GACf,IAAI,IAAI,MAAM,CAAC,GACf,IAAI;AAGR,MAAI,OAAO,CAAC,IAAI,OAAO,CAAC,GAAG;AACzB,aAAS,OAAO,MAAM,EAAE,QAAQ;AAChC,IAAAA,SAAQA,OAAM,MAAM,EAAE,QAAQ;AAAA,EAChC;AAEA,SAAO,EAAE,IAAI,GAAG;AACd,MAAE,CAAC,IAAI,UAAU,OAAO,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;AACzC,MAAE,CAAC,IAAI,YAAYA,OAAM,CAAC,GAAGA,OAAM,IAAI,CAAC,CAAC;AAAA,EAC3C;AAEA,SAAO,SAASD,IAAG;AACjB,QAAIE,KAAI,eAAO,QAAQF,IAAG,GAAG,CAAC,IAAI;AAClC,WAAO,EAAEE,EAAC,EAAE,EAAEA,EAAC,EAAEF,EAAC,CAAC;AAAA,EACrB;AACF;AAEO,SAAS,KAAK,QAAQ,QAAQ;AACnC,SAAO,OACF,OAAO,OAAO,OAAO,CAAC,EACtB,MAAM,OAAO,MAAM,CAAC,EACpB,YAAY,OAAO,YAAY,CAAC,EAChC,MAAM,OAAO,MAAM,CAAC,EACpB,QAAQ,OAAO,QAAQ,CAAC;AAC/B;AAEO,SAAS,cAAc;AAC5B,MAAI,SAAS,MACTC,SAAQ,MACR,cAAc,eACd,WACA,aACA,SACA,QAAQ,UACR,WACA,QACA;AAEJ,WAAS,UAAU;AACjB,QAAI,IAAI,KAAK,IAAI,OAAO,QAAQA,OAAM,MAAM;AAC5C,QAAI,UAAU,SAAU,SAAQ,QAAQ,OAAO,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;AAChE,gBAAY,IAAI,IAAI,UAAU;AAC9B,aAAS,QAAQ;AACjB,WAAO;AAAA,EACT;AAEA,WAAS,MAAMD,IAAG;AAChB,WAAOA,MAAK,QAAQ,MAAMA,KAAI,CAACA,EAAC,IAAI,WAAW,WAAW,SAAS,UAAU,OAAO,IAAI,SAAS,GAAGC,QAAO,WAAW,IAAI,UAAU,MAAMD,EAAC,CAAC,CAAC;AAAA,EAC/I;AAEA,QAAM,SAAS,SAASG,IAAG;AACzB,WAAO,MAAM,aAAa,UAAU,QAAQ,UAAUF,QAAO,OAAO,IAAI,SAAS,GAAG,cAAiB,IAAIE,EAAC,CAAC,CAAC;AAAA,EAC9G;AAEA,QAAM,SAAS,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,SAAS,MAAM,KAAK,GAAGC,OAAM,GAAG,QAAQ,KAAK,OAAO,MAAM;AAAA,EACvF;AAEA,QAAM,QAAQ,SAAS,GAAG;AACxB,WAAO,UAAU,UAAUH,SAAQ,MAAM,KAAK,CAAC,GAAG,QAAQ,KAAKA,OAAM,MAAM;AAAA,EAC7E;AAEA,QAAM,aAAa,SAAS,GAAG;AAC7B,WAAOA,SAAQ,MAAM,KAAK,CAAC,GAAG,cAAc,eAAkB,QAAQ;AAAA,EACxE;AAEA,QAAM,QAAQ,SAAS,GAAG;AACxB,WAAO,UAAU,UAAU,QAAQ,IAAI,OAAO,UAAU,QAAQ,KAAK,UAAU;AAAA,EACjF;AAEA,QAAM,cAAc,SAAS,GAAG;AAC9B,WAAO,UAAU,UAAU,cAAc,GAAG,QAAQ,KAAK;AAAA,EAC3D;AAEA,QAAM,UAAU,SAAS,GAAG;AAC1B,WAAO,UAAU,UAAU,UAAU,GAAG,SAAS;AAAA,EACnD;AAEA,SAAO,SAAS,GAAG,GAAG;AACpB,gBAAY,GAAG,cAAc;AAC7B,WAAO,QAAQ;AAAA,EACjB;AACF;AAEe,SAAR,aAA8B;AACnC,SAAO,YAAY,EAAE,UAAU,QAAQ;AACzC;;;AC5He,SAAR,sBAAiBI,IAAG;AACzB,SAAO,KAAK,IAAIA,KAAI,KAAK,MAAMA,EAAC,CAAC,KAAK,OAChCA,GAAE,eAAe,IAAI,EAAE,QAAQ,MAAM,EAAE,IACvCA,GAAE,SAAS,EAAE;AACrB;AAKO,SAAS,mBAAmBA,IAAG,GAAG;AACvC,MAAI,CAAC,SAASA,EAAC,KAAKA,OAAM,EAAG,QAAO;AACpC,MAAI,KAAKA,KAAI,IAAIA,GAAE,cAAc,IAAI,CAAC,IAAIA,GAAE,cAAc,GAAG,QAAQ,GAAG,GAAG,cAAcA,GAAE,MAAM,GAAG,CAAC;AAIrG,SAAO;AAAA,IACL,YAAY,SAAS,IAAI,YAAY,CAAC,IAAI,YAAY,MAAM,CAAC,IAAI;AAAA,IACjE,CAACA,GAAE,MAAM,IAAI,CAAC;AAAA,EAChB;AACF;;;ACjBe,SAAR,iBAAiBC,IAAG;AACzB,SAAOA,KAAI,mBAAmB,KAAK,IAAIA,EAAC,CAAC,GAAGA,KAAIA,GAAE,CAAC,IAAI;AACzD;;;ACJe,SAAR,oBAAiB,UAAU,WAAW;AAC3C,SAAO,SAASC,QAAO,OAAO;AAC5B,QAAI,IAAIA,OAAM,QACV,IAAI,CAAC,GACL,IAAI,GACJ,IAAI,SAAS,CAAC,GACd,SAAS;AAEb,WAAO,IAAI,KAAK,IAAI,GAAG;AACrB,UAAI,SAAS,IAAI,IAAI,MAAO,KAAI,KAAK,IAAI,GAAG,QAAQ,MAAM;AAC1D,QAAE,KAAKA,OAAM,UAAU,KAAK,GAAG,IAAI,CAAC,CAAC;AACrC,WAAK,UAAU,IAAI,KAAK,MAAO;AAC/B,UAAI,SAAS,KAAK,IAAI,KAAK,SAAS,MAAM;AAAA,IAC5C;AAEA,WAAO,EAAE,QAAQ,EAAE,KAAK,SAAS;AAAA,EACnC;AACF;;;ACjBe,SAAR,uBAAiB,UAAU;AAChC,SAAO,SAASC,QAAO;AACrB,WAAOA,OAAM,QAAQ,UAAU,SAAS,GAAG;AACzC,aAAO,SAAS,CAAC,CAAC;AAAA,IACpB,CAAC;AAAA,EACH;AACF;;;ACLA,IAAI,KAAK;AAEM,SAAR,gBAAiC,WAAW;AACjD,MAAI,EAAE,QAAQ,GAAG,KAAK,SAAS,GAAI,OAAM,IAAI,MAAM,qBAAqB,SAAS;AACjF,MAAI;AACJ,SAAO,IAAI,gBAAgB;AAAA,IACzB,MAAM,MAAM,CAAC;AAAA,IACb,OAAO,MAAM,CAAC;AAAA,IACd,MAAM,MAAM,CAAC;AAAA,IACb,QAAQ,MAAM,CAAC;AAAA,IACf,MAAM,MAAM,CAAC;AAAA,IACb,OAAO,MAAM,CAAC;AAAA,IACd,OAAO,MAAM,CAAC;AAAA,IACd,WAAW,MAAM,CAAC,KAAK,MAAM,CAAC,EAAE,MAAM,CAAC;AAAA,IACvC,MAAM,MAAM,CAAC;AAAA,IACb,MAAM,MAAM,EAAE;AAAA,EAChB,CAAC;AACH;AAEA,gBAAgB,YAAY,gBAAgB;AAErC,SAAS,gBAAgB,WAAW;AACzC,OAAK,OAAO,UAAU,SAAS,SAAY,MAAM,UAAU,OAAO;AAClE,OAAK,QAAQ,UAAU,UAAU,SAAY,MAAM,UAAU,QAAQ;AACrE,OAAK,OAAO,UAAU,SAAS,SAAY,MAAM,UAAU,OAAO;AAClE,OAAK,SAAS,UAAU,WAAW,SAAY,KAAK,UAAU,SAAS;AACvE,OAAK,OAAO,CAAC,CAAC,UAAU;AACxB,OAAK,QAAQ,UAAU,UAAU,SAAY,SAAY,CAAC,UAAU;AACpE,OAAK,QAAQ,CAAC,CAAC,UAAU;AACzB,OAAK,YAAY,UAAU,cAAc,SAAY,SAAY,CAAC,UAAU;AAC5E,OAAK,OAAO,CAAC,CAAC,UAAU;AACxB,OAAK,OAAO,UAAU,SAAS,SAAY,KAAK,UAAU,OAAO;AACnE;AAEA,gBAAgB,UAAU,WAAW,WAAW;AAC9C,SAAO,KAAK,OACN,KAAK,QACL,KAAK,OACL,KAAK,UACJ,KAAK,OAAO,MAAM,OAClB,KAAK,UAAU,SAAY,KAAK,KAAK,IAAI,GAAG,KAAK,QAAQ,CAAC,MAC1D,KAAK,QAAQ,MAAM,OACnB,KAAK,cAAc,SAAY,KAAK,MAAM,KAAK,IAAI,GAAG,KAAK,YAAY,CAAC,MACxE,KAAK,OAAO,MAAM,MACnB,KAAK;AACb;;;AC7Ce,SAAR,mBAAiB,GAAG;AACzB,MAAK,UAAS,IAAI,EAAE,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,IAAI,GAAG,EAAE,GAAG;AAC1D,YAAQ,EAAE,CAAC,GAAG;AAAA,MACZ,KAAK;AAAK,aAAK,KAAK;AAAG;AAAA,MACvB,KAAK;AAAK,YAAI,OAAO,EAAG,MAAK;AAAG,aAAK;AAAG;AAAA,MACxC;AAAS,YAAI,CAAC,CAAC,EAAE,CAAC,EAAG,OAAM;AAAK,YAAI,KAAK,EAAG,MAAK;AAAG;AAAA,IACtD;AAAA,EACF;AACA,SAAO,KAAK,IAAI,EAAE,MAAM,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC,IAAI;AACrD;;;ACRO,IAAI;AAEI,SAAR,yBAAiBC,IAAG,GAAG;AAC5B,MAAI,IAAI,mBAAmBA,IAAG,CAAC;AAC/B,MAAI,CAAC,EAAG,QAAO,iBAAiB,QAAWA,GAAE,YAAY,CAAC;AAC1D,MAAI,cAAc,EAAE,CAAC,GACjB,WAAW,EAAE,CAAC,GACd,IAAI,YAAY,iBAAiB,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,WAAW,CAAC,CAAC,CAAC,IAAI,KAAK,GAC5F,IAAI,YAAY;AACpB,SAAO,MAAM,IAAI,cACX,IAAI,IAAI,cAAc,IAAI,MAAM,IAAI,IAAI,CAAC,EAAE,KAAK,GAAG,IACnD,IAAI,IAAI,YAAY,MAAM,GAAG,CAAC,IAAI,MAAM,YAAY,MAAM,CAAC,IAC3D,OAAO,IAAI,MAAM,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,mBAAmBA,IAAG,KAAK,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC;AAC3F;;;ACbe,SAAR,sBAAiBC,IAAG,GAAG;AAC5B,MAAI,IAAI,mBAAmBA,IAAG,CAAC;AAC/B,MAAI,CAAC,EAAG,QAAOA,KAAI;AACnB,MAAI,cAAc,EAAE,CAAC,GACjB,WAAW,EAAE,CAAC;AAClB,SAAO,WAAW,IAAI,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,KAAK,GAAG,IAAI,cACxD,YAAY,SAAS,WAAW,IAAI,YAAY,MAAM,GAAG,WAAW,CAAC,IAAI,MAAM,YAAY,MAAM,WAAW,CAAC,IAC7G,cAAc,IAAI,MAAM,WAAW,YAAY,SAAS,CAAC,EAAE,KAAK,GAAG;AAC3E;;;ACNA,IAAO,sBAAQ;AAAA,EACb,KAAK,CAACC,IAAG,OAAOA,KAAI,KAAK,QAAQ,CAAC;AAAA,EAClC,KAAK,CAACA,OAAM,KAAK,MAAMA,EAAC,EAAE,SAAS,CAAC;AAAA,EACpC,KAAK,CAACA,OAAMA,KAAI;AAAA,EAChB,KAAK;AAAA,EACL,KAAK,CAACA,IAAG,MAAMA,GAAE,cAAc,CAAC;AAAA,EAChC,KAAK,CAACA,IAAG,MAAMA,GAAE,QAAQ,CAAC;AAAA,EAC1B,KAAK,CAACA,IAAG,MAAMA,GAAE,YAAY,CAAC;AAAA,EAC9B,KAAK,CAACA,OAAM,KAAK,MAAMA,EAAC,EAAE,SAAS,CAAC;AAAA,EACpC,KAAK,CAACA,IAAG,MAAM,sBAAcA,KAAI,KAAK,CAAC;AAAA,EACvC,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK,CAACA,OAAM,KAAK,MAAMA,EAAC,EAAE,SAAS,EAAE,EAAE,YAAY;AAAA,EACnD,KAAK,CAACA,OAAM,KAAK,MAAMA,EAAC,EAAE,SAAS,EAAE;AACvC;;;AClBe,SAARC,kBAAiBC,IAAG;AACzB,SAAOA;AACT;;;ACOA,IAAI,MAAM,MAAM,UAAU;AAA1B,IACI,WAAW,CAAC,KAAI,KAAI,KAAI,KAAI,KAAI,KAAI,QAAI,KAAI,IAAG,KAAI,KAAI,KAAI,KAAI,KAAI,KAAI,KAAI,GAAG;AAEnE,SAAR,eAAiBC,SAAQ;AAC9B,MAAI,QAAQA,QAAO,aAAa,UAAaA,QAAO,cAAc,SAAYC,oBAAW,oBAAY,IAAI,KAAKD,QAAO,UAAU,MAAM,GAAGA,QAAO,YAAY,EAAE,GACzJ,iBAAiBA,QAAO,aAAa,SAAY,KAAKA,QAAO,SAAS,CAAC,IAAI,IAC3E,iBAAiBA,QAAO,aAAa,SAAY,KAAKA,QAAO,SAAS,CAAC,IAAI,IAC3E,UAAUA,QAAO,YAAY,SAAY,MAAMA,QAAO,UAAU,IAChE,WAAWA,QAAO,aAAa,SAAYC,oBAAW,uBAAe,IAAI,KAAKD,QAAO,UAAU,MAAM,CAAC,GACtG,UAAUA,QAAO,YAAY,SAAY,MAAMA,QAAO,UAAU,IAChE,QAAQA,QAAO,UAAU,SAAY,WAAMA,QAAO,QAAQ,IAC1D,MAAMA,QAAO,QAAQ,SAAY,QAAQA,QAAO,MAAM;AAE1D,WAAS,UAAU,WAAW,SAAS;AACrC,gBAAY,gBAAgB,SAAS;AAErC,QAAI,OAAO,UAAU,MACjB,QAAQ,UAAU,OAClBE,QAAO,UAAU,MACjB,SAAS,UAAU,QACnBC,QAAO,UAAU,MACjB,QAAQ,UAAU,OAClB,QAAQ,UAAU,OAClB,YAAY,UAAU,WACtB,OAAO,UAAU,MACjB,OAAO,UAAU;AAGrB,QAAI,SAAS,IAAK,SAAQ,MAAM,OAAO;AAAA,aAG9B,CAAC,oBAAY,IAAI,EAAG,eAAc,WAAc,YAAY,KAAK,OAAO,MAAM,OAAO;AAG9F,QAAIA,SAAS,SAAS,OAAO,UAAU,IAAM,CAAAA,QAAO,MAAM,OAAO,KAAK,QAAQ;AAI9E,QAAI,UAAU,WAAW,QAAQ,WAAW,SAAY,QAAQ,SAAS,OAAO,WAAW,MAAM,iBAAiB,WAAW,OAAO,SAAS,KAAK,IAAI,IAAI,MAAM,KAAK,YAAY,IAAI,KACjL,UAAU,WAAW,MAAM,iBAAiB,OAAO,KAAK,IAAI,IAAI,UAAU,OAAO,WAAW,QAAQ,WAAW,SAAY,QAAQ,SAAS;AAKhJ,QAAI,aAAa,oBAAY,IAAI,GAC7B,cAAc,aAAa,KAAK,IAAI;AAMxC,gBAAY,cAAc,SAAY,IAChC,SAAS,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,SAAS,CAAC,IACzD,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,SAAS,CAAC;AAEzC,aAASC,QAAOC,QAAO;AACrB,UAAI,cAAc,QACd,cAAc,QACd,GAAG,GAAG;AAEV,UAAI,SAAS,KAAK;AAChB,sBAAc,WAAWA,MAAK,IAAI;AAClC,QAAAA,SAAQ;AAAA,MACV,OAAO;AACL,QAAAA,SAAQ,CAACA;AAGT,YAAI,gBAAgBA,SAAQ,KAAK,IAAIA,SAAQ;AAG7C,QAAAA,SAAQ,MAAMA,MAAK,IAAI,MAAM,WAAW,KAAK,IAAIA,MAAK,GAAG,SAAS;AAGlE,YAAI,KAAM,CAAAA,SAAQ,mBAAWA,MAAK;AAGlC,YAAI,iBAAiB,CAACA,WAAU,KAAKH,UAAS,IAAK,iBAAgB;AAGnE,uBAAe,gBAAiBA,UAAS,MAAMA,QAAO,QAASA,UAAS,OAAOA,UAAS,MAAM,KAAKA,SAAQ;AAC3G,uBAAe,SAAS,OAAO,CAAC,MAAMG,MAAK,KAAK,mBAAmB,SAAY,SAAS,IAAI,iBAAiB,CAAC,IAAI,MAAM,eAAe,iBAAiBH,UAAS,MAAM,MAAM;AAI7K,YAAI,aAAa;AACf,cAAI,IAAI,IAAIG,OAAM;AAClB,iBAAO,EAAE,IAAI,GAAG;AACd,gBAAI,IAAIA,OAAM,WAAW,CAAC,GAAG,KAAK,KAAK,IAAI,IAAI;AAC7C,6BAAe,MAAM,KAAK,UAAUA,OAAM,MAAM,IAAI,CAAC,IAAIA,OAAM,MAAM,CAAC,KAAK;AAC3E,cAAAA,SAAQA,OAAM,MAAM,GAAG,CAAC;AACxB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,UAAI,SAAS,CAACF,MAAM,CAAAE,SAAQ,MAAMA,QAAO,QAAQ;AAGjD,UAAI,SAAS,YAAY,SAASA,OAAM,SAAS,YAAY,QACzD,UAAU,SAAS,QAAQ,IAAI,MAAM,QAAQ,SAAS,CAAC,EAAE,KAAK,IAAI,IAAI;AAG1E,UAAI,SAASF,MAAM,CAAAE,SAAQ,MAAM,UAAUA,QAAO,QAAQ,SAAS,QAAQ,YAAY,SAAS,QAAQ,GAAG,UAAU;AAGrH,cAAQ,OAAO;AAAA,QACb,KAAK;AAAK,UAAAA,SAAQ,cAAcA,SAAQ,cAAc;AAAS;AAAA,QAC/D,KAAK;AAAK,UAAAA,SAAQ,cAAc,UAAUA,SAAQ;AAAa;AAAA,QAC/D,KAAK;AAAK,UAAAA,SAAQ,QAAQ,MAAM,GAAG,SAAS,QAAQ,UAAU,CAAC,IAAI,cAAcA,SAAQ,cAAc,QAAQ,MAAM,MAAM;AAAG;AAAA,QAC9H;AAAS,UAAAA,SAAQ,UAAU,cAAcA,SAAQ;AAAa;AAAA,MAChE;AAEA,aAAO,SAASA,MAAK;AAAA,IACvB;AAEA,IAAAD,QAAO,WAAW,WAAW;AAC3B,aAAO,YAAY;AAAA,IACrB;AAEA,WAAOA;AAAA,EACT;AAEA,WAASE,cAAa,WAAWD,QAAO;AACtC,QAAI,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,iBAASA,MAAK,IAAI,CAAC,CAAC,CAAC,IAAI,GACjE,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,GACnB,IAAI,WAAW,YAAY,gBAAgB,SAAS,GAAG,UAAU,OAAO,KAAK,YAAY,EAAC,QAAQ,SAAS,IAAI,IAAI,CAAC,EAAC,CAAC;AAC1H,WAAO,SAASA,QAAO;AACrB,aAAO,EAAE,IAAIA,MAAK;AAAA,IACpB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,cAAcC;AAAA,EAChB;AACF;;;AChJA,IAAI;AACG,IAAI;AACJ,IAAI;AAEX,cAAc;AAAA,EACZ,WAAW;AAAA,EACX,UAAU,CAAC,CAAC;AAAA,EACZ,UAAU,CAAC,KAAK,EAAE;AACpB,CAAC;AAEc,SAAR,cAA+B,YAAY;AAChD,WAAS,eAAa,UAAU;AAChC,WAAS,OAAO;AAChB,iBAAe,OAAO;AACtB,SAAO;AACT;;;ACfe,SAAR,uBAAiB,MAAM;AAC5B,SAAO,KAAK,IAAI,GAAG,CAAC,iBAAS,KAAK,IAAI,IAAI,CAAC,CAAC;AAC9C;;;ACFe,SAAR,wBAAiB,MAAMC,QAAO;AACnC,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,iBAASA,MAAK,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,iBAAS,KAAK,IAAI,IAAI,CAAC,CAAC;AAC9G;;;ACFe,SAAR,uBAAiB,MAAMC,MAAK;AACjC,SAAO,KAAK,IAAI,IAAI,GAAGA,OAAM,KAAK,IAAIA,IAAG,IAAI;AAC7C,SAAO,KAAK,IAAI,GAAG,iBAASA,IAAG,IAAI,iBAAS,IAAI,CAAC,IAAI;AACvD;;;ACFe,SAAR,WAA4B,OAAO,MAAM,OAAO,WAAW;AAChE,MAAI,OAAO,SAAS,OAAO,MAAM,KAAK,GAClC;AACJ,cAAY,gBAAgB,aAAa,OAAO,OAAO,SAAS;AAChE,UAAQ,UAAU,MAAM;AAAA,IACtB,KAAK,KAAK;AACR,UAAIC,SAAQ,KAAK,IAAI,KAAK,IAAI,KAAK,GAAG,KAAK,IAAI,IAAI,CAAC;AACpD,UAAI,UAAU,aAAa,QAAQ,CAAC,MAAM,YAAY,wBAAgB,MAAMA,MAAK,CAAC,EAAG,WAAU,YAAY;AAC3G,aAAO,aAAa,WAAWA,MAAK;AAAA,IACtC;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,KAAK;AACR,UAAI,UAAU,aAAa,QAAQ,CAAC,MAAM,YAAY,uBAAe,MAAM,KAAK,IAAI,KAAK,IAAI,KAAK,GAAG,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAG,WAAU,YAAY,aAAa,UAAU,SAAS;AAC9K;AAAA,IACF;AAAA,IACA,KAAK;AAAA,IACL,KAAK,KAAK;AACR,UAAI,UAAU,aAAa,QAAQ,CAAC,MAAM,YAAY,uBAAe,IAAI,CAAC,EAAG,WAAU,YAAY,aAAa,UAAU,SAAS,OAAO;AAC1I;AAAA,IACF;AAAA,EACF;AACA,SAAO,OAAO,SAAS;AACzB;;;ACvBO,SAAS,UAAU,OAAO;AAC/B,MAAI,SAAS,MAAM;AAEnB,QAAM,QAAQ,SAAS,OAAO;AAC5B,QAAI,IAAI,OAAO;AACf,WAAO,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,GAAG,SAAS,OAAO,KAAK,KAAK;AAAA,EAChE;AAEA,QAAM,aAAa,SAAS,OAAO,WAAW;AAC5C,QAAI,IAAI,OAAO;AACf,WAAO,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,GAAG,SAAS,OAAO,KAAK,OAAO,SAAS;AAAA,EAChF;AAEA,QAAM,OAAO,SAAS,OAAO;AAC3B,QAAI,SAAS,KAAM,SAAQ;AAE3B,QAAI,IAAI,OAAO;AACf,QAAI,KAAK;AACT,QAAI,KAAK,EAAE,SAAS;AACpB,QAAI,QAAQ,EAAE,EAAE;AAChB,QAAI,OAAO,EAAE,EAAE;AACf,QAAI;AACJ,QAAI;AACJ,QAAI,UAAU;AAEd,QAAI,OAAO,OAAO;AAChB,aAAO,OAAO,QAAQ,MAAM,OAAO;AACnC,aAAO,IAAI,KAAK,IAAI,KAAK;AAAA,IAC3B;AAEA,WAAO,YAAY,GAAG;AACpB,aAAO,cAAc,OAAO,MAAM,KAAK;AACvC,UAAI,SAAS,SAAS;AACpB,UAAE,EAAE,IAAI;AACR,UAAE,EAAE,IAAI;AACR,eAAO,OAAO,CAAC;AAAA,MACjB,WAAW,OAAO,GAAG;AACnB,gBAAQ,KAAK,MAAM,QAAQ,IAAI,IAAI;AACnC,eAAO,KAAK,KAAK,OAAO,IAAI,IAAI;AAAA,MAClC,WAAW,OAAO,GAAG;AACnB,gBAAQ,KAAK,KAAK,QAAQ,IAAI,IAAI;AAClC,eAAO,KAAK,MAAM,OAAO,IAAI,IAAI;AAAA,MACnC,OAAO;AACL;AAAA,MACF;AACA,gBAAU;AAAA,IACZ;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEe,SAARC,UAA0B;AAC/B,MAAI,QAAQ,WAAW;AAEvB,QAAM,OAAO,WAAW;AACtB,WAAO,KAAK,OAAOA,QAAO,CAAC;AAAA,EAC7B;AAEA,YAAU,MAAM,OAAO,SAAS;AAEhC,SAAO,UAAU,KAAK;AACxB;;;ACrEe,SAAR,KAAsB,QAAQ,UAAU;AAC7C,WAAS,OAAO,MAAM;AAEtB,MAAI,KAAK,GACL,KAAK,OAAO,SAAS,GACrB,KAAK,OAAO,EAAE,GACd,KAAK,OAAO,EAAE,GACd;AAEJ,MAAI,KAAK,IAAI;AACX,QAAI,IAAI,KAAK,IAAI,KAAK;AACtB,QAAI,IAAI,KAAK,IAAI,KAAK;AAAA,EACxB;AAEA,SAAO,EAAE,IAAI,SAAS,MAAM,EAAE;AAC9B,SAAO,EAAE,IAAI,SAAS,KAAK,EAAE;AAC7B,SAAO;AACT;;;ACXA,SAAS,aAAaC,IAAG;AACvB,SAAO,KAAK,IAAIA,EAAC;AACnB;AAEA,SAAS,aAAaA,IAAG;AACvB,SAAO,KAAK,IAAIA,EAAC;AACnB;AAEA,SAAS,cAAcA,IAAG;AACxB,SAAO,CAAC,KAAK,IAAI,CAACA,EAAC;AACrB;AAEA,SAAS,cAAcA,IAAG;AACxB,SAAO,CAAC,KAAK,IAAI,CAACA,EAAC;AACrB;AAEA,SAAS,MAAMA,IAAG;AAChB,SAAO,SAASA,EAAC,IAAI,EAAE,OAAOA,MAAKA,KAAI,IAAI,IAAIA;AACjD;AAEA,SAAS,KAAK,MAAM;AAClB,SAAO,SAAS,KAAK,QACf,SAAS,KAAK,IAAI,KAAK,MACvB,CAAAA,OAAK,KAAK,IAAI,MAAMA,EAAC;AAC7B;AAEA,SAAS,KAAK,MAAM;AAClB,SAAO,SAAS,KAAK,IAAI,KAAK,MACxB,SAAS,MAAM,KAAK,SACnB,SAAS,KAAK,KAAK,SAClB,OAAO,KAAK,IAAI,IAAI,GAAG,CAAAA,OAAK,KAAK,IAAIA,EAAC,IAAI;AACpD;AAEA,SAAS,QAAQ,GAAG;AAClB,SAAO,CAACA,IAAG,MAAM,CAAC,EAAE,CAACA,IAAG,CAAC;AAC3B;AAEO,SAAS,QAAQ,WAAW;AACjC,QAAM,QAAQ,UAAU,cAAc,YAAY;AAClD,QAAM,SAAS,MAAM;AACrB,MAAI,OAAO;AACX,MAAI;AACJ,MAAI;AAEJ,WAAS,UAAU;AACjB,WAAO,KAAK,IAAI,GAAG,OAAO,KAAK,IAAI;AACnC,QAAI,OAAO,EAAE,CAAC,IAAI,GAAG;AACnB,aAAO,QAAQ,IAAI,GAAG,OAAO,QAAQ,IAAI;AACzC,gBAAU,eAAe,aAAa;AAAA,IACxC,OAAO;AACL,gBAAU,cAAc,YAAY;AAAA,IACtC;AACA,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,SAAS,GAAG;AACvB,WAAO,UAAU,UAAU,OAAO,CAAC,GAAG,QAAQ,KAAK;AAAA,EACrD;AAEA,QAAM,SAAS,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,OAAO,CAAC,GAAG,QAAQ,KAAK,OAAO;AAAA,EAC5D;AAEA,QAAM,QAAQ,WAAS;AACrB,UAAM,IAAI,OAAO;AACjB,QAAI,IAAI,EAAE,CAAC;AACX,QAAI,IAAI,EAAE,EAAE,SAAS,CAAC;AACtB,UAAM,IAAI,IAAI;AAEd,QAAI,EAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;AAEtB,QAAI,IAAI,KAAK,CAAC;AACd,QAAI,IAAI,KAAK,CAAC;AACd,QAAI;AACJ,QAAI;AACJ,UAAM,IAAI,SAAS,OAAO,KAAK,CAAC;AAChC,QAAI,IAAI,CAAC;AAET,QAAI,EAAE,OAAO,MAAM,IAAI,IAAI,GAAG;AAC5B,UAAI,KAAK,MAAM,CAAC,GAAG,IAAI,KAAK,KAAK,CAAC;AAClC,UAAI,IAAI,EAAG,QAAO,KAAK,GAAG,EAAE,GAAG;AAC7B,aAAK,IAAI,GAAG,IAAI,MAAM,EAAE,GAAG;AACzB,cAAI,IAAI,IAAI,IAAI,KAAK,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC;AACrC,cAAI,IAAI,EAAG;AACX,cAAI,IAAI,EAAG;AACX,YAAE,KAAK,CAAC;AAAA,QACV;AAAA,MACF;AAAA,UAAO,QAAO,KAAK,GAAG,EAAE,GAAG;AACzB,aAAK,IAAI,OAAO,GAAG,KAAK,GAAG,EAAE,GAAG;AAC9B,cAAI,IAAI,IAAI,IAAI,KAAK,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC;AACrC,cAAI,IAAI,EAAG;AACX,cAAI,IAAI,EAAG;AACX,YAAE,KAAK,CAAC;AAAA,QACV;AAAA,MACF;AACA,UAAI,EAAE,SAAS,IAAI,EAAG,KAAI,MAAM,GAAG,GAAG,CAAC;AAAA,IACzC,OAAO;AACL,UAAI,MAAM,GAAG,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,EAAE,IAAI,IAAI;AAAA,IAC9C;AACA,WAAO,IAAI,EAAE,QAAQ,IAAI;AAAA,EAC3B;AAEA,QAAM,aAAa,CAAC,OAAO,cAAc;AACvC,QAAI,SAAS,KAAM,SAAQ;AAC3B,QAAI,aAAa,KAAM,aAAY,SAAS,KAAK,MAAM;AACvD,QAAI,OAAO,cAAc,YAAY;AACnC,UAAI,EAAE,OAAO,OAAO,YAAY,gBAAgB,SAAS,GAAG,aAAa,KAAM,WAAU,OAAO;AAChG,kBAAY,OAAO,SAAS;AAAA,IAC9B;AACA,QAAI,UAAU,SAAU,QAAO;AAC/B,UAAM,IAAI,KAAK,IAAI,GAAG,OAAO,QAAQ,MAAM,MAAM,EAAE,MAAM;AACzD,WAAO,OAAK;AACV,UAAI,IAAI,IAAI,KAAK,KAAK,MAAM,KAAK,CAAC,CAAC,CAAC;AACpC,UAAI,IAAI,OAAO,OAAO,IAAK,MAAK;AAChC,aAAO,KAAK,IAAI,UAAU,CAAC,IAAI;AAAA,IACjC;AAAA,EACF;AAEA,QAAM,OAAO,MAAM;AACjB,WAAO,OAAO,KAAK,OAAO,GAAG;AAAA,MAC3B,OAAO,CAAAA,OAAK,KAAK,KAAK,MAAM,KAAKA,EAAC,CAAC,CAAC;AAAA,MACpC,MAAM,CAAAA,OAAK,KAAK,KAAK,KAAK,KAAKA,EAAC,CAAC,CAAC;AAAA,IACpC,CAAC,CAAC;AAAA,EACJ;AAEA,SAAO;AACT;AAEe,SAAR,MAAuB;AAC5B,QAAM,QAAQ,QAAQ,YAAY,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;AACnD,QAAM,OAAO,MAAM,KAAK,OAAO,IAAI,CAAC,EAAE,KAAK,MAAM,KAAK,CAAC;AACvD,YAAU,MAAM,OAAO,SAAS;AAChC,SAAO;AACT;;;ACvIA,SAAS,gBAAgB,GAAG;AAC1B,SAAO,SAASC,IAAG;AACjB,WAAO,KAAK,KAAKA,EAAC,IAAI,KAAK,MAAM,KAAK,IAAIA,KAAI,CAAC,CAAC;AAAA,EAClD;AACF;AAEA,SAAS,gBAAgB,GAAG;AAC1B,SAAO,SAASA,IAAG;AACjB,WAAO,KAAK,KAAKA,EAAC,IAAI,KAAK,MAAM,KAAK,IAAIA,EAAC,CAAC,IAAI;AAAA,EAClD;AACF;AAEO,SAAS,UAAU,WAAW;AACnC,MAAI,IAAI,GAAG,QAAQ,UAAU,gBAAgB,CAAC,GAAG,gBAAgB,CAAC,CAAC;AAEnE,QAAM,WAAW,SAAS,GAAG;AAC3B,WAAO,UAAU,SAAS,UAAU,gBAAgB,IAAI,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,IAAI;AAAA,EACrF;AAEA,SAAO,UAAU,KAAK;AACxB;AAEe,SAAR,SAA0B;AAC/B,MAAI,QAAQ,UAAU,YAAY,CAAC;AAEnC,QAAM,OAAO,WAAW;AACtB,WAAO,KAAK,OAAO,OAAO,CAAC,EAAE,SAAS,MAAM,SAAS,CAAC;AAAA,EACxD;AAEA,SAAO,UAAU,MAAM,OAAO,SAAS;AACzC;;;AC9BA,SAAS,aAAa,UAAU;AAC9B,SAAO,SAASC,IAAG;AACjB,WAAOA,KAAI,IAAI,CAAC,KAAK,IAAI,CAACA,IAAG,QAAQ,IAAI,KAAK,IAAIA,IAAG,QAAQ;AAAA,EAC/D;AACF;AAEA,SAAS,cAAcA,IAAG;AACxB,SAAOA,KAAI,IAAI,CAAC,KAAK,KAAK,CAACA,EAAC,IAAI,KAAK,KAAKA,EAAC;AAC7C;AAEA,SAAS,gBAAgBA,IAAG;AAC1B,SAAOA,KAAI,IAAI,CAACA,KAAIA,KAAIA,KAAIA;AAC9B;AAEO,SAAS,OAAO,WAAW;AAChC,MAAI,QAAQ,UAAU,UAAU,QAAQ,GACpC,WAAW;AAEf,WAAS,UAAU;AACjB,WAAO,aAAa,IAAI,UAAU,UAAU,QAAQ,IAC9C,aAAa,MAAM,UAAU,eAAe,eAAe,IAC3D,UAAU,aAAa,QAAQ,GAAG,aAAa,IAAI,QAAQ,CAAC;AAAA,EACpE;AAEA,QAAM,WAAW,SAAS,GAAG;AAC3B,WAAO,UAAU,UAAU,WAAW,CAAC,GAAG,QAAQ,KAAK;AAAA,EACzD;AAEA,SAAO,UAAU,KAAK;AACxB;AAEe,SAAR,MAAuB;AAC5B,MAAI,QAAQ,OAAO,YAAY,CAAC;AAEhC,QAAM,OAAO,WAAW;AACtB,WAAO,KAAK,OAAO,IAAI,CAAC,EAAE,SAAS,MAAM,SAAS,CAAC;AAAA,EACrD;AAEA,YAAU,MAAM,OAAO,SAAS;AAEhC,SAAO;AACT;AAEO,SAASC,QAAO;AACrB,SAAO,IAAI,MAAM,MAAM,SAAS,EAAE,SAAS,GAAG;AAChD;;;AC9Ce,SAARC,YAA4B;AACjC,MAAI,SAAS,CAAC,GACVC,SAAQ,CAAC,GACT,aAAa,CAAC,GACd;AAEJ,WAAS,UAAU;AACjB,QAAI,IAAI,GAAG,IAAI,KAAK,IAAI,GAAGA,OAAM,MAAM;AACvC,iBAAa,IAAI,MAAM,IAAI,CAAC;AAC5B,WAAO,EAAE,IAAI,EAAG,YAAW,IAAI,CAAC,IAAI,eAAU,QAAQ,IAAI,CAAC;AAC3D,WAAO;AAAA,EACT;AAEA,WAAS,MAAMC,IAAG;AAChB,WAAOA,MAAK,QAAQ,MAAMA,KAAI,CAACA,EAAC,IAAI,UAAUD,OAAM,eAAO,YAAYC,EAAC,CAAC;AAAA,EAC3E;AAEA,QAAM,eAAe,SAASC,IAAG;AAC/B,QAAI,IAAIF,OAAM,QAAQE,EAAC;AACvB,WAAO,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI;AAAA,MAC1B,IAAI,IAAI,WAAW,IAAI,CAAC,IAAI,OAAO,CAAC;AAAA,MACpC,IAAI,WAAW,SAAS,WAAW,CAAC,IAAI,OAAO,OAAO,SAAS,CAAC;AAAA,IAClE;AAAA,EACF;AAEA,QAAM,SAAS,SAAS,GAAG;AACzB,QAAI,CAAC,UAAU,OAAQ,QAAO,OAAO,MAAM;AAC3C,aAAS,CAAC;AACV,aAAS,KAAK,EAAG,KAAI,KAAK,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC,EAAG,QAAO,KAAK,CAAC;AAC/D,WAAO,KAAK,SAAS;AACrB,WAAO,QAAQ;AAAA,EACjB;AAEA,QAAM,QAAQ,SAAS,GAAG;AACxB,WAAO,UAAU,UAAUF,SAAQ,MAAM,KAAK,CAAC,GAAG,QAAQ,KAAKA,OAAM,MAAM;AAAA,EAC7E;AAEA,QAAM,UAAU,SAAS,GAAG;AAC1B,WAAO,UAAU,UAAU,UAAU,GAAG,SAAS;AAAA,EACnD;AAEA,QAAM,YAAY,WAAW;AAC3B,WAAO,WAAW,MAAM;AAAA,EAC1B;AAEA,QAAM,OAAO,WAAW;AACtB,WAAOD,UAAS,EACX,OAAO,MAAM,EACb,MAAMC,MAAK,EACX,QAAQ,OAAO;AAAA,EACtB;AAEA,SAAO,UAAU,MAAM,OAAO,SAAS;AACzC;;;ACpDe,SAAR,WAA4B;AACjC,MAAI,KAAK,GACL,KAAK,GACL,IAAI,GACJ,SAAS,CAAC,GAAG,GACbG,SAAQ,CAAC,GAAG,CAAC,GACb;AAEJ,WAAS,MAAMC,IAAG;AAChB,WAAOA,MAAK,QAAQA,MAAKA,KAAID,OAAM,eAAO,QAAQC,IAAG,GAAG,CAAC,CAAC,IAAI;AAAA,EAChE;AAEA,WAAS,UAAU;AACjB,QAAI,IAAI;AACR,aAAS,IAAI,MAAM,CAAC;AACpB,WAAO,EAAE,IAAI,EAAG,QAAO,CAAC,MAAM,IAAI,KAAK,MAAM,IAAI,KAAK,OAAO,IAAI;AACjE,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC,IAAI,EAAE;AAAA,EACnF;AAEA,QAAM,QAAQ,SAAS,GAAG;AACxB,WAAO,UAAU,UAAU,KAAKD,SAAQ,MAAM,KAAK,CAAC,GAAG,SAAS,GAAG,QAAQ,KAAKA,OAAM,MAAM;AAAA,EAC9F;AAEA,QAAM,eAAe,SAASE,IAAG;AAC/B,QAAI,IAAIF,OAAM,QAAQE,EAAC;AACvB,WAAO,IAAI,IAAI,CAAC,KAAK,GAAG,IAClB,IAAI,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,IACtB,KAAK,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,IAC3B,CAAC,OAAO,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,EACjC;AAEA,QAAM,UAAU,SAAS,GAAG;AAC1B,WAAO,UAAU,UAAU,UAAU,GAAG,SAAS;AAAA,EACnD;AAEA,QAAM,aAAa,WAAW;AAC5B,WAAO,OAAO,MAAM;AAAA,EACtB;AAEA,QAAM,OAAO,WAAW;AACtB,WAAO,SAAS,EACX,OAAO,CAAC,IAAI,EAAE,CAAC,EACf,MAAMF,MAAK,EACX,QAAQ,OAAO;AAAA,EACtB;AAEA,SAAO,UAAU,MAAM,UAAU,KAAK,GAAG,SAAS;AACpD;;;ACpDe,SAAR,YAA6B;AAClC,MAAI,SAAS,CAAC,GAAG,GACbG,SAAQ,CAAC,GAAG,CAAC,GACb,SACA,IAAI;AAER,WAAS,MAAMC,IAAG;AAChB,WAAOA,MAAK,QAAQA,MAAKA,KAAID,OAAM,eAAO,QAAQC,IAAG,GAAG,CAAC,CAAC,IAAI;AAAA,EAChE;AAEA,QAAM,SAAS,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,SAAS,MAAM,KAAK,CAAC,GAAG,IAAI,KAAK,IAAI,OAAO,QAAQD,OAAM,SAAS,CAAC,GAAG,SAAS,OAAO,MAAM;AAAA,EAC1H;AAEA,QAAM,QAAQ,SAAS,GAAG;AACxB,WAAO,UAAU,UAAUA,SAAQ,MAAM,KAAK,CAAC,GAAG,IAAI,KAAK,IAAI,OAAO,QAAQA,OAAM,SAAS,CAAC,GAAG,SAASA,OAAM,MAAM;AAAA,EACxH;AAEA,QAAM,eAAe,SAASE,IAAG;AAC/B,QAAI,IAAIF,OAAM,QAAQE,EAAC;AACvB,WAAO,CAAC,OAAO,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,EAClC;AAEA,QAAM,UAAU,SAAS,GAAG;AAC1B,WAAO,UAAU,UAAU,UAAU,GAAG,SAAS;AAAA,EACnD;AAEA,QAAM,OAAO,WAAW;AACtB,WAAO,UAAU,EACZ,OAAO,MAAM,EACb,MAAMF,MAAK,EACX,QAAQ,OAAO;AAAA,EACtB;AAEA,SAAO,UAAU,MAAM,OAAO,SAAS;AACzC;;;ACtCA,IAAM,KAAK,oBAAI;AAAf,IAAqB,KAAK,oBAAI;AAEvB,SAAS,aAAa,QAAQ,SAAS,OAAO,OAAO;AAE1D,WAAS,SAASG,OAAM;AACtB,WAAO,OAAOA,QAAO,UAAU,WAAW,IAAI,oBAAI,SAAO,oBAAI,KAAK,CAACA,KAAI,CAAC,GAAGA;AAAA,EAC7E;AAEA,WAAS,QAAQ,CAACA,UAAS;AACzB,WAAO,OAAOA,QAAO,oBAAI,KAAK,CAACA,KAAI,CAAC,GAAGA;AAAA,EACzC;AAEA,WAAS,OAAO,CAACA,UAAS;AACxB,WAAO,OAAOA,QAAO,IAAI,KAAKA,QAAO,CAAC,CAAC,GAAG,QAAQA,OAAM,CAAC,GAAG,OAAOA,KAAI,GAAGA;AAAA,EAC5E;AAEA,WAAS,QAAQ,CAACA,UAAS;AACzB,UAAM,KAAK,SAASA,KAAI,GAAG,KAAK,SAAS,KAAKA,KAAI;AAClD,WAAOA,QAAO,KAAK,KAAKA,QAAO,KAAK;AAAA,EACtC;AAEA,WAAS,SAAS,CAACA,OAAM,SAAS;AAChC,WAAO,QAAQA,QAAO,oBAAI,KAAK,CAACA,KAAI,GAAG,QAAQ,OAAO,IAAI,KAAK,MAAM,IAAI,CAAC,GAAGA;AAAA,EAC/E;AAEA,WAAS,QAAQ,CAAC,OAAO,MAAM,SAAS;AACtC,UAAMC,SAAQ,CAAC;AACf,YAAQ,SAAS,KAAK,KAAK;AAC3B,WAAO,QAAQ,OAAO,IAAI,KAAK,MAAM,IAAI;AACzC,QAAI,EAAE,QAAQ,SAAS,EAAE,OAAO,GAAI,QAAOA;AAC3C,QAAI;AACJ;AAAG,MAAAA,OAAM,KAAK,WAAW,oBAAI,KAAK,CAAC,KAAK,CAAC,GAAG,QAAQ,OAAO,IAAI,GAAG,OAAO,KAAK;AAAA,WACvE,WAAW,SAAS,QAAQ;AACnC,WAAOA;AAAA,EACT;AAEA,WAAS,SAAS,CAAC,SAAS;AAC1B,WAAO,aAAa,CAACD,UAAS;AAC5B,UAAIA,SAAQA,MAAM,QAAO,OAAOA,KAAI,GAAG,CAAC,KAAKA,KAAI,EAAG,CAAAA,MAAK,QAAQA,QAAO,CAAC;AAAA,IAC3E,GAAG,CAACA,OAAM,SAAS;AACjB,UAAIA,SAAQA,OAAM;AAChB,YAAI,OAAO,EAAG,QAAO,EAAE,QAAQ,GAAG;AAChC,iBAAO,QAAQA,OAAM,EAAE,GAAG,CAAC,KAAKA,KAAI,GAAG;AAAA,UAAC;AAAA,QAC1C;AAAA,YAAO,QAAO,EAAE,QAAQ,GAAG;AACzB,iBAAO,QAAQA,OAAM,CAAE,GAAG,CAAC,KAAKA,KAAI,GAAG;AAAA,UAAC;AAAA,QAC1C;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,OAAO;AACT,aAAS,QAAQ,CAAC,OAAO,QAAQ;AAC/B,SAAG,QAAQ,CAAC,KAAK,GAAG,GAAG,QAAQ,CAAC,GAAG;AACnC,aAAO,EAAE,GAAG,OAAO,EAAE;AACrB,aAAO,KAAK,MAAM,MAAM,IAAI,EAAE,CAAC;AAAA,IACjC;AAEA,aAAS,QAAQ,CAAC,SAAS;AACzB,aAAO,KAAK,MAAM,IAAI;AACtB,aAAO,CAAC,SAAS,IAAI,KAAK,EAAE,OAAO,KAAK,OAClC,EAAE,OAAO,KAAK,WACd,SAAS,OAAO,QACZ,CAAC,MAAM,MAAM,CAAC,IAAI,SAAS,IAC3B,CAAC,MAAM,SAAS,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC;AAAA,IACpD;AAAA,EACF;AAEA,SAAO;AACT;;;AClEO,IAAM,cAAc,aAAa,MAAM;AAE9C,GAAG,CAACE,OAAM,SAAS;AACjB,EAAAA,MAAK,QAAQ,CAACA,QAAO,IAAI;AAC3B,GAAG,CAAC,OAAO,QAAQ;AACjB,SAAO,MAAM;AACf,CAAC;AAGD,YAAY,QAAQ,CAAC,MAAM;AACzB,MAAI,KAAK,MAAM,CAAC;AAChB,MAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,GAAI,QAAO;AACrC,MAAI,EAAE,IAAI,GAAI,QAAO;AACrB,SAAO,aAAa,CAACA,UAAS;AAC5B,IAAAA,MAAK,QAAQ,KAAK,MAAMA,QAAO,CAAC,IAAI,CAAC;AAAA,EACvC,GAAG,CAACA,OAAM,SAAS;AACjB,IAAAA,MAAK,QAAQ,CAACA,QAAO,OAAO,CAAC;AAAA,EAC/B,GAAG,CAAC,OAAO,QAAQ;AACjB,YAAQ,MAAM,SAAS;AAAA,EACzB,CAAC;AACH;AAEO,IAAM,eAAe,YAAY;;;ACxBjC,IAAM,iBAAiB;AACvB,IAAM,iBAAiB,iBAAiB;AACxC,IAAM,eAAe,iBAAiB;AACtC,IAAM,cAAc,eAAe;AACnC,IAAM,eAAe,cAAc;AACnC,IAAM,gBAAgB,cAAc;AACpC,IAAM,eAAe,cAAc;;;ACHnC,IAAM,SAAS,aAAa,CAACC,UAAS;AAC3C,EAAAA,MAAK,QAAQA,QAAOA,MAAK,gBAAgB,CAAC;AAC5C,GAAG,CAACA,OAAM,SAAS;AACjB,EAAAA,MAAK,QAAQ,CAACA,QAAO,OAAO,cAAc;AAC5C,GAAG,CAAC,OAAO,QAAQ;AACjB,UAAQ,MAAM,SAAS;AACzB,GAAG,CAACA,UAAS;AACX,SAAOA,MAAK,cAAc;AAC5B,CAAC;AAEM,IAAM,UAAU,OAAO;;;ACVvB,IAAM,aAAa,aAAa,CAACC,UAAS;AAC/C,EAAAA,MAAK,QAAQA,QAAOA,MAAK,gBAAgB,IAAIA,MAAK,WAAW,IAAI,cAAc;AACjF,GAAG,CAACA,OAAM,SAAS;AACjB,EAAAA,MAAK,QAAQ,CAACA,QAAO,OAAO,cAAc;AAC5C,GAAG,CAAC,OAAO,QAAQ;AACjB,UAAQ,MAAM,SAAS;AACzB,GAAG,CAACA,UAAS;AACX,SAAOA,MAAK,WAAW;AACzB,CAAC;AAEM,IAAM,cAAc,WAAW;AAE/B,IAAM,YAAY,aAAa,CAACA,UAAS;AAC9C,EAAAA,MAAK,cAAc,GAAG,CAAC;AACzB,GAAG,CAACA,OAAM,SAAS;AACjB,EAAAA,MAAK,QAAQ,CAACA,QAAO,OAAO,cAAc;AAC5C,GAAG,CAAC,OAAO,QAAQ;AACjB,UAAQ,MAAM,SAAS;AACzB,GAAG,CAACA,UAAS;AACX,SAAOA,MAAK,cAAc;AAC5B,CAAC;AAEM,IAAM,aAAa,UAAU;;;ACtB7B,IAAM,WAAW,aAAa,CAACC,UAAS;AAC7C,EAAAA,MAAK,QAAQA,QAAOA,MAAK,gBAAgB,IAAIA,MAAK,WAAW,IAAI,iBAAiBA,MAAK,WAAW,IAAI,cAAc;AACtH,GAAG,CAACA,OAAM,SAAS;AACjB,EAAAA,MAAK,QAAQ,CAACA,QAAO,OAAO,YAAY;AAC1C,GAAG,CAAC,OAAO,QAAQ;AACjB,UAAQ,MAAM,SAAS;AACzB,GAAG,CAACA,UAAS;AACX,SAAOA,MAAK,SAAS;AACvB,CAAC;AAEM,IAAM,YAAY,SAAS;AAE3B,IAAM,UAAU,aAAa,CAACA,UAAS;AAC5C,EAAAA,MAAK,cAAc,GAAG,GAAG,CAAC;AAC5B,GAAG,CAACA,OAAM,SAAS;AACjB,EAAAA,MAAK,QAAQ,CAACA,QAAO,OAAO,YAAY;AAC1C,GAAG,CAAC,OAAO,QAAQ;AACjB,UAAQ,MAAM,SAAS;AACzB,GAAG,CAACA,UAAS;AACX,SAAOA,MAAK,YAAY;AAC1B,CAAC;AAEM,IAAM,WAAW,QAAQ;;;ACtBzB,IAAM,UAAU;AAAA,EACrB,CAAAC,UAAQA,MAAK,SAAS,GAAG,GAAG,GAAG,CAAC;AAAA,EAChC,CAACA,OAAM,SAASA,MAAK,QAAQA,MAAK,QAAQ,IAAI,IAAI;AAAA,EAClD,CAAC,OAAO,SAAS,MAAM,SAAS,IAAI,kBAAkB,IAAI,MAAM,kBAAkB,KAAK,kBAAkB;AAAA,EACzG,CAAAA,UAAQA,MAAK,QAAQ,IAAI;AAC3B;AAEO,IAAM,WAAW,QAAQ;AAEzB,IAAM,SAAS,aAAa,CAACA,UAAS;AAC3C,EAAAA,MAAK,YAAY,GAAG,GAAG,GAAG,CAAC;AAC7B,GAAG,CAACA,OAAM,SAAS;AACjB,EAAAA,MAAK,WAAWA,MAAK,WAAW,IAAI,IAAI;AAC1C,GAAG,CAAC,OAAO,QAAQ;AACjB,UAAQ,MAAM,SAAS;AACzB,GAAG,CAACA,UAAS;AACX,SAAOA,MAAK,WAAW,IAAI;AAC7B,CAAC;AAEM,IAAM,UAAU,OAAO;AAEvB,IAAM,UAAU,aAAa,CAACA,UAAS;AAC5C,EAAAA,MAAK,YAAY,GAAG,GAAG,GAAG,CAAC;AAC7B,GAAG,CAACA,OAAM,SAAS;AACjB,EAAAA,MAAK,WAAWA,MAAK,WAAW,IAAI,IAAI;AAC1C,GAAG,CAAC,OAAO,QAAQ;AACjB,UAAQ,MAAM,SAAS;AACzB,GAAG,CAACA,UAAS;AACX,SAAO,KAAK,MAAMA,QAAO,WAAW;AACtC,CAAC;AAEM,IAAM,WAAW,QAAQ;;;AC/BhC,SAAS,YAAY,GAAG;AACtB,SAAO,aAAa,CAACC,UAAS;AAC5B,IAAAA,MAAK,QAAQA,MAAK,QAAQ,KAAKA,MAAK,OAAO,IAAI,IAAI,KAAK,CAAC;AACzD,IAAAA,MAAK,SAAS,GAAG,GAAG,GAAG,CAAC;AAAA,EAC1B,GAAG,CAACA,OAAM,SAAS;AACjB,IAAAA,MAAK,QAAQA,MAAK,QAAQ,IAAI,OAAO,CAAC;AAAA,EACxC,GAAG,CAAC,OAAO,QAAQ;AACjB,YAAQ,MAAM,SAAS,IAAI,kBAAkB,IAAI,MAAM,kBAAkB,KAAK,kBAAkB;AAAA,EAClG,CAAC;AACH;AAEO,IAAM,aAAa,YAAY,CAAC;AAChC,IAAM,aAAa,YAAY,CAAC;AAChC,IAAM,cAAc,YAAY,CAAC;AACjC,IAAM,gBAAgB,YAAY,CAAC;AACnC,IAAM,eAAe,YAAY,CAAC;AAClC,IAAM,aAAa,YAAY,CAAC;AAChC,IAAM,eAAe,YAAY,CAAC;AAElC,IAAM,cAAc,WAAW;AAC/B,IAAM,cAAc,WAAW;AAC/B,IAAM,eAAe,YAAY;AACjC,IAAM,iBAAiB,cAAc;AACrC,IAAM,gBAAgB,aAAa;AACnC,IAAM,cAAc,WAAW;AAC/B,IAAM,gBAAgB,aAAa;AAE1C,SAAS,WAAW,GAAG;AACrB,SAAO,aAAa,CAACA,UAAS;AAC5B,IAAAA,MAAK,WAAWA,MAAK,WAAW,KAAKA,MAAK,UAAU,IAAI,IAAI,KAAK,CAAC;AAClE,IAAAA,MAAK,YAAY,GAAG,GAAG,GAAG,CAAC;AAAA,EAC7B,GAAG,CAACA,OAAM,SAAS;AACjB,IAAAA,MAAK,WAAWA,MAAK,WAAW,IAAI,OAAO,CAAC;AAAA,EAC9C,GAAG,CAAC,OAAO,QAAQ;AACjB,YAAQ,MAAM,SAAS;AAAA,EACzB,CAAC;AACH;AAEO,IAAM,YAAY,WAAW,CAAC;AAC9B,IAAM,YAAY,WAAW,CAAC;AAC9B,IAAM,aAAa,WAAW,CAAC;AAC/B,IAAM,eAAe,WAAW,CAAC;AACjC,IAAM,cAAc,WAAW,CAAC;AAChC,IAAM,YAAY,WAAW,CAAC;AAC9B,IAAM,cAAc,WAAW,CAAC;AAEhC,IAAM,aAAa,UAAU;AAC7B,IAAM,aAAa,UAAU;AAC7B,IAAM,cAAc,WAAW;AAC/B,IAAM,gBAAgB,aAAa;AACnC,IAAM,eAAe,YAAY;AACjC,IAAM,aAAa,UAAU;AAC7B,IAAM,eAAe,YAAY;;;ACrDjC,IAAM,YAAY,aAAa,CAACC,UAAS;AAC9C,EAAAA,MAAK,QAAQ,CAAC;AACd,EAAAA,MAAK,SAAS,GAAG,GAAG,GAAG,CAAC;AAC1B,GAAG,CAACA,OAAM,SAAS;AACjB,EAAAA,MAAK,SAASA,MAAK,SAAS,IAAI,IAAI;AACtC,GAAG,CAAC,OAAO,QAAQ;AACjB,SAAO,IAAI,SAAS,IAAI,MAAM,SAAS,KAAK,IAAI,YAAY,IAAI,MAAM,YAAY,KAAK;AACzF,GAAG,CAACA,UAAS;AACX,SAAOA,MAAK,SAAS;AACvB,CAAC;AAEM,IAAM,aAAa,UAAU;AAE7B,IAAM,WAAW,aAAa,CAACA,UAAS;AAC7C,EAAAA,MAAK,WAAW,CAAC;AACjB,EAAAA,MAAK,YAAY,GAAG,GAAG,GAAG,CAAC;AAC7B,GAAG,CAACA,OAAM,SAAS;AACjB,EAAAA,MAAK,YAAYA,MAAK,YAAY,IAAI,IAAI;AAC5C,GAAG,CAAC,OAAO,QAAQ;AACjB,SAAO,IAAI,YAAY,IAAI,MAAM,YAAY,KAAK,IAAI,eAAe,IAAI,MAAM,eAAe,KAAK;AACrG,GAAG,CAACA,UAAS;AACX,SAAOA,MAAK,YAAY;AAC1B,CAAC;AAEM,IAAM,YAAY,SAAS;;;ACxB3B,IAAM,WAAW,aAAa,CAACC,UAAS;AAC7C,EAAAA,MAAK,SAAS,GAAG,CAAC;AAClB,EAAAA,MAAK,SAAS,GAAG,GAAG,GAAG,CAAC;AAC1B,GAAG,CAACA,OAAM,SAAS;AACjB,EAAAA,MAAK,YAAYA,MAAK,YAAY,IAAI,IAAI;AAC5C,GAAG,CAAC,OAAO,QAAQ;AACjB,SAAO,IAAI,YAAY,IAAI,MAAM,YAAY;AAC/C,GAAG,CAACA,UAAS;AACX,SAAOA,MAAK,YAAY;AAC1B,CAAC;AAGD,SAAS,QAAQ,CAAC,MAAM;AACtB,SAAO,CAAC,SAAS,IAAI,KAAK,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,KAAK,OAAO,aAAa,CAACA,UAAS;AAC9E,IAAAA,MAAK,YAAY,KAAK,MAAMA,MAAK,YAAY,IAAI,CAAC,IAAI,CAAC;AACvD,IAAAA,MAAK,SAAS,GAAG,CAAC;AAClB,IAAAA,MAAK,SAAS,GAAG,GAAG,GAAG,CAAC;AAAA,EAC1B,GAAG,CAACA,OAAM,SAAS;AACjB,IAAAA,MAAK,YAAYA,MAAK,YAAY,IAAI,OAAO,CAAC;AAAA,EAChD,CAAC;AACH;AAEO,IAAM,YAAY,SAAS;AAE3B,IAAM,UAAU,aAAa,CAACA,UAAS;AAC5C,EAAAA,MAAK,YAAY,GAAG,CAAC;AACrB,EAAAA,MAAK,YAAY,GAAG,GAAG,GAAG,CAAC;AAC7B,GAAG,CAACA,OAAM,SAAS;AACjB,EAAAA,MAAK,eAAeA,MAAK,eAAe,IAAI,IAAI;AAClD,GAAG,CAAC,OAAO,QAAQ;AACjB,SAAO,IAAI,eAAe,IAAI,MAAM,eAAe;AACrD,GAAG,CAACA,UAAS;AACX,SAAOA,MAAK,eAAe;AAC7B,CAAC;AAGD,QAAQ,QAAQ,CAAC,MAAM;AACrB,SAAO,CAAC,SAAS,IAAI,KAAK,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,KAAK,OAAO,aAAa,CAACA,UAAS;AAC9E,IAAAA,MAAK,eAAe,KAAK,MAAMA,MAAK,eAAe,IAAI,CAAC,IAAI,CAAC;AAC7D,IAAAA,MAAK,YAAY,GAAG,CAAC;AACrB,IAAAA,MAAK,YAAY,GAAG,GAAG,GAAG,CAAC;AAAA,EAC7B,GAAG,CAACA,OAAM,SAAS;AACjB,IAAAA,MAAK,eAAeA,MAAK,eAAe,IAAI,OAAO,CAAC;AAAA,EACtD,CAAC;AACH;AAEO,IAAM,WAAW,QAAQ;;;ACrChC,SAAS,OAAO,MAAM,OAAO,MAAM,KAAK,MAAM,QAAQ;AAEpD,QAAM,gBAAgB;AAAA,IACpB,CAAC,QAAS,GAAQ,cAAc;AAAA,IAChC,CAAC,QAAS,GAAI,IAAI,cAAc;AAAA,IAChC,CAAC,QAAQ,IAAI,KAAK,cAAc;AAAA,IAChC,CAAC,QAAQ,IAAI,KAAK,cAAc;AAAA,IAChC,CAAC,QAAS,GAAQ,cAAc;AAAA,IAChC,CAAC,QAAS,GAAI,IAAI,cAAc;AAAA,IAChC,CAAC,QAAQ,IAAI,KAAK,cAAc;AAAA,IAChC,CAAC,QAAQ,IAAI,KAAK,cAAc;AAAA,IAChC,CAAG,MAAO,GAAQ,YAAc;AAAA,IAChC,CAAG,MAAO,GAAI,IAAI,YAAc;AAAA,IAChC,CAAG,MAAO,GAAI,IAAI,YAAc;AAAA,IAChC,CAAG,MAAM,IAAI,KAAK,YAAc;AAAA,IAChC,CAAI,KAAM,GAAQ,WAAc;AAAA,IAChC,CAAI,KAAM,GAAI,IAAI,WAAc;AAAA,IAChC,CAAG,MAAO,GAAQ,YAAc;AAAA,IAChC,CAAE,OAAQ,GAAQ,aAAc;AAAA,IAChC,CAAE,OAAQ,GAAI,IAAI,aAAc;AAAA,IAChC,CAAG,MAAO,GAAQ,YAAc;AAAA,EAClC;AAEA,WAASC,OAAM,OAAO,MAAM,OAAO;AACjC,UAAM,UAAU,OAAO;AACvB,QAAI,QAAS,EAAC,OAAO,IAAI,IAAI,CAAC,MAAM,KAAK;AACzC,UAAM,WAAW,SAAS,OAAO,MAAM,UAAU,aAAa,QAAQ,aAAa,OAAO,MAAM,KAAK;AACrG,UAAMA,SAAQ,WAAW,SAAS,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;AAC7D,WAAO,UAAUA,OAAM,QAAQ,IAAIA;AAAA,EACrC;AAEA,WAAS,aAAa,OAAO,MAAM,OAAO;AACxC,UAAM,SAAS,KAAK,IAAI,OAAO,KAAK,IAAI;AACxC,UAAM,IAAI,SAAS,CAAC,CAAC,EAAC,EAAEC,KAAI,MAAMA,KAAI,EAAE,MAAM,eAAe,MAAM;AACnE,QAAI,MAAM,cAAc,OAAQ,QAAO,KAAK,MAAM,SAAS,QAAQ,cAAc,OAAO,cAAc,KAAK,CAAC;AAC5G,QAAI,MAAM,EAAG,QAAO,YAAY,MAAM,KAAK,IAAI,SAAS,OAAO,MAAM,KAAK,GAAG,CAAC,CAAC;AAC/E,UAAM,CAAC,GAAG,IAAI,IAAI,cAAc,SAAS,cAAc,IAAI,CAAC,EAAE,CAAC,IAAI,cAAc,CAAC,EAAE,CAAC,IAAI,SAAS,IAAI,IAAI,CAAC;AAC3G,WAAO,EAAE,MAAM,IAAI;AAAA,EACrB;AAEA,SAAO,CAACD,QAAO,YAAY;AAC7B;AAEA,IAAM,CAAC,UAAU,eAAe,IAAI,OAAO,SAAS,UAAU,WAAW,SAAS,SAAS,SAAS;AACpG,IAAM,CAAC,WAAW,gBAAgB,IAAI,OAAO,UAAU,WAAW,YAAY,SAAS,UAAU,UAAU;;;AC1C3G,SAAS,UAAU,GAAG;AACpB,MAAI,KAAK,EAAE,KAAK,EAAE,IAAI,KAAK;AACzB,QAAIE,QAAO,IAAI,KAAK,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACpD,IAAAA,MAAK,YAAY,EAAE,CAAC;AACpB,WAAOA;AAAA,EACT;AACA,SAAO,IAAI,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACnD;AAEA,SAAS,QAAQ,GAAG;AAClB,MAAI,KAAK,EAAE,KAAK,EAAE,IAAI,KAAK;AACzB,QAAIA,QAAO,IAAI,KAAK,KAAK,IAAI,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;AAC9D,IAAAA,MAAK,eAAe,EAAE,CAAC;AACvB,WAAOA;AAAA,EACT;AACA,SAAO,IAAI,KAAK,KAAK,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;AAC7D;AAEA,SAAS,QAAQC,IAAG,GAAG,GAAG;AACxB,SAAO,EAAC,GAAGA,IAAG,GAAM,GAAM,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAC;AAClD;AAEe,SAAR,aAA8BC,SAAQ;AAC3C,MAAI,kBAAkBA,QAAO,UACzB,cAAcA,QAAO,MACrB,cAAcA,QAAO,MACrB,iBAAiBA,QAAO,SACxB,kBAAkBA,QAAO,MACzB,uBAAuBA,QAAO,WAC9B,gBAAgBA,QAAO,QACvB,qBAAqBA,QAAO;AAEhC,MAAI,WAAW,SAAS,cAAc,GAClC,eAAe,aAAa,cAAc,GAC1C,YAAY,SAAS,eAAe,GACpC,gBAAgB,aAAa,eAAe,GAC5C,iBAAiB,SAAS,oBAAoB,GAC9C,qBAAqB,aAAa,oBAAoB,GACtD,UAAU,SAAS,aAAa,GAChC,cAAc,aAAa,aAAa,GACxC,eAAe,SAAS,kBAAkB,GAC1C,mBAAmB,aAAa,kBAAkB;AAEtD,MAAI,UAAU;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AAEA,MAAI,aAAa;AAAA,IACf,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AAEA,MAAI,SAAS;AAAA,IACX,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AAGA,UAAQ,IAAI,UAAU,aAAa,OAAO;AAC1C,UAAQ,IAAI,UAAU,aAAa,OAAO;AAC1C,UAAQ,IAAI,UAAU,iBAAiB,OAAO;AAC9C,aAAW,IAAI,UAAU,aAAa,UAAU;AAChD,aAAW,IAAI,UAAU,aAAa,UAAU;AAChD,aAAW,IAAI,UAAU,iBAAiB,UAAU;AAEpD,WAAS,UAAU,WAAWC,UAAS;AACrC,WAAO,SAASH,OAAM;AACpB,UAAI,SAAS,CAAC,GACV,IAAI,IACJ,IAAI,GACJ,IAAI,UAAU,QACd,GACAI,MACAC;AAEJ,UAAI,EAAEL,iBAAgB,MAAO,CAAAA,QAAO,oBAAI,KAAK,CAACA,KAAI;AAElD,aAAO,EAAE,IAAI,GAAG;AACd,YAAI,UAAU,WAAW,CAAC,MAAM,IAAI;AAClC,iBAAO,KAAK,UAAU,MAAM,GAAG,CAAC,CAAC;AACjC,eAAKI,OAAM,KAAK,IAAI,UAAU,OAAO,EAAE,CAAC,CAAC,MAAM,KAAM,KAAI,UAAU,OAAO,EAAE,CAAC;AAAA,cACxE,CAAAA,OAAM,MAAM,MAAM,MAAM;AAC7B,cAAIC,UAASF,SAAQ,CAAC,EAAG,KAAIE,QAAOL,OAAMI,IAAG;AAC7C,iBAAO,KAAK,CAAC;AACb,cAAI,IAAI;AAAA,QACV;AAAA,MACF;AAEA,aAAO,KAAK,UAAU,MAAM,GAAG,CAAC,CAAC;AACjC,aAAO,OAAO,KAAK,EAAE;AAAA,IACvB;AAAA,EACF;AAEA,WAAS,SAAS,WAAW,GAAG;AAC9B,WAAO,SAAS,QAAQ;AACtB,UAAI,IAAI,QAAQ,MAAM,QAAW,CAAC,GAC9B,IAAI,eAAe,GAAG,WAAW,UAAU,IAAI,CAAC,GAChD,MAAM;AACV,UAAI,KAAK,OAAO,OAAQ,QAAO;AAG/B,UAAI,OAAO,EAAG,QAAO,IAAI,KAAK,EAAE,CAAC;AACjC,UAAI,OAAO,EAAG,QAAO,IAAI,KAAK,EAAE,IAAI,OAAQ,OAAO,IAAI,EAAE,IAAI,EAAE;AAG/D,UAAI,KAAK,EAAE,OAAO,GAAI,GAAE,IAAI;AAG5B,UAAI,OAAO,EAAG,GAAE,IAAI,EAAE,IAAI,KAAK,EAAE,IAAI;AAGrC,UAAI,EAAE,MAAM,OAAW,GAAE,IAAI,OAAO,IAAI,EAAE,IAAI;AAG9C,UAAI,OAAO,GAAG;AACZ,YAAI,EAAE,IAAI,KAAK,EAAE,IAAI,GAAI,QAAO;AAChC,YAAI,EAAE,OAAO,GAAI,GAAE,IAAI;AACvB,YAAI,OAAO,GAAG;AACZ,iBAAO,QAAQ,QAAQ,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,MAAM,KAAK,UAAU;AACzD,iBAAO,MAAM,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,IAAI;AACnE,iBAAO,OAAO,OAAO,OAAO,EAAE,IAAI,KAAK,CAAC;AACxC,YAAE,IAAI,KAAK,eAAe;AAC1B,YAAE,IAAI,KAAK,YAAY;AACvB,YAAE,IAAI,KAAK,WAAW,KAAK,EAAE,IAAI,KAAK;AAAA,QACxC,OAAO;AACL,iBAAO,UAAU,QAAQ,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,MAAM,KAAK,OAAO;AACxD,iBAAO,MAAM,KAAK,QAAQ,IAAI,WAAW,KAAK,IAAI,IAAI,WAAW,IAAI;AACrE,iBAAO,QAAQ,OAAO,OAAO,EAAE,IAAI,KAAK,CAAC;AACzC,YAAE,IAAI,KAAK,YAAY;AACvB,YAAE,IAAI,KAAK,SAAS;AACpB,YAAE,IAAI,KAAK,QAAQ,KAAK,EAAE,IAAI,KAAK;AAAA,QACrC;AAAA,MACF,WAAW,OAAO,KAAK,OAAO,GAAG;AAC/B,YAAI,EAAE,OAAO,GAAI,GAAE,IAAI,OAAO,IAAI,EAAE,IAAI,IAAI,OAAO,IAAI,IAAI;AAC3D,cAAM,OAAO,IAAI,QAAQ,QAAQ,EAAE,GAAG,GAAG,CAAC,CAAC,EAAE,UAAU,IAAI,UAAU,QAAQ,EAAE,GAAG,GAAG,CAAC,CAAC,EAAE,OAAO;AAChG,UAAE,IAAI;AACN,UAAE,IAAI,OAAO,KAAK,EAAE,IAAI,KAAK,IAAI,EAAE,IAAI,KAAK,MAAM,KAAK,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,MAAM,KAAK;AAAA,MACzF;AAIA,UAAI,OAAO,GAAG;AACZ,UAAE,KAAK,EAAE,IAAI,MAAM;AACnB,UAAE,KAAK,EAAE,IAAI;AACb,eAAO,QAAQ,CAAC;AAAA,MAClB;AAGA,aAAO,UAAU,CAAC;AAAA,IACpB;AAAA,EACF;AAEA,WAAS,eAAe,GAAG,WAAW,QAAQ,GAAG;AAC/C,QAAI,IAAI,GACJ,IAAI,UAAU,QACd,IAAI,OAAO,QACX,GACA;AAEJ,WAAO,IAAI,GAAG;AACZ,UAAI,KAAK,EAAG,QAAO;AACnB,UAAI,UAAU,WAAW,GAAG;AAC5B,UAAI,MAAM,IAAI;AACZ,YAAI,UAAU,OAAO,GAAG;AACxB,gBAAQ,OAAO,KAAK,OAAO,UAAU,OAAO,GAAG,IAAI,CAAC;AACpD,YAAI,CAAC,UAAW,IAAI,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAI,QAAO;AAAA,MACxD,WAAW,KAAK,OAAO,WAAW,GAAG,GAAG;AACtC,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,YAAY,GAAG,QAAQ,GAAG;AACjC,QAAI,IAAI,SAAS,KAAK,OAAO,MAAM,CAAC,CAAC;AACrC,WAAO,KAAK,EAAE,IAAI,aAAa,IAAI,EAAE,CAAC,EAAE,YAAY,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAAA,EAC7E;AAEA,WAAS,kBAAkB,GAAG,QAAQ,GAAG;AACvC,QAAI,IAAI,eAAe,KAAK,OAAO,MAAM,CAAC,CAAC;AAC3C,WAAO,KAAK,EAAE,IAAI,mBAAmB,IAAI,EAAE,CAAC,EAAE,YAAY,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAAA,EACnF;AAEA,WAAS,aAAa,GAAG,QAAQ,GAAG;AAClC,QAAI,IAAI,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AACtC,WAAO,KAAK,EAAE,IAAI,cAAc,IAAI,EAAE,CAAC,EAAE,YAAY,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAAA,EAC9E;AAEA,WAAS,gBAAgB,GAAG,QAAQ,GAAG;AACrC,QAAI,IAAI,aAAa,KAAK,OAAO,MAAM,CAAC,CAAC;AACzC,WAAO,KAAK,EAAE,IAAI,iBAAiB,IAAI,EAAE,CAAC,EAAE,YAAY,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAAA,EACjF;AAEA,WAAS,WAAW,GAAG,QAAQ,GAAG;AAChC,QAAI,IAAI,QAAQ,KAAK,OAAO,MAAM,CAAC,CAAC;AACpC,WAAO,KAAK,EAAE,IAAI,YAAY,IAAI,EAAE,CAAC,EAAE,YAAY,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAAA,EAC5E;AAEA,WAAS,oBAAoB,GAAG,QAAQ,GAAG;AACzC,WAAO,eAAe,GAAG,iBAAiB,QAAQ,CAAC;AAAA,EACrD;AAEA,WAAS,gBAAgB,GAAG,QAAQ,GAAG;AACrC,WAAO,eAAe,GAAG,aAAa,QAAQ,CAAC;AAAA,EACjD;AAEA,WAAS,gBAAgB,GAAG,QAAQ,GAAG;AACrC,WAAO,eAAe,GAAG,aAAa,QAAQ,CAAC;AAAA,EACjD;AAEA,WAAS,mBAAmB,GAAG;AAC7B,WAAO,qBAAqB,EAAE,OAAO,CAAC;AAAA,EACxC;AAEA,WAAS,cAAc,GAAG;AACxB,WAAO,gBAAgB,EAAE,OAAO,CAAC;AAAA,EACnC;AAEA,WAAS,iBAAiB,GAAG;AAC3B,WAAO,mBAAmB,EAAE,SAAS,CAAC;AAAA,EACxC;AAEA,WAAS,YAAY,GAAG;AACtB,WAAO,cAAc,EAAE,SAAS,CAAC;AAAA,EACnC;AAEA,WAAS,aAAa,GAAG;AACvB,WAAO,eAAe,EAAE,EAAE,SAAS,KAAK,GAAG;AAAA,EAC7C;AAEA,WAAS,cAAc,GAAG;AACxB,WAAO,IAAI,CAAC,EAAE,EAAE,SAAS,IAAI;AAAA,EAC/B;AAEA,WAAS,sBAAsB,GAAG;AAChC,WAAO,qBAAqB,EAAE,UAAU,CAAC;AAAA,EAC3C;AAEA,WAAS,iBAAiB,GAAG;AAC3B,WAAO,gBAAgB,EAAE,UAAU,CAAC;AAAA,EACtC;AAEA,WAAS,oBAAoB,GAAG;AAC9B,WAAO,mBAAmB,EAAE,YAAY,CAAC;AAAA,EAC3C;AAEA,WAAS,eAAe,GAAG;AACzB,WAAO,cAAc,EAAE,YAAY,CAAC;AAAA,EACtC;AAEA,WAAS,gBAAgB,GAAG;AAC1B,WAAO,eAAe,EAAE,EAAE,YAAY,KAAK,GAAG;AAAA,EAChD;AAEA,WAAS,iBAAiB,GAAG;AAC3B,WAAO,IAAI,CAAC,EAAE,EAAE,YAAY,IAAI;AAAA,EAClC;AAEA,SAAO;AAAA,IACL,QAAQ,SAAS,WAAW;AAC1B,UAAI,IAAI,UAAU,aAAa,IAAI,OAAO;AAC1C,QAAE,WAAW,WAAW;AAAE,eAAO;AAAA,MAAW;AAC5C,aAAO;AAAA,IACT;AAAA,IACA,OAAO,SAAS,WAAW;AACzB,UAAI,IAAI,SAAS,aAAa,IAAI,KAAK;AACvC,QAAE,WAAW,WAAW;AAAE,eAAO;AAAA,MAAW;AAC5C,aAAO;AAAA,IACT;AAAA,IACA,WAAW,SAAS,WAAW;AAC7B,UAAI,IAAI,UAAU,aAAa,IAAI,UAAU;AAC7C,QAAE,WAAW,WAAW;AAAE,eAAO;AAAA,MAAW;AAC5C,aAAO;AAAA,IACT;AAAA,IACA,UAAU,SAAS,WAAW;AAC5B,UAAI,IAAI,SAAS,aAAa,IAAI,IAAI;AACtC,QAAE,WAAW,WAAW;AAAE,eAAO;AAAA,MAAW;AAC5C,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,IAAI,OAAO,EAAC,KAAK,IAAI,KAAK,KAAK,KAAK,IAAG;AAAvC,IACI,WAAW;AADf,IAEI,YAAY;AAFhB,IAGI,YAAY;AAEhB,SAAS,IAAIE,QAAO,MAAM,OAAO;AAC/B,MAAIC,QAAOD,SAAQ,IAAI,MAAM,IACzB,UAAUC,QAAO,CAACD,SAAQA,UAAS,IACnC,SAAS,OAAO;AACpB,SAAOC,SAAQ,SAAS,QAAQ,IAAI,MAAM,QAAQ,SAAS,CAAC,EAAE,KAAK,IAAI,IAAI,SAAS;AACtF;AAEA,SAAS,QAAQ,GAAG;AAClB,SAAO,EAAE,QAAQ,WAAW,MAAM;AACpC;AAEA,SAAS,SAAS,OAAO;AACvB,SAAO,IAAI,OAAO,SAAS,MAAM,IAAI,OAAO,EAAE,KAAK,GAAG,IAAI,KAAK,GAAG;AACpE;AAEA,SAAS,aAAa,OAAO;AAC3B,SAAO,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,MAAM,CAAC,KAAK,YAAY,GAAG,CAAC,CAAC,CAAC;AAChE;AAEA,SAAS,yBAAyB,GAAG,QAAQ,GAAG;AAC9C,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,SAAO,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAC9C;AAEA,SAAS,yBAAyB,GAAG,QAAQ,GAAG;AAC9C,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,SAAO,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAC9C;AAEA,SAAS,sBAAsB,GAAG,QAAQ,GAAG;AAC3C,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,SAAO,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAC9C;AAEA,SAAS,mBAAmB,GAAG,QAAQ,GAAG;AACxC,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,SAAO,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAC9C;AAEA,SAAS,sBAAsB,GAAG,QAAQ,GAAG;AAC3C,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,SAAO,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAC9C;AAEA,SAAS,cAAc,GAAG,QAAQ,GAAG;AACnC,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,SAAO,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAC9C;AAEA,SAAS,UAAU,GAAG,QAAQ,GAAG;AAC/B,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,SAAO,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,KAAK,OAAO,MAAO,IAAI,EAAE,CAAC,EAAE,UAAU;AAC3E;AAEA,SAAS,UAAU,GAAG,QAAQ,GAAG;AAC/B,MAAI,IAAI,+BAA+B,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAClE,SAAO,KAAK,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,QAAQ,IAAI,EAAE,CAAC,EAAE,UAAU;AAC5E;AAEA,SAAS,aAAa,GAAG,QAAQ,GAAG;AAClC,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,SAAO,KAAK,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AACrD;AAEA,SAAS,iBAAiB,GAAG,QAAQ,GAAG;AACtC,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,SAAO,KAAK,EAAE,IAAI,EAAE,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AACjD;AAEA,SAAS,gBAAgB,GAAG,QAAQ,GAAG;AACrC,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,SAAO,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAC9C;AAEA,SAAS,eAAe,GAAG,QAAQ,GAAG;AACpC,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,SAAO,KAAK,EAAE,IAAI,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AACvD;AAEA,SAAS,YAAY,GAAG,QAAQ,GAAG;AACjC,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,SAAO,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAC9C;AAEA,SAAS,aAAa,GAAG,QAAQ,GAAG;AAClC,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,SAAO,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAC9C;AAEA,SAAS,aAAa,GAAG,QAAQ,GAAG;AAClC,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,SAAO,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAC9C;AAEA,SAAS,kBAAkB,GAAG,QAAQ,GAAG;AACvC,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,SAAO,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAC9C;AAEA,SAAS,kBAAkB,GAAG,QAAQ,GAAG;AACvC,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC5C,SAAO,KAAK,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC,IAAI,GAAI,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAChE;AAEA,SAAS,oBAAoB,GAAG,QAAQ,GAAG;AACzC,MAAI,IAAI,UAAU,KAAK,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC;AAC7C,SAAO,IAAI,IAAI,EAAE,CAAC,EAAE,SAAS;AAC/B;AAEA,SAAS,mBAAmB,GAAG,QAAQ,GAAG;AACxC,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,CAAC,CAAC;AACrC,SAAO,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAC9C;AAEA,SAAS,0BAA0B,GAAG,QAAQ,GAAG;AAC/C,MAAI,IAAI,SAAS,KAAK,OAAO,MAAM,CAAC,CAAC;AACrC,SAAO,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU;AAC9C;AAEA,SAAS,iBAAiB,GAAG,GAAG;AAC9B,SAAO,IAAI,EAAE,QAAQ,GAAG,GAAG,CAAC;AAC9B;AAEA,SAAS,aAAa,GAAG,GAAG;AAC1B,SAAO,IAAI,EAAE,SAAS,GAAG,GAAG,CAAC;AAC/B;AAEA,SAAS,aAAa,GAAG,GAAG;AAC1B,SAAO,IAAI,EAAE,SAAS,IAAI,MAAM,IAAI,GAAG,CAAC;AAC1C;AAEA,SAAS,gBAAgB,GAAG,GAAG;AAC7B,SAAO,IAAI,IAAI,QAAQ,MAAM,SAAS,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AACpD;AAEA,SAAS,mBAAmB,GAAG,GAAG;AAChC,SAAO,IAAI,EAAE,gBAAgB,GAAG,GAAG,CAAC;AACtC;AAEA,SAAS,mBAAmB,GAAG,GAAG;AAChC,SAAO,mBAAmB,GAAG,CAAC,IAAI;AACpC;AAEA,SAAS,kBAAkB,GAAG,GAAG;AAC/B,SAAO,IAAI,EAAE,SAAS,IAAI,GAAG,GAAG,CAAC;AACnC;AAEA,SAAS,cAAc,GAAG,GAAG;AAC3B,SAAO,IAAI,EAAE,WAAW,GAAG,GAAG,CAAC;AACjC;AAEA,SAAS,cAAc,GAAG,GAAG;AAC3B,SAAO,IAAI,EAAE,WAAW,GAAG,GAAG,CAAC;AACjC;AAEA,SAAS,0BAA0B,GAAG;AACpC,MAAI,MAAM,EAAE,OAAO;AACnB,SAAO,QAAQ,IAAI,IAAI;AACzB;AAEA,SAAS,uBAAuB,GAAG,GAAG;AACpC,SAAO,IAAI,WAAW,MAAM,SAAS,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC;AACvD;AAEA,SAAS,KAAK,GAAG;AACf,MAAI,MAAM,EAAE,OAAO;AACnB,SAAQ,OAAO,KAAK,QAAQ,IAAK,aAAa,CAAC,IAAI,aAAa,KAAK,CAAC;AACxE;AAEA,SAAS,oBAAoB,GAAG,GAAG;AACjC,MAAI,KAAK,CAAC;AACV,SAAO,IAAI,aAAa,MAAM,SAAS,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,EAAE,OAAO,MAAM,IAAI,GAAG,CAAC;AACpF;AAEA,SAAS,0BAA0B,GAAG;AACpC,SAAO,EAAE,OAAO;AAClB;AAEA,SAAS,uBAAuB,GAAG,GAAG;AACpC,SAAO,IAAI,WAAW,MAAM,SAAS,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC;AACvD;AAEA,SAAS,WAAW,GAAG,GAAG;AACxB,SAAO,IAAI,EAAE,YAAY,IAAI,KAAK,GAAG,CAAC;AACxC;AAEA,SAAS,cAAc,GAAG,GAAG;AAC3B,MAAI,KAAK,CAAC;AACV,SAAO,IAAI,EAAE,YAAY,IAAI,KAAK,GAAG,CAAC;AACxC;AAEA,SAAS,eAAe,GAAG,GAAG;AAC5B,SAAO,IAAI,EAAE,YAAY,IAAI,KAAO,GAAG,CAAC;AAC1C;AAEA,SAAS,kBAAkB,GAAG,GAAG;AAC/B,MAAI,MAAM,EAAE,OAAO;AACnB,MAAK,OAAO,KAAK,QAAQ,IAAK,aAAa,CAAC,IAAI,aAAa,KAAK,CAAC;AACnE,SAAO,IAAI,EAAE,YAAY,IAAI,KAAO,GAAG,CAAC;AAC1C;AAEA,SAAS,WAAW,GAAG;AACrB,MAAI,IAAI,EAAE,kBAAkB;AAC5B,UAAQ,IAAI,IAAI,OAAO,KAAK,IAAI,QAC1B,IAAI,IAAI,KAAK,GAAG,KAAK,CAAC,IACtB,IAAI,IAAI,IAAI,KAAK,CAAC;AAC1B;AAEA,SAAS,oBAAoB,GAAG,GAAG;AACjC,SAAO,IAAI,EAAE,WAAW,GAAG,GAAG,CAAC;AACjC;AAEA,SAAS,gBAAgB,GAAG,GAAG;AAC7B,SAAO,IAAI,EAAE,YAAY,GAAG,GAAG,CAAC;AAClC;AAEA,SAAS,gBAAgB,GAAG,GAAG;AAC7B,SAAO,IAAI,EAAE,YAAY,IAAI,MAAM,IAAI,GAAG,CAAC;AAC7C;AAEA,SAAS,mBAAmB,GAAG,GAAG;AAChC,SAAO,IAAI,IAAI,OAAO,MAAM,QAAQ,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AAClD;AAEA,SAAS,sBAAsB,GAAG,GAAG;AACnC,SAAO,IAAI,EAAE,mBAAmB,GAAG,GAAG,CAAC;AACzC;AAEA,SAAS,sBAAsB,GAAG,GAAG;AACnC,SAAO,sBAAsB,GAAG,CAAC,IAAI;AACvC;AAEA,SAAS,qBAAqB,GAAG,GAAG;AAClC,SAAO,IAAI,EAAE,YAAY,IAAI,GAAG,GAAG,CAAC;AACtC;AAEA,SAAS,iBAAiB,GAAG,GAAG;AAC9B,SAAO,IAAI,EAAE,cAAc,GAAG,GAAG,CAAC;AACpC;AAEA,SAAS,iBAAiB,GAAG,GAAG;AAC9B,SAAO,IAAI,EAAE,cAAc,GAAG,GAAG,CAAC;AACpC;AAEA,SAAS,6BAA6B,GAAG;AACvC,MAAI,MAAM,EAAE,UAAU;AACtB,SAAO,QAAQ,IAAI,IAAI;AACzB;AAEA,SAAS,0BAA0B,GAAG,GAAG;AACvC,SAAO,IAAI,UAAU,MAAM,QAAQ,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC;AACrD;AAEA,SAAS,QAAQ,GAAG;AAClB,MAAI,MAAM,EAAE,UAAU;AACtB,SAAQ,OAAO,KAAK,QAAQ,IAAK,YAAY,CAAC,IAAI,YAAY,KAAK,CAAC;AACtE;AAEA,SAAS,uBAAuB,GAAG,GAAG;AACpC,MAAI,QAAQ,CAAC;AACb,SAAO,IAAI,YAAY,MAAM,QAAQ,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,EAAE,UAAU,MAAM,IAAI,GAAG,CAAC;AACpF;AAEA,SAAS,6BAA6B,GAAG;AACvC,SAAO,EAAE,UAAU;AACrB;AAEA,SAAS,0BAA0B,GAAG,GAAG;AACvC,SAAO,IAAI,UAAU,MAAM,QAAQ,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC;AACrD;AAEA,SAAS,cAAc,GAAG,GAAG;AAC3B,SAAO,IAAI,EAAE,eAAe,IAAI,KAAK,GAAG,CAAC;AAC3C;AAEA,SAAS,iBAAiB,GAAG,GAAG;AAC9B,MAAI,QAAQ,CAAC;AACb,SAAO,IAAI,EAAE,eAAe,IAAI,KAAK,GAAG,CAAC;AAC3C;AAEA,SAAS,kBAAkB,GAAG,GAAG;AAC/B,SAAO,IAAI,EAAE,eAAe,IAAI,KAAO,GAAG,CAAC;AAC7C;AAEA,SAAS,qBAAqB,GAAG,GAAG;AAClC,MAAI,MAAM,EAAE,UAAU;AACtB,MAAK,OAAO,KAAK,QAAQ,IAAK,YAAY,CAAC,IAAI,YAAY,KAAK,CAAC;AACjE,SAAO,IAAI,EAAE,eAAe,IAAI,KAAO,GAAG,CAAC;AAC7C;AAEA,SAAS,gBAAgB;AACvB,SAAO;AACT;AAEA,SAAS,uBAAuB;AAC9B,SAAO;AACT;AAEA,SAAS,oBAAoB,GAAG;AAC9B,SAAO,CAAC;AACV;AAEA,SAAS,2BAA2B,GAAG;AACrC,SAAO,KAAK,MAAM,CAAC,IAAI,GAAI;AAC7B;;;ACtrBA,IAAIC;AACG,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AAEXC,eAAc;AAAA,EACZ,UAAU;AAAA,EACV,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS,CAAC,MAAM,IAAI;AAAA,EACpB,MAAM,CAAC,UAAU,UAAU,WAAW,aAAa,YAAY,UAAU,UAAU;AAAA,EACnF,WAAW,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAAA,EAC3D,QAAQ,CAAC,WAAW,YAAY,SAAS,SAAS,OAAO,QAAQ,QAAQ,UAAU,aAAa,WAAW,YAAY,UAAU;AAAA,EACjI,aAAa,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAClG,CAAC;AAEc,SAARA,eAA+B,YAAY;AAChD,EAAAD,UAAS,aAAa,UAAU;AAChC,eAAaA,QAAO;AACpB,cAAYA,QAAO;AACnB,cAAYA,QAAO;AACnB,aAAWA,QAAO;AAClB,SAAOA;AACT;;;ACpBA,SAAS,KAAK,GAAG;AACf,SAAO,IAAI,KAAK,CAAC;AACnB;AAEA,SAASE,QAAO,GAAG;AACjB,SAAO,aAAa,OAAO,CAAC,IAAI,CAAC,oBAAI,KAAK,CAAC,CAAC;AAC9C;AAEO,SAAS,SAASC,QAAO,cAAc,MAAM,OAAO,MAAM,KAAK,MAAM,QAAQC,SAAQC,SAAQ;AAClG,MAAI,QAAQ,WAAW,GACnB,SAAS,MAAM,QACf,SAAS,MAAM;AAEnB,MAAI,oBAAoBA,QAAO,KAAK,GAChC,eAAeA,QAAO,KAAK,GAC3B,eAAeA,QAAO,OAAO,GAC7B,aAAaA,QAAO,OAAO,GAC3B,YAAYA,QAAO,OAAO,GAC1B,aAAaA,QAAO,OAAO,GAC3B,cAAcA,QAAO,IAAI,GACzBC,cAAaD,QAAO,IAAI;AAE5B,WAASE,YAAWC,OAAM;AACxB,YAAQJ,QAAOI,KAAI,IAAIA,QAAO,oBACxB,OAAOA,KAAI,IAAIA,QAAO,eACtB,KAAKA,KAAI,IAAIA,QAAO,eACpB,IAAIA,KAAI,IAAIA,QAAO,aACnB,MAAMA,KAAI,IAAIA,QAAQ,KAAKA,KAAI,IAAIA,QAAO,YAAY,aACtD,KAAKA,KAAI,IAAIA,QAAO,cACpBF,aAAYE,KAAI;AAAA,EACxB;AAEA,QAAM,SAAS,SAASC,IAAG;AACzB,WAAO,IAAI,KAAK,OAAOA,EAAC,CAAC;AAAA,EAC3B;AAEA,QAAM,SAAS,SAAS,GAAG;AACzB,WAAO,UAAU,SAAS,OAAO,MAAM,KAAK,GAAGP,OAAM,CAAC,IAAI,OAAO,EAAE,IAAI,IAAI;AAAA,EAC7E;AAEA,QAAM,QAAQ,SAAS,UAAU;AAC/B,QAAI,IAAI,OAAO;AACf,WAAOC,OAAM,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,GAAG,YAAY,OAAO,KAAK,QAAQ;AAAA,EACtE;AAEA,QAAM,aAAa,SAAS,OAAO,WAAW;AAC5C,WAAO,aAAa,OAAOI,cAAaF,QAAO,SAAS;AAAA,EAC1D;AAEA,QAAM,OAAO,SAAS,UAAU;AAC9B,QAAI,IAAI,OAAO;AACf,QAAI,CAAC,YAAY,OAAO,SAAS,UAAU,WAAY,YAAW,aAAa,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,GAAG,YAAY,OAAO,KAAK,QAAQ;AACtI,WAAO,WAAW,OAAO,KAAK,GAAG,QAAQ,CAAC,IAAI;AAAA,EAChD;AAEA,QAAM,OAAO,WAAW;AACtB,WAAO,KAAK,OAAO,SAASF,QAAO,cAAc,MAAM,OAAO,MAAM,KAAK,MAAM,QAAQC,SAAQC,OAAM,CAAC;AAAA,EACxG;AAEA,SAAO;AACT;AAEe,SAAR,OAAwB;AAC7B,SAAO,UAAU,MAAM,SAAS,WAAW,kBAAkB,UAAU,WAAW,YAAU,SAAS,UAAU,YAAY,QAAY,UAAU,EAAE,OAAO,CAAC,IAAI,KAAK,KAAM,GAAG,CAAC,GAAG,IAAI,KAAK,KAAM,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS;AACpN;;;ACjEe,SAAR,UAA2B;AAChC,SAAO,UAAU,MAAM,SAAS,UAAU,iBAAiB,SAAS,UAAU,WAAS,QAAQ,SAAS,WAAW,QAAW,SAAS,EAAE,OAAO,CAAC,KAAK,IAAI,KAAM,GAAG,CAAC,GAAG,KAAK,IAAI,KAAM,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS;AAC1M;;;ACCA,SAASK,eAAc;AACrB,MAAI,KAAK,GACL,KAAK,GACLC,KACAC,KACA,KACA,WACA,eAAe,UACf,QAAQ,OACR;AAEJ,WAAS,MAAMC,IAAG;AAChB,WAAOA,MAAK,QAAQ,MAAMA,KAAI,CAACA,EAAC,IAAI,UAAU,aAAa,QAAQ,IAAI,OAAOA,MAAK,UAAUA,EAAC,IAAIF,OAAM,KAAK,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGE,EAAC,CAAC,IAAIA,GAAE;AAAA,EACvJ;AAEA,QAAM,SAAS,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,CAAC,IAAI,EAAE,IAAI,GAAGF,MAAK,UAAU,KAAK,CAAC,EAAE,GAAGC,MAAK,UAAU,KAAK,CAAC,EAAE,GAAG,MAAMD,QAAOC,MAAK,IAAI,KAAKA,MAAKD,MAAK,SAAS,CAAC,IAAI,EAAE;AAAA,EACpJ;AAEA,QAAM,QAAQ,SAAS,GAAG;AACxB,WAAO,UAAU,UAAU,QAAQ,CAAC,CAAC,GAAG,SAAS;AAAA,EACnD;AAEA,QAAM,eAAe,SAAS,GAAG;AAC/B,WAAO,UAAU,UAAU,eAAe,GAAG,SAAS;AAAA,EACxD;AAEA,WAASG,OAAM,aAAa;AAC1B,WAAO,SAAS,GAAG;AACjB,UAAI,IAAI;AACR,aAAO,UAAU,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,eAAe,YAAY,IAAI,EAAE,GAAG,SAAS,CAAC,aAAa,CAAC,GAAG,aAAa,CAAC,CAAC;AAAA,IACzH;AAAA,EACF;AAEA,QAAM,QAAQA,OAAM,aAAW;AAE/B,QAAM,aAAaA,OAAM,aAAgB;AAEzC,QAAM,UAAU,SAAS,GAAG;AAC1B,WAAO,UAAU,UAAU,UAAU,GAAG,SAAS;AAAA,EACnD;AAEA,SAAO,SAAS,GAAG;AACjB,gBAAY,GAAGH,MAAK,EAAE,EAAE,GAAGC,MAAK,EAAE,EAAE,GAAG,MAAMD,QAAOC,MAAK,IAAI,KAAKA,MAAKD;AACvE,WAAO;AAAA,EACT;AACF;AAEO,SAASI,MAAK,QAAQ,QAAQ;AACnC,SAAO,OACF,OAAO,OAAO,OAAO,CAAC,EACtB,aAAa,OAAO,aAAa,CAAC,EAClC,MAAM,OAAO,MAAM,CAAC,EACpB,QAAQ,OAAO,QAAQ,CAAC;AAC/B;AAEe,SAAR,aAA8B;AACnC,MAAI,QAAQ,UAAUL,aAAY,EAAE,QAAQ,CAAC;AAE7C,QAAM,OAAO,WAAW;AACtB,WAAOK,MAAK,OAAO,WAAW,CAAC;AAAA,EACjC;AAEA,SAAO,iBAAiB,MAAM,OAAO,SAAS;AAChD;;;AC1CA,IAAMC,wBAAuB;AAC7B,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAO1B,SAASC,iBACPC,QACA,aACA,OAKoB;AACpB,UAAQ,aAAa;AAAA,IACnB,KAAK;AAAA,IACL,KAAK,WAAW;AACd,YAAM,IAAI,OAAOA,MAAK;AACtB,UAAI,eAAe,SAAS,OAAO,MAAM,cAAc,YAAY;AACjE,cAAM,KAAM,MAA4B,UAAU;AAClD,cAAM,MAAO,MAA4B,CAAC;AAC1C,YAAI,QAAQ,OAAW,QAAO;AAE9B,eAAO,KAAK,IAAI,MAAM,KAAK,IAAI;AAAA,MACjC;AACA,aAAQ,MAA6B,CAAC;AAAA,IACxC;AAAA,IACA,KAAK,YAAY;AACf,YAAM,KAAM,MAAoC,IAAI,KAAKA,MAAwB,CAAC;AAClF,aAAO,OAAO,MAAM,EAAE,IAAI,SAAY;AAAA,IACxC;AAAA,IACA,SAAS;AACP,YAAM,MAAM,OAAOA,MAAK;AACxB,UAAI,CAAC,OAAO,SAAS,GAAG,EAAG,QAAO;AAClC,aAAQ,MAAsC,GAAG;AAAA,IACnD;AAAA,EACF;AACF;AAcO,SAAS,oBACd,MACA,QACA,YACA,WACa;AACb,QAAM,WAAW,KAAK;AACtB,QAAM,WAAW,SAAS;AAC1B,QAAM,WAAW,SAAS;AAE1B,MAAI,CAAC,YAAY,CAAC,YAAY,CAAC,OAAO,KAAK,CAAC,OAAO,GAAG;AACpD,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,SAAS,OAAO,EAAE;AAKxB,QAAM,SAAS,OAAO,EAAE;AAKxB,QAAM,QAAQ,SAAS;AACvB,QAAM,QAAQ,SAAS;AAEvB,QAAM,WAAW,SAAS,SAAS,WAAW,SAAS,QAAQ,SAAS,QAAQ;AAChF,QAAM,oBAAoB,UAAU,SAAS;AAC7C,QAAM,aAAa,UAAU;AAC7B,QAAM,YAAY,SAAS,QAAQ,WAAW,SAAS,OAAO,SAAS,KAAK,QAAQ;AAGpF,MAAI;AACJ,MAAI,WAAW;AACb,UAAM,aAAa,KAAK,KAAK,IAAI,CAAC,MAAM,OAAO,EAAE,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAE9F,UAAM,UAAUC,KAAI,UAAU,KAAK;AACnC,UAAM,UAAUC,KAAI,UAAU,KAAK;AAEnC,gBAAYC,MAAU,EACnB,OAAO,CAAC,SAAS,OAAO,CAAC,EACzB,MAAM,CAAC,mBAAmB,iBAAiB,CAAC;AAAA,EACjD;AAEA,QAAM,QAAqB,CAAC;AAE5B,aAAW,OAAO,KAAK,MAAM;AAC3B,UAAM,OAAO,IAAI,SAAS,KAAK;AAC/B,UAAM,OAAO,IAAI,SAAS,KAAK;AAE/B,UAAM,KAAKJ,iBAAgB,MAAM,OAAO,MAAM;AAC9C,UAAM,KAAKA,iBAAgB,MAAM,OAAO,MAAM;AAE9C,QAAI,OAAO,UAAa,OAAO,OAAW;AAE1C,UAAM,WAAW,cAAc,CAAC,oBAAoB,OAAO,IAAI,UAAU,KAAK,EAAE,IAAI;AACpF,QAAIK;AACJ,QAAI,qBAAqB,YAAY;AACnC,YAAM,MAAM,OAAO,IAAI,UAAU,CAAC;AAClC,MAAAA,SAAQ,OAAO,SAAS,GAAG,IACvB,mBAAmB,QAAQ,GAAG,IAC9B,SAAS,QAAQ,aAAa;AAAA,IACpC,OAAO;AACL,MAAAA,SAAQ,SAAS,QAAQ,YAAY,aAAa;AAAA,IACpD;AAEA,QAAI,SAASN;AACb,QAAI,aAAa,WAAW;AAC1B,YAAM,UAAU,OAAO,IAAI,SAAS,CAAC;AACrC,UAAI,OAAO,SAAS,OAAO,GAAG;AAC5B,iBAAS,UAAU,OAAO;AAAA,MAC5B;AAAA,IACF;AAEA,UAAM,aAAa,CAAC,GAAG,SAAS,KAAK,IAAI,IAAI,IAAI,GAAG,SAAS,KAAK,IAAI,IAAI,EAAE;AAC5E,QAAI,SAAU,YAAW,KAAK,GAAG,UAAU,IAAI,QAAQ,EAAE;AACzD,QAAI,aAAa,IAAI,SAAS,KAAK,MAAM;AACvC,iBAAW,KAAK,GAAG,SAAS,IAAI,IAAI,SAAS,CAAC,EAAE;AAAA,IAClD;AAEA,UAAM,OAAiB;AAAA,MACrB,OAAO,eAAe,WAAW,KAAK,IAAI,CAAC;AAAA,IAC7C;AAEA,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,GAAG;AAAA,MACH,MAAMM;AAAA,MACN,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,aAAa;AAAA,MACb,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AC5KA,IAAM,kBAAkB;AACxB,IAAM,yBAAyB;AAC/B,IAAM,iBAAiB;AAUvB,SAAS,iBACP,QAC6C;AAC7C,QAAM,IAAI,OAAO;AACjB,MAAI,IAAI,EAAG,QAAO;AAElB,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,QAAQ;AACZ,MAAI,QAAQ;AAEZ,aAAW,KAAK,QAAQ;AACtB,YAAQ,EAAE;AACV,YAAQ,EAAE;AACV,aAAS,EAAE,IAAI,EAAE;AACjB,aAAS,EAAE,IAAI,EAAE;AAAA,EACnB;AAEA,QAAM,cAAc,IAAI,QAAQ,OAAO;AACvC,MAAI,gBAAgB,EAAG,QAAO;AAE9B,QAAM,SAAS,IAAI,QAAQ,OAAO,QAAQ;AAC1C,QAAM,aAAa,OAAO,QAAQ,QAAQ;AAE1C,SAAO,EAAE,OAAO,UAAU;AAC5B;AAYO,SAAS,iBAAiB,OAAqC;AACpE,MAAI,MAAM,SAAS,EAAG,QAAO;AAE7B,QAAM,SAAS,MAAM,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,EAAE,GAAG,EAAE;AACtD,QAAM,SAAS,iBAAiB,MAAM;AACtC,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,EAAE,OAAO,UAAU,IAAI;AAG7B,MAAI,OAAO;AACX,MAAI,OAAO;AACX,aAAW,KAAK,OAAO;AACrB,QAAI,EAAE,KAAK,KAAM,QAAO,EAAE;AAC1B,QAAI,EAAE,KAAK,KAAM,QAAO,EAAE;AAAA,EAC5B;AAGA,QAAM,KAAK,QAAQ,OAAO;AAC1B,QAAM,KAAK,QAAQ,OAAO;AAE1B,QAAM,OAAiB;AAAA,IACrB,OAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,GAAG,MAAM,GAAG,GAAG;AAAA,MACjB,EAAE,GAAG,MAAM,GAAG,GAAG;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,MAAM,CAAC;AAAA,IACP;AAAA,EACF;AACF;;;AC9EO,IAAM,kBAAiC,CAAC,MAAM,QAAQ,WAAW,UAAU,WAAW;AAC3F,QAAM,aAAa,oBAAoB,MAAM,QAAQ,WAAW,QAAQ;AACxE,QAAM,QAAgB,CAAC,GAAG,UAAU;AAGpC,QAAM,YAAY,iBAAiB,UAAU;AAC7C,MAAI,WAAW;AAEb,UAAM,QAAQ,SAAS;AAAA,EACzB;AAEA,SAAO;AACT;;;ACxBA,SAAS,0BAAAC,+BAA8B;AAUhC,SAAS,iBACd,MACA,QACkB;AAClB,QAAM,WAAW,KAAK;AACtB,QAAM,WAAW,SAAS;AAC1B,QAAM,WAAW,SAAS;AAC1B,QAAM,cAAc,SAAS;AAE7B,MAAI,CAAC,eAAe,EAAE,WAAW,aAAc,QAAO,CAAC;AAEvD,QAAM,QAA0B,CAAC;AACjC,QAAM,gBAAgB,SAAS,SAAS,WAAW,SAAS,QAAQ,SAAS,QAAQ;AACrF,QAAM,aAAa,eAAe;AAClC,QAAM,eAAe,SAAS,QAAQ,WAAW,SAAS,OAAO,SAAS,OAAO;AAEjF,aAAW,OAAO,KAAK,MAAM;AAE3B,QAAIC,KAAI;AACR,QAAI,YAAY,OAAO,GAAG;AACxB,YAAM,OAAO,WAAW,OAAO,EAAE,OAAO,OAAO,EAAE,MAAM,IAAI,SAAS,KAAK,CAAC;AAC1E,UAAI,QAAQ,KAAM;AAClB,MAAAA,KAAI;AAAA,IACN;AAGA,QAAIC,KAAI;AACR,QAAI,YAAY,OAAO,GAAG;AACxB,YAAM,OAAO,WAAW,OAAO,EAAE,OAAO,OAAO,EAAE,MAAM,IAAI,SAAS,KAAK,CAAC;AAC1E,UAAI,QAAQ,KAAM;AAClB,MAAAA,KAAI;AAAA,IACN;AAEA,UAAM,OAAO,OAAO,IAAI,YAAY,KAAK,KAAK,EAAE;AAChD,QAAI,CAAC,KAAM;AAEX,UAAMC,SAAQC;AAAA,MACZ,aACI,SAAS,QAAQ,OAAO,IAAI,UAAU,KAAK,aAAa,CAAC,IACzD,SAAS,QAAQ,aAAa;AAAA,IACpC;AAEA,UAAM,WAAW,eACb,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,IAAI,aAAa,KAAK,CAAC,KAAK,EAAE,CAAC,IAC/D;AAEJ,UAAM,OAAiB;AAAA,MACrB,OAAO;AAAA,IACT;AAEA,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,GAAAH;AAAA,MACA,GAAAC;AAAA,MACA;AAAA,MACA,MAAMC;AAAA,MACN;AAAA,MACA,YAAY;AAAA,MACZ,OACE,SAAS,SAAS,WAAW,SAAS,QAClC,OAAO,IAAI,SAAS,MAAM,KAAK,CAAC,KAAK,IACrC;AAAA,MACN,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAKO,IAAM,eAA8B,CAAC,MAAM,QAAQ,YAAY,WAAW,WAAW;AAC1F,SAAO,iBAAiB,MAAM,MAAM;AACtC;;;ACrFA,SAAS,0BAAAE,+BAA8B;AAQvC,IAAM,sBAAsB;AAUrB,SAAS,iBACd,MACA,QACA,YACkB;AAClB,QAAM,WAAW,KAAK;AACtB,QAAM,WAAW,SAAS;AAC1B,QAAM,WAAW,SAAS;AAE1B,MAAI,CAAC,YAAY,CAAC,YAAY,CAAC,OAAO,KAAK,CAAC,OAAO,EAAG,QAAO,CAAC;AAE9D,QAAM,gBAAgB,SAAS,SAAS,WAAW,SAAS,QAAQ,SAAS,QAAQ;AACrF,QAAM,aAAa,eAAe;AAClC,QAAM,QAA0B,CAAC;AAGjC,QAAM,eAAe,SAAS,SAAS,kBAAkB,SAAS,SAAS;AAC3E,QAAM,SAAoC,eAAe,eAAe;AAExE,aAAW,OAAO,KAAK,MAAM;AAC3B,UAAM,OAAO,WAAW,OAAO,EAAE,OAAO,OAAO,EAAE,MAAM,IAAI,SAAS,KAAK,CAAC;AAC1E,UAAM,OAAO,WAAW,OAAO,EAAE,OAAO,OAAO,EAAE,MAAM,IAAI,SAAS,KAAK,CAAC;AAC1E,QAAI,QAAQ,QAAQ,QAAQ,KAAM;AAElC,UAAMC,SAAQC;AAAA,MACZ,aACI,SAAS,QAAQ,OAAO,IAAI,UAAU,KAAK,aAAa,CAAC,IACzD,SAAS,QAAQ,aAAa;AAAA,IACpC;AAEA,UAAM,OAAiB;AAAA,MACrB,OAAO,GAAG,IAAI,SAAS,KAAK,CAAC,KAAK,IAAI,SAAS,KAAK,CAAC;AAAA,IACvD;AAEA,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,GAAG;AAAA,MACH,GAAG;AAAA,MACH,QAAQ;AAAA,MACR;AAAA,MACA,QAAQD;AAAA,MACR,aAAa;AAAA,MACb,SACE,SAAS,WAAW,WAAW,SAAS,UACpC,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,IAAI,SAAS,QAAQ,KAAK,CAAC,KAAK,CAAC,CAAC,IACjE;AAAA,MACN,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAKO,IAAM,eAA8B,CAAC,MAAM,QAAQ,WAAW,WAAW,WAAW;AACzF,SAAO,iBAAiB,MAAM,QAAQ,SAAS;AACjD;;;AClDA,IAAM,mBAAkD;AAAA,EACtD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,KAAK;AAAA;AAAA,EACL,gBAAgB;AAAA;AAAA,EAChB,OAAO;AAAA;AAAA,EACP,KAAK;AAAA;AAAA,EACL,aAAa;AAAA;AAAA,EACb,QAAQ;AAAA;AAAA,EACR,UAAU;AAAA;AAAA,EACV,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA;AACR;AAMO,SAAS,2BAAiC;AAC/C,aAAW,CAAC,MAAM,QAAQ,KAAK,OAAO,QAAQ,gBAAgB,GAAG;AAC/D,0BAAsB,MAAM,QAAQ;AAAA,EACtC;AACF;AAGA,yBAAyB;;;ACjClB,SAAS,qBAAqB,OAAe,QAAgC;AAElF,MAAI,OAAO,GAAG,SAAS,QAAQ;AAC7B,WAAO,wBAAwB,OAAO,MAAM;AAAA,EAC9C;AAGA,QAAM,YAAoB,CAAC;AAC3B,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,QAAQ;AACxB,YAAM,KAAK;AACX,gBAAU,KAAK,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,OAAO,GAAG,OAAO,QAAQ,GAAG,OAAO,CAAC;AAAA,IACzE,WAAW,KAAK,SAAS,SAAS;AAChC,YAAM,KAAK;AACX,gBAAU,KAAK;AAAA,QACb,GAAG,GAAG,KAAK,GAAG;AAAA,QACd,GAAG,GAAG,KAAK,GAAG;AAAA,QACd,OAAO,GAAG,IAAI;AAAA,QACd,QAAQ,GAAG,IAAI;AAAA,MACjB,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,wBAAwB,OAAe,QAAgC;AAC9E,QAAM,OAAO,oBAAI,IAA2D;AAE5E,aAAW,QAAQ,OAAO;AACxB,QAAI;AACJ,QAAIE;AACJ,QAAIC;AAEJ,QAAI,KAAK,SAAS,SAAS;AACzB,YAAM,KAAK;AACX,WAAK,GAAG;AACR,MAAAD,QAAO,GAAG,KAAK,GAAG;AAClB,MAAAC,SAAQ,GAAG,KAAK,GAAG;AAAA,IACrB,WAAW,KAAK,SAAS,QAAQ;AAC/B,YAAM,KAAK;AACX,WAAK,GAAG,IAAI,GAAG,SAAS;AACxB,MAAAD,QAAO,GAAG;AACV,MAAAC,SAAQ,GAAG,IAAI,GAAG;AAAA,IACpB,OAAO;AACL;AAAA,IACF;AAGA,UAAM,MAAM,KAAK,MAAM,EAAE;AACzB,UAAM,WAAW,KAAK,IAAI,GAAG;AAC7B,QAAI,UAAU;AACZ,eAAS,OAAO,KAAK,IAAI,SAAS,MAAMD,KAAI;AAC5C,eAAS,OAAO,KAAK,IAAI,SAAS,MAAMC,MAAK;AAAA,IAC/C,OAAO;AACL,WAAK,IAAI,KAAK,EAAE,MAAMD,OAAM,MAAMC,QAAO,OAAO,GAAG,CAAC;AAAA,IACtD;AAAA,EACF;AAGA,QAAM,YAAY,OAAO,EAAG;AAC5B,QAAM,YAAY,UAAU,YAAY,KAAK;AAC7C,MAAI,cAAc,EAAG,QAAO,CAAC;AAE7B,QAAM,YAAoB,CAAC;AAC3B,aAAW,EAAE,MAAM,MAAM,MAAM,KAAK,KAAK,OAAO,GAAG;AACjD,cAAU,KAAK;AAAA,MACb,GAAG;AAAA,MACH,GAAG,QAAQ,YAAY;AAAA,MACvB,OAAO,OAAO;AAAA,MACd,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAaO,SAAS,mBACd,UACA,UACA,SACQ;AACR,MAAI,aAAa,OAAO;AACtB,UAAM,QAAQ,SAAS,GAAG;AAC1B,UAAM,QAAQ,SAAS,GAAG;AAC1B,UAAM,cACH,UAAU,aAAa,UAAU,aAAa,UAAU,eACzD,UAAU;AACZ,QAAI,YAAY;AACd,aAAO;AAAA,IACT;AAAA,EACF,WAAW,aAAa,OAAO;AAC7B,UAAM,cAAc,QAAQ;AAC5B,QAAI,eAAe,cAAc,GAAG;AAClC,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAOA,SAAS,oBAAoB,MAAoB;AAC/C,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AACH,aAAO,KAAK;AAAA;AAAA,IACd,KAAK;AACH,aAAO,KAAK;AAAA;AAAA,IACd,KAAK;AACH,aAAO,KAAK,WAAW,KAAK;AAAA;AAAA,IAC9B,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAYO,SAAS,uBACd,OACA,WACM;AACN,MAAI,CAAC,WAAW,QAAS;AAIzB,MAAI,UAAU,iBAAiB,SAAS;AACtC,UAAM,UAAU,MAAM,IAAI,CAAC,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,EAAE;AACzD,YAAQ,KAAK,CAAC,GAAG,MAAM;AACrB,YAAM,KAAK,oBAAoB,EAAE,IAAI;AACrC,YAAM,KAAK,oBAAoB,EAAE,IAAI;AACrC,aAAO,KAAK;AAAA,IACd,CAAC;AACD,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,YAAM,IAAI,QAAQ,CAAC,EAAE;AACrB,UAAI,EAAE,SAAS,UAAW,EAAe,WAAY;AACrD,QAAE,iBAAiB;AAAA,IACrB;AAAA,EACF;AAMA,QAAM,gBAAgB,oBAAI,IAAoB;AAC9C,QAAM,gBAAgB,oBAAI,IAAoB;AAC9C,MAAI,iBAAiB;AACrB,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,UAAW,KAAkB,YAAY;AACzD,YAAM,OAAO;AACb,YAAM,QAAQ,KAAK;AACnB,UAAI,CAAC,cAAc,IAAI,KAAK,GAAG;AAC7B,sBAAc,IAAI,OAAO,gBAAgB;AAAA,MAC3C;AACA,WAAK,iBAAiB,cAAc,IAAI,KAAK;AAC7C,YAAM,MAAM,cAAc,IAAI,KAAK,KAAK;AACxC,WAAK,WAAW;AAChB,oBAAc,IAAI,OAAO,MAAM,CAAC;AAAA,IAClC;AAAA,EACF;AACF;;;ACxMO,SAAS,qBACd,QACA,UACA,OACM;AACN,MAAI,CAAC,OAAO,MAAO;AAEnB,QAAM,mBAAmB,CAAC,EACxB,SAAS,SACT,WAAW,SAAS,SACnB,SAAS,MAAM,OAAO,OAAgC;AAEzD,MAAI,iBAAkB;AAEtB,MAAI,OAAO,MAAM,SAAS,cAAc;AACtC,UAAM,WAAW,OAAO,OAAO,MAAM,OAAO,UAAU,EAAE,CAAC,KAAK,MAAM,OAAO;AAC3E,IAAC,OAAO,MAAM,MAAiD,MAAM;AAAA,MACnE,SAAS,CAAC;AAAA,MACV,SAAS,SAAS,SAAS,CAAC;AAAA,IAC9B,CAAC;AAAA,EACH,OAAO;AACL,IAAC,OAAO,MAAM,MAAuC,MAAM,MAAM,OAAO,WAAW;AAAA,EACrF;AACF;;;ACrBO,SAAS,qBAAqB,MAAiB,UAA+B;AACnF,MAAI,SAAS;AACb,aAAW,WAAW,CAAC,KAAK,GAAG,GAAY;AACzC,UAAM,MAAM,SAAS,OAAO;AAC5B,QAAI,CAAC,KAAK,OAAO,QAAQ,CAAC,IAAI,MAAM,OAAQ;AAC5C,UAAM,SAAS,IAAI,MAAM;AACzB,UAAM,QAAQ,IAAI;AAClB,QAAI,MAAM,QAAQ,MAAM,KAAK,OAAO,WAAW,KAAK,OAAO,OAAO,CAAC,MAAM,UAAU;AACjF,YAAM,CAAC,IAAI,EAAE,IAAI;AACjB,eAAS,OAAO,OAAO,CAAC,QAAQ;AAC9B,cAAM,IAAI,OAAO,IAAI,KAAK,CAAC;AAC3B,eAAO,OAAO,SAAS,CAAC,KAAK,KAAK,MAAM,KAAK;AAAA,MAC/C,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;;;ACtBA,SAAS,2BAA2B;AAKpC,IAAM,mBAAmB;AAGzB,IAAM,2BAA2B;AAGjC,IAAM,2BAA2B;AAU1B,SAAS,yBACd,MACA,WACA,MACA,OACa;AACb,MAAI,CAAC,UAAW,QAAO;AAEvB,QAAM,YAAY,KAAK;AACvB,QAAM,eAAe,MAAM,QAAQ;AACnC,QAAM,SAAS,KAAK,MAAM,QAAQ,eAAe;AACjD,QAAM,cAAc,KAAK,GAAG,QACxB,2BACA,KAAK,IACH,2BACA;AACN,QAAM,oBAAoB,KAAK,OAAO,UAAU,KAAK,OAAO,UAAU,KAAK,OAAO;AAClF,QAAM,SAAS,oBACX,UAAU,IAAI,UAAU,SAAS,cAAc,kBAAkB,IACjE,UAAU,IAAI,UAAU,SAAS,cAAc,MAAM,QAAQ;AAEjE,SAAO,EAAE,GAAG,QAAQ,GAAG,QAAQ,OAAO,qBAAqB,QAAQ,iBAAiB;AACtF;;;AClCA,IAAM,iBAAiB;AAAA,EACrB,UAAU;AAAA,EACV,MAAM;AAAA,EACN,cAAc;AAAA,EACd,cAAc;AAAA,EACd,iBAAiB;AACnB;AAGA,IAAM,uBAAuB;AAMtB,SAAS,iBAAiB,MAAgE;AAC/F,MAAI,SAAS,UAAa,SAAS,MAAO,QAAO;AAGjD,MAAI,SAAS,MAAM;AACjB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU,eAAe;AAAA,MACzB,MAAM,eAAe;AAAA,MACrB,cAAc,eAAe;AAAA,MAC7B,cAAc,eAAe;AAAA,MAC7B,iBAAiB,eAAe;AAAA,IAClC;AAAA,EACF;AAGA,QAAM,SAAS;AAGf,MAAI,OAAO,UAAU,SAAU,OAAO,UAAU,UAAa,CAAC,YAAY,MAAM,GAAI;AAClF,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,mBAAmB,OAAO,KAAK;AAEnD,SAAO;AAAA,IACL,SAAS;AAAA,IACT,UAAU,YAAY;AAAA,IACtB,MAAM,YAAY;AAAA,IAClB,cAAc,YAAY;AAAA,IAC1B,cAAc,YAAY;AAAA,IAC1B,iBAAiB,OAAO,mBAAmB,eAAe;AAAA,EAC5D;AACF;AAKO,SAAS,kBAAkB,OAAe,cAA8B;AAC7E,MAAI,gBAAgB,EAAG,QAAO;AAC9B,SAAO,KAAK,IAAI,OAAO,uBAAuB,YAAY;AAC5D;AAEA,SAAS,YAAY,QAAkC;AACrD,SAAO,OAAO,UAAU,UAAa,OAAO,WAAW,UAAa,OAAO,SAAS;AACtF;AASA,SAAS,mBAAmB,OAAkE;AAC5F,MAAI,UAAU,UAAa,UAAU,MAAM;AACzC,WAAO;AAAA,MACL,UAAU,eAAe;AAAA,MACzB,MAAM,eAAe;AAAA,MACrB,cAAc,eAAe;AAAA,MAC7B,cAAc,eAAe;AAAA,IAC/B;AAAA,EACF;AAEA,QAAM,MAAM;AACZ,QAAM,UAAU,eAAe,IAAI,OAAO;AAE1C,SAAO;AAAA,IACL,UAAU,IAAI,YAAY,eAAe;AAAA,IACzC,MAAM,IAAI,QAAQ,eAAe;AAAA,IACjC,cAAc,QAAQ;AAAA,IACtB,cAAc,QAAQ;AAAA,EACxB;AACF;AAEA,SAAS,eAAe,SAGtB;AACA,MAAI,YAAY,MAAO,QAAO,EAAE,OAAO,GAAG,OAAO,QAAQ;AACzD,MAAI,YAAY,UAAa,YAAY,MAAM;AAC7C,WAAO,EAAE,OAAO,eAAe,cAAc,OAAO,eAAe,aAAa;AAAA,EAClF;AACA,SAAO;AAAA,IACL,OAAO,QAAQ,SAAS,eAAe;AAAA,IACvC,OAAO,QAAQ,SAAS,eAAe;AAAA,EACzC;AACF;;;ACjGA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAeP,SAAS,qBAAqBC,QAAgE;AAC5F,MAAIA,WAAU,OAAW,QAAO;AAChC,MAAI,OAAOA,WAAU,SAAU,QAAO,EAAE,MAAMA,OAAM;AACpD,SAAOA;AACT;AAGA,SAAS,gBAAgB,QAA8C;AACrE,MAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,SAAO;AAAA,IACL,OAAO,qBAAqB,OAAO,KAAK;AAAA,IACxC,UAAU,qBAAqB,OAAO,QAAQ;AAAA,IAC9C,QAAQ,qBAAqB,OAAO,MAAM;AAAA,IAC1C,QAAQ,qBAAqB,OAAO,MAAM;AAAA,IAC1C,QAAQ,qBAAqB,OAAO,MAAM;AAAA,EAC5C;AACF;AAOA,SAAS,eAAe,MAAiB,OAA0B;AAEjE,QAAM,aAAa,KAAK,IAAI,IAAI,KAAK,MAAM;AAC3C,MAAI,eAAe;AACnB,MAAI,YAAY;AAChB,MAAI,eAAe;AAEnB,WAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,UAAMA,SAAQ,KAAK,CAAC,EAAE,KAAK;AAC3B,QAAIA,UAAS,KAAM;AACnB;AAGA,QAAI,OAAOA,WAAU,YAAY,OAAO,SAASA,MAAK,GAAG;AACvD;AACA;AAAA,IACF;AAGA,QAAI,OAAOA,WAAU,UAAU;AAE7B,YAAM,MAAM,OAAOA,MAAK;AACxB,UAAI,CAAC,OAAO,MAAM,GAAG,KAAK,OAAO,SAAS,GAAG,KAAKA,OAAM,KAAK,MAAM,IAAI;AACrE;AACA;AAAA,MACF;AAGA,YAAMC,QAAO,IAAI,KAAKD,MAAK;AAC3B,UAAI,CAAC,OAAO,MAAMC,MAAK,QAAQ,CAAC,GAAG;AACjC;AACA;AAAA,MACF;AAAA,IACF;AAEA,QAAID,kBAAiB,QAAQ,CAAC,OAAO,MAAMA,OAAM,QAAQ,CAAC,GAAG;AAC3D;AAAA,IACF;AAAA,EACF;AAEA,MAAI,iBAAiB,EAAG,QAAO;AAG/B,MAAI,YAAY,eAAe,IAAK,QAAO;AAE3C,MAAI,eAAe,eAAe,IAAK,QAAO;AAE9C,SAAO;AACT;AAGA,SAAS,mBAAmB,UAAoB,MAAiB,UAA8B;AAC7F,QAAM,SAAS,EAAE,GAAG,SAAS;AAE7B,aAAW,WAAW,CAAC,KAAK,KAAK,SAAS,QAAQ,QAAQ,GAAY;AACpE,UAAM,OAAO,OAAO,OAAO;AAC3B,QAAI,CAAC,KAAM;AAGX,QAAI,eAAe,KAAM;AAEzB,QAAI,CAAC,KAAK,MAAM;AACd,YAAM,WAAW,eAAe,MAAM,KAAK,KAAK;AAChD,MAAC,OAAmC,OAAO,IAAI,EAAE,GAAG,MAAM,MAAM,SAAS;AACzE,eAAS;AAAA,QACP,qBAAqB,OAAO,aAAa,QAAQ,iCAAiC,KAAK,KAAK;AAAA,MAC9F;AAAA,IACF,OAAO;AAEL,YAAM,aAAa,eAAe,MAAM,KAAK,KAAK;AAClD,UAAI,KAAK,SAAS,aAAa,eAAe,YAAY;AACxD,iBAAS,KAAK,UAAU,KAAK,KAAK,8CAA8C;AAAA,MAClF;AACA,UAAI,KAAK,SAAS,aAAa,eAAe,gBAAgB;AAC5D,iBAAS,KAAK,UAAU,KAAK,KAAK,kDAAkD;AAAA,MACtF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAOA,SAAS,qBAAqB,aAAqD;AACjF,MAAI,CAAC,eAAe,YAAY,WAAW,EAAG,QAAO,CAAC;AAEtD,SAAO,YAAY,IAAI,CAAC,QAAQ;AAC9B,YAAQ,IAAI,MAAM;AAAA,MAChB,KAAK;AACH,eAAO;AAAA,UACL,GAAG;AAAA,UACH,UAAU,IAAI,YAAY;AAAA,UAC1B,YAAY,IAAI,cAAc;AAAA,UAC9B,SAAS,IAAI,WAAW;AAAA,QAC1B;AAAA,MACF,KAAK;AACH,eAAO;AAAA,UACL,GAAG;AAAA,UACH,SAAS,IAAI,WAAW;AAAA,UACxB,MAAM,IAAI,QAAQ;AAAA,QACpB;AAAA,MACF,KAAK;AACH,eAAO;AAAA,UACL,GAAG;AAAA,UACH,OAAO,IAAI,SAAS;AAAA,UACpB,aAAa,IAAI,eAAe;AAAA,UAChC,QAAQ,IAAI,UAAU;AAAA,UACtB,SAAS,IAAI,WAAW;AAAA,QAC1B;AAAA,MACF;AACE,eAAO;AAAA,IACX;AAAA,EACF,CAAC;AACH;AAMA,SAAS,mBAAmB,MAAiB,UAAyC;AACpF,QAAM,WAAW,mBAAmB,KAAK,UAAU,KAAK,MAAM,QAAQ;AACtE,QAAM,WAAW,gBAAgB,KAAK,IAAI;AAC1C,QAAM,UAAU,eAAe,KAAK,IAAI;AAExC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM,KAAK;AAAA,IACX;AAAA,IACA,QAAQ,gBAAgB,KAAK,MAAM;AAAA,IACnC,aAAa,qBAAqB,KAAK,WAAW;AAAA,IAClD,QAAQ;AAAA,MACN,SAAS,KAAK,QAAQ,WAAW;AAAA,MACjC,QAAQ,KAAK,QAAQ,UAAU;AAAA,MAC/B,QAAQ,KAAK,QAAQ,UAAU;AAAA,MAC/B,SAAS,KAAK,QAAQ;AAAA,IACxB;AAAA,IACA,QAAQ,KAAK;AAAA,IACb,YAAY,KAAK,cAAc;AAAA,IAC/B,OAAO,KAAK,SAAS,CAAC;AAAA,IACtB,UAAU,KAAK,YAAY;AAAA,IAC3B,cAAc,KAAK,gBAAgB,CAAC;AAAA,IACpC,cAAc,KAAK,gBAAgB,CAAC;AAAA,IACpC,WAAW,KAAK,aAAa;AAAA,EAC/B;AACF;AAEA,SAAS,mBAAmB,MAAiB,WAA0C;AACrF,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM,KAAK;AAAA,IACX,SAAS,KAAK;AAAA,IACd,QAAQ,KAAK;AAAA,IACb,QAAQ,gBAAgB,KAAK,MAAM;AAAA,IACnC,OAAO,KAAK,SAAS,CAAC;AAAA,IACtB,UAAU,KAAK,YAAY;AAAA,IAC3B,QAAQ,KAAK,UAAU;AAAA,IACvB,YAAY,KAAK,cAAc;AAAA,IAC/B,mBAAmB,KAAK,qBAAqB;AAAA,IAC7C,SAAS,KAAK,WAAW;AAAA,IACzB,YAAY,KAAK,cAAc;AAAA,IAC/B,WAAW,KAAK;AAAA,IAChB,WAAW,KAAK,aAAa;AAAA,EAC/B;AACF;AAEA,SAAS,oBAAoB,MAAkB,WAA2C;AACxF,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM,KAAK;AAAA,IACX,UAAU,KAAK;AAAA,IACf,WAAW,KAAK,aAAa;AAAA,IAC7B,aAAa,KAAK,eAAe;AAAA,IACjC,WAAW,KAAK,aAAa;AAAA,IAC7B,YAAY,KAAK,cAAc;AAAA,IAC/B,WAAW,KAAK,aAAa;AAAA,IAC7B,gBAAgB,KAAK,kBAAkB;AAAA,IACvC,UAAU,KAAK;AAAA,IACf,QAAQ,gBAAgB,KAAK,MAAM;AAAA,IACnC,QAAQ,KAAK;AAAA,IACb,OAAO,KAAK,SAAS,CAAC;AAAA,IACtB,UAAU,KAAK,YAAY;AAAA,IAC3B,WAAW,KAAK;AAAA,IAChB,aAAa,KAAK;AAAA,IAClB,aAAa,KAAK;AAAA,IAClB,WAAW,KAAK,aAAa;AAAA,EAC/B;AACF;AAEA,SAAS,mBAAmB,MAAiB,WAA0C;AAErF,QAAM,gBAAgB;AAAA,IACpB,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,cAAc;AAAA,EAChB;AACA,QAAM,SAAS,KAAK,SAChB;AAAA,IACE,GAAG;AAAA,IACH,GAAG,KAAK;AAAA,EACV,IACA;AAEJ,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO,KAAK;AAAA,IACZ,OAAO,KAAK;AAAA,IACZ,UAAU,KAAK,YAAY,CAAC;AAAA,IAC5B;AAAA,IACA,eAAe,KAAK;AAAA,IACpB,QAAQ,gBAAgB,KAAK,MAAM;AAAA,IACnC,aAAa,qBAAqB,KAAK,WAAW;AAAA,IAClD,OAAO,KAAK,SAAS,CAAC;AAAA,IACtB,UAAU,KAAK,YAAY;AAAA,IAC3B,WAAW,KAAK,aAAa;AAAA,EAC/B;AACF;AAaO,SAAS,cAAc,MAAe,WAAqB,CAAC,GAAmB;AACpF,MAAI,YAAY,IAAI,GAAG;AAIrB,UAAM,SAAS,cAAc,IAAI;AACjC,QAAI,OAAO,WAAW,GAAG;AACvB,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AACA,WAAO,mBAAmB,OAAO,CAAC,GAAG,QAAQ;AAAA,EAC/C;AACA,MAAI,YAAY,IAAI,GAAG;AACrB,WAAO,mBAAmB,MAAM,QAAQ;AAAA,EAC1C;AACA,MAAI,YAAY,IAAI,GAAG;AACrB,WAAO,mBAAmB,MAAM,QAAQ;AAAA,EAC1C;AACA,MAAI,YAAY,IAAI,GAAG;AACrB,WAAO,mBAAmB,MAAM,QAAQ;AAAA,EAC1C;AACA,MAAI,aAAa,IAAI,GAAG;AACtB,WAAO,oBAAoB,MAAM,QAAQ;AAAA,EAC3C;AAEA,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAUO,SAAS,cACd,MACA,YACA,gBACA,kBACA,iBACa;AACb,QAAM,eAAe,KAAK,QAAQ;AAClC,QAAM,mBACJ,kBAAkB,KAAK,WACnB,EAAE,GAAG,gBAAgB,GAAG,KAAK,SAAS,IACrC,KAAK,YAAY;AACxB,QAAM,qBAAqB,CAAC,GAAI,oBAAoB,CAAC,GAAI,GAAI,KAAK,aAAa,CAAC,CAAE;AAElF,QAAM,oBAAoB,KAAK,aAAa;AAE5C,QAAM,SAAsB,CAAC;AAE7B,aAAW,SAAS,KAAK,OAAO;AAC9B,QAAI,YAAY,KAAK,GAAG;AAEtB,aAAO;AAAA,QACL,GAAG;AAAA,UACD;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,OAAO;AAEL,YAAM,aAAa,MAAM,QAAQ,gBAAgB,CAAC;AAClD,YAAM,iBAAiB,mBACnB,EAAE,GAAG,kBAAkB,GAAG,MAAM,SAAS,IACzC,MAAM;AACV,YAAM,mBAAmB,CAAC,GAAG,oBAAoB,GAAI,MAAM,aAAa,CAAC,CAAE;AAE3E,aAAO,KAAK;AAAA,QACV,GAAG;AAAA,QACH,MAAM;AAAA,QACN,UAAU;AAAA,QACV,WAAW,iBAAiB,SAAS,IAAI,mBAAmB;AAAA;AAAA,QAE5D,GAAI,MAAM,cAAc,UAAa,sBAAsB,SACvD,EAAE,WAAW,kBAAkB,IAC/B,CAAC;AAAA,MACP,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;;;AC7XA;AAAA,EAEE;AAAA,EACA;AAAA,OAGK;AAQP,IAAM,oBAAoB,oBAAI,IAAY,CAAC,gBAAgB,YAAY,WAAW,SAAS,CAAC;AAE5F,IAAM,mBAAmB,oBAAI,IAAY,CAAC,QAAQ,SAAS,KAAK,CAAC;AAGjE,SAAS,gBAAgBE,QAAyB;AAChD,MAAIA,kBAAiB,KAAM,QAAO,CAAC,OAAO,MAAMA,OAAM,QAAQ,CAAC;AAC/D,MAAI,OAAOA,WAAU,UAAU;AAC7B,UAAM,IAAI,IAAI,KAAKA,MAAK;AACxB,WAAO,CAAC,OAAO,MAAM,EAAE,QAAQ,CAAC;AAAA,EAClC;AACA,MAAI,OAAOA,WAAU,SAAU,QAAO;AACtC,SAAO;AACT;AAGA,SAAS,UAAUA,QAAyB;AAC1C,MAAI,OAAOA,WAAU,SAAU,QAAO,OAAO,SAASA,MAAK;AAC3D,MAAI,OAAOA,WAAU,UAAU;AAC7B,UAAM,IAAI,OAAOA,MAAK;AACtB,WAAO,CAAC,OAAO,MAAM,CAAC,KAAK,OAAO,SAAS,CAAC;AAAA,EAC9C;AACA,SAAO;AACT;AAMA,SAAS,kBAAkB,MAA+B,QAAiC;AACzF,QAAM,WACJ,OAAO,KAAK,SAAS,WAAW,KAAK,OAAQ,KAAK,MAAkC;AAGtF,MAAI,CAAC,MAAM,QAAQ,KAAK,IAAI,GAAG;AAC7B,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YAAY;AAAA,IACd,CAAC;AACD;AAAA,EACF;AAEA,MAAI,KAAK,KAAK,WAAW,GAAG;AAC1B,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YAAY;AAAA,IACd,CAAC;AACD;AAAA,EACF;AAGA,QAAM,WAAW,KAAK,KAAK,CAAC;AAC5B,MAAI,OAAO,aAAa,YAAY,aAAa,QAAQ,MAAM,QAAQ,QAAQ,GAAG;AAChF,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YACE;AAAA,IACJ,CAAC;AACD;AAAA,EACF;AAGA,MAAI,CAAC,KAAK,YAAY,OAAO,KAAK,aAAa,UAAU;AACvD,UAAMC,SAAQ,oBAAoB,QAAoB;AACtD,UAAM,mBAAmB,OAAO,QAAQA,MAAK,EAC1C,OAAO,CAAC,CAAC,EAAE,IAAI,MAAM,KAAK,QAAQ,EAClC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE;AACnB,WAAO,KAAK;AAAA,MACV,SAAS,eAAe,QAAQ;AAAA,MAChC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YAAY,kDAAkD,iBAAiB,KAAK,IAAI,CAAC,0BAA0B,iBAAiB,IAAI,CAAC,OAAO,GAAG,EAAE,iCAAiC,EAAE,KAAK,IAAI,CAAC;AAAA,IACpM,CAAC;AACD;AAAA,EACF;AAEA,QAAM,QAAQ,oBAAoB,QAAoB;AACtD,QAAM,WAAW,KAAK;AACtB,QAAM,cAAc,IAAI,IAAI,OAAO,KAAK,QAAmC,CAAC;AAC5E,QAAM,mBAAmB,CAAC,GAAG,WAAW,EAAE,KAAK,IAAI;AAGnD,aAAW,CAAC,SAAS,IAAI,KAAK,OAAO,QAAQ,KAAK,GAAG;AACnD,QAAI,KAAK,YAAY,CAAC,SAAS,OAAO,GAAG;AACvC,YAAM,eAAe,KAAK,aAAa,KAAK,MAAM;AAClD,aAAO,KAAK;AAAA,QACV,SAAS,eAAe,QAAQ,4BAA4B,OAAO;AAAA,QACnE,MAAM,YAAY,OAAO;AAAA,QACzB,MAAM;AAAA,QACN,YAAY,gBAAgB,OAAO,iCAAiC,gBAAgB,eAAe,YAAY,eAAe,OAAO,eAAe,CAAC,GAAG,WAAW,EAAE,CAAC,KAAK,SAAS,aAAa,KAAK,aAAa,CAAC,CAAC;AAAA,MACvN,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,kBAAkB,oBAAI,IAAY;AACxC,MAAI,MAAM,QAAQ,KAAK,SAAS,GAAG;AACjC,eAAW,KAAK,KAAK,WAAwC;AAC3D,UAAI,OAAO,EAAE,OAAO,SAAU,iBAAgB,IAAI,EAAE,EAAE;AACtD,UAAI,MAAM,QAAQ,EAAE,EAAE,GAAG;AACvB,mBAAW,KAAK,EAAE,IAAI;AACpB,cAAI,OAAO,MAAM,SAAU,iBAAgB,IAAI,CAAC;AAAA,QAClD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,aAAW,CAAC,SAAS,WAAW,KAAK,OAAO,QAAQ,QAAQ,GAAG;AAC7D,QAAI,CAAC,eAAe,OAAO,gBAAgB,SAAU;AAGrD,QAAI,YAAY,aAAa,MAAM,QAAQ,WAAW,GAAG;AACvD,eAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;AAC3C,cAAM,OAAO,YAAY,CAAC;AAC1B,YAAI,CAAC,QAAQ,OAAO,SAAS,SAAU;AACvC,YAAI,CAAC,KAAK,SAAS,OAAO,KAAK,UAAU,UAAU;AACjD,iBAAO,KAAK;AAAA,YACV,SAAS,gCAAgC,CAAC;AAAA,YAC1C,MAAM,oBAAoB,CAAC;AAAA,YAC3B,MAAM;AAAA,YACN,YAAY,4CAA4C,gBAAgB;AAAA,UAC1E,CAAC;AACD;AAAA,QACF;AACA,YAAI,CAAC,YAAY,IAAI,KAAK,KAAK,KAAK,CAAC,gBAAgB,IAAI,KAAK,KAAK,GAAG;AACpE,iBAAO,KAAK;AAAA,YACV,SAAS,gCAAgC,CAAC,YAAY,KAAK,KAAK,gDAAgD,gBAAgB;AAAA,YAChI,MAAM,oBAAoB,CAAC;AAAA,YAC3B,MAAM;AAAA,YACN,YAAY,0CAA0C,gBAAgB;AAAA,UACxE,CAAC;AAAA,QACH;AACA,YAAI,KAAK,QAAQ,CAAC,kBAAkB,IAAI,KAAK,IAAc,GAAG;AAC5D,iBAAO,KAAK;AAAA,YACV,SAAS,gCAAgC,CAAC,WAAW,KAAK,IAAI,mCAAmC,CAAC,GAAG,iBAAiB,EAAE,KAAK,IAAI,CAAC;AAAA,YAClI,MAAM,oBAAoB,CAAC;AAAA,YAC3B,MAAM;AAAA,YACN,YAAY,eAAe,CAAC,GAAG,iBAAiB,EAAE,KAAK,IAAI,CAAC;AAAA,UAC9D,CAAC;AAAA,QACH;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,aAAa;AACnB,UAAM,cAAc,MAAM,OAA6B;AAGvD,QAAI,eAAe,WAAY;AAG/B,QAAI,CAAC,WAAW,SAAS,OAAO,WAAW,UAAU,UAAU;AAC7D,aAAO,KAAK;AAAA,QACV,SAAS,wBAAwB,OAAO;AAAA,QACxC,MAAM,YAAY,OAAO;AAAA,QACzB,MAAM;AAAA,QACN,YAAY,yGAAyG,OAAO,6CAA6C,gBAAgB;AAAA,MAC3L,CAAC;AACD;AAAA,IACF;AAGA,QAAI,CAAC,YAAY,IAAI,WAAW,KAAK,KAAK,CAAC,gBAAgB,IAAI,WAAW,KAAK,GAAG;AAChF,aAAO,KAAK;AAAA,QACV,SAAS,wBAAwB,OAAO,WAAW,WAAW,KAAK,gDAAgD,gBAAgB;AAAA,QACnI,MAAM,YAAY,OAAO;AAAA,QACzB,MAAM;AAAA,QACN,YAAY,0CAA0C,gBAAgB;AAAA,MACxE,CAAC;AAAA,IACH;AAGA,QAAI,WAAW,QAAQ,CAAC,kBAAkB,IAAI,WAAW,IAAc,GAAG;AACxE,aAAO,KAAK;AAAA,QACV,SAAS,wBAAwB,OAAO,UAAU,WAAW,IAAI,mCAAmC,CAAC,GAAG,iBAAiB,EAAE,KAAK,IAAI,CAAC;AAAA,QACrI,MAAM,YAAY,OAAO;AAAA,QACzB,MAAM;AAAA,QACN,YAAY,eAAe,CAAC,GAAG,iBAAiB,EAAE,KAAK,IAAI,CAAC;AAAA,MAC9D,CAAC;AAAA,IACH;AAGA,QAAI,eAAe,WAAW,QAAQ,YAAY,aAAa,SAAS,GAAG;AACzE,UAAI,CAAC,YAAY,aAAa,SAAS,WAAW,IAAiB,GAAG;AACpE,eAAO,KAAK;AAAA,UACV,SAAS,wBAAwB,OAAO,QAAQ,QAAQ,gCAAgC,WAAW,IAAI,qBAAqB,YAAY,aAAa,KAAK,IAAI,CAAC;AAAA,UAC/J,MAAM,YAAY,OAAO;AAAA,UACzB,MAAM;AAAA,UACN,YAAY,mBAAmB,OAAO,oBAAoB,YAAY,aAAa,KAAK,IAAI,CAAC;AAAA,QAC/F,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,WAAW,QAAQ,WAAW,SAAS,YAAY,IAAI,WAAW,KAAe,GAAG;AACtF,YAAM,OAAO,KAAK;AAClB,YAAM,YAAY,WAAW;AAC7B,YAAM,YAAY,WAAW;AAE7B,YAAM,aAAa,KAAK,IAAI,GAAG,KAAK,MAAM;AAE1C,UAAI,cAAc,YAAY;AAC5B,YAAI,eAAe;AACnB,iBAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,gBAAM,MAAM,KAAK,CAAC,EAAE,SAAS;AAC7B,cAAI,OAAO,QAAQ,CAAC,gBAAgB,GAAG,GAAG;AACxC;AAAA,UACF;AAAA,QACF;AACA,YAAI,eAAe,GAAG;AACpB,iBAAO,KAAK;AAAA,YACV,SAAS,wBAAwB,OAAO,WAAW,SAAS;AAAA,YAC5D,MAAM,YAAY,OAAO;AAAA,YACzB,MAAM;AAAA,YACN,YAAY,kDAAkD,SAAS;AAAA,UACzE,CAAC;AAAA,QACH;AAAA,MACF;AAEA,UAAI,cAAc,gBAAgB;AAChC,YAAI,kBAAkB;AACtB,iBAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,gBAAM,MAAM,KAAK,CAAC,EAAE,SAAS;AAC7B,cAAI,OAAO,QAAQ,CAAC,UAAU,GAAG,GAAG;AAClC;AAAA,UACF;AAAA,QACF;AACA,YAAI,kBAAkB,GAAG;AACvB,iBAAO,KAAK;AAAA,YACV,SAAS,wBAAwB,OAAO,WAAW,SAAS;AAAA,YAC5D,MAAM,YAAY,OAAO;AAAA,YACzB,MAAM;AAAA,YACN,YAAY,kDAAkD,SAAS;AAAA,UACzE,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,KAAK,aAAa,UAAa,CAAC,iBAAiB,IAAI,KAAK,QAAkB,GAAG;AACjF,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YACE;AAAA,IACJ,CAAC;AAAA,EACH;AACF;AAMA,SAAS,kBAAkB,MAA+B,QAAiC;AACzF,MAAI,CAAC,MAAM,QAAQ,KAAK,IAAI,GAAG;AAC7B,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YAAY;AAAA,IACd,CAAC;AACD;AAAA,EACF;AAEA,MAAI,KAAK,KAAK,WAAW,GAAG;AAC1B,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YAAY;AAAA,IACd,CAAC;AACD;AAAA,EACF;AAEA,MAAI,CAAC,MAAM,QAAQ,KAAK,OAAO,GAAG;AAChC,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YACE;AAAA,IACJ,CAAC;AACD;AAAA,EACF;AAEA,QAAM,OAAO,KAAK;AAClB,QAAM,WAAW,KAAK,CAAC;AACvB,MAAI,OAAO,aAAa,YAAY,aAAa,QAAQ,MAAM,QAAQ,QAAQ,GAAG;AAChF,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YACE;AAAA,IACJ,CAAC;AACD;AAAA,EACF;AAEA,QAAM,cAAc,IAAI,IAAI,OAAO,KAAK,QAAmC,CAAC;AAC5E,QAAM,mBAAmB,CAAC,GAAG,WAAW,EAAE,KAAK,IAAI;AACnD,QAAM,UAAU,KAAK;AAErB,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,MAAM,QAAQ,CAAC;AACrB,QAAI,CAAC,OAAO,OAAO,QAAQ,UAAU;AACnC,aAAO,KAAK;AAAA,QACV,SAAS,uBAAuB,CAAC;AAAA,QACjC,MAAM,WAAW,CAAC;AAAA,QAClB,MAAM;AAAA,QACN,YAAY;AAAA,MACd,CAAC;AACD;AAAA,IACF;AAGA,QAAI,CAAC,IAAI,OAAO,OAAO,IAAI,QAAQ,UAAU;AAC3C,aAAO,KAAK;AAAA,QACV,SAAS,uBAAuB,CAAC;AAAA,QACjC,MAAM,WAAW,CAAC;AAAA,QAClB,MAAM;AAAA,QACN,YAAY,0DAA0D,gBAAgB;AAAA,MACxF,CAAC;AACD;AAAA,IACF;AAGA,QAAI,CAAC,YAAY,IAAI,IAAI,GAAa,GAAG;AACvC,aAAO,KAAK;AAAA,QACV,SAAS,uBAAuB,CAAC,UAAU,IAAI,GAAG,gDAAgD,gBAAgB;AAAA,QAClH,MAAM,WAAW,CAAC;AAAA,QAClB,MAAM;AAAA,QACN,YAAY,0CAA0C,gBAAgB;AAAA,MACxE,CAAC;AAAA,IACH;AAGA,UAAM,UAAU,CAAC,WAAW,OAAO,aAAa,SAAS,QAAQ,gBAAgB,EAAE;AAAA,MACjF,CAAC,MAAM,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM;AAAA,IACtC;AACA,QAAI,QAAQ,SAAS,GAAG;AACtB,aAAO,KAAK;AAAA,QACV,SAAS,uBAAuB,CAAC,mCAAmC,QAAQ,KAAK,IAAI,CAAC;AAAA,QACtF,MAAM,WAAW,CAAC;AAAA,QAClB,MAAM;AAAA,QACN,YAAY,mEAAmE,QAAQ,KAAK,IAAI,CAAC;AAAA,MACnG,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAMA,SAAS,kBAAkB,MAA+B,QAAiC;AAEzF,MAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,GAAG;AAC9B,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YACE;AAAA,IACJ,CAAC;AACD;AAAA,EACF;AAEA,MAAI,KAAK,MAAM,WAAW,GAAG;AAC3B,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YAAY;AAAA,IACd,CAAC;AACD;AAAA,EACF;AAGA,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,QAAQ,KAAK;AACnB,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,aAAO,KAAK;AAAA,QACV,SAAS,qBAAqB,CAAC;AAAA,QAC/B,MAAM,SAAS,CAAC;AAAA,QAChB,MAAM;AAAA,QACN,YAAY;AAAA,MACd,CAAC;AACD;AAAA,IACF;AACA,QAAI,OAAO,KAAK,OAAO,YAAY,KAAK,OAAO,IAAI;AACjD,aAAO,KAAK;AAAA,QACV,SAAS,qBAAqB,CAAC;AAAA,QAC/B,MAAM,SAAS,CAAC;AAAA,QAChB,MAAM;AAAA,QACN,YAAY;AAAA,MACd,CAAC;AAAA,IACH,OAAO;AACL,cAAQ,IAAI,KAAK,EAAE;AAAA,IACrB;AAAA,EACF;AAGA,MAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,GAAG;AAC9B,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YAAY;AAAA,IACd,CAAC;AACD;AAAA,EACF;AAGA,QAAM,QAAQ,KAAK;AACnB,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,aAAO,KAAK;AAAA,QACV,SAAS,qBAAqB,CAAC;AAAA,QAC/B,MAAM,SAAS,CAAC;AAAA,QAChB,MAAM;AAAA,QACN,YACE;AAAA,MACJ,CAAC;AACD;AAAA,IACF;AAEA,QAAI,OAAO,KAAK,WAAW,YAAY,KAAK,WAAW,IAAI;AACzD,aAAO,KAAK;AAAA,QACV,SAAS,qBAAqB,CAAC;AAAA,QAC/B,MAAM,SAAS,CAAC;AAAA,QAChB,MAAM;AAAA,QACN,YAAY;AAAA,MACd,CAAC;AAAA,IACH,WAAW,QAAQ,OAAO,KAAK,CAAC,QAAQ,IAAI,KAAK,MAAM,GAAG;AACxD,aAAO,KAAK;AAAA,QACV,SAAS,qBAAqB,CAAC,aAAa,KAAK,MAAM;AAAA,QACvD,MAAM,SAAS,CAAC;AAAA,QAChB,MAAM;AAAA,QACN,YAAY,qCAAqC,CAAC,GAAG,OAAO,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,GAAG,QAAQ,OAAO,IAAI,QAAQ,EAAE;AAAA,MACtH,CAAC;AAAA,IACH;AAEA,QAAI,OAAO,KAAK,WAAW,YAAY,KAAK,WAAW,IAAI;AACzD,aAAO,KAAK;AAAA,QACV,SAAS,qBAAqB,CAAC;AAAA,QAC/B,MAAM,SAAS,CAAC;AAAA,QAChB,MAAM;AAAA,QACN,YAAY;AAAA,MACd,CAAC;AAAA,IACH,WAAW,QAAQ,OAAO,KAAK,CAAC,QAAQ,IAAI,KAAK,MAAM,GAAG;AACxD,aAAO,KAAK;AAAA,QACV,SAAS,qBAAqB,CAAC,aAAa,KAAK,MAAM;AAAA,QACvD,MAAM,SAAS,CAAC;AAAA,QAChB,MAAM;AAAA,QACN,YAAY,qCAAqC,CAAC,GAAG,OAAO,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,GAAG,QAAQ,OAAO,IAAI,QAAQ,EAAE;AAAA,MACtH,CAAC;AAAA,IACH;AAAA,EACF;AAGA,MAAI,KAAK,YAAY,OAAO,KAAK,aAAa,UAAU;AACtD,UAAM,WAAW,KAAK;AACtB,UAAM,YAAY,MAAM,CAAC;AACzB,UAAM,YAAY,MAAM,SAAS,IAAK,MAAM,CAAC,IAAgC;AAC7E,UAAM,aAAa,YAAY,IAAI,IAAI,OAAO,KAAK,SAAS,CAAC,IAAI,oBAAI,IAAY;AACjF,UAAM,aAAa,YAAY,IAAI,IAAI,OAAO,KAAK,SAAS,CAAC,IAAI,oBAAI,IAAY;AAEjF,UAAM,eAAe,CAAC,aAAa,YAAY,WAAW;AAC1D,eAAW,WAAW,cAAc;AAClC,YAAM,KAAK,SAAS,OAAO;AAC3B,UAAI,IAAI,SAAS,OAAO,GAAG,UAAU,YAAY,CAAC,WAAW,IAAI,GAAG,KAAK,GAAG;AAC1E,eAAO,KAAK;AAAA,UACV,SAAS,wBAAwB,OAAO,WAAW,GAAG,KAAK,gDAAgD,CAAC,GAAG,UAAU,EAAE,KAAK,IAAI,CAAC;AAAA,UACrI,MAAM,YAAY,OAAO;AAAA,UACzB,MAAM;AAAA,UACN,YAAY,+BAA+B,CAAC,GAAG,UAAU,EAAE,KAAK,IAAI,CAAC;AAAA,QACvE,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,eAAe,CAAC,aAAa,WAAW;AAC9C,eAAW,WAAW,cAAc;AAClC,YAAM,KAAK,SAAS,OAAO;AAC3B,UAAI,IAAI,SAAS,OAAO,GAAG,UAAU,YAAY,aAAa,CAAC,WAAW,IAAI,GAAG,KAAK,GAAG;AACvF,eAAO,KAAK;AAAA,UACV,SAAS,wBAAwB,OAAO,WAAW,GAAG,KAAK,gDAAgD,CAAC,GAAG,UAAU,EAAE,KAAK,IAAI,CAAC;AAAA,UACrI,MAAM,YAAY,OAAO;AAAA,UACzB,MAAM;AAAA,UACN,YAAY,+BAA+B,CAAC,GAAG,UAAU,EAAE,KAAK,IAAI,CAAC;AAAA,QACvE,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,MAAI,KAAK,UAAU,OAAO,KAAK,WAAW,UAAU;AAClD,UAAM,SAAS,KAAK;AACpB,QAAI,OAAO,QAAQ,OAAO,SAAS,SAAS;AAC1C,aAAO,KAAK;AAAA,QACV,SAAS,4BAA4B,OAAO,IAAI;AAAA,QAChD,MAAM;AAAA,QACN,MAAM;AAAA,QACN,YACE;AAAA,MACJ,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAMA,SAAS,mBAAmB,MAA+B,QAAiC;AAE1F,MAAI,CAAC,MAAM,QAAQ,KAAK,IAAI,GAAG;AAC7B,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YACE;AAAA,IACJ,CAAC;AACD;AAAA,EACF;AAEA,MAAI,KAAK,KAAK,WAAW,GAAG;AAC1B,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YAAY;AAAA,IACd,CAAC;AACD;AAAA,EACF;AAEA,QAAM,WAAW,KAAK,KAAK,CAAC;AAC5B,MAAI,OAAO,aAAa,YAAY,aAAa,QAAQ,MAAM,QAAQ,QAAQ,GAAG;AAChF,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YACE;AAAA,IACJ,CAAC;AACD;AAAA,EACF;AAGA,MAAI,CAAC,KAAK,YAAY,OAAO,KAAK,aAAa,UAAU;AACvD,WAAO,KAAK;AAAA,MACV,SACE;AAAA,MACF,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YACE;AAAA,IACJ,CAAC;AACD;AAAA,EACF;AAEA,QAAM,WAAW,KAAK;AACtB,QAAM,cAAc,IAAI,IAAI,OAAO,KAAK,QAAmC,CAAC;AAC5E,QAAM,mBAAmB,CAAC,GAAG,WAAW,EAAE,KAAK,IAAI;AAGnD,aAAW,WAAW,CAAC,UAAU,UAAU,OAAO,GAAY;AAC5D,UAAM,KAAK,SAAS,OAAO;AAC3B,QAAI,CAAC,MAAM,OAAO,OAAO,UAAU;AACjC,aAAO,KAAK;AAAA,QACV,SAAS,yCAAyC,OAAO;AAAA,QACzD,MAAM,YAAY,OAAO;AAAA,QACzB,MAAM;AAAA,QACN,YAAY,gBAAgB,OAAO,iCAAiC,gBAAgB,eAAe,OAAO,eAAe,CAAC,GAAG,WAAW,EAAE,CAAC,KAAK,SAAS,aAAa,YAAY,UAAU,iBAAiB,SAAS;AAAA,MACxN,CAAC;AACD;AAAA,IACF;AAEA,QAAI,CAAC,GAAG,SAAS,OAAO,GAAG,UAAU,UAAU;AAC7C,aAAO,KAAK;AAAA,QACV,SAAS,wBAAwB,OAAO;AAAA,QACxC,MAAM,YAAY,OAAO;AAAA,QACzB,MAAM;AAAA,QACN,YAAY,4CAA4C,gBAAgB;AAAA,MAC1E,CAAC;AACD;AAAA,IACF;AAEA,QAAI,CAAC,YAAY,IAAI,GAAG,KAAe,GAAG;AACxC,aAAO,KAAK;AAAA,QACV,SAAS,wBAAwB,OAAO,WAAW,GAAG,KAAK,gDAAgD,gBAAgB;AAAA,QAC3H,MAAM,YAAY,OAAO;AAAA,QACzB,MAAM;AAAA,QACN,YAAY,0CAA0C,gBAAgB;AAAA,MACxE,CAAC;AAAA,IACH;AAAA,EACF;AAGA,MAAI,KAAK,aAAa,UAAa,CAAC,iBAAiB,IAAI,KAAK,QAAkB,GAAG;AACjF,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YACE;AAAA,IACJ,CAAC;AAAA,EACH;AACF;AAMA,SAAS,kBAAkB,MAA+B,QAAiC;AACzF,QAAM,QAAQ,KAAK;AAEnB,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO,KAAK;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YAAY;AAAA,IACd,CAAC;AACD;AAAA,EACF;AAEA,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,QAAQ,MAAM,CAAC;AACrB,QAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AAC/D,aAAO,KAAK;AAAA,QACV,SAAS,qBAAqB,CAAC;AAAA,QAC/B,MAAM,SAAS,CAAC;AAAA,QAChB,MAAM;AAAA,QACN,YACE;AAAA,MACJ,CAAC;AACD;AAAA,IACF;AAEA,UAAM,WAAW;AACjB,UAAM,gBAAgB,WAAW,YAAY,MAAM,QAAQ,SAAS,KAAK;AACzE,UAAM,eAAe,UAAU;AAE/B,QAAI,CAAC,iBAAiB,CAAC,cAAc;AACnC,aAAO,KAAK;AAAA,QACV,SAAS,qBAAqB,CAAC;AAAA,QAC/B,MAAM,SAAS,CAAC;AAAA,QAChB,MAAM;AAAA,QACN,YACE;AAAA,MACJ,CAAC;AACD;AAAA,IACF;AAEA,QAAI,eAAe;AACjB,wBAAkB,UAAU,MAAM;AAAA,IACpC,WAAW,cAAc;AAEvB,YAAM,OAAO,SAAS;AACtB,UAAI;AACJ,UAAI,OAAO,SAAS,UAAU;AAC5B,oBAAY;AAAA,MACd,WAAW,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,GAAG;AACnE,oBAAa,KAAiC;AAAA,MAChD;AAEA,UAAI,CAAC,aAAa,CAAC,WAAW,IAAI,SAAS,GAAG;AAC5C,eAAO,KAAK;AAAA,UACV,SAAS,qBAAqB,CAAC,WAAW,aAAa,OAAO,IAAI,CAAC;AAAA,UACnE,MAAM,SAAS,CAAC;AAAA,UAChB,MAAM;AAAA,UACN,YAAY,0BAA0B,CAAC,GAAG,UAAU,EAAE,KAAK,IAAI,CAAC;AAAA,QAClE,CAAC;AACD;AAAA,MACF;AAIA,YAAM,aAAa,MAAM,QAAQ,SAAS,IAAI,KAAM,SAAS,KAAmB,SAAS;AACzF,YAAM,gBAAgB,MAAM,QAAQ,KAAK,IAAI,KAAM,KAAK,KAAmB,SAAS;AAEpF,UAAI,cAAc,eAAe;AAE/B,cAAM,sBAAsB,EAAE,GAAG,SAAS;AAC1C,YAAI,CAAC,cAAc,eAAe;AAChC,8BAAoB,OAAO,KAAK;AAAA,QAClC;AAEA,YAAI,KAAK,YAAY,OAAO,KAAK,aAAa,UAAU;AACtD,8BAAoB,WAAW;AAAA,YAC7B,GAAI,KAAK;AAAA,YACT,GAAK,SAAS,YAAwC,CAAC;AAAA,UACzD;AAAA,QACF;AACA,YAAI,oBAAoB,QAAQ,oBAAoB,UAAU;AAC5D,4BAAkB,qBAAqB,MAAM;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAaO,SAAS,aAAa,MAAiC;AAC5D,QAAM,SAA4B,CAAC;AAGnC,MAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,IAAI,GAAG;AAC5D,WAAO;AAAA,MACL,OAAO;AAAA,MACP,QAAQ;AAAA,QACN;AAAA,UACE,SAAS;AAAA,UACT,MAAM;AAAA,UACN,YACE;AAAA,QACJ;AAAA,MACF;AAAA,MACA,YAAY;AAAA,IACd;AAAA,EACF;AAEA,QAAM,MAAM;AAOZ,QAAM,WAAW,WAAW,OAAO,MAAM,QAAQ,IAAI,KAAK;AAC1D,QAAM,UAAU,UAAU;AAC1B,QAAM,UAAU,IAAI,SAAS;AAC7B,QAAM,UAAU,IAAI,SAAS;AAC7B,QAAM,WAAW,IAAI,SAAS;AAC9B,QAAM,UAAU,YAAY,CAAC,WAAW,CAAC,WAAW,CAAC;AACrD,QAAM,UAAU,WAAW,CAAC,YAAY,CAAC,WAAW,CAAC,WAAW,CAAC;AAEjE,MAAI,CAAC,WAAW,CAAC,WAAW,CAAC,WAAW,CAAC,YAAY,CAAC,SAAS;AAC7D,WAAO;AAAA,MACL,OAAO;AAAA,MACP,QAAQ;AAAA,QACN;AAAA,UACE,SACE;AAAA,UACF,MAAM;AAAA,UACN,MAAM;AAAA,UACN,YAAY,yMAAyM,CAAC,GAAG,UAAU,EAAE,KAAK,IAAI,CAAC;AAAA,QACjP;AAAA,MACF;AAAA,MACA,YAAY;AAAA,IACd;AAAA,EACF;AAGA,MAAI,SAAS;AACX,sBAAkB,KAAK,MAAM;AAAA,EAC/B;AAGA,MAAI,SAAS;AACX,UAAM,OAAO,IAAI;AACjB,QAAI;AAEJ,QAAI,OAAO,SAAS,UAAU;AAC5B,kBAAY;AAAA,IACd,WAAW,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,GAAG;AACnE,kBAAa,KAAiC;AAAA,IAChD;AAEA,QAAI,CAAC,aAAa,CAAC,WAAW,IAAI,SAAS,GAAG;AAC5C,aAAO;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,UACN;AAAA,YACE,SAAS,gBAAgB,aAAa,OAAO,IAAI,CAAC,iDAAiD,CAAC,GAAG,UAAU,EAAE,KAAK,IAAI,CAAC;AAAA,YAC7H,MAAM;AAAA,YACN,MAAM;AAAA,YACN,YAAY,0BAA0B,CAAC,GAAG,UAAU,EAAE,KAAK,IAAI,CAAC;AAAA,UAClE;AAAA,QACF;AAAA,QACA,YAAY;AAAA,MACd;AAAA,IACF;AAEA,sBAAkB,KAAK,MAAM;AAAA,EAC/B,WAAW,SAAS;AAClB,sBAAkB,KAAK,MAAM;AAAA,EAC/B,WAAW,SAAS;AAClB,sBAAkB,KAAK,MAAM;AAAA,EAC/B,WAAW,UAAU;AACnB,uBAAmB,KAAK,MAAM;AAAA,EAChC;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,WAAO,EAAE,OAAO,OAAO,QAAQ,YAAY,KAAK;AAAA,EAClD;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,QAAQ,CAAC;AAAA,IACT,YAAY;AAAA,EACd;AACF;;;AC/zBO,SAAS,QAAQ,MAA8B;AACpD,QAAM,aAAa,aAAa,IAAI;AAEpC,MAAI,CAAC,WAAW,SAAS,CAAC,WAAW,YAAY;AAC/C,UAAM,gBAAgB,WAAW,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI;AACvE,UAAM,IAAI,MAAM;AAAA,EAAkB,aAAa,EAAE;AAAA,EACnD;AAEA,QAAM,WAAqB,CAAC;AAC5B,QAAM,aAAa,cAAc,WAAW,YAAY,QAAQ;AAEhE,SAAO,EAAE,MAAM,YAAY,SAAS;AACtC;;;ACPA,SAAS,YAAY,eAAe,oBAAoB;;;ACCxD,IAAM,sBAAsB;AAC5B,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AAExB,IAAM,qBAAqB;AAC3B,IAAM,iBAAiB;AACvB,IAAM,iBAAiB;AAEvB,IAAMC,wBAAuB;AAYtB,SAAS,YAAYC,MAAa,SAAiB,KAAa;AAErE,QAAM,QAAQA,KAAI,QAAQ,MAAM,EAAE;AAClC,MAAI,MAAM,WAAW,KAAK,MAAM,WAAW,EAAG,QAAOA;AAGrD,QAAM,OACJ,MAAM,WAAW,IACb,MACG,MAAM,EAAE,EACR,IAAI,CAAC,MAAM,IAAI,CAAC,EAChB,KAAK,EAAE,IACV;AAEN,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,KAAK,IAAI,OAAO,CAAC;AACnF,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,KAAK,IAAI,OAAO,CAAC;AACnF,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,KAAK,IAAI,OAAO,CAAC;AAEnF,SAAO,IAAI,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC;AAChH;AAKA,SAAS,eAAeA,MAAa,SAAyB;AAC5D,QAAM,QAAQA,KAAI,QAAQ,MAAM,EAAE;AAClC,MAAI,MAAM,WAAW,KAAK,MAAM,WAAW,GAAG;AAE5C,WAAOA;AAAA,EACT;AAEA,QAAM,OACJ,MAAM,WAAW,IACb,MACG,MAAM,EAAE,EACR,IAAI,CAAC,MAAM,IAAI,CAAC,EAChB,KAAK,EAAE,IACV;AAEN,QAAM,IAAI,SAAS,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE;AAC3C,QAAM,IAAI,SAAS,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE;AAC3C,QAAM,IAAI,SAAS,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE;AAE3C,SAAO,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,OAAO;AAC1C;AAKA,SAAS,eAAe,OAAoB,OAAyC;AACnF,QAAM,UAAU,oBAAI,IAAoB;AACxC,aAAW,QAAQ,OAAO;AACxB,YAAQ,IAAI,KAAK,IAAI,CAAC;AAAA,EACxB;AACA,aAAW,QAAQ,OAAO;AACxB,YAAQ,IAAI,KAAK,SAAS,QAAQ,IAAI,KAAK,MAAM,KAAK,KAAK,CAAC;AAC5D,YAAQ,IAAI,KAAK,SAAS,QAAQ,IAAI,KAAK,MAAM,KAAK,KAAK,CAAC;AAAA,EAC9D;AACA,SAAO;AACT;AAaO,SAAS,mBACd,OACA,UACA,OACA,OACA,eACqB;AACrB,QAAM,UAAU,eAAe,OAAO,KAAK;AAC3C,QAAM,YAAY,KAAK,IAAI,GAAG,GAAG,QAAQ,OAAO,CAAC;AAGjD,MAAI;AACJ,MAAI,SAAS,UAAU,OAAO;AAC5B,UAAM,QAAQ,SAAS,SAAS;AAChC,UAAM,SAAS,MAAM,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAElF,UAAM,UAAUC,KAAI,MAAM,KAAK;AAC/B,UAAM,UAAUC,KAAI,MAAM,KAAK;AAE/B,gBAAYC,MAAU,EAAE,OAAO,CAAC,SAAS,OAAO,CAAC,EAAE,MAAM,CAAC,iBAAiB,eAAe,CAAC;AAAA,EAC7F;AAGA,MAAI;AACJ,MAAI,SAAS,WAAW,OAAO;AAC7B,UAAM,QAAQ,SAAS,UAAU;AACjC,UAAM,YAAY,SAAS,UAAU,QAAQ;AAC7C,UAAM,cAAc,SAAS,UAAU;AAEvC,QAAI,cAAc,gBAAgB;AAChC,YAAM,SAAS,MAAM,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAClF,YAAM,WAAWF,KAAI,MAAM,KAAK;AAChC,YAAM,WAAWC,KAAI,MAAM,KAAK;AAGhC,YAAM,cAAc,OAAO,OAAO,MAAM,OAAO,UAAU;AACzD,YAAM,UAAU,YAAY,SAAS,IAAI,YAAY,CAAC,IAAI,CAAC,QAAQ,MAAM;AAEzE,YAAM,SACJ,aAAa,UAAU,YAAY,OAAO,WAAW,IAChD,YAAY,SACb,CAAC,UAAU,QAAQ;AACzB,YAAME,SACJ,aAAa,SAAS,YAAY,MAAM,UAAU,IAC7C,YAAY,QACb,CAAC,QAAQ,CAAC,GAAG,QAAQ,QAAQ,SAAS,CAAC,CAAC;AAE9C,YAAM,aAAaC,QAAoB,EAAE,OAAO,MAAM,EAAE,MAAMD,MAAK;AAEnE,gBAAU,CAAC,SAAoB;AAC7B,cAAM,MAAM,OAAO,KAAK,KAAK,CAAC;AAC9B,eAAO,OAAO,SAAS,GAAG,IAAI,WAAW,GAAG,IAAI,MAAM,OAAO,YAAY,CAAC;AAAA,MAC5E;AAAA,IACF,OAAO;AAEL,YAAM,SACJ,aAAa,UAAU,MAAM,QAAQ,YAAY,MAAM,IAClD,YAAY,SACb,CAAC,GAAG,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC;AAC3D,YAAMA,SACJ,aAAa,SAAS,YAAY,MAAM,SAAS,IAC5C,YAAY,QACb,MAAM,OAAO;AAEnB,YAAM,eAAe,QAAqB,EAAE,OAAO,MAAM,EAAE,MAAMA,MAAK;AAEtE,gBAAU,CAAC,SAAoB,aAAa,OAAO,KAAK,KAAK,KAAK,EAAE,CAAC;AAAA,IACvE;AAAA,EACF;AAEA,QAAM,eAAe,MAAM,OAAO,YAAY,CAAC;AAE/C,SAAO,MAAM,IAAI,CAAC,SAAS;AAEzB,QAAI,SAAS;AACb,QAAI,aAAa,SAAS,UAAU,OAAO;AACzC,YAAM,MAAM,OAAO,KAAK,SAAS,SAAS,KAAK,CAAC;AAChD,UAAI,OAAO,SAAS,GAAG,GAAG;AACxB,iBAAS,UAAU,GAAG;AAAA,MACxB;AAAA,IACF;AAGA,UAAM,OAAO,UAAU,QAAQ,IAAI,IAAI;AAGvC,UAAM,SAAS,YAAY,IAAI;AAG/B,QAAI;AACJ,QAAI,SAAS,WAAW,OAAO;AAC7B,YAAM,WAAW,KAAK,SAAS,UAAU,KAAK;AAC9C,cAAQ,YAAY,OAAO,OAAO,QAAQ,IAAI;AAAA,IAChD,OAAO;AACL,cAAQ,KAAK;AAAA,IACf;AAGA,UAAM,SAAS,QAAQ,IAAI,KAAK,EAAE,KAAK;AACvC,UAAM,gBAAgB,YAAY,IAAI,SAAS,YAAY;AAG3D,UAAM,EAAE,IAAI,KAAK,GAAG,KAAK,IAAI;AAC7B,UAAM,OAAgC,EAAE,IAAI,KAAK,IAAI,GAAG,KAAK;AAG7D,UAAM,WAAW,gBAAgB,KAAK,EAAE;AACxC,UAAM,YAAY,UAAU,QAAQ;AACpC,UAAM,cAAc,UAAU,UAAU;AACxC,UAAM,mBAAmB,UAAU,eAAeL;AAClD,UAAM,cAAc,UAAU,UAAU;AACxC,UAAM,qBAAqB,UAAU,kBAAkB,WAAW;AAElE,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,aAAa;AAAA,MACb;AAAA,MACA,eAAe;AAAA,MACf,WAAW;AAAA,MACX;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAYO,SAAS,mBACd,OACA,UACA,OACqB;AAErB,MAAI;AACJ,MAAI,SAAS,WAAW,OAAO;AAC7B,UAAM,QAAQ,SAAS,UAAU;AACjC,UAAM,SAAS,MAAM,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAElF,UAAM,WAAWE,KAAI,MAAM,KAAK;AAChC,UAAM,WAAWC,KAAI,MAAM,KAAK;AAEhC,iBAAaG,QAAY,EAAE,OAAO,CAAC,UAAU,QAAQ,CAAC,EAAE,MAAM,CAAC,gBAAgB,cAAc,CAAC;AAAA,EAChG;AAGA,MAAI;AACJ,MAAI,SAAS,WAAW,OAAO;AAC7B,UAAM,QAAQ,SAAS,UAAU;AACjC,UAAM,YAAY,SAAS,UAAU,QAAQ;AAC7C,UAAM,cAAc,SAAS,UAAU;AAEvC,QAAI,cAAc,gBAAgB;AAChC,YAAM,SAAS,MAAM,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAClF,YAAM,WAAWJ,KAAI,MAAM,KAAK;AAChC,YAAM,WAAWC,KAAI,MAAM,KAAK;AAEhC,YAAM,cAAc,OAAO,OAAO,MAAM,OAAO,UAAU;AACzD,YAAM,UAAU,YAAY,SAAS,IAAI,YAAY,CAAC,IAAI,CAAC,QAAQ,MAAM;AAEzE,YAAM,SACJ,aAAa,UAAU,YAAY,OAAO,WAAW,IAChD,YAAY,SACb,CAAC,UAAU,QAAQ;AACzB,YAAME,SACJ,aAAa,SAAS,YAAY,MAAM,UAAU,IAC7C,YAAY,QACb,CAAC,QAAQ,CAAC,GAAG,QAAQ,QAAQ,SAAS,CAAC,CAAC;AAE9C,YAAM,aAAaC,QAAoB,EAAE,OAAO,MAAM,EAAE,MAAMD,MAAK;AAEnE,oBAAc,CAAC,SAAoB;AACjC,cAAM,MAAM,OAAO,KAAK,KAAK,CAAC;AAC9B,eAAO,OAAO,SAAS,GAAG,IAAI,WAAW,GAAG,IAAI,eAAe,MAAM,OAAO,MAAM,GAAG;AAAA,MACvF;AAAA,IACF,OAAO;AACL,YAAM,SACJ,aAAa,UAAU,MAAM,QAAQ,YAAY,MAAM,IAClD,YAAY,SACb,CAAC,GAAG,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC;AAC3D,YAAMA,SACJ,aAAa,SAAS,YAAY,MAAM,SAAS,IAC5C,YAAY,QACb,MAAM,OAAO;AAEnB,YAAM,eAAe,QAAqB,EAAE,OAAO,MAAM,EAAE,MAAMA,MAAK;AAEtE,oBAAc,CAAC,SAAoB,aAAa,OAAO,KAAK,KAAK,KAAK,EAAE,CAAC;AAAA,IAC3E;AAAA,EACF;AAEA,QAAM,mBAAmB,eAAe,MAAM,OAAO,MAAM,GAAG;AAG9D,QAAM,cAAoD,CAAC,SAAS,UAAU,QAAQ;AACtF,MAAI;AACJ,MAAI,SAAS,WAAW,OAAO;AAC7B,UAAM,QAAQ,SAAS,UAAU;AACjC,UAAM,eAAe,CAAC,GAAG,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC;AAC1E,UAAM,WAAW,oBAAI,IAA2C;AAChE,aAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,eAAS,IAAI,aAAa,CAAC,GAAG,YAAY,IAAI,YAAY,MAAM,CAAC;AAAA,IACnE;AACA,cAAU,CAAC,SAAoB,SAAS,IAAI,OAAO,KAAK,KAAK,KAAK,EAAE,CAAC,KAAK;AAAA,EAC5E;AAEA,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,UAAM,EAAE,QAAQ,QAAQ,GAAG,KAAK,IAAI;AAEpC,QAAI,cAAc;AAClB,QAAI,cAAc,SAAS,WAAW,OAAO;AAC3C,YAAM,MAAM,OAAO,KAAK,SAAS,UAAU,KAAK,CAAC;AACjD,UAAI,OAAO,SAAS,GAAG,GAAG;AACxB,sBAAc,WAAW,GAAG;AAAA,MAC9B;AAAA,IACF;AAEA,UAAM,SAAS,cAAc,YAAY,IAAI,IAAI;AACjD,UAAM,QAAQ,UAAU,QAAQ,IAAI,IAAK;AAEzC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM,EAAE,QAAQ,QAAQ,GAAG,KAAK;AAAA,IAClC;AAAA,EACF,CAAC;AACH;;;ACzUO,SAAS,kBACd,OACA,iBACM;AACN,MAAI,CAAC,gBAAiB;AAEtB,aAAW,QAAQ,OAAO;AACxB,UAAME,SAAQ,KAAK,KAAK,eAAe;AACvC,SAAK,YAAYA,UAAS,OAAO,OAAOA,MAAK,IAAI;AAAA,EACnD;AACF;AAYO,SAAS,uBACd,OACA,OACqB;AACrB,QAAM,WAAW,oBAAI,IAAoB;AACzC,QAAM,UAAU,MAAM,OAAO;AAC7B,MAAI,aAAa;AAEjB,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,aAAa,QAAQ,CAAC,SAAS,IAAI,KAAK,SAAS,GAAG;AAC3D,eAAS,IAAI,KAAK,WAAW,QAAQ,aAAa,QAAQ,MAAM,CAAC;AACjE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAcO,SAAS,qBACd,OACA,UACM;AACN,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,aAAa,MAAM;AAC1B,YAAM,iBAAiB,SAAS,IAAI,KAAK,SAAS;AAClD,UAAI,gBAAgB;AAClB,aAAK,OAAO;AACZ,aAAK,SAAS,YAAY,cAAc;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AACF;;;AFvDA,IAAM,cAAc;AACpB,IAAM,aAAa;AACnB,IAAM,YAAY;AAalB,SAAS,iBACP,OACA,mBACA,gBACA,OACA,gBACc;AACd,QAAM,aAAwB;AAAA,IAC5B,YAAY,MAAM,MAAM;AAAA,IACxB,UAAU,MAAM,MAAM,MAAM;AAAA,IAC5B,YAAY,MAAM,MAAM,QAAQ;AAAA,IAChC,MAAM,MAAM,OAAO;AAAA,IACnB,YAAY;AAAA,EACd;AAEA,MAAI;AAEJ,MAAI,kBAAkB,kBAAkB,OAAO,GAAG;AAEhD,cAAU,CAAC,GAAG,kBAAkB,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,OAAOC,MAAK,OAAO;AAAA,MAClE;AAAA,MACA,OAAAA;AAAA,MACA,OAAO;AAAA,MACP,QAAQ;AAAA,IACV,EAAE;AAAA,EACJ,OAAO;AAIL,UAAM,iBAAiB,oBAAI,IAAoB;AAC/C,eAAW,QAAQ,OAAO;AACxB,YAAM,WAAW,iBACb,OAAO,KAAK,KAAK,cAAc,KAAK,KAAK,SAAS,KAAK,EAAE,IACxD,KAAK,SAAS,KAAK;AACxB,UAAI,CAAC,eAAe,IAAI,QAAQ,GAAG;AACjC,uBAAe,IAAI,UAAU,KAAK,IAAI;AAAA,MACxC;AAAA,IACF;AAGA,QAAI,eAAe,QAAQ,GAAG;AAC5B,gBAAU,CAAC;AAAA,IACb,OAAO;AACL,gBAAU,CAAC,GAAG,eAAe,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,OAAOA,MAAK,OAAO;AAAA,QAC/D;AAAA,QACA,OAAAA;AAAA,QACA,OAAO;AAAA,QACP,QAAQ;AAAA,MACV,EAAE;AAAA,IACJ;AAAA,EACF;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,IACV;AAAA,IACA,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,GAAG,QAAQ,EAAE;AAAA,IAC1C;AAAA,IACA,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,UAAU;AAAA,EACZ;AACF;AAWA,SAAS,mBAAmB,OAAyD;AACnF,QAAM,cAAc,oBAAI,IAA4B;AAEpD,aAAW,QAAQ,OAAO;AACxB,UAAM,SAAyB,CAAC;AAGhC,QAAI,KAAK,aAAa,MAAM;AAC1B,aAAO,KAAK;AAAA,QACV,OAAO;AAAA,QACP,OAAO,KAAK;AAAA,QACZ,OAAO,KAAK;AAAA,MACd,CAAC;AAAA,IACH;AAGA,eAAW,CAAC,KAAKC,MAAK,KAAK,OAAO,QAAQ,KAAK,IAAI,GAAG;AACpD,UAAI,QAAQ,KAAM;AAClB,UAAIA,UAAS,KAAM;AAEnB,aAAO,KAAK;AAAA,QACV,OAAO;AAAA,QACP,OAAO,OAAOA,WAAU,WAAWA,OAAM,eAAe,IAAI,OAAOA,MAAK;AAAA,MAC1E,CAAC;AAAA,IACH;AAEA,gBAAY,IAAI,KAAK,IAAI;AAAA,MACvB,OAAO,KAAK,SAAS,KAAK;AAAA,MAC1B;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AA4BO,SAAS,aAAa,MAAe,SAA2C;AAErF,QAAM,EAAE,MAAM,WAAW,IAAI,QAAY,IAAI;AAE7C,MAAI,EAAE,UAAU,eAAe,WAAW,SAAS,SAAS;AAC1D,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAY;AAGlB,QAAM,eAAgB,KAAiC;AACvD,QAAM,YAAY,iBAAiB,SAAY,UAAU,YAAa,QAAQ,aAAa;AAG3F,QAAM,oBAAoB,QAAQ,QAC9B,EAAE,GAAG,UAAU,OAAO,GAAG,QAAQ,MAAM,IACvC,UAAU;AACd,MAAI,QAAuB,aAAa,iBAAiB;AACzD,MAAI,QAAQ,UAAU;AACpB,YAAQ,WAAW,KAAK;AAAA,EAC1B;AAGA,QAAM,gBAAgB;AAAA,IACpB,UAAU;AAAA,IACV,UAAU;AAAA,IACV,UAAU;AAAA,IACV;AAAA,IACA,UAAU;AAAA,EACZ;AAGA,QAAM,kBAAkB,UAAU,OAAO,YAAY;AACrD,QAAM,iBAAiB,CAAC,CAAC;AACzB,oBAAkB,eAAe,eAAe;AAKhD,QAAM,uBAAuB,CAAC,CAAC,UAAU,SAAS,WAAW;AAC7D,MAAI,oBAAoB,oBAAI,IAAoB;AAChD,MAAI,kBAAkB,CAAC,sBAAsB;AAC3C,wBAAoB,uBAAuB,eAAe,KAAK;AAC/D,yBAAqB,eAAe,iBAAiB;AAAA,EACvD;AAGA,QAAM,gBAAgB,mBAAmB,UAAU,OAAO,UAAU,UAAU,KAAK;AAGnF,QAAM,0BAA0B,kBAAkB,CAAC;AACnD,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,SAAS,WAAW;AAAA,EAChC;AAGA,QAAM,qBAAqB,mBAAmB,aAAa;AAG3D,QAAM,iBAAiB,kBAAkB;AACzC,QAAM,WAAW;AAAA,IACf,sBAAsB,cAAc,MAAM,cAAc,cAAc,MAAM;AAAA,EAC9E;AACA,MAAI,iBAAiB,GAAG;AACtB,aAAS,KAAK,kBAAkB,cAAc,cAAc;AAAA,EAC9D;AACA,QAAM,OAAO;AAAA,IACX,SAAS,SAAS,KAAK,IAAI;AAAA,IAC3B,mBAAmB,cAAc,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,aAAa,IAAI,EAAE,SAAS,EAAE,CAAC;AAAA,IACpF,MAAM;AAAA,IACN,mBAAmB,cAAc,SAAS;AAAA,EAC5C;AAGA,QAAM,mBAAmB,UAAU,OAAO,oBAAoB;AAC9D,QAAM,YACJ,cAAc,SAAS,IACnB,KAAK,IAAI,GAAG,cAAc,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAC9C;AACN,QAAM,mBAAqC;AAAA,IACzC,gBAAgB,UAAU,OAAO,kBAAkB;AAAA,IACnD,cAAc,UAAU,OAAO,gBAAgB;AAAA,IAC/C,YAAY,kBAAkB,EAAE,OAAO,iBAAiB,UAAU,IAAI,IAAI;AAAA,IAC1E,YAAY;AAAA,IACZ,eAAe;AAAA,IACf,iBAAiB,YAAY;AAAA,IAC7B;AAAA,IACA,cAAc,UAAU,OAAO;AAAA,IAC/B,aAAa,UAAU,OAAO;AAAA,EAChC;AAGA,QAAM,SAAS;AAAA,IACb;AAAA,MACE,OAAO,UAAU,OAAO;AAAA,MACxB,UAAU,UAAU,OAAO;AAAA,MAC3B,QAAQ,UAAU,OAAO;AAAA,MACzB,QAAQ,UAAU,OAAO;AAAA,MACzB,QAAQ,UAAU,OAAO;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,MACV,OAAO,QAAQ;AAAA,MACf,QAAQ,QAAQ;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGA,IAAM,4BAA4B;;;AGpTlC,SAAS,qBAAAC,0BAAyB;AAMlC,IAAM,sBAAsB;AAG5B,IAAM,iBAAiB;AAGhB,SAAS,aACd,MACA,UACA,YACA,aACQ;AACR,SAAO,cACH,YAAY,MAAM,UAAU,UAAU,EAAE,QACxCA,mBAAkB,MAAM,UAAU,UAAU;AAClD;AAGO,SAAS,aACdC,QACA,UACA,YACA,aACA,cAAyC,cAChC;AACT,MAAIA,OAAM,SAAS,EAAG,QAAO;AAC7B,QAAM,SAAS,WAAW;AAE1B,MAAI,gBAAgB,YAAY;AAI9B,UAAM,SAAS,CAAC,GAAGA,MAAK,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AAChE,UAAM,cAAc,WAAW;AAC/B,aAAS,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,KAAK;AAC1C,YAAM,UAAU,OAAO,CAAC,EAAE,WAAW,cAAc;AACnD,YAAM,OAAO,OAAO,IAAI,CAAC,EAAE,WAAW,cAAc;AACpD,UAAI,UAAU,SAAS,KAAM,QAAO;AAAA,IACtC;AACA,WAAO;AAAA,EACT;AAEA,WAAS,IAAI,GAAG,IAAIA,OAAM,SAAS,GAAG,KAAK;AACzC,UAAM,SAAS,aAAaA,OAAM,CAAC,EAAE,OAAO,UAAU,YAAY,WAAW;AAC7E,UAAM,SAAS,aAAaA,OAAM,IAAI,CAAC,EAAE,OAAO,UAAU,YAAY,WAAW;AACjF,UAAM,SAASA,OAAM,CAAC,EAAE,WAAW,SAAS;AAC5C,UAAM,QAAQA,OAAM,IAAI,CAAC,EAAE,WAAW,SAAS;AAC/C,QAAI,SAAS,SAAS,MAAO,QAAO;AAAA,EACtC;AACA,SAAO;AACT;AAOO,SAAS,kBACdA,QACA,UACA,YACA,aACA,cAAyC,cAC7B;AACZ,MAAI,CAAC,aAAaA,QAAO,UAAU,YAAY,aAAa,WAAW,EAAG,QAAOA;AAEjF,MAAI,UAAUA;AACd,SAAO,QAAQ,SAAS,gBAAgB;AAEtC,UAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC3B,aAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG;AAC9C,cAAQ,KAAK,QAAQ,CAAC,CAAC;AAAA,IACzB;AACA,QAAI,QAAQ,SAAS,EAAG,SAAQ,KAAK,QAAQ,QAAQ,SAAS,CAAC,CAAC;AAChE,cAAU;AAEV,QAAI,CAAC,aAAa,SAAS,UAAU,YAAY,aAAa,WAAW,EAAG;AAAA,EAC9E;AACA,SAAO;AACT;;;ACvFA;AAAA,EACE,oBAAAC;AAAA,EACA,oBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAAC;AAAA,OACK;AAuBP,IAAM,gBAAkD;AAAA,EACtD,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AACX;AAEA,IAAM,gBAAkD;AAAA,EACtD,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AACX;AAeA,IAAM,qBAAiE;AAAA,EACrE,MAAM,CAAC,GAAG,CAAC;AAAA,EACX,SAAS,CAAC,GAAG,CAAC;AAAA,EACd,SAAS,CAAC,GAAG,CAAC;AAChB;AAEA,IAAM,qBAAiE;AAAA,EACrE,MAAM,CAAC,GAAG,CAAC;AAAA,EACX,SAAS,CAAC,GAAG,CAAC;AAAA,EACd,SAAS,CAAC,GAAG,CAAC;AAChB;AASA,IAAM,cAAgD;AAAA,EACpD,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AACX;AAOO,SAAS,gBACd,YACA,SACA,aACQ;AACR,QAAM,YAAY,gBAAgB,MAAM,cAAc,OAAO,IAAI,cAAc,OAAO;AACtF,QAAM,CAACC,MAAKC,IAAG,IACb,gBAAgB,MAAM,mBAAmB,OAAO,IAAI,mBAAmB,OAAO;AAChF,QAAM,MAAM,KAAK,MAAM,aAAa,SAAS;AAC7C,SAAO,KAAK,IAAID,MAAK,KAAK,IAAIC,MAAK,GAAG,CAAC;AACzC;AAGA,IAAM,sBAAsB,oBAAI,IAAI;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGD,IAAM,uBAAuB,oBAAI,IAAI,CAAC,QAAQ,KAAK,CAAC;AAGpD,SAAS,gBAAgBC,QAAgB,eAAsC;AAC7E,QAAM,YAAY,cAAc,QAAQ,MAAM;AAE9C,MAAI,qBAAqB,IAAI,cAAc,IAAI,GAAG;AAChD,UAAM,cAAc,uBAAuB,SAAS;AACpD,QAAI,YAAa,QAAO,YAAYA,MAAa;AACjD,UAAM,SAAS,cAAc,SAAS;AACtC,WAAO,WAAWA,QAAe,QAAW,QAAW,MAAM;AAAA,EAC/D;AAEA,MAAI,oBAAoB,IAAI,cAAc,IAAI,GAAG;AAC/C,UAAM,MAAMA;AACZ,QAAI,WAAW;AACb,YAAM,MAAMJ,kBAAiB,SAAS;AACtC,UAAI,IAAK,QAAO,IAAI,GAAG;AAAA,IACzB;AAEA,QAAI,KAAK,IAAI,GAAG,KAAK,IAAM,QAAOD,kBAAiB,GAAG;AACtD,WAAOE,cAAa,GAAG;AAAA,EACzB;AAEA,SAAO,OAAOG,MAAK;AACrB;AAUO,SAAS,gBACd,eACA,SACA,aACY;AACZ,QAAM,QAAQ,cAAc;AAI5B,MAAI,EAAE,WAAW,UAAU,OAAO,MAAM,UAAU,YAAY;AAC5D,UAAM,SAAS,MAAM,OAAO;AAC5B,WAAO,OAAO,IAAI,CAACA,YAAoB;AAAA,MACrC,OAAAA;AAAA,MACA,UAAW,MAA4BA,MAAsB;AAAA,MAC7D,OAAO,gBAAgBA,QAAO,aAAa;AAAA,IAC7C,EAAE;AAAA,EACJ;AAEA,QAAM,gBAAgB,cAAc,QAAQ,MAAM;AAClD,QAAM,QAAQ,iBAAiB,eAAe,YAAY,OAAO;AACjE,SAAO,qBAAqB,eAAe,KAAK;AAClD;AAWO,SAAS,qBAAqB,eAA8B,OAA2B;AAC5F,QAAM,QAAQ,cAAc;AAC5B,MAAI,EAAE,WAAW,UAAU,OAAO,MAAM,UAAU,YAAY;AAC5D,WAAO,gBAAgB,eAAe,MAAM;AAAA,EAC9C;AACA,QAAM,MAAiB,MAAM,MAAM,KAAK;AACxC,SAAO,IAAI,IAAI,CAACA,YAAoB;AAAA,IAClC,OAAAA;AAAA,IACA,UAAU,MAAMA,MAAsB;AAAA,IACtC,OAAO,gBAAgBA,QAAO,aAAa;AAAA,EAC7C,EAAE;AACJ;AAGO,SAAS,uBAAuB,eAAuC;AAC5E,QAAM,QAAQ,cAAc;AAC5B,SAAO,WAAW,SAAS,OAAO,MAAM,UAAU;AACpD;AAGO,SAAS,iBACd,eACA,SACY;AACZ,QAAM,QAAQ,cAAc;AAC5B,QAAM,SAAmB,MAAM,OAAO;AACtC,QAAM,oBAAoB,cAAc,QAAQ,MAAM;AACtD,QAAM,WAAW,qBAAqB,YAAY,OAAO;AAIzD,MAAI,iBAAiB;AACrB,OAAK,cAAc,SAAS,UAAU,sBAAsB,OAAO,SAAS,UAAU;AACpF,UAAM,OAAO,KAAK,KAAK,OAAO,SAAS,QAAQ;AAC/C,qBAAiB,OAAO,OAAO,CAAC,GAAW,MAAc,IAAI,SAAS,CAAC;AAAA,EACzE;AAEA,QAAMC,SAAQ,eAAe,IAAI,CAACD,WAAkB;AAElD,UAAM,YAAY,cAAc,SAAS,SAAU,QAA8B;AACjF,UAAM,MAAM,aACP,UAAUA,MAAK,KAAK,KAAK,UAAU,UAAU,IAAI,IAChD,MAAMA,MAAK,KAA4B;AAE7C,WAAO;AAAA,MACL,OAAAA;AAAA,MACA,UAAU;AAAA,MACV,OAAOA;AAAA,IACT;AAAA,EACF,CAAC;AAED,SAAOC;AACT;AAGO,SAAS,qBAAqB,QAAmB,eAA0C;AAChG,QAAM,QAAQ,cAAc;AAC5B,SAAO,OAAO,IAAI,CAACD,WAAU;AAC3B,QAAI;AACJ,QAAI,qBAAqB,IAAI,cAAc,IAAI,GAAG;AAChD,YAAM,IAAIA,kBAAiB,OAAOA,SAAQ,IAAI,KAAK,OAAOA,MAAK,CAAC;AAChE,iBAAY,MAA4B,CAAkB;AAAA,IAC5D,WACE,cAAc,SAAS,UACvB,cAAc,SAAS,WACvB,cAAc,SAAS,WACvB;AACA,YAAM,IAAI,OAAOA,MAAK;AACtB,YAAM,YAAY,cAAc,SAAS,SAAU,QAA8B;AACjF,iBAAW,aACN,UAAU,CAAC,KAAK,KAAK,UAAU,UAAU,IAAI,IAC5C,MAAM,CAAoB,KAA4B;AAAA,IAC9D,OAAO;AACL,iBAAY,MAA4BA,MAAsB;AAAA,IAChE;AACA,WAAO;AAAA,MACL,OAAAA;AAAA,MACA;AAAA,MACA,OAAO,gBAAgBA,QAAO,aAAa;AAAA,IAC7C;AAAA,EACF,CAAC;AACH;;;AC5NA,IAAM,2BAA2B;AACjC,IAAM,2BAA2B;AAMjC,IAAM,0BAA0B;AAChC,IAAM,0BAA0B;AAGhC,IAAM,gBAAoC,CAAC,QAAQ,WAAW,SAAS;AAgBhE,SAAS,iBACd,aACA,YACA,kBACA,kBACkB;AAClB,MAAI,UAAU;AAEd,MAAI,aAAa,kBAAkB;AACjC,cAAU;AAAA,EACZ,WAAW,aAAa,kBAAkB;AAGxC,UAAM,UAAU,cAAc,QAAQ,WAAW;AACjD,UAAM,aAAa,cAAc,QAAQ,SAAS;AAClD,cAAU,cAAc,KAAK,IAAI,SAAS,UAAU,CAAC;AAAA,EACvD;AAEA,SAAO;AACT;AAOA,IAAM,wBAAwB;AAgB9B,IAAM,sBAAsB;AAmB5B,SAAS,mBACP,OACA,cACA,cACA,UACA,YACA,YACA,aACA,aACY;AACZ,MAAI,CAAC,SAAS,CAAC,uBAAuB,KAAK,EAAG,QAAO;AAErD,QAAM,YAAY,eAAe;AACjC,QAAM,aAAa,aAAa,SAAS;AACzC,QAAM,WAAW,aAAa,cAAc,UAAU,YAAY,aAAa,WAAW;AAC1F,MAAI,CAAC,cAAc,CAAC,SAAU,QAAO;AAIrC,QAAM,eACJ,gBAAgB,aAAa,2BAA2B;AAC1D,QAAM,QAAQ,cAAc,eAAe,wBAAwB;AAKnE,MAAI;AACJ,WAAS,IAAI,eAAe,GAAG,KAAK,GAAG,KAAK;AAC1C,UAAM,YAAY,qBAAqB,OAAO,CAAC;AAC/C,UAAM,sBAAsB,UAAU,SAAS;AAC/C,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,CAAC,uBAAuB,CAAC,mBAAmB;AAC9C,aAAO;AAAA,IACT;AACA,QAAI,UAAU,UAAU,MAAO,mBAAkB;AAAA,EACnD;AAKA,QAAM,WAAW,mBAAmB,qBAAqB,OAAO,KAAK;AACrE,SAAO,kBAAkB,UAAU,UAAU,YAAY,aAAa,WAAW;AACnF;AAqBO,SAAS,YACd,QACA,WACA,UACA,OACA,aACY;AACZ,QAAM,SAAqB,CAAC;AAC5B,QAAM,cAAc,SAAS;AAI7B,QAAM,WAAW;AAAA,IACf;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,EACF;AACA,QAAM,WAAW;AAAA,IACf;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,EACF;AAEA,QAAM,iBAA4B;AAAA,IAChC,YAAY,MAAM,MAAM;AAAA,IACxB,UAAU,MAAM,MAAM,MAAM;AAAA,IAC5B,YAAY,MAAM,MAAM,QAAQ;AAAA,IAChC,MAAM,MAAM,OAAO;AAAA,IACnB,YAAY;AAAA,IACZ,aAAa;AAAA,EACf;AAEA,QAAM,iBAA4B;AAAA,IAChC,YAAY,MAAM,MAAM;AAAA,IACxB,UAAU,MAAM,MAAM,MAAM;AAAA,IAC5B,YAAY,MAAM,MAAM,QAAQ;AAAA,IAChC,MAAM,MAAM,OAAO;AAAA,IACnB,YAAY;AAAA,EACd;AAEA,QAAM,EAAE,SAAS,IAAI;AACrB,QAAM,EAAE,WAAW,IAAI;AAEvB,MAAI,OAAO,GAAG;AACZ,UAAM,aAAa,OAAO,EAAE,QAAQ;AACpC,UAAM,gBACJ,OAAO,EAAE,SAAS,UAAU,OAAO,EAAE,SAAS,WAAW,OAAO,EAAE,SAAS;AAE7E,UAAM,eAAe,gBACjB,gBAAgB,UAAU,OAAO,UAAU,GAAG,IAC9C;AAGJ,QAAI;AACJ,QAAI,YAAY,QAAQ;AACtB,iBAAW,qBAAqB,WAAW,QAAQ,OAAO,CAAC;AAAA,IAC7D,WAAW,CAAC,eAAe;AACzB,iBAAW,iBAAiB,OAAO,GAAG,QAAQ;AAAA,IAChD,OAAO;AACL,iBAAW,gBAAgB,OAAO,GAAG,UAAU,YAAY;AAAA,IAC7D;AAIA,UAAM,YAAwB,SAAS,IAAI,CAAC,OAAO;AAAA,MACjD,UAAU,EAAE;AAAA,MACZ,OAAO;AAAA,IACT,EAAE;AAIF,UAAM,aAAa,OAAO,EAAE,SAAS,UAAU,CAAC,YAAY,aAAa,CAAC,YAAY;AACtF,QAAIE;AACJ,QAAI,CAAC,YAAY;AACf,MAAAA,SAAQ;AAAA,IACV,WAAW,eAAe;AAGxB,MAAAA,SAAQ;AAAA,QACN,OAAO;AAAA,QACP;AAAA,QACA,gBAAgB,SAAS;AAAA,QACzB;AAAA,QACA;AAAA,QACA,UAAU;AAAA,QACV;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,MAAAA,SAAQ,kBAAkB,UAAU,UAAU,YAAY,WAAW;AAAA,IACvE;AAIA,QAAI,YAAY,YAAY;AAC5B,QAAI,cAAc,UAAa,OAAO,EAAE,SAAS,UAAUA,OAAM,SAAS,GAAG;AAC3E,YAAM,YAAa,OAAO,EAAE,MAA4B,UAAU;AAClE,UAAI,gBAAgB;AACpB,iBAAW,KAAKA,QAAO;AACrB,cAAM,IAAI,aAAa,EAAE,OAAO,UAAU,YAAY,WAAW;AACjE,YAAI,IAAI,cAAe,iBAAgB;AAAA,MACzC;AAEA,UAAI,gBAAgB,YAAY,MAAM;AACpC,oBAAY;AAAA,MACd;AAAA,IACF;AAEA,UAAM,YAAY,YAAY;AAE9B,WAAO,IAAI;AAAA,MACT,OAAAA;AAAA,MACA,WAAW,YAAY,OAAO,YAAY,CAAC;AAAA,MAC3C,OAAO;AAAA,MACP,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA,OAAO,EAAE,GAAG,UAAU,GAAG,GAAG,UAAU,IAAI,UAAU,OAAO;AAAA,MAC3D,KAAK,EAAE,GAAG,UAAU,IAAI,UAAU,OAAO,GAAG,UAAU,IAAI,UAAU,OAAO;AAAA,MAC3E,QAAQ,YAAY;AAAA,MACpB,YAAY,YAAY;AAAA,MACxB,WAAW,YAAY;AAAA,MACvB,QAAQ,YAAY;AAAA,MACpB,cAAc,YAAY;AAAA,MAC1B,cAAc,YAAY;AAAA,MAC1B,cAAc,YAAY;AAAA,MAC1B,YAAY,YAAY;AAAA,IAC1B;AAAA,EACF;AAEA,MAAI,OAAO,GAAG;AACZ,UAAM,aAAa,OAAO,EAAE,QAAQ;AACpC,UAAM,gBACJ,OAAO,EAAE,SAAS,UAAU,OAAO,EAAE,SAAS,WAAW,OAAO,EAAE,SAAS;AAG7E,UAAM,eAAe,gBACjB,gBAAgB,UAAU,QAAQ,UAAU,GAAG,IAC/C;AAGJ,QAAI;AACJ,QAAI,YAAY,QAAQ;AACtB,iBAAW,qBAAqB,WAAW,QAAQ,OAAO,CAAC;AAAA,IAC7D,WAAW,CAAC,eAAe;AACzB,iBAAW,iBAAiB,OAAO,GAAG,QAAQ;AAAA,IAChD,OAAO;AACL,iBAAW,gBAAgB,OAAO,GAAG,UAAU,YAAY;AAAA,IAC7D;AAGA,UAAM,aAAa,OAAO,EAAE,SAAS,UAAU,CAAC,YAAY,aAAa,CAAC,YAAY;AACtF,QAAIA;AACJ,QAAI,CAAC,YAAY;AACf,MAAAA,SAAQ;AAAA,IACV,WAAW,eAAe;AAGxB,MAAAA,SAAQ;AAAA,QACN,OAAO;AAAA,QACP;AAAA,QACA,gBAAgB,SAAS;AAAA,QACzB;AAAA,QACA;AAAA,QACA,UAAU;AAAA,QACV;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,MAAAA,SAAQ,kBAAkB,UAAU,UAAU,YAAY,aAAa,UAAU;AAAA,IACnF;AAGA,UAAM,YAAwBA,OAAM,IAAI,CAAC,OAAO;AAAA,MAC9C,UAAU,EAAE;AAAA,MACZ,OAAO;AAAA,IACT,EAAE;AAEF,UAAM,YAAY,YAAY;AAC9B,UAAM,YAAY,YAAY;AAE9B,WAAO,IAAI;AAAA,MACT,OAAAA;AAAA;AAAA,MAEA;AAAA,MACA,OAAO;AAAA,MACP,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA,OAAO,EAAE,GAAG,UAAU,GAAG,GAAG,UAAU,EAAE;AAAA,MACxC,KAAK,EAAE,GAAG,UAAU,GAAG,GAAG,UAAU,IAAI,UAAU,OAAO;AAAA,MACzD,QAAQ,YAAY;AAAA,MACpB,YAAY,YAAY;AAAA,MACxB,WAAW,YAAY;AAAA,MACvB,QAAQ,YAAY;AAAA,MACpB,cAAc,YAAY;AAAA,MAC1B,cAAc,YAAY;AAAA,MAC1B,cAAc,YAAY;AAAA,MAC1B,YAAY,YAAY;AAAA,IAC1B;AAAA,EACF;AAEA,SAAO;AACT;;;AChYA,SAAS,iBAAAC,gBAAe,qBAAAC,0BAAyB;AA4BjD,SAAS,cAAc,QAAwE;AAC7F,SAAO;AAAA,IACL,OAAO,OAAO;AAAA,IACd,UAAU,OAAO;AAAA,IACjB,QAAQ,OAAO;AAAA,IACf,QAAQ,OAAO;AAAA,IACf,QAAQ,OAAO;AAAA,EACjB;AACF;AAOA,SAAS,aAAa,aAAqB,OAAe,QAAwB;AAChF,QAAM,SAAS,KAAK,IAAI,OAAO,MAAM;AACrC,MAAI,UAAU,IAAK,QAAO;AAC1B,MAAI,UAAU,IAAK,QAAO,KAAK,IAAI,KAAK,MAAM,cAAc,GAAG,GAAG,CAAC;AACnE,QAAM,KAAK,SAAS,OAAO;AAC3B,SAAO,KAAK,IAAI,KAAK,MAAM,eAAe,MAAM,IAAI,IAAI,GAAG,CAAC;AAC9D;AAGA,IAAM,kBAAkB;AACxB,IAAM,mBAAmB;AAgBlB,SAAS,kBACd,MACA,SACA,cACA,OACA,UACA,YAAqB,MACH;AAClB,QAAM,EAAE,OAAO,OAAO,IAAI;AAE1B,QAAM,UAAU,aAAa,MAAM,QAAQ,SAAS,OAAO,MAAM;AACjE,QAAM,aAAa,MAAM,QAAQ;AACjC,QAAM,aAAa,UAAU,cAAc;AAG3C,QAAM,SAASC;AAAA,IACb,cAAc,KAAK,MAAM;AAAA,IACzB;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,QAAM,QAAc,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,OAAO;AAGhD,QAAM,WAAW,KAAK,aAAa;AACnC,QAAM,WAAW,KAAK;AAKtB,QAAM,QAAQ,SAAS,GAAG;AAC1B,QAAM,gBAAgB,CAAC,CAAC,OAAO;AAC/B,QAAM,aAAa,OAAO;AAE1B,MAAI;AACJ,MAAI,UAAU;AACZ,kBAAc;AAAA,EAChB,WAAW,cAAc,KAAK,IAAI,UAAU,IAAI,IAAI;AAGlD,UAAM,WAAW,KAAK,IAAI,UAAU,KAAK,KAAK,KAAK;AACnD,UAAM,SAAS,SAAS,GAAG;AAC3B,QAAI,gBAAgB;AACpB,QAAI,QAAQ;AACV,iBAAW,OAAO,KAAK,MAAM;AAC3B,cAAM,QAAQ,OAAO,IAAI,MAAM,KAAK,EAAE;AACtC,cAAM,IAAIC,mBAAkB,OAAO,MAAM,MAAM,MAAM,UAAU,MAAM,MAAM,QAAQ,MAAM;AACzF,YAAI,IAAI,cAAe,iBAAgB;AAAA,MACzC;AAAA,IACF;AAEA,UAAM,gBAAgB,gBAAgB,KAAK,IAAI,QAAQ,IAAI;AAE3D,UAAM,cAAc,KAAK,IAAI,eAAe,GAAG;AAC/C,kBAAc,gBAAgB,cAAc,KAAK;AAAA,EACnD,OAAO;AACL,kBAAc,gBAAgB,KAAK;AAAA,EACrC;AAMA,QAAM,aAAa,YAAY,OAAO,cAAc,IAAI,IAAI;AAC5D,QAAM,UAAmB;AAAA,IACvB,KAAK,UAAU,OAAO,YAAY;AAAA,IAClC,OAAO,WAAW,WAAW,UAAU;AAAA,IACvC,QAAQ,UAAU,OAAO,eAAe;AAAA,IACxC,MAAM,WAAW,WAAW,UAAU;AAAA,EACxC;AAIA,QAAM,eAAe,KAAK,OAAO;AACjC,OAAK,KAAK,aAAa,UAAU,KAAK,aAAa,WAAW,iBAAiB,QAAQ;AAErF,UAAM,WAAW,SAAS;AAC1B,UAAM,aAAa,YAAY,WAAW,WAAW,SAAS,QAAQ;AACtE,QAAI,YAAY;AACd,UAAI,gBAAgB;AACpB,YAAM,OAAO,oBAAI,IAAY;AAC7B,iBAAW,OAAO,KAAK,MAAM;AAC3B,cAAM,QAAQ,OAAO,IAAI,UAAU,KAAK,EAAE;AAC1C,YAAI,CAAC,KAAK,IAAI,KAAK,GAAG;AACpB,eAAK,IAAI,KAAK;AACd,gBAAM,IAAIA,mBAAkB,OAAO,IAAI,GAAG;AAC1C,cAAI,IAAI,cAAe,iBAAgB;AAAA,QACzC;AAAA,MACF;AACA,UAAI,gBAAgB,GAAG;AACrB,gBAAQ,QAAQ,KAAK,IAAI,QAAQ,OAAO,UAAU,gBAAgB,CAAC;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AAMA,MACE,UAAU,uBAAuB,kBACjC,KAAK,YAAY,SAAS,KAC1B,SAAS,GACT;AACA,UAAM,SAAS,SAAS,EAAE;AAE1B,QAAI;AACJ,eAAW,OAAO,KAAK,MAAM;AAC3B,YAAM,IAAI,IAAI,MAAM;AACpB,UAAI,KAAK,SAAS,QAAQ,QAAQ,OAAO,CAAC,KAAK,OAAO,IAAI,GAAI,QAAO;AAAA,IACvE;AACA,QAAI,QAAQ,MAAM;AAChB,YAAM,UAAU,OAAO,IAAI;AAC3B,iBAAW,OAAO,KAAK,aAAa;AAClC,YAAI,IAAI,SAAS,UAAU,OAAO,IAAI,CAAC,MAAM,SAAS;AACpD,gBAAM,YAAYA,mBAAkB,IAAI,MAAM,IAAI,YAAY,IAAI,IAAI,cAAc,GAAG;AACvF,gBAAM,KAAK,IAAI,QAAQ,MAAM;AAI7B,gBAAM,SAAS,IAAI,UAAU;AAC7B,gBAAM,kBACJ,WAAW,SACP;AAAA;AAAA,YAEA,WAAW,UACT;AAAA;AAAA,cAEA,YAAY;AAAA;AAAA;AACpB,gBAAM,gBAAgB,KAAK,IAAI,GAAG,kBAAkB,EAAE;AACtD,cAAI,gBAAgB,GAAG;AACrB,oBAAQ,QAAQ,KAAK,IAAI,QAAQ,OAAO,UAAU,gBAAgB,EAAE;AAAA,UACtE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,SAAS,KAAK,CAAC,UAAU;AAC3B,QACE,KAAK,aAAa,SAClB,KAAK,aAAa,YAClB,KAAK,aAAa,cAClB,SAAS,EAAE,SAAS,aACpB,SAAS,EAAE,SAAS,WACpB;AAEA,YAAM,SAAS,SAAS,EAAE;AAC1B,UAAI,gBAAgB;AACpB,iBAAW,OAAO,KAAK,MAAM;AAC3B,cAAM,QAAQ,OAAO,IAAI,MAAM,KAAK,EAAE;AACtC,cAAM,IAAIA,mBAAkB,OAAO,MAAM,MAAM,MAAM,UAAU,MAAM,MAAM,QAAQ,MAAM;AACzF,YAAI,IAAI,cAAe,iBAAgB;AAAA,MACzC;AACA,UAAI,gBAAgB,GAAG;AACrB,gBAAQ,OAAO,KAAK,IAAI,QAAQ,MAAM,UAAU,gBAAgB,EAAE;AAAA,MACpE;AAAA,IACF,WAAW,SAAS,EAAE,SAAS,kBAAkB,SAAS,EAAE,SAAS,YAAY;AAE/E,YAAM,SAAS,SAAS,EAAE;AAC1B,YAAM,cAAe,SAAS,EAAE,MAA8C;AAG9E,UAAI,YAAY;AAChB,iBAAW,OAAO,KAAK,MAAM;AAC3B,cAAM,IAAI,OAAO,IAAI,MAAM,CAAC;AAC5B,YAAI,OAAO,SAAS,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,UAAW,aAAY,KAAK,IAAI,CAAC;AAAA,MAC3E;AAEA,UAAI;AACJ,UAAI,aAAa;AAEf,YAAI;AACF,gBAAM,MAAM,OAAS,WAAW;AAChC,wBAAc,IAAI,SAAS;AAAA,QAC7B,QAAQ;AACN,wBAAc,OAAO,SAAS;AAAA,QAChC;AAAA,MACF,OAAO;AAEL,YAAI,aAAa,IAAe,eAAc;AAAA,iBACrC,aAAa,IAAW,eAAc;AAAA,iBACtC,aAAa,IAAO,eAAc;AAAA,iBAClC,aAAa,IAAK,eAAc;AAAA,iBAChC,aAAa,GAAI,eAAc;AAAA,YACnC,eAAc;AAAA,MACrB;AAEA,YAAM,YAAY,KAAK,KAAK,KAAK,CAAC,MAAM,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM;AACvE,YAAM,WAAW,YAAY;AAC7B,YAAM,aAAaA;AAAA,QACjB;AAAA,QACA,MAAM,MAAM,MAAM;AAAA,QAClB,MAAM,MAAM,QAAQ;AAAA,MACtB;AAEA,cAAQ,OAAO,KAAK,IAAI,QAAQ,MAAM,UAAU,aAAa,EAAE;AAAA,IACjE;AAAA,EACF;AAGA,QAAM,QAAQ,SAAS,GAAG;AAC1B,MAAI,UAAU,MAAM,SAAS,MAAM,UAAU,CAAC,UAAU;AACtD,UAAM,qBAAqB,KAAK,KAAK,KAAK,MAAM,MAAM,MAAM,OAAO,CAAC,IAAI;AACxE,YAAQ,OAAO,KAAK,IAAI,QAAQ,MAAM,UAAU,kBAAkB;AAAA,EACpE;AAGA,MAAI,aAAa,QAAQ,SAAS,GAAG;AACnC,QAAI,aAAa,aAAa,WAAW,aAAa,aAAa,gBAAgB;AACjF,cAAQ,SAAS,aAAa,OAAO,QAAQ;AAAA,IAC/C,WAAW,aAAa,aAAa,OAAO;AAC1C,cAAQ,OAAO,aAAa,OAAO,SAAS;AAAA,IAC9C,WAAW,aAAa,aAAa,UAAU;AAC7C,cAAQ,UAAU,aAAa,OAAO,SAAS;AAAA,IACjD;AAAA,EACF;AAGA,MAAI,YAAkB;AAAA,IACpB,GAAG,QAAQ;AAAA,IACX,GAAG,QAAQ;AAAA,IACX,OAAO,KAAK,IAAI,GAAG,QAAQ,QAAQ,OAAO,QAAQ,KAAK;AAAA,IACvD,QAAQ,KAAK,IAAI,GAAG,SAAS,QAAQ,MAAM,QAAQ,MAAM;AAAA,EAC3D;AAGA,OACG,UAAU,QAAQ,mBAAmB,UAAU,SAAS,qBACzD,eAAe,UACf;AAEA,UAAM,eAAe,eAAe,SAAS,YAAY;AACzD,UAAM,iBAAiBD;AAAA,MACrB,cAAc,KAAK,MAAM;AAAA,MACzB;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,UAAM,qBAAqB,YAAY,eAAe,cAAc,IAAI,IAAI;AAC5E,UAAM,SAAS,UAAU,eAAe,YAAY;AACpD,UAAM,WAAW,QAAQ,MAAM;AAC/B,UAAM,YAAY,UAAU,eAAe,eAAe;AAC1D,UAAM,cAAc,QAAQ,SAAS;AAErC,QAAI,WAAW,KAAK,cAAc,GAAG;AACnC,cAAQ,MACN,UACC,aAAa,QAAQ,SAAS,KAAK,aAAa,aAAa,QAC1D,aAAa,OAAO,SAAS,IAC7B;AACN,cAAQ,SAAS;AAEjB,kBAAY;AAAA,QACV,GAAG,QAAQ;AAAA,QACX,GAAG,QAAQ;AAAA,QACX,OAAO,KAAK,IAAI,GAAG,QAAQ,QAAQ,OAAO,QAAQ,KAAK;AAAA,QACvD,QAAQ,KAAK,IAAI,GAAG,SAAS,QAAQ,MAAM,QAAQ,MAAM;AAAA,MAC3D;AAEA,aAAO,EAAE,OAAO,QAAQ,gBAAgB,WAAW,SAAS,MAAM;AAAA,IACpE;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,QAAQ,WAAW,SAAS,MAAM;AACpD;;;AChUO,SAAS,iBACd,MACA,WACA,eAAe,OACC;AAChB,QAAM,aAA6B,CAAC;AACpC,QAAM,WAA2B,CAAC;AAGlC,MAAI,KAAK,GAAG;AACV,eAAW,YAAY,KAAK,EAAE,WAAW;AACvC,iBAAW,KAAK;AAAA,QACd,IAAI,UAAU;AAAA,QACd,IAAI,SAAS;AAAA,QACb,IAAI,UAAU,IAAI,UAAU;AAAA,QAC5B,IAAI,SAAS;AAAA,QACb,OAAO,SAAS;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF;AAGA,MAAI,gBAAgB,KAAK,GAAG;AAC1B,eAAW,YAAY,KAAK,EAAE,WAAW;AACvC,eAAS,KAAK;AAAA,QACZ,IAAI,SAAS;AAAA,QACb,IAAI,UAAU;AAAA,QACd,IAAI,SAAS;AAAA,QACb,IAAI,UAAU,IAAI,UAAU;AAAA,QAC5B,OAAO,SAAS;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO,EAAE,YAAY,SAAS;AAChC;;;AC2BA,SAAS,YAAY,MAAiB,OAA0B;AAC9D,SAAO,KAAK,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,KAAK,IAAI;AAC1D;AAGA,SAAS,WAAW,QAA2B;AAC7C,SAAO,OACJ,IAAI,CAAC,MAAO,aAAa,OAAO,IAAI,IAAI,KAAK,OAAO,CAAC,CAAC,CAAE,EACxD,OAAO,CAAC,MAAM,CAAC,OAAO,MAAM,EAAE,QAAQ,CAAC,CAAC;AAC7C;AAGA,SAAS,aAAa,QAA6B;AACjD,SAAO,OACJ,IAAI,CAAC,MAAO,OAAO,MAAM,WAAW,IAAI,OAAO,CAAC,CAAE,EAClD,OAAO,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AACrC;AAGA,SAAS,cAAc,QAA6B;AAClD,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,SAAmB,CAAC;AAC1B,aAAW,KAAK,QAAQ;AACtB,UAAM,IAAI,OAAO,CAAC;AAClB,QAAI,CAAC,KAAK,IAAI,CAAC,GAAG;AAChB,WAAK,IAAI,CAAC;AACV,aAAO,KAAK,CAAC;AAAA,IACf;AAAA,EACF;AACA,SAAO;AACT;AAQA,SAAS,qBACP,QACA,MACU;AACV,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,SAAS,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,GAAG,QAAW,EAAE,SAAS,KAAK,CAAC,CAAC;AAC1F,MAAI,SAAS,aAAc,QAAO,QAAQ;AAC1C,SAAO;AACT;AAOA,SAAS,sBACP,OACA,SACM;AACN,MAAI,QAAQ,OAAO,OAAO;AACxB,UAAM,MAAM,IAAI;AAAA,EAClB;AACA,MAAI,QAAQ,OAAO,SAAS;AAC1B,UAAM,CAAC,IAAI,EAAE,IAAI,MAAM,MAAM;AAC7B,UAAM,MAAM,CAAC,IAAI,EAAE,CAAC;AAAA,EACtB;AACF;AAMA,SAAS,eACP,SACA,MACA,YACA,UACe;AACf,QAAM,SAAS,WAAW,YAAY,MAAM,QAAQ,KAAK,CAAC;AAC1D,QAAM,SAAS,QAAQ,OAAO,SAC1B,CAAC,IAAI,KAAK,QAAQ,MAAM,OAAO,CAAC,CAAW,GAAG,IAAI,KAAK,QAAQ,MAAM,OAAO,CAAC,CAAW,CAAC,IACxF,OAAO,MAAM;AAElB,QAAM,QAAQ,KAAU,EAAE,OAAO,MAAM,EAAE,MAAM,CAAC,YAAY,QAAQ,CAAC;AAMrE,MAAI,CAAC,QAAQ,OAAO,UAAU,QAAQ,OAAO,SAAS,MAAM;AAC1D,UAAM,KAAK;AAAA,EACb;AACA,wBAAsB,OAAO,OAAO;AAEpC,SAAO,EAAE,OAAO,MAAM,QAAQ,QAAQ;AACxC;AAEA,SAAS,cACP,SACA,MACA,YACA,UACe;AACf,QAAM,SAAS,WAAW,YAAY,MAAM,QAAQ,KAAK,CAAC;AAC1D,QAAM,SAAS,QAAQ,OAAO,SAC1B,CAAC,IAAI,KAAK,QAAQ,MAAM,OAAO,CAAC,CAAW,GAAG,IAAI,KAAK,QAAQ,MAAM,OAAO,CAAC,CAAW,CAAC,IACxF,OAAO,MAAM;AAElB,QAAM,QAAQ,QAAS,EAAE,OAAO,MAAM,EAAE,MAAM,CAAC,YAAY,QAAQ,CAAC;AAGpE,MAAI,CAAC,QAAQ,OAAO,UAAU,QAAQ,OAAO,SAAS,MAAM;AAC1D,UAAM,KAAK;AAAA,EACb;AACA,wBAAsB,OAAO,OAAO;AAEpC,SAAO,EAAE,OAAO,MAAM,OAAO,QAAQ;AACvC;AAEA,SAAS,iBACP,SACA,MACA,YACA,UACe;AACf,QAAM,SAAS,aAAa,YAAY,MAAM,QAAQ,KAAK,CAAC;AAE5D,MAAI;AACJ,MAAI;AAEJ,MAAI,QAAQ,OAAO,QAAQ;AACzB,UAAM,CAAC,IAAI,EAAE,IAAI,QAAQ,MAAM;AAC/B,gBAAY;AACZ,gBAAY;AAAA,EACd,OAAO;AACL,gBAAYE,KAAI,MAAM,KAAK;AAC3B,gBAAYC,KAAI,MAAM,KAAK;AAG3B,QAAI,QAAQ,OAAO,SAAS,OAAO;AACjC,kBAAY,KAAK,IAAI,GAAG,SAAS;AACjC,kBAAY,KAAK,IAAI,GAAG,SAAS;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,QAAQC,QAAY,EAAE,OAAO,CAAC,WAAW,SAAS,CAAC,EAAE,MAAM,CAAC,YAAY,QAAQ,CAAC;AAEvF,MAAI,CAAC,QAAQ,OAAO,UAAU,QAAQ,OAAO,SAAS,OAAO;AAC3D,UAAM,KAAK;AAAA,EACb;AACA,wBAAsB,OAAO,OAAO;AAEpC,SAAO,EAAE,OAAO,MAAM,UAAU,QAAQ;AAC1C;AAEA,SAAS,cACP,SACA,MACA,YACA,UACe;AACf,QAAM,SAAS,aAAa,YAAY,MAAM,QAAQ,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC;AACjF,QAAM,YAAY,QAAQ,OAAO,SAC5B,QAAQ,MAAM,OAA4B,CAAC,IAC3CF,KAAI,MAAM,KAAK;AACpB,QAAM,YAAY,QAAQ,OAAO,SAC5B,QAAQ,MAAM,OAA4B,CAAC,IAC3CC,KAAI,MAAM,KAAK;AAEpB,QAAM,QAAQ,IAAS,EAAE,OAAO,CAAC,WAAW,SAAS,CAAC,EAAE,MAAM,CAAC,YAAY,QAAQ,CAAC;AAEpF,MAAI,QAAQ,OAAO,SAAS,QAAW;AACrC,UAAM,KAAK,QAAQ,MAAM,IAAI;AAAA,EAC/B;AACA,MAAI,CAAC,QAAQ,OAAO,UAAU,QAAQ,OAAO,SAAS,OAAO;AAC3D,UAAM,KAAK;AAAA,EACb;AACA,wBAAsB,OAAO,OAAO;AAEpC,SAAO,EAAE,OAAO,MAAM,OAAO,QAAQ;AACvC;AAEA,SAAS,cACP,SACA,MACA,YACA,UACe;AACf,QAAM,SAAS,aAAa,YAAY,MAAM,QAAQ,KAAK,CAAC;AAE5D,MAAI;AACJ,MAAI;AAEJ,MAAI,QAAQ,OAAO,QAAQ;AACzB,KAAC,WAAW,SAAS,IAAI,QAAQ,MAAM;AAAA,EACzC,OAAO;AACL,gBAAYD,KAAI,MAAM,KAAK;AAC3B,gBAAYC,KAAI,MAAM,KAAK;AAC3B,QAAI,QAAQ,OAAO,SAAS,OAAO;AACjC,kBAAY,KAAK,IAAI,GAAG,SAAS;AACjC,kBAAY,KAAK,IAAI,GAAG,SAAS;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,QAAQ,IAAS,EAAE,OAAO,CAAC,WAAW,SAAS,CAAC,EAAE,MAAM,CAAC,YAAY,QAAQ,CAAC;AAEpF,MAAI,QAAQ,OAAO,aAAa,QAAW;AACzC,UAAM,SAAS,QAAQ,MAAM,QAAQ;AAAA,EACvC;AACA,MAAI,CAAC,QAAQ,OAAO,UAAU,QAAQ,OAAO,SAAS,OAAO;AAC3D,UAAM,KAAK;AAAA,EACb;AACA,wBAAsB,OAAO,OAAO;AAEpC,SAAO,EAAE,OAAO,MAAM,OAAO,QAAQ;AACvC;AAEA,SAAS,eACP,SACA,MACA,YACA,UACe;AACf,QAAM,SAAS,aAAa,YAAY,MAAM,QAAQ,KAAK,CAAC;AAE5D,MAAI;AACJ,MAAI;AAEJ,MAAI,QAAQ,OAAO,QAAQ;AACzB,KAAC,WAAW,SAAS,IAAI,QAAQ,MAAM;AAAA,EACzC,OAAO;AACL,gBAAYD,KAAI,MAAM,KAAK;AAC3B,gBAAYC,KAAI,MAAM,KAAK;AAC3B,QAAI,QAAQ,OAAO,SAAS,OAAO;AACjC,kBAAY,KAAK,IAAI,GAAG,SAAS;AACjC,kBAAY,KAAK,IAAI,GAAG,SAAS;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,QAAQE,MAAU,EAAE,OAAO,CAAC,WAAW,SAAS,CAAC,EAAE,MAAM,CAAC,YAAY,QAAQ,CAAC;AAErF,MAAI,CAAC,QAAQ,OAAO,UAAU,QAAQ,OAAO,SAAS,OAAO;AAC3D,UAAM,KAAK;AAAA,EACb;AACA,wBAAsB,OAAO,OAAO;AAEpC,SAAO,EAAE,OAAO,MAAM,QAAQ,QAAQ;AACxC;AAEA,SAAS,iBACP,SACA,MACA,YACA,UACe;AACf,QAAM,SAAS,aAAa,YAAY,MAAM,QAAQ,KAAK,CAAC;AAE5D,MAAI;AACJ,MAAI;AAEJ,MAAI,QAAQ,OAAO,QAAQ;AACzB,KAAC,WAAW,SAAS,IAAI,QAAQ,MAAM;AAAA,EACzC,OAAO;AACL,gBAAYH,KAAI,MAAM,KAAK;AAC3B,gBAAYC,KAAI,MAAM,KAAK;AAC3B,QAAI,QAAQ,OAAO,SAAS,OAAO;AACjC,kBAAY,KAAK,IAAI,GAAG,SAAS;AACjC,kBAAY,KAAK,IAAI,GAAG,SAAS;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,QAAQ,OAAY,EAAE,OAAO,CAAC,WAAW,SAAS,CAAC,EAAE,MAAM,CAAC,YAAY,QAAQ,CAAC;AAEvF,MAAI,QAAQ,OAAO,aAAa,QAAW;AACzC,UAAM,SAAS,QAAQ,MAAM,QAAQ;AAAA,EACvC;AACA,MAAI,CAAC,QAAQ,OAAO,UAAU,QAAQ,OAAO,SAAS,OAAO;AAC3D,UAAM,KAAK;AAAA,EACb;AACA,wBAAsB,OAAO,OAAO;AAEpC,SAAO,EAAE,OAAO,MAAM,UAAU,QAAQ;AAC1C;AAEA,SAAS,mBACP,SACA,MACA,YACA,UACe;AACf,QAAM,SAAS,aAAa,YAAY,MAAM,QAAQ,KAAK,CAAC;AAC5D,QAAMG,SAAQ,QAAQ,OAAO,QACxB,QAAQ,MAAM,QACf,UAAU,YAAY,UAAU,CAAC;AAErC,QAAM,QAAQC,UAAsB,EAAE,OAAO,MAAM,EAAE,MAAMD,MAAK;AAEhE,SAAO,EAAE,OAAoC,MAAM,YAAY,QAAQ;AACzE;AAEA,SAAS,mBACP,SACA,MACA,YACA,UACe;AACf,QAAM,SAAS,aAAa,YAAY,MAAM,QAAQ,KAAK,CAAC;AAC5D,QAAM,YAAY,QAAQ,OAAO,SAC5B,QAAQ,MAAM,OAA4B,CAAC,IAC3CJ,KAAI,MAAM,KAAK;AACpB,QAAM,YAAY,QAAQ,OAAO,SAC5B,QAAQ,MAAM,OAA4B,CAAC,IAC3CC,KAAI,MAAM,KAAK;AACpB,QAAMG,SAAQ,QAAQ,OAAO,QACxB,QAAQ,MAAM,QACf,UAAU,YAAY,UAAU,CAAC;AAErC,QAAM,QAAQ,SAAsB,EAAE,OAAO,CAAC,WAAW,SAAS,CAAC,EAAE,MAAMA,MAAK;AAEhF,SAAO,EAAE,OAAoC,MAAM,YAAY,QAAQ;AACzE;AAEA,SAAS,oBACP,SACA,OACA,YACA,UACe;AAEf,QAAM,eAAe,QAAQ,OAAO,SAAU,QAAQ,MAAM,SAAsB,CAAC,GAAG;AACtF,QAAMA,SAAQ,QAAQ,OAAO,QACxB,QAAQ,MAAM,QACf,UAAU,YAAY,UAAU,aAAa,SAAS,CAAC;AAE3D,QAAM,QAAQ,UAA+B,EAAE,OAAO,YAAY,EAAE,MAAMA,MAAK;AAE/E,SAAO,EAAE,OAAoC,MAAM,aAAa,QAAQ;AAC1E;AAGA,SAAS,UAAU,OAAe,KAAa,OAAyB;AACtE,MAAI,SAAS,EAAG,QAAO,CAAC,KAAK;AAC7B,QAAM,QAAQ,MAAM,UAAU,QAAQ;AACtC,SAAO,MAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,CAAC,GAAG,MAAM,QAAQ,OAAO,CAAC;AACjE;AAEA,SAAS,eACP,SACA,MACA,YACA,UACe;AACf,QAAM,SAAS,QAAQ,OAAO,SACzB,QAAQ,MAAM,SACf,qBAAqB,cAAc,YAAY,MAAM,QAAQ,KAAK,CAAC,GAAG,QAAQ,IAAI;AAEtF,QAAM,UAAU,QAAQ,OAAO,WAAW;AAC1C,QAAM,QAAQ,KAAU,EAAE,OAAO,MAAM,EAAE,MAAM,CAAC,YAAY,QAAQ,CAAC,EAAE,QAAQ,OAAO;AAEtF,MAAI,QAAQ,OAAO,iBAAiB,QAAW;AAC7C,UAAM,aAAa,QAAQ,MAAM,YAAY;AAAA,EAC/C;AACA,MAAI,QAAQ,OAAO,iBAAiB,QAAW;AAC7C,UAAM,aAAa,QAAQ,MAAM,YAAY;AAAA,EAC/C;AACA,MAAI,QAAQ,OAAO,SAAS;AAC1B,UAAM,CAAC,IAAI,EAAE,IAAI,MAAM,MAAM;AAC7B,UAAM,MAAM,CAAC,IAAI,EAAE,CAAC;AAAA,EACtB;AAEA,SAAO,EAAE,OAAO,MAAM,QAAQ,QAAQ;AACxC;AAEA,SAAS,gBACP,SACA,MACA,YACA,UACe;AACf,QAAM,SAAS,QAAQ,OAAO,SACzB,QAAQ,MAAM,SACf,qBAAqB,cAAc,YAAY,MAAM,QAAQ,KAAK,CAAC,GAAG,QAAQ,IAAI;AAEtF,QAAM,UAAU,QAAQ,OAAO,WAAW;AAC1C,QAAM,QAAQE,OAAW,EAAE,OAAO,MAAM,EAAE,MAAM,CAAC,YAAY,QAAQ,CAAC,EAAE,QAAQ,OAAO;AAEvF,MAAI,QAAQ,OAAO,SAAS;AAC1B,UAAM,CAAC,IAAI,EAAE,IAAI,MAAM,MAAM;AAC7B,UAAM,MAAM,CAAC,IAAI,EAAE,CAAC;AAAA,EACtB;AAEA,SAAO,EAAE,OAAO,MAAM,SAAS,QAAQ;AACzC;AAEA,SAAS,uBACP,SACA,MACA,SACe;AAEf,QAAM,iBAAiB,QAAQ,OAAO;AACtC,QAAM,SAAS,iBACX,eAAe,IAAI,MAAM,IACzB,qBAAqB,cAAc,YAAY,MAAM,QAAQ,KAAK,CAAC,GAAG,QAAQ,IAAI;AAGtF,QAAM,gBAAgB,QAAQ,OAAO;AACrC,QAAM,SAAS,iBAAiB;AAEhC,QAAM,QAAQ,QAAqB,EAAE,OAAO,MAAM,EAAE,MAAM,MAAM;AAEhE,SAAO,EAAE,OAAO,MAAM,WAAW,QAAQ;AAC3C;AAEA,SAAS,0BACP,SACA,MACA,SACe;AACf,QAAM,SAAS,aAAa,YAAY,MAAM,QAAQ,KAAK,CAAC;AAC5D,QAAM,YAAYN,KAAI,MAAM,KAAK;AACjC,QAAM,YAAYC,KAAI,MAAM,KAAK;AAGjC,QAAM,gBAAgB,QAAQ,OAAO;AACrC,QAAM,SAAS,iBAAiB;AAEhC,QAAM,QAAQC,QAAoB,EAC/B,OAAO,CAAC,WAAW,SAAS,CAAC,EAC7B,MAAM,CAAC,OAAO,CAAC,GAAG,OAAO,OAAO,SAAS,CAAC,CAAC,CAAC,EAC5C,MAAM,IAAI;AAKb,SAAO,EAAE,OAAoC,MAAM,cAAc,QAAQ;AAC3E;AAUA,SAAS,qBACP,SACA,MACA,YACA,UACA,WACA,MACe;AAEf,MAAI,QAAQ,OAAO,MAAM;AACvB,YAAQ,QAAQ,MAAM,MAAM;AAAA,MAC1B,KAAK;AACH,eAAO,eAAe,SAAS,MAAM,YAAY,QAAQ;AAAA,MAC3D,KAAK;AACH,eAAO,cAAc,SAAS,MAAM,YAAY,QAAQ;AAAA,MAC1D,KAAK;AACH,eAAO,iBAAiB,SAAS,MAAM,YAAY,QAAQ;AAAA,MAC7D,KAAK;AACH,eAAO,cAAc,SAAS,MAAM,YAAY,QAAQ;AAAA,MAC1D,KAAK;AACH,eAAO,cAAc,SAAS,MAAM,YAAY,QAAQ;AAAA,MAC1D,KAAK;AACH,eAAO,eAAe,SAAS,MAAM,YAAY,QAAQ;AAAA,MAC3D,KAAK;AACH,eAAO,iBAAiB,SAAS,MAAM,YAAY,QAAQ;AAAA,MAC7D,KAAK;AACH,eAAO,mBAAmB,SAAS,MAAM,YAAY,QAAQ;AAAA,MAC/D,KAAK;AACH,eAAO,mBAAmB,SAAS,MAAM,YAAY,QAAQ;AAAA,MAC/D,KAAK;AACH,eAAO,oBAAoB,SAAS,MAAM,YAAY,QAAQ;AAAA,MAChE,KAAK;AACH,eAAO,eAAe,SAAS,MAAM,YAAY,QAAQ;AAAA,MAC3D,KAAK;AACH,eAAO,gBAAgB,SAAS,MAAM,YAAY,QAAQ;AAAA,MAC5D,KAAK;AACH,eAAO,eAAe,SAAS,MAAM,YAAY,QAAQ;AAAA,IAC7D;AAAA,EACF;AAGA,UAAQ,QAAQ,MAAM;AAAA,IACpB,KAAK;AACH,aAAO,eAAe,SAAS,MAAM,YAAY,QAAQ;AAAA,IAC3D,KAAK;AACH,aAAO,iBAAiB,SAAS,MAAM,YAAY,QAAQ;AAAA,IAC7D,KAAK;AAAA,IACL,KAAK;AAEH,UACE,cAAc,UACZ,cAAc,YAAY,cAAc,eAAe,SAAS,KAClE;AACA,eAAO,eAAe,SAAS,MAAM,YAAY,QAAQ;AAAA,MAC3D;AACA,aAAO,gBAAgB,SAAS,MAAM,YAAY,QAAQ;AAAA,IAC5D;AACE,aAAO,iBAAiB,SAAS,MAAM,YAAY,QAAQ;AAAA,EAC/D;AACF;AAcO,SAAS,cACd,MACA,WACA,MACgB;AAChB,QAAM,SAAyB,CAAC;AAChC,QAAM,WAAW,KAAK;AAGtB,MAAI,KAAK,aAAa,SAAS;AAC7B,QAAI,SAAS,GAAG,SAAS,kBAAkB,SAAS,EAAE,OAAO,SAAS,QAAW;AAC/E,UAAI,CAAC,SAAS,EAAE,OAAO;AACrB,QAAC,SAAS,EAA0C,QAAQ,EAAE,MAAM,MAAM;AAAA,MAC5E,OAAO;AACL,QAAC,SAAS,EAAE,MAAkC,OAAO;AAAA,MACvD;AAAA,IACF;AACA,QAAI,SAAS,GAAG,SAAS,kBAAkB,SAAS,EAAE,OAAO,SAAS,QAAW;AAC/E,UAAI,CAAC,SAAS,EAAE,OAAO;AACrB,QAAC,SAAS,EAA0C,QAAQ,EAAE,MAAM,MAAM;AAAA,MAC5E,OAAO;AACL,QAAC,SAAS,EAAE,MAAkC,OAAO;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AAEA,MAAI,SAAS,GAAG;AAGd,QAAI,QAAQ;AACZ,QAAI,WAAW,SAAS;AACxB,UAAM,iBAAiB,SAAS,EAAE,UAAU,QAAQ,SAAS,EAAE,UAAU;AACzE,QACE,KAAK,aAAa,SAClB,SAAS,SACT,SAAS,EAAE,SAAS,kBACpB,CAAC,gBACD;AACA,UAAI,SAAS,EAAE,UAAU,aAAa;AAEpC,mBAAW,EAAE,GAAG,SAAS,GAAG,OAAO,EAAE,GAAG,SAAS,EAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,MAAM,EAAE;AAAA,MAC1F,WAAW,SAAS,EAAE,UAAU,UAAU;AAExC,cAAM,SAAS,SAAS,GAAG;AAC3B,cAAM,SAAS,SAAS,EAAE;AAC1B,YAAI,QAAQ;AACV,gBAAM,OAAO,oBAAI,IAAoB;AACrC,qBAAW,OAAO,MAAM;AACtB,kBAAM,MAAM,OAAO,IAAI,MAAM,KAAK,EAAE;AACpC,kBAAM,MAAM,OAAO,IAAI,MAAM,KAAK,CAAC;AACnC,gBAAI,OAAO,SAAS,GAAG,KAAK,MAAM,GAAG;AACnC,mBAAK,IAAI,MAAM,KAAK,IAAI,GAAG,KAAK,KAAK,GAAG;AAAA,YAC1C;AAAA,UACF;AACA,gBAAM,SAAS,KAAK,IAAI,GAAG,KAAK,OAAO,GAAG,CAAC;AAC3C,gBAAM,OAAO,SAAS;AACtB,qBAAW;AAAA,YACT,GAAG,SAAS;AAAA,YACZ,OAAO,EAAE,GAAG,SAAS,EAAE,OAAO,QAAQ,CAAC,CAAC,MAAM,IAAI,GAAG,MAAM,KAAK;AAAA,UAClE;AAAA,QACF;AAAA,MACF,OAAO;AAEL,cAAM,SAAS,SAAS,GAAG;AAC3B,cAAM,SAAS,SAAS,EAAE;AAC1B,YAAI,QAAQ;AACV,gBAAM,OAAO,oBAAI,IAAoB;AACrC,qBAAW,OAAO,MAAM;AACtB,kBAAM,MAAM,OAAO,IAAI,MAAM,KAAK,EAAE;AACpC,kBAAM,MAAM,OAAO,IAAI,MAAM,KAAK,CAAC;AACnC,gBAAI,OAAO,SAAS,GAAG,KAAK,MAAM,GAAG;AACnC,mBAAK,IAAI,MAAM,KAAK,IAAI,GAAG,KAAK,KAAK,GAAG;AAAA,YAC1C;AAAA,UACF;AACA,gBAAM,SAAS,KAAK,IAAI,GAAG,KAAK,OAAO,GAAG,CAAC;AAE3C,kBAAQ,CAAC,GAAG,MAAM,EAAE,CAAC,MAAM,GAAG,OAAO,CAAY;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AAEA,WAAO,IAAI;AAAA,MACT;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV,UAAU,IAAI,UAAU;AAAA,MACxB,KAAK;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAEA,MAAI,SAAS,GAAG;AAKd,QAAI,QAAQ;AACZ,QAAI,WAAW,SAAS;AACxB,UAAM,gBACJ,KAAK,aAAa,UACjB,SAAS,GAAG,SAAS,aAAa,SAAS,GAAG,SAAS,cACxD,SAAS,EAAE,SAAS;AACtB,UAAM,iBAAiB,SAAS,EAAE,UAAU,QAAQ,SAAS,EAAE,UAAU;AACzE,SACG,iBAAiB,KAAK,aAAa,WACpC,SAAS,SACT,SAAS,EAAE,SAAS,kBACpB,CAAC,gBACD;AACA,UAAI,SAAS,EAAE,UAAU,aAAa;AAEpC,mBAAW,EAAE,GAAG,SAAS,GAAG,OAAO,EAAE,GAAG,SAAS,EAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,MAAM,EAAE;AAAA,MAC1F,WAAW,SAAS,EAAE,UAAU,UAAU;AAExC,cAAM,SAAS,SAAS,GAAG;AAC3B,cAAM,SAAS,SAAS,EAAE;AAC1B,YAAI,QAAQ;AACV,gBAAM,OAAO,oBAAI,IAAoB;AACrC,qBAAW,OAAO,MAAM;AACtB,kBAAM,MAAM,OAAO,IAAI,MAAM,KAAK,EAAE;AACpC,kBAAM,MAAM,OAAO,IAAI,MAAM,KAAK,CAAC;AACnC,gBAAI,OAAO,SAAS,GAAG,KAAK,MAAM,GAAG;AACnC,mBAAK,IAAI,MAAM,KAAK,IAAI,GAAG,KAAK,KAAK,GAAG;AAAA,YAC1C;AAAA,UACF;AACA,gBAAM,SAAS,KAAK,IAAI,GAAG,KAAK,OAAO,GAAG,CAAC;AAC3C,gBAAM,OAAO,SAAS;AACtB,qBAAW;AAAA,YACT,GAAG,SAAS;AAAA,YACZ,OAAO,EAAE,GAAG,SAAS,EAAE,OAAO,QAAQ,CAAC,CAAC,MAAM,IAAI,GAAG,MAAM,KAAK;AAAA,UAClE;AAAA,QACF;AAAA,MACF,OAAO;AAEL,cAAM,SAAS,SAAS,GAAG;AAC3B,cAAM,SAAS,SAAS,EAAE;AAC1B,YAAI,QAAQ;AACV,gBAAM,OAAO,oBAAI,IAAoB;AACrC,qBAAW,OAAO,MAAM;AACtB,kBAAM,MAAM,OAAO,IAAI,MAAM,KAAK,EAAE;AACpC,kBAAM,MAAM,OAAO,IAAI,MAAM,KAAK,CAAC;AACnC,gBAAI,OAAO,SAAS,GAAG,KAAK,MAAM,GAAG;AACnC,mBAAK,IAAI,MAAM,KAAK,IAAI,GAAG,KAAK,KAAK,GAAG;AAAA,YAC1C;AAAA,UACF;AACA,gBAAM,SAAS,KAAK,IAAI,GAAG,KAAK,OAAO,GAAG,CAAC;AAE3C,kBAAQ,CAAC,GAAG,MAAM,EAAE,CAAC,MAAM,GAAG,OAAO,CAAY;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AAGA,WAAO,IAAI;AAAA,MACT;AAAA,MACA;AAAA,MACA,UAAU,IAAI,UAAU;AAAA,MACxB,UAAU;AAAA,MACV,KAAK;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAEA,MAAI,SAAS,OAAO;AAClB,UAAM,iBAAiB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,QAAI,WAAW,SAAS,OAAO;AAC7B,UAAI,SAAS,MAAM,SAAS,gBAAgB;AAE1C,eAAO,QAAQ,0BAA0B,SAAS,OAAO,MAAM,cAAc;AAAA,MAC/E,OAAO;AAEL,eAAO,QAAQ,uBAAuB,SAAS,OAAO,MAAM,cAAc;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AC5xBA,SAAS,uBAAAK,sBAAqB,qBAAAC,2BAAyB;;;ACLvD,SAAS,qBAAAC,0BAAyB;AAU3B,IAAMC,eAAc;AACpB,IAAMC,cAAa;AACnB,IAAMC,aAAY;AAuBlB,SAAS,kBACd,SACA,UACA,YACA,SACkB;AAClB,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,EAAE,UAAU,GAAG,cAAc,GAAG,WAAW,CAAC,EAAE;AAAA,EACvD;AAEA,MAAI,WAAW;AACf,MAAI,WAAW;AACf,QAAM,YAAsB,CAAC;AAC7B,MAAI,eAAe,QAAQ;AAC3B,MAAI,qBAAqB;AAEzB,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,aAAaH;AAAA,MACjB,QAAQ,CAAC,EAAE;AAAA,MACX,WAAW;AAAA,MACX,WAAW;AAAA,IACb;AACA,UAAM,aAAaC,eAAcC,cAAa,aAAaC;AAE3D,QAAI,WAAW,aAAa,YAAY,WAAW,GAAG;AACpD,gBAAU,KAAK,QAAQ;AACvB;AACA,iBAAW;AACX,UAAI,CAAC,sBAAsB,WAAW,QAAQ,WAAW,SAAS;AAChE,uBAAe;AACf,6BAAqB;AAAA,MACvB;AAAA,IACF,OAAO;AACL,kBAAY;AAAA,IACd;AAAA,EACF;AAGA,YAAU,KAAK,QAAQ;AAEvB,SAAO,EAAE,UAAU,cAAc,UAAU;AAC7C;;;AD9DA,IAAM,iBAAiB;AACvB,IAAM,qBAAqB;AAG3B,IAAM,gCAAgC;AAGtC,IAAM,sBAAsB;AAO5B,SAAS,mBAAmB,UAAwC;AAClE,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAGA,SAAS,oBAAoB,MAA2B,OAAqC;AAC3F,QAAM,WAAW,KAAK,SAAS;AAC/B,MAAI,CAAC,SAAU,QAAO,CAAC;AAGvB,MAAI,eAAe,SAAU,QAAO,CAAC;AAGrC,MAAI,SAAS,SAAS,eAAgB,QAAO,CAAC;AAE9C,QAAM,eAAe,CAAC,GAAG,IAAI,IAAI,KAAK,KAAK,IAAI,CAAC,MAAM,OAAO,EAAE,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC;AACjF,QAAM,iBAAiB,SAAS,OAAO;AACvC,QAAM,gBAAgB,SAAS,OAAO;AACtC,QAAM,UAAU,iBAAiB,MAAM,OAAO;AAC9C,QAAM,QAAQ,mBAAmB,KAAK,QAAQ;AAE9C,SAAO,aAAa,IAAI,CAACC,QAAO,MAAM;AAGpC,QAAI,aAAa;AACjB,QAAI,kBAAkB,eAAe;AACnC,YAAM,YAAY,eAAe,QAAQA,MAAK;AAC9C,UAAI,aAAa,EAAG,cAAa;AAAA,IACnC;AACA,WAAO;AAAA,MACL,OAAOA;AAAA,MACP,OAAO,QAAQ,aAAa,QAAQ,MAAM;AAAA,MAC1C;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF,CAAC;AACH;AAKA,SAAS,gBAAgB,SAAwB,UAAiC;AAChF,MAAI,YAAY,QAAQ,UAAU,YAAY,EAAG,QAAO;AAExD,QAAM,YAAY,QAAQ,MAAM,GAAG,QAAQ;AAC3C,QAAM,YAAY,QAAQ,SAAS;AACnC,YAAU,KAAK;AAAA,IACb,OAAO,IAAI,SAAS;AAAA,IACpB,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ,CAAC;AAED,SAAO;AACT;AAeO,SAAS,cACd,MACA,UACA,OACA,WACA,YAAqB,MACP;AAEd,MAAI,KAAK,QAAQ,SAAS,SAAS,SAAS,oBAAoB,GAAG;AACjE,WAAO;AAAA,MACL,UAAU;AAAA,MACV,SAAS,CAAC;AAAA,MACV,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,GAAG,QAAQ,EAAE;AAAA,MAC1C,YAAY;AAAA,QACV,YAAY,MAAM,MAAM;AAAA,QACxB,UAAU,MAAM,MAAM,MAAM;AAAA,QAC5B,YAAY,MAAM,MAAM,QAAQ;AAAA,QAChC,MAAM,MAAM,OAAO;AAAA,QACnB,YAAY;AAAA,MACd;AAAA,MACA,YAAYC;AAAA,MACZ,WAAWC;AAAA,MACX,UAAUC;AAAA,IACZ;AAAA,EACF;AAEA,MAAI,UAAU,oBAAoB,MAAM,KAAK;AAK7C,QAAM,eAAe,KAAK,aAAa,UAAU,KAAK,aAAa;AACnE,QAAM,YAAY,KAAK,OAAO,YAAY;AAC1C,QAAM,mBAAmB,SAAS,cAAc;AAChD,QAAM,mBAAmB,KAAK,SAAS,SAAS;AAChD,QAAM,kBAAkB,KAAK,QAAQ,SAAS;AAE9C,MAAI,gBAAgB,aAAa,oBAAoB,oBAAoB,iBAAiB;AACxF,UAAM,SAAS,KAAK,aAAa;AACjC,UAAM,eACJ,KAAK,SAAS,GAAG,SAAS,iBAAiB,KAAK,SAAS,IAAI,KAAK,SAAS;AAC7E,UAAMC,cAAa,cAAc;AACjC,UAAM,YAAYA,gBAAe,QAAQA,gBAAe;AAExD,QAAI,CAAC,UAAU,CAAC,WAAW;AACzB,gBAAU,CAAC;AAAA,IACb;AAAA,EACF;AAEA,QAAM,aAAwB;AAAA,IAC5B,YAAY,MAAM,MAAM;AAAA,IACxB,UAAU,MAAM,MAAM,MAAM;AAAA,IAC5B,YAAY,MAAM,MAAM,QAAQ;AAAA,IAChC,MAAM,MAAM,OAAO;AAAA,IACnB,YAAY;AAAA,EACd;AAGA,QAAM,mBACJ,KAAK,QAAQ,aAAa,SAAS,mBAAmB,UAAU,UAAU;AAG5E,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO;AAAA,MACL,UAAU;AAAA,MACV,SAAS,CAAC;AAAA,MACV,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,GAAG,QAAQ,EAAE;AAAA,MAC1C;AAAA,MACA,YAAYH;AAAA,MACZ,WAAWC;AAAA,MACX,UAAUC;AAAA,IACZ;AAAA,EACF;AAEA,MAAI,qBAAqB,WAAW,qBAAqB,gBAAgB;AAEvE,UAAM,gBAAgB,KAAK;AAAA,MACzB,GAAG,QAAQ,IAAI,CAAC,MAAME,oBAAkB,EAAE,OAAO,WAAW,UAAU,WAAW,UAAU,CAAC;AAAA,IAC9F;AACA,UAAM,cAAc,KAAK;AAAA,MACvB;AAAA,MACAJ,eAAcC,cAAa,gBAAgB,iBAAiB;AAAA,IAC9D;AACA,UAAM,cAAc,KAAK,IAAID,cAAa,WAAW,WAAW,WAAW,UAAU;AAGrF,UAAM,iBACJ,SAAS,kBAAkB,IAAI,SAAS,kBAAkB;AAC5D,UAAM,kBAAkB,UAAU,SAAS;AAG3C,UAAM,eAAe,KAAK;AAAA,MACxB;AAAA,MACA,KAAK,OAAO,kBAAkB,iBAAiB,MAAM,cAAc,EAAE;AAAA,IACvE;AAEA,UAAM,aACJ,KAAK,QAAQ,eAAe,OAAO,KAAK,IAAI,GAAG,KAAK,OAAO,WAAW,IAAI;AAC5E,QAAI,QAAQ,SAAS,YAAY;AAC/B,gBAAU,gBAAgB,SAAS,UAAU;AAAA,IAC/C;AAEA,UAAMK,gBACJ,QAAQ,SAAS,eAAe,QAAQ,SAAS,KAAK,IAAI,iBAAiB;AAC7E,UAAM,gBAAgB,KAAK,IAAIA,eAAc,UAAU,MAAM;AAG7D,UAAM,UACJ,qBAAqB,iBACjB,UAAU,IAAI,UAAU,SAAS,gBACjC,UAAU;AAGhB,UAAMC,YAAW,KAAK,QAAQ,QAAQ,MAAM;AAC5C,UAAMC,YAAW,KAAK,QAAQ,QAAQ,MAAM;AAE5C,WAAO;AAAA,MACL,UAAU;AAAA,MACV;AAAA,MACA,QAAQ;AAAA,QACN,GAAG,UAAU,IAAI,UAAU,QAAQ,cAAcD;AAAA,QACjD,GAAG,UAAUC;AAAA,QACb,OAAO;AAAA,QACP,QAAQ;AAAA,MACV;AAAA,MACA;AAAA,MACA,YAAYP;AAAA,MACZ,WAAWC;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAKA,QAAM,eAAe,aAAa,qBAAqB;AACvD,QAAM,iBACJ,UAAU,QAAQ,iBAAiB,KAAK,eAAeO,uBAAsB;AAG/E,MAAI,KAAK,QAAQ,eAAe,MAAM;AACpC,UAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,OAAO,WAAW;AACjD,QAAI,QAAQ,QAAQ,QAAQ;AAC1B,gBAAU,gBAAgB,SAAS,KAAK;AAAA,IAC1C;AAAA,EACF;AAGA,QAAM,UACJ,KAAK,QAAQ,WAAW,OACpB,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,IAC/B,KAAK,QAAQ,WAAW,OACtB,KAAK,KAAK,QAAQ,SAAS,KAAK,OAAO,OAAO,IAC9C;AACR,QAAM,EAAE,aAAa,IAAI,kBAAkB,SAAS,gBAAgB,YAAY,OAAO;AAEvF,MAAI,eAAe,QAAQ,QAAQ;AACjC,cAAU,gBAAgB,SAAS,YAAY;AAAA,EACjD;AAEA,QAAM,aAAa,QAAQ,OAAO,CAACC,MAAK,UAAU;AAChD,UAAM,aAAaL,oBAAkB,MAAM,OAAO,WAAW,UAAU,WAAW,UAAU;AAC5F,WAAOK,OAAMT,eAAcC,cAAa,aAAaC;AAAA,EACvD,GAAG,CAAC;AAGJ,QAAM,EAAE,SAAS,IAAI,kBAAkB,SAAS,gBAAgB,UAAU;AAE1E,QAAM,YAAYF,eAAc;AAChC,QAAM,eAAe,WAAW,YAAY,iBAAiB;AAG7D,QAAM,WAAW,KAAK,QAAQ,QAAQ,MAAM;AAC5C,QAAM,WAAW,KAAK,QAAQ,QAAQ,MAAM;AAE5C,SAAO;AAAA,IACL,UAAU;AAAA,IACV;AAAA,IACA,QAAQ;AAAA,MACN,GAAG,UAAU,IAAI;AAAA,MACjB,IACG,qBAAqB,WAClB,UAAU,IAAI,UAAU,SAAS,eACjC,UAAU,KAAK;AAAA,MACrB,OAAO,KAAK,IAAI,YAAY,cAAc;AAAA,MAC1C,QAAQ;AAAA,IACV;AAAA,IACA;AAAA,IACA,YAAYA;AAAA,IACZ,WAAWC;AAAA,IACX,UAAUC;AAAA,EACZ;AACF;;;AEhSA;AAAA,EACE,cAAAQ;AAAA,EACA,oBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,gBAAAC;AAAA,OACK;;;ACnCQ,SAARC,KAAqB,QAAQ,SAAS;AAC3C,MAAIA;AACJ,MAAI,YAAY,QAAW;AACzB,eAAWC,UAAS,QAAQ;AAC1B,UAAIA,UAAS,SACLD,OAAMC,UAAUD,SAAQ,UAAaC,UAASA,SAAS;AAC7D,QAAAD,OAAMC;AAAA,MACR;AAAA,IACF;AAAA,EACF,OAAO;AACL,QAAI,QAAQ;AACZ,aAASA,UAAS,QAAQ;AACxB,WAAKA,SAAQ,QAAQA,QAAO,EAAE,OAAO,MAAM,MAAM,SACzCD,OAAMC,UAAUD,SAAQ,UAAaC,UAASA,SAAS;AAC7D,QAAAD,OAAMC;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAOD;AACT;;;ACnBe,SAARE,KAAqB,QAAQ,SAAS;AAC3C,MAAIA;AACJ,MAAI,YAAY,QAAW;AACzB,eAAWC,UAAS,QAAQ;AAC1B,UAAIA,UAAS,SACLD,OAAMC,UAAUD,SAAQ,UAAaC,UAASA,SAAS;AAC7D,QAAAD,OAAMC;AAAA,MACR;AAAA,IACF;AAAA,EACF,OAAO;AACL,QAAI,QAAQ;AACZ,aAASA,UAAS,QAAQ;AACxB,WAAKA,SAAQ,QAAQA,QAAO,EAAE,OAAO,MAAM,MAAM,SACzCD,OAAMC,UAAUD,SAAQ,UAAaC,UAASA,SAAS;AAC7D,QAAAD,OAAMC;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAOD;AACT;;;ACnBe,SAAR,IAAqB,QAAQ,SAAS;AAC3C,MAAIE,OAAM;AACV,MAAI,YAAY,QAAW;AACzB,aAASC,UAAS,QAAQ;AACxB,UAAIA,SAAQ,CAACA,QAAO;AAClB,QAAAD,QAAOC;AAAA,MACT;AAAA,IACF;AAAA,EACF,OAAO;AACL,QAAI,QAAQ;AACZ,aAASA,UAAS,QAAQ;AACxB,UAAIA,SAAQ,CAAC,QAAQA,QAAO,EAAE,OAAO,MAAM,GAAG;AAC5C,QAAAD,QAAOC;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,SAAOD;AACT;;;ACfA,SAAS,YAAY,GAAG;AACtB,SAAO,EAAE,OAAO;AAClB;AAEO,SAAS,KAAK,MAAM;AACzB,SAAO,KAAK;AACd;AAEO,SAAS,MAAM,MAAM,GAAG;AAC7B,SAAO,IAAI,IAAI,KAAK;AACtB;AAEO,SAAS,QAAQ,MAAM,GAAG;AAC/B,SAAO,KAAK,YAAY,SAAS,KAAK,QAAQ,IAAI;AACpD;AAEO,SAAS,OAAO,MAAM;AAC3B,SAAO,KAAK,YAAY,SAAS,KAAK,QAChC,KAAK,YAAY,SAASE,KAAI,KAAK,aAAa,WAAW,IAAI,IAC/D;AACR;;;ACtBe,SAAR,SAA0BC,IAAG;AAClC,SAAO,WAAW;AAChB,WAAOA;AAAA,EACT;AACF;;;ACAA,SAAS,uBAAuB,GAAG,GAAG;AACpC,SAAO,iBAAiB,EAAE,QAAQ,EAAE,MAAM,KAAK,EAAE,QAAQ,EAAE;AAC7D;AAEA,SAAS,uBAAuB,GAAG,GAAG;AACpC,SAAO,iBAAiB,EAAE,QAAQ,EAAE,MAAM,KAAK,EAAE,QAAQ,EAAE;AAC7D;AAEA,SAAS,iBAAiB,GAAG,GAAG;AAC9B,SAAO,EAAE,KAAK,EAAE;AAClB;AAEA,SAAS,MAAM,GAAG;AAChB,SAAO,EAAE;AACX;AAEA,SAAS,UAAU,GAAG;AACpB,SAAO,EAAE;AACX;AAEA,SAAS,aAAa,OAAO;AAC3B,SAAO,MAAM;AACf;AAEA,SAAS,aAAa,OAAO;AAC3B,SAAO,MAAM;AACf;AAEA,SAAS,KAAK,UAAU,IAAI;AAC1B,QAAM,OAAO,SAAS,IAAI,EAAE;AAC5B,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,cAAc,EAAE;AAC3C,SAAO;AACT;AAEA,SAAS,oBAAoB,EAAC,MAAK,GAAG;AACpC,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,KAAK;AACd,QAAI,KAAK;AACT,eAAW,QAAQ,KAAK,aAAa;AACnC,WAAK,KAAK,KAAK,KAAK,QAAQ;AAC5B,YAAM,KAAK;AAAA,IACb;AACA,eAAW,QAAQ,KAAK,aAAa;AACnC,WAAK,KAAK,KAAK,KAAK,QAAQ;AAC5B,YAAM,KAAK;AAAA,IACb;AAAA,EACF;AACF;AAEe,SAAR,SAA0B;AAC/B,MAAI,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK;AACjC,MAAI,KAAK;AACT,MAAI,KAAK,GAAG;AACZ,MAAI,KAAK;AACT,MAAI,QAAQ;AACZ,MAAI;AACJ,MAAI;AACJ,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,MAAI,aAAa;AAEjB,WAAS,SAAS;AAChB,UAAM,QAAQ,EAAC,OAAO,MAAM,MAAM,MAAM,SAAS,GAAG,OAAO,MAAM,MAAM,MAAM,SAAS,EAAC;AACvF,qBAAiB,KAAK;AACtB,sBAAkB,KAAK;AACvB,sBAAkB,KAAK;AACvB,uBAAmB,KAAK;AACxB,wBAAoB,KAAK;AACzB,wBAAoB,KAAK;AACzB,WAAO;AAAA,EACT;AAEA,SAAO,SAAS,SAAS,OAAO;AAC9B,wBAAoB,KAAK;AACzB,WAAO;AAAA,EACT;AAEA,SAAO,SAAS,SAAS,GAAG;AAC1B,WAAO,UAAU,UAAU,KAAK,OAAO,MAAM,aAAa,IAAI,SAAS,CAAC,GAAG,UAAU;AAAA,EACvF;AAEA,SAAO,YAAY,SAAS,GAAG;AAC7B,WAAO,UAAU,UAAU,QAAQ,OAAO,MAAM,aAAa,IAAI,SAAS,CAAC,GAAG,UAAU;AAAA,EAC1F;AAEA,SAAO,WAAW,SAAS,GAAG;AAC5B,WAAO,UAAU,UAAU,OAAO,GAAG,UAAU;AAAA,EACjD;AAEA,SAAO,YAAY,SAAS,GAAG;AAC7B,WAAO,UAAU,UAAU,KAAK,CAAC,GAAG,UAAU;AAAA,EAChD;AAEA,SAAO,cAAc,SAAS,GAAG;AAC/B,WAAO,UAAU,UAAU,KAAK,KAAK,CAAC,GAAG,UAAU;AAAA,EACrD;AAEA,SAAO,QAAQ,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,QAAQ,OAAO,MAAM,aAAa,IAAI,SAAS,CAAC,GAAG,UAAU;AAAA,EAC1F;AAEA,SAAO,QAAQ,SAAS,GAAG;AACzB,WAAO,UAAU,UAAU,QAAQ,OAAO,MAAM,aAAa,IAAI,SAAS,CAAC,GAAG,UAAU;AAAA,EAC1F;AAEA,SAAO,WAAW,SAAS,GAAG;AAC5B,WAAO,UAAU,UAAU,WAAW,GAAG,UAAU;AAAA,EACrD;AAEA,SAAO,OAAO,SAAS,GAAG;AACxB,WAAO,UAAU,UAAU,KAAK,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,KAAK,IAAI,KAAK,EAAE;AAAA,EAC7F;AAEA,SAAO,SAAS,SAAS,GAAG;AAC1B,WAAO,UAAU,UAAU,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;AAAA,EACtH;AAEA,SAAO,aAAa,SAAS,GAAG;AAC9B,WAAO,UAAU,UAAU,aAAa,CAAC,GAAG,UAAU;AAAA,EACxD;AAEA,WAAS,iBAAiB,EAAC,OAAAC,QAAO,OAAAC,OAAK,GAAG;AACxC,eAAW,CAAC,GAAG,IAAI,KAAKD,OAAM,QAAQ,GAAG;AACvC,WAAK,QAAQ;AACb,WAAK,cAAc,CAAC;AACpB,WAAK,cAAc,CAAC;AAAA,IACtB;AACA,UAAM,WAAW,IAAI,IAAIA,OAAM,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,GAAG,GAAGA,MAAK,GAAG,CAAC,CAAC,CAAC;AAClE,eAAW,CAAC,GAAG,IAAI,KAAKC,OAAM,QAAQ,GAAG;AACvC,WAAK,QAAQ;AACb,UAAI,EAAC,QAAQ,OAAM,IAAI;AACvB,UAAI,OAAO,WAAW,SAAU,UAAS,KAAK,SAAS,KAAK,UAAU,MAAM;AAC5E,UAAI,OAAO,WAAW,SAAU,UAAS,KAAK,SAAS,KAAK,UAAU,MAAM;AAC5E,aAAO,YAAY,KAAK,IAAI;AAC5B,aAAO,YAAY,KAAK,IAAI;AAAA,IAC9B;AACA,QAAI,YAAY,MAAM;AACpB,iBAAW,EAAC,aAAa,YAAW,KAAKD,QAAO;AAC9C,oBAAY,KAAK,QAAQ;AACzB,oBAAY,KAAK,QAAQ;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAEA,WAAS,kBAAkB,EAAC,OAAAA,OAAK,GAAG;AAClC,eAAW,QAAQA,QAAO;AACxB,WAAK,QAAQ,KAAK,eAAe,SAC3B,KAAK,IAAI,IAAI,KAAK,aAAa,KAAK,GAAG,IAAI,KAAK,aAAa,KAAK,CAAC,IACnE,KAAK;AAAA,IACb;AAAA,EACF;AAEA,WAAS,kBAAkB,EAAC,OAAAA,OAAK,GAAG;AAClC,UAAM,IAAIA,OAAM;AAChB,QAAI,UAAU,IAAI,IAAIA,MAAK;AAC3B,QAAI,OAAO,oBAAI;AACf,QAAIE,KAAI;AACR,WAAO,QAAQ,MAAM;AACnB,iBAAW,QAAQ,SAAS;AAC1B,aAAK,QAAQA;AACb,mBAAW,EAAC,OAAM,KAAK,KAAK,aAAa;AACvC,eAAK,IAAI,MAAM;AAAA,QACjB;AAAA,MACF;AACA,UAAI,EAAEA,KAAI,EAAG,OAAM,IAAI,MAAM,eAAe;AAC5C,gBAAU;AACV,aAAO,oBAAI;AAAA,IACb;AAAA,EACF;AAEA,WAAS,mBAAmB,EAAC,OAAAF,OAAK,GAAG;AACnC,UAAM,IAAIA,OAAM;AAChB,QAAI,UAAU,IAAI,IAAIA,MAAK;AAC3B,QAAI,OAAO,oBAAI;AACf,QAAIE,KAAI;AACR,WAAO,QAAQ,MAAM;AACnB,iBAAW,QAAQ,SAAS;AAC1B,aAAK,SAASA;AACd,mBAAW,EAAC,OAAM,KAAK,KAAK,aAAa;AACvC,eAAK,IAAI,MAAM;AAAA,QACjB;AAAA,MACF;AACA,UAAI,EAAEA,KAAI,EAAG,OAAM,IAAI,MAAM,eAAe;AAC5C,gBAAU;AACV,aAAO,oBAAI;AAAA,IACb;AAAA,EACF;AAEA,WAAS,kBAAkB,EAAC,OAAAF,OAAK,GAAG;AAClC,UAAME,KAAIC,KAAIH,QAAO,OAAK,EAAE,KAAK,IAAI;AACrC,UAAM,MAAM,KAAK,KAAK,OAAOE,KAAI;AACjC,UAAM,UAAU,IAAI,MAAMA,EAAC;AAC3B,eAAW,QAAQF,QAAO;AACxB,YAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAIE,KAAI,GAAG,KAAK,MAAM,MAAM,KAAK,MAAM,MAAMA,EAAC,CAAC,CAAC,CAAC;AAC5E,WAAK,QAAQ;AACb,WAAK,KAAK,KAAK,IAAI;AACnB,WAAK,KAAK,KAAK,KAAK;AACpB,UAAI,QAAQ,CAAC,EAAG,SAAQ,CAAC,EAAE,KAAK,IAAI;AAAA,UAC/B,SAAQ,CAAC,IAAI,CAAC,IAAI;AAAA,IACzB;AACA,QAAI,KAAM,YAAW,UAAU,SAAS;AACtC,aAAO,KAAK,IAAI;AAAA,IAClB;AACA,WAAO;AAAA,EACT;AAEA,WAAS,uBAAuB,SAAS;AACvC,UAAM,KAAKE,KAAI,SAAS,QAAM,KAAK,MAAM,EAAE,SAAS,KAAK,MAAM,IAAI,GAAG,KAAK,CAAC;AAC5E,eAAWJ,UAAS,SAAS;AAC3B,UAAIK,KAAI;AACR,iBAAW,QAAQL,QAAO;AACxB,aAAK,KAAKK;AACV,aAAK,KAAKA,KAAI,KAAK,QAAQ;AAC3B,QAAAA,KAAI,KAAK,KAAK;AACd,mBAAW,QAAQ,KAAK,aAAa;AACnC,eAAK,QAAQ,KAAK,QAAQ;AAAA,QAC5B;AAAA,MACF;AACA,MAAAA,MAAK,KAAKA,KAAI,OAAOL,OAAM,SAAS;AACpC,eAAS,IAAI,GAAG,IAAIA,OAAM,QAAQ,EAAE,GAAG;AACrC,cAAM,OAAOA,OAAM,CAAC;AACpB,aAAK,MAAMK,MAAK,IAAI;AACpB,aAAK,MAAMA,MAAK,IAAI;AAAA,MACtB;AACA,mBAAaL,MAAK;AAAA,IACpB;AAAA,EACF;AAEA,WAAS,oBAAoB,OAAO;AAClC,UAAM,UAAU,kBAAkB,KAAK;AACvC,SAAK,KAAK,IAAI,KAAK,KAAK,OAAOG,KAAI,SAAS,OAAK,EAAE,MAAM,IAAI,EAAE;AAC/D,2BAAuB,OAAO;AAC9B,aAAS,IAAI,GAAG,IAAI,YAAY,EAAE,GAAG;AACnC,YAAM,QAAQ,KAAK,IAAI,MAAM,CAAC;AAC9B,YAAM,OAAO,KAAK,IAAI,IAAI,QAAQ,IAAI,KAAK,UAAU;AACrD,uBAAiB,SAAS,OAAO,IAAI;AACrC,uBAAiB,SAAS,OAAO,IAAI;AAAA,IACvC;AAAA,EACF;AAGA,WAAS,iBAAiB,SAAS,OAAO,MAAM;AAC9C,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAAI,GAAG,EAAE,GAAG;AAC9C,YAAM,SAAS,QAAQ,CAAC;AACxB,iBAAW,UAAU,QAAQ;AAC3B,YAAIE,KAAI;AACR,YAAI,IAAI;AACR,mBAAW,EAAC,QAAQ,OAAAC,OAAK,KAAK,OAAO,aAAa;AAChD,cAAI,IAAIA,UAAS,OAAO,QAAQ,OAAO;AACvC,UAAAD,MAAK,UAAU,QAAQ,MAAM,IAAI;AACjC,eAAK;AAAA,QACP;AACA,YAAI,EAAE,IAAI,GAAI;AACd,YAAIE,OAAMF,KAAI,IAAI,OAAO,MAAM;AAC/B,eAAO,MAAME;AACb,eAAO,MAAMA;AACb,yBAAiB,MAAM;AAAA,MACzB;AACA,UAAI,SAAS,OAAW,QAAO,KAAK,gBAAgB;AACpD,MAAAC,mBAAkB,QAAQ,IAAI;AAAA,IAChC;AAAA,EACF;AAGA,WAAS,iBAAiB,SAAS,OAAO,MAAM;AAC9C,aAAS,IAAI,QAAQ,QAAQ,IAAI,IAAI,GAAG,KAAK,GAAG,EAAE,GAAG;AACnD,YAAM,SAAS,QAAQ,CAAC;AACxB,iBAAW,UAAU,QAAQ;AAC3B,YAAIH,KAAI;AACR,YAAI,IAAI;AACR,mBAAW,EAAC,QAAQ,OAAAC,OAAK,KAAK,OAAO,aAAa;AAChD,cAAI,IAAIA,UAAS,OAAO,QAAQ,OAAO;AACvC,UAAAD,MAAK,UAAU,QAAQ,MAAM,IAAI;AACjC,eAAK;AAAA,QACP;AACA,YAAI,EAAE,IAAI,GAAI;AACd,YAAIE,OAAMF,KAAI,IAAI,OAAO,MAAM;AAC/B,eAAO,MAAME;AACb,eAAO,MAAMA;AACb,yBAAiB,MAAM;AAAA,MACzB;AACA,UAAI,SAAS,OAAW,QAAO,KAAK,gBAAgB;AACpD,MAAAC,mBAAkB,QAAQ,IAAI;AAAA,IAChC;AAAA,EACF;AAEA,WAASA,mBAAkBR,QAAO,OAAO;AACvC,UAAM,IAAIA,OAAM,UAAU;AAC1B,UAAM,UAAUA,OAAM,CAAC;AACvB,iCAA6BA,QAAO,QAAQ,KAAK,IAAI,IAAI,GAAG,KAAK;AACjE,iCAA6BA,QAAO,QAAQ,KAAK,IAAI,IAAI,GAAG,KAAK;AACjE,iCAA6BA,QAAO,IAAIA,OAAM,SAAS,GAAG,KAAK;AAC/D,iCAA6BA,QAAO,IAAI,GAAG,KAAK;AAAA,EAClD;AAGA,WAAS,6BAA6BA,QAAOK,IAAG,GAAG,OAAO;AACxD,WAAO,IAAIL,OAAM,QAAQ,EAAE,GAAG;AAC5B,YAAM,OAAOA,OAAM,CAAC;AACpB,YAAMO,OAAMF,KAAI,KAAK,MAAM;AAC3B,UAAIE,MAAK,KAAM,MAAK,MAAMA,KAAI,KAAK,MAAMA;AACzC,MAAAF,KAAI,KAAK,KAAK;AAAA,IAChB;AAAA,EACF;AAGA,WAAS,6BAA6BL,QAAOK,IAAG,GAAG,OAAO;AACxD,WAAO,KAAK,GAAG,EAAE,GAAG;AAClB,YAAM,OAAOL,OAAM,CAAC;AACpB,YAAMO,OAAM,KAAK,KAAKF,MAAK;AAC3B,UAAIE,MAAK,KAAM,MAAK,MAAMA,KAAI,KAAK,MAAMA;AACzC,MAAAF,KAAI,KAAK,KAAK;AAAA,IAChB;AAAA,EACF;AAEA,WAAS,iBAAiB,EAAC,aAAa,YAAW,GAAG;AACpD,QAAI,aAAa,QAAW;AAC1B,iBAAW,EAAC,QAAQ,EAAC,aAAAI,aAAW,EAAC,KAAK,aAAa;AACjD,QAAAA,aAAY,KAAK,sBAAsB;AAAA,MACzC;AACA,iBAAW,EAAC,QAAQ,EAAC,aAAAC,aAAW,EAAC,KAAK,aAAa;AACjD,QAAAA,aAAY,KAAK,sBAAsB;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAEA,WAAS,aAAaV,QAAO;AAC3B,QAAI,aAAa,QAAW;AAC1B,iBAAW,EAAC,aAAa,YAAW,KAAKA,QAAO;AAC9C,oBAAY,KAAK,sBAAsB;AACvC,oBAAY,KAAK,sBAAsB;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAGA,WAAS,UAAU,QAAQ,QAAQ;AACjC,QAAIK,KAAI,OAAO,MAAM,OAAO,YAAY,SAAS,KAAK,KAAK;AAC3D,eAAW,EAAC,QAAQ,MAAM,MAAK,KAAK,OAAO,aAAa;AACtD,UAAI,SAAS,OAAQ;AACrB,MAAAA,MAAK,QAAQ;AAAA,IACf;AACA,eAAW,EAAC,QAAQ,MAAM,MAAK,KAAK,OAAO,aAAa;AACtD,UAAI,SAAS,OAAQ;AACrB,MAAAA,MAAK;AAAA,IACP;AACA,WAAOA;AAAA,EACT;AAGA,WAAS,UAAU,QAAQ,QAAQ;AACjC,QAAIA,KAAI,OAAO,MAAM,OAAO,YAAY,SAAS,KAAK,KAAK;AAC3D,eAAW,EAAC,QAAQ,MAAM,MAAK,KAAK,OAAO,aAAa;AACtD,UAAI,SAAS,OAAQ;AACrB,MAAAA,MAAK,QAAQ;AAAA,IACf;AACA,eAAW,EAAC,QAAQ,MAAM,MAAK,KAAK,OAAO,aAAa;AACtD,UAAI,SAAS,OAAQ;AACrB,MAAAA,MAAK;AAAA,IACP;AACA,WAAOA;AAAA,EACT;AAEA,SAAO;AACT;;;ACxUA,IAAM,YAA2D;AAAA,EAC/D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAoBO,SAAS,oBACd,MACA,aACA,aACA,YACA,MACA,WACA,aACA,WACA,YACA,UACoB;AAEpB,QAAM,UAAU,oBAAI,IAAY;AAChC,aAAW,OAAO,MAAM;AACtB,YAAQ,IAAI,OAAO,IAAI,WAAW,CAAC,CAAC;AACpC,YAAQ,IAAI,OAAO,IAAI,WAAW,CAAC,CAAC;AAAA,EACtC;AAGA,QAAM,QAA8C,CAAC,GAAG,OAAO,EAAE,IAAI,CAAC,QAAQ;AAAA,IAC5E;AAAA,IACA,OAAO;AAAA,EACT,EAAE;AAEF,QAAM,QAKD,KAAK,IAAI,CAAC,SAAS;AAAA,IACtB,QAAQ,OAAO,IAAI,WAAW,CAAC;AAAA,IAC/B,QAAQ,OAAO,IAAI,WAAW,CAAC;AAAA,IAC/B,OAAO,OAAO,IAAI,UAAU,CAAC,KAAK;AAAA,IAClC,MAAM,EAAE,GAAG,IAAI;AAAA,EACjB,EAAE;AAGF,QAAM,UAAU,UAAU,SAAS,KAAK;AAExC,QAAM,YAAY,OAAgE,EAC/E,OAAO,CAAC,MAAM,EAAE,EAAE,EAClB,UAAU,OAAmF,EAC7F,UAAU,SAAS,EACnB,YAAY,WAAW,EACvB,OAAO;AAAA,IACN,CAAC,KAAK,GAAG,KAAK,CAAC;AAAA,IACf,CAAC,KAAK,IAAI,KAAK,OAAO,KAAK,IAAI,KAAK,MAAM;AAAA,EAC5C,CAAC,EACA,WAAW,UAAU;AAKxB,MAAI,YAAY,SAAS,SAAS,GAAG;AACnC,UAAM,WAAW,IAAI,IAAI,SAAS,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AACzD,UAAM,WAAW,SAAS;AAC1B,cAAU;AAAA,MACR,CAAC,GAAqC,OACnC,SAAS,IAAK,EAA2B,EAAE,KAAK,aAChD,SAAS,IAAK,EAA2B,EAAE,KAAK;AAAA,IACrD;AAAA,EACF;AAEA,QAAM,QAAQ,UAAU;AAAA,IACtB;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,OAAO,MAAM;AAAA,IACb,OAAO,MAAM;AAAA,EACf;AACF;AAgBO,SAAS,iBAAiB,MAA4B;AAC3D,QAAM,SAAS,KAAK;AACpB,QAAM,SAAS,KAAK;AAEpB,QAAM,KAAK,OAAO,MAAM;AACxB,QAAM,KAAK,OAAO,MAAM;AACxB,QAAM,KAAK,KAAK,MAAM;AACtB,QAAM,KAAK,KAAK,MAAM;AACtB,QAAM,cAAc,KAAK,SAAS,KAAK;AACvC,QAAM,aAAa;AAGnB,QAAM,MAAM,KAAK,MAAM;AAGvB,QAAM,QAAQ,KAAK;AACnB,QAAM,QAAQ,KAAK;AAGnB,QAAM,QAAQ,KAAK;AACnB,QAAM,QAAQ,KAAK;AAEnB,SAAO;AAAA,IACL,IAAI,EAAE,IAAI,KAAK;AAAA,IACf,IAAI,EAAE,IAAI,KAAK,IAAI,EAAE,IAAI,KAAK,IAAI,EAAE,IAAI,KAAK;AAAA,IAC7C,IAAI,EAAE,IAAI,KAAK;AAAA,IACf,IAAI,EAAE,IAAI,KAAK,IAAI,EAAE,IAAI,KAAK,IAAI,EAAE,IAAI,KAAK;AAAA,IAC7C;AAAA,EACF,EAAE,KAAK,GAAG;AACZ;;;APxIA,IAAM,YAAY;AAClB,IAAM,qBAAqB;AAC3B,IAAM,oBAAoB;AAC1B,IAAM,qBAAqB;AAO3B,SAAS,UAAU,SAAmB,OAAuB;AAC3D,SAAO,QAAQ,QAAQ,QAAQ,MAAM;AACvC;AAQA,SAAS,kBACP,OACA,SACA,YACA,MACA,aACA,aACqB;AACrB,QAAM,WAAW,oBAAI,IAAoB;AAEzC,MAAI,YAAY;AAEd,UAAM,kBAAkB,oBAAI,IAAoB;AAChD,eAAW,OAAO,MAAM;AACtB,YAAM,MAAM,OAAO,IAAI,WAAW,CAAC;AACnC,YAAM,MAAM,OAAO,IAAI,WAAW,CAAC;AACnC,YAAM,MAAM,OAAO,IAAI,UAAU,CAAC;AAClC,UAAI,CAAC,gBAAgB,IAAI,GAAG,EAAG,iBAAgB,IAAI,KAAK,GAAG;AAC3D,UAAI,CAAC,gBAAgB,IAAI,GAAG,EAAG,iBAAgB,IAAI,KAAK,GAAG;AAAA,IAC7D;AAGA,UAAM,gBAAgB,oBAAI,IAAoB;AAC9C,QAAI,UAAU;AACd,eAAW,QAAQ,OAAO;AACxB,YAAM,WAAW,gBAAgB,IAAI,KAAK,EAAE,KAAK,KAAK;AACtD,UAAI,CAAC,cAAc,IAAI,QAAQ,GAAG;AAChC,sBAAc,IAAI,UAAU,SAAS;AAAA,MACvC;AACA,eAAS,IAAI,KAAK,IAAI,UAAU,SAAS,cAAc,IAAI,QAAQ,CAAE,CAAC;AAAA,IACxE;AAAA,EACF,OAAO;AAEL,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,eAAS,IAAI,MAAM,CAAC,EAAE,IAAI,UAAU,SAAS,CAAC,CAAC;AAAA,IACjD;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,cACP,WACA,aACA,aACA,cAC8C;AAC9C,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAO,EAAE,aAAa,aAAa,YAAY;AAAA,IACjD,KAAK;AACH,aAAO,EAAE,aAAa,aAAa,YAAY;AAAA,IACjD,KAAK;AACH,aAAO,EAAE,aAAa,cAAc,aAAa,aAAa;AAAA,IAChE;AACE,aAAO,EAAE,aAAa,YAAY;AAAA,EACtC;AACF;AAOA,SAAS,iBACP,MACA,UACA,OACA,WACA,iBAA4C,QAC5C,gBACA,SACyB;AACzB,QAAM,QAAQ,KAAK,SAAS;AAG5B,MAAI;AACJ,MAAI,mBAAmB,QAAQ;AAC7B,gBAAY;AAAA,EACd,WAAW,mBAAmB,SAAS;AACrC,gBAAY;AAAA,EACd,OAAO;AAEL,gBAAY,UAAU;AAAA,EACxB;AAEA,QAAM,QAAmB;AAAA,IACvB,YAAY,MAAM,MAAM;AAAA,IACxB,UAAU,MAAM,MAAM,MAAM;AAAA,IAC5B,YAAY,MAAM,MAAM,QAAQ;AAAA,IAChC,MAAM,MAAM,OAAO;AAAA,IACnB,YAAY;AAAA,EACd;AAEA,QAAM,KAAK,KAAK,MAAM;AACtB,QAAM,KAAK,KAAK,MAAM;AACtB,QAAM,KAAK,KAAK,MAAM;AACtB,QAAM,KAAK,KAAK,MAAM;AACtB,QAAM,QAAQ,KAAK,MAAM;AAGzB,QAAMM,OAAM,WAAW;AACvB,MAAI;AACJ,MAAI,mBAAmB,QAAW;AAChC,QAAI,WAAW;AAEb,iBAAW,KAAK,YAAYA;AAAA,IAC9B,OAAO;AAEL,iBAAW,iBAAiBA,QAAO,KAAK;AAAA,IAC1C;AACA,QAAI,aAAa,UAAa,WAAW,EAAG,YAAW;AAAA,EACzD;AAEA,MAAI,WAAW;AACb,WAAO;AAAA,MACL,MAAM,KAAK,SAAS,KAAK;AAAA,MACzB,GAAG,KAAK;AAAA,MACR,GAAG;AAAA,MACH,OAAO,EAAE,GAAG,OAAO,YAAY,OAAO,kBAAkB,UAAU;AAAA,MAClE,SAAS;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM,KAAK,SAAS,KAAK;AAAA,IACzB,GAAG,KAAK;AAAA,IACR,GAAG;AAAA,IACH,OAAO,EAAE,GAAG,OAAO,YAAY,SAAS,kBAAkB,UAAU;AAAA,IACpE,SAAS;AAAA,IACT;AAAA,EACF;AACF;AAcO,SAAS,cAAc,MAAe,SAAuC;AAElF,QAAM,EAAE,MAAM,WAAW,IAAI,QAAY,IAAI;AAE7C,MAAI,EAAE,UAAU,eAAe,WAAW,SAAS,UAAU;AAC3D,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAa;AAGnB,QAAM,eAAgB,KAAiC;AACvD,QAAM,YAAY,iBAAiB,SAAY,WAAW,YAAa,QAAQ,aAAa;AAG5F,QAAM,oBAAoB,QAAQ,QAC9B,EAAE,GAAG,WAAW,OAAO,GAAG,QAAQ,MAAM,IACxC,WAAW;AACf,QAAM,aAA4BC,cAAa,iBAAiB;AAChE,MAAI,QAAuB;AAC3B,MAAI,QAAQ,UAAU;AACpB,YAAQC,YAAW,KAAK;AAKxB,YAAQ;AAAA,MACN,GAAG;AAAA,MACH,QAAQ,EAAE,GAAG,MAAM,QAAQ,aAAa,WAAW,OAAO,YAAY;AAAA,IACxE;AAAA,EACF;AAGA,QAAM,SAASC;AAAA,IACb;AAAA,MACE,OAAO,WAAW,OAAO;AAAA,MACzB,UAAU,WAAW,OAAO;AAAA,MAC5B,QAAQ,WAAW,OAAO;AAAA,MAC1B,QAAQ,WAAW,OAAO;AAAA,MAC1B,QAAQ,WAAW,OAAO;AAAA,IAC5B;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,QAAM,UAAU,MAAM,QAAQ;AAC9B,QAAM,WAAiB;AAAA,IACrB,GAAG;AAAA,IACH,GAAG,UAAU,OAAO;AAAA,IACpB,OAAO,QAAQ,QAAQ,UAAU;AAAA,IACjC,QAAQ,QAAQ,SAAS,OAAO,YAAY,OAAO,eAAe,UAAU;AAAA,EAC9E;AAGA,MAAI,SAAS,SAAS,KAAK,SAAS,UAAU,GAAG;AAC/C,WAAO,YAAY,UAAU,QAAQ,OAAO,SAAS,SAAS;AAAA,EAChE;AAGA,QAAM,cAAc,WAAW,SAAS,OAAO;AAC/C,QAAM,cAAc,WAAW,SAAS,OAAO;AAC/C,QAAM,aAAa,WAAW,SAAS,MAAM;AAC7C,QAAM,aAAa,WAAW,SAAS,OAAO;AAI9C,QAAM,cAAc,oBAAI,IAAY;AACpC,aAAW,OAAO,WAAW,MAAM;AACjC,gBAAY,IAAI,OAAO,IAAI,WAAW,CAAC,CAAC;AACxC,gBAAY,IAAI,OAAO,IAAI,WAAW,CAAC,CAAC;AAAA,EAC1C;AACA,QAAM,eAAe;AAAA,IACnB,CAAC,GAAG,WAAW,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;AAAA,IACrC,MAAM,OAAO;AAAA,IACb;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,EACF;AACA,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,QAAM,YAAY,OAAO,QAAQ,SAAS,IAAI,IAAI;AAClD,QAAM,OAAa;AAAA,IACjB,GAAG,SAAS;AAAA,IACZ,GAAG,SAAS,IAAI,OAAO,OAAO,SAAS;AAAA,IACvC,OAAO,SAAS;AAAA,IAChB,QAAQ,SAAS,SAAS,OAAO,OAAO,SAAS;AAAA,EACnD;AAEA,MAAI,KAAK,UAAU,GAAG;AACpB,WAAO,YAAY,MAAM,QAAQ,OAAO,SAAS,SAAS;AAAA,EAC5D;AAGA,QAAM,gBAAgB,MAAM,MAAM,MAAM;AACxC,QAAM,kBAAkB,MAAM,MAAM,QAAQ;AAC5C,QAAM,YAAY,WAAW,aAAa;AAE1C,MAAI,aAAmB,EAAE,GAAG,KAAK;AACjC,MAAI,EAAE,OAAO,MAAM,IAAI;AAAA,IACrB,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,WAAW;AAAA,IACX,WAAW;AAAA,IACX,WAAW;AAAA,IACX,WAAW;AAAA,EACb;AAGA,QAAM,iBAAiB,WAAW,kBAAkB;AACpD,QAAM,gBAAgB,MAAM,OAAO,CAACC,MAAK,MAAM,KAAK,IAAIA,MAAK,EAAE,SAAS,CAAC,GAAG,CAAC;AAC7E,QAAM,YAAY,KAAK,IAAI,KAAK;AAChC,MAAI,cAAc;AAClB,aAAW,QAAQ,OAAO;AACxB,UAAM,QAAQ,KAAK,SAAS;AAE5B,UAAM,aACJ,mBAAmB,UAAW,mBAAmB,UAAU,UAAU;AACvE,QAAI,WAAY;AAChB,UAAM,UAAU,KAAK,MAAM,aAAa;AACxC,UAAM,YAAY,KAAK,SAAS,KAAK;AACrC,UAAM,aAAaC,oBAAkB,WAAW,eAAe,eAAe;AAC9E,UAAM,WAAW,SAAS,aAAa;AACvC,QAAI,WAAW,YAAa,eAAc;AAAA,EAC5C;AAGA,MAAI,cAAc,GAAG;AACnB,UAAM,SAAS,KAAK,KAAK,WAAW,IAAI;AACxC,iBAAa;AAAA,MACX,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,MACR,OAAO,KAAK,IAAI,KAAK,QAAQ,QAAQ,EAAE;AAAA,MACvC,QAAQ,KAAK;AAAA,IACf;AACA,KAAC,EAAE,OAAO,MAAM,IAAI;AAAA,MAClB,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,WAAW;AAAA,MACX,WAAW;AAAA,MACX,WAAW;AAAA,MACX,WAAW;AAAA,IACb;AAAA,EACF;AAGA,QAAM,eAAe;AAAA,IACnB;AAAA,IACA,MAAM,OAAO;AAAA,IACb;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,EACF;AAGA,QAAM,WAAW,MAAM,OAAO,CAACD,MAAK,MAAM,KAAK,IAAIA,MAAK,EAAE,SAAS,CAAC,GAAG,CAAC;AAGxE,QAAM,YAA8B,MAAM,IAAI,CAAC,SAAS;AACtD,UAAM,OAAO,aAAa,IAAI,KAAK,EAAE,KAAK,MAAM,OAAO,YAAY,CAAC;AACpE,UAAM,QAAQ,KAAK,SAAS;AAE5B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,GAAG,KAAK,MAAM;AAAA,MACd,GAAG,KAAK,MAAM;AAAA,MACd,QAAQ,KAAK,MAAM,MAAM,KAAK,MAAM;AAAA,MACpC,SAAS,KAAK,MAAM,MAAM,KAAK,MAAM;AAAA,MACrC;AAAA,MACA,cAAc;AAAA,MACd,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,MACF;AAAA,MACA,QAAQ,KAAK;AAAA,MACb,OAAO,KAAK,SAAS;AAAA,MACrB;AAAA,MACA,MAAM,EAAE,IAAI,KAAK,IAAI,OAAO,KAAK,MAAM;AAAA,MACvC,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,OAAO,GAAG,KAAK,KAAK,KAAK,gBAAgB,KAAK,SAAS,GAAG,WAAW,WAAW,CAAC;AAAA,MACnF;AAAA,MACA,gBAAgB;AAAA;AAAA,IAClB;AAAA,EACF,CAAC;AAGD,YAAU,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AACvD,WAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,cAAU,CAAC,EAAE,iBAAiB;AAAA,EAChC;AAGA,QAAM,eAAe,MAAM,OAAO;AAClC,QAAM,YAA8B,MAAM,IAAI,CAAC,MAAM,MAAM;AACzD,UAAM,aAAa,KAAK;AACxB,UAAM,aAAa,KAAK;AACxB,UAAM,WAAW,aAAa,IAAI,WAAW,EAAE,KAAK,MAAM,OAAO,YAAY,CAAC;AAC9E,UAAM,WAAW,aAAa,IAAI,WAAW,EAAE,KAAK,MAAM,OAAO,YAAY,CAAC;AAC9E,UAAM,SAAS,cAAc,WAAW,WAAW,UAAU,UAAU,YAAY;AAEnF,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM,iBAAiB,IAAI;AAAA,MAC3B,aAAa,OAAO;AAAA,MACpB,aAAa,OAAO;AAAA,MACpB,aACE,WAAW,gBAAgB,QAAQ,WAAW,oBAAoB;AAAA,MACpE,UAAU,WAAW;AAAA,MACrB,UAAU,WAAW;AAAA,MACrB,OAAO,KAAK,SAAS;AAAA,MACrB,OAAO,KAAK;AAAA,MACZ,MAAO,KAAsD,QAAQ,CAAC;AAAA,MACtE,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,OAAO,GAAG,WAAW,KAAK,OAAO,WAAW,KAAK,KAAK,gBAAgB,KAAK,OAAO,WAAW,WAAW,CAAC;AAAA,MAC3G;AAAA;AAAA,MAEA,gBAAgB,UAAU,SAAS;AAAA,IACrC;AAAA,EACF,CAAC;AAGD,QAAM,cAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,QAAM,qBAAqB,wBAAwB,WAAW,WAAW,WAAW,WAAW;AAG/F,QAAM,OAAO;AAAA,IACX,SAAS,uBAAuB,UAAU,MAAM,cAAc,UAAU,MAAM;AAAA,IAC9E,mBAAmB,UAAU,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,UAAU,OAAO,EAAE,KAAK,CAAC,CAAC;AAAA,IACjF,MAAM;AAAA,IACN,mBAAmB,UAAU,SAAS;AAAA,EACxC;AAGA,QAAM,oBAAmD,iBAAiB,WAAW,SAAS;AAE9F,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,MACV,OAAO,QAAQ;AAAA,MACf,QAAQ,QAAQ;AAAA,IAClB;AAAA,IACA,WAAW;AAAA,IACX;AAAA,EACF;AACF;AAMA,SAAS,kBACP,cACA,YACA,MACA,aACA,aACA,OACA,MACc;AACd,QAAM,aAAwB;AAAA,IAC5B,YAAY,MAAM,MAAM;AAAA,IACxB,UAAU,MAAM,MAAM,MAAM;AAAA,IAC5B,YAAY,MAAM,MAAM,QAAQ;AAAA,IAChC,MAAM,MAAM,OAAO;AAAA,IACnB,YAAY;AAAA,EACd;AAEA,MAAI;AAEJ,MAAI,YAAY;AAEd,UAAM,iBAAiB,oBAAI,IAAoB;AAC/C,UAAM,kBAAkB,oBAAI,IAAoB;AAChD,eAAW,OAAO,MAAM;AACtB,YAAM,MAAM,OAAO,IAAI,WAAW,CAAC;AACnC,YAAM,MAAM,OAAO,IAAI,WAAW,CAAC;AACnC,YAAM,MAAM,OAAO,IAAI,UAAU,CAAC;AAClC,UAAI,CAAC,gBAAgB,IAAI,GAAG,EAAG,iBAAgB,IAAI,KAAK,GAAG;AAC3D,UAAI,CAAC,gBAAgB,IAAI,GAAG,EAAG,iBAAgB,IAAI,KAAK,GAAG;AAAA,IAC7D;AACA,eAAW,CAAC,QAAQ,QAAQ,KAAK,iBAAiB;AAChD,UAAI,CAAC,eAAe,IAAI,QAAQ,GAAG;AACjC,uBAAe,IAAI,UAAU,aAAa,IAAI,MAAM,KAAK,MAAM,OAAO,YAAY,CAAC,CAAC;AAAA,MACtF;AAAA,IACF;AAEA,cAAU,CAAC,GAAG,eAAe,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,OAAOE,MAAK,OAAO;AAAA,MAC/D;AAAA,MACA,OAAAA;AAAA,MACA,OAAO;AAAA,MACP,QAAQ;AAAA,IACV,EAAE;AAAA,EACJ,OAAO;AAEL,cAAU,CAAC;AAAA,EACb;AAGA,MAAI,SAAS,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,GAAG,QAAQ,EAAE;AAE/C,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,aAAaC,eAAc;AACjC,UAAM,iBAAiB,KAAK;AAG5B,UAAM,EAAE,SAAS,IAAI,kBAAkB,SAAS,gBAAgB,UAAU;AAC1E,UAAM,iBAAiB,KAAK,IAAI,UAAU,CAAC;AAC3C,UAAM,eAAe,iBAAiB;AAEtC,aAAS;AAAA,MACP,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,MACR,OAAO;AAAA,MACP,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAYA;AAAA,IACZ,WAAWC;AAAA,IACX,UAAUC;AAAA,EACZ;AACF;AAMA,SAAS,gBAAgBC,QAAe,aAA8B;AACpE,MAAI,aAAa;AACf,UAAM,MAAMC,kBAAiB,WAAW;AACxC,QAAI,IAAK,QAAO,IAAID,MAAK;AAAA,EAC3B;AACA,SAAOE,cAAaF,MAAK;AAC3B;AAEA,SAAS,wBACP,OACA,OACA,aAC6B;AAC7B,QAAM,cAAc,oBAAI,IAA4B;AAGpD,aAAW,QAAQ,OAAO;AACxB,UAAM,SAAyB;AAAA,MAC7B;AAAA,QACE,OAAO;AAAA,QACP,OAAO,gBAAgB,KAAK,OAAO,WAAW;AAAA,MAChD;AAAA,IACF;AACA,gBAAY,IAAI,QAAQ,KAAK,MAAM,IAAI;AAAA,MACrC,OAAO,KAAK,MAAM;AAAA,MAClB;AAAA,IACF,CAAC;AAAA,EACH;AAGA,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,UAAM,SAAyB;AAAA,MAC7B;AAAA,QACE,OAAO;AAAA,QACP,OAAO,gBAAgB,KAAK,OAAO,WAAW;AAAA,MAChD;AAAA,IACF;AACA,gBAAY,IAAI,QAAQ,KAAK,QAAQ,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI;AAAA,MAC7D,OAAO,GAAG,KAAK,QAAQ,WAAW,KAAK,QAAQ;AAAA,MAC/C;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAMA,SAAS,YACP,MACA,QACA,OACA,SACA,WACc;AACd,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,CAAC;AAAA,IACR,OAAO,CAAC;AAAA,IACR,QAAQ;AAAA,MACN,UAAU;AAAA,MACV,SAAS,CAAC;AAAA,MACV,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,GAAG,QAAQ,EAAE;AAAA,MAC1C,YAAY;AAAA,QACV,YAAY,MAAM,MAAM;AAAA,QACxB,UAAU,MAAM,MAAM,MAAM;AAAA,QAC5B,YAAY,MAAM,MAAM,QAAQ;AAAA,QAChC,MAAM,MAAM,OAAO;AAAA,QACnB,YAAY;AAAA,MACd;AAAA,MACA,YAAYH;AAAA,MACZ,WAAWC;AAAA,MACX,UAAUC;AAAA,IACZ;AAAA,IACA,oBAAoB,oBAAI,IAAI;AAAA,IAC5B,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,mBAAmB,CAAC;AAAA,MACpB,MAAM;AAAA,MACN,mBAAmB;AAAA,IACrB;AAAA,IACA;AAAA,IACA,YAAY;AAAA,MACV,OAAO,QAAQ;AAAA,MACf,QAAQ,QAAQ;AAAA,IAClB;AAAA,IACA;AAAA,EACF;AACF;;;AQ/pBA,SAAS,iBAAAI,gBAAe,qBAAAC,2BAAyB;;;ACVjD,IAAM,qBAAqB;AAQpB,SAAS,eACdC,QACA,QACA,WACA,WACA,OACA,WACkF;AAClF,QAAM,WAAW,OAAO,SAAS,MAAM,OAAO,YAAY,CAAC;AAC3D,QAAM,eAAe,YAAY;AAEjC,MAAI,CAAC,OAAO,SAASA,MAAK,GAAG;AAC3B,WAAO,EAAE,YAAY,GAAG,WAAW,GAAG,UAAU,YAAY,MAAM;AAAA,EACpE;AAEA,MAAI,CAAC,cAAc;AAEjB,UAAM,WAAW,OAAO,YAAY;AACpC,QAAI,YAAY,GAAG;AACjB,aAAO,EAAE,YAAY,GAAG,WAAW,GAAG,UAAU,YAAY,MAAM;AAAA,IACpE;AACA,UAAMC,cAAa,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGD,SAAQ,QAAQ,CAAC;AAC5D,WAAO,EAAE,YAAAC,aAAY,WAAW,GAAG,UAAU,YAAY,MAAM;AAAA,EACjE;AAGA,QAAM,SAAS,OAAO,YAAY;AAClC,QAAM,SAAS,KAAK,IAAI,SAAS;AACjC,QAAM,aAAa,SAAS;AAC5B,MAAI,eAAe,GAAG;AACpB,WAAO,EAAE,YAAY,GAAG,WAAW,GAAG,UAAU,YAAY,MAAM;AAAA,EACpE;AAEA,QAAM,UAAU,SAAS;AAEzB,MAAID,UAAS,GAAG;AACd,UAAMC,cAAaD,SAAQ;AAC3B,WAAO,EAAE,YAAAC,aAAY,WAAW,SAAS,UAAU,YAAY,MAAM;AAAA,EACvE;AAGA,QAAM,aAAa,KAAK,IAAID,MAAK,IAAI;AACrC,SAAO;AAAA,IACL;AAAA,IACA,WAAW,UAAU;AAAA,IACrB,UAAU,OAAO,SAAS;AAAA,IAC1B,YAAY;AAAA,EACd;AACF;AAKO,SAAS,iBAAiB,MAAiC,KAAqB;AACrF,MAAIE,OAAM;AACV,aAAW,OAAO,MAAM;AACtB,UAAM,MAAM,IAAI,GAAG;AACnB,QAAI,OAAO,QAAQ,YAAY,OAAO,SAAS,GAAG,KAAK,MAAMA,MAAK;AAChE,MAAAA,OAAM;AAAA,IACR;AAAA,EACF;AACA,SAAOA;AACT;AAKO,SAAS,iBAAiB,MAAiC,KAAqB;AACrF,MAAIC,OAAM;AACV,aAAW,OAAO,MAAM;AACtB,UAAM,MAAM,IAAI,GAAG;AACnB,QAAI,OAAO,QAAQ,YAAY,OAAO,SAAS,GAAG,KAAK,MAAMA,MAAK;AAChE,MAAAA,OAAM;AAAA,IACR;AAAA,EACF;AACA,SAAOA;AACT;;;ACrFA,SAAS,6BAA6B;;;ACJtC,SAAS,qBAAqB;AAKvB,SAAS,oBAAoB,IAAoB;AACtD,QAAM,QAAQ;AACd,QAAM,QAAQ;AACd,QAAM,aAAa,cAAc,OAAO,EAAE;AAC1C,QAAM,aAAa,cAAc,OAAO,EAAE;AAC1C,SAAO,cAAc,aAAa,QAAQ;AAC5C;;;ADIO,SAAS,sBACd,MACA,QACA,OACA,UACwB;AACxB,QAAM,SAAS,oBAAI,IAAuB;AAC1C,QAAM,cAAc,OAAO;AAC3B,MAAI,CAAC,YAAa,QAAO;AAEzB,QAAM,qBAAqB,MAAM,OAAO;AACxC,MAAI,mBAAmB;AACvB,QAAM,eAAe,oBAAI,IAAoB;AAC7C,QAAM,UAAU;AAChB,QAAM,SAAS,MAAM,OAAO;AAE5B,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,MAAM,KAAK,CAAC,EAAE,OAAO,GAAG;AAC9B,QAAI,OAAO,KAAM;AAEjB,UAAM,MAAM,OAAO,GAAG;AACtB,QAAI;AACJ,QAAI,aAAa;AAEjB,QAAI,YAAY,GAAG,KAAK,MAAM;AAC5B,UAAI,YAAY,GAAG,MAAM,iBAAiB,YAAY,GAAG,MAAM,QAAQ;AAErE;AAAA,MACF;AACA,WAAK,YAAY,GAAG;AACpB,mBAAa;AAAA,IACf,WAAW,OAAO,YAAY;AAE5B,UAAI,aAAa,IAAI,GAAG,GAAG;AACzB,aAAK,aAAa,IAAI,GAAG;AAAA,MAC3B,OAAO;AACL,aAAK,mBAAmB,mBAAmB,mBAAmB,MAAM;AACpE;AACA,qBAAa,IAAI,KAAK,EAAE;AAAA,MAC1B;AAAA,IACF,OAAO;AAEL;AAAA,IACF;AAGA,QAAI,YAAY,CAAC,YAAY;AAC3B,WAAK,sBAAsB,IAAI,SAAS,MAAM;AAAA,IAChD;AAEA,UAAM,YAAY,oBAAoB,EAAE;AACxC,WAAO,IAAI,GAAG;AAAA,MACZ,iBAAiB;AAAA,MACjB,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AEpEA,SAAS,oBAAAC,mBAAkB,cAAAC,aAAY,gBAAAC,qBAAoB;AAK3D,SAAS,eAAeC,QAAiC;AACvD,MAAI,OAAOA,WAAU,SAAU,QAAO,OAAO,SAASA,MAAK;AAC3D,SAAO;AACT;AAKA,SAAS,YAAYA,QAAyB;AAC5C,MAAIA,kBAAiB,KAAM,QAAO,CAAC,OAAO,MAAMA,OAAM,QAAQ,CAAC;AAC/D,SAAO;AACT;AAWO,SAAS,WAAWA,QAAgB,QAAqC;AAC9E,QAAM,QAAmB,CAAC;AAG1B,MAAIA,UAAS,MAAM;AACjB,WAAO;AAAA,MACL,OAAAA;AAAA,MACA,gBAAgB;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO,UAAU,eAAeA,MAAK,GAAG;AAC1C,UAAM,YAAYH,kBAAiB,OAAO,MAAM;AAChD,QAAI,WAAW;AACb,aAAO;AAAA,QACL,OAAAG;AAAA,QACA,gBAAgB,UAAUA,MAAK;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,eAAeA,MAAK,GAAG;AACzB,WAAO;AAAA,MACL,OAAAA;AAAA,MACA,gBAAgBD,cAAaC,MAAK;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAGA,MAAI,YAAYA,MAAK,GAAG;AACtB,WAAO;AAAA,MACL,OAAAA;AAAA,MACA,gBAAgBF,YAAWE,MAAa;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL,OAAAA;AAAA,IACA,gBAAgB,OAAOA,MAAK;AAAA,IAC5B;AAAA,EACF;AACF;AAMO,SAAS,qBAAqBA,QAAgB,QAA8B;AACjF,MAAIA,UAAS,KAAM,QAAO;AAE1B,MAAI,OAAO,UAAU,eAAeA,MAAK,GAAG;AAC1C,UAAM,YAAYH,kBAAiB,OAAO,MAAM;AAChD,QAAI,WAAW;AACb,aAAO,UAAUG,MAAK;AAAA,IACxB;AAAA,EACF;AAEA,MAAI,eAAeA,MAAK,GAAG;AACzB,WAAOD,cAAaC,MAAK;AAAA,EAC3B;AAEA,SAAO,OAAOA,MAAK;AACrB;;;ACjGA,SAAS,yBAAAC,8BAA6B;AAStC,SAAS,sBAAsB,OAAwC;AACrE,MAAI,MAAM,WAAW,EAAG,QAAO,MAAM;AACrC,MAAI,MAAM,WAAW,EAAG,QAAO,MAAM,MAAM,CAAC;AAE5C,SAAO,CAAC,MAAc;AACpB,UAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;AAC1C,UAAM,UAAU,WAAW,MAAM,SAAS;AAC1C,UAAM,KAAK,KAAK,MAAM,OAAO;AAC7B,UAAM,KAAK,KAAK,IAAI,KAAK,GAAG,MAAM,SAAS,CAAC;AAC5C,UAAM,OAAO,UAAU;AACvB,WAAO,YAAe,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,IAAI;AAAA,EAClD;AACF;AASA,SAAS,eAAe,SAAwC,OAAgC;AAC9F,MAAI,MAAM,QAAQ,OAAO,EAAG,QAAO;AAEnC,QAAM,cAAc,MAAM,OAAO;AACjC,QAAM,cAAc,MAAM,OAAO;AAEjC,MAAI,OAAO,YAAY,UAAU;AAC/B,QAAI,YAAY,OAAO,EAAG,QAAO,YAAY,OAAO;AACpD,QAAI,YAAY,OAAO,EAAG,QAAO,YAAY,OAAO;AAAA,EACtD;AAGA,QAAM,cAAc,OAAO,KAAK,WAAW,EAAE,CAAC;AAC9C,SAAO,cAAc,YAAY,WAAW,IAAI,CAAC,WAAW,SAAS;AACvE;AAOO,SAAS,qBACd,MACA,QACA,OACA,UACwB;AACxB,QAAM,SAAS,oBAAI,IAAuB;AAC1C,QAAM,SAAS,OAAO;AACtB,MAAI,CAAC,OAAQ,QAAO;AAGpB,QAAM,aAAa,OAAO,gBAAgB,OAAO;AAGjD,QAAM,gBAAoD,CAAC;AAC3D,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,MAAM,KAAK,CAAC,EAAE,UAAU;AAC9B,QAAI,OAAO,QAAQ,YAAY,OAAO,SAAS,GAAG,GAAG;AACnD,oBAAc,KAAK,EAAE,OAAO,GAAG,OAAO,IAAI,CAAC;AAAA,IAC7C;AAAA,EACF;AAEA,MAAI,cAAc,WAAW,EAAG,QAAO;AAGvC,MAAI;AACJ,MAAI,OAAO,QAAQ;AACjB,aAAS,OAAO;AAAA,EAClB,OAAO;AACL,QAAIC,OAAM;AACV,QAAIC,OAAM;AACV,eAAW,EAAE,OAAAC,OAAM,KAAK,eAAe;AACrC,UAAIA,SAAQF,KAAK,CAAAA,OAAME;AACvB,UAAIA,SAAQD,KAAK,CAAAA,OAAMC;AAAA,IACzB;AACA,aAAS,CAACF,MAAKC,IAAG;AAAA,EACpB;AAGA,MAAI,QAAQ,eAAe,OAAO,SAAS,KAAK;AAChD,MAAI,UAAU;AACZ,UAAM,UAAU;AAChB,UAAM,SAAS,MAAM,OAAO;AAC5B,YAAQ,MAAM,IAAI,CAAC,MAAME,uBAAsB,GAAG,SAAS,MAAM,CAAC;AAAA,EACpE;AAEA,QAAM,eAAe,sBAAsB,KAAK;AAChD,QAAM,QAAQ,WAAgB,YAAY,EAAE,OAAO,MAAM,EAAE,MAAM,IAAI;AAGrE,aAAW,EAAE,OAAO,OAAAD,OAAM,KAAK,eAAe;AAC5C,UAAM,KAAK,MAAMA,MAAK;AACtB,UAAM,YAAY,oBAAoB,EAAE;AAExC,WAAO,IAAI,OAAO;AAAA,MAChB,iBAAiB;AAAA,MACjB,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AC7GO,SAAS,aACd,MACA,MACA,UAMA;AACA,QAAM,YAAY,KAAK;AAGvB,MAAI,YAAY,GAAG;AACjB,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA,YAAY;AAAA,MACZ,MAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,YAAY,QAAQ,CAAC;AAE9D,QAAM,cAAc,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,aAAa,CAAC,CAAC;AAC9D,QAAM,QAAQ,cAAc;AAC5B,QAAM,MAAM,KAAK,IAAI,QAAQ,UAAU,SAAS;AAEhD,SAAO;AAAA,IACL,MAAM,KAAK,MAAM,OAAO,GAAG;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,MAAM;AAAA,EACR;AACF;;;AC9BO,SAAS,iBACd,MACA,SACqB;AACrB,QAAM,QAAQ,oBAAI,IAAoB;AAEtC,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,MAAM,KAAK,CAAC;AAClB,UAAM,QAAkB,CAAC;AAEzB,eAAW,OAAO,SAAS;AACzB,YAAM,KAAK,qBAAqB,IAAI,IAAI,GAAG,GAAG,GAAG,CAAC;AAAA,IACpD;AAEA,UAAM,IAAI,GAAG,MAAM,KAAK,GAAG,EAAE,YAAY,CAAC;AAAA,EAC5C;AAEA,SAAO;AACT;AAQO,SAAS,eACd,MACA,OACA,aACA,iBACwD;AACxD,MAAI,CAAC,SAAS,MAAM,KAAK,MAAM,IAAI;AACjC,WAAO,EAAE,MAAM,SAAS,gBAAgB;AAAA,EAC1C;AAEA,QAAM,aAAa,MAAM,YAAY;AACrC,QAAM,eAA0C,CAAC;AACjD,QAAM,kBAA4B,CAAC;AAEnC,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,cAAc,gBAAgB,CAAC;AACrC,UAAM,aAAa,YAAY,IAAI,WAAW;AAC9C,QAAI,YAAY,SAAS,UAAU,GAAG;AACpC,mBAAa,KAAK,KAAK,CAAC,CAAC;AACzB,sBAAgB,KAAK,WAAW;AAAA,IAClC;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,cAAc,SAAS,gBAAgB;AACxD;;;ACvCO,SAAS,SAAS,MAAiC,MAA6B;AACrF,QAAM,EAAE,QAAQ,UAAU,IAAI;AAC9B,QAAM,aAAa,cAAc,QAAQ,IAAI;AAG7C,QAAM,UAAU,KAAK,IAAI,CAAC,KAAK,OAAO,EAAE,KAAK,OAAO,EAAE,EAAE;AAExD,UAAQ,KAAK,CAAC,GAAG,MAAM;AACrB,UAAM,OAAO,EAAE,IAAI,MAAM;AACzB,UAAM,OAAO,EAAE,IAAI,MAAM;AAGzB,UAAM,QAAQ,QAAQ;AACtB,UAAM,QAAQ,QAAQ;AACtB,QAAI,SAAS,MAAO,QAAO,EAAE,QAAQ,EAAE;AACvC,QAAI,MAAO,QAAO;AAClB,QAAI,MAAO,QAAO;AAElB,QAAI,MAAM;AAGV,QAAI,OAAO,SAAS,YAAY,OAAO,SAAS,UAAU;AACxD,YAAM,OAAO;AAAA,IACf,WAES,gBAAgB,QAAQ,gBAAgB,MAAM;AACrD,YAAM,KAAK,QAAQ,IAAI,KAAK,QAAQ;AAAA,IACtC,OAEK;AACH,YAAM,OAAO,IAAI,EAAE,cAAc,OAAO,IAAI,CAAC;AAAA,IAC/C;AAGA,QAAI,QAAQ,EAAG,QAAO,EAAE,QAAQ,EAAE;AAClC,WAAO,MAAM;AAAA,EACf,CAAC;AAED,SAAO;AAAA,IACL,MAAM,QAAQ,IAAI,CAAC,SAAS,KAAK,GAAG;AAAA,IACpC,iBAAiB,QAAQ,IAAI,CAAC,SAAS,KAAK,KAAK;AAAA,EACnD;AACF;;;AC/CA,SAAS,cACP,KACA,WACA,QACU;AACV,QAAM,QAAQ,OAAO,eAAe;AACpC,QAAM,MAAM,IAAI,KAAK;AAErB,MAAI,CAAC,MAAM,QAAQ,GAAG,EAAG,QAAO,CAAC;AAEjC,SAAO,IACJ,IAAI,CAAC,MAAO,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,IAAI,IAAI,IAAK,EACnE,OAAO,CAAC,MAAmB,MAAM,IAAI;AAC1C;AAOO,SAAS,iBACd,QACA,QACA,OACA,WACsB;AACtB,MAAI,OAAO,WAAW,EAAG,QAAO;AAEhC,QAAM,OAAO,OAAO,QAAQ;AAC5B,QAAME,SAAQ,OAAO,SAAS,MAAM,OAAO,YAAY,CAAC;AAExD,MAAIC,OAAM;AACV,MAAIC,OAAM;AACV,aAAW,KAAK,QAAQ;AACtB,QAAI,IAAID,KAAK,CAAAA,OAAM;AACnB,QAAI,IAAIC,KAAK,CAAAA,OAAM;AAAA,EACrB;AAEA,QAAMC,SAAQD,OAAMD;AACpB,QAAMG,aAAY,CAAC,MAAuBD,WAAU,IAAI,OAAO,IAAIF,QAAOE;AAE1E,QAAM,aAAa,OAAO,CAAC;AAC3B,QAAM,WAAW,OAAO,OAAO,SAAS,CAAC;AAEzC,MAAI,SAAS,QAAQ;AACnB,UAAME,UAAS,OAAO,IAAI,CAAC,GAAG,OAAO;AAAA,MACnC,GAAG,OAAO,WAAW,IAAI,MAAM,KAAK,OAAO,SAAS;AAAA,MACpD,GAAGD,WAAU,CAAC;AAAA,IAChB,EAAE;AAEF,WAAO;AAAA,MACL;AAAA,MACA,QAAAC;AAAA,MACA,MAAM,CAAC;AAAA,MACP,OAAAL;AAAA,MACA,OAAO,OAAO;AAAA,MACd;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,QAAM,OAAO,OAAO,IAAII,UAAS;AACjC,QAAM,SAAS,OAAO,IAAI,CAAC,GAAG,OAAO;AAAA,IACnC,GAAG,OAAO,WAAW,IAAI,MAAM,KAAK,OAAO,SAAS;AAAA,IACpD,GAAGA,WAAU,CAAC;AAAA,EAChB,EAAE;AAEF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAAJ;AAAA,IACA,OAAO,OAAO;AAAA,IACd;AAAA,IACA;AAAA,EACF;AACF;AAKO,SAAS,uBACd,KACA,WACA,QACA,OACA,UACsB;AACtB,QAAM,SAAS,cAAc,KAAK,WAAW,MAAM;AACnD,SAAO,iBAAiB,QAAQ,QAAQ,OAAO,QAAQ;AACzD;;;ATxEA,SAAS,kBAAkB,KAA+C;AACxE,MAAI,IAAI,UAAW,QAAO;AAC1B,MAAI,IAAI,IAAK,QAAO;AACpB,MAAI,IAAI,QAAS,QAAO;AACxB,MAAI,IAAI,MAAO,QAAO;AACtB,MAAI,IAAI,KAAM,QAAO;AACrB,MAAI,IAAI,eAAgB,QAAO;AAC/B,SAAO;AACT;AAMA,SAAS,eACP,KACA,MAC6B;AAC7B,MAAI,IAAI,MAAO,QAAO,IAAI;AAG1B,aAAW,OAAO,MAAM;AACtB,UAAM,MAAM,IAAI,IAAI,GAAG;AACvB,QAAI,OAAO,MAAM;AACf,aAAO,OAAO,QAAQ,WAAW,UAAU;AAAA,IAC7C;AAAA,EACF;AACA,SAAO;AACT;AAMA,SAAS,oBACP,KACA,MACA,UACQ;AACR,QAAM,YAAY;AAClB,QAAM,UAAU;AAGhB,MAAI,IAAI,UAAW,QAAO;AAC1B,MAAI,IAAI,MAAO,SAAQ,IAAI,MAAM,SAAS,MAAM;AAChD,MAAI,IAAI,KAAM,QAAO;AAGrB,QAAM,QAAQ,IAAI,SAAS,IAAI;AAC/B,QAAM,cAAcM,oBAAkB,OAAO,UAAU,GAAG,IAAI;AAG9D,QAAM,aAAa,KAAK,IAAI,KAAK,KAAK,MAAM;AAC5C,MAAI,eAAe;AAEnB,WAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,UAAM,MAAM,KAAK,CAAC,EAAE,IAAI,GAAG;AAC3B,UAAM,OAAO,OAAO,OAAO,KAAK,OAAO,GAAG;AAC1C,UAAM,QAAQA,oBAAkB,MAAM,UAAU,GAAG,IAAI;AACvD,QAAI,QAAQ,aAAc,gBAAe;AAAA,EAC3C;AAEA,SAAO,KAAK,IAAI,WAAW,aAAa,YAAY;AACtD;AAKA,SAAS,eACP,SACA,MACA,YACA,OACkB;AAClB,QAAM,WAAW,MAAM,MAAM,MAAM;AAKnC,QAAM,UAAU,QAAQ,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,aAAa,IAAI,SAAS,IAAI,KAAK;AAE/E,QAAM,gBAAgB,QAAQ,IAAI,CAAC,QAAQ;AACzC,QAAI,IAAI,OAAO;AAEb,UAAI,IAAI,MAAM,SAAS,IAAI,GAAG;AAC5B,eAAO,SAAS,IAAI,OAAO,EAAE,KAAK;AAAA,MACpC;AACA,UAAI,IAAI,MAAM,SAAS,GAAG,GAAG;AAC3B,eAAQ,WAAW,IAAI,KAAK,IAAI,MAAO,cAAc;AAAA,MACvD;AACA,aAAO,SAAS,IAAI,OAAO,EAAE,KAAK;AAAA,IACpC;AACA,WAAO,oBAAoB,KAAK,MAAM,QAAQ;AAAA,EAChD,CAAC;AAGD,QAAM,aAAa,cAAc,OAAO,CAACC,MAAK,GAAG,MAAMA,QAAO,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC;AACpF,QAAM,YAAY,cAAc,OAAO,CAACA,MAAK,GAAG,MAAMA,QAAO,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC;AACnF,QAAM,iBAAiB,aAAa;AACpC,QAAM,YAAY,YAAY,KAAK,iBAAiB,IAAI,iBAAiB,YAAY;AAErF,SAAO,QAAQ,IAAI,CAAC,KAAK,OAAO;AAAA,IAC9B,KAAK,IAAI;AAAA,IACT,OAAO,IAAI,SAAS,IAAI;AAAA,IACxB,OAAO,KAAK,IAAI,IAAI,QAAQ,CAAC,IAAI,cAAc,CAAC,IAAI,KAAK,MAAM,cAAc,CAAC,IAAI,SAAS,CAAC;AAAA,IAC5F,UAAU,IAAI,YAAY;AAAA,IAC1B,OAAO,eAAe,KAAK,IAAI;AAAA,IAC/B,UAAU,kBAAkB,GAAG;AAAA,EACjC,EAAE;AACJ;AASA,SAAS,UACPC,QACA,QACA,gBACA,cACA,eACA,SAGA,eACW;AACX,QAAM,OAAO,WAAWA,QAAO,MAAM;AAGrC,MAAI,OAAOA,WAAU,UAAU;AAC7B,SAAK,QAAQ,EAAE,GAAG,KAAK,OAAO,aAAa,eAAe;AAAA,EAC5D;AAEA,QAAM,WAAW,eAAe;AAEhC,UAAQ,UAAU;AAAA,IAChB,KAAK,WAAW;AACd,YAAM,SAAS,eAAe,EAAE,GAAG,KAAK,OAAO,GAAG,aAAa,IAAI,KAAK;AACxE,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,QACV,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,KAAK,YAAY;AACf,YAAM,SAAS,gBAAgB,EAAE,GAAG,KAAK,OAAO,GAAG,cAAc,IAAI,KAAK;AAC1E,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,QACV,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,KAAK,OAAO;AACV,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,QACV,UAAU,SAAS,cAAc;AAAA,QACjC,WAAW,SAAS,aAAa;AAAA,QACjC,UAAU,SAAS,YAAY;AAAA,QAC/B,YAAY,SAAS,cAAc;AAAA,MACrC;AAAA,IACF;AAAA,IACA,KAAK,aAAa;AAChB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,IACA,KAAK,SAAS;AACZ,YAAM,MAAM,OAAOA,WAAU,WAAWA,SAAQ;AAChD,YAAM,YAAY,OAAO,SAAS,CAAC;AACnC,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,QACV;AAAA,QACA,YAAY,UAAU,SAAS;AAAA,QAC/B,aAAa,UAAU,UAAU;AAAA,QACjC,SAAS,UAAU,WAAW;AAAA,MAChC;AAAA,IACF;AAAA,IACA,KAAK,QAAQ;AACX,YAAM,OAAO,OAAOA,WAAU,WAAWA,SAAQ;AACjD,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,QACV,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AACP,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;AAkBO,SAAS,mBACd,MACA,SACA,OACa;AACb,QAAM,OAAO,KAAK;AAClB,QAAM,WAAW,MAAM;AAGvB,QAAM,kBAAkB,eAAe,KAAK,SAAS,MAAM,QAAQ,OAAO,KAAK;AAG/E,QAAM,cAAc,KAAK,SACrB,iBAAiB,MAAM,KAAK,OAAO,IACnC,oBAAI,IAAoB;AAG5B,MAAI,cAAc;AAClB,MAAI,kBAAkB,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC;AAG1C,MAAI,QAAQ,MAAM;AAChB,UAAM,SAAS,SAAS,aAAa,QAAQ,IAAI;AAEjD,sBAAkB,OAAO,gBAAgB,IAAI,CAAC,MAAM,gBAAgB,CAAC,CAAC;AACtE,kBAAc,OAAO;AAAA,EACvB;AAGA,MAAI,KAAK,UAAU,QAAQ,QAAQ;AACjC,UAAM,WAAW,eAAe,aAAa,QAAQ,QAAQ,aAAa,eAAe;AACzF,kBAAc,SAAS;AACvB,sBAAkB,SAAS;AAAA,EAC7B;AAEA,QAAM,gBAAgB,YAAY;AAGlC,MAAI,WAAW;AACf,MAAI,cAAc;AAClB,MAAI;AAEJ,MAAI,KAAK,YAAY;AACnB,eACE,QAAQ,aAAa,OAAO,KAAK,eAAe,WAAW,KAAK,WAAW,WAAW;AACxF,kBAAc,QAAQ,QAAQ;AAC9B,UAAM,YAAY,aAAa,aAAa,aAAa,QAAQ;AAGjE,UAAM,QAAQ,UAAU,OAAO;AAC/B,UAAM,MAAM,QAAQ,UAAU,KAAK;AACnC,UAAM,cAAc,gBAAgB,MAAM,OAAO,GAAG;AAEpD,kBAAc,UAAU;AACxB,sBAAkB;AAElB,sBAAkB;AAAA,MAChB,MAAM,UAAU;AAAA,MAChB;AAAA,MACA,WAAW,UAAU;AAAA,MACrB,YAAY,UAAU;AAAA,IACxB;AAAA,EACF;AAKA,QAAM,cAAc,oBAAI,IAAoC;AAC5D,QAAM,eAAe,oBAAI,IAAoC;AAC7D,QAAM,WAAW,oBAAI,IAAoB;AACzC,QAAM,UAAU,oBAAI,IAAoB;AAExC,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,KAAK;AAC5C,UAAM,MAAM,KAAK,QAAQ,CAAC;AAC1B,UAAM,WAAW,gBAAgB,CAAC;AAElC,QAAI,SAAS,aAAa,aAAa,IAAI,SAAS;AAClD,kBAAY,IAAI,IAAI,KAAK,qBAAqB,MAAM,KAAK,OAAO,QAAQ,CAAC;AAAA,IAC3E;AACA,QAAI,SAAS,aAAa,cAAc,IAAI,gBAAgB;AAC1D,mBAAa,IAAI,IAAI,KAAK,sBAAsB,MAAM,KAAK,OAAO,QAAQ,CAAC;AAAA,IAC7E;AACA,QAAI,SAAS,aAAa,SAAS,IAAI,KAAK;AAC1C,eAAS,IAAI,IAAI,KAAK,iBAAiB,MAAM,IAAI,GAAG,CAAC;AACrD,cAAQ,IAAI,IAAI,KAAK,iBAAiB,MAAM,IAAI,GAAG,CAAC;AAAA,IACtD;AAAA,EACF;AAGA,QAAM,OAAmB,YAAY,IAAI,CAAC,KAAK,MAAM;AACnD,UAAM,UAAU,gBAAgB,CAAC;AACjC,UAAM,QAAQ,KAAK,SAAS,OAAO,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,OAAO,OAAO;AAEhF,UAAM,QAAqB,KAAK,QAAQ,IAAI,CAAC,KAAK,MAAM;AACtD,YAAM,WAAW,gBAAgB,CAAC;AAClC,YAAMA,SAAQ,IAAI,IAAI,GAAG;AAGzB,YAAM,eAAe,YAAY,IAAI,IAAI,GAAG,GAAG,IAAI,OAAO;AAC1D,YAAM,gBAAgB,aAAa,IAAI,IAAI,GAAG,GAAG,IAAI,OAAO;AAE5D,UAAI;AAGJ,UAAI,SAAS,aAAa,SAAS,IAAI,OAAO,OAAOA,WAAU,UAAU;AACvE,kBAAU;AAAA,UACRA;AAAA,UACA,IAAI;AAAA,UACJ,SAAS,IAAI,IAAI,GAAG,KAAK;AAAA,UACzB,QAAQ,IAAI,IAAI,GAAG,KAAK;AAAA,UACxB;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAEA,UAAI,gBAAsC;AAC1C,UAAI,SAAS,aAAa,eAAe,IAAI,WAAW;AACtD,wBAAgB,uBAAuB,KAAK,IAAI,KAAK,IAAI,WAAW,OAAO,QAAQ;AAAA,MACrF;AAEA,aAAO,UAAUA,QAAO,KAAK,UAAU,cAAc,eAAe,SAAS,aAAa;AAAA,IAC5F,CAAC;AAED,WAAO,EAAE,IAAI,OAAO,OAAO,MAAM,IAAI;AAAA,EACvC,CAAC;AAGD,QAAM,YAAY,KAAK;AACvB,QAAM,SAASC;AAAA,IACb;AAAA,MACE,OAAO,KAAK,OAAO;AAAA,MACnB,UAAU,KAAK,OAAO;AAAA,MACtB,QAAQ,KAAK,OAAO;AAAA,MACpB,QAAQ,KAAK,OAAO;AAAA,MACpB,QAAQ,KAAK,OAAO;AAAA,IACtB;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,QAAM,YAAY,KAAK,OAAO,OAAO,QAAQ;AAC7C,QAAM,UAAU,YAAY,UAAU,SAAS,KAAK,mBAAmB,KAAK,MAAM;AAElF,SAAO;AAAA,IACL;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA,MAAM,QAAQ;AAAA,IACd,YAAY;AAAA,IACZ,QAAQ;AAAA,MACN,SAAS,KAAK;AAAA,MACd,aAAa;AAAA,MACb,OAAO,QAAQ,UAAU;AAAA,IAC3B;AAAA,IACA,mBAAmB,KAAK;AAAA,IACxB,SAAS,KAAK;AAAA,IACd,MAAM;AAAA,MACJ;AAAA,MACA,SAAS,GAAG,gBAAgB,MAAM,aAAa,aAAa;AAAA,IAC9D;AAAA,IACA;AAAA,IACA,WAAW,iBAAiB,KAAK,SAAS;AAAA,IAC1C;AAAA,EACF;AACF;;;AUrZA;AAAA,EACE,0BAAAC;AAAA,EACA,cAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,0BAAAC;AAAA,OACK;AAUP,SAAS,YAAYC,QAAgB,WAAoBC,SAAyB;AAChF,MAAID,UAAS,KAAM,QAAO;AAE1B,MAAI,cAAc,cAAcA,kBAAiB,MAAM;AACrD,UAAM,cAAcE,wBAAuBD,OAAM;AACjD,QAAI,YAAa,QAAO,YAAYD,MAA+B;AACnE,WAAOG,YAAWH,MAA+B;AAAA,EACnD;AAEA,MAAI,OAAOA,WAAU,UAAU;AAC7B,QAAIC,SAAQ;AACV,UAAI;AACF,eAAO,OAASA,OAAM,EAAED,MAAK;AAAA,MAC/B,QAAQ;AACN,eAAOI,cAAaJ,MAAK;AAAA,MAC3B;AAAA,IACF;AACA,WAAOI,cAAaJ,MAAK;AAAA,EAC3B;AAEA,SAAO,OAAOA,MAAK;AACrB;AAGA,SAAS,aAAa,IAA6B;AACjD,SAAO,GAAG,SAAS,GAAG,MAAM,SAAS,GAAG;AAC1C;AAGA,SAAS,cAAc,IAAyC;AAC9D,SAAO,GAAG,UAAU,GAAG,MAAM;AAC/B;AAGA,SAAS,2BAA2B,KAAc,UAA6C;AAC7F,SAAO,SAAS,IAAI,CAAC,QAAQ;AAAA,IAC3B,OAAO,aAAa,EAAE;AAAA,IACtB,OAAO,YAAY,IAAI,GAAG,KAAK,GAAG,GAAG,MAAM,cAAc,EAAE,CAAC;AAAA,EAC9D,EAAE;AACJ;AAGA,SAAS,YAAY,KAAc,UAAoBK,QAAgC;AACrF,MAAI,SAAS,SAAS;AACpB,UAAM,WAAW,MAAM,QAAQ,SAAS,OAAO,IAAI,SAAS,UAAU,CAAC,SAAS,OAAO;AACvF,WAAO,2BAA2B,KAAK,QAAQ;AAAA,EACjD;AAEA,QAAM,SAAyB,CAAC;AAGhC,MAAI,SAAS,SAAS,WAAW,SAAS,OAAO;AAC/C,WAAO,KAAK;AAAA,MACV,OAAO,aAAa,SAAS,KAAK;AAAA,MAClC,OAAO;AAAA,QACL,IAAI,SAAS,MAAM,KAAK;AAAA,QACxB,SAAS,MAAM;AAAA,QACf,cAAc,SAAS,KAAK;AAAA,MAC9B;AAAA,MACA,OAAAA;AAAA,IACF,CAAC;AAAA,EACH;AAGA,MAAI,SAAS,GAAG;AACd,WAAO,KAAK;AAAA,MACV,OAAO,aAAa,SAAS,CAAC;AAAA,MAC9B,OAAO,YAAY,IAAI,SAAS,EAAE,KAAK,GAAG,SAAS,EAAE,MAAM,cAAc,SAAS,CAAC,CAAC;AAAA,MACpF,OAAO,SAAS,QAAQ,SAAYA;AAAA,IACtC,CAAC;AAAA,EACH;AAGA,MAAI,SAAS,GAAG;AACd,WAAO,KAAK;AAAA,MACV,OAAO,aAAa,SAAS,CAAC;AAAA,MAC9B,OAAO,YAAY,IAAI,SAAS,EAAE,KAAK,GAAG,SAAS,EAAE,MAAM,cAAc,SAAS,CAAC,CAAC;AAAA,IACtF,CAAC;AAAA,EACH;AAGA,MAAI,SAAS,QAAQ,WAAW,SAAS,MAAM;AAC7C,WAAO,KAAK;AAAA,MACV,OAAO,aAAa,SAAS,IAAI;AAAA,MACjC,OAAO;AAAA,QACL,IAAI,SAAS,KAAK,KAAK;AAAA,QACvB,SAAS,KAAK;AAAA,QACd,cAAc,SAAS,IAAI;AAAA,MAC7B;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAGA,SAAS,gBAAgB,KAAc,UAAwC;AAE7E,MAAI,SAAS,QAAQ;AACnB,WAAO,OAAO,IAAI,SAAS,OAAO,KAAK,KAAK,EAAE;AAAA,EAChD;AAGA,MAAI,SAAS,GAAG,SAAS,YAAY;AACnC,WAAO,YAAY,IAAI,SAAS,EAAE,KAAK,GAAG,UAAU;AAAA,EACtD;AAGA,MAAI,SAAS,GAAG,SAAS,aAAa,SAAS,GAAG,SAAS,WAAW;AACpE,WAAO,OAAO,IAAI,SAAS,EAAE,KAAK,KAAK,EAAE;AAAA,EAC3C;AAGA,MAAI,SAAS,GAAG,SAAS,aAAa,SAAS,GAAG,SAAS,WAAW;AACpE,WAAO,OAAO,IAAI,SAAS,EAAE,KAAK,KAAK,EAAE;AAAA,EAC3C;AAIA,MAAI,SAAS,GAAG,SAAS,kBAAkB,SAAS,GAAG,SAAS,gBAAgB;AAC9E,UAAM,gBAAgB,IAAI;AAAA,MACxB,CAAC,SAAS,GAAG,SAAS,GAAG,SAAS,OAAO,SAAS,MAAM,SAAS,MAAM,EACpE,OAAO,CAAC,OAA8B,CAAC,CAAC,MAAM,WAAW,EAAE,EAC3D,IAAI,CAAC,OAAO,GAAG,KAAK;AAAA,IACzB;AACA,eAAW,CAAC,KAAKL,MAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,UAAI,CAAC,cAAc,IAAI,GAAG,KAAK,OAAOA,WAAU,UAAU;AACxD,eAAOA;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAGA,MAAI,SAAS,SAAS,WAAW,SAAS,OAAO;AAC/C,WAAO,OAAO,IAAI,SAAS,MAAM,KAAK,KAAK,EAAE;AAAA,EAC/C;AAEA,SAAO;AACT;AAMA,SAAS,gBACP,MACA,UACA,YACiC;AAGjC,MAAI,KAAK,YAAY;AACnB,eAAW,MAAM,KAAK,YAAY;AAChC,SAAG,UAAU;AAAA,QACX,OAAO,gBAAgB,GAAG,OAAO,QAAQ;AAAA,QACzC,QAAQ,YAAY,GAAG,OAAO,UAAU,KAAK,MAAM;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAAC;AACV;AAEA,SAAS,iBACP,MACA,UACA,WACiC;AACjC,QAAM,QAAQ,gBAAgB,KAAK,MAAM,QAAQ;AACjD,QAAM,SAAS,YAAY,KAAK,MAAM,UAAUM,yBAAuB,KAAK,IAAI,CAAC;AAEjF,SAAO,CAAC,CAAC,SAAS,SAAS,IAAI,EAAE,OAAO,OAAO,CAAC,CAAC;AACnD;AAEA,SAAS,gBACP,MACA,UACA,WACiC;AACjC,QAAM,QAAQ,gBAAgB,KAAK,MAAM,QAAQ;AACjD,QAAM,SAAS,YAAY,KAAK,MAAM,UAAUA,yBAAuB,KAAK,IAAI,CAAC;AAEjF,SAAO,CAAC,CAAC,QAAQ,SAAS,IAAI,EAAE,OAAO,OAAO,CAAC,CAAC;AAClD;AAEA,SAAS,eACP,MACA,UACA,WACiC;AACjC,QAAM,MAAM,KAAK;AACjB,QAAM,SAAyB,CAAC;AAGhC,QAAM,WAAW,SAAS,SAAS,WAAW,SAAS,QAAQ,SAAS,QAAQ;AAChF,MAAI,UAAU;AACZ,UAAM,eAAe,OAAO,IAAI,SAAS,KAAK,KAAK,EAAE;AACrD,QAAI,SAAS,GAAG;AACd,aAAO,KAAK;AAAA,QACV,OAAO;AAAA,QACP,OAAO,YAAY,IAAI,SAAS,EAAE,KAAK,GAAG,SAAS,EAAE,MAAM,cAAc,SAAS,CAAC,CAAC;AAAA,QACpF,OAAOA,yBAAuB,KAAK,IAAI;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,EACF,WAAW,SAAS,GAAG;AACrB,WAAO,KAAK;AAAA,MACV,OAAO,aAAa,SAAS,CAAC;AAAA,MAC9B,OAAO,YAAY,IAAI,SAAS,EAAE,KAAK,GAAG,SAAS,EAAE,MAAM,cAAc,SAAS,CAAC,CAAC;AAAA,MACpF,OAAOA,yBAAuB,KAAK,IAAI;AAAA,IACzC,CAAC;AAAA,EACH;AAEA,QAAM,QAAQ,WAAW,OAAO,IAAI,SAAS,KAAK,KAAK,EAAE,IAAI;AAE7D,SAAO,CAAC,CAAC,OAAO,SAAS,IAAI,EAAE,OAAO,OAAO,CAAC,CAAC;AACjD;AAEA,SAAS,gBACP,MACA,UACA,YACiC;AAGjC,MAAI,KAAK,YAAY;AACnB,eAAW,MAAM,KAAK,YAAY;AAChC,SAAG,UAAU;AAAA,QACX,OAAO,gBAAgB,GAAG,OAAO,QAAQ;AAAA,QACzC,QAAQ,YAAY,GAAG,OAAO,UAAUA,yBAAuB,KAAK,IAAI,CAAC;AAAA,MAC3E;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAAC;AACV;AAaO,SAAS,0BACd,MACA,OAC6B;AAC7B,QAAM,WAAW,KAAK;AACtB,QAAM,cAAc,oBAAI,IAA4B;AAEpD,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,UAA2C,CAAC;AAEhD,YAAQ,KAAK,MAAM;AAAA,MACjB,KAAK;AACH,kBAAU,gBAAgB,MAAM,UAAU,CAAC;AAC3C;AAAA,MACF,KAAK;AACH,kBAAU,gBAAgB,MAAM,UAAU,CAAC;AAC3C;AAAA,MACF,KAAK;AACH,kBAAU,iBAAiB,MAAM,UAAU,CAAC;AAC5C;AAAA,MACF,KAAK;AACH,kBAAU,gBAAgB,MAAM,UAAU,CAAC;AAC3C;AAAA,MACF,KAAK;AACH,kBAAU,eAAe,MAAM,UAAU,CAAC;AAC1C;AAAA,IACJ;AAEA,eAAW,CAAC,KAAK,OAAO,KAAK,SAAS;AACpC,kBAAY,IAAI,KAAK,OAAO;AAAA,IAC9B;AAAA,EACF;AAEA,SAAO;AACT;;;AC/SA,SAAS,iBAAiB,IAAiB,QAA0B;AACnE,MAAI,OAAO,WAAW,EAAG,QAAO;AAEhC,UAAQ,IAAI;AAAA,IACV,KAAK;AACH,aAAO,OAAO;AAAA,IAChB,KAAK;AACH,aAAO,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC;AAAA,IACzC,KAAK,QAAQ;AACX,YAAMC,OAAM,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC;AAC5C,aAAOA,OAAM,OAAO;AAAA,IACtB;AAAA,IACA,KAAK,UAAU;AACb,YAAM,SAAS,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAC/C,YAAM,MAAM,KAAK,MAAM,OAAO,SAAS,CAAC;AACxC,aAAO,OAAO,SAAS,MAAM,KAAK,OAAO,MAAM,CAAC,IAAI,OAAO,GAAG,KAAK,IAAI,OAAO,GAAG;AAAA,IACnF;AAAA,IACA,KAAK;AACH,aAAO,KAAK,IAAI,GAAG,MAAM;AAAA,IAC3B,KAAK;AACH,aAAO,KAAK,IAAI,GAAG,MAAM;AAAA,IAC3B,KAAK,YAAY;AACf,UAAI,OAAO,SAAS,EAAG,QAAO;AAC9B,YAAM,OAAO,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,OAAO;AACxD,aAAO,OAAO,OAAO,CAAC,GAAG,MAAM,KAAK,IAAI,SAAS,GAAG,CAAC,IAAI,OAAO;AAAA,IAClE;AAAA,IACA,KAAK,SAAS;AACZ,UAAI,OAAO,SAAS,EAAG,QAAO;AAC9B,YAAM,IAAI,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,OAAO;AACrD,aAAO,KAAK,KAAK,OAAO,OAAO,CAAC,GAAG,MAAM,KAAK,IAAI,MAAM,GAAG,CAAC,IAAI,OAAO,MAAM;AAAA,IAC/E;AAAA,IACA,KAAK,MAAM;AACT,YAAM,IAAI,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAC1C,YAAM,KAAK,EAAE,SAAS,KAAK;AAC3B,YAAM,KAAK,KAAK,MAAM,CAAC;AACvB,YAAM,OAAO,IAAI;AACjB,aAAO,EAAE,EAAE,IAAI,SAAS,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE;AAAA,IACpD;AAAA,IACA,KAAK,MAAM;AACT,YAAM,IAAI,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAC1C,YAAM,KAAK,EAAE,SAAS,KAAK;AAC3B,YAAM,KAAK,KAAK,MAAM,CAAC;AACvB,YAAM,OAAO,IAAI;AACjB,aAAO,EAAE,EAAE,IAAI,SAAS,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE;AAAA,IACpD;AAAA,IACA;AACE,aAAO;AAAA,EACX;AACF;AAKA,SAAS,SAAS,KAAc,SAA2B;AACzD,SAAO,QAAQ,IAAI,CAAC,MAAM,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,IAAM;AAC7D;AAaO,SAAS,aAAa,MAAiB,WAA0C;AACtF,QAAM,EAAE,WAAW,QAAQ,IAAI;AAG/B,QAAM,SAAS,oBAAI,IAAuB;AAC1C,aAAW,OAAO,MAAM;AACtB,UAAM,MAAM,SAAS,KAAK,OAAO;AACjC,UAAM,WAAW,OAAO,IAAI,GAAG;AAC/B,QAAI,UAAU;AACZ,eAAS,KAAK,GAAG;AAAA,IACnB,OAAO;AACL,aAAO,IAAI,KAAK,CAAC,GAAG,CAAC;AAAA,IACvB;AAAA,EACF;AAGA,QAAM,SAAoB,CAAC;AAC3B,aAAW,QAAQ,OAAO,OAAO,GAAG;AAElC,UAAM,SAAkB,CAAC;AACzB,eAAW,SAAS,SAAS;AAC3B,aAAO,KAAK,IAAI,KAAK,CAAC,EAAE,KAAK;AAAA,IAC/B;AAGA,eAAW,OAAO,WAAW;AAE3B,UAAI,IAAI,OAAO,YAAY;AACzB,eAAO,IAAI,EAAE,IAAI,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC,EAAE;AACxD;AAAA,MACF;AAEA,YAAM,SAAS,KACZ,IAAI,CAAC,MAAM;AAEV,YAAI,IAAI,OAAO,QAAS,QAAO;AAC/B,cAAM,IAAI,OAAO,EAAE,IAAI,KAAK,CAAC;AAC7B,eAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAAA,MAClC,CAAC,EACA,OAAO,CAAC,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC;AAEjC,aAAO,IAAI,EAAE,IAAI,iBAAiB,IAAI,IAAI,MAAM;AAAA,IAClD;AAEA,WAAO,KAAK,MAAM;AAAA,EACpB;AAEA,SAAO;AACT;;;ACtHA,SAAS,YAAYC,SAA0B,SAAiBC,OAAuB;AACrF,QAAM,OAAOD,QAAO,CAAC,IAAIA,QAAO,CAAC;AACjC,MAAI,SAAS,EAAG,QAAO;AAEvB,MAAI,OAAO,OAAO;AAElB,MAAIC,OAAM;AAER,UAAM,YAAY,MAAM,KAAK,MAAM,KAAK,MAAM,IAAI,CAAC;AACnD,UAAM,WAAW,OAAO;AAExB,QAAI,YAAY,KAAK;AACnB,aAAO;AAAA,IACT,WAAW,YAAY,KAAK;AAC1B,aAAO,IAAI;AAAA,IACb,WAAW,YAAY,KAAK;AAC1B,aAAO,IAAI;AAAA,IACb,OAAO;AACL,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AAEA,SAAO;AACT;AAaO,SAAS,OAAO,MAAiB,WAAoC;AAC1E,QAAM,SAAoB,UAAU,QAAQ,OAAO,CAAC,IAAI,UAAU;AAClE,QAAM,UAAU,OAAO,WAAW;AAClC,QAAMA,QAAO,OAAO,QAAQ;AAC5B,QAAM,QAAQ,UAAU;AAGxB,MAAID,UAAS,OAAO;AACpB,MAAI,CAACA,SAAQ;AACX,QAAIE,OAAM;AACV,QAAIC,OAAM;AACV,eAAW,OAAO,MAAM;AACtB,YAAM,IAAI,OAAO,IAAI,KAAK,CAAC;AAC3B,UAAI,OAAO,SAAS,CAAC,GAAG;AACtB,YAAI,IAAID,KAAK,CAAAA,OAAM;AACnB,YAAI,IAAIC,KAAK,CAAAA,OAAM;AAAA,MACrB;AAAA,IACF;AACA,IAAAH,UAAS,CAACE,SAAQ,WAAW,IAAIA,MAAKC,SAAQ,YAAY,IAAIA,IAAG;AAAA,EACnE;AAEA,QAAM,OAAO,OAAO,QAAQ,YAAYH,SAAQ,SAASC,KAAI;AAC7D,QAAM,CAAC,SAAS,KAAK,IAAI,MAAM,QAAQ,UAAU,EAAE,IAAI,UAAU,KAAK,CAAC,UAAU,IAAI,MAAS;AAE9F,SAAO,KAAK,IAAI,CAAC,QAAQ;AACvB,UAAM,IAAI,OAAO,IAAI,KAAK,CAAC;AAC3B,UAAM,SAAS,EAAE,GAAG,IAAI;AAExB,QAAI,CAAC,OAAO,SAAS,CAAC,GAAG;AACvB,aAAO,OAAO,IAAI;AAClB,UAAI,MAAO,QAAO,KAAK,IAAI;AAAA,IAC7B,OAAO;AACL,YAAM,WAAW,KAAK,OAAO,IAAID,QAAQ,CAAC,KAAK,IAAI,IAAI,OAAOA,QAAQ,CAAC;AACvE,aAAO,OAAO,IAAI;AAClB,UAAI,MAAO,QAAO,KAAK,IAAI,WAAW;AAAA,IACxC;AAEA,WAAO;AAAA,EACT,CAAC;AACH;;;AC3EA,SAAS,mBAAmB,OAAgB,MAAmC;AAC7E,QAAM,aAAa,OAAO,MAAM,KAAK,KAAK,CAAC;AAG3C,UAAQ,KAAK,IAAI;AAAA,IACf,KAAK;AACH,aAAO,KAAK,IAAI,UAAU;AAAA,IAC5B,KAAK;AACH,aAAO,KAAK,MAAM,UAAU;AAAA,IAC9B,KAAK;AACH,aAAO,KAAK,MAAM,UAAU;AAAA,IAC9B,KAAK;AACH,aAAO,KAAK,KAAK,UAAU;AAAA,IAC7B,KAAK;AACH,aAAO,KAAK,IAAI,UAAU;AAAA,IAC5B,KAAK;AACH,aAAO,KAAK,KAAK,UAAU;AAAA,EAC/B;AAGA,QAAM,UAAU,KAAK,WAAW,SAAY,OAAO,MAAM,KAAK,MAAM,CAAC,IAAK,KAAK,SAAS;AAExF,UAAQ,KAAK,IAAI;AAAA,IACf,KAAK;AACH,aAAO,aAAa;AAAA,IACtB,KAAK;AACH,aAAO,aAAa;AAAA,IACtB,KAAK;AACH,aAAO,aAAa;AAAA,IACtB,KAAK;AACH,aAAO,YAAY,IAAI,MAAM,aAAa;AAAA,EAC9C;AACF;AAWO,SAAS,aAAa,MAAiB,WAA0C;AACtF,SAAO,KAAK,IAAI,CAAC,SAAS;AAAA,IACxB,GAAG;AAAA,IACH,CAAC,UAAU,EAAE,GAAG,mBAAmB,KAAK,UAAU,SAAS;AAAA,EAC7D,EAAE;AACJ;;;AC7CO,SAAS,UAAU,MAAiB,WAAuC;AAChF,SAAO,KAAK,OAAO,CAAC,UAAU,kBAAkB,OAAO,SAAS,CAAC;AACnE;;;ACKO,SAAS,QAAQ,MAAiB,WAAqC;AAC5E,QAAM,EAAE,KAAK,IAAI;AACjB,QAAM,CAAC,OAAO,OAAO,IAAI,UAAU,MAAM,CAAC,OAAO,OAAO;AACxD,QAAM,UAAU,IAAI,IAAI,IAAI;AAE5B,QAAM,SAAoB,CAAC;AAE3B,aAAW,OAAO,MAAM;AAEtB,UAAM,OAAgB,CAAC;AACvB,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,GAAG,GAAG;AACxC,UAAI,CAAC,QAAQ,IAAI,CAAC,GAAG;AACnB,aAAK,CAAC,IAAI;AAAA,MACZ;AAAA,IACF;AAGA,eAAW,SAAS,MAAM;AACxB,aAAO,KAAK;AAAA,QACV,GAAG;AAAA,QACH,CAAC,KAAK,GAAG;AAAA,QACT,CAAC,OAAO,GAAG,IAAI,KAAK;AAAA,MACtB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;;;ACrCA,SAAS,gBAAgBI,OAAYC,OAAiC;AACpE,UAAQA,OAAM;AAAA,IACZ,KAAK;AACH,aAAOD,MAAK,YAAY;AAAA,IAC1B,KAAK;AACH,aAAO,KAAK,MAAMA,MAAK,SAAS,IAAI,CAAC,IAAI;AAAA,IAC3C,KAAK;AACH,aAAOA,MAAK,SAAS;AAAA;AAAA,IACvB,KAAK,QAAQ;AAEX,YAAM,IAAI,IAAI,KAAKA,MAAK,QAAQ,CAAC;AACjC,QAAE,SAAS,GAAG,GAAG,GAAG,CAAC;AACrB,QAAE,QAAQ,EAAE,QAAQ,IAAI,KAAM,EAAE,OAAO,IAAI,KAAK,CAAE;AAClD,YAAM,YAAY,IAAI,KAAK,EAAE,YAAY,GAAG,GAAG,CAAC;AAChD,aAAO,KAAK,OAAO,EAAE,QAAQ,IAAI,UAAU,QAAQ,KAAK,QAAW,KAAK,CAAC;AAAA,IAC3E;AAAA,IACA,KAAK;AACH,aAAOA,MAAK,OAAO;AAAA;AAAA,IACrB,KAAK,aAAa;AAChB,YAAM,QAAQ,IAAI,KAAKA,MAAK,YAAY,GAAG,GAAG,CAAC;AAC/C,YAAM,OAAOA,MAAK,QAAQ,IAAI,MAAM,QAAQ;AAC5C,aAAO,KAAK,MAAM,OAAO,KAAQ;AAAA,IACnC;AAAA,IACA,KAAK;AACH,aAAOA,MAAK,QAAQ;AAAA;AAAA,IACtB,KAAK;AACH,aAAOA,MAAK,SAAS;AAAA,IACvB,KAAK;AACH,aAAOA,MAAK,WAAW;AAAA,IACzB,KAAK;AACH,aAAOA,MAAK,WAAW;AAAA,IACzB,KAAK;AACH,aAAOA,MAAK,gBAAgB;AAAA;AAAA,IAE9B,KAAK;AACH,aAAO,GAAGA,MAAK,YAAY,CAAC,IAAI,OAAOA,MAAK,SAAS,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,IAC9E,KAAK;AACH,aAAO,GAAGA,MAAK,YAAY,CAAC,IAAI,OAAOA,MAAK,SAAS,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,OAAOA,MAAK,QAAQ,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,IACzH,KAAK;AACH,aAAO,GAAG,OAAOA,MAAK,SAAS,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,OAAOA,MAAK,QAAQ,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,IACnG,KAAK;AACH,aAAO,GAAG,OAAOA,MAAK,SAAS,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,OAAOA,MAAK,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,EACpG;AACF;AAMA,SAAS,OAAOE,QAA6B;AAC3C,MAAIA,kBAAiB,KAAM,QAAOA;AAClC,MAAI,OAAOA,WAAU,YAAY,OAAOA,WAAU,UAAU;AAC1D,UAAM,IAAI,IAAI,KAAKA,MAAK;AACxB,WAAO,OAAO,MAAM,EAAE,QAAQ,CAAC,IAAI,OAAO;AAAA,EAC5C;AACA,SAAO;AACT;AAYO,SAAS,YAAY,MAAiB,WAAyC;AACpF,SAAO,KAAK,IAAI,CAAC,QAAQ;AACvB,UAAMF,QAAO,OAAO,IAAI,UAAU,KAAK,CAAC;AACxC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,CAAC,UAAU,EAAE,GAAGA,QAAO,gBAAgBA,OAAM,UAAU,QAAQ,IAAI;AAAA,IACrE;AAAA,EACF,CAAC;AACH;;;ACpDO,SAAS,cAAc,MAAiB,YAAoC;AACjF,MAAI,SAAS;AAEb,aAAW,aAAa,YAAY;AAClC,QAAI,YAAY,WAAW;AACzB,eAAS,UAAU,QAAQ,UAAU,MAAM;AAAA,IAC7C,WAAW,SAAS,WAAW;AAC7B,eAAS,OAAO,QAAQ,SAAS;AAAA,IACnC,WAAW,eAAe,WAAW;AACnC,eAAS,aAAa,QAAQ,SAAS;AAAA,IACzC,WAAW,cAAc,WAAW;AAClC,eAAS,YAAY,QAAQ,SAAS;AAAA,IACxC,WAAW,eAAe,WAAW;AACnC,eAAS,aAAa,QAAQ,SAAS;AAAA,IACzC,WAAW,UAAU,WAAW;AAC9B,eAAS,QAAQ,QAAQ,SAAS;AAAA,IACpC;AAAA,EACF;AAEA,SAAO;AACT;;;AnL8BO,SAAS,oBAAoB,MAAwD;AAC1F,QAAM,WAAW,KAAK;AACtB,MAAI,CAAC,SAAU,QAAO;AAEtB,QAAM,sBAAmC,CAAC;AAC1C,QAAM,kBAAkB,EAAE,GAAG,SAAS;AACtC,MAAI,UAAU;AAEd,aAAW,WAAW,OAAO,KAAK,QAAQ,GAAG;AAC3C,UAAM,KAAK,SAAS,OAAO;AAC3B,QAAI,CAAC,MAAM,CAAC,GAAG,MAAO;AAGtB,QAAI,GAAG,OAAO,QAAQ,GAAG,QAAQ,OAAO;AACtC,YAAM,QAAQ,GAAG;AACjB,YAAM,cAAc,OAAO,KAAK;AAChC,YAAM,eAA6B;AAAA,QACjC,KAAK,GAAG,QAAQ,OAAO,OAAQ,GAAG;AAAA,QAClC;AAAA,QACA,IAAI;AAAA,MACN;AACA,0BAAoB,KAAK,YAAY;AAGrC,YAAM,EAAE,KAAK,MAAM,GAAG,KAAK,IAAI;AAC/B,sBAAgB,OAAO,IAAI,EAAE,GAAG,MAAM,OAAO,YAAY;AACzD,gBAAU;AAAA,IACZ;AAGA,UAAM,UAAU,gBAAgB,OAAO,KAAK;AAC5C,QAAI,QAAQ,UAAU;AACpB,YAAM,QAAQ,QAAQ;AACtB,YAAMG,QAAO,QAAQ;AACrB,YAAM,cAAc,GAAGA,KAAI,IAAI,KAAK;AACpC,YAAM,oBAAuC;AAAA,QAC3C,UAAUA;AAAA,QACV;AAAA,QACA,IAAI;AAAA,MACN;AACA,0BAAoB,KAAK,iBAAiB;AAG1C,YAAM,EAAE,UAAU,KAAK,GAAG,KAAK,IAAI;AACnC,sBAAgB,OAAO,IAAI,EAAE,GAAG,MAAM,OAAO,YAAY;AACzD,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,MAAI,CAAC,QAAS,QAAO;AAGrB,QAAM,qBAAsB,KAAK,aAAyC,CAAC;AAC3E,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU;AAAA,IACV,WAAW,CAAC,GAAG,qBAAqB,GAAG,kBAAkB;AAAA,EAC3D;AACF;AAkBO,SAAS,aAAa,MAAe,SAAsC;AAGhF,QAAM,eACJ,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,IACnD,oBAAoB,IAA+B,IACnD;AAGN,QAAM,EAAE,MAAM,WAAW,IAAI,QAAY,YAAY;AAErD,MAAI,UAAU,cAAe,WAAkD,SAAS,SAAS;AAC/F,UAAM,IAAI,MAAM,+DAA+D;AAAA,EACjF;AACA,MAAI,UAAU,cAAe,WAAkD,SAAS,SAAS;AAC/F,UAAM,IAAI,MAAM,+DAA+D;AAAA,EACjF;AACA,MACE,UAAU,cACT,WAAkD,SAAS,UAC5D;AACA,UAAM,IAAI,MAAM,iEAAiE;AAAA,EACnF;AAEA,MAAI,YAAY;AAGhB,QAAM,eAAgB,aAAyC;AAC/D,QAAM,YAAY,iBAAiB,SAAY,UAAU,YAAa,QAAQ,aAAa;AAM3F,QAAM,gBAAiB,aAAyC;AAGhE,MAAI,iBAAiB,cAAc,SAAS,GAAG;AAC7C,gBAAY,EAAE,GAAG,WAAW,MAAM,cAAc,UAAU,MAAM,aAAa,EAAE;AAAA,EACjF;AAGA,QAAM,aAAa,cAAc,QAAQ,KAAK;AAC9C,QAAM,cAAc,eAAe,QAAQ,MAAM;AACjD,MAAI,WAAW,kBAAkB,YAAY,WAAW;AAGxD,QAAM,UAAU;AAChB,QAAM,YAAY,QAAQ;AAQ1B,MAAI,YAAY,UAAU,GAAG;AAC3B,UAAM,KAAK,UAAU,UAAU;AAC/B,QAAI,GAAG,QAAQ;AACb,kBAAY;AAAA,QACV,GAAG;AAAA,QACH,QAAQ;AAAA,UACN,GAAG,UAAU;AAAA,UACb,GAAI,GAAG;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,QAAI,GAAG,QAAQ;AACb,kBAAY;AAAA,QACV,GAAG;AAAA,QACH,QAAQ;AAAA,UACN,GAAG,UAAU;AAAA,UACb,GAAI,GAAG;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,QAAI,GAAG,QAAQ;AACb,kBAAY;AAAA,QACV,GAAG;AAAA,QACH,QAAQ;AAAA,UACN,GAAG,UAAU;AAAA,UACb,GAAI,GAAG;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,QAAI,GAAG,aAAa;AAClB,kBAAY;AAAA,QACV,GAAG;AAAA,QACH,aAAa,GAAG;AAAA,MAClB;AAGA,iBAAW,EAAE,GAAG,UAAU,oBAAoB,SAAS;AAAA,IACzD;AAAA,EACF;AAIA,QAAM,mBAAqB,YAAY,UAAU,GAC7C,aAAa,QAAQ;AACzB,QAAM,oBAAoB,iBAAiB,gBAAgB;AAG3D,QAAM,oBAAoB,QAAQ,QAC9B,EAAE,GAAG,UAAU,OAAO,GAAG,QAAQ,MAAM,IACvC,UAAU;AACd,MAAI,QAAuBC,cAAa,iBAAiB;AACzD,MAAI,QAAQ,UAAU;AACpB,YAAQC,YAAW,KAAK;AAAA,EAC1B;AAKA,QAAM,kBAAwB;AAAA,IAC5B,GAAG;AAAA,IACH,GAAG;AAAA,IACH,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,EAClB;AACA,QAAM,eAAe,cAAc,WAAW,UAAU,OAAO,iBAAiB,SAAS;AAGzF,QAAM,OAAO,kBAAkB,WAAW,SAAS,cAAc,OAAO,UAAU,SAAS;AAC3F,QAAM,YAAY,KAAK;AAMvB,QAAM,aAAmB,EAAE,GAAG,UAAU;AACxC,MAAI,aAAa,QAAQ,SAAS,GAAG;AACnC,YAAQ,aAAa,UAAU;AAAA,MAC7B,KAAK;AACH,mBAAW,KAAK,aAAa,OAAO,SAAS;AAC7C,mBAAW,UAAU,aAAa,OAAO,SAAS;AAClD;AAAA,MACF,KAAK;AACH,mBAAW,UAAU,aAAa,OAAO,SAAS;AAClD;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,mBAAW,SAAS,aAAa,OAAO,QAAQ;AAChD;AAAA,IACJ;AAAA,EACF;AACA,QAAM,cAAc,cAAc,WAAW,UAAU,OAAO,YAAY,SAAS;AAInF,MAAI,aAAa,UAAU;AAG3B,MACE,UAAU,aAAa,SAAS,KAChC,UAAU,SAAS,SACnB,WAAW,UAAU,SAAS,OAC9B;AACA,UAAM,aAAa,UAAU,SAAS,MAAM;AAC5C,UAAM,YAAY,IAAI,IAAI,UAAU,YAAY;AAChD,iBAAa,WAAW,OAAO,CAAC,QAAQ,CAAC,UAAU,IAAI,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC;AAAA,EACjF;AAGA,eAAa,qBAAqB,YAAY,UAAU,QAAQ;AAGhE,QAAM,aAAa,eAAe,UAAU,OAAO,EAAE,GAAG,WAAW,MAAM,WAAW,IAAI;AAGxF,QAAM,SAAS,cAAc,YAAY,WAAW,WAAW,IAAI;AAGnE,uBAAqB,QAAQ,WAAW,UAAU,KAAK;AAKvD,SAAO,eAAe,UAAU,QAAQ,QAAQ,MAAM,OAAO,YAAY,CAAC;AAG1E,QAAM,WAAW,UAAU,aAAa;AAGxC,QAAM,OAAO,WACT,EAAE,GAAG,QAAW,GAAG,OAAU,IAC7B,YAAY,QAAQ,WAAW,UAAU,OAAO,QAAQ,WAAW;AAIvE,MAAI,CAAC,UAAU;AACb,qBAAiB,MAAM,SAAS;AAAA,EAClC;AAGA,QAAM,cAAc;AAAA,IAClB,WAAW;AAAA,IACX,WAAW;AAAA,IACX,WAAW;AAAA,EACb;AACA,QAAM,WAAW,iBAAiB,WAAW;AAC7C,QAAM,QAAgB,WAAW,SAAS,YAAY,QAAQ,WAAW,UAAU,KAAK,IAAI,CAAC;AAG7F,QAAM,YAAoB,CAAC;AAC3B,MAAI,YAAY,OAAO,QAAQ,GAAG;AAChC,cAAU,KAAK,YAAY,MAAM;AAAA,EACnC;AACA,YAAU,KAAK,GAAG,qBAAqB,OAAO,MAAM,CAAC;AAGrD,aAAW,QAAQ,OAAO;AACxB,QAAI,WAAW,QAAQ,KAAK,OAAO,SAAS;AAC1C,gBAAU,KAAK,mBAAmB,KAAK,KAAK,CAAC;AAAA,IAC/C;AAAA,EACF;AAGA,QAAM,gBAAgB,yBAAyB,MAAM,WAAW,MAAM,KAAK;AAC3E,MAAI,cAAe,WAAU,KAAK,aAAa;AAC/C,QAAM,cAAoC;AAAA,IACxC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA,EAAE,OAAO,KAAK,MAAM,OAAO,QAAQ,KAAK,MAAM,OAAO;AAAA,EACvD;AAGA,QAAM,qBAAqB,0BAA0B,WAAW,KAAK;AAGrE,QAAM,UAAU;AAAA,IACd;AAAA,MACE,MAAM,UAAU;AAAA,MAChB,MAAM,UAAU;AAAA,MAChB,UAAU,UAAU;AAAA,MACpB,QAAQ,UAAU;AAAA,IACpB;AAAA,IACA,UAAU;AAAA,EACZ;AACA,QAAM,oBAAoB;AAAA,IACxB;AAAA,MACE,MAAM,UAAU;AAAA,MAChB,MAAM,UAAU;AAAA,MAChB,UAAU,UAAU;AAAA,IACtB;AAAA,IACA,UAAU;AAAA,EACZ;AAGA,yBAAuB,OAAO,iBAAiB;AAE/C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,KAAK;AAAA,IACb,MAAM;AAAA,MACJ,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA,MAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN,mBAAmB,MAAM,SAAS;AAAA,IACpC;AAAA,IACA;AAAA,IACA,YAAY;AAAA,MACV,OAAO,QAAQ;AAAA,MACf,QAAQ,QAAQ;AAAA,IAClB;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA,aAAa,QAAQ;AAAA,EACvB;AACF;AAiBO,SAAS,aAAa,MAAiB,SAAsC;AAElF,QAAM,SAAS,cAAc,IAAI;AAEjC,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AAGA,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,aAAa,iBAAiB,QAAQ,IAAI;AAChD,WAAO,aAAa,YAAY,OAAO;AAAA,EACzC;AAIA,QAAM,cAAc,iBAAiB,QAAQ,IAAI;AACjD,QAAM,gBAAgB,aAAa,aAAa,OAAO;AAIvD,QAAM,WAAmB,CAAC;AAC1B,QAAM,aAAa,oBAAI,IAAY;AACnC,QAAM,sBAAsB,CAAC,GAAG,cAAc,OAAO,OAAO;AAC5D,aAAW,SAAS,qBAAqB;AACvC,eAAW,IAAI,MAAM,KAAK;AAAA,EAC5B;AAEA,aAAW,QAAQ,QAAQ;AAIzB,UAAM,aAAa,aAAa,MAAiB,OAAO;AAExD,aAAS,KAAK,GAAG,WAAW,KAAK;AAGjC,eAAW,SAAS,WAAW,OAAO,SAAS;AAC7C,UAAI,CAAC,WAAW,IAAI,MAAM,KAAK,GAAG;AAChC,mBAAW,IAAI,MAAM,KAAK;AAC1B,4BAAoB,KAAK,KAAK;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO;AAAA,IACP,QAAQ;AAAA,MACN,GAAG,cAAc;AAAA,MACjB,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAOA,SAAS,iBAAiB,QAAqB,WAAiC;AAE9E,QAAM,UAAU,OAAO,QAAQ,CAAC,SAAS,KAAK,IAAI;AAElD,QAAM,UAAU;AAAA,IACd,GAAG,OAAO,CAAC;AAAA,IACX,MAAM;AAAA;AAAA,IAEN,QAAQ,UAAU,UAAU,OAAO,CAAC,EAAE;AAAA,IACtC,QAAQ,UAAU,UAAU,OAAO,CAAC,EAAE;AAAA,IACtC,QAAQ,UAAU,UAAU,OAAO,CAAC,EAAE;AAAA,IACtC,YAAY,UAAU,cAAc,OAAO,CAAC,EAAE;AAAA,IAC9C,OAAO,UAAU,SAAS,OAAO,CAAC,EAAE;AAAA,IACpC,UAAU,UAAU,YAAY,OAAO,CAAC,EAAE;AAAA,IAC1C,WAAW,UAAU,aAAa,OAAO,CAAC,EAAE;AAAA,IAC5C,cAAc,UAAU,gBAAgB,OAAO,CAAC,EAAE;AAAA,EACpD;AAEA,SAAO;AACT;AAiBO,SAAS,aAAa,MAAe,SAA2C;AACrF,QAAM,EAAE,MAAM,WAAW,IAAI,QAAY,IAAI;AAE7C,QAAM,WACJ,UAAU,aAAc,WAAkD,OAAO;AACnF,MAAI,aAAa,SAAS;AACxB,UAAM,IAAI,MAAM,mEAAmE;AAAA,EACrF;AAEA,QAAM,YAAY;AAGlB,QAAM,oBAAoB,QAAQ,QAC9B,EAAE,GAAG,UAAU,OAAO,GAAG,QAAQ,MAAM,IACvC,UAAU;AACd,MAAI,QAAuBD,cAAa,iBAAiB;AACzD,MAAI,QAAQ,UAAU;AACpB,YAAQC,YAAW,KAAK;AAAA,EAC1B;AAGA,QAAM,eAAgB,KAAiC;AACvD,QAAM,YAAY,iBAAiB,SAAY,UAAU,YAAa,QAAQ,aAAa;AAE3F,SAAO,mBAAmB,EAAE,GAAG,WAAW,UAAU,GAAG,SAAS,KAAK;AACvE;AAmBO,SAASC,cAAa,MAAe,SAA2C;AACrF,SAAO,aAAiB,MAAM,OAAO;AACvC;AAkBO,SAASC,eACd,MACA,SACoD;AACpD,SAAO,cAAkB,MAAM,OAAO;AACxC;","names":["adaptTheme","resolveTheme","x","value","date","strValue","x","y","defaultStroke","value","min","max","value","value","date","groupKey","value","color","estimateTextWidth","estimateTextWidth","isGradientDef","value","color","isGradientDef","y","groupKey","buildD3Formatter","estimateTextWidth","getRepresentativeColor","resolveCollisions","LABEL_FONT_SIZE","LABEL_FONT_WEIGHT","buildD3Formatter","estimateTextWidth","getRepresentativeColor","resolveCollisions","value","color","buildD3Formatter","estimateTextWidth","getRepresentativeColor","resolveCollisions","LABEL_FONT_SIZE","LABEL_FONT_WEIGHT","buildD3Formatter","estimateTextWidth","getRepresentativeColor","resolveCollisions","getRepresentativeColor","getRepresentativeColor","x","constant","x","pi","tau","epsilon","x","y","path","t0","t1","x","x","y","x","y","path","path","value","sum","i","j","x","y","point","x","y","tension","x","point","t0","t1","y","x","y","x","y","none_default","none_default","value","y","y","color","getRepresentativeColor","none_default","getRepresentativeColor","color","getRepresentativeColor","point","estimateTextWidth","resolveCollisions","LABEL_FONT_SIZE","LABEL_FONT_WEIGHT","LABEL_OFFSET_X","getRepresentativeColor","isGradientDef","threshold","sum","slice","value","center","color","isGradientDef","path","estimateTextWidth","resolveCollisions","LABEL_FONT_SIZE","LABEL_FONT_WEIGHT","estimateTextWidth","resolveCollisions","getRepresentativeColor","color","getRepresentativeColor","x","left","right","center","x","min","max","value","key","value","value","ticks","max","value","min","value","range","range","range","value","copy","point","format","value","min","max","t1","basis_default","constant_default","x","y","y","constant_default","y","color","rgb","basis_default","x","x","zero","i","constant_default","x","number","x","x","range","i","y","number","x","x","value","value","x","x","x","identity_default","x","locale","identity_default","sign","zero","format","value","formatPrefix","value","max","value","linear","x","x","x","sqrt","quantile","range","x","y","range","x","y","range","x","y","date","range","date","date","date","date","date","date","date","date","ticks","step","date","y","locale","formats","pad","format","value","sign","locale","defaultLocale","number","ticks","second","format","formatYear","tickFormat","date","y","transformer","t0","t1","x","range","copy","DEFAULT_POINT_RADIUS","resolvePosition","value","min","max","sqrt","color","getRepresentativeColor","x","y","color","getRepresentativeColor","getRepresentativeColor","color","getRepresentativeColor","left","right","value","date","value","rules","DEFAULT_STROKE_WIDTH","hex","min","max","sqrt","range","linear","value","color","value","estimateTextWidth","ticks","abbreviateNumber","buildD3Formatter","formatNumber","min","max","value","ticks","ticks","computeChrome","estimateTextWidth","computeChrome","estimateTextWidth","min","max","linear","sqrt","range","quantile","point","BRAND_RESERVE_WIDTH","estimateTextWidth","estimateTextWidth","SWATCH_SIZE","SWATCH_GAP","ENTRY_GAP","value","SWATCH_SIZE","SWATCH_GAP","ENTRY_GAP","stackValue","estimateTextWidth","legendHeight","offsetDx","offsetDy","BRAND_RESERVE_WIDTH","sum","adaptTheme","buildD3Formatter","computeChrome","estimateTextWidth","formatNumber","resolveTheme","max","value","min","value","sum","value","min","x","nodes","links","x","max","min","y","value","dy","resolveCollisions","sourceLinks","targetLinks","pad","resolveTheme","adaptTheme","computeChrome","max","estimateTextWidth","color","SWATCH_SIZE","SWATCH_GAP","ENTRY_GAP","value","buildD3Formatter","formatNumber","computeChrome","estimateTextWidth","value","barPercent","max","min","buildD3Formatter","formatDate","formatNumber","value","adaptColorForDarkMode","min","max","value","adaptColorForDarkMode","color","min","max","range","normalize","points","estimateTextWidth","sum","value","computeChrome","buildTemporalFormatter","formatDate","formatNumber","getRepresentativeColor","value","format","buildTemporalFormatter","formatDate","formatNumber","color","getRepresentativeColor","sum","extent","nice","min","max","date","unit","value","unit","resolveTheme","adaptTheme","compileGraph","compileSankey"]}
|