Rami-Troudi commited on
Commit
64e5c41
·
1 Parent(s): 1008099

Improve UI and unify api, types and schemas

Browse files
ui/app/api/data/route.ts ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { NextResponse } from "next/server";
2
+ import { DataResponse } from "@/types/data";
3
+
4
+ export async function GET() {
5
+ // TODO: replace mock data with real backend call
6
+ const datasets = [
7
+ { name: "DrugBank Compounds", type: "Molecules", count: "12,450", size: "45.2 MB", updated: "2024-01-15" },
8
+ { name: "ChEMBL Kinase Inhibitors", type: "Molecules", count: "8,234", size: "32.1 MB", updated: "2024-01-10" },
9
+ { name: "Custom Protein Targets", type: "Proteins", count: "1,245", size: "78.5 MB", updated: "2024-01-08" },
10
+ ];
11
+
12
+ const stats = {
13
+ datasets: 5,
14
+ molecules: "24.5K",
15
+ proteins: "1.2K",
16
+ storage: "156 MB",
17
+ };
18
+
19
+ const response: DataResponse = { datasets, stats };
20
+ return NextResponse.json(response);
21
+ }
ui/app/api/explorer/route.ts ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { NextResponse } from "next/server";
2
+ import { ExplorerResponse, DataPoint } from "@/types/explorer";
3
+ import { ExplorerRequestSchema } from "@/schemas/explorer";
4
+
5
+ const clusters = [
6
+ { cx: 2, cy: 3, color: "var(--color-chart-1)" },
7
+ { cx: -2, cy: -1, color: "var(--color-chart-2)" },
8
+ { cx: 4, cy: -2, color: "var(--color-chart-3)" },
9
+ { cx: -1, cy: 4, color: "var(--color-chart-4)" },
10
+ ];
11
+
12
+ export async function GET(request: Request) {
13
+ const { searchParams } = new URL(request.url);
14
+
15
+ // Validate query params
16
+ const result = ExplorerRequestSchema.safeParse({
17
+ dataset: searchParams.get("dataset") || undefined,
18
+ view: searchParams.get("view") || undefined,
19
+ colorBy: searchParams.get("colorBy") || undefined,
20
+ });
21
+
22
+ if (!result.success) {
23
+ return NextResponse.json({ error: result.error }, { status: 400 });
24
+ }
25
+
26
+ // TODO: replace mock generation with backend embeddings
27
+ const points: DataPoint[] = [];
28
+ for (let i = 0; i < 200; i++) {
29
+ const cluster = clusters[Math.floor(i / 50)];
30
+ points.push({
31
+ x: cluster.cx + (Math.random() - 0.5) * 2,
32
+ y: cluster.cy + (Math.random() - 0.5) * 2,
33
+ z: Math.random() * 100,
34
+ color: cluster.color,
35
+ name: `Mol_${i}`,
36
+ affinity: Math.random() * 100,
37
+ });
38
+ }
39
+
40
+ const metrics = {
41
+ activeMolecules: 12450,
42
+ clusters: 4,
43
+ avgConfidence: 0.89,
44
+ };
45
+
46
+ const response: ExplorerResponse = { points, metrics };
47
+ return NextResponse.json(response);
48
+ }
ui/app/data/data-view.tsx ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client"
2
+
3
+ import { Card, CardContent } from "@/components/ui/card"
4
+ import { Button } from "@/components/ui/button"
5
+ import { Badge } from "@/components/ui/badge"
6
+ import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"
7
+ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
8
+ import { Folder, FileText, Database, HardDrive, Upload, CloudUpload, Eye, Download, Trash2 } from "lucide-react"
9
+ import { SectionHeader } from "@/components/page-header"
10
+ import { Dataset, Statistics } from "@/types/data"
11
+
12
+ interface DataViewProps {
13
+ datasets: Dataset[];
14
+ stats: Statistics | null;
15
+ }
16
+
17
+ export function DataView({ datasets, stats }: DataViewProps) {
18
+ const statCards = [
19
+ { label: "Datasets", value: stats?.datasets?.toString() ?? "—", icon: Folder, color: "text-blue-500" },
20
+ { label: "Molecules", value: stats?.molecules ?? "—", icon: FileText, color: "text-cyan-500" },
21
+ { label: "Proteins", value: stats?.proteins ?? "—", icon: Database, color: "text-emerald-500" },
22
+ { label: "Storage Used", value: stats?.storage ?? "—", icon: HardDrive, color: "text-amber-500" },
23
+ ]
24
+
25
+ return (
26
+ <div className="space-y-8">
27
+ <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
28
+ {statCards.map((stat, i) => (
29
+ <Card key={i}>
30
+ <CardContent className="p-6">
31
+ <div className="flex justify-between items-start mb-2">
32
+ <div className="text-sm font-medium text-muted-foreground">{stat.label}</div>
33
+ <div className={`text-lg ${stat.color}`}><stat.icon className="h-5 w-5" /></div>
34
+ </div>
35
+ <div className="text-2xl font-bold">{stat.value}</div>
36
+ </CardContent>
37
+ </Card>
38
+ ))}
39
+ </div>
40
+
41
+ <Tabs defaultValue="datasets">
42
+ <TabsList>
43
+ <TabsTrigger value="datasets">Datasets</TabsTrigger>
44
+ <TabsTrigger value="upload">Upload</TabsTrigger>
45
+ <TabsTrigger value="processing">Processing</TabsTrigger>
46
+ </TabsList>
47
+ <TabsContent value="datasets" className="space-y-4">
48
+ <SectionHeader title="Your Datasets" icon={<Folder className="h-5 w-5 text-primary" />} />
49
+ <Card>
50
+ <Table>
51
+ <TableHeader>
52
+ <TableRow>
53
+ <TableHead>Name</TableHead>
54
+ <TableHead>Type</TableHead>
55
+ <TableHead>Items</TableHead>
56
+ <TableHead>Size</TableHead>
57
+ <TableHead>Updated</TableHead>
58
+ <TableHead className="text-right">Actions</TableHead>
59
+ </TableRow>
60
+ </TableHeader>
61
+ <TableBody>
62
+ {datasets.length === 0 && (
63
+ <TableRow>
64
+ <TableCell colSpan={6} className="text-center text-muted-foreground text-sm">No datasets found.</TableCell>
65
+ </TableRow>
66
+ )}
67
+ {datasets.map((ds, i) => (
68
+ <TableRow key={i}>
69
+ <TableCell className="font-medium">{ds.name}</TableCell>
70
+ <TableCell>
71
+ <div className="flex items-center gap-2">
72
+ <Badge variant={ds.type === 'Molecules' ? 'default' : 'secondary'}>{ds.type}</Badge>
73
+ </div>
74
+ </TableCell>
75
+ <TableCell>{ds.count}</TableCell>
76
+ <TableCell>{ds.size}</TableCell>
77
+ <TableCell>{ds.updated}</TableCell>
78
+ <TableCell className="text-right">
79
+ <div className="flex justify-end gap-2">
80
+ <Button size="icon" variant="ghost" className="h-8 w-8"><Eye className="h-4 w-4" /></Button>
81
+ <Button size="icon" variant="ghost" className="h-8 w-8"><Download className="h-4 w-4" /></Button>
82
+ <Button size="icon" variant="ghost" className="h-8 w-8 text-destructive hover:text-destructive"><Trash2 className="h-4 w-4" /></Button>
83
+ </div>
84
+ </TableCell>
85
+ </TableRow>
86
+ ))}
87
+ </TableBody>
88
+ </Table>
89
+ </Card>
90
+ </TabsContent>
91
+ <TabsContent value="upload">
92
+ <SectionHeader title="Upload New Data" icon={<Upload className="h-5 w-5 text-primary" />} />
93
+ <Card>
94
+ <CardContent className="p-12">
95
+ <div className="border-2 border-dashed rounded-lg p-12 flex flex-col items-center justify-center text-center space-y-4 hover:bg-accent/50 transition-colors cursor-pointer">
96
+ <div className="h-16 w-16 rounded-full bg-primary/10 flex items-center justify-center text-primary">
97
+ <CloudUpload className="h-8 w-8" />
98
+ </div>
99
+ <div>
100
+ <div className="text-lg font-semibold">Click to upload or drag and drop</div>
101
+ <div className="text-sm text-muted-foreground">CSV, SDF, FASTA, or JSON (max 50MB)</div>
102
+ </div>
103
+ </div>
104
+ </CardContent>
105
+ </Card>
106
+ </TabsContent>
107
+ <TabsContent value="processing">
108
+ <Card>
109
+ <CardContent className="p-12 text-center text-muted-foreground">
110
+ No active processing tasks.
111
+ </CardContent>
112
+ </Card>
113
+ </TabsContent>
114
+ </Tabs>
115
+ </div>
116
+ )
117
+ }
ui/app/data/page.tsx CHANGED
@@ -1,116 +1,49 @@
1
- "use client"
 
 
 
 
 
2
 
3
- import { PageHeader, SectionHeader } from "@/components/page-header"
4
- import { Card, CardContent } from "@/components/ui/card"
5
- import { Button } from "@/components/ui/button"
6
- import { Badge } from "@/components/ui/badge"
7
- import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"
8
- import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
9
- import { Folder, FileText, Database, HardDrive, Upload, CloudUpload, Eye, Download, Trash2 } from "lucide-react"
10
-
11
- export default function DataPage() {
12
- const datasets = [
13
- { name: "DrugBank Compounds", type: "Molecules", count: "12,450", size: "45.2 MB", updated: "2024-01-15" },
14
- { name: "ChEMBL Kinase Inhibitors", type: "Molecules", count: "8,234", size: "32.1 MB", updated: "2024-01-10" },
15
- { name: "Custom Protein Targets", type: "Proteins", count: "1,245", size: "78.5 MB", updated: "2024-01-08" },
16
- ]
 
 
 
 
 
 
17
 
18
- return (
19
- <div className="space-y-8 animate-in fade-in duration-500">
20
- <PageHeader
21
- title="Data Management"
22
- subtitle="Upload, manage, and organize your datasets"
23
- icon={<Database className="h-8 w-8" />}
24
- />
25
 
26
- <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
27
- {[
28
- { label: "Datasets", value: "5", icon: Folder, color: "text-blue-500" },
29
- { label: "Molecules", value: "24.5K", icon: FileText, color: "text-cyan-500" },
30
- { label: "Proteins", value: "1.2K", icon: Database, color: "text-emerald-500" },
31
- { label: "Storage Used", value: "156 MB", icon: HardDrive, color: "text-amber-500" },
32
- ].map((stat, i) => (
33
- <Card key={i}>
34
- <CardContent className="p-6">
35
- <div className="flex justify-between items-start mb-2">
36
- <div className="text-sm font-medium text-muted-foreground">{stat.label}</div>
37
- <div className={`text-lg ${stat.color}`}><stat.icon className="h-5 w-5" /></div>
38
- </div>
39
- <div className="text-2xl font-bold">{stat.value}</div>
40
- </CardContent>
41
- </Card>
42
- ))}
43
- </div>
44
 
45
- <Tabs defaultValue="datasets">
46
- <TabsList>
47
- <TabsTrigger value="datasets">Datasets</TabsTrigger>
48
- <TabsTrigger value="upload">Upload</TabsTrigger>
49
- <TabsTrigger value="processing">Processing</TabsTrigger>
50
- </TabsList>
51
- <TabsContent value="datasets" className="space-y-4">
52
- <SectionHeader title="Your Datasets" icon={<Folder className="h-5 w-5 text-primary" />} />
53
- <Card>
54
- <Table>
55
- <TableHeader>
56
- <TableRow>
57
- <TableHead>Name</TableHead>
58
- <TableHead>Type</TableHead>
59
- <TableHead>Items</TableHead>
60
- <TableHead>Size</TableHead>
61
- <TableHead>Updated</TableHead>
62
- <TableHead className="text-right">Actions</TableHead>
63
- </TableRow>
64
- </TableHeader>
65
- <TableBody>
66
- {datasets.map((ds, i) => (
67
- <TableRow key={i}>
68
- <TableCell className="font-medium">{ds.name}</TableCell>
69
- <TableCell>
70
- <div className="flex items-center gap-2">
71
- <Badge variant={ds.type === 'Molecules' ? 'default' : 'secondary'}>{ds.type}</Badge>
72
- </div>
73
- </TableCell>
74
- <TableCell>{ds.count}</TableCell>
75
- <TableCell>{ds.size}</TableCell>
76
- <TableCell>{ds.updated}</TableCell>
77
- <TableCell className="text-right">
78
- <div className="flex justify-end gap-2">
79
- <Button size="icon" variant="ghost" className="h-8 w-8"><Eye className="h-4 w-4" /></Button>
80
- <Button size="icon" variant="ghost" className="h-8 w-8"><Download className="h-4 w-4" /></Button>
81
- <Button size="icon" variant="ghost" className="h-8 w-8 text-destructive hover:text-destructive"><Trash2 className="h-4 w-4" /></Button>
82
- </div>
83
- </TableCell>
84
- </TableRow>
85
- ))}
86
- </TableBody>
87
- </Table>
88
- </Card>
89
- </TabsContent>
90
- <TabsContent value="upload">
91
- <SectionHeader title="Upload New Data" icon={<Upload className="h-5 w-5 text-primary" />} />
92
- <Card>
93
- <CardContent className="p-12">
94
- <div className="border-2 border-dashed rounded-lg p-12 flex flex-col items-center justify-center text-center space-y-4 hover:bg-accent/50 transition-colors cursor-pointer">
95
- <div className="h-16 w-16 rounded-full bg-primary/10 flex items-center justify-center text-primary">
96
- <CloudUpload className="h-8 w-8" />
97
- </div>
98
- <div>
99
- <div className="text-lg font-semibold">Click to upload or drag and drop</div>
100
- <div className="text-sm text-muted-foreground">CSV, SDF, FASTA, or JSON (max 50MB)</div>
101
- </div>
102
- </div>
103
- </CardContent>
104
- </Card>
105
- </TabsContent>
106
- <TabsContent value="processing">
107
- <Card>
108
- <CardContent className="p-12 text-center text-muted-foreground">
109
- No active processing tasks.
110
- </CardContent>
111
- </Card>
112
- </TabsContent>
113
- </Tabs>
114
- </div>
115
- )
116
  }
 
1
+ import { Suspense } from 'react'
2
+ import { getApiUrl } from "@/lib/api-utils"
3
+ import { DataView } from "./data-view"
4
+ import { PageHeader } from "@/components/page-header"
5
+ import { Database, Loader2 } from "lucide-react"
6
+ import { DataResponse } from "@/types/data"
7
 
8
+ async function getData() {
9
+ try {
10
+ const apiUrl = getApiUrl()
11
+ const baseUrl = apiUrl || 'http://localhost:3000'
12
+
13
+ const res = await fetch(`${baseUrl}/api/data`, {
14
+ cache: 'no-store'
15
+ })
16
+
17
+ if (!res.ok) {
18
+ throw new Error(`Failed to fetch data: ${res.status}`)
19
+ }
20
+
21
+ const json = await res.json() as DataResponse
22
+ return json
23
+ } catch (error) {
24
+ console.error("Error fetching data:", error)
25
+ return { datasets: [], stats: { datasets: 0, molecules: "0", proteins: "0", storage: "0" } }
26
+ }
27
+ }
28
 
29
+ export default async function DataPage() {
30
+ const { datasets, stats } = await getData()
 
 
 
 
 
31
 
32
+ return (
33
+ <div className="space-y-8 animate-in fade-in duration-500">
34
+ <PageHeader
35
+ title="Data Management"
36
+ subtitle="Upload, manage, and organize your datasets"
37
+ icon={<Database className="h-8 w-8" />}
38
+ />
 
 
 
 
 
 
 
 
 
 
 
39
 
40
+ <Suspense fallback={
41
+ <div className="flex h-[400px] w-full items-center justify-center">
42
+ <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
43
+ </div>
44
+ }>
45
+ <DataView datasets={datasets} stats={stats} />
46
+ </Suspense>
47
+ </div>
48
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  }
ui/app/explorer/chart.tsx ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client"
2
+
3
+ import { ResponsiveContainer, ScatterChart, Scatter, XAxis, YAxis, ZAxis, Tooltip, Cell } from "recharts"
4
+ import { Card, CardContent } from "@/components/ui/card"
5
+ import { AlertCircle } from "lucide-react"
6
+ import { DataPoint } from "@/types/explorer"
7
+
8
+ export function ExplorerChart({ data }: { data: DataPoint[] }) {
9
+ if (!data || data.length === 0) {
10
+ return (
11
+ <div className="flex h-full items-center justify-center text-muted-foreground">
12
+ <AlertCircle className="mr-2 h-4 w-4" />
13
+ No data available for this configuration.
14
+ </div>
15
+ )
16
+ }
17
+
18
+ return (
19
+ <Card className="h-[500px] overflow-hidden bg-gradient-to-br from-card to-secondary/30">
20
+ <CardContent className="p-4 h-full relative">
21
+ <ResponsiveContainer width="100%" height="100%">
22
+ <ScatterChart margin={{ top: 20, right: 20, bottom: 20, left: 20 }}>
23
+ <XAxis type="number" dataKey="x" name="PC1" stroke="currentColor" fontSize={12} tickLine={false} axisLine={{ strokeOpacity: 0.2 }} />
24
+ <YAxis type="number" dataKey="y" name="PC2" stroke="currentColor" fontSize={12} tickLine={false} axisLine={{ strokeOpacity: 0.2 }} />
25
+ <ZAxis type="number" dataKey="z" range={[50, 400]} />
26
+ <Tooltip
27
+ cursor={{ strokeDasharray: '3 3' }}
28
+ content={({ active, payload }) => {
29
+ if (active && payload && payload.length) {
30
+ const point = payload[0].payload as DataPoint;
31
+ return (
32
+ <div className="bg-popover border border-border p-3 rounded-lg shadow-xl text-sm z-50">
33
+ <p className="font-bold mb-1 text-primary">{point.name}</p>
34
+ <div className="grid grid-cols-2 gap-x-4 gap-y-1 text-xs text-muted-foreground">
35
+ <span>X:</span> <span className="text-foreground">{Number(point.x).toFixed(2)}</span>
36
+ <span>Y:</span> <span className="text-foreground">{Number(point.y).toFixed(2)}</span>
37
+ <span>Affinity:</span> <span className="text-foreground">{Number(point.affinity).toFixed(2)}</span>
38
+ </div>
39
+ </div>
40
+ )
41
+ }
42
+ return null;
43
+ }}
44
+ />
45
+ <Scatter name="Molecules" data={data} fill="#8884d8" animationDuration={1000}>
46
+ {data.map((entry, index) => (
47
+ <Cell key={`cell-${index}`} fill={entry.color} fillOpacity={0.7} className="hover:opacity-100 transition-opacity duration-200" />
48
+ ))}
49
+ </Scatter>
50
+ </ScatterChart>
51
+ </ResponsiveContainer>
52
+ </CardContent>
53
+ </Card>
54
+ )
55
+ }
ui/app/explorer/components.tsx ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { useRouter, useSearchParams } from "next/navigation"
5
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
6
+ import { Label } from "@/components/ui/label"
7
+ import { Button } from "@/components/ui/button"
8
+ import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"
9
+ import { RefreshCw, SlidersHorizontal } from "lucide-react"
10
+
11
+ export function ExplorerControls() {
12
+ const router = useRouter()
13
+ const searchParams = useSearchParams()
14
+ const [isPending, startTransition] = React.useTransition()
15
+
16
+ const dataset = searchParams.get("dataset") || "DrugBank"
17
+ const visualization = searchParams.get("view") || "UMAP"
18
+ const colorBy = searchParams.get("colorBy") || "Activity"
19
+
20
+ const createQueryString = React.useCallback(
21
+ (name: string, value: string) => {
22
+ const params = new URLSearchParams(searchParams.toString())
23
+ params.set(name, value)
24
+ return params.toString()
25
+ },
26
+ [searchParams]
27
+ )
28
+
29
+ const handleUpdate = (name: string, value: string) => {
30
+ startTransition(() => {
31
+ router.push(`?${createQueryString(name, value)}`, { scroll: false })
32
+ })
33
+ }
34
+
35
+ return (
36
+ <Card className="h-full border-l-4 border-l-primary/50">
37
+ <CardHeader>
38
+ <CardTitle className="flex items-center gap-2 text-lg">
39
+ <SlidersHorizontal className="h-5 w-5" />
40
+ Controls
41
+ </CardTitle>
42
+ </CardHeader>
43
+ <CardContent className="space-y-6">
44
+ <div className="space-y-2">
45
+ <Label htmlFor="dataset">Dataset</Label>
46
+ <Select value={dataset} onValueChange={(v) => handleUpdate("dataset", v)}>
47
+ <SelectTrigger id="dataset">
48
+ <SelectValue placeholder="Select dataset" />
49
+ </SelectTrigger>
50
+ <SelectContent>
51
+ <SelectItem value="DrugBank">DrugBank</SelectItem>
52
+ <SelectItem value="ChEMBL">ChEMBL</SelectItem>
53
+ <SelectItem value="ZINC">ZINC</SelectItem>
54
+ </SelectContent>
55
+ </Select>
56
+ </div>
57
+ <div className="space-y-2">
58
+ <Label htmlFor="visualization">Algorithm</Label>
59
+ <Select value={visualization} onValueChange={(v) => handleUpdate("view", v)}>
60
+ <SelectTrigger id="visualization">
61
+ <SelectValue placeholder="Select algorithm" />
62
+ </SelectTrigger>
63
+ <SelectContent>
64
+ <SelectItem value="UMAP">UMAP</SelectItem>
65
+ <SelectItem value="t-SNE">t-SNE</SelectItem>
66
+ <SelectItem value="PCA">PCA</SelectItem>
67
+ </SelectContent>
68
+ </Select>
69
+ </div>
70
+ <div className="space-y-2">
71
+ <Label htmlFor="colorBy">Color Mapping</Label>
72
+ <Select value={colorBy} onValueChange={(v) => handleUpdate("colorBy", v)}>
73
+ <SelectTrigger id="colorBy">
74
+ <SelectValue placeholder="Select color metric" />
75
+ </SelectTrigger>
76
+ <SelectContent>
77
+ <SelectItem value="Activity">Binding Affinity</SelectItem>
78
+ <SelectItem value="MW">Molecular Weight</SelectItem>
79
+ <SelectItem value="LogP">LogP</SelectItem>
80
+ <SelectItem value="Cluster">Cluster ID</SelectItem>
81
+ </SelectContent>
82
+ </Select>
83
+ </div>
84
+
85
+ <div className="pt-4">
86
+ <Button
87
+ variant="secondary"
88
+ className="w-full"
89
+ disabled={isPending}
90
+ onClick={() => handleUpdate("refresh", Date.now().toString())}
91
+ >
92
+ <RefreshCw className={`mr-2 h-4 w-4 ${isPending ? "animate-spin" : ""}`} />
93
+ {isPending ? "Updating..." : "Regenerate View"}
94
+ </Button>
95
+ </div>
96
+ </CardContent>
97
+ </Card>
98
+ )
99
+ }
ui/app/explorer/page.tsx CHANGED
@@ -1,213 +1,76 @@
1
- "use client"
 
 
 
 
 
2
 
3
- import * as React from "react"
4
- import { PageHeader, SectionHeader } from "@/components/page-header"
5
- import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"
6
- import { Button } from "@/components/ui/button"
7
- import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
8
- import { Label } from "@/components/ui/label"
9
- import { Dna, RefreshCw, Map as MapIcon, BarChart2, Activity, Zap, Grid3X3 } from "lucide-react"
10
- import { ResponsiveContainer, ScatterChart, Scatter, XAxis, YAxis, ZAxis, Tooltip, Cell } from "recharts"
11
-
12
- interface DataPoint {
13
- x: number;
14
- y: number;
15
- z: number;
16
- color: string;
17
- name: string;
18
- affinity: number;
19
  }
20
 
21
- export default function ExplorerPage() {
22
- const [dataset, setDataset] = React.useState("DrugBank")
23
- const [visualization, setVisualization] = React.useState("UMAP")
24
- const [colorBy, setColorBy] = React.useState("Activity")
25
- const [data, setData] = React.useState<DataPoint[]>([])
26
-
27
- // Sample Data Generation
28
- React.useEffect(() => {
29
- const points: DataPoint[] = []
30
- const clusters = [
31
- { cx: 2, cy: 3, color: "var(--color-chart-1)" },
32
- { cx: -2, cy: -1, color: "var(--color-chart-2)" },
33
- { cx: 4, cy: -2, color: "var(--color-chart-3)" },
34
- { cx: -1, cy: 4, color: "var(--color-chart-4)" }
35
- ]
36
-
37
- for (let i = 0; i < 200; i++) {
38
- const cluster = clusters[Math.floor(i / 50)]
39
- points.push({
40
- x: cluster.cx + (Math.random() - 0.5) * 2,
41
- y: cluster.cy + (Math.random() - 0.5) * 2,
42
- z: Math.random() * 100,
43
- color: cluster.color,
44
- name: `Mol_${i}`,
45
- affinity: Math.random() * 100
46
- })
47
  }
48
- setData(points)
49
- }, [dataset])
50
 
51
- return (
52
- <div className="space-y-8 animate-in fade-in duration-500">
53
- <PageHeader
54
- title="Data Explorer"
55
- subtitle="Visualize molecular embeddings and relationships"
56
- icon={<Dna className="h-8 w-8 text-primary" />}
57
- />
58
 
59
- <Card className="border-l-4 border-l-primary/50">
60
- <CardHeader>
61
- <CardTitle className="flex items-center gap-2">
62
- <Activity className="h-5 w-5" />
63
- Visualization Controls
64
- </CardTitle>
65
- <CardDescription>Adjust projection parameters and visual styles</CardDescription>
66
- </CardHeader>
67
- <CardContent className="grid grid-cols-1 md:grid-cols-4 gap-6">
68
- <div className="space-y-2">
69
- <Label htmlFor="dataset">Dataset</Label>
70
- <Select value={dataset} onValueChange={setDataset}>
71
- <SelectTrigger id="dataset">
72
- <SelectValue placeholder="Select dataset" />
73
- </SelectTrigger>
74
- <SelectContent>
75
- <SelectItem value="DrugBank">DrugBank</SelectItem>
76
- <SelectItem value="ChEMBL">ChEMBL</SelectItem>
77
- <SelectItem value="ZINC">ZINC</SelectItem>
78
- </SelectContent>
79
- </Select>
80
- </div>
81
- <div className="space-y-2">
82
- <Label htmlFor="visualization">Algorithm</Label>
83
- <Select value={visualization} onValueChange={setVisualization}>
84
- <SelectTrigger id="visualization">
85
- <SelectValue placeholder="Select algorithm" />
86
- </SelectTrigger>
87
- <SelectContent>
88
- <SelectItem value="UMAP">UMAP</SelectItem>
89
- <SelectItem value="t-SNE">t-SNE</SelectItem>
90
- <SelectItem value="PCA">PCA</SelectItem>
91
- </SelectContent>
92
- </Select>
93
- </div>
94
- <div className="space-y-2">
95
- <Label htmlFor="colorBy">Color Mapping</Label>
96
- <Select value={colorBy} onValueChange={setColorBy}>
97
- <SelectTrigger id="colorBy">
98
- <SelectValue placeholder="Select color metric" />
99
- </SelectTrigger>
100
- <SelectContent>
101
- <SelectItem value="Activity">Binding Affinity</SelectItem>
102
- <SelectItem value="MW">Molecular Weight</SelectItem>
103
- <SelectItem value="LogP">LogP</SelectItem>
104
- <SelectItem value="Cluster">Cluster ID</SelectItem>
105
- </SelectContent>
106
- </Select>
107
- </div>
108
- <div className="flex items-end">
109
- <Button variant="secondary" className="w-full" onClick={() => setDataset(d => d === "DrugBank" ? "ChEMBL" : "DrugBank")}>
110
- <RefreshCw className="mr-2 h-4 w-4" />
111
- Regenerate View
112
- </Button>
113
- </div>
114
- </CardContent>
115
- </Card>
116
 
117
- <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
118
- <div className="lg:col-span-2 space-y-4">
119
- <SectionHeader title="Embedding Space" icon={<MapIcon className="h-5 w-5 text-primary" />} />
120
- <Card className="h-[500px] overflow-hidden bg-gradient-to-br from-card to-secondary/30">
121
- <CardContent className="p-4 h-full">
122
- <ResponsiveContainer width="100%" height="100%">
123
- <ScatterChart margin={{ top: 20, right: 20, bottom: 20, left: 20 }}>
124
- <XAxis type="number" dataKey="x" name="PC1" stroke="currentColor" fontSize={12} tickLine={false} axisLine={{ strokeOpacity: 0.2 }} />
125
- <YAxis type="number" dataKey="y" name="PC2" stroke="currentColor" fontSize={12} tickLine={false} axisLine={{ strokeOpacity: 0.2 }} />
126
- <ZAxis type="number" dataKey="z" range={[50, 400]} />
127
- <Tooltip
128
- cursor={{ strokeDasharray: '3 3' }}
129
- content={({ active, payload }) => {
130
- if (active && payload && payload.length) {
131
- const data = payload[0].payload;
132
- return (
133
- <div className="bg-popover border border-border p-3 rounded-lg shadow-xl text-sm">
134
- <p className="font-bold mb-1 text-primary">{data.name}</p>
135
- <div className="grid grid-cols-2 gap-x-4 gap-y-1 text-xs text-muted-foreground">
136
- <span>X:</span> <span className="text-foreground">{Number(data.x).toFixed(2)}</span>
137
- <span>Y:</span> <span className="text-foreground">{Number(data.y).toFixed(2)}</span>
138
- <span>Affinity:</span> <span className="text-foreground">{Number(data.affinity).toFixed(2)}</span>
139
- </div>
140
- </div>
141
- )
142
- }
143
- return null;
144
- }}
145
- />
146
- <Scatter name="Molecules" data={data} fill="#8884d8">
147
- {data.map((entry, index) => (
148
- <Cell key={`cell-${index}`} fill={entry.color} fillOpacity={0.7} className="hover:opacity-100 transition-opacity duration-200" />
149
- ))}
150
- </Scatter>
151
- </ScatterChart>
152
- </ResponsiveContainer>
153
- </CardContent>
154
- </Card>
155
- </div>
156
 
157
- <div className="space-y-6">
158
- <SectionHeader title="Data Intelligence" icon={<Grid3X3 className="h-5 w-5 text-primary" />} />
159
-
160
- <div className="grid grid-cols-1 gap-4">
161
- <Card>
162
- <CardHeader className="pb-2">
163
- <CardTitle className="text-sm font-medium text-muted-foreground flex items-center justify-between">
164
- Active Molecules
165
- <Zap className="h-4 w-4 text-yellow-500" />
166
- </CardTitle>
167
- </CardHeader>
168
- <CardContent>
169
- <div className="text-2xl font-bold">12,450</div>
170
- <p className="text-xs text-muted-foreground mt-1">+2.5% from last month</p>
171
- </CardContent>
172
- </Card>
173
- <Card>
174
- <CardHeader className="pb-2">
175
- <CardTitle className="text-sm font-medium text-muted-foreground flex items-center justify-between">
176
- Clusters Identified
177
- <Grid3X3 className="h-4 w-4 text-blue-500" />
178
- </CardTitle>
179
- </CardHeader>
180
- <CardContent>
181
- <div className="text-2xl font-bold text-chart-2">4</div>
182
- <p className="text-xs text-muted-foreground mt-1">Distinct chemical series</p>
183
- </CardContent>
184
- </Card>
185
- <Card>
186
- <CardHeader className="pb-2">
187
- <CardTitle className="text-sm font-medium text-muted-foreground flex items-center justify-between">
188
- Avg Confidence
189
- <BarChart2 className="h-4 w-4 text-green-500" />
190
- </CardTitle>
191
- </CardHeader>
192
- <CardContent>
193
- <div className="text-2xl font-bold text-chart-3">0.89</div>
194
- <p className="text-xs text-muted-foreground mt-1">Across all predictions</p>
195
- </CardContent>
196
- </Card>
197
- </div>
198
-
199
- <div className="p-4 rounded-lg bg-secondary/50 border border-secondary">
200
- <h4 className="font-semibold mb-2 text-sm flex items-center gap-2">
201
- <Zap className="h-3 w-3 text-primary" />
202
- Quick Actions
203
- </h4>
204
- <div className="space-y-2">
205
- <Button variant="outline" size="sm" className="w-full justify-start text-xs">Exort Selection as CSV</Button>
206
- <Button variant="outline" size="sm" className="w-full justify-start text-xs">Run Clustering Analysis</Button>
207
- </div>
208
- </div>
209
- </div>
210
  </div>
 
211
  </div>
212
  )
213
  }
 
1
+ import { Suspense } from "react"
2
+ import { getApiUrl } from "@/lib/api-utils"
3
+ import { ExplorerControls } from "./components"
4
+ import { ExplorerChart } from "./chart"
5
+ import { Loader2 } from "lucide-react"
6
+ import { ExplorerResponse } from "@/types/explorer"
7
 
8
+ interface ExplorerPageProps {
9
+ searchParams?: { [key: string]: string | string[] | undefined }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  }
11
 
12
+ async function getExplorerData(dataset: string, view: string) {
13
+ try {
14
+ const apiUrl = getApiUrl()
15
+ const baseUrl = apiUrl || "http://localhost:3000"
16
+
17
+ const res = await fetch(
18
+ `${baseUrl}/api/explorer?dataset=${encodeURIComponent(dataset)}&view=${encodeURIComponent(view)}`,
19
+ { cache: "no-store" }
20
+ )
21
+
22
+ if (!res.ok) {
23
+ console.error(`Failed to fetch data: ${res.status} ${res.statusText}`)
24
+ return []
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  }
 
 
26
 
27
+ const json = (await res.json()) as ExplorerResponse
28
+ return json.points || []
29
+ } catch (error) {
30
+ console.error("Error fetching explorer data:", error)
31
+ return []
32
+ }
33
+ }
34
 
35
+ function pickParam(v: string | string[] | undefined) {
36
+ return Array.isArray(v) ? v[0] : v
37
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
+ export default async function ExplorerPage({ searchParams }: ExplorerPageProps) {
40
+ const dataset = pickParam(searchParams?.dataset) || "DAVIS"
41
+ const view = pickParam(searchParams?.view) || "PCA"
42
+
43
+ const data = await getExplorerData(dataset, view)
44
+
45
+ return (
46
+ <div className="container mx-auto p-6 space-y-6">
47
+ <div className="flex flex-col space-y-2">
48
+ <h1 className="text-3xl font-bold tracking-tight">Data Explorer</h1>
49
+ <p className="text-muted-foreground">
50
+ Visualize binding affinity landscapes and model predictions in 3D space using dimensionality reduction.
51
+ </p>
52
+ </div>
53
+
54
+ <div className="grid grid-cols-1 lg:grid-cols-4 gap-6">
55
+ <div className="lg:col-span-1">
56
+ <Suspense fallback={<div>Loading controls...</div>}>
57
+ <ExplorerControls />
58
+ </Suspense>
59
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
+ <div className="lg:col-span-3">
62
+ <Suspense
63
+ key={`${dataset}-${view}`}
64
+ fallback={
65
+ <div className="h-[500px] flex items-center justify-center border rounded-lg bg-muted/10">
66
+ <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
67
+ </div>
68
+ }
69
+ >
70
+ <ExplorerChart data={data} />
71
+ </Suspense>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  </div>
73
+ </div>
74
  </div>
75
  )
76
  }
ui/components.json CHANGED
@@ -18,5 +18,7 @@
18
  "lib": "@/lib",
19
  "hooks": "@/hooks"
20
  },
21
- "registries": {}
 
 
22
  }
 
18
  "lib": "@/lib",
19
  "hooks": "@/hooks"
20
  },
21
+ "registries": {
22
+ "@animate-ui": "https://animate-ui.com/r/{name}.json"
23
+ }
24
  }
ui/components/ui/skeleton.tsx ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { cn } from "@/lib/utils"
2
+
3
+ function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
4
+ return (
5
+ <div
6
+ data-slot="skeleton"
7
+ className={cn("bg-accent animate-pulse rounded-md", className)}
8
+ {...props}
9
+ />
10
+ )
11
+ }
12
+
13
+ export { Skeleton }
ui/hooks/use-controlled-state.tsx ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from 'react';
2
+
3
+ interface CommonControlledStateProps<T> {
4
+ value?: T;
5
+ defaultValue?: T;
6
+ }
7
+
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ export function useControlledState<T, Rest extends any[] = []>(
10
+ props: CommonControlledStateProps<T> & {
11
+ onChange?: (value: T, ...args: Rest) => void;
12
+ },
13
+ ): readonly [T, (next: T, ...args: Rest) => void] {
14
+ const { value, defaultValue, onChange } = props;
15
+
16
+ const [state, setInternalState] = React.useState<T>(
17
+ value !== undefined ? value : (defaultValue as T),
18
+ );
19
+
20
+ React.useEffect(() => {
21
+ if (value !== undefined) setInternalState(value);
22
+ }, [value]);
23
+
24
+ const setState = React.useCallback(
25
+ (next: T, ...args: Rest) => {
26
+ setInternalState(next);
27
+ onChange?.(next, ...args);
28
+ },
29
+ [onChange],
30
+ );
31
+
32
+ return [state, setState] as const;
33
+ }
ui/hooks/use-mobile.ts ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+
3
+ const MOBILE_BREAKPOINT = 768
4
+
5
+ export function useIsMobile() {
6
+ const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
7
+
8
+ React.useEffect(() => {
9
+ const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
10
+ const onChange = () => {
11
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
12
+ }
13
+ mql.addEventListener("change", onChange)
14
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
15
+ return () => mql.removeEventListener("change", onChange)
16
+ }, [])
17
+
18
+ return !!isMobile
19
+ }
ui/lib/api-utils.ts ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ export function getApiUrl() {
2
+ if (typeof window !== "undefined") return ""; // browser should use relative url
3
+ if (process.env.BACKEND_URL) return `https://${process.env.BACKEND_URL}`; // SSR should use vercel url
4
+ return `http://localhost:${process.env.PORT ?? 3000}`; // dev SSR should use localhost
5
+ }
ui/lib/get-strict-context.tsx ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from 'react';
2
+
3
+ function getStrictContext<T>(
4
+ name?: string,
5
+ ): readonly [
6
+ ({
7
+ value,
8
+ children,
9
+ }: {
10
+ value: T;
11
+ children?: React.ReactNode;
12
+ }) => React.JSX.Element,
13
+ () => T,
14
+ ] {
15
+ const Context = React.createContext<T | undefined>(undefined);
16
+
17
+ const Provider = ({
18
+ value,
19
+ children,
20
+ }: {
21
+ value: T;
22
+ children?: React.ReactNode;
23
+ }) => <Context.Provider value={value}>{children}</Context.Provider>;
24
+
25
+ const useSafeContext = () => {
26
+ const ctx = React.useContext(Context);
27
+ if (ctx === undefined) {
28
+ throw new Error(`useContext must be used within ${name ?? 'a Provider'}`);
29
+ }
30
+ return ctx;
31
+ };
32
+
33
+ return [Provider, useSafeContext] as const;
34
+ }
35
+
36
+ export { getStrictContext };
ui/next.config.ts CHANGED
@@ -1,7 +1,38 @@
1
  import type { NextConfig } from "next";
2
 
3
  const nextConfig: NextConfig = {
4
- /* config options here */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  };
6
 
7
  export default nextConfig;
 
1
  import type { NextConfig } from "next";
2
 
3
  const nextConfig: NextConfig = {
4
+ reactStrictMode: true,
5
+ poweredByHeader: false,
6
+ productionBrowserSourceMaps: false,
7
+ compress: true,
8
+ output: "standalone",
9
+ cacheComponents: true,
10
+ turbopack: {},
11
+ experimental: {
12
+ turbopackFileSystemCacheForDev: true,
13
+ turbopackFileSystemCacheForBuild: false,
14
+ },
15
+ images: {
16
+ formats: ["image/avif", "image/webp"],
17
+ remotePatterns: [],
18
+ dangerouslyAllowSVG: false,
19
+ },
20
+ async headers() {
21
+ return [
22
+ {
23
+ source: "/:path*",
24
+ headers: [
25
+ { key: "Strict-Transport-Security", value: "max-age=63072000; includeSubDomains; preload" },
26
+ { key: "X-Frame-Options", value: "DENY" },
27
+ { key: "X-Content-Type-Options", value: "nosniff" },
28
+ { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
29
+ { key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" },
30
+ { key: "Cross-Origin-Opener-Policy", value: "same-origin" },
31
+ { key: "Cross-Origin-Resource-Policy", value: "same-origin" },
32
+ ],
33
+ },
34
+ ];
35
+ },
36
  };
37
 
38
  export default nextConfig;
ui/package.json CHANGED
@@ -21,11 +21,14 @@
21
  "clsx": "^2.1.1",
22
  "framer-motion": "^12.29.2",
23
  "lucide-react": "^0.563.0",
 
24
  "next": "^16.1.4",
 
25
  "react": "^19.2.3",
26
  "react-dom": "^19.2.3",
27
  "recharts": "^3.7.0",
28
- "tailwind-merge": "^3.4.0"
 
29
  },
30
  "devDependencies": {
31
  "@tailwindcss/postcss": "^4.1.18",
 
21
  "clsx": "^2.1.1",
22
  "framer-motion": "^12.29.2",
23
  "lucide-react": "^0.563.0",
24
+ "motion": "^12.29.2",
25
  "next": "^16.1.4",
26
+ "radix-ui": "^1.4.3",
27
  "react": "^19.2.3",
28
  "react-dom": "^19.2.3",
29
  "recharts": "^3.7.0",
30
+ "tailwind-merge": "^3.4.0",
31
+ "zod": "^4.3.6"
32
  },
33
  "devDependencies": {
34
  "@tailwindcss/postcss": "^4.1.18",
ui/pnpm-lock.yaml CHANGED
@@ -41,9 +41,15 @@ importers:
41
  lucide-react:
42
  specifier: ^0.563.0
43
  version: 0.563.0(react@19.2.3)
 
 
 
44
  next:
45
  specifier: ^16.1.4
46
  version: 16.1.4(@babel/core@7.28.6)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
 
 
 
47
  react:
48
  specifier: ^19.2.3
49
  version: 19.2.3
@@ -56,6 +62,9 @@ importers:
56
  tailwind-merge:
57
  specifier: ^3.4.0
58
  version: 3.4.0
 
 
 
59
  devDependencies:
60
  '@tailwindcss/postcss':
61
  specifier: ^4.1.18
@@ -631,6 +640,45 @@ packages:
631
  '@radix-ui/primitive@1.1.3':
632
  resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==}
633
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
634
  '@radix-ui/react-arrow@1.1.7':
635
  resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==}
636
  peerDependencies:
@@ -644,6 +692,58 @@ packages:
644
  '@types/react-dom':
645
  optional: true
646
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
647
  '@radix-ui/react-collection@1.1.7':
648
  resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==}
649
  peerDependencies:
@@ -666,6 +766,19 @@ packages:
666
  '@types/react':
667
  optional: true
668
 
 
 
 
 
 
 
 
 
 
 
 
 
 
669
  '@radix-ui/react-context@1.1.2':
670
  resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==}
671
  peerDependencies:
@@ -675,6 +788,19 @@ packages:
675
  '@types/react':
676
  optional: true
677
 
 
 
 
 
 
 
 
 
 
 
 
 
 
678
  '@radix-ui/react-direction@1.1.1':
679
  resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==}
680
  peerDependencies:
@@ -697,6 +823,19 @@ packages:
697
  '@types/react-dom':
698
  optional: true
699
 
 
 
 
 
 
 
 
 
 
 
 
 
 
700
  '@radix-ui/react-focus-guards@1.1.3':
701
  resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==}
702
  peerDependencies:
@@ -719,6 +858,32 @@ packages:
719
  '@types/react-dom':
720
  optional: true
721
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
722
  '@radix-ui/react-id@1.1.1':
723
  resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==}
724
  peerDependencies:
@@ -728,6 +893,19 @@ packages:
728
  '@types/react':
729
  optional: true
730
 
 
 
 
 
 
 
 
 
 
 
 
 
 
731
  '@radix-ui/react-label@2.1.8':
732
  resolution: {integrity: sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==}
733
  peerDependencies:
@@ -741,6 +919,84 @@ packages:
741
  '@types/react-dom':
742
  optional: true
743
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
744
  '@radix-ui/react-popper@1.2.8':
745
  resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==}
746
  peerDependencies:
@@ -806,6 +1062,32 @@ packages:
806
  '@types/react-dom':
807
  optional: true
808
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
809
  '@radix-ui/react-roving-focus@1.1.11':
810
  resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==}
811
  peerDependencies:
@@ -819,6 +1101,19 @@ packages:
819
  '@types/react-dom':
820
  optional: true
821
 
 
 
 
 
 
 
 
 
 
 
 
 
 
822
  '@radix-ui/react-select@2.2.6':
823
  resolution: {integrity: sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==}
824
  peerDependencies:
@@ -832,6 +1127,19 @@ packages:
832
  '@types/react-dom':
833
  optional: true
834
 
 
 
 
 
 
 
 
 
 
 
 
 
 
835
  '@radix-ui/react-separator@1.1.8':
836
  resolution: {integrity: sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g==}
837
  peerDependencies:
@@ -845,8 +1153,65 @@ packages:
845
  '@types/react-dom':
846
  optional: true
847
 
848
- '@radix-ui/react-slider@1.3.6':
849
- resolution: {integrity: sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
850
  peerDependencies:
851
  '@types/react': '*'
852
  '@types/react-dom': '*'
@@ -858,26 +1223,34 @@ packages:
858
  '@types/react-dom':
859
  optional: true
860
 
861
- '@radix-ui/react-slot@1.2.3':
862
- resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==}
863
  peerDependencies:
864
  '@types/react': '*'
 
865
  react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
 
866
  peerDependenciesMeta:
867
  '@types/react':
868
  optional: true
 
 
869
 
870
- '@radix-ui/react-slot@1.2.4':
871
- resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==}
872
  peerDependencies:
873
  '@types/react': '*'
 
874
  react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
 
875
  peerDependenciesMeta:
876
  '@types/react':
877
  optional: true
 
 
878
 
879
- '@radix-ui/react-switch@1.2.6':
880
- resolution: {integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==}
881
  peerDependencies:
882
  '@types/react': '*'
883
  '@types/react-dom': '*'
@@ -889,8 +1262,8 @@ packages:
889
  '@types/react-dom':
890
  optional: true
891
 
892
- '@radix-ui/react-tabs@1.1.13':
893
- resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==}
894
  peerDependencies:
895
  '@types/react': '*'
896
  '@types/react-dom': '*'
@@ -938,6 +1311,15 @@ packages:
938
  '@types/react':
939
  optional: true
940
 
 
 
 
 
 
 
 
 
 
941
  '@radix-ui/react-use-layout-effect@1.1.1':
942
  resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==}
943
  peerDependencies:
@@ -2674,6 +3056,20 @@ packages:
2674
  motion-utils@12.29.2:
2675
  resolution: {integrity: sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A==}
2676
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2677
  ms@2.1.3:
2678
  resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
2679
 
@@ -2935,6 +3331,19 @@ packages:
2935
  queue-microtask@1.2.3:
2936
  resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
2937
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2938
  range-parser@1.2.1:
2939
  resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
2940
  engines: {node: '>= 0.6'}
@@ -4104,6 +4513,46 @@ snapshots:
4104
 
4105
  '@radix-ui/primitive@1.1.3': {}
4106
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4107
  '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4108
  dependencies:
4109
  '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -4113,6 +4562,60 @@ snapshots:
4113
  '@types/react': 19.2.9
4114
  '@types/react-dom': 19.2.3(@types/react@19.2.9)
4115
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4116
  '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4117
  dependencies:
4118
  '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
@@ -4131,60 +4634,276 @@ snapshots:
4131
  optionalDependencies:
4132
  '@types/react': 19.2.9
4133
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4134
  '@radix-ui/react-context@1.1.2(@types/react@19.2.9)(react@19.2.3)':
4135
  dependencies:
4136
  react: 19.2.3
4137
  optionalDependencies:
4138
  '@types/react': 19.2.9
4139
 
4140
- '@radix-ui/react-direction@1.1.1(@types/react@19.2.9)(react@19.2.3)':
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4141
  dependencies:
 
4142
  react: 19.2.3
 
4143
  optionalDependencies:
4144
  '@types/react': 19.2.9
 
4145
 
4146
- '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4147
  dependencies:
4148
  '@radix-ui/primitive': 1.1.3
 
4149
  '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
 
 
 
 
 
 
 
 
 
4150
  '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
 
 
4151
  '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4152
- '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4153
  react: 19.2.3
4154
  react-dom: 19.2.3(react@19.2.3)
 
4155
  optionalDependencies:
4156
  '@types/react': 19.2.9
4157
  '@types/react-dom': 19.2.3(@types/react@19.2.9)
4158
 
4159
- '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.9)(react@19.2.3)':
4160
  dependencies:
 
 
 
 
 
 
 
 
 
 
4161
  react: 19.2.3
 
4162
  optionalDependencies:
4163
  '@types/react': 19.2.9
 
4164
 
4165
- '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4166
  dependencies:
 
 
4167
  '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
 
 
 
 
 
4168
  '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4169
  '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.9)(react@19.2.3)
 
 
 
 
4170
  react: 19.2.3
4171
  react-dom: 19.2.3(react@19.2.3)
4172
  optionalDependencies:
4173
  '@types/react': 19.2.9
4174
  '@types/react-dom': 19.2.3(@types/react@19.2.9)
4175
 
4176
- '@radix-ui/react-id@1.1.1(@types/react@19.2.9)(react@19.2.3)':
4177
  dependencies:
 
 
 
 
 
 
 
 
 
 
 
4178
  '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4179
  react: 19.2.3
 
4180
  optionalDependencies:
4181
  '@types/react': 19.2.9
 
4182
 
4183
- '@radix-ui/react-label@2.1.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4184
  dependencies:
4185
- '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4186
  react: 19.2.3
4187
  react-dom: 19.2.3(react@19.2.3)
 
4188
  optionalDependencies:
4189
  '@types/react': 19.2.9
4190
  '@types/react-dom': 19.2.3(@types/react@19.2.9)
@@ -4245,6 +4964,34 @@ snapshots:
4245
  '@types/react': 19.2.9
4246
  '@types/react-dom': 19.2.3(@types/react@19.2.9)
4247
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4248
  '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4249
  dependencies:
4250
  '@radix-ui/primitive': 1.1.3
@@ -4262,6 +5009,23 @@ snapshots:
4262
  '@types/react': 19.2.9
4263
  '@types/react-dom': 19.2.3(@types/react@19.2.9)
4264
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4265
  '@radix-ui/react-select@2.2.6(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4266
  dependencies:
4267
  '@radix-ui/number': 1.1.1
@@ -4291,6 +5055,15 @@ snapshots:
4291
  '@types/react': 19.2.9
4292
  '@types/react-dom': 19.2.3(@types/react@19.2.9)
4293
 
 
 
 
 
 
 
 
 
 
4294
  '@radix-ui/react-separator@1.1.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4295
  dependencies:
4296
  '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -4364,6 +5137,87 @@ snapshots:
4364
  '@types/react': 19.2.9
4365
  '@types/react-dom': 19.2.3(@types/react@19.2.9)
4366
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4367
  '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.9)(react@19.2.3)':
4368
  dependencies:
4369
  react: 19.2.3
@@ -4392,6 +5246,13 @@ snapshots:
4392
  optionalDependencies:
4393
  '@types/react': 19.2.9
4394
 
 
 
 
 
 
 
 
4395
  '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.9)(react@19.2.3)':
4396
  dependencies:
4397
  react: 19.2.3
@@ -6161,6 +7022,14 @@ snapshots:
6161
 
6162
  motion-utils@12.29.2: {}
6163
 
 
 
 
 
 
 
 
 
6164
  ms@2.1.3: {}
6165
 
6166
  msw@2.12.7(@types/node@25.0.10)(typescript@5.9.3):
@@ -6437,6 +7306,69 @@ snapshots:
6437
 
6438
  queue-microtask@1.2.3: {}
6439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6440
  range-parser@1.2.1: {}
6441
 
6442
  raw-body@3.0.2:
 
41
  lucide-react:
42
  specifier: ^0.563.0
43
  version: 0.563.0(react@19.2.3)
44
+ motion:
45
+ specifier: ^12.29.2
46
+ version: 12.29.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
47
  next:
48
  specifier: ^16.1.4
49
  version: 16.1.4(@babel/core@7.28.6)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
50
+ radix-ui:
51
+ specifier: ^1.4.3
52
+ version: 1.4.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
53
  react:
54
  specifier: ^19.2.3
55
  version: 19.2.3
 
62
  tailwind-merge:
63
  specifier: ^3.4.0
64
  version: 3.4.0
65
+ zod:
66
+ specifier: ^4.3.6
67
+ version: 4.3.6
68
  devDependencies:
69
  '@tailwindcss/postcss':
70
  specifier: ^4.1.18
 
640
  '@radix-ui/primitive@1.1.3':
641
  resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==}
642
 
643
+ '@radix-ui/react-accessible-icon@1.1.7':
644
+ resolution: {integrity: sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A==}
645
+ peerDependencies:
646
+ '@types/react': '*'
647
+ '@types/react-dom': '*'
648
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
649
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
650
+ peerDependenciesMeta:
651
+ '@types/react':
652
+ optional: true
653
+ '@types/react-dom':
654
+ optional: true
655
+
656
+ '@radix-ui/react-accordion@1.2.12':
657
+ resolution: {integrity: sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==}
658
+ peerDependencies:
659
+ '@types/react': '*'
660
+ '@types/react-dom': '*'
661
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
662
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
663
+ peerDependenciesMeta:
664
+ '@types/react':
665
+ optional: true
666
+ '@types/react-dom':
667
+ optional: true
668
+
669
+ '@radix-ui/react-alert-dialog@1.1.15':
670
+ resolution: {integrity: sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==}
671
+ peerDependencies:
672
+ '@types/react': '*'
673
+ '@types/react-dom': '*'
674
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
675
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
676
+ peerDependenciesMeta:
677
+ '@types/react':
678
+ optional: true
679
+ '@types/react-dom':
680
+ optional: true
681
+
682
  '@radix-ui/react-arrow@1.1.7':
683
  resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==}
684
  peerDependencies:
 
692
  '@types/react-dom':
693
  optional: true
694
 
695
+ '@radix-ui/react-aspect-ratio@1.1.7':
696
+ resolution: {integrity: sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==}
697
+ peerDependencies:
698
+ '@types/react': '*'
699
+ '@types/react-dom': '*'
700
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
701
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
702
+ peerDependenciesMeta:
703
+ '@types/react':
704
+ optional: true
705
+ '@types/react-dom':
706
+ optional: true
707
+
708
+ '@radix-ui/react-avatar@1.1.10':
709
+ resolution: {integrity: sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==}
710
+ peerDependencies:
711
+ '@types/react': '*'
712
+ '@types/react-dom': '*'
713
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
714
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
715
+ peerDependenciesMeta:
716
+ '@types/react':
717
+ optional: true
718
+ '@types/react-dom':
719
+ optional: true
720
+
721
+ '@radix-ui/react-checkbox@1.3.3':
722
+ resolution: {integrity: sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==}
723
+ peerDependencies:
724
+ '@types/react': '*'
725
+ '@types/react-dom': '*'
726
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
727
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
728
+ peerDependenciesMeta:
729
+ '@types/react':
730
+ optional: true
731
+ '@types/react-dom':
732
+ optional: true
733
+
734
+ '@radix-ui/react-collapsible@1.1.12':
735
+ resolution: {integrity: sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==}
736
+ peerDependencies:
737
+ '@types/react': '*'
738
+ '@types/react-dom': '*'
739
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
740
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
741
+ peerDependenciesMeta:
742
+ '@types/react':
743
+ optional: true
744
+ '@types/react-dom':
745
+ optional: true
746
+
747
  '@radix-ui/react-collection@1.1.7':
748
  resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==}
749
  peerDependencies:
 
766
  '@types/react':
767
  optional: true
768
 
769
+ '@radix-ui/react-context-menu@2.2.16':
770
+ resolution: {integrity: sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww==}
771
+ peerDependencies:
772
+ '@types/react': '*'
773
+ '@types/react-dom': '*'
774
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
775
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
776
+ peerDependenciesMeta:
777
+ '@types/react':
778
+ optional: true
779
+ '@types/react-dom':
780
+ optional: true
781
+
782
  '@radix-ui/react-context@1.1.2':
783
  resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==}
784
  peerDependencies:
 
788
  '@types/react':
789
  optional: true
790
 
791
+ '@radix-ui/react-dialog@1.1.15':
792
+ resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==}
793
+ peerDependencies:
794
+ '@types/react': '*'
795
+ '@types/react-dom': '*'
796
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
797
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
798
+ peerDependenciesMeta:
799
+ '@types/react':
800
+ optional: true
801
+ '@types/react-dom':
802
+ optional: true
803
+
804
  '@radix-ui/react-direction@1.1.1':
805
  resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==}
806
  peerDependencies:
 
823
  '@types/react-dom':
824
  optional: true
825
 
826
+ '@radix-ui/react-dropdown-menu@2.1.16':
827
+ resolution: {integrity: sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==}
828
+ peerDependencies:
829
+ '@types/react': '*'
830
+ '@types/react-dom': '*'
831
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
832
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
833
+ peerDependenciesMeta:
834
+ '@types/react':
835
+ optional: true
836
+ '@types/react-dom':
837
+ optional: true
838
+
839
  '@radix-ui/react-focus-guards@1.1.3':
840
  resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==}
841
  peerDependencies:
 
858
  '@types/react-dom':
859
  optional: true
860
 
861
+ '@radix-ui/react-form@0.1.8':
862
+ resolution: {integrity: sha512-QM70k4Zwjttifr5a4sZFts9fn8FzHYvQ5PiB19O2HsYibaHSVt9fH9rzB0XZo/YcM+b7t/p7lYCT/F5eOeF5yQ==}
863
+ peerDependencies:
864
+ '@types/react': '*'
865
+ '@types/react-dom': '*'
866
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
867
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
868
+ peerDependenciesMeta:
869
+ '@types/react':
870
+ optional: true
871
+ '@types/react-dom':
872
+ optional: true
873
+
874
+ '@radix-ui/react-hover-card@1.1.15':
875
+ resolution: {integrity: sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==}
876
+ peerDependencies:
877
+ '@types/react': '*'
878
+ '@types/react-dom': '*'
879
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
880
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
881
+ peerDependenciesMeta:
882
+ '@types/react':
883
+ optional: true
884
+ '@types/react-dom':
885
+ optional: true
886
+
887
  '@radix-ui/react-id@1.1.1':
888
  resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==}
889
  peerDependencies:
 
893
  '@types/react':
894
  optional: true
895
 
896
+ '@radix-ui/react-label@2.1.7':
897
+ resolution: {integrity: sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==}
898
+ peerDependencies:
899
+ '@types/react': '*'
900
+ '@types/react-dom': '*'
901
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
902
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
903
+ peerDependenciesMeta:
904
+ '@types/react':
905
+ optional: true
906
+ '@types/react-dom':
907
+ optional: true
908
+
909
  '@radix-ui/react-label@2.1.8':
910
  resolution: {integrity: sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==}
911
  peerDependencies:
 
919
  '@types/react-dom':
920
  optional: true
921
 
922
+ '@radix-ui/react-menu@2.1.16':
923
+ resolution: {integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==}
924
+ peerDependencies:
925
+ '@types/react': '*'
926
+ '@types/react-dom': '*'
927
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
928
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
929
+ peerDependenciesMeta:
930
+ '@types/react':
931
+ optional: true
932
+ '@types/react-dom':
933
+ optional: true
934
+
935
+ '@radix-ui/react-menubar@1.1.16':
936
+ resolution: {integrity: sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA==}
937
+ peerDependencies:
938
+ '@types/react': '*'
939
+ '@types/react-dom': '*'
940
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
941
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
942
+ peerDependenciesMeta:
943
+ '@types/react':
944
+ optional: true
945
+ '@types/react-dom':
946
+ optional: true
947
+
948
+ '@radix-ui/react-navigation-menu@1.2.14':
949
+ resolution: {integrity: sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==}
950
+ peerDependencies:
951
+ '@types/react': '*'
952
+ '@types/react-dom': '*'
953
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
954
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
955
+ peerDependenciesMeta:
956
+ '@types/react':
957
+ optional: true
958
+ '@types/react-dom':
959
+ optional: true
960
+
961
+ '@radix-ui/react-one-time-password-field@0.1.8':
962
+ resolution: {integrity: sha512-ycS4rbwURavDPVjCb5iS3aG4lURFDILi6sKI/WITUMZ13gMmn/xGjpLoqBAalhJaDk8I3UbCM5GzKHrnzwHbvg==}
963
+ peerDependencies:
964
+ '@types/react': '*'
965
+ '@types/react-dom': '*'
966
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
967
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
968
+ peerDependenciesMeta:
969
+ '@types/react':
970
+ optional: true
971
+ '@types/react-dom':
972
+ optional: true
973
+
974
+ '@radix-ui/react-password-toggle-field@0.1.3':
975
+ resolution: {integrity: sha512-/UuCrDBWravcaMix4TdT+qlNdVwOM1Nck9kWx/vafXsdfj1ChfhOdfi3cy9SGBpWgTXwYCuboT/oYpJy3clqfw==}
976
+ peerDependencies:
977
+ '@types/react': '*'
978
+ '@types/react-dom': '*'
979
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
980
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
981
+ peerDependenciesMeta:
982
+ '@types/react':
983
+ optional: true
984
+ '@types/react-dom':
985
+ optional: true
986
+
987
+ '@radix-ui/react-popover@1.1.15':
988
+ resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==}
989
+ peerDependencies:
990
+ '@types/react': '*'
991
+ '@types/react-dom': '*'
992
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
993
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
994
+ peerDependenciesMeta:
995
+ '@types/react':
996
+ optional: true
997
+ '@types/react-dom':
998
+ optional: true
999
+
1000
  '@radix-ui/react-popper@1.2.8':
1001
  resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==}
1002
  peerDependencies:
 
1062
  '@types/react-dom':
1063
  optional: true
1064
 
1065
+ '@radix-ui/react-progress@1.1.7':
1066
+ resolution: {integrity: sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==}
1067
+ peerDependencies:
1068
+ '@types/react': '*'
1069
+ '@types/react-dom': '*'
1070
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1071
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1072
+ peerDependenciesMeta:
1073
+ '@types/react':
1074
+ optional: true
1075
+ '@types/react-dom':
1076
+ optional: true
1077
+
1078
+ '@radix-ui/react-radio-group@1.3.8':
1079
+ resolution: {integrity: sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==}
1080
+ peerDependencies:
1081
+ '@types/react': '*'
1082
+ '@types/react-dom': '*'
1083
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1084
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1085
+ peerDependenciesMeta:
1086
+ '@types/react':
1087
+ optional: true
1088
+ '@types/react-dom':
1089
+ optional: true
1090
+
1091
  '@radix-ui/react-roving-focus@1.1.11':
1092
  resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==}
1093
  peerDependencies:
 
1101
  '@types/react-dom':
1102
  optional: true
1103
 
1104
+ '@radix-ui/react-scroll-area@1.2.10':
1105
+ resolution: {integrity: sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==}
1106
+ peerDependencies:
1107
+ '@types/react': '*'
1108
+ '@types/react-dom': '*'
1109
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1110
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1111
+ peerDependenciesMeta:
1112
+ '@types/react':
1113
+ optional: true
1114
+ '@types/react-dom':
1115
+ optional: true
1116
+
1117
  '@radix-ui/react-select@2.2.6':
1118
  resolution: {integrity: sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==}
1119
  peerDependencies:
 
1127
  '@types/react-dom':
1128
  optional: true
1129
 
1130
+ '@radix-ui/react-separator@1.1.7':
1131
+ resolution: {integrity: sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==}
1132
+ peerDependencies:
1133
+ '@types/react': '*'
1134
+ '@types/react-dom': '*'
1135
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1136
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1137
+ peerDependenciesMeta:
1138
+ '@types/react':
1139
+ optional: true
1140
+ '@types/react-dom':
1141
+ optional: true
1142
+
1143
  '@radix-ui/react-separator@1.1.8':
1144
  resolution: {integrity: sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g==}
1145
  peerDependencies:
 
1153
  '@types/react-dom':
1154
  optional: true
1155
 
1156
+ '@radix-ui/react-slider@1.3.6':
1157
+ resolution: {integrity: sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==}
1158
+ peerDependencies:
1159
+ '@types/react': '*'
1160
+ '@types/react-dom': '*'
1161
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1162
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1163
+ peerDependenciesMeta:
1164
+ '@types/react':
1165
+ optional: true
1166
+ '@types/react-dom':
1167
+ optional: true
1168
+
1169
+ '@radix-ui/react-slot@1.2.3':
1170
+ resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==}
1171
+ peerDependencies:
1172
+ '@types/react': '*'
1173
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1174
+ peerDependenciesMeta:
1175
+ '@types/react':
1176
+ optional: true
1177
+
1178
+ '@radix-ui/react-slot@1.2.4':
1179
+ resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==}
1180
+ peerDependencies:
1181
+ '@types/react': '*'
1182
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1183
+ peerDependenciesMeta:
1184
+ '@types/react':
1185
+ optional: true
1186
+
1187
+ '@radix-ui/react-switch@1.2.6':
1188
+ resolution: {integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==}
1189
+ peerDependencies:
1190
+ '@types/react': '*'
1191
+ '@types/react-dom': '*'
1192
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1193
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1194
+ peerDependenciesMeta:
1195
+ '@types/react':
1196
+ optional: true
1197
+ '@types/react-dom':
1198
+ optional: true
1199
+
1200
+ '@radix-ui/react-tabs@1.1.13':
1201
+ resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==}
1202
+ peerDependencies:
1203
+ '@types/react': '*'
1204
+ '@types/react-dom': '*'
1205
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1206
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1207
+ peerDependenciesMeta:
1208
+ '@types/react':
1209
+ optional: true
1210
+ '@types/react-dom':
1211
+ optional: true
1212
+
1213
+ '@radix-ui/react-toast@1.2.15':
1214
+ resolution: {integrity: sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==}
1215
  peerDependencies:
1216
  '@types/react': '*'
1217
  '@types/react-dom': '*'
 
1223
  '@types/react-dom':
1224
  optional: true
1225
 
1226
+ '@radix-ui/react-toggle-group@1.1.11':
1227
+ resolution: {integrity: sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==}
1228
  peerDependencies:
1229
  '@types/react': '*'
1230
+ '@types/react-dom': '*'
1231
  react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1232
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1233
  peerDependenciesMeta:
1234
  '@types/react':
1235
  optional: true
1236
+ '@types/react-dom':
1237
+ optional: true
1238
 
1239
+ '@radix-ui/react-toggle@1.1.10':
1240
+ resolution: {integrity: sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==}
1241
  peerDependencies:
1242
  '@types/react': '*'
1243
+ '@types/react-dom': '*'
1244
  react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1245
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1246
  peerDependenciesMeta:
1247
  '@types/react':
1248
  optional: true
1249
+ '@types/react-dom':
1250
+ optional: true
1251
 
1252
+ '@radix-ui/react-toolbar@1.1.11':
1253
+ resolution: {integrity: sha512-4ol06/1bLoFu1nwUqzdD4Y5RZ9oDdKeiHIsntug54Hcr1pgaHiPqHFEaXI1IFP/EsOfROQZ8Mig9VTIRza6Tjg==}
1254
  peerDependencies:
1255
  '@types/react': '*'
1256
  '@types/react-dom': '*'
 
1262
  '@types/react-dom':
1263
  optional: true
1264
 
1265
+ '@radix-ui/react-tooltip@1.2.8':
1266
+ resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==}
1267
  peerDependencies:
1268
  '@types/react': '*'
1269
  '@types/react-dom': '*'
 
1311
  '@types/react':
1312
  optional: true
1313
 
1314
+ '@radix-ui/react-use-is-hydrated@0.1.0':
1315
+ resolution: {integrity: sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==}
1316
+ peerDependencies:
1317
+ '@types/react': '*'
1318
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
1319
+ peerDependenciesMeta:
1320
+ '@types/react':
1321
+ optional: true
1322
+
1323
  '@radix-ui/react-use-layout-effect@1.1.1':
1324
  resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==}
1325
  peerDependencies:
 
3056
  motion-utils@12.29.2:
3057
  resolution: {integrity: sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A==}
3058
 
3059
+ motion@12.29.2:
3060
+ resolution: {integrity: sha512-jMpHdAzEDF1QQ055cB+1lOBLdJ6ialVWl6QQzpJI2OvmHequ7zFVHM2mx0HNAy+Tu4omUlApfC+4vnkX0geEOg==}
3061
+ peerDependencies:
3062
+ '@emotion/is-prop-valid': '*'
3063
+ react: ^18.0.0 || ^19.0.0
3064
+ react-dom: ^18.0.0 || ^19.0.0
3065
+ peerDependenciesMeta:
3066
+ '@emotion/is-prop-valid':
3067
+ optional: true
3068
+ react:
3069
+ optional: true
3070
+ react-dom:
3071
+ optional: true
3072
+
3073
  ms@2.1.3:
3074
  resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
3075
 
 
3331
  queue-microtask@1.2.3:
3332
  resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
3333
 
3334
+ radix-ui@1.4.3:
3335
+ resolution: {integrity: sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA==}
3336
+ peerDependencies:
3337
+ '@types/react': '*'
3338
+ '@types/react-dom': '*'
3339
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
3340
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
3341
+ peerDependenciesMeta:
3342
+ '@types/react':
3343
+ optional: true
3344
+ '@types/react-dom':
3345
+ optional: true
3346
+
3347
  range-parser@1.2.1:
3348
  resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
3349
  engines: {node: '>= 0.6'}
 
4513
 
4514
  '@radix-ui/primitive@1.1.3': {}
4515
 
4516
+ '@radix-ui/react-accessible-icon@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4517
+ dependencies:
4518
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4519
+ react: 19.2.3
4520
+ react-dom: 19.2.3(react@19.2.3)
4521
+ optionalDependencies:
4522
+ '@types/react': 19.2.9
4523
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4524
+
4525
+ '@radix-ui/react-accordion@1.2.12(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4526
+ dependencies:
4527
+ '@radix-ui/primitive': 1.1.3
4528
+ '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4529
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4530
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4531
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4532
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4533
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4534
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4535
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
4536
+ react: 19.2.3
4537
+ react-dom: 19.2.3(react@19.2.3)
4538
+ optionalDependencies:
4539
+ '@types/react': 19.2.9
4540
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4541
+
4542
+ '@radix-ui/react-alert-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4543
+ dependencies:
4544
+ '@radix-ui/primitive': 1.1.3
4545
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4546
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4547
+ '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4548
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4549
+ '@radix-ui/react-slot': 1.2.3(@types/react@19.2.9)(react@19.2.3)
4550
+ react: 19.2.3
4551
+ react-dom: 19.2.3(react@19.2.3)
4552
+ optionalDependencies:
4553
+ '@types/react': 19.2.9
4554
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4555
+
4556
  '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4557
  dependencies:
4558
  '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
 
4562
  '@types/react': 19.2.9
4563
  '@types/react-dom': 19.2.3(@types/react@19.2.9)
4564
 
4565
+ '@radix-ui/react-aspect-ratio@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4566
+ dependencies:
4567
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4568
+ react: 19.2.3
4569
+ react-dom: 19.2.3(react@19.2.3)
4570
+ optionalDependencies:
4571
+ '@types/react': 19.2.9
4572
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4573
+
4574
+ '@radix-ui/react-avatar@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4575
+ dependencies:
4576
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4577
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4578
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4579
+ '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.9)(react@19.2.3)
4580
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4581
+ react: 19.2.3
4582
+ react-dom: 19.2.3(react@19.2.3)
4583
+ optionalDependencies:
4584
+ '@types/react': 19.2.9
4585
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4586
+
4587
+ '@radix-ui/react-checkbox@1.3.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4588
+ dependencies:
4589
+ '@radix-ui/primitive': 1.1.3
4590
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4591
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4592
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4593
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4594
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
4595
+ '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4596
+ '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4597
+ react: 19.2.3
4598
+ react-dom: 19.2.3(react@19.2.3)
4599
+ optionalDependencies:
4600
+ '@types/react': 19.2.9
4601
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4602
+
4603
+ '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4604
+ dependencies:
4605
+ '@radix-ui/primitive': 1.1.3
4606
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4607
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4608
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4609
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4610
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4611
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
4612
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4613
+ react: 19.2.3
4614
+ react-dom: 19.2.3(react@19.2.3)
4615
+ optionalDependencies:
4616
+ '@types/react': 19.2.9
4617
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4618
+
4619
  '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4620
  dependencies:
4621
  '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
 
4634
  optionalDependencies:
4635
  '@types/react': 19.2.9
4636
 
4637
+ '@radix-ui/react-context-menu@2.2.16(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4638
+ dependencies:
4639
+ '@radix-ui/primitive': 1.1.3
4640
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4641
+ '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4642
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4643
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4644
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
4645
+ react: 19.2.3
4646
+ react-dom: 19.2.3(react@19.2.3)
4647
+ optionalDependencies:
4648
+ '@types/react': 19.2.9
4649
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4650
+
4651
  '@radix-ui/react-context@1.1.2(@types/react@19.2.9)(react@19.2.3)':
4652
  dependencies:
4653
  react: 19.2.3
4654
  optionalDependencies:
4655
  '@types/react': 19.2.9
4656
 
4657
+ '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4658
+ dependencies:
4659
+ '@radix-ui/primitive': 1.1.3
4660
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4661
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4662
+ '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4663
+ '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.9)(react@19.2.3)
4664
+ '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4665
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4666
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4667
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4668
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4669
+ '@radix-ui/react-slot': 1.2.3(@types/react@19.2.9)(react@19.2.3)
4670
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
4671
+ aria-hidden: 1.2.6
4672
+ react: 19.2.3
4673
+ react-dom: 19.2.3(react@19.2.3)
4674
+ react-remove-scroll: 2.7.2(@types/react@19.2.9)(react@19.2.3)
4675
+ optionalDependencies:
4676
+ '@types/react': 19.2.9
4677
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4678
+
4679
+ '@radix-ui/react-direction@1.1.1(@types/react@19.2.9)(react@19.2.3)':
4680
+ dependencies:
4681
+ react: 19.2.3
4682
+ optionalDependencies:
4683
+ '@types/react': 19.2.9
4684
+
4685
+ '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4686
+ dependencies:
4687
+ '@radix-ui/primitive': 1.1.3
4688
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4689
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4690
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4691
+ '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4692
+ react: 19.2.3
4693
+ react-dom: 19.2.3(react@19.2.3)
4694
+ optionalDependencies:
4695
+ '@types/react': 19.2.9
4696
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4697
+
4698
+ '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4699
+ dependencies:
4700
+ '@radix-ui/primitive': 1.1.3
4701
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4702
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4703
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4704
+ '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4705
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4706
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
4707
+ react: 19.2.3
4708
+ react-dom: 19.2.3(react@19.2.3)
4709
+ optionalDependencies:
4710
+ '@types/react': 19.2.9
4711
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4712
+
4713
+ '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.9)(react@19.2.3)':
4714
+ dependencies:
4715
+ react: 19.2.3
4716
+ optionalDependencies:
4717
+ '@types/react': 19.2.9
4718
+
4719
+ '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4720
+ dependencies:
4721
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4722
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4723
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4724
+ react: 19.2.3
4725
+ react-dom: 19.2.3(react@19.2.3)
4726
+ optionalDependencies:
4727
+ '@types/react': 19.2.9
4728
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4729
+
4730
+ '@radix-ui/react-form@0.1.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4731
+ dependencies:
4732
+ '@radix-ui/primitive': 1.1.3
4733
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4734
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4735
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4736
+ '@radix-ui/react-label': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4737
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4738
+ react: 19.2.3
4739
+ react-dom: 19.2.3(react@19.2.3)
4740
+ optionalDependencies:
4741
+ '@types/react': 19.2.9
4742
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4743
+
4744
+ '@radix-ui/react-hover-card@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4745
+ dependencies:
4746
+ '@radix-ui/primitive': 1.1.3
4747
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4748
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4749
+ '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4750
+ '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4751
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4752
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4753
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4754
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
4755
+ react: 19.2.3
4756
+ react-dom: 19.2.3(react@19.2.3)
4757
+ optionalDependencies:
4758
+ '@types/react': 19.2.9
4759
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4760
+
4761
+ '@radix-ui/react-id@1.1.1(@types/react@19.2.9)(react@19.2.3)':
4762
+ dependencies:
4763
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4764
+ react: 19.2.3
4765
+ optionalDependencies:
4766
+ '@types/react': 19.2.9
4767
+
4768
+ '@radix-ui/react-label@2.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4769
+ dependencies:
4770
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4771
+ react: 19.2.3
4772
+ react-dom: 19.2.3(react@19.2.3)
4773
+ optionalDependencies:
4774
+ '@types/react': 19.2.9
4775
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4776
+
4777
+ '@radix-ui/react-label@2.1.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4778
  dependencies:
4779
+ '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4780
  react: 19.2.3
4781
+ react-dom: 19.2.3(react@19.2.3)
4782
  optionalDependencies:
4783
  '@types/react': 19.2.9
4784
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4785
 
4786
+ '@radix-ui/react-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4787
  dependencies:
4788
  '@radix-ui/primitive': 1.1.3
4789
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4790
  '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4791
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4792
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4793
+ '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4794
+ '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.9)(react@19.2.3)
4795
+ '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4796
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4797
+ '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4798
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4799
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4800
  '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4801
+ '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4802
+ '@radix-ui/react-slot': 1.2.3(@types/react@19.2.9)(react@19.2.3)
4803
  '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4804
+ aria-hidden: 1.2.6
4805
  react: 19.2.3
4806
  react-dom: 19.2.3(react@19.2.3)
4807
+ react-remove-scroll: 2.7.2(@types/react@19.2.9)(react@19.2.3)
4808
  optionalDependencies:
4809
  '@types/react': 19.2.9
4810
  '@types/react-dom': 19.2.3(@types/react@19.2.9)
4811
 
4812
+ '@radix-ui/react-menubar@1.1.16(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4813
  dependencies:
4814
+ '@radix-ui/primitive': 1.1.3
4815
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4816
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4817
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4818
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4819
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4820
+ '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4821
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4822
+ '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4823
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
4824
  react: 19.2.3
4825
+ react-dom: 19.2.3(react@19.2.3)
4826
  optionalDependencies:
4827
  '@types/react': 19.2.9
4828
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4829
 
4830
+ '@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4831
  dependencies:
4832
+ '@radix-ui/primitive': 1.1.3
4833
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4834
  '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4835
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4836
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4837
+ '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4838
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4839
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4840
  '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4841
  '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4842
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
4843
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4844
+ '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4845
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4846
  react: 19.2.3
4847
  react-dom: 19.2.3(react@19.2.3)
4848
  optionalDependencies:
4849
  '@types/react': 19.2.9
4850
  '@types/react-dom': 19.2.3(@types/react@19.2.9)
4851
 
4852
+ '@radix-ui/react-one-time-password-field@0.1.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4853
  dependencies:
4854
+ '@radix-ui/number': 1.1.1
4855
+ '@radix-ui/primitive': 1.1.3
4856
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4857
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4858
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4859
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4860
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4861
+ '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4862
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
4863
+ '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.9)(react@19.2.3)
4864
+ '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.9)(react@19.2.3)
4865
  '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4866
  react: 19.2.3
4867
+ react-dom: 19.2.3(react@19.2.3)
4868
  optionalDependencies:
4869
  '@types/react': 19.2.9
4870
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4871
 
4872
+ '@radix-ui/react-password-toggle-field@0.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4873
  dependencies:
4874
+ '@radix-ui/primitive': 1.1.3
4875
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4876
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4877
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4878
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4879
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
4880
+ '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.9)(react@19.2.3)
4881
+ '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.9)(react@19.2.3)
4882
+ react: 19.2.3
4883
+ react-dom: 19.2.3(react@19.2.3)
4884
+ optionalDependencies:
4885
+ '@types/react': 19.2.9
4886
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4887
+
4888
+ '@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4889
+ dependencies:
4890
+ '@radix-ui/primitive': 1.1.3
4891
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4892
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4893
+ '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4894
+ '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.9)(react@19.2.3)
4895
+ '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4896
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4897
+ '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4898
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4899
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4900
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4901
+ '@radix-ui/react-slot': 1.2.3(@types/react@19.2.9)(react@19.2.3)
4902
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
4903
+ aria-hidden: 1.2.6
4904
  react: 19.2.3
4905
  react-dom: 19.2.3(react@19.2.3)
4906
+ react-remove-scroll: 2.7.2(@types/react@19.2.9)(react@19.2.3)
4907
  optionalDependencies:
4908
  '@types/react': 19.2.9
4909
  '@types/react-dom': 19.2.3(@types/react@19.2.9)
 
4964
  '@types/react': 19.2.9
4965
  '@types/react-dom': 19.2.3(@types/react@19.2.9)
4966
 
4967
+ '@radix-ui/react-progress@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4968
+ dependencies:
4969
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4970
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4971
+ react: 19.2.3
4972
+ react-dom: 19.2.3(react@19.2.3)
4973
+ optionalDependencies:
4974
+ '@types/react': 19.2.9
4975
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4976
+
4977
+ '@radix-ui/react-radio-group@1.3.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4978
+ dependencies:
4979
+ '@radix-ui/primitive': 1.1.3
4980
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4981
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
4982
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4983
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4984
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4985
+ '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
4986
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
4987
+ '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4988
+ '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.9)(react@19.2.3)
4989
+ react: 19.2.3
4990
+ react-dom: 19.2.3(react@19.2.3)
4991
+ optionalDependencies:
4992
+ '@types/react': 19.2.9
4993
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
4994
+
4995
  '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
4996
  dependencies:
4997
  '@radix-ui/primitive': 1.1.3
 
5009
  '@types/react': 19.2.9
5010
  '@types/react-dom': 19.2.3(@types/react@19.2.9)
5011
 
5012
+ '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
5013
+ dependencies:
5014
+ '@radix-ui/number': 1.1.1
5015
+ '@radix-ui/primitive': 1.1.3
5016
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
5017
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
5018
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.9)(react@19.2.3)
5019
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5020
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5021
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.9)(react@19.2.3)
5022
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.9)(react@19.2.3)
5023
+ react: 19.2.3
5024
+ react-dom: 19.2.3(react@19.2.3)
5025
+ optionalDependencies:
5026
+ '@types/react': 19.2.9
5027
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
5028
+
5029
  '@radix-ui/react-select@2.2.6(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
5030
  dependencies:
5031
  '@radix-ui/number': 1.1.1
 
5055
  '@types/react': 19.2.9
5056
  '@types/react-dom': 19.2.3(@types/react@19.2.9)
5057
 
5058
+ '@radix-ui/react-separator@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
5059
+ dependencies:
5060
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5061
+ react: 19.2.3
5062
+ react-dom: 19.2.3(react@19.2.3)
5063
+ optionalDependencies:
5064
+ '@types/react': 19.2.9
5065
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
5066
+
5067
  '@radix-ui/react-separator@1.1.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
5068
  dependencies:
5069
  '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
 
5137
  '@types/react': 19.2.9
5138
  '@types/react-dom': 19.2.3(@types/react@19.2.9)
5139
 
5140
+ '@radix-ui/react-toast@1.2.15(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
5141
+ dependencies:
5142
+ '@radix-ui/primitive': 1.1.3
5143
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5144
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
5145
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
5146
+ '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5147
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5148
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5149
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5150
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.9)(react@19.2.3)
5151
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
5152
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.9)(react@19.2.3)
5153
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5154
+ react: 19.2.3
5155
+ react-dom: 19.2.3(react@19.2.3)
5156
+ optionalDependencies:
5157
+ '@types/react': 19.2.9
5158
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
5159
+
5160
+ '@radix-ui/react-toggle-group@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
5161
+ dependencies:
5162
+ '@radix-ui/primitive': 1.1.3
5163
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
5164
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.9)(react@19.2.3)
5165
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5166
+ '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5167
+ '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5168
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
5169
+ react: 19.2.3
5170
+ react-dom: 19.2.3(react@19.2.3)
5171
+ optionalDependencies:
5172
+ '@types/react': 19.2.9
5173
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
5174
+
5175
+ '@radix-ui/react-toggle@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
5176
+ dependencies:
5177
+ '@radix-ui/primitive': 1.1.3
5178
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5179
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
5180
+ react: 19.2.3
5181
+ react-dom: 19.2.3(react@19.2.3)
5182
+ optionalDependencies:
5183
+ '@types/react': 19.2.9
5184
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
5185
+
5186
+ '@radix-ui/react-toolbar@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
5187
+ dependencies:
5188
+ '@radix-ui/primitive': 1.1.3
5189
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
5190
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.9)(react@19.2.3)
5191
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5192
+ '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5193
+ '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5194
+ '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5195
+ react: 19.2.3
5196
+ react-dom: 19.2.3(react@19.2.3)
5197
+ optionalDependencies:
5198
+ '@types/react': 19.2.9
5199
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
5200
+
5201
+ '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
5202
+ dependencies:
5203
+ '@radix-ui/primitive': 1.1.3
5204
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
5205
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
5206
+ '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5207
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.9)(react@19.2.3)
5208
+ '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5209
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5210
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5211
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5212
+ '@radix-ui/react-slot': 1.2.3(@types/react@19.2.9)(react@19.2.3)
5213
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
5214
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
5215
+ react: 19.2.3
5216
+ react-dom: 19.2.3(react@19.2.3)
5217
+ optionalDependencies:
5218
+ '@types/react': 19.2.9
5219
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
5220
+
5221
  '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.9)(react@19.2.3)':
5222
  dependencies:
5223
  react: 19.2.3
 
5246
  optionalDependencies:
5247
  '@types/react': 19.2.9
5248
 
5249
+ '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@19.2.9)(react@19.2.3)':
5250
+ dependencies:
5251
+ react: 19.2.3
5252
+ use-sync-external-store: 1.6.0(react@19.2.3)
5253
+ optionalDependencies:
5254
+ '@types/react': 19.2.9
5255
+
5256
  '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.9)(react@19.2.3)':
5257
  dependencies:
5258
  react: 19.2.3
 
7022
 
7023
  motion-utils@12.29.2: {}
7024
 
7025
+ motion@12.29.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
7026
+ dependencies:
7027
+ framer-motion: 12.29.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7028
+ tslib: 2.8.1
7029
+ optionalDependencies:
7030
+ react: 19.2.3
7031
+ react-dom: 19.2.3(react@19.2.3)
7032
+
7033
  ms@2.1.3: {}
7034
 
7035
  msw@2.12.7(@types/node@25.0.10)(typescript@5.9.3):
 
7306
 
7307
  queue-microtask@1.2.3: {}
7308
 
7309
+ radix-ui@1.4.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
7310
+ dependencies:
7311
+ '@radix-ui/primitive': 1.1.3
7312
+ '@radix-ui/react-accessible-icon': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7313
+ '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7314
+ '@radix-ui/react-alert-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7315
+ '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7316
+ '@radix-ui/react-aspect-ratio': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7317
+ '@radix-ui/react-avatar': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7318
+ '@radix-ui/react-checkbox': 1.3.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7319
+ '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7320
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7321
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.9)(react@19.2.3)
7322
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.9)(react@19.2.3)
7323
+ '@radix-ui/react-context-menu': 2.2.16(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7324
+ '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7325
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.9)(react@19.2.3)
7326
+ '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7327
+ '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7328
+ '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.9)(react@19.2.3)
7329
+ '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7330
+ '@radix-ui/react-form': 0.1.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7331
+ '@radix-ui/react-hover-card': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7332
+ '@radix-ui/react-label': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7333
+ '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7334
+ '@radix-ui/react-menubar': 1.1.16(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7335
+ '@radix-ui/react-navigation-menu': 1.2.14(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7336
+ '@radix-ui/react-one-time-password-field': 0.1.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7337
+ '@radix-ui/react-password-toggle-field': 0.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7338
+ '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7339
+ '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7340
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7341
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7342
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7343
+ '@radix-ui/react-progress': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7344
+ '@radix-ui/react-radio-group': 1.3.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7345
+ '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7346
+ '@radix-ui/react-scroll-area': 1.2.10(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7347
+ '@radix-ui/react-select': 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7348
+ '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7349
+ '@radix-ui/react-slider': 1.3.6(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7350
+ '@radix-ui/react-slot': 1.2.3(@types/react@19.2.9)(react@19.2.3)
7351
+ '@radix-ui/react-switch': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7352
+ '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7353
+ '@radix-ui/react-toast': 1.2.15(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7354
+ '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7355
+ '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7356
+ '@radix-ui/react-toolbar': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7357
+ '@radix-ui/react-tooltip': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7358
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.9)(react@19.2.3)
7359
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.9)(react@19.2.3)
7360
+ '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.9)(react@19.2.3)
7361
+ '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.9)(react@19.2.3)
7362
+ '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.9)(react@19.2.3)
7363
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.9)(react@19.2.3)
7364
+ '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.9)(react@19.2.3)
7365
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
7366
+ react: 19.2.3
7367
+ react-dom: 19.2.3(react@19.2.3)
7368
+ optionalDependencies:
7369
+ '@types/react': 19.2.9
7370
+ '@types/react-dom': 19.2.3(@types/react@19.2.9)
7371
+
7372
  range-parser@1.2.1: {}
7373
 
7374
  raw-body@3.0.2:
ui/schemas/data.ts ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { z } from "zod";
2
+
3
+ export const DatasetSchema = z.object({
4
+ name: z.string(),
5
+ type: z.string(),
6
+ count: z.string(),
7
+ size: z.string(),
8
+ updated: z.string(),
9
+ });
10
+
11
+ export const StatisticsSchema = z.object({
12
+ datasets: z.number(),
13
+ molecules: z.string(),
14
+ proteins: z.string(),
15
+ storage: z.string(),
16
+ });
17
+
18
+ export const DataResponseSchema = z.object({
19
+ datasets: z.array(DatasetSchema),
20
+ stats: StatisticsSchema,
21
+ });
ui/schemas/explorer.ts ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { z } from "zod";
2
+
3
+ export const DataPointSchema = z.object({
4
+ x: z.number(),
5
+ y: z.number(),
6
+ z: z.number(),
7
+ color: z.string(),
8
+ name: z.string(),
9
+ affinity: z.number(),
10
+ });
11
+
12
+ export const ExplorerMetricsSchema = z.object({
13
+ activeMolecules: z.number(),
14
+ clusters: z.number(),
15
+ avgConfidence: z.number(),
16
+ });
17
+
18
+ export const ExplorerResponseSchema = z.object({
19
+ points: z.array(DataPointSchema),
20
+ metrics: ExplorerMetricsSchema,
21
+ });
22
+
23
+ export const ExplorerRequestSchema = z.object({
24
+ dataset: z.string().optional().default("DrugBank"),
25
+ view: z.string().optional().default("UMAP"),
26
+ colorBy: z.string().optional().default("Activity"),
27
+ });
ui/types/data.ts ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import { z } from "zod";
2
+ import { DatasetSchema, StatisticsSchema, DataResponseSchema } from "@/schemas/data";
3
+
4
+ export type Dataset = z.infer<typeof DatasetSchema>;
5
+ export type Statistics = z.infer<typeof StatisticsSchema>;
6
+ export type DataResponse = z.infer<typeof DataResponseSchema>;
ui/types/explorer.ts ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ import { z } from "zod";
2
+ import { DataPointSchema, ExplorerMetricsSchema, ExplorerResponseSchema, ExplorerRequestSchema } from "@/schemas/explorer";
3
+
4
+ export type DataPoint = z.infer<typeof DataPointSchema>;
5
+ export type ExplorerMetrics = z.infer<typeof ExplorerMetricsSchema>;
6
+ export type ExplorerResponse = z.infer<typeof ExplorerResponseSchema>;
7
+ export type ExplorerRequest = z.infer<typeof ExplorerRequestSchema>;