{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "projection-line",
  "type": "registry:component",
  "title": "Projection Line",
  "description": "Forecast segment extending a line series past the last data point",
  "dependencies": [
    "@visx/shape@4.0.1-alpha.0",
    "motion"
  ],
  "registryDependencies": [
    "@bklit/chart-context",
    "@bklit/line-chart"
  ],
  "files": [
    {
      "path": "src/charts/projection-line.tsx",
      "content": "\"use client\";\n\nimport { curveLinear } from \"@visx/curve\";\nimport { LinePath } from \"@visx/shape\";\nimport { useCallback, useId, useMemo } from \"react\";\nimport { useChartStable, useYScale } from \"./chart-context\";\nimport {\n  buildHorizontalTangentBezierPath,\n  type ProjectionCurveKind,\n  type ProjectionPoint,\n} from \"./projection-utils\";\n\n// biome-ignore lint/suspicious/noExplicitAny: d3 curve factory type\ntype CurveFactory = any;\n\nexport type ProjectionStrokeStyle = \"solid\" | \"gradient\";\n\nexport interface ProjectionLineProps {\n  /** Projection path points — anchor (last data row) + horizon end. */\n  data: ProjectionPoint[];\n  /** Y-scale group id. Default: `\"left\"`. */\n  yAxisId?: string | number;\n  /** Solid stroke color. Default: var(--chart-3) */\n  stroke?: string;\n  /** Solid or path-aligned gradient stroke. Default: solid */\n  strokeStyle?: ProjectionStrokeStyle;\n  /** Gradient start color when `strokeStyle` is gradient. Default: `stroke` */\n  gradientStart?: string;\n  /** Gradient end color when `strokeStyle` is gradient. Default: var(--chart-5) */\n  gradientEnd?: string;\n  /** Stroke width. Default: 2 */\n  strokeWidth?: number;\n  /** Straight segment or horizontal-tangent S-curve. Default: linear */\n  curveKind?: ProjectionCurveKind;\n  /** Advanced curve override (used when `curveKind` is omitted). */\n  curve?: CurveFactory;\n  /** Dash pattern. Default: \"6,4\" */\n  strokeDasharray?: string;\n  /** Stroke opacity. Default: 1 */\n  strokeOpacity?: number;\n  /** Show horizon endpoint marker. Default: true */\n  showEndMarker?: boolean;\n  /** @deprecated Use `showEndMarker`. */\n  showEndpoints?: boolean;\n  /** Endpoint marker radius. Default: 5 */\n  endpointRadius?: number;\n  className?: string;\n}\n\nfunction resolveVisibleEndX(\n  endX: number,\n  innerWidth: number,\n  endpointRadius: number,\n  strokeWidth: number\n): number {\n  const edgePadding = endpointRadius + strokeWidth * 0.5 + 1;\n  return Math.min(endX, Math.max(0, innerWidth - edgePadding));\n}\n\nfunction renderProjectionStroke({\n  bezierPath,\n  curve,\n  curveKind,\n  data,\n  getX,\n  getY,\n  linearPath,\n  strokeProps,\n}: {\n  bezierPath: string | null;\n  curve: CurveFactory | undefined;\n  curveKind: ProjectionCurveKind;\n  data: ProjectionPoint[];\n  getX: (point: ProjectionPoint) => number;\n  getY: (point: ProjectionPoint) => number;\n  linearPath: string | null;\n  strokeProps: {\n    stroke: string;\n    strokeDasharray: string;\n    strokeLinecap: \"round\";\n    strokeOpacity: number;\n    strokeWidth: number;\n  };\n}) {\n  if (curveKind === \"bezier\" && bezierPath) {\n    return <path d={bezierPath} fill=\"none\" {...strokeProps} />;\n  }\n  if (curveKind === \"linear\" && linearPath) {\n    return <path d={linearPath} fill=\"none\" {...strokeProps} />;\n  }\n  return (\n    <LinePath\n      curve={curve ?? curveLinear}\n      data={data}\n      {...strokeProps}\n      x={getX}\n      y={getY}\n    />\n  );\n}\n\nexport function ProjectionLine({\n  data,\n  yAxisId,\n  stroke = \"var(--chart-3)\",\n  strokeStyle = \"solid\",\n  gradientStart,\n  gradientEnd = \"var(--chart-5)\",\n  strokeWidth = 2,\n  curveKind = \"linear\",\n  curve,\n  strokeDasharray = \"6,4\",\n  strokeOpacity = 1,\n  showEndMarker,\n  showEndpoints,\n  endpointRadius = 5,\n  className,\n}: ProjectionLineProps) {\n  const { xScale, chartPhase, innerWidth } = useChartStable();\n  const yScale = useYScale(yAxisId);\n  const gradientId = useId().replace(/:/g, \"\");\n  const showMarker = showEndMarker ?? showEndpoints ?? true;\n  const resolvedGradientStart = gradientStart ?? stroke;\n\n  const getX = useCallback(\n    (point: ProjectionPoint) => xScale(point.date) ?? 0,\n    [xScale]\n  );\n  const getY = useCallback(\n    (point: ProjectionPoint) => yScale(point.value) ?? 0,\n    [yScale]\n  );\n\n  const startPoint = data[0];\n  const endPoint = data.at(-1);\n\n  const geometry = useMemo(() => {\n    if (!(startPoint && endPoint)) {\n      return null;\n    }\n    const startX = getX(startPoint);\n    const startY = getY(startPoint);\n    const endX = getX(endPoint);\n    const endY = getY(endPoint);\n    const visibleEndX = resolveVisibleEndX(\n      endX,\n      innerWidth,\n      showMarker ? endpointRadius : 0,\n      strokeWidth\n    );\n    return { startX, startY, visibleEndX, endY };\n  }, [\n    endPoint,\n    endpointRadius,\n    getX,\n    getY,\n    innerWidth,\n    showMarker,\n    startPoint,\n    strokeWidth,\n  ]);\n\n  const bezierPath = useMemo(() => {\n    if (curveKind !== \"bezier\" || !geometry) {\n      return null;\n    }\n    return buildHorizontalTangentBezierPath(\n      geometry.startX,\n      geometry.startY,\n      geometry.visibleEndX,\n      geometry.endY\n    );\n  }, [curveKind, geometry]);\n\n  const linearPath = useMemo(() => {\n    if (curveKind !== \"linear\" || !geometry) {\n      return null;\n    }\n    return `M ${geometry.startX},${geometry.startY} L ${geometry.visibleEndX},${geometry.endY}`;\n  }, [curveKind, geometry]);\n\n  const showStroke =\n    chartPhase === \"revealing\" ||\n    chartPhase === \"ready\" ||\n    chartPhase === \"exitingReady\";\n\n  if (data.length < 2 || !geometry) {\n    return null;\n  }\n\n  const resolvedStroke =\n    strokeStyle === \"gradient\" && geometry ? `url(#${gradientId})` : stroke;\n  const strokeProps = {\n    stroke: showStroke ? resolvedStroke : \"transparent\",\n    strokeDasharray,\n    strokeLinecap: \"round\" as const,\n    strokeOpacity,\n    strokeWidth,\n  };\n\n  return (\n    <g className={className ?? \"chart-projection-line\"}>\n      {strokeStyle === \"gradient\" && geometry ? (\n        <defs>\n          <linearGradient\n            gradientUnits=\"userSpaceOnUse\"\n            id={gradientId}\n            x1={geometry.startX}\n            x2={geometry.visibleEndX}\n            y1={geometry.startY}\n            y2={geometry.endY}\n          >\n            <stop offset=\"0%\" stopColor={resolvedGradientStart} />\n            <stop offset=\"100%\" stopColor={gradientEnd} />\n          </linearGradient>\n        </defs>\n      ) : null}\n      {renderProjectionStroke({\n        bezierPath,\n        curve,\n        curveKind,\n        data,\n        getX,\n        getY,\n        linearPath,\n        strokeProps,\n      })}\n    </g>\n  );\n}\n\nProjectionLine.displayName = \"ProjectionLine\";\n\nexport default ProjectionLine;\n",
      "type": "registry:component",
      "target": "components/charts/projection-line.tsx"
    },
    {
      "path": "src/charts/projection-line-end-marker.tsx",
      "content": "\"use client\";\n\nimport { useCallback } from \"react\";\nimport { useChartStable, useYScale } from \"./chart-context\";\nimport type { ProjectionPoint } from \"./projection-utils\";\n\nexport interface ProjectionLineEndMarkerProps {\n  data: ProjectionPoint[];\n  yAxisId?: string | number;\n  stroke?: string;\n  strokeOpacity?: number;\n  radius?: number;\n}\n\n/** Renders the projection horizon dot outside the series reveal clip. */\nexport function ProjectionLineEndMarker({\n  data,\n  yAxisId,\n  stroke = \"var(--chart-3)\",\n  strokeOpacity = 1,\n  radius = 5,\n}: ProjectionLineEndMarkerProps) {\n  const { xScale, chartPhase, innerWidth } = useChartStable();\n  const yScale = useYScale(yAxisId);\n\n  const getX = useCallback(\n    (point: ProjectionPoint) => xScale(point.date) ?? 0,\n    [xScale]\n  );\n  const getY = useCallback(\n    (point: ProjectionPoint) => yScale(point.value) ?? 0,\n    [yScale]\n  );\n\n  const showStroke =\n    chartPhase === \"revealing\" ||\n    chartPhase === \"ready\" ||\n    chartPhase === \"exitingReady\";\n\n  if (!showStroke || data.length < 2) {\n    return null;\n  }\n\n  const endPoint = data.at(-1);\n  if (!endPoint) {\n    return null;\n  }\n  const edgePadding = radius + 1;\n  const endX = Math.min(getX(endPoint), Math.max(0, innerWidth - edgePadding));\n  const endY = getY(endPoint);\n\n  return (\n    <circle\n      cx={endX}\n      cy={endY}\n      fill={stroke}\n      fillOpacity={strokeOpacity}\n      r={radius * 0.85}\n    />\n  );\n}\n\nProjectionLineEndMarker.displayName = \"ProjectionLineEndMarker\";\n\n(\n  ProjectionLineEndMarker as unknown as Record<string, boolean>\n).__isPostOverlay = true;\n\nexport default ProjectionLineEndMarker;\n",
      "type": "registry:component",
      "target": "components/charts/projection-line-end-marker.tsx"
    },
    {
      "path": "src/charts/projection-utils.ts",
      "content": "export type ProjectionMode = \"auto\" | \"target\" | \"manual\";\nexport type ProjectionAutoMethod = \"linearRegression\" | \"lastSegment\";\n/** How the projection segment is drawn between anchor and horizon. */\nexport type ProjectionCurveKind = \"linear\" | \"bezier\";\n/** @deprecated Stepped density removed — projections always anchor → horizon. */\nexport type ProjectionPathDensity = \"stepped\" | \"endpoints\";\n\nexport interface ProjectionPoint {\n  date: Date;\n  value: number;\n}\n\nexport interface BuildProjectionPathOptions {\n  sourceData: Record<string, unknown>[];\n  seriesKey: string;\n  xDataKey?: string;\n  mode: ProjectionMode;\n  autoMethod?: ProjectionAutoMethod;\n  /** Auto mode: stepped points per interval, or anchor + end only. Default: stepped */\n  pathDensity?: ProjectionPathDensity;\n  /** Index in sourceData where projection anchors (default: last point). */\n  startIndex?: number;\n  /** How many future points to generate (matches source cadence). */\n  horizonPoints?: number;\n  /** Target Y at the final projected date (target mode). */\n  endValue?: number;\n  /** Full manual path — anchor + future points (manual mode). */\n  points?: ProjectionPoint[];\n}\n\nfunction readDate(row: Record<string, unknown>, xDataKey: string): Date | null {\n  const raw = row[xDataKey];\n  if (raw instanceof Date && !Number.isNaN(raw.getTime())) {\n    return raw;\n  }\n  if (typeof raw === \"number\" && Number.isFinite(raw)) {\n    const date = new Date(raw);\n    return Number.isNaN(date.getTime()) ? null : date;\n  }\n  if (typeof raw === \"string\") {\n    const date = new Date(raw);\n    return Number.isNaN(date.getTime()) ? null : date;\n  }\n  return null;\n}\n\nfunction readValue(\n  row: Record<string, unknown>,\n  seriesKey: string\n): number | null {\n  const raw = row[seriesKey];\n  return typeof raw === \"number\" && Number.isFinite(raw) ? raw : null;\n}\n\nfunction resolveStartIndex(\n  sourceData: Record<string, unknown>[],\n  startIndex: number | undefined\n): number {\n  if (startIndex == null || !Number.isFinite(startIndex)) {\n    return Math.max(0, sourceData.length - 1);\n  }\n  return Math.min(Math.max(0, Math.floor(startIndex)), sourceData.length - 1);\n}\n\nfunction intervalFromAdjacentRows(\n  sourceData: Record<string, unknown>[],\n  xDataKey: string,\n  startIndex: number\n): number | null {\n  if (startIndex < 1) {\n    return null;\n  }\n  const prevRow = sourceData[startIndex - 1];\n  const currentRow = sourceData[startIndex];\n  const prev = prevRow ? readDate(prevRow, xDataKey) : null;\n  const current = currentRow ? readDate(currentRow, xDataKey) : null;\n  if (!(prev && current)) {\n    return null;\n  }\n  const delta = current.getTime() - prev.getTime();\n  return delta > 0 ? delta : null;\n}\n\nfunction intervalFromSeriesSpan(\n  sourceData: Record<string, unknown>[],\n  xDataKey: string\n): number | null {\n  if (sourceData.length < 2) {\n    return null;\n  }\n  const firstRow = sourceData[0];\n  const lastRow = sourceData.at(-1);\n  const first = firstRow ? readDate(firstRow, xDataKey) : null;\n  const last = lastRow ? readDate(lastRow, xDataKey) : null;\n  if (!(first && last)) {\n    return null;\n  }\n  const span = last.getTime() - first.getTime();\n  return span > 0 ? span / (sourceData.length - 1) : null;\n}\n\nfunction resolveIntervalMs(\n  sourceData: Record<string, unknown>[],\n  xDataKey: string,\n  startIndex: number\n): number {\n  return (\n    intervalFromAdjacentRows(sourceData, xDataKey, startIndex) ??\n    intervalFromSeriesSpan(sourceData, xDataKey) ??\n    86_400_000\n  );\n}\n\nfunction linearRegressionSlope(points: { t: number; y: number }[]): number {\n  if (points.length < 2) {\n    return 0;\n  }\n  const n = points.length;\n  let sumT = 0;\n  let sumY = 0;\n  let sumTY = 0;\n  let sumTT = 0;\n  for (const { t, y } of points) {\n    sumT += t;\n    sumY += y;\n    sumTY += t * y;\n    sumTT += t * t;\n  }\n  const denom = n * sumTT - sumT * sumT;\n  if (Math.abs(denom) < 1e-12) {\n    return 0;\n  }\n  return (n * sumTY - sumT * sumY) / denom;\n}\n\nfunction buildAutoFutureValues(options: {\n  anchorTime: number;\n  anchorValue: number;\n  autoMethod: ProjectionAutoMethod;\n  historyPoints: { t: number; y: number }[];\n  horizonPoints: number;\n  intervalMs: number;\n  pathDensity: ProjectionPathDensity;\n}): ProjectionPoint[] {\n  const {\n    anchorTime,\n    anchorValue,\n    autoMethod,\n    historyPoints,\n    horizonPoints,\n    intervalMs,\n    pathDensity,\n  } = options;\n\n  const slope =\n    autoMethod === \"lastSegment\" && historyPoints.length >= 2\n      ? (() => {\n          const prev = historyPoints.at(-2);\n          const last = historyPoints.at(-1);\n          if (!(prev && last)) {\n            return 0;\n          }\n          const dt = last.t - prev.t;\n          return dt === 0 ? 0 : (last.y - prev.y) / dt;\n        })()\n      : linearRegressionSlope(historyPoints);\n\n  if (pathDensity === \"endpoints\") {\n    const endTime = anchorTime + intervalMs * horizonPoints;\n    const endValue = anchorValue + slope * intervalMs * horizonPoints;\n    return [\n      { date: new Date(anchorTime), value: anchorValue },\n      { date: new Date(endTime), value: endValue },\n    ];\n  }\n\n  const result: ProjectionPoint[] = [\n    { date: new Date(anchorTime), value: anchorValue },\n  ];\n\n  for (let i = 1; i <= horizonPoints; i++) {\n    const t = anchorTime + intervalMs * i;\n    const value = anchorValue + slope * intervalMs * i;\n    result.push({ date: new Date(t), value });\n  }\n\n  return result;\n}\n\n/** Slope (value change per ms) at the projection anchor from the last data segment. */\nexport function computeProjectionAnchorTangentSlope(\n  sourceData: Record<string, unknown>[],\n  seriesKey: string,\n  xDataKey = \"date\",\n  startIndexProp?: number\n): number {\n  if (sourceData.length < 2) {\n    return 0;\n  }\n  const startIndex = resolveStartIndex(sourceData, startIndexProp);\n  const historyPoints: { t: number; y: number }[] = [];\n  for (let i = 0; i <= startIndex; i++) {\n    const row = sourceData[i];\n    if (!row) {\n      continue;\n    }\n    const date = readDate(row, xDataKey);\n    const value = readValue(row, seriesKey);\n    if (date && value != null) {\n      historyPoints.push({ t: date.getTime(), y: value });\n    }\n  }\n  if (historyPoints.length < 2) {\n    return 0;\n  }\n  const prev = historyPoints.at(-2);\n  const last = historyPoints.at(-1);\n  if (!(prev && last)) {\n    return 0;\n  }\n  const dt = last.t - prev.t;\n  return dt === 0 ? 0 : (last.y - prev.y) / dt;\n}\n\n/** Cubic bezier with horizontal tangents at start and end (price-target S-curve). */\nexport function buildHorizontalTangentBezierPath(\n  x0: number,\n  y0: number,\n  x1: number,\n  y1: number,\n  /** How far control points sit along the x span (0–0.5). Default: 0.45 */\n  tension = 0.45\n): string {\n  const dx = x1 - x0;\n  if (Math.abs(dx) < 1e-6) {\n    return `M ${x0},${y0} L ${x1},${y1}`;\n  }\n  const t = Math.min(0.5, Math.max(0.05, tension));\n  const c1x = x0 + dx * t;\n  const c2x = x1 - dx * t;\n  return `M ${x0},${y0} C ${c1x},${y0} ${c2x},${y1} ${x1},${y1}`;\n}\n\nfunction buildTargetPath(options: {\n  anchorTime: number;\n  anchorValue: number;\n  endValue: number;\n  horizonPoints: number;\n  intervalMs: number;\n}): ProjectionPoint[] {\n  const { anchorTime, anchorValue, endValue, horizonPoints, intervalMs } =\n    options;\n  const endTime = anchorTime + intervalMs * horizonPoints;\n  return [\n    { date: new Date(anchorTime), value: anchorValue },\n    { date: new Date(endTime), value: endValue },\n  ];\n}\n\n/** Build a projection path from historical chart data or explicit points. */\nexport function buildProjectionPath(\n  options: BuildProjectionPathOptions\n): ProjectionPoint[] {\n  const {\n    sourceData,\n    seriesKey,\n    xDataKey = \"date\",\n    mode,\n    autoMethod = \"linearRegression\",\n    pathDensity = \"endpoints\",\n    startIndex: startIndexProp,\n    horizonPoints = 6,\n    endValue,\n    points,\n  } = options;\n\n  if (mode === \"manual\" && points && points.length >= 2) {\n    return points.map((point) => ({\n      date: new Date(point.date),\n      value: point.value,\n    }));\n  }\n\n  if (sourceData.length === 0) {\n    return [];\n  }\n\n  const startIndex = resolveStartIndex(sourceData, startIndexProp);\n  const anchorRow = sourceData[startIndex];\n  if (!anchorRow) {\n    return [];\n  }\n\n  const anchorDate = readDate(anchorRow, xDataKey);\n  const anchorValue = readValue(anchorRow, seriesKey);\n  if (!anchorDate || anchorValue == null) {\n    return [];\n  }\n\n  const intervalMs = resolveIntervalMs(sourceData, xDataKey, startIndex);\n  const anchorTime = anchorDate.getTime();\n\n  const historyPoints: { t: number; y: number }[] = [];\n  for (let i = 0; i <= startIndex; i++) {\n    const row = sourceData[i];\n    if (!row) {\n      continue;\n    }\n    const date = readDate(row, xDataKey);\n    const value = readValue(row, seriesKey);\n    if (date && value != null) {\n      historyPoints.push({ t: date.getTime(), y: value });\n    }\n  }\n\n  if (mode === \"target\" && endValue != null && Number.isFinite(endValue)) {\n    return buildTargetPath({\n      anchorTime,\n      anchorValue,\n      endValue,\n      horizonPoints,\n      intervalMs,\n    });\n  }\n\n  return buildAutoFutureValues({\n    anchorTime,\n    anchorValue,\n    autoMethod,\n    historyPoints,\n    horizonPoints,\n    intervalMs,\n    pathDensity,\n  });\n}\n\n/** Collect numeric Y extents from projection point arrays. */\nexport function projectionValueExtents(\n  paths: ProjectionPoint[][]\n): { minValue: number; maxValue: number } | null {\n  let minValue = Number.POSITIVE_INFINITY;\n  let maxValue = Number.NEGATIVE_INFINITY;\n\n  for (const path of paths) {\n    for (const point of path) {\n      if (point.value < minValue) {\n        minValue = point.value;\n      }\n      if (point.value > maxValue) {\n        maxValue = point.value;\n      }\n    }\n  }\n\n  if (minValue === Number.POSITIVE_INFINITY) {\n    return null;\n  }\n\n  return { minValue, maxValue };\n}\n\n/** Collect date extents from projection point arrays. */\nexport function projectionDateExtents(\n  paths: ProjectionPoint[][]\n): { minTime: number; maxTime: number } | null {\n  let minTime = Number.POSITIVE_INFINITY;\n  let maxTime = Number.NEGATIVE_INFINITY;\n\n  for (const path of paths) {\n    for (const point of path) {\n      const time = point.date.getTime();\n      if (time < minTime) {\n        minTime = time;\n      }\n      if (time > maxTime) {\n        maxTime = time;\n      }\n    }\n  }\n\n  if (minTime === Number.POSITIVE_INFINITY) {\n    return null;\n  }\n\n  return { minTime, maxTime };\n}\n",
      "type": "registry:component",
      "target": "components/charts/projection-utils.ts"
    },
    {
      "path": "src/charts/line-series-terminal-marker.tsx",
      "content": "\"use client\";\n\nimport { motion } from \"motion/react\";\nimport { useMemo } from \"react\";\nimport { useChartStable, useYScale } from \"./chart-context\";\nimport { StaticSeriesPointMarker } from \"./series-point-marker\";\n\nexport interface LineSeriesTerminalMarkerProps {\n  dataKey: string;\n  yAxisId?: string | number;\n  fill?: string;\n  stroke?: string;\n  radius?: number;\n  ringGap?: number;\n  strokeWidth?: number;\n}\n\nfunction isTerminalMarkerPhaseVisible(phase: string): boolean {\n  return phase === \"ready\" || phase === \"exitingReady\";\n}\n\n/** Hollow ring at the last data point — shared anchor for projection lines. */\nexport function LineSeriesTerminalMarker({\n  dataKey,\n  yAxisId,\n  fill = \"transparent\",\n  stroke = \"var(--chart-1)\",\n  radius = 5,\n  ringGap = 0,\n  strokeWidth = 1.5,\n}: LineSeriesTerminalMarkerProps) {\n  const { data, xScale, xAccessor, chartPhase, revealEpoch, enterTransition } =\n    useChartStable();\n  const yScale = useYScale(yAxisId);\n\n  const point = useMemo(() => {\n    const lastRow = data.at(-1);\n    if (!lastRow) {\n      return null;\n    }\n    const value = lastRow[dataKey];\n    if (typeof value !== \"number\") {\n      return null;\n    }\n    return {\n      cx: xScale(xAccessor(lastRow)) ?? 0,\n      cy: yScale(value) ?? 0,\n    };\n  }, [data, dataKey, xAccessor, xScale, yScale]);\n\n  const visible = isTerminalMarkerPhaseVisible(chartPhase);\n  const fadeTransition =\n    enterTransition && typeof enterTransition === \"object\"\n      ? enterTransition\n      : { duration: 0.28, ease: [0.22, 1, 0.36, 1] as const };\n\n  if (!point) {\n    return null;\n  }\n\n  return (\n    <motion.g\n      animate={{\n        opacity: visible ? 1 : 0,\n        scale: visible ? 1 : 0.55,\n      }}\n      initial={{ opacity: 0, scale: 0.55 }}\n      key={revealEpoch ?? 0}\n      style={{\n        transformBox: \"fill-box\" as const,\n        transformOrigin: `${point.cx}px ${point.cy}px`,\n      }}\n      transition={fadeTransition}\n    >\n      <StaticSeriesPointMarker\n        cx={point.cx}\n        cy={point.cy}\n        fill={fill}\n        radius={radius}\n        ringGap={ringGap}\n        stroke={stroke}\n        strokeWidth={strokeWidth}\n      />\n    </motion.g>\n  );\n}\n\nLineSeriesTerminalMarker.displayName = \"LineSeriesTerminalMarker\";\n\n(\n  LineSeriesTerminalMarker as unknown as Record<string, boolean>\n).__isPostOverlay = true;\n\nexport default LineSeriesTerminalMarker;\n",
      "type": "registry:component",
      "target": "components/charts/line-series-terminal-marker.tsx"
    }
  ]
}