{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "defi-chart",
  "type": "registry:ui",
  "description": "Chart component for displaying real-time data",
  "files": [
    {
      "path": "packages/defi/chart.tsx",
      "content": "\"use client\";\n\nimport React from \"react\";\nimport {\n    BarChart,\n    Bar,\n    XAxis,\n    YAxis,\n    Cell,\n    CartesianGrid,\n    ReferenceLine,\n} from \"recharts\";\nimport {\n    ChartConfig,\n    ChartContainer,\n    ChartTooltip,\n} from \"@/components/ui/chart\";\n\nconst data = [\n    // November 2024\n    { date: \"2024-11-01\", openClose: [0.9188, 0.9201], high: 0.9232, low: 0.917 },\n    { date: \"2024-11-04\", openClose: [0.9193, 0.9181], high: 0.92, low: 0.9162 },\n    {\n        date: \"2024-11-05\",\n        openClose: [0.9193, 0.9171],\n        high: 0.9197,\n        low: 0.9144,\n    },\n    {\n        date: \"2024-11-06\",\n        openClose: [0.9149, 0.9252],\n        high: 0.9361,\n        low: 0.9144,\n    },\n    { date: \"2024-11-07\", openClose: [0.932, 0.9286], high: 0.9334, low: 0.9238 },\n    {\n        date: \"2024-11-08\",\n        openClose: [0.9257, 0.9305],\n        high: 0.9357,\n        low: 0.9254,\n    },\n    {\n        date: \"2024-11-11\",\n        openClose: [0.9339, 0.9365],\n        high: 0.9409,\n        low: 0.9322,\n    },\n    {\n        date: \"2024-11-12\",\n        openClose: [0.9384, 0.9408],\n        high: 0.9438,\n        low: 0.9378,\n    },\n    { date: \"2024-11-13\", openClose: [0.9413, 0.943], high: 0.9473, low: 0.9388 },\n    { date: \"2024-11-14\", openClose: [0.9467, 0.9488], high: 0.9526, low: 0.945 },\n    {\n        date: \"2024-11-15\",\n        openClose: [0.9497, 0.9475],\n        high: 0.9509,\n        low: 0.9441,\n    },\n    {\n        date: \"2024-11-18\",\n        openClose: [0.9497, 0.9462],\n        high: 0.9497,\n        low: 0.9428,\n    },\n    {\n        date: \"2024-11-19\",\n        openClose: [0.9435, 0.9467],\n        high: 0.9501,\n        low: 0.9433,\n    },\n    {\n        date: \"2024-11-20\",\n        openClose: [0.9438, 0.9471],\n        high: 0.9517,\n        low: 0.9425,\n    },\n    {\n        date: \"2024-11-21\",\n        openClose: [0.9484, 0.9516],\n        high: 0.9558,\n        low: 0.9474,\n    },\n    {\n        date: \"2024-11-22\",\n        openClose: [0.9547, 0.9601],\n        high: 0.9677,\n        low: 0.9526,\n    },\n    { date: \"2024-11-25\", openClose: [0.9542, 0.9533], high: 0.957, low: 0.9497 },\n    {\n        date: \"2024-11-26\",\n        openClose: [0.9528, 0.9537],\n        high: 0.9592,\n        low: 0.9483,\n    },\n    {\n        date: \"2024-11-27\",\n        openClose: [0.9534, 0.9496],\n        high: 0.9547,\n        low: 0.9445,\n    },\n    { date: \"2024-11-28\", openClose: [0.9464, 0.948], high: 0.9499, low: 0.9461 },\n    {\n        date: \"2024-11-29\",\n        openClose: [0.9474, 0.9462],\n        high: 0.9486,\n        low: 0.9437,\n    },\n\n    // December 2024\n    {\n        date: \"2024-12-02\",\n        openClose: [0.9454, 0.9507],\n        high: 0.9559,\n        low: 0.9454,\n    },\n    {\n        date: \"2024-12-03\",\n        openClose: [0.9525, 0.9517],\n        high: 0.9541,\n        low: 0.9492,\n    },\n    {\n        date: \"2024-12-04\",\n        openClose: [0.9515, 0.9516],\n        high: 0.9549,\n        low: 0.9484,\n    },\n    { date: \"2024-12-05\", openClose: [0.9514, 0.948], high: 0.9516, low: 0.9444 },\n    {\n        date: \"2024-12-06\",\n        openClose: [0.9445, 0.9447],\n        high: 0.9485,\n        low: 0.9408,\n    },\n    { date: \"2024-12-09\", openClose: [0.947, 0.9467], high: 0.9495, low: 0.9439 },\n    {\n        date: \"2024-12-10\",\n        openClose: [0.9476, 0.9494],\n        high: 0.9525,\n        low: 0.9463,\n    },\n    {\n        date: \"2024-12-11\",\n        openClose: [0.9499, 0.9515],\n        high: 0.9542,\n        low: 0.9488,\n    },\n    {\n        date: \"2024-12-12\",\n        openClose: [0.9527, 0.9526],\n        high: 0.9557,\n        low: 0.9496,\n    },\n    {\n        date: \"2024-12-13\",\n        openClose: [0.9554, 0.9534],\n        high: 0.9566,\n        low: 0.9502,\n    },\n    { date: \"2024-12-16\", openClose: [0.953, 0.9525], high: 0.9547, low: 0.9503 },\n    {\n        date: \"2024-12-17\",\n        openClose: [0.9513, 0.9518],\n        high: 0.9543,\n        low: 0.9493,\n    },\n    { date: \"2024-12-18\", openClose: [0.9532, 0.959], high: 0.9667, low: 0.9512 },\n    {\n        date: \"2024-12-19\",\n        openClose: [0.9659, 0.9629],\n        high: 0.9664,\n        low: 0.9595,\n    },\n    { date: \"2024-12-20\", openClose: [0.965, 0.962], high: 0.9668, low: 0.9572 },\n    { date: \"2024-12-23\", openClose: [0.9583, 0.9601], high: 0.963, low: 0.9573 },\n    { date: \"2024-12-24\", openClose: [0.9609, 0.9618], high: 0.963, low: 0.9606 },\n    {\n        date: \"2024-12-26\",\n        openClose: [0.9614, 0.9606],\n        high: 0.9624,\n        low: 0.9588,\n    },\n    { date: \"2024-12-27\", openClose: [0.9594, 0.9593], high: 0.961, low: 0.9575 },\n    {\n        date: \"2024-12-30\",\n        openClose: [0.9588, 0.9602],\n        high: 0.9642,\n        low: 0.9562,\n    },\n    { date: \"2024-12-31\", openClose: [0.9609, 0.963], high: 0.9667, low: 0.9593 },\n\n    // January 2025\n    { date: \"2025-01-02\", openClose: [0.9656, 0.971], high: 0.9781, low: 0.9639 },\n    { date: \"2025-01-03\", openClose: [0.974, 0.9722], high: 0.9745, low: 0.9699 },\n    {\n        date: \"2025-01-06\",\n        openClose: [0.9704, 0.9648],\n        high: 0.9713,\n        low: 0.9582,\n    },\n    {\n        date: \"2025-01-07\",\n        openClose: [0.9624, 0.9627],\n        high: 0.9671,\n        low: 0.9584,\n    },\n    {\n        date: \"2025-01-08\",\n        openClose: [0.9671, 0.9694],\n        high: 0.9733,\n        low: 0.9655,\n    },\n    {\n        date: \"2025-01-09\",\n        openClose: [0.9691, 0.9706],\n        high: 0.9724,\n        low: 0.9689,\n    },\n    {\n        date: \"2025-01-10\",\n        openClose: [0.9709, 0.9743],\n        high: 0.9789,\n        low: 0.9698,\n    },\n    {\n        date: \"2025-01-13\",\n        openClose: [0.9768, 0.9791],\n        high: 0.9826,\n        low: 0.9756,\n    },\n    {\n        date: \"2025-01-14\",\n        openClose: [0.9762, 0.9734],\n        high: 0.9767,\n        low: 0.9701,\n    },\n    {\n        date: \"2025-01-15\",\n        openClose: [0.9701, 0.9703],\n        high: 0.9747,\n        low: 0.9659,\n    },\n    { date: \"2025-01-16\", openClose: [0.9718, 0.972], high: 0.9745, low: 0.9695 },\n    {\n        date: \"2025-01-17\",\n        openClose: [0.9707, 0.9711],\n        high: 0.9741,\n        low: 0.9681,\n    },\n    { date: \"2025-01-20\", openClose: [0.9725, 0.9662], high: 0.974, low: 0.9585 },\n    { date: \"2025-01-21\", openClose: [0.96, 0.9626], high: 0.9669, low: 0.9583 },\n    { date: \"2025-01-22\", openClose: [0.959, 0.9592], high: 0.9621, low: 0.9563 },\n    { date: \"2025-01-23\", openClose: [0.9606, 0.961], high: 0.964, low: 0.958 },\n    {\n        date: \"2025-01-24\",\n        openClose: [0.9601, 0.9554],\n        high: 0.9604,\n        low: 0.9505,\n    },\n    { date: \"2025-01-27\", openClose: [0.9541, 0.953], high: 0.9565, low: 0.9494 },\n    {\n        date: \"2025-01-28\",\n        openClose: [0.9531, 0.9566],\n        high: 0.9603,\n        low: 0.9529,\n    },\n    {\n        date: \"2025-01-29\",\n        openClose: [0.9587, 0.9603],\n        high: 0.9631,\n        low: 0.9575,\n    },\n    {\n        date: \"2025-01-30\",\n        openClose: [0.9596, 0.9591],\n        high: 0.9628,\n        low: 0.9553,\n    },\n    {\n        date: \"2025-01-31\",\n        openClose: [0.9623, 0.9652],\n        high: 0.9661,\n        low: 0.9585,\n    },\n\n    // February 2025\n    {\n        date: \"2025-02-03\",\n        openClose: [0.9775, 0.9729],\n        high: 0.9796,\n        low: 0.9662,\n    },\n    {\n        date: \"2025-02-04\",\n        openClose: [0.9667, 0.9681],\n        high: 0.9735,\n        low: 0.9627,\n    },\n    { date: \"2025-02-05\", openClose: [0.9635, 0.961], high: 0.9643, low: 0.9576 },\n    { date: \"2025-02-06\", openClose: [0.9612, 0.9635], high: 0.9659, low: 0.961 },\n    {\n        date: \"2025-02-07\",\n        openClose: [0.9631, 0.9655],\n        high: 0.9702,\n        low: 0.9607,\n    },\n    { date: \"2025-02-10\", openClose: [0.9691, 0.97], high: 0.9726, low: 0.9675 },\n    {\n        date: \"2025-02-11\",\n        openClose: [0.9702, 0.9674],\n        high: 0.9716,\n        low: 0.9632,\n    },\n    {\n        date: \"2025-02-12\",\n        openClose: [0.9651, 0.9641],\n        high: 0.9693,\n        low: 0.9589,\n    },\n    { date: \"2025-02-13\", openClose: [0.9631, 0.9597], high: 0.964, low: 0.9554 },\n    {\n        date: \"2025-02-14\",\n        openClose: [0.9555, 0.9541],\n        high: 0.9572,\n        low: 0.9511,\n    },\n    { date: \"2025-02-17\", openClose: [0.954, 0.9536], high: 0.9554, low: 0.9518 },\n    { date: \"2025-02-18\", openClose: [0.9539, 0.956], high: 0.9583, low: 0.9536 },\n    {\n        date: \"2025-02-19\",\n        openClose: [0.9573, 0.9587],\n        high: 0.9615,\n        low: 0.9559,\n    },\n    {\n        date: \"2025-02-20\",\n        openClose: [0.9594, 0.9559],\n        high: 0.9598,\n        low: 0.9521,\n    },\n    { date: \"2025-02-21\", openClose: [0.9523, 0.9545], high: 0.957, low: 0.9519 },\n    {\n        date: \"2025-02-24\",\n        openClose: [0.9541, 0.9533],\n        high: 0.9567,\n        low: 0.9498,\n    },\n    {\n        date: \"2025-02-25\",\n        openClose: [0.9553, 0.9535],\n        high: 0.9563,\n        low: 0.9507,\n    },\n    { date: \"2025-02-26\", openClose: [0.951, 0.9522], high: 0.9546, low: 0.9499 },\n    {\n        date: \"2025-02-27\",\n        openClose: [0.9538, 0.9574],\n        high: 0.9618,\n        low: 0.9531,\n    },\n    {\n        date: \"2025-02-28\",\n        openClose: [0.9617, 0.9625],\n        high: 0.9653,\n        low: 0.9597,\n    },\n];\n\ninterface CandlestickData {\n    date: string;\n    openClose: [number, number];\n    high: number;\n    low: number;\n}\n\nconst chartConfig = {\n    openClose: {\n        label: \"Price\",\n        color: \"var(--chart-1)\",\n    },\n    high: {\n        label: \"High\",\n        color: \"var(--chart-2)\",\n    },\n    low: {\n        label: \"Low\",\n        color: \"var(--chart-3)\",\n    },\n} satisfies ChartConfig;\n\ninterface CandlestickProps {\n    x: number;\n    y: number;\n    width: number;\n    height: number;\n    low: number;\n    high: number;\n    openClose: [number, number];\n}\n\nconst Candlestick = (props: CandlestickProps) => {\n    const {\n        x,\n        y,\n        width,\n        height,\n        low,\n        high,\n        openClose: [open, close],\n    } = props;\n    const isGrowing = open < close;\n    const ratio = Math.abs(height / (open - close));\n\n    return (\n        <g>\n            <path\n                className={`${isGrowing ? \"fill-emerald-500\" : \"fill-rose-500\"}`}\n                d={`\n            M ${x},${y}\n            L ${x},${y + height}\n            L ${x + width},${y + height}\n            L ${x + width},${y}\n            L ${x},${y}\n          `}\n            />\n            <g\n                className={`${isGrowing ? \"stroke-emerald-500\" : \"stroke-rose-500\"}`}\n                strokeWidth=\"1\"\n            >\n                {/* bottom line */}\n                {isGrowing ? (\n                    <path\n                        d={`\n                M ${x + width / 2}, ${y + height}\n                v ${(open - low) * ratio}\n              `}\n                    />\n                ) : (\n                    <path\n                        d={`\n                M ${x + width / 2}, ${y}\n                v ${(close - low) * ratio}\n              `}\n                    />\n                )}\n                {/* top line */}\n                {isGrowing ? (\n                    <path\n                        d={`\n                M ${x + width / 2}, ${y}\n                v ${(close - high) * ratio}\n              `}\n                    />\n                ) : (\n                    <path\n                        d={`\n                M ${x + width / 2}, ${y + height}\n                v ${(open - high) * ratio}\n              `}\n                    />\n                )}\n            </g>\n        </g>\n    );\n};\n\nconst renderCandlestick = (props: any) => {\n    // Extract the necessary data from the props\n    const { x, y, width, height, payload } = props;\n\n    // If we have valid payload, use its data\n    if (\n        payload &&\n        payload.low !== undefined &&\n        payload.high !== undefined &&\n        payload.openClose\n    ) {\n        return (\n            <Candlestick\n                x={x}\n                y={y}\n                width={width}\n                height={height}\n                low={payload.low}\n                high={payload.high}\n                openClose={payload.openClose}\n            />\n        );\n    }\n\n    // Return an empty candlestick with default values if payload is missing\n    return (\n        <Candlestick\n            x={x || 0}\n            y={y || 0}\n            width={width || 0}\n            height={height || 0}\n            low={0}\n            high={0}\n            openClose={[0, 0]}\n        />\n    );\n};\n\nconst CustomTooltip = ({ active, payload }: { active?: boolean; payload?: any[] }) => {\n    if (active && payload && payload.length) {\n        const data = payload[0]?.payload as CandlestickData | undefined;\n        if (!data) return null;\n\n        return (\n            <div className=\"bg-popover text-popover-foreground grid min-w-32 items-start gap-1.5 rounded-lg border px-3 py-1.5 text-xs\">\n                <p className=\"font-medium\">\n                    {new Date(data.date).toLocaleDateString(\"en-US\", {\n                        weekday: \"short\",\n                        year: \"numeric\",\n                        month: \"short\",\n                        day: \"numeric\",\n                    })}\n                </p>\n                <p className=\"text-muted-foreground\">\n                    Open:{\" \"}\n                    <span className=\"text-foreground font-medium\">\n                        {data.openClose[0]}\n                    </span>\n                </p>\n                <p className=\"text-muted-foreground\">\n                    High: <span className=\"text-foreground font-medium\">{data.high}</span>\n                </p>\n                <p className=\"text-muted-foreground\">\n                    Low: <span className=\"text-foreground font-medium\">{data.low}</span>\n                </p>\n                <p className=\"text-muted-foreground\">\n                    Close:{\" \"}\n                    <span className=\"text-foreground font-medium\">\n                        {data.openClose[1]}\n                    </span>\n                </p>\n            </div>\n        );\n    }\n\n    return null;\n};\n\nfunction CandlestickChart() {\n    const minValue = data.reduce(\n        (minValue: number | null, { low, openClose: [open, close] }) => {\n            const currentMin = Math.min(low ?? 0, open ?? 0, close ?? 0);\n            return minValue === null || currentMin < minValue ? currentMin : minValue;\n        },\n        null as number | null,\n    );\n    const maxValue = data.reduce(\n        (maxValue: number, { high, openClose: [open, close] }) => {\n            const currentMax = Math.max(high ?? 0, open ?? 0, close ?? 0);\n            return maxValue === null || currentMax > maxValue ? currentMax : maxValue;\n        },\n        minValue || 0,\n    );\n\n    // Format date to \"Jan '25\" style\n    const formatDate = (dateStr: string) => {\n        const date = new Date(dateStr);\n        const month = date.toLocaleString(\"en-US\", { month: \"short\" });\n        const year = date.getFullYear().toString().slice(2);\n        return `${month} '${year}`;\n    };\n\n    // Custom tick formatter to show each month only once\n    const customTickFormatter = (value: string, index: number) => {\n        const currentDate = new Date(value);\n        const currentMonth = currentDate.getMonth();\n        const currentYear = currentDate.getFullYear();\n\n        // For the first item, always show the month\n        if (index === 0) return formatDate(value);\n\n        // Get previous date safely\n        const prevItem = data[index - 1];\n        if (!prevItem) return formatDate(value);\n\n        const prevDate = new Date(prevItem.date);\n        const prevMonth = prevDate.getMonth();\n        const prevYear = prevDate.getFullYear();\n\n        // Only show the month if it's different from the previous one\n        if (currentMonth !== prevMonth || currentYear !== prevYear) {\n            return formatDate(value);\n        }\n\n        return \"\";\n    };\n\n    // Get the most recent day's close value\n    const mostRecentData = data[data.length - 1];\n    const mostRecentClose = mostRecentData ? mostRecentData.openClose[1] : null;\n\n    // Add this line to define isGrowing\n    const isGrowing =\n        mostRecentData &&\n            mostRecentData.openClose &&\n            mostRecentData.openClose[1] !== undefined &&\n            mostRecentData.openClose[0] !== undefined\n            ? mostRecentData.openClose[1] > mostRecentData.openClose[0]\n            : undefined;\n\n    return (\n        <div className=\"w-full\">\n            <ChartContainer\n                config={chartConfig}\n                className=\"aspect-auto h-110 w-full [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-zinc-950/5 dark:[&_.recharts-rectangle.recharts-tooltip-cursor]:fill-zinc-950/25 [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/64 [&_.recharts-cartesian-axis-line]:stroke-border/64 [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground/72 dark:[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground/64\"\n            >\n                <BarChart data={data} maxBarSize={20} margin={{ left: 20, right: -5 }}>\n                    <CartesianGrid vertical={false} strokeWidth={1} />\n                    <XAxis\n                        dataKey=\"date\"\n                        tickLine={false}\n                        tickFormatter={customTickFormatter}\n                        interval={0}\n                        minTickGap={5}\n                        tickMargin={12}\n                    />\n                    <YAxis\n                        domain={[\n                            minValue !== null\n                                ? minValue - (maxValue - (minValue ?? 0)) * 0.1\n                                : 0,\n                            maxValue + (maxValue - (minValue ?? 0)) * 0.1,\n                        ]}\n                        tickCount={7}\n                        tickLine={false}\n                        orientation=\"right\"\n                        tickFormatter={(value: any) => value.toFixed(4)}\n                    />\n\n                    {/* Reference line for most recent close value */}\n                    {mostRecentClose && (\n                        <ReferenceLine\n                            y={mostRecentClose}\n                            stroke=\"var(--muted-foreground)\"\n                            opacity={0.5}\n                            strokeWidth={1}\n                            strokeDasharray=\"2 2\"\n                            label={({ viewBox }: any) => (\n                                <g\n                                    transform={`translate(${viewBox.x + viewBox.width + 5},${viewBox.y})`}\n                                >\n                                    <rect\n                                        x={-2}\n                                        y={-10}\n                                        width={50}\n                                        height={20}\n                                        fill={\n                                            isGrowing\n                                                ? \"var(--color-emerald-500)\"\n                                                : \"var(--color-rose-500)\"\n                                        }\n                                        rx={4}\n                                    />\n                                    <text\n                                        x={2}\n                                        y={4}\n                                        fill=\"#fff\"\n                                        fontSize={12}\n                                        fontWeight=\"500\"\n                                        textAnchor=\"start\"\n                                    >\n                                        {mostRecentClose.toFixed(4)}\n                                    </text>\n                                </g>\n                            )}\n                        />\n                    )}\n\n                    <ChartTooltip content={<CustomTooltip />} />\n                    <Bar dataKey=\"openClose\" shape={renderCandlestick}>\n                        {data.map(({ date }: any) => (\n                            <Cell key={`cell-${date}`} />\n                        ))}\n                    </Bar>\n                </BarChart>\n            </ChartContainer>\n        </div>\n    );\n}\n\nexport { CandlestickChart };",
      "type": "registry:component"
    }
  ]
}