feat: graphs

This commit is contained in:
2025-03-05 16:26:04 +00:00
parent b52735a0a4
commit 7ba2659fbf
6 changed files with 494 additions and 4 deletions

View File

@ -23,7 +23,8 @@
"qr-code-styling": "^1.8.4",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^7.0.1"
"react-router-dom": "^7.0.1",
"recharts": "^2.15.1"
},
"devDependencies": {
"@eslint/js": "^9.8.0",

View File

@ -101,11 +101,22 @@ export interface PatchVm {
reverse_dns?: string;
}
export interface TimeSeriesData {
timestamp: number;
cpu: number;
memory: number;
memory_size: number;
net_in: number;
net_out: number;
disk_write: number;
disk_read: number;
}
export class LNVpsApi {
constructor(
readonly url: string,
readonly publisher: EventPublisher | undefined,
) {}
) { }
async getAccount() {
const { data } = await this.#handleResponse<ApiResponse<AccountDetail>>(
@ -135,6 +146,13 @@ export class LNVpsApi {
return data;
}
async getVmTimeSeries(id: number) {
const { data } = await this.#handleResponse<ApiResponse<Array<TimeSeriesData>>>(
await this.#req(`/api/v1/vm/${id}/time-series`, "GET"),
);
return data;
}
async patchVm(id: number, req: PatchVm) {
const { data } = await this.#handleResponse<ApiResponse<void>>(
await this.#req(`/api/v1/vm/${id}`, "PATCH", req),

View File

@ -14,6 +14,7 @@ import { TosPage } from "./pages/terms.tsx";
import { StatusPage } from "./pages/status.tsx";
import { AccountSettings } from "./pages/account-settings.tsx";
import { VmBillingPage } from "./pages/vm-billing.tsx";
import { VmGraphsPage } from "./pages/vm-graphs.tsx";
const system = new NostrSystem({
automaticOutboxModel: false,
@ -58,6 +59,10 @@ const router = createBrowserRouter([
path: "/vm/billing/:action?",
element: <VmBillingPage />,
},
{
path: "/vm/graphs",
element: <VmGraphsPage />
},
{
path: "/tos",
element: <TosPage />,

121
src/pages/vm-graphs.tsx Normal file
View File

@ -0,0 +1,121 @@
import { Link, useLocation } from "react-router-dom";
import { TimeSeriesData, VmInstance } from "../api";
import useLogin from "../hooks/login";
import { useEffect, useState } from "react";
import { ResponsiveContainer, XAxis, YAxis, Tooltip, LineChart, Line, Legend } from "recharts";
export function VmGraphsPage() {
const { state } = useLocation() as { state?: VmInstance };
const login = useLogin();
const [data, setData] = useState<Array<TimeSeriesData>>();
useEffect(() => {
if (!state) return;
login?.api.getVmTimeSeries(state.id).then(setData);
}, [login]);
const maxRam = data?.reduce((acc, v) => {
const mb = v.memory_size / 1024 / 1024;
return acc < mb ? mb : acc;
}, 0) ?? 0;
const KB = 1024;
const MB = 1024 * 1024;
function scaleLabel(v: number) {
switch (net_scale) {
case MB: return "MiB";
case KB: return "KiB";
}
return "B";
}
const net_scale = data?.reduce((acc, v) => {
const b = Math.max(v.net_in, v.net_out);
if (b > MB && b > acc) {
return MB;
} else if (b > KB && b > acc) {
return KB;
} else {
return acc;
}
}, 0) ?? 0;
const net_scale_label = scaleLabel(net_scale);
const disk_scale = data?.reduce((acc, v) => {
const b = Math.max(v.disk_read, v.disk_write);
if (b > MB && b > acc) {
return MB;
} else if (b > KB && b > acc) {
return KB;
} else {
return acc;
}
}, 0) ?? 0;
const disk_scale_label = scaleLabel(disk_scale);
const sortedData = (data ?? [])
.sort((a, b) => a.timestamp - b.timestamp)
.map((v) => ({
timestamp: new Date(v.timestamp * 1000).toLocaleTimeString(),
CPU: 100 * v.cpu,
RAM: v.memory / 1024 / 1024,
NET_IN: v.net_in / net_scale,
NET_OUT: v.net_out / net_scale,
DISK_READ: v.disk_read / disk_scale,
DISK_WRITE: v.disk_write / disk_scale,
}));
const toolTip = <Tooltip cursor={{ fill: "rgba(200,200,200,0.5)" }}
content={({ active, payload }) => {
if (active && payload && payload.length) {
const data = payload[0].payload as TimeSeriesData;
return <div className="flex flex-col gap-2 bg-neutral-700 rounded-xl px-2 py-3">
<div>{data.timestamp}</div>
{payload.map((p) => <div>{p.name}: {Number(p.value).toFixed(2)}{p.unit}</div>)}
</div>;
}
}} />;
return <div className="flex flex-col gap-4">
<Link to={"/vm"} state={state}>
&lt; Back
</Link>
<h2>CPU</h2>
<ResponsiveContainer height={200}>
<LineChart data={sortedData} margin={{ left: 0, right: 0 }} style={{ userSelect: "none" }}>
<XAxis dataKey="timestamp" />
<YAxis unit="%" domain={[0, 100]} />
<Line type="monotone" dataKey="CPU" unit="%" dot={false} />
{toolTip}
</LineChart>
</ResponsiveContainer>
<h2>Memory</h2>
<ResponsiveContainer height={200}>
<LineChart data={sortedData} margin={{ left: 0, right: 0 }} style={{ userSelect: "none" }}>
<XAxis dataKey="timestamp" />
<YAxis unit="MB" domain={[0, maxRam]} />
<Line type="monotone" dataKey="RAM" unit="MB" dot={false} />
{toolTip}
</LineChart>
</ResponsiveContainer>
<h2>Network</h2>
<ResponsiveContainer height={200}>
<LineChart data={sortedData} margin={{ left: 20, right: 0 }} style={{ userSelect: "none" }}>
<XAxis dataKey="timestamp" />
<YAxis unit={`${net_scale_label}/s`} domain={[0, "auto"]} />
<Line type="monotone" dataKey="NET_IN" unit={`${net_scale_label}/s`} stroke="red" dot={false} />
<Line type="monotone" dataKey="NET_OUT" unit={`${net_scale_label}/s`} stroke="green" dot={false} />
{toolTip}
<Legend />
</LineChart>
</ResponsiveContainer>
<h2>Disk</h2>
<ResponsiveContainer height={200}>
<LineChart data={sortedData} margin={{ left: 20, right: 0 }} style={{ userSelect: "none" }}>
<XAxis dataKey="timestamp" />
<YAxis unit={`${disk_scale_label}/s`} domain={[0, "auto"]} />
<Line type="monotone" dataKey="DISK_READ" unit={`${disk_scale_label}/s`} stroke="red" dot={false} />
<Line type="monotone" dataKey="DISK_WRITE" unit={`${disk_scale_label}/s`} stroke="green" dot={false} />
{toolTip}
<Legend />
</LineChart>
</ResponsiveContainer>
</div>
}

View File

@ -139,6 +139,9 @@ export default function VmPage() {
<AsyncButton onClick={() => navigate("/vm/billing", { state })}>
Billing
</AsyncButton>
<AsyncButton onClick={() => navigate("/vm/graphs", { state })}>
Graphs
</AsyncButton>
</div>
{/*
{!term && <AsyncButton onClick={openTerminal}>Connect Terminal</AsyncButton>}

346
yarn.lock
View File

@ -204,6 +204,15 @@ __metadata:
languageName: node
linkType: hard
"@babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7":
version: 7.26.9
resolution: "@babel/runtime@npm:7.26.9"
dependencies:
regenerator-runtime: "npm:^0.14.0"
checksum: 10c0/e8517131110a6ec3a7360881438b85060e49824e007f4a64b5dfa9192cf2bb5c01e84bfc109f02d822c7edb0db926928dd6b991e3ee460b483fb0fac43152d9b
languageName: node
linkType: hard
"@babel/template@npm:^7.25.0":
version: 7.25.0
resolution: "@babel/template@npm:7.25.0"
@ -882,6 +891,75 @@ __metadata:
languageName: node
linkType: hard
"@types/d3-array@npm:^3.0.3":
version: 3.2.1
resolution: "@types/d3-array@npm:3.2.1"
checksum: 10c0/38bf2c778451f4b79ec81a2288cb4312fe3d6449ecdf562970cc339b60f280f31c93a024c7ff512607795e79d3beb0cbda123bb07010167bce32927f71364bca
languageName: node
linkType: hard
"@types/d3-color@npm:*":
version: 3.1.3
resolution: "@types/d3-color@npm:3.1.3"
checksum: 10c0/65eb0487de606eb5ad81735a9a5b3142d30bc5ea801ed9b14b77cb14c9b909f718c059f13af341264ee189acf171508053342142bdf99338667cea26a2d8d6ae
languageName: node
linkType: hard
"@types/d3-ease@npm:^3.0.0":
version: 3.0.2
resolution: "@types/d3-ease@npm:3.0.2"
checksum: 10c0/aff5a1e572a937ee9bff6465225d7ba27d5e0c976bd9eacdac2e6f10700a7cb0c9ea2597aff6b43a6ed850a3210030870238894a77ec73e309b4a9d0333f099c
languageName: node
linkType: hard
"@types/d3-interpolate@npm:^3.0.1":
version: 3.0.4
resolution: "@types/d3-interpolate@npm:3.0.4"
dependencies:
"@types/d3-color": "npm:*"
checksum: 10c0/066ebb8da570b518dd332df6b12ae3b1eaa0a7f4f0c702e3c57f812cf529cc3500ec2aac8dc094f31897790346c6b1ebd8cd7a077176727f4860c2b181a65ca4
languageName: node
linkType: hard
"@types/d3-path@npm:*":
version: 3.1.1
resolution: "@types/d3-path@npm:3.1.1"
checksum: 10c0/2c36eb31ebaf2ce4712e793fd88087117976f7c4ed69cc2431825f999c8c77cca5cea286f3326432b770739ac6ccd5d04d851eb65e7a4dbcc10c982b49ad2c02
languageName: node
linkType: hard
"@types/d3-scale@npm:^4.0.2":
version: 4.0.9
resolution: "@types/d3-scale@npm:4.0.9"
dependencies:
"@types/d3-time": "npm:*"
checksum: 10c0/4ac44233c05cd50b65b33ecb35d99fdf07566bcdbc55bc1306b2f27d1c5134d8c560d356f2c8e76b096e9125ffb8d26d95f78d56e210d1c542cb255bdf31d6c8
languageName: node
linkType: hard
"@types/d3-shape@npm:^3.1.0":
version: 3.1.7
resolution: "@types/d3-shape@npm:3.1.7"
dependencies:
"@types/d3-path": "npm:*"
checksum: 10c0/38e59771c1c4c83b67aa1f941ce350410522a149d2175832fdc06396b2bb3b2c1a2dd549e0f8230f9f24296ee5641a515eaf10f55ee1ef6c4f83749e2dd7dcfd
languageName: node
linkType: hard
"@types/d3-time@npm:*, @types/d3-time@npm:^3.0.0":
version: 3.0.4
resolution: "@types/d3-time@npm:3.0.4"
checksum: 10c0/6d9e2255d63f7a313a543113920c612e957d70da4fb0890931da6c2459010291b8b1f95e149a538500c1c99e7e6c89ffcce5554dd29a31ff134a38ea94b6d174
languageName: node
linkType: hard
"@types/d3-timer@npm:^3.0.0":
version: 3.0.2
resolution: "@types/d3-timer@npm:3.0.2"
checksum: 10c0/c644dd9571fcc62b1aa12c03bcad40571553020feeb5811f1d8a937ac1e65b8a04b759b4873aef610e28b8714ac71c9885a4d6c127a048d95118f7e5b506d9e1
languageName: node
linkType: hard
"@types/estree@npm:1.0.5":
version: 1.0.5
resolution: "@types/estree@npm:1.0.5"
@ -1389,6 +1467,13 @@ __metadata:
languageName: node
linkType: hard
"clsx@npm:^2.0.0":
version: 2.1.1
resolution: "clsx@npm:2.1.1"
checksum: 10c0/c4c8eb865f8c82baab07e71bfa8897c73454881c4f99d6bc81585aecd7c441746c1399d08363dc096c550cceaf97bd4ce1e8854e1771e9998d9f94c4fe075839
languageName: node
linkType: hard
"color-convert@npm:^1.9.0":
version: 1.9.3
resolution: "color-convert@npm:1.9.3"
@ -1476,6 +1561,99 @@ __metadata:
languageName: node
linkType: hard
"d3-array@npm:2 - 3, d3-array@npm:2.10.0 - 3, d3-array@npm:^3.1.6":
version: 3.2.4
resolution: "d3-array@npm:3.2.4"
dependencies:
internmap: "npm:1 - 2"
checksum: 10c0/08b95e91130f98c1375db0e0af718f4371ccacef7d5d257727fe74f79a24383e79aba280b9ffae655483ffbbad4fd1dec4ade0119d88c4749f388641c8bf8c50
languageName: node
linkType: hard
"d3-color@npm:1 - 3":
version: 3.1.0
resolution: "d3-color@npm:3.1.0"
checksum: 10c0/a4e20e1115fa696fce041fbe13fbc80dc4c19150fa72027a7c128ade980bc0eeeba4bcf28c9e21f0bce0e0dbfe7ca5869ef67746541dcfda053e4802ad19783c
languageName: node
linkType: hard
"d3-ease@npm:^3.0.1":
version: 3.0.1
resolution: "d3-ease@npm:3.0.1"
checksum: 10c0/fec8ef826c0cc35cda3092c6841e07672868b1839fcaf556e19266a3a37e6bc7977d8298c0fcb9885e7799bfdcef7db1baaba9cd4dcf4bc5e952cf78574a88b0
languageName: node
linkType: hard
"d3-format@npm:1 - 3":
version: 3.1.0
resolution: "d3-format@npm:3.1.0"
checksum: 10c0/049f5c0871ebce9859fc5e2f07f336b3c5bfff52a2540e0bac7e703fce567cd9346f4ad1079dd18d6f1e0eaa0599941c1810898926f10ac21a31fd0a34b4aa75
languageName: node
linkType: hard
"d3-interpolate@npm:1.2.0 - 3, d3-interpolate@npm:^3.0.1":
version: 3.0.1
resolution: "d3-interpolate@npm:3.0.1"
dependencies:
d3-color: "npm:1 - 3"
checksum: 10c0/19f4b4daa8d733906671afff7767c19488f51a43d251f8b7f484d5d3cfc36c663f0a66c38fe91eee30f40327443d799be17169f55a293a3ba949e84e57a33e6a
languageName: node
linkType: hard
"d3-path@npm:^3.1.0":
version: 3.1.0
resolution: "d3-path@npm:3.1.0"
checksum: 10c0/dc1d58ec87fa8319bd240cf7689995111a124b141428354e9637aa83059eb12e681f77187e0ada5dedfce346f7e3d1f903467ceb41b379bfd01cd8e31721f5da
languageName: node
linkType: hard
"d3-scale@npm:^4.0.2":
version: 4.0.2
resolution: "d3-scale@npm:4.0.2"
dependencies:
d3-array: "npm:2.10.0 - 3"
d3-format: "npm:1 - 3"
d3-interpolate: "npm:1.2.0 - 3"
d3-time: "npm:2.1.1 - 3"
d3-time-format: "npm:2 - 4"
checksum: 10c0/65d9ad8c2641aec30ed5673a7410feb187a224d6ca8d1a520d68a7d6eac9d04caedbff4713d1e8545be33eb7fec5739983a7ab1d22d4e5ad35368c6729d362f1
languageName: node
linkType: hard
"d3-shape@npm:^3.1.0":
version: 3.2.0
resolution: "d3-shape@npm:3.2.0"
dependencies:
d3-path: "npm:^3.1.0"
checksum: 10c0/f1c9d1f09926daaf6f6193ae3b4c4b5521e81da7d8902d24b38694517c7f527ce3c9a77a9d3a5722ad1e3ff355860b014557b450023d66a944eabf8cfde37132
languageName: node
linkType: hard
"d3-time-format@npm:2 - 4":
version: 4.1.0
resolution: "d3-time-format@npm:4.1.0"
dependencies:
d3-time: "npm:1 - 3"
checksum: 10c0/735e00fb25a7fd5d418fac350018713ae394eefddb0d745fab12bbff0517f9cdb5f807c7bbe87bb6eeb06249662f8ea84fec075f7d0cd68609735b2ceb29d206
languageName: node
linkType: hard
"d3-time@npm:1 - 3, d3-time@npm:2.1.1 - 3, d3-time@npm:^3.0.0":
version: 3.1.0
resolution: "d3-time@npm:3.1.0"
dependencies:
d3-array: "npm:2 - 3"
checksum: 10c0/a984f77e1aaeaa182679b46fbf57eceb6ebdb5f67d7578d6f68ef933f8eeb63737c0949991618a8d29472dbf43736c7d7f17c452b2770f8c1271191cba724ca1
languageName: node
linkType: hard
"d3-timer@npm:^3.0.1":
version: 3.0.1
resolution: "d3-timer@npm:3.0.1"
checksum: 10c0/d4c63cb4bb5461d7038aac561b097cd1c5673969b27cbdd0e87fa48d9300a538b9e6f39b4a7f0e3592ef4f963d858c8a9f0e92754db73116770856f2fc04561a
languageName: node
linkType: hard
"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4":
version: 4.3.6
resolution: "debug@npm:4.3.6"
@ -1488,6 +1666,13 @@ __metadata:
languageName: node
linkType: hard
"decimal.js-light@npm:^2.4.1":
version: 2.5.1
resolution: "decimal.js-light@npm:2.5.1"
checksum: 10c0/4fd33f535aac9e5bd832796831b65d9ec7914ad129c7437b3ab991b0c2eaaa5a57e654e6174c4a17f1b3895ea366f0c1ab4955cdcdf7cfdcf3ad5a58b456c020
languageName: node
linkType: hard
"deep-is@npm:^0.1.3":
version: 0.1.4
resolution: "deep-is@npm:0.1.4"
@ -1518,6 +1703,16 @@ __metadata:
languageName: node
linkType: hard
"dom-helpers@npm:^5.0.1":
version: 5.2.1
resolution: "dom-helpers@npm:5.2.1"
dependencies:
"@babel/runtime": "npm:^7.8.7"
csstype: "npm:^3.0.2"
checksum: 10c0/f735074d66dd759b36b158fa26e9d00c9388ee0e8c9b16af941c38f014a37fc80782de83afefd621681b19ac0501034b4f1c4a3bff5caa1b8667f0212b5e124c
languageName: node
linkType: hard
"eastasianwidth@npm:^0.2.0":
version: 0.2.0
resolution: "eastasianwidth@npm:0.2.0"
@ -1799,6 +1994,13 @@ __metadata:
languageName: node
linkType: hard
"eventemitter3@npm:^4.0.1":
version: 4.0.7
resolution: "eventemitter3@npm:4.0.7"
checksum: 10c0/5f6d97cbcbac47be798e6355e3a7639a84ee1f7d9b199a07017f1d2f1e2fe236004d14fa5dfaeba661f94ea57805385e326236a6debbc7145c8877fbc0297c6b
languageName: node
linkType: hard
"eventemitter3@npm:^5.0.1":
version: 5.0.1
resolution: "eventemitter3@npm:5.0.1"
@ -1820,6 +2022,13 @@ __metadata:
languageName: node
linkType: hard
"fast-equals@npm:^5.0.1":
version: 5.2.2
resolution: "fast-equals@npm:5.2.2"
checksum: 10c0/2bfeac6317a8959a00e2134749323557e5df6dea3af24e4457297733eace8ce4313fcbca2cf4532f3a6792607461e80442cd8d3af148d5c2e4e98ad996d6e5b5
languageName: node
linkType: hard
"fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0":
version: 3.3.2
resolution: "fast-glob@npm:3.3.2"
@ -2142,6 +2351,13 @@ __metadata:
languageName: node
linkType: hard
"internmap@npm:1 - 2":
version: 2.0.3
resolution: "internmap@npm:2.0.3"
checksum: 10c0/8cedd57f07bbc22501516fbfc70447f0c6812871d471096fad9ea603516eacc2137b633633daf432c029712df0baefd793686388ddf5737e3ea15074b877f7ed
languageName: node
linkType: hard
"ip-address@npm:^9.0.5":
version: 9.0.5
resolution: "ip-address@npm:9.0.5"
@ -2401,6 +2617,7 @@ __metadata:
react: "npm:^18.3.1"
react-dom: "npm:^18.3.1"
react-router-dom: "npm:^7.0.1"
recharts: "npm:^2.15.1"
tailwindcss: "npm:^3.4.8"
typescript: "npm:^5.5.3"
typescript-eslint: "npm:^8.0.0"
@ -2424,7 +2641,14 @@ __metadata:
languageName: node
linkType: hard
"loose-envify@npm:^1.1.0":
"lodash@npm:^4.17.21":
version: 4.17.21
resolution: "lodash@npm:4.17.21"
checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c
languageName: node
linkType: hard
"loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0":
version: 1.4.0
resolution: "loose-envify@npm:1.4.0"
dependencies:
@ -2708,7 +2932,7 @@ __metadata:
languageName: node
linkType: hard
"object-assign@npm:^4.0.1":
"object-assign@npm:^4.0.1, object-assign@npm:^4.1.1":
version: 4.1.1
resolution: "object-assign@npm:4.1.1"
checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414
@ -2959,6 +3183,17 @@ __metadata:
languageName: node
linkType: hard
"prop-types@npm:^15.6.2, prop-types@npm:^15.8.1":
version: 15.8.1
resolution: "prop-types@npm:15.8.1"
dependencies:
loose-envify: "npm:^1.4.0"
object-assign: "npm:^4.1.1"
react-is: "npm:^16.13.1"
checksum: 10c0/59ece7ca2fb9838031d73a48d4becb9a7cc1ed10e610517c7d8f19a1e02fa47f7c27d557d8a5702bec3cfeccddc853579832b43f449e54635803f277b1c78077
languageName: node
linkType: hard
"punycode@npm:^2.1.0":
version: 2.3.1
resolution: "punycode@npm:2.3.1"
@ -3001,6 +3236,20 @@ __metadata:
languageName: node
linkType: hard
"react-is@npm:^16.13.1":
version: 16.13.1
resolution: "react-is@npm:16.13.1"
checksum: 10c0/33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1
languageName: node
linkType: hard
"react-is@npm:^18.3.1":
version: 18.3.1
resolution: "react-is@npm:18.3.1"
checksum: 10c0/f2f1e60010c683479e74c63f96b09fb41603527cd131a9959e2aee1e5a8b0caf270b365e5ca77d4a6b18aae659b60a86150bb3979073528877029b35aecd2072
languageName: node
linkType: hard
"react-refresh@npm:^0.14.2":
version: 0.14.2
resolution: "react-refresh@npm:0.14.2"
@ -3038,6 +3287,35 @@ __metadata:
languageName: node
linkType: hard
"react-smooth@npm:^4.0.4":
version: 4.0.4
resolution: "react-smooth@npm:4.0.4"
dependencies:
fast-equals: "npm:^5.0.1"
prop-types: "npm:^15.8.1"
react-transition-group: "npm:^4.4.5"
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
checksum: 10c0/d94cb27f808721ec040d320ca1927919199495fd212e54eb9dc8ee3f73ff1d808a34be9f4b09fe49b01f411ac2387fdf0e4bee297f18faf56f94bfbef5fd204c
languageName: node
linkType: hard
"react-transition-group@npm:^4.4.5":
version: 4.4.5
resolution: "react-transition-group@npm:4.4.5"
dependencies:
"@babel/runtime": "npm:^7.5.5"
dom-helpers: "npm:^5.0.1"
loose-envify: "npm:^1.4.0"
prop-types: "npm:^15.6.2"
peerDependencies:
react: ">=16.6.0"
react-dom: ">=16.6.0"
checksum: 10c0/2ba754ba748faefa15f87c96dfa700d5525054a0141de8c75763aae6734af0740e77e11261a1e8f4ffc08fd9ab78510122e05c21c2d79066c38bb6861a886c82
languageName: node
linkType: hard
"react@npm:^18.2.0, react@npm:^18.3.1":
version: 18.3.1
resolution: "react@npm:18.3.1"
@ -3065,6 +3343,41 @@ __metadata:
languageName: node
linkType: hard
"recharts-scale@npm:^0.4.4":
version: 0.4.5
resolution: "recharts-scale@npm:0.4.5"
dependencies:
decimal.js-light: "npm:^2.4.1"
checksum: 10c0/64ce1fc4ebe62001787bf4dc4cbb779452d33831619309c71c50277c58e8968ffe98941562d9d0d5ffdb02588ebd62f4fe6548fa826110fd458db9c3cc6dadc1
languageName: node
linkType: hard
"recharts@npm:^2.15.1":
version: 2.15.1
resolution: "recharts@npm:2.15.1"
dependencies:
clsx: "npm:^2.0.0"
eventemitter3: "npm:^4.0.1"
lodash: "npm:^4.17.21"
react-is: "npm:^18.3.1"
react-smooth: "npm:^4.0.4"
recharts-scale: "npm:^0.4.4"
tiny-invariant: "npm:^1.3.1"
victory-vendor: "npm:^36.6.8"
peerDependencies:
react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
checksum: 10c0/1ec3cea442382fe986500b5cc95ef3d5ee194a1cb244fa0fe288b5474c0aa501f89ed39590e1a5fec6ecdfd7ab92bb1e986699a66688423608b75b2559a865b3
languageName: node
linkType: hard
"regenerator-runtime@npm:^0.14.0":
version: 0.14.1
resolution: "regenerator-runtime@npm:0.14.1"
checksum: 10c0/1b16eb2c4bceb1665c89de70dcb64126a22bc8eb958feef3cd68fe11ac6d2a4899b5cd1b80b0774c7c03591dc57d16631a7f69d2daa2ec98100e2f29f7ec4cc4
languageName: node
linkType: hard
"resolve-from@npm:^4.0.0":
version: 4.0.0
resolution: "resolve-from@npm:4.0.0"
@ -3468,6 +3781,13 @@ __metadata:
languageName: node
linkType: hard
"tiny-invariant@npm:^1.3.1":
version: 1.3.3
resolution: "tiny-invariant@npm:1.3.3"
checksum: 10c0/65af4a07324b591a059b35269cd696aba21bef2107f29b9f5894d83cc143159a204b299553435b03874ebb5b94d019afa8b8eff241c8a4cfee95872c2e1c1c4a
languageName: node
linkType: hard
"to-fast-properties@npm:^2.0.0":
version: 2.0.0
resolution: "to-fast-properties@npm:2.0.0"
@ -3607,6 +3927,28 @@ __metadata:
languageName: node
linkType: hard
"victory-vendor@npm:^36.6.8":
version: 36.9.2
resolution: "victory-vendor@npm:36.9.2"
dependencies:
"@types/d3-array": "npm:^3.0.3"
"@types/d3-ease": "npm:^3.0.0"
"@types/d3-interpolate": "npm:^3.0.1"
"@types/d3-scale": "npm:^4.0.2"
"@types/d3-shape": "npm:^3.1.0"
"@types/d3-time": "npm:^3.0.0"
"@types/d3-timer": "npm:^3.0.0"
d3-array: "npm:^3.1.6"
d3-ease: "npm:^3.0.1"
d3-interpolate: "npm:^3.0.1"
d3-scale: "npm:^4.0.2"
d3-shape: "npm:^3.1.0"
d3-time: "npm:^3.0.0"
d3-timer: "npm:^3.0.1"
checksum: 10c0/bad36de3bf4d406834743c2e99a8281d786af324d7e84b7f7a2fc02c27a3779034fb0c3c4707d4c8e68683334d924a67100cfa13985235565e83b9877f8e2ffd
languageName: node
linkType: hard
"vite@npm:^5.4.0":
version: 5.4.0
resolution: "vite@npm:5.4.0"