diff --git a/app/api/graph/[graph]/[node]/route.ts b/app/api/graph/[graph]/[node]/route.ts index 80f4cf81..6d0e7e1f 100644 --- a/app/api/graph/[graph]/[node]/route.ts +++ b/app/api/graph/[graph]/[node]/route.ts @@ -22,6 +22,7 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{ const result = await graph.query(query, { params: { nodeId } }); return NextResponse.json({ result }, { status: 200 }) } catch (err: unknown) { + console.error(err) return NextResponse.json({ message: (err as Error).message }, { status: 400 }) } } \ No newline at end of file diff --git a/app/api/graph/[graph]/route.ts b/app/api/graph/[graph]/route.ts index 82ab66ec..baf85d6a 100644 --- a/app/api/graph/[graph]/route.ts +++ b/app/api/graph/[graph]/route.ts @@ -22,6 +22,7 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise return NextResponse.json({ message: `${graphId} graph deleted` }) } } catch (err: unknown) { + console.error(err) return NextResponse.json({ message: (err as Error).message }, { status: 400 }) } } @@ -34,46 +35,39 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{ return client } - const { graph: graphId } = await params; + const { graph: name } = await params; const sourceName = request.nextUrl.searchParams.get("sourceName") try { if (sourceName) { const graph = client.selectGraph(sourceName); - const success = await graph.copy(graphId) + const success = await graph.copy(name) if (!success) throw new Error("Failed to copy graph") return NextResponse.json({ success }, { status: 200 }) } const type = request.nextUrl.searchParams.get("type") - const key = request.nextUrl.searchParams.get("key") + const openaikey = request.nextUrl.searchParams.get("key") const srcs = await request.json() - if (!key) console.error("Missing parameter 'key'") - - if (!srcs) console.error("Missing parameter 'srcs'") // eslint-disable-next-line @typescript-eslint/no-explicit-any - const socket = (await client.connection).options?.socket as any - - if (!socket) console.error("socket not found") - - const data = { - host: socket.host, - port: socket.port, - name: graphId, - srcs, - openaikey: key, - } + const { host, port } = (await client.connection).options?.socket as any - if (!type) console.error("Missing parameter 'type'") + if (!openaikey || !srcs || !host || !port || !type) throw new Error("Missing parameters") const res = await securedFetch(`http://localhost:5000/${prepareArg(type!)}`, { method: "POST", headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(data) + body: JSON.stringify({ + host, + port, + name, + srcs, + openaikey, + }) }) const result = await res.json() @@ -82,6 +76,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{ return NextResponse.json({ result }, { status: 200 }) } catch (err: unknown) { + console.error(err) return NextResponse.json({ message: (err as Error).message }, { status: 400 }) } } @@ -98,7 +93,7 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise< const sourceName = request.nextUrl.searchParams.get("sourceName") try { - if (!sourceName) throw (new Error("Missing parameter 'sourceName'")) + if (!sourceName) throw new Error("Missing parameter sourceName") const data = await (await client.connection).renameNX(sourceName, graphId); @@ -106,6 +101,7 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise< return NextResponse.json({ data }) } catch (err: unknown) { + console.error(err) return NextResponse.json({ message: (err as Error).message }, { status: 400 }) } } @@ -135,7 +131,7 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{ const create = request.nextUrl.searchParams.get("create") const role = request.nextUrl.searchParams.get("role") - if (!query) throw new Error("Missing parameter 'query'") + if (!query) throw new Error("Missing parameter query") if (create === "false" && !(await client.list()).some((g) => g === graphId)) return NextResponse.json({}, { status: 200 }) @@ -146,10 +142,11 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{ ? await graph.roQuery(query) : await graph.query(query) - if (!result) throw new Error("something went wrong") + if (!result) throw new Error("Something went wrong") return NextResponse.json({ result }, { status: 200 }) } catch (err: unknown) { + console.error(err) return NextResponse.json({ message: (err as Error).message }, { status: 400 }) } } \ No newline at end of file diff --git a/app/api/graph/model.ts b/app/api/graph/model.ts index a1e79574..91df1a2e 100644 --- a/app/api/graph/model.ts +++ b/app/api/graph/model.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-param-reassign */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { EdgeDataDefinition, NodeDataDefinition } from 'cytoscape'; @@ -11,7 +12,6 @@ export type Node = NodeObject<{ expand: boolean, collapsed: boolean, data: { - name: string, [key: string]: any } }> @@ -36,13 +36,37 @@ export type GraphData = { links: Link[] } +export type NodeCell = { + id: number, + labels: string[], + properties: { + [key: string]: any + } +} + +export type LinkCell = { + id: number, + relationshipType: string, + sourceId: number, + destinationId: number, + properties: { + [key: string]: any + } +} + +export type DataCell = NodeCell | LinkCell | number | string | null + +export type DataRow = { + [key: string]: DataCell +} + +export type Data = DataRow[] + export const DEFAULT_COLORS = [ - "#7167F6", - "#ED70B1", - "#EF8759", - "#99E4E5", - "#F2EB47", - "#89D86D" + "#7466FF", + "#FF66B3", + "#FF804D", + "#80E6E6" ] export interface Query { @@ -69,7 +93,7 @@ export class Graph { private columns: string[]; - private data: any[]; + private data: Data; private metadata: any[]; @@ -106,14 +130,7 @@ export class Graph { this.labelsMap = labelsMap; this.nodesMap = nodesMap; this.linksMap = edgesMap; - this.COLORS_ORDER_VALUE = colors || [ - "#7167F6", - "#ED70B1", - "#EF8759", - "#99E4E5", - "#F2EB47", - "#89D86D" - ] + this.COLORS_ORDER_VALUE = colors || DEFAULT_COLORS } get Id(): string { @@ -164,10 +181,14 @@ export class Graph { return this.columns; } - get Data(): any[] { + get Data(): Data { return this.data; } + set Data(data: Data) { + this.data = data; + } + get Metadata(): any[] { return this.metadata; } @@ -195,7 +216,7 @@ export class Graph { return graph } - public extendNode(cell: any, collapsed = false) { + public extendNode(cell: NodeCell, collapsed = false) { // check if category already exists in categories const categories = this.createCategory(cell.labels.length === 0 ? [""] : cell.labels) // check if node already exists in nodes or fake node was created @@ -209,9 +230,7 @@ export class Graph { visible: true, expand: false, collapsed, - data: { - name: cell.id.toString(), - } + data: {} } Object.entries(cell.properties).forEach(([key, value]) => { node.data[key] = value as string; @@ -228,25 +247,32 @@ export class Graph { currentNode.color = this.getCategoryColorValue(categories[0].index) currentNode.expand = false currentNode.collapsed = collapsed - currentNode.data = { - name: cell.id.toString() - } Object.entries(cell.properties).forEach(([key, value]) => { currentNode.data[key] = value as string; }); // remove empty category if there are no more empty nodes category if (Array.from(this.nodesMap.values()).every(n => n.category.some(c => c !== ""))) { - this.categories = this.categories.filter(l => l.name !== "") + this.categories = this.categories.filter(l => l.name !== "").map(c => { + // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain + if (this.categoriesMap.get("")?.index! < c.index) { + c.index -= 1 + this.categoriesMap.get(c.name)!.index = c.index + } + return c + }) this.categoriesMap.delete("") this.categoriesColorIndex -= 1 + this.elements.nodes.forEach(n => { + n.color = this.getCategoryColorValue(this.categoriesMap.get(n.category[0])?.index) + }) } } return currentNode } - public extendEdge(cell: any, collapsed = false) { + public extendEdge(cell: LinkCell, collapsed = false) { const label = this.createLabel(cell.relationshipType) const currentEdge = this.linksMap.get(cell.id) @@ -254,14 +280,14 @@ export class Graph { if (!currentEdge) { let category let link: Link - + if (cell.sourceId === cell.destinationId) { let source = this.nodesMap.get(cell.sourceId) - + if (!source) { [category] = this.createCategory([""]) } - + if (!source) { source = { id: cell.sourceId, @@ -270,15 +296,13 @@ export class Graph { expand: false, collapsed, visible: true, - data: { - name: cell.sourceId.toString(), - }, + data: {}, } - + this.nodesMap.set(cell.sourceId, source) this.elements.nodes.push(source) } - + link = { id: cell.id, source, @@ -294,7 +318,7 @@ export class Graph { } else { let source = this.nodesMap.get(cell.sourceId) let target = this.nodesMap.get(cell.destinationId) - + if (!source || !target) { [category] = this.createCategory([""]) } @@ -307,9 +331,7 @@ export class Graph { expand: false, collapsed, visible: true, - data: { - name: cell.sourceId.toString(), - }, + data: {}, } this.nodesMap.set(cell.sourceId, source) @@ -325,9 +347,7 @@ export class Graph { expand: false, collapsed, visible: true, - data: { - name: cell.destinationId.toString(), - } + data: {}, } } @@ -361,7 +381,7 @@ export class Graph { return currentEdge } - public extend(results: any, collapsed = false): (Node | Link)[] { + public extend(results: { data: Data, metadata: any[] }, collapsed = false): (Node | Link)[] { const newElements: (Node | Link)[] = [] const data = results?.data @@ -374,7 +394,7 @@ export class Graph { } this.metadata = results.metadata - this.data.forEach((row: any[]) => { + this.data.forEach((row: DataRow) => { Object.values(row).forEach((cell: any) => { if (cell instanceof Object) { if (cell.nodes) { @@ -393,6 +413,28 @@ export class Graph { }) }) + newElements.filter((element): element is Link => "source" in element).forEach((link) => { + const start = link.source + const end = link.target + const sameNodesLinks = this.elements.links.filter(l => (l.source.id === start.id && l.target.id === end.id) || (l.target.id === start.id && l.source.id === end.id)) + const index = sameNodesLinks.findIndex(l => l.id === link.id) || 0 + const even = index % 2 === 0 + let curve + + if (start.id === end.id) { + if (even) { + curve = Math.floor(-(index / 2)) - 3 + } else { + curve = Math.floor((index + 1) / 2) + 2 + } + } else if (even) { + curve = Math.floor(-(index / 2)) + } else { + curve = Math.floor((index + 1) / 2) + } + + link.curve = curve * 0.1 + }) return newElements } @@ -478,7 +520,6 @@ export class Graph { } } - public getCategoryColorValue(index = 0): string { return this.COLORS_ORDER_VALUE[index % this.COLORS_ORDER_VALUE.length] } diff --git a/app/api/graph/route.ts b/app/api/graph/route.ts index 844ee45c..c39388cf 100644 --- a/app/api/graph/route.ts +++ b/app/api/graph/route.ts @@ -22,6 +22,7 @@ export async function GET(request: NextRequest) { return NextResponse.json({ result }, { status: 200 }) } catch (err: unknown) { + console.error(err) return NextResponse.json({ message: (err as Error).message }, { status: 400 }) } } @@ -45,6 +46,7 @@ export async function POST(request: NextRequest) { return NextResponse.json({ config }, { status: 200 }) } } catch (err: unknown) { + console.error(err) return NextResponse.json({ message: (err as Error).message }, { status: 400 }) } } \ No newline at end of file diff --git a/app/api/user/[user]/route.ts b/app/api/user/[user]/route.ts index 8b0564de..4ac20f50 100644 --- a/app/api/user/[user]/route.ts +++ b/app/api/user/[user]/route.ts @@ -1,6 +1,6 @@ import { NextRequest, NextResponse } from "next/server" import { getClient } from "../../auth/[...nextauth]/options" -import { ROLE } from "../options" +import { ROLE } from "../model" // eslint-disable-next-line import/prefer-default-export export async function PATCH(req: NextRequest, { params }: { params: Promise<{ user: string }> }) { @@ -18,6 +18,7 @@ export async function PATCH(req: NextRequest, { params }: { params: Promise<{ us await (await client.connection).aclSetUser(username, role) return NextResponse.json({ message: "User created" }, { status: 200 }) } catch (err: unknown) { + console.error(err) return NextResponse.json({ message: (err as Error).message }, { status: 400 }) } } \ No newline at end of file diff --git a/app/api/user/model.ts b/app/api/user/model.ts index 429c15b0..43e5b280 100644 --- a/app/api/user/model.ts +++ b/app/api/user/model.ts @@ -1,5 +1,18 @@ export interface User{ username: string role: string - selected?: boolean -} \ No newline at end of file +} + +export interface CreateUser { + username: string + password: string + role: string +} + +export const ROLE = new Map( + [ + ["Admin", ["on", "~*", "&*", "+@all"]], + ["Read-Write", ["on", "~*", "resetchannels", "-@all", "+graph.explain", "+graph.list", "+ping", "+graph.ro_query", "+info", "+dump", "+graph.delete", "+graph.query", "+graph.profile"]], + ["Read-Only", ["on", "~*", "resetchannels", "-@all", "+graph.explain", "+graph.list", "+ping", "+graph.ro_query", "+info", "+dump"]] + ] +) \ No newline at end of file diff --git a/app/api/user/options.ts b/app/api/user/options.ts deleted file mode 100644 index 146d2f59..00000000 --- a/app/api/user/options.ts +++ /dev/null @@ -1,13 +0,0 @@ -export interface CreateUser { - username: string - password: string - role: string -} - -export const ROLE = new Map( - [ - ["Admin", ["on", "~*", "&*", "+@all"]], - ["Read-Write", ["on", "~*", "resetchannels", "-@all", "+graph.explain", "+graph.list", "+ping", "+graph.ro_query", "+info", "+dump", "+graph.delete", "+graph.query", "+graph.profile"]], - ["Read-Only", ["on", "~*", "resetchannels", "-@all", "+graph.explain", "+graph.list", "+ping", "+graph.ro_query", "+info", "+dump"]] - ] -) \ No newline at end of file diff --git a/app/api/user/route.ts b/app/api/user/route.ts index aa68835c..5463c89c 100644 --- a/app/api/user/route.ts +++ b/app/api/user/route.ts @@ -1,7 +1,6 @@ import { NextRequest, NextResponse } from "next/server"; import { getClient } from "@/app/api/auth/[...nextauth]/options"; -import { User } from "./model" -import { CreateUser, ROLE } from "./options"; +import { User, CreateUser, ROLE } from "./model"; export async function GET() { @@ -26,12 +25,13 @@ export async function GET() { return { username: userDetails[1], role: role ? role[0] : "Unknown", - checked: false + selected: false, } }) return NextResponse.json({ result }, { status: 200 }) } catch (err: unknown) { + console.error(err) return NextResponse.json({ message: (err as Error).message }, { status: 400 }) } } @@ -44,36 +44,27 @@ export async function POST(req: NextRequest) { } const connection = await client.connection - const isDelete = req.nextUrl.searchParams.get("isDelete") - - if (isDelete === "true") { - const { users } = await req.json() - - await Promise.all(users.map(async (user: CreateUser) => { - await connection.aclDelUser(user.username) - })) - - return NextResponse.json({ message: "Users deleted" }, { status: 200 }) - } - const { username, password, role } = await req.json() as CreateUser + const roleValue = ROLE.get(role) - try { - if (!username || !password || !roleValue) throw (new Error("Missing parameters")) - try { - const user = await connection.aclGetUser(username) + try { + if (!username || !password || !roleValue) throw new Error("Missing parameters") - if (user) { - return NextResponse.json({ message: `User ${username} already exists` }, { status: 409 }) - } + try { + const user = await connection.aclGetUser(username) + + if (user) { + return NextResponse.json({ message: `User ${username} already exists` }, { status: 409 }) + } } catch (err: unknown) { + console.error(err) // Just a workaround for https://github.com/redis/node-redis/issues/2745 } await connection.aclSetUser(username, roleValue.concat(`>${password}`)) return NextResponse.json( - { message: "User created" }, + { message: "Success" }, { status: 201, headers: { @@ -82,6 +73,30 @@ export async function POST(req: NextRequest) { } ) } catch (err: unknown) { + console.error(err) + return NextResponse.json({ message: (err as Error).message }, { status: 400 }) + } +} + +export async function DELETE(req: NextRequest) { + + const client = await getClient() + + if (client instanceof NextResponse) { + return client + } + + const connection = await client.connection + const { users } = await req.json() + + try { + await Promise.all(users.map(async (user: User) => { + await connection.aclDelUser(user.username) + })) + + return NextResponse.json({ message: "Users deleted" }, { status: 200 }) + } catch (err: unknown) { + console.error(err) return NextResponse.json({ message: (err as Error).message }, { status: 400 }) } } \ No newline at end of file diff --git a/app/components/CloseDialog.tsx b/app/components/CloseDialog.tsx index 75fb2cb4..f26a3e70 100644 --- a/app/components/CloseDialog.tsx +++ b/app/components/CloseDialog.tsx @@ -1,28 +1,28 @@ 'use client'; import { DialogClose } from "@/components/ui/dialog"; -import { cn } from "@/lib/utils"; import { X } from "lucide-react"; -import Button from "./ui/Button"; +import Button, { Variant } from "./ui/Button"; /* eslint-disable react/require-default-props */ interface Props extends React.DetailedHTMLProps, HTMLButtonElement> { icon?: JSX.Element label?: string - variant?: "Large" | "Primary" | "Secondary" | "button" + variant?: Variant } -export default function CloseDialog({ className, label, variant, icon, ...props }: Props) { +export default function CloseDialog({ className, label, icon, ...props }: Props) { return ( ) } \ No newline at end of file diff --git a/app/components/CreateGraph.tsx b/app/components/CreateGraph.tsx new file mode 100644 index 00000000..8cb14894 --- /dev/null +++ b/app/components/CreateGraph.tsx @@ -0,0 +1,101 @@ +/* eslint-disable react/require-default-props */ + +"use client" + +import { useState } from "react" +import { AlertCircle, PlusCircle } from "lucide-react" +import { prepareArg, securedFetch } from "@/lib/utils" +import { useToast } from "@/components/ui/use-toast" +import DialogComponent from "./DialogComponent" +import Button from "./ui/Button" +import CloseDialog from "./CloseDialog" +import Input from "./ui/Input" + +interface Props { + onSetGraphName: (name: string) => void + type: string + trigger?: React.ReactNode +} + +export default function CreateGraph({ + onSetGraphName, + type, + trigger = ( + + ), +}: Props) { + + const [graphName, setGraphName] = useState("") + const [open, setOpen] = useState(false) + const { toast } = useToast() + + const handleCreateGraph = async (e: React.FormEvent) => { + e.preventDefault() + if (!graphName) { + toast({ + title: "Error", + description: "Graph name cannot be empty", + variant: "destructive" + }) + return + } + const q = 'RETURN 1' + const result = await securedFetch(`api/graph/${prepareArg(graphName)}/?query=${prepareArg(q)}`, { + method: "GET", + }, toast) + + if (!result.ok) return + + onSetGraphName(graphName) + setGraphName("") + setOpen(false) + } + + return ( + +
{ + e.preventDefault() + handleCreateGraph(e) + }}> +
+ +

Name your graph:

+ ref?.focus()} + value={graphName} + onChange={(e) => setGraphName(e.target.value)} + /> +
+
+
+
+
+ ) +} \ No newline at end of file diff --git a/app/components/DialogComponent.tsx b/app/components/DialogComponent.tsx index ca6749aa..f6ae932f 100644 --- a/app/components/DialogComponent.tsx +++ b/app/components/DialogComponent.tsx @@ -1,6 +1,6 @@ 'use client'; -import { DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog"; +import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; import { cn } from "@/lib/utils"; import { ReactNode } from "react"; import CloseDialog from "./CloseDialog"; @@ -9,26 +9,40 @@ import CloseDialog from "./CloseDialog"; interface Props { children: React.ReactNode title: string + open?: boolean + onOpenChange?: (open: boolean) => void + trigger: React.ReactNode description?: ReactNode className?: string } -export default function DialogComponent({ children, title, description, className }: Props) { +export default function DialogComponent({ + children, + open, + onOpenChange, + trigger, + title, + description, + className, +}: Props) { return ( - - - {title} - - -
+ + + {trigger} + + + + {title} + + { description && - + {description} } {children} -
-
+ + ) -} \ No newline at end of file +} diff --git a/app/components/EditorComponent.tsx b/app/components/EditorComponent.tsx index fc2c6990..c8b28db7 100644 --- a/app/components/EditorComponent.tsx +++ b/app/components/EditorComponent.tsx @@ -1,5 +1,8 @@ /* eslint-disable consistent-return */ /* eslint-disable react-hooks/exhaustive-deps */ + +"use client"; + import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"; import { Editor, Monaco } from "@monaco-editor/react" import { useEffect, useRef, useState } from "react" @@ -7,6 +10,7 @@ import * as monaco from "monaco-editor"; import { prepareArg, securedFetch } from "@/lib/utils"; import { Maximize2 } from "lucide-react"; import { Session } from "next-auth"; +import { useToast } from "@/components/ui/use-toast"; import { Graph } from "../api/graph/model"; import Button from "./ui/Button"; @@ -52,10 +56,10 @@ const monacoOptions: monaco.editor.IStandaloneEditorConstructionOptions = { loop: false, }, automaticLayout: true, - fontSize: 30, + fontSize: 26, fontWeight: "200", wordWrap: "off", - lineHeight: 38, + lineHeight: 37, lineNumbersMinChars: 2, overviewRulerLanes: 0, overviewRulerBorder: false, @@ -197,9 +201,12 @@ const getEmptySuggestions = (): Suggestions => ({ functions: [] }) +const PLACEHOLDER = "Type your query here to start" + export default function EditorComponent({ currentQuery, historyQueries, setCurrentQuery, maximize, runQuery, graph, isCollapsed, data }: Props) { const [query, setQuery] = useState(currentQuery) + const placeholderRef = useRef(null) const [monacoInstance, setMonacoInstance] = useState() const [prevGraphName, setPrevGraphName] = useState("") const [sugProvider, setSugProvider] = useState() @@ -213,6 +220,7 @@ export default function EditorComponent({ currentQuery, historyQueries, setCurre currentQuery, historyCounter: historyQueries.length }) + const { toast } = useToast() useEffect(() => { historyRef.current.historyQueries = historyQueries @@ -240,8 +248,8 @@ export default function EditorComponent({ currentQuery, historyQueries, setCurre { token: 'number', foreground: '#b5cea8' }, ], colors: { - 'editor.background': '#1F1F3D', - 'editor.foreground': 'ffffff', + 'editor.background': '#191919', + 'editor.foreground': '#ffffff', 'editorSuggestWidget.background': '#272745', 'editorSuggestWidget.foreground': '#FFFFFF', 'editorSuggestWidget.selectedBackground': '#57577B', @@ -277,7 +285,7 @@ export default function EditorComponent({ currentQuery, historyQueries, setCurre await securedFetch(`api/graph/${prepareArg(graph.Id)}/?query=${prepareArg(labelsQuery)}&role=${data?.user.role}`, { method: "GET" - }).then((res) => res.json()).then((json) => { + }, toast).then((res) => res.json()).then((json) => { json.result.data.forEach(({ label }: { label: string }) => { sug.push({ label, @@ -295,7 +303,7 @@ export default function EditorComponent({ currentQuery, historyQueries, setCurre await securedFetch(`api/graph/${prepareArg(graph.Id)}/?query=${prepareArg(relationshipTypeQuery)}&role=${data?.user.role}`, { method: "GET" - }).then((res) => res.json()).then((json) => { + }, toast).then((res) => res.json()).then((json) => { json.result.data.forEach(({ relationshipType }: { relationshipType: string }) => { sug.push({ label: relationshipType, @@ -313,7 +321,7 @@ export default function EditorComponent({ currentQuery, historyQueries, setCurre await securedFetch(`api/graph/${prepareArg(graph.Id)}/?query=${prepareArg(propertyKeysQuery)}&role=${data?.user.role}`, { method: "GET" - }).then((res) => res.json()).then((json) => { + }, toast).then((res) => res.json()).then((json) => { json.result.data.forEach(({ propertyKey }: { propertyKey: string }) => { sug.push({ label: propertyKey, @@ -330,7 +338,7 @@ export default function EditorComponent({ currentQuery, historyQueries, setCurre const proceduresQuery = `CALL dbms.procedures() YIELD name` await securedFetch(`api/graph/${prepareArg(graph.Id)}/?query=${prepareArg(proceduresQuery)}&role=${data?.user.role}`, { method: "GET" - }).then((res) => res.json()).then((json) => { + }, toast).then((res) => res.json()).then((json) => { [...json.result.data.map(({ name }: { name: string }) => name), ...FUNCTIONS].forEach((name: string) => { functions.push({ label: name, @@ -434,15 +442,16 @@ export default function EditorComponent({ currentQuery, historyQueries, setCurre const run = async () => { const sug: Suggestions = getEmptySuggestions() - - await Promise.all(graph.Metadata.map(async (meta: string) => { - if (meta.includes("Labels")) await addLabelsSuggestions(sug.labels) - if (meta.includes("RelationshipTypes")) await addRelationshipTypesSuggestions(sug.relationshipTypes) - if (meta.includes("PropertyKeys")) await addPropertyKeysSuggestions(sug.propertyKeys) - })) + if (graph.Metadata.length > 0) { + await Promise.all(graph.Metadata.map(async (meta: string) => { + if (meta.includes("Labels")) await addLabelsSuggestions(sug.labels) + if (meta.includes("RelationshipTypes")) await addRelationshipTypesSuggestions(sug.relationshipTypes) + if (meta.includes("PropertyKeys")) await addPropertyKeysSuggestions(sug.propertyKeys) + })) + } Object.entries(sug).forEach(([key, value]) => { if (value.length === 0) { - sug[key as "labels" || "propertyKeys" || "relationshipTypes"] = suggestions[key as "labels" || "propertyKeys" || "relationshipTypes"] + sug[key as keyof Suggestions] = suggestions[key as keyof Suggestions] } }) @@ -531,6 +540,25 @@ export default function EditorComponent({ currentQuery, historyQueries, setCurre }; const handleEditorDidMount = (e: monaco.editor.IStandaloneCodeEditor, monacoI: Monaco) => { + const updatePlaceholderVisibility = () => { + const hasContent = !!e.getValue(); + if (placeholderRef.current) { + placeholderRef.current.style.display = hasContent ? 'none' : 'block'; + } + }; + + e.onDidFocusEditorText(() => { + if (placeholderRef.current) { + placeholderRef.current.style.display = 'none'; + } + }); + + e.onDidBlurEditorText(() => { + updatePlaceholderVisibility(); + }); + + // Initial check + updatePlaceholderVisibility(); setMonacoInstance(monacoI) @@ -612,17 +640,16 @@ export default function EditorComponent({ currentQuery, historyQueries, setCurre runQuery(query) }} > -
+
document.body.clientHeight / 100 * MAX_HEIGHT ? document.body.clientHeight / 100 * MAX_HEIGHT : lineNumber * LINE_HEIGHT} - className="Editor" language="custom-language" options={{ ...monacoOptions, lineNumbers: lineNumber > 1 ? "on" : "off", }} - value={blur ? query.replace(/\s+/g, ' ').trim() : query} + value={(blur ? query.replace(/\s+/g, ' ').trim() : query)} onChange={(val) => historyRef.current.historyCounter ? setQuery(val || "") : setCurrentQuery(val || "")} theme="custom-theme" beforeMount={handleEditorWillMount} @@ -632,14 +659,19 @@ export default function EditorComponent({ currentQuery, historyQueries, setCurre +
+ {PLACEHOLDER} +
+ + ) +} \ No newline at end of file diff --git a/app/components/ForceGraph.tsx b/app/components/ForceGraph.tsx index 6dbacbb0..0380c22c 100644 --- a/app/components/ForceGraph.tsx +++ b/app/components/ForceGraph.tsx @@ -1,32 +1,32 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable react/require-default-props */ /* eslint-disable no-param-reassign */ "use client" -import { Dispatch, RefObject, SetStateAction, useState } from "react" +import { Dispatch, RefObject, SetStateAction, useEffect, useRef, useState } from "react" import ForceGraph2D from "react-force-graph-2d" import { securedFetch } from "@/lib/utils" +import { useToast } from "@/components/ui/use-toast" import { Graph, GraphData, Link, Node } from "../api/graph/model" interface Props { graph: Graph // eslint-disable-next-line @typescript-eslint/no-explicit-any - chartRef: RefObject + chartRef: RefObject data: GraphData selectedElement: Node | Link | undefined setSelectedElement: (element: Node | Link | undefined) => void selectedElements: (Node | Link)[] setSelectedElements: Dispatch> - cooldownTime: number | undefined cooldownTicks: number | undefined - setCooldownTicks: Dispatch> + handleCooldown: (ticks?: number) => void type?: "schema" | "graph" isAddElement?: boolean setSelectedNodes?: Dispatch> + isCollapsed: boolean } - - const NODE_SIZE = 6 const PADDING = 2; @@ -38,17 +38,32 @@ export default function ForceGraph({ setSelectedElement, selectedElements, setSelectedElements, - cooldownTime, cooldownTicks, - setCooldownTicks, + handleCooldown, type = "graph", isAddElement = false, setSelectedNodes, + isCollapsed }: Props) { const [parentWidth, setParentWidth] = useState(0) const [parentHeight, setParentHeight] = useState(0) const [hoverElement, setHoverElement] = useState() + const parentRef = useRef(null) + const toast = useToast() + + useEffect(() => { + if (!chartRef.current || data.nodes.length === 0 || data.links.length === 0) return + chartRef.current.d3Force('link').id((link: any) => link.id).distance(50) + chartRef.current.d3Force('charge').strength(-300) + chartRef.current.d3Force('center').strength(0.05) + }, [chartRef, data.links.length, data.nodes.length]) + + useEffect(() => { + if (!parentRef.current) return + setParentWidth(parentRef.current.clientWidth) + setParentHeight(parentRef.current.clientHeight) + }, [parentRef.current?.clientWidth, parentRef.current?.clientHeight, isCollapsed]) const onFetchNode = async (node: Node) => { const result = await securedFetch(`/api/graph/${graph.Id}/${node.id}`, { @@ -56,7 +71,7 @@ export default function ForceGraph({ headers: { 'Content-Type': 'application/json' } - }); + }, toast); if (result.ok) { const json = await result.json() @@ -90,7 +105,7 @@ export default function ForceGraph({ graph.removeLinks() } - const handelNodeRightClick = async (node: Node) => { + const handleNodeRightClick = async (node: Node) => { if (!node.expand) { await onFetchNode(node) } else { @@ -98,7 +113,7 @@ export default function ForceGraph({ } } - const handelHover = (element: Node | Link | null) => { + const handleHover = (element: Node | Link | null) => { setHoverElement(element === null ? undefined : element) } @@ -138,16 +153,13 @@ export default function ForceGraph({ } return ( -
{ - if (!ref) return - setParentWidth(ref.clientWidth) - setParentHeight(ref.clientHeight) - }} className="w-full h-full relative"> +
node.data.name || node.id.toString()} graphData={data} nodeRelSize={NODE_SIZE} nodeCanvasObjectMode={() => 'after'} @@ -157,10 +169,10 @@ export default function ForceGraph({ nodeCanvasObject={(node, ctx) => { if (!node.x || !node.y) return - ctx.lineWidth = (selectedElement && !("source" in selectedElement) && selectedElement.id === node.id - || hoverElement && !("source" in hoverElement) && hoverElement.id === node.id) ? 1 : 0.5 - ctx.fillStyle = node.color; - ctx.strokeStyle = 'black'; + ctx.lineWidth = ((selectedElement && !("source" in selectedElement) && selectedElement.id === node.id) + || (hoverElement && !("source" in hoverElement) && hoverElement.id === node.id) + || (selectedElements.length > 0 && selectedElements.some(el => el.id === node.id && !("source" in el)))) ? 1 : 0.5 + ctx.strokeStyle = 'white'; ctx.beginPath(); ctx.arc(node.x, node.y, NODE_SIZE, 0, 2 * Math.PI, false); @@ -171,13 +183,18 @@ export default function ForceGraph({ ctx.fillStyle = 'black'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; - ctx.font = '4px Arial'; + ctx.font = '3px Arial'; const ellipsis = '...'; const ellipsisWidth = ctx.measureText(ellipsis).width; const nodeSize = NODE_SIZE * 2 - PADDING; - let { name } = type === "graph" - ? { ...node.data } - : { name: node.category[0] } + + let name + + if (type === "graph") { + name = node.data.name || node.id.toString() + } else { + [name] = node.category + } // truncate text if it's too long if (ctx.measureText(name).width > nodeSize) { @@ -199,20 +216,7 @@ export default function ForceGraph({ ctx.strokeStyle = link.color; ctx.globalAlpha = 0.5; - const sameNodesLinks = graph.Elements.links.filter(l => (l.source.id === start.id && l.target.id === end.id) || (l.target.id === start.id && l.source.id === end.id)) - const index = sameNodesLinks.findIndex(l => l.id === link.id) || 0 - const even = index % 2 === 0 - let curve - if (start.id === end.id) { - if (even) { - curve = Math.floor(-(index / 2)) - 3 - } else { - curve = Math.floor((index + 1) / 2) + 2 - } - - link.curve = curve * 0.1 - const radius = NODE_SIZE * link.curve * 6.2; const angleOffset = -Math.PI / 4; // 45 degrees offset for text alignment const textX = start.x + radius * Math.cos(angleOffset); @@ -222,14 +226,6 @@ export default function ForceGraph({ ctx.translate(textX, textY); ctx.rotate(-angleOffset); } else { - if (even) { - curve = Math.floor(-(index / 2)) - } else { - curve = Math.floor((index + 1) / 2) - } - - link.curve = curve * 0.1 - const midX = (start.x + end.x) / 2 + (end.y - start.y) * (link.curve / 2); const midY = (start.y + end.y) / 2 + (start.x - end.x) * (link.curve / 2); @@ -249,25 +245,25 @@ export default function ForceGraph({ ctx.fillStyle = 'black'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; - ctx.font = '2px Arial'; + ctx.font = "2px Arial" ctx.fillText(link.label, 0, 0); ctx.restore() }} onNodeClick={handleClick} onLinkClick={handleClick} - onNodeHover={handelHover} - onLinkHover={handelHover} - onNodeRightClick={handelNodeRightClick} + onNodeHover={handleHover} + onLinkHover={handleHover} + onNodeRightClick={handleNodeRightClick} onBackgroundClick={handleUnselected} onBackgroundRightClick={handleUnselected} onEngineStop={() => { - setCooldownTicks(0) + handleCooldown(0) }} linkCurvature="curve" nodeVisibility="visible" linkVisibility="visible" cooldownTicks={cooldownTicks} - cooldownTime={cooldownTime} + cooldownTime={2000} />
) diff --git a/app/components/FormComponent.tsx b/app/components/FormComponent.tsx new file mode 100644 index 00000000..fd7af685 --- /dev/null +++ b/app/components/FormComponent.tsx @@ -0,0 +1,153 @@ +/* eslint-disable react/no-array-index-key */ +/* eslint-disable no-param-reassign */ + +"use client" + +import { useState } from "react" +import { AlertCircle, EyeIcon, EyeOffIcon } from "lucide-react" +import { cn } from "@/lib/utils" +import Button from "./ui/Button" +import Combobox from "./ui/combobox" +import Input from "./ui/Input" + +export type Error = { + message: string + condition: (value: string) => boolean +} + +export type Field = { + label: string + value: string + onChange?: (e: React.ChangeEvent) => void + type: string + info?: string + options?: string[] + onSelectedValue?: (value: string) => void + placeholder?: string + required: boolean + show?: boolean + description?: string + errors?: Error[] +} + +interface Props { + handleSubmit: (e: React.FormEvent) => void + fields: Field[] + error?: { + message: string + show: boolean + } + children?: React.ReactNode + submitButtonLabel?: string +} + +export default function FormComponent({ handleSubmit, fields, error = undefined, children = undefined, submitButtonLabel = "Submit" }: Props) { + const [show, setShow] = useState<{ [key: string]: boolean }>({}); + const [errors, setErrors] = useState<{ [key: string]: boolean }>({}); + + const onHandleSubmit = (e: React.FormEvent) => { + e.preventDefault() + + const newErrors: { [key: string]: boolean } = {} + + fields.forEach(field => { + if (field.errors) { + newErrors[field.label] = field.errors.some(err => err.condition(field.value)) + } + }) + + setErrors(newErrors) + + if (Object.values(newErrors).some(value => value)) return + + handleSubmit(e) + } + + return ( +
+ { + fields.map((field) => { + const passwordType = show[field.label] ? "text" : "password" + return ( +
+
+ + { + field.info && + + } +
+
+ { + field.type === "password" && + + } + { + field.type === "select" ? + + : { + field.onChange!(e) + if (field.errors) { + setErrors(prev => ({ + ...prev, + [field.label]: field.errors!.some(err => err.condition(e.target.value)) + })) + } + }} /> + } +

{field.description}

+ { + field.errors && errors[field.label] ? +

{field.errors.find((err) => err.condition(field.value))?.message}

+ :

+ } +

+
+ ) + }) + } + {children} + {error?.show &&

{error.message}

} +
+
+
+ ) +} + +FormComponent.defaultProps = { + children: undefined, + error: undefined, + submitButtonLabel: "Submit" +} \ No newline at end of file diff --git a/app/components/Header.tsx b/app/components/Header.tsx index 69c22976..66c05915 100644 --- a/app/components/Header.tsx +++ b/app/components/Header.tsx @@ -1,198 +1,103 @@ +/* eslint-disable react/require-default-props */ + 'use client' -// import { Dialog, DialogClose, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; -import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from "@/components/ui/dropdown-menu"; -import { LifeBuoy, PlusCircle, Settings } from "lucide-react"; -import { FormEvent, useState } from "react"; +import { LifeBuoy, LogOut, Settings } from "lucide-react"; +import { Dispatch, SetStateAction } from "react"; import Image from "next/image"; -import { Toast, cn, prepareArg, securedFetch } from "@/lib/utils"; +import { cn } from "@/lib/utils"; import { useRouter, usePathname } from "next/navigation"; -import { Role } from "next-auth"; -import { Dialog, DialogTrigger } from "@/components/ui/dialog"; +import { signOut, useSession } from "next-auth/react"; +import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger } from "@/components/ui/navigation-menu"; import Button from "./ui/Button"; -import Avatar from "./ui/Avatar"; -import DialogComponent from "./DialogComponent"; -import Input from "./ui/Input"; +import CreateGraph from "./CreateGraph"; -/* eslint-disable react/require-default-props */ interface Props { - inCreate?: boolean - onSetGraphName?: (graphName: string) => void + onSetGraphName?: Dispatch> } -export default function Header({ inCreate = false, onSetGraphName }: Props) { - const [helpOpen, setHelpOpen] = useState(false) - const [createOpen, setCreateOpen] = useState(false) +export default function Header({ onSetGraphName }: Props) { const router = useRouter() const pathname = usePathname() - const [userStatus, setUserStatus] = useState() - const [graphName, setGraphName] = useState("") const type = pathname.includes("/schema") ? "Schema" : "Graph" - - const handelCreateGraph = async (e: FormEvent) => { - - if (!onSetGraphName) return - - e.preventDefault() - - const name = `${graphName}${type === "Schema" ? "_schema" : ""}` - - const q = `RETURN 1` - const result = await securedFetch(`api/graph/${prepareArg(name)}/?query=${prepareArg(q)}`, { - method: "GET" - }) - - if (result.ok) { - Toast(`${type} ${graphName} created successfully!`, "Success") - onSetGraphName(graphName) - setCreateOpen(false) - setGraphName("") - } - } - + const inCreate = pathname.includes("/create") + const { data: session } = useSession() + return (
-
-
+
- +

|

-
+
-
- { - !inCreate && - - +
+ + + + + + + +

Help

+
+ + + +
+ { + !inCreate && + - - -
-
-

Name:

- ref?.focus()} - variant="Default" - value={graphName} - onChange={(e) => setGraphName(e.target.value)} - /> -
-
- } - {/* - - - - - Create New Graph - - - - - - do you want to upload data or empty graph ? - -
- - -

Upload Data

-
-
- - - -
-
-
*/} - - + } + +
+
) } diff --git a/app/components/TableComponent.tsx b/app/components/TableComponent.tsx new file mode 100644 index 00000000..75162630 --- /dev/null +++ b/app/components/TableComponent.tsx @@ -0,0 +1,224 @@ +/* eslint-disable react/no-array-index-key */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable no-nested-ternary */ +/* eslint-disable react/require-default-props */ + +"use client" + +import { Checkbox } from "@/components/ui/checkbox"; +import { JSONTree } from "react-json-tree" +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; +import { cn } from "@/lib/utils"; +import { useState } from "react"; +import { CheckCircle, Pencil, XCircle } from "lucide-react"; +import Button from "./ui/Button"; +import Input from "./ui/Input"; +import { DataCell } from "../api/graph/model"; + +type Cell = { + value: DataCell, + onChange?: (value: string) => Promise +} + +export interface Row { + cells: Cell[] + checked?: boolean +} + +interface Props { + headers: string[], + rows: Row[], + children?: React.ReactNode, + setRows?: (rows: Row[]) => void +} + +export default function TableComponent({ headers, rows, children, setRows }: Props) { + + const [search, setSearch] = useState("") + const [isSearchable, setIsSearchable] = useState(false) + const [editable, setEditable] = useState("") + const [hover, setHover] = useState("") + const [newValue, setNewValue] = useState("") + + const handleSetEditable = (editValue: string, value: string) => { + setEditable(editValue) + setNewValue(value) + } + + return ( +
+
+ {children} + { + isSearchable ? + ref?.focus()} + variant="primary" + className="grow" + value={search} + type="text" + placeholder="Search for" + onBlur={() => setIsSearchable(false)} + onKeyDown={(e) => { + if (e.key === "Escape") { + e.preventDefault() + setIsSearchable(false) + setSearch("") + } + + if (e.key !== "Enter") return + e.preventDefault() + setIsSearchable(false) + }} + onChange={(e) => setSearch(e.target.value)} + /> + :
+ + + + { + setRows ? + + 0 && rows.every(row => row.checked)} + onCheckedChange={() => { + const checked = !rows.every(row => row.checked) + setRows(rows.map(row => ({ ...row, checked }))) + }} + /> + + : null + } + { + headers.map((header, i) => ( + + {header} + + )) + } + + + + { + rows + .filter((row) => typeof row.cells[0].value === "string" ? row.cells[0].value.toLowerCase().includes(search.toLowerCase()) : !search) + .map((row, i) => ( + setHover(`${i}`)} onMouseLeave={() => setHover("")} data-id={typeof row.cells[0].value === "string" && row.cells[0].value} key={i}> + { + setRows ? + + { + setRows(rows.map((r, k) => k === i ? ({ ...r, checked: !r.checked }) : r)) + }} + /> + + : null + } + { + row.cells.map((cell, j) => ( + + { + typeof cell.value === "object" ? + false} + keyPath={[headers[j]]} + theme={{ + base00: "var(--background)", // background + base01: '#000000', + base02: '#CE9178', + base03: '#CE9178', // open values + base04: '#CE9178', + base05: '#CE9178', + base06: '#CE9178', + base07: '#CE9178', + base08: '#CE9178', + base09: '#b5cea8', // numbers + base0A: '#CE9178', + base0B: '#CE9178', // close values + base0C: '#CE9178', + base0D: '#99E4E5', // * keys + base0E: '#ae81ff', + base0F: '#cc6633' + }} + data={cell.value} + /> + : cell.value && + editable === `${i}-${j}` ? +
+ ref?.focus()} + variant="primary" + className="grow" + value={newValue} + onChange={(e) => setNewValue(e.target.value)} + onKeyDown={async (e) => { + if (e.key === "Escape") { + e.preventDefault() + handleSetEditable("", "") + } + + if (e.key !== "Enter") return + + e.preventDefault() + const result = await cell.onChange!(newValue) + if (result) { + handleSetEditable("", "") + } + }} + /> +
+ + +
+
+ :
+

{cell.value}

+
+ { + cell.onChange && hover === `${i}` && + + } +
+
+ } +
+ )) + } +
+ )) + } +
+
+
+ ) +} \ No newline at end of file diff --git a/app/components/ToastButton.tsx b/app/components/ToastButton.tsx new file mode 100644 index 00000000..fe1f5b96 --- /dev/null +++ b/app/components/ToastButton.tsx @@ -0,0 +1,17 @@ +import { ToastAction } from "@/components/ui/toast"; +import { Undo } from "lucide-react"; +import Button from "./ui/Button"; + +interface Props extends React.HTMLAttributes { + onClick: () => void +} + +export default function ToastButton({ onClick }: Props) { + return ( + + + + ) +} \ No newline at end of file diff --git a/app/components/graph/DeleteGraph.tsx b/app/components/graph/DeleteGraph.tsx index 406b2372..7f0de3ff 100644 --- a/app/components/graph/DeleteGraph.tsx +++ b/app/components/graph/DeleteGraph.tsx @@ -1,5 +1,6 @@ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog"; -import { Toast, prepareArg, securedFetch } from "@/lib/utils"; +import { useToast } from "@/components/ui/use-toast"; +import { prepareArg, securedFetch } from "@/lib/utils"; export default function DeleteGraph({ graphName, isOpen, onOpen, onDeleteGraph, isSchema }: { graphName: string @@ -10,15 +11,19 @@ export default function DeleteGraph({ graphName, isOpen, onOpen, onDeleteGraph, }) { const type = isSchema ? "Schema" : "Graph" - + const { toast } = useToast() + const deleteGraph = async () => { const name = `${graphName}${isSchema ? "_schema" : ""}` const result = await securedFetch(`/api/graph/${prepareArg(name)}`, { method: "DELETE", - }); + }, toast); if (result.ok) { - Toast(`${type} ${graphName} deleted`, "Success") + toast({ + title: "Success", + description: `${type} ${graphName} deleted`, + }) onDeleteGraph(graphName) } } diff --git a/app/components/graph/UploadGraph.tsx b/app/components/graph/UploadGraph.tsx index ad83acab..090fd07f 100644 --- a/app/components/graph/UploadGraph.tsx +++ b/app/components/graph/UploadGraph.tsx @@ -1,7 +1,6 @@ -import { Dialog, DialogTrigger } from "@/components/ui/dialog"; +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; import { useState } from "react"; import Dropzone from "../ui/Dropzone"; -import DialogComponent from "../DialogComponent"; import Button from "../ui/Button"; import CloseDialog from "../CloseDialog"; @@ -29,15 +28,20 @@ export default function UploadGraph({ disabled, open, onOpenChange }: { /> } - + + + Upload Data + +
- -
+ ) } \ No newline at end of file diff --git a/app/components/node/DeleteNode.tsx b/app/components/node/DeleteNode.tsx deleted file mode 100644 index 4d670f73..00000000 --- a/app/components/node/DeleteNode.tsx +++ /dev/null @@ -1,53 +0,0 @@ -'use client'; - -import { Toast } from "@/lib/utils"; -import { Trash2 } from "lucide-react"; -import { Dialog, DialogClose, DialogTrigger } from "@/components/ui/dialog"; -import Button from "../ui/Button"; -import DialogComponent from "../DialogComponent"; - -/* eslint-disable react/require-default-props */ -interface Props { - disabled?: boolean - onDelete: () => void -} - -export default function DeleteNode({ disabled, onDelete }: Props) { - - const onDeleteNode = async () => { - onDelete() - Toast("Success", "Node deleted") - } - - return ( - - - - - -
- -
-
-
- ) -} \ No newline at end of file diff --git a/app/components/ui/Avatar.tsx b/app/components/ui/Avatar.tsx deleted file mode 100644 index 09fa6eab..00000000 --- a/app/components/ui/Avatar.tsx +++ /dev/null @@ -1,50 +0,0 @@ -'use client'; - -import { useSession, signIn, signOut } from "next-auth/react" -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu" -import { Role } from "next-auth"; -import { useEffect } from "react"; -import Button from "./Button"; - -export default function AvatarButton({ setUserStatus }: { setUserStatus: (status: Role) => void }) { - const { data: session, status } = useSession() - useEffect(() => { - setUserStatus(session?.user.role || "Read-Only") - }, [session, setUserStatus]) - - if (status === "unauthenticated" || !session) { - return ( - )) diff --git a/app/components/ui/Dropzone.tsx b/app/components/ui/Dropzone.tsx index 86e8bd9c..93426311 100644 --- a/app/components/ui/Dropzone.tsx +++ b/app/components/ui/Dropzone.tsx @@ -61,7 +61,7 @@ function Dropzone({ filesCount = false, className = "", withTable = false, disab
{ withTable && -
+
{`Uploaded Files ${filesCount ? `(${files.length})`: ''}`}
diff --git a/app/components/ui/Input.tsx b/app/components/ui/Input.tsx index 8de68d18..03df10f7 100644 --- a/app/components/ui/Input.tsx +++ b/app/components/ui/Input.tsx @@ -1,24 +1,33 @@ -import { cn } from "@/lib/utils" -import { forwardRef } from "react" +/* eslint-disable react/require-default-props */ +/* eslint-disable react/jsx-props-no-spreading */ + +"use client" + +import { cn } from "@/lib/utils"; +import { forwardRef } from "react"; interface Props extends React.InputHTMLAttributes { - variant: "Default" | "Small" + variant?: "primary" | "secondary" | "default"; + className?: string; } -const Input = forwardRef(({ variant, className, ...props }: Props, ref) => ( - -)) +const Input = forwardRef(({ + variant = "default", + className, + ...props +}, ref) => ( + + )) Input.displayName = "Input" diff --git a/app/components/ui/combobox.tsx b/app/components/ui/combobox.tsx index 030dcae7..8ccf2e20 100644 --- a/app/components/ui/combobox.tsx +++ b/app/components/ui/combobox.tsx @@ -1,254 +1,170 @@ +/* eslint-disable @typescript-eslint/no-use-before-define */ +/* eslint-disable react/require-default-props */ + "use client" -import { Dialog, DialogTrigger } from "@/components/ui/dialog" -import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "@/components/ui/dropdown-menu" -import { Toast, cn, prepareArg, securedFetch } from "@/lib/utils" -import { Trash2, UploadIcon } from "lucide-react" -import { Dispatch, SetStateAction, useEffect, useState } from "react" -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" -import UploadGraph from "../graph/UploadGraph" -import DeleteGraph from "../graph/DeleteGraph" +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog" +import { cn, prepareArg, securedFetch } from "@/lib/utils" +import { useEffect, useState } from "react" +import { Select, SelectContent, SelectGroup, SelectItem, SelectSeparator, SelectTrigger, SelectValue } from "@/components/ui/select" +import { useToast } from "@/components/ui/use-toast" import Button from "./Button" +import TableComponent, { Row } from "../TableComponent" +import CloseDialog from "../CloseDialog" +import ExportGraph from "../ExportGraph" import DialogComponent from "../DialogComponent" -import Input from "./Input" -/* eslint-disable react/require-default-props */ interface ComboboxProps { isSelectGraph?: boolean, disabled?: boolean, inTable?: boolean, type?: string | undefined, options: string[], - setOptions?: Dispatch>, + setOptions?: (value: string[]) => void, selectedValue?: string, - setSelectedValue: (value: string) => void, + setSelectedValue?: (value: string) => void, isSchema?: boolean defaultOpen?: boolean onOpenChange?: (open: boolean) => void - setReload?: Dispatch> } -export default function Combobox({ isSelectGraph, disabled = false, inTable, type, options, setOptions, selectedValue = "", setSelectedValue, isSchema = false, defaultOpen = false, onOpenChange, setReload }: ComboboxProps) { +export default function Combobox({ isSelectGraph = false, disabled = false, inTable, type, options, setOptions, selectedValue = "", setSelectedValue, isSchema = false, defaultOpen = false, onOpenChange }: ComboboxProps) { - const [openDialog, setOpenDialog] = useState(false) + const [openMenage, setOpenMenage] = useState(false) const [open, setOpen] = useState(defaultOpen) - const [optionName, setOptionName] = useState("") - const [editable, setEditable] = useState("") - const [isUploadOpen, setIsUploadOpen] = useState() - const [isDeleteOpen, setIsDeleteOpen] = useState() - - useEffect(() => { - if (options.length !== 1) return - setSelectedValue(options[0]) - }, [options]) - - const onExport = async (graphName: string) => { - const result = await securedFetch(`api/graph/${prepareArg(graphName)}/export`, { - method: "GET" - }) - - if (!result.ok) return - - const blob = await result.blob() - const url = window.URL.createObjectURL(blob) - try { - const link = document.createElement('a') - link.href = url - link.setAttribute('download', `${selectedValue}.dump`) - document.body.appendChild(link) - link.click() - link.parentNode?.removeChild(link) - window.URL.revokeObjectURL(url) - } catch (e) { - Toast((e as Error).message) - } - } + const [rows, setRows] = useState([]) + const [openDelete, setOpenDelete] = useState(false) + const { toast } = useToast() - const handelDelete = (option: string) => { - if (!setOptions) return - setOptions(prev => prev.filter(name => name !== option)) - if (selectedValue !== option) return - setSelectedValue("") - setOpenDialog(false) - } - - const handelSetOption = async (e: React.KeyboardEvent, option: string) => { - if (!setOptions) return - if (e.key !== "Enter") return - const result = await securedFetch(`api/graph/${prepareArg(optionName)}/?sourceName=${prepareArg(option)}`, { + const handleSetOption = async (option: string, optionName: string) => { + const result = await securedFetch(`api/graph/${prepareArg(option)}/?sourceName=${prepareArg(optionName)}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: optionName }) - }) + }, toast) + + if (result.ok) { + + const newOptions = options.map((opt) => opt === optionName ? option : opt) + setOptions!(newOptions) + + if (setSelectedValue && optionName === selectedValue) setSelectedValue(option) - if (!result.ok) { - const json = await result.json() - Toast(json.message) - return + handleSetRows(newOptions) } - const newOptions = options.map((opt) => opt === option ? optionName : opt) - setOptions(newOptions) - setSelectedValue(optionName) - setEditable("") + return result.ok + } + + const handleSetRows = (opts: string[]) => { + setRows(opts.map(opt => ({ checked: false, name: opt, cells: [{ value: opt, onChange: (value: string) => handleSetOption(value, opt) }] }))) + } + + useEffect(() => { + handleSetRows(options) + + if (options.length !== 1 || !setSelectedValue) return + + setSelectedValue(options[0]) + }, [options]) + + const handleDelete = async (opts: string[]) => { + const names = opts.map(opt => isSchema ? `${opt}_schema` : opt) + + const newNames = await Promise.all(names.map(async (name) => { + const result = await securedFetch(`api/graph/${prepareArg(name)}`, { + method: "DELETE" + }, toast) + + if (!result.ok) return name + + return "" + + })).then(graphNames => graphNames.filter(name => name !== "")) + + setOptions!(newNames) + + if (opts.includes(selectedValue) && setSelectedValue) setSelectedValue("") + + setOpenDelete(false) + setOpenMenage(false) + handleSetRows(options.filter(opt => !opts.includes(opt))) } return ( - - { + + ref?.focus()} - value={optionName} - onChange={(e) => setOptionName(e.target.value)} - onBlur={() => setEditable("")} - onKeyDown={(e) => handelSetOption(e, option)} - /> - : option - } - - -
- + + + + + Manage Graphs + + + + opt.checked).length === 0} + label="Delete" + />} + description="Are you sure you want to delete the selected graph?" + > +
+
+
+ opt.checked).map(opt => opt.cells[0].value as string)} type={type!} /> +
+
) } \ No newline at end of file diff --git a/app/create/page.tsx b/app/create/page.tsx index 62376379..7f24880a 100644 --- a/app/create/page.tsx +++ b/app/create/page.tsx @@ -5,7 +5,8 @@ import { FormEvent, useEffect, useState } from "react"; import { useRouter } from "next/navigation"; import { Progress } from "@/components/ui/progress"; import useSWR from "swr"; -import { Toast, prepareArg, securedFetch } from "@/lib/utils"; +import { prepareArg, securedFetch } from "@/lib/utils"; +import { useToast } from "@/components/ui/use-toast"; import Header from "../components/Header"; import Input from "../components/ui/Input"; import Button from "../components/ui/Button"; @@ -26,6 +27,7 @@ export default function Create() { const [progress, setProgress] = useState(0) const [openaiKey, setOpenaiKey] = useState("") const router = useRouter() + const { toast } = useToast() useEffect(() => { if (progress !== 100) return @@ -34,10 +36,14 @@ export default function Create() { const res = await securedFetch(`api/graph/${prepareArg(graphName)}_schema/?query=${prepareArg(q)}`, { method: "GET" - }) + }, toast) if (!res.ok) { - Toast() + toast({ + title: "Error", + description: "Error while loading schema", + variant: "destructive" + }) setProgress(0) setCurrentTab(null) setFilesPath([]) @@ -47,7 +53,11 @@ export default function Create() { const j = await res.json() if (!j.result.data.length) { - Toast() + toast({ + title: "Error", + description: "Error while loading schema", + variant: "destructive" + }) setProgress(0) setCurrentTab(null) setFilesPath([]) @@ -65,10 +75,14 @@ export default function Create() { const result = await securedFetch(url, { method: "GET", - }) + }, toast) if (!result.ok) { - Toast() + toast({ + title: "Error", + description: "Error while loading schema", + variant: "destructive" + }) return } @@ -95,10 +109,14 @@ export default function Create() { const result = await securedFetch(`api/upload`, { method: "POST", body: formData - }); + }, toast); if (!result.ok) { - Toast() + toast({ + title: "Error", + description: "Error while uploading file", + variant: "destructive" + }) return "" } @@ -115,11 +133,15 @@ export default function Create() { "Content-Type": "application/json" }, body: JSON.stringify(newFilesPath) - }) + }, toast) if (!result.ok) { - Toast() + toast({ + title: "Error", + description: "Error while creating schema", + variant: "destructive" + }) setFilesPath([]) setProgress(0) setCurrentTab(null) @@ -136,10 +158,14 @@ export default function Create() { const result = await securedFetch(`api/graph/${prepareArg(graphName)}/?type=populate_kg/?key=${prepareArg(openaiKey)}`, { method: "POST", body: JSON.stringify(filesPath) - }) + }, toast) if (!result.ok) { - Toast() + toast({ + title: "Error", + description: "Error while creating graph", + variant: "destructive" + }) return } setCurrentTab("graph") @@ -158,7 +184,6 @@ export default function Create() { // }) // if (!ok) { - // Toast("Failed to set label") // return ok // } @@ -199,7 +224,7 @@ export default function Create() { onClick={() => setCurrentTab(null)} />
) @@ -298,7 +326,7 @@ export default function Create() { return (
-
+

Create New Graph

diff --git a/app/globals.css b/app/globals.css index ac686b04..830ec076 100644 --- a/app/globals.css +++ b/app/globals.css @@ -4,14 +4,17 @@ @layer base { :root { - --background: 240 28% 21%; - --foreground: 0 0% 100%; - --popover: 240 28% 21%; + --background: 0 0% 14%; + --foreground: 0 0% 10%; + --primary: 243 91% 68%; + --secondary: 39 33% 96%; + --destructive: 0 84% 60%; + --accent: var(--background); + --popover: var(--primary); --popover-foreground: 0 0% 100%; - --secondary: 240 17% 41%; - --primary: 244 89% 68%; --radius: 0.5rem; - --muted: 0 0% 100%; + --input: var(--popover-foreground); + --muted: 0 0% 80%; } :focus-visible { @@ -27,8 +30,20 @@ @layer components { + @font-face { + font-family: 'Fira Code'; + src: url('/fonts/fira_code.ttf') format('truetype'); + font-display: swap; + } + + @font-face { + font-family: 'Oswald'; + src: url('/fonts/oswald.ttf') format('truetype'); + font-display: swap; + } + .tabs-trigger { - @apply !p-3 rounded-lg hover:bg-[#444466] bg-[#57577B] data-[state=active]:!bg-[#444466] data-[state=active]:font-bold; + @apply !p-2 rounded-lg data-[state=active]:bg-foreground data-[state=active]:!text-white !text-white; } .hide-scrollbar { @@ -49,41 +64,30 @@ background: linear-gradient(180deg, #EC806C 0%, #B66EBD 43.41%, #7568F2 100%); } - .LoginForm { - background: linear-gradient(180deg, #EC806C 0%, #B66EBD 43.41%, #7568F2 100%); - color: white; - } - - .LoginForm>form>p { - font-family: "Obviously Narrow" !important; - } - - .Text { - background: linear-gradient(90deg, #EC806C 0%, #B66EBD 43.41%, #7568F2 100%); - background-clip: text; - color: transparent; - } - .Top { background: linear-gradient(90deg, #EC806C 0%, #B66EBD 43.41%, #7568F2 100%); } - .Header { - @apply bg-white text-black - } - .DataPanel { @apply h-full w-full flex flex-col shadow-lg; - background-color: #434366; + background-color: #232323; } - + .Dropzone { display: flex; flex: 1 1 0%; - background-color: #434366; + background-color: #232323; align-items: center; justify-content: center; } + + .Secondary { + border-image: linear-gradient(90deg, #EC806C 0%, #B66EBD 43.41%, #7568F2 100%) 1; + } + + .monaco-placeholder { + @apply text-[#666] absolute select-none top-2 left-2; + } } input[type="number"]::-webkit-outer-spin-button, @@ -101,17 +105,31 @@ input[type="number"] { margin-top: 0.5rem; } -@font-face { - font-family: 'Obviously Narrow'; - src: url('/fonts/obviously_narrow.woff2') format('woff2'), - url('/fonts/obviously_narrow.woff') format('woff'); +* { + font-family: font-FiraCode, 'monospace'; } -@font-face { - font-family: 'Fira Code'; - src: url('/fonts/fira_code.ttf') format('truetype'), +.Title { + font-family: font-Oswald, 'monospace'; } -* { - font-family: 'Fira Code'; -} \ No newline at end of file + +::-webkit-scrollbar { + width: 20px; + height: 20px; + } + + ::-webkit-scrollbar-corner { + background-color: transparent; + } + + ::-webkit-scrollbar-thumb { + background-color: #d6dee1; + border-radius: 20px; + border: 6px solid transparent; + background-clip: content-box; + } + + ::-webkit-scrollbar-thumb:hover { + background-color: #a8bbbf; + } \ No newline at end of file diff --git a/app/graph/DeleteElement.tsx b/app/graph/DeleteElement.tsx new file mode 100644 index 00000000..c3d870eb --- /dev/null +++ b/app/graph/DeleteElement.tsx @@ -0,0 +1,48 @@ +/* eslint-disable react/require-default-props */ + +"use client" + +import CloseDialog from "../components/CloseDialog"; +import DialogComponent from "../components/DialogComponent"; +import Button from "../components/ui/Button"; + +interface Props { + onDeleteElement: () => void + trigger: React.ReactNode + open: boolean + setOpen: (open: boolean) => void + description: string +} + +export default function DeleteElement({ + onDeleteElement, + trigger, + open, + setOpen, + description, +}: Props) { + + return ( + +
+
+
+ ) +} \ No newline at end of file diff --git a/app/graph/Duplicate.tsx b/app/graph/Duplicate.tsx index 92f83f10..f39ae8dd 100644 --- a/app/graph/Duplicate.tsx +++ b/app/graph/Duplicate.tsx @@ -1,51 +1,58 @@ import { FormEvent, useState } from "react"; -import { Toast, prepareArg, securedFetch } from "@/lib/utils"; -import { Dialog } from "@/components/ui/dialog"; +import { prepareArg, securedFetch } from "@/lib/utils"; +import { useToast } from "@/components/ui/use-toast"; import DialogComponent from "../components/DialogComponent"; -import Input from "../components/ui/Input"; import Button from "../components/ui/Button"; +import Input from "../components/ui/Input"; -export default function Duplicate({ open, onOpenChange, selectedValue, onDuplicate }: { +export default function Duplicate({ open, onOpenChange, selectedValue, onDuplicate, disabled }: { selectedValue: string, open: boolean, onOpenChange: (open: boolean) => void onDuplicate: (duplicateName: string) => void + disabled: boolean }) { const [duplicateName, setDuplicateName] = useState(""); - - const handelDuplicate = async (e: FormEvent) => { + const { toast } = useToast() + + const handleDuplicate = async (e: FormEvent) => { e.preventDefault() - const result = await securedFetch(`api/graph/${prepareArg(duplicateName)}/?sourceName=${prepareArg(selectedValue)}`, { + await securedFetch(`api/graph/${prepareArg(duplicateName)}/?sourceName=${prepareArg(selectedValue)}`, { method: "POST" - }) - - if (!result.ok) { - Toast() - return - } + }, toast) onOpenChange(false) onDuplicate(duplicateName) } return ( - - -
-
-

Graph Name

- setDuplicateName(e.target.value)} required /> -
+ } + className="w-[25%]" + description="Enter a new graph name" + title="Duplicate Graph" + > + +
+

Graph Name

+ setDuplicateName(e.target.value)} + required + /> +
+
+
+ + ) } \ No newline at end of file diff --git a/app/graph/GraphDataPanel.tsx b/app/graph/GraphDataPanel.tsx index 16497566..abe0c406 100644 --- a/app/graph/GraphDataPanel.tsx +++ b/app/graph/GraphDataPanel.tsx @@ -1,22 +1,29 @@ -'use client' - +/* eslint-disable @typescript-eslint/no-use-before-define */ /* eslint-disable no-param-reassign */ +/* eslint-disable react/require-default-props */ + +'use client' -import { prepareArg, securedFetch, Toast } from "@/lib/utils"; +import { prepareArg, securedFetch } from "@/lib/utils"; import { Dispatch, SetStateAction, useEffect, useState } from "react"; -import { Check, ChevronRight, MinusCircle, Pencil, PlusCircle, Trash2, X } from "lucide-react"; +import { Check, ChevronRight, Pencil, Plus, Trash2, X } from "lucide-react"; import { Session } from "next-auth"; +import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; +import { useToast } from "@/components/ui/use-toast"; import Button from "../components/ui/Button"; -import Input from "../components/ui/Input"; import { Graph, Link, Node } from "../api/graph/model"; +import Input from "../components/ui/Input"; +import DialogComponent from "../components/DialogComponent"; +import CloseDialog from "../components/CloseDialog"; +import DeleteElement from "./DeleteElement"; +import ToastButton from "../components/ToastButton"; -/* eslint-disable react/require-default-props */ interface Props { obj: Node | Link; setObj: Dispatch>; onExpand: () => void; graph: Graph; - onDeleteElement?: () => Promise; + onDeleteElement: () => Promise; data: Session | null; } @@ -26,28 +33,48 @@ export default function GraphDataPanel({ obj, setObj, onExpand, onDeleteElement, const [editable, setEditable] = useState(""); const [hover, setHover] = useState(""); const [isAddValue, setIsAddValue] = useState(false); + const [deleteOpen, setDeleteOpen] = useState(false) const [newKey, setNewKey] = useState(""); const [newVal, setNewVal] = useState(""); const [label, setLabel] = useState([""]); const type = !("source" in obj) + const { toast } = useToast() + + const handleSetEditable = (key: string, val: string) => { + if (key !== "") { + setIsAddValue(false) + } + + setEditable(key) + setNewVal(val) + } useEffect(() => { setAttributes(Object.keys(obj.data).filter((key) => (key !== "name" || obj.data.name !== obj.id))); setLabel(type ? obj.category : [obj.label]); }, [obj, type]); - const setProperty = async (key: string, val: string) => { + const setProperty = async (key: string, val: string, isUndo: boolean, actionType: ("added" | "set") = "set") => { const { id } = obj + if (!val || val === "") { + toast({ + title: "Error", + description: "Please fill in the value field", + variant: "destructive" + }) + return false + } const q = `MATCH ${type ? "(e)" : "()-[e]-()"} WHERE id(e) = ${id} SET e.${key} = '${val}'` const success = (await securedFetch(`api/graph/${prepareArg(graph.Id)}/?query=${prepareArg(q)}`, { method: "GET" - })).ok + }, toast)).ok if (success) { graph.getElements().forEach(e => { if (e.id !== id) return e.data[key] = val }) + const value = obj.data[key] setObj((prev) => { if (!prev) return prev if ("source" in prev) { @@ -67,194 +94,278 @@ export default function GraphDataPanel({ obj, setObj, onExpand, onDeleteElement, } } as Node }) - setNewVal("") + + graph.Data = graph.Data.map(row => { + const newRow = Object.entries(row).map(([k, cell]) => { + if (cell && typeof cell === "object" && cell.id === id) { + return [k, { ...cell, properties: { ...cell.properties, [key]: val } }] + } + return [k, cell] + }) + return Object.fromEntries(newRow) + }) + handleSetEditable("", "") + toast({ + title: "Success", + description: `Attribute ${actionType}`, + variant: "default", + action: isUndo ? setProperty(key, value, false)} /> : undefined + }) } return success } + const handleAddValue = async (key: string, value: string) => { + if (!key || key === "" || !value || value === "") { + toast({ + title: "Error", + description: "Please fill in both fields", + variant: "destructive" + }) + return + } + + const success = await setProperty(key, value, false, "added") + if (!success) return + setIsAddValue(false) + setNewKey("") + setNewVal("") + } + const removeProperty = async (key: string) => { const { id } = obj const q = `MATCH ${type ? "(e)" : "()-[e]-()"} WHERE id(e) = ${id} SET e.${key} = NULL` const success = (await securedFetch(`api/graph/${prepareArg(graph.Id)}/?query=${prepareArg(q)}`, { method: "GET" - })).ok + }, toast)).ok if (success) { + const value = obj.data[key] + graph.getElements().forEach((e) => { if (e.id !== id) return delete e.data[key] }) const newObj = { ...obj } + delete newObj.data[key] setObj(newObj) + + graph.Data = graph.Data.map(row => { + const newRow = Object.entries(row).map(([k, cell]) => { + if (cell && typeof cell === "object" && cell.id === id) { + delete cell.properties[key] + return [k, cell] + } + return [k, cell] + }) + return Object.fromEntries(newRow) + }) + + toast({ + title: "Success", + description: "Attribute removed", + action: handleAddValue(key, value)} />, + variant: "default" + }) } return success } - const handelAddValue = async (e: React.KeyboardEvent) => { + const handleAddKeyDown = async (e: React.KeyboardEvent) => { if (e.key === "Escape") { setIsAddValue(false) setNewKey("") setNewVal("") + return } if (e.key !== "Enter") return - if (!newKey || !newVal) { - Toast("Please fill in both fields") + handleAddValue(newKey, newVal) + } + + const handleSetKeyDown = async (e: React.KeyboardEvent) => { + if (e.key === "Escape") { + handleSetEditable("", "") + setNewKey("") } - const success = await setProperty(newKey, newVal) - if (!success) return - setIsAddValue(false) - setNewKey("") - } + if (e.key !== "Enter") return + setProperty(editable, newVal, true) + } return ( -
-
-
+
+
+
-
-

Attributes {attributes.length}

+ > + + +

{label}

+

{attributes.length} Attributes

-
-
    + + + + + Key + Value + + + + + + id: + {obj.id} + { attributes.map((key) => ( -
    setHover(key)} onMouseLeave={() => setHover("")} + key={key} > -
    - { - editable === key ? -
    - +
    - : hover === key && -
    -
    - } -
    -
    -

    {key}:

    -
    -
    + handleSetEditable("", "") + }}> + + + + : hover === key && + <> + + + + + } + title="Delete Attribute" + description="Are you sure you want to delete this attribute?" + > +
    +
    +
    + + } +
    + + {key}: + { editable === key && data?.user.role !== "Read-Only" ? ref?.focus()} - variant="Small" + className="w-full" value={newVal} onChange={(e) => setNewVal(e.target.value)} - onKeyDown={(e) => { - if (e.key === "Escape") { - setEditable("") - } - - if (e.key !== "Enter") return - - setProperty(key, newVal) - setEditable("") - }} + onKeyDown={handleSetKeyDown} + onBlur={() => handleSetEditable("", "")} /> :
    - + + )) } - {isAddValue && ( -
    - setNewKey(e.target.value)} - onKeyDown={handelAddValue} - /> - setNewVal(e.target.value)} - onBlur={() => setIsAddValue(false)} - onKeyDown={handelAddValue} - /> -
    - )} -
    + { + isAddValue && data?.user.role !== "Read-Only" && + + + + + + + !newKey ? ref?.focus() : undefined} + className="w-full" + value={newKey} + onChange={(e) => setNewKey(e.target.value)} + onKeyDown={handleAddKeyDown} + /> + + + setNewVal(e.target.value)} + onKeyDown={handleAddKeyDown} + /> + + + } + + + + +
    +
    + : } - onClick={() => setIsAddValue(prev => !prev)} disabled={data?.user.role === "Read-Only"} - /> -
    -
-
-
+ variant="Primary" + label={`Delete ${type ? "Node" : "Relation"}`} + > + + + } + />
) diff --git a/app/graph/GraphView.tsx b/app/graph/GraphView.tsx index ae80051c..0128c162 100644 --- a/app/graph/GraphView.tsx +++ b/app/graph/GraphView.tsx @@ -6,11 +6,13 @@ import { useRef, useState, useEffect, Dispatch, SetStateAction } from "react"; import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/components/ui/resizable"; import { ImperativePanelHandle } from "react-resizable-panels"; -import { ChevronLeft, GitGraph, Maximize2, Minimize2, Table } from "lucide-react" +import { ChevronLeft, GitGraph, Maximize2, Minimize2, Pause, Play, Table } from "lucide-react" import { cn, prepareArg, securedFetch } from "@/lib/utils"; import dynamic from "next/dynamic"; import { Session } from "next-auth"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { useToast } from "@/components/ui/use-toast"; +import { Switch } from "@/components/ui/switch"; import { Category, Graph, GraphData, Link, Node } from "../api/graph/model"; import DataPanel from "./GraphDataPanel"; import Labels from "./labels"; @@ -45,7 +47,7 @@ function GraphView({ graph, selectedElement, setSelectedElement, runQuery, histo const [maximize, setMaximize] = useState(false) const [tabsValue, setTabsValue] = useState("") const [cooldownTicks, setCooldownTicks] = useState(0) - const [cooldownTime, setCooldownTime] = useState(2000) + const { toast } = useToast() useEffect(() => { let timeout: NodeJS.Timeout @@ -70,6 +72,11 @@ function GraphView({ graph, selectedElement, setSelectedElement, runQuery, histo setTabsValue(graph.getElements().length !== 0 ? "Graph" : defaultChecked) }, [graph.getElements().length, graph.Data.length]) + + const handleCooldown = (ticks?: number) => { + setCooldownTicks(ticks) + } + useEffect(() => { setSelectedElement(undefined) setSelectedElements([]) @@ -105,10 +112,6 @@ function GraphView({ graph, selectedElement, setSelectedElement, runQuery, histo onExpand(!!selectedElement) }, [selectedElement]) - const handelCooldown = () => { - setCooldownTicks(1000) - } - const onCategoryClick = (category: Category) => { category.show = !category.show graph.Elements.nodes.forEach((node) => { @@ -138,8 +141,7 @@ function GraphView({ graph, selectedElement, setSelectedElement, runQuery, histo setData({ ...graph.Elements }) } - - const handelDeleteElement = async () => { + const handleDeleteElement = async () => { if (selectedElements.length === 0 && selectedElement) { selectedElements.push(selectedElement) setSelectedElement(undefined) @@ -161,7 +163,7 @@ function GraphView({ graph, selectedElement, setSelectedElement, runQuery, histo const result = await securedFetch(`api/graph/${prepareArg(graph.Id)}/?query=${prepareArg(q)} `, { method: "GET" - }) + }, toast) if (!result.ok) return @@ -179,19 +181,37 @@ function GraphView({ graph, selectedElement, setSelectedElement, runQuery, histo fetchCount() }) + + graph.Data = graph.Data.map(row => { + const newRow = Object.entries(row).map(([key, cell]) => { + if (typeof cell === "object" && cell && selectedElements.some(element => element.id === cell.id)) { + return [key, undefined] + } + return [key, cell] + }) + if (newRow.every(([, cell]) => cell === undefined)) { + return undefined + } + return Object.fromEntries(newRow) + }) + setSelectedElements([]) setSelectedElement(undefined) graph.removeLinks(selectedElements.map((element) => element.id)) setData({ ...graph.Elements }) - handelCooldown() + toast({ + title: "Success", + description: `${selectedElements.length > 1 ? "Elements" : "Element"} deleted`, + }) + handleCooldown() } - const handelRunQuery = async (q: string) => { + const handleRunQuery = async (q: string) => { await runQuery(q) chartRef.current?.zoomToFit(1000, 40) - handelCooldown() + handleCooldown() } return ( @@ -206,12 +226,12 @@ function GraphView({ graph, selectedElement, setSelectedElement, runQuery, histo maximize={maximize} currentQuery={query} historyQueries={historyQueries} - runQuery={handelRunQuery} + runQuery={handleRunQuery} setCurrentQuery={setQuery} data={session} /> - - + +
{ isCollapsed && graph.Id && }
- { - !maximize ? - +
+ {cooldownTicks === undefined ? : } + { + handleCooldown(cooldownTicks === undefined ? 0 : undefined) + }} + /> +
{ (graph.Categories.length > 0 || graph.Labels.length > 0) && @@ -299,7 +320,7 @@ function GraphView({ graph, selectedElement, setSelectedElement, runQuery, histo - + } diff --git a/app/graph/Selector.tsx b/app/graph/Selector.tsx index 557aed7f..96ad75f3 100644 --- a/app/graph/Selector.tsx +++ b/app/graph/Selector.tsx @@ -1,25 +1,29 @@ 'use client' -import { useEffect, useRef, useState } from "react"; -import { Dialog, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; +import { SetStateAction, Dispatch, useEffect, useRef, useState } from "react"; +import { DialogTitle } from "@/components/ui/dialog"; import { Editor } from "@monaco-editor/react"; -import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"; import { editor } from "monaco-editor"; -import { Toast, cn, prepareArg, securedFetch } from "@/lib/utils"; +import { cn, prepareArg, securedFetch } from "@/lib/utils"; import { Session } from "next-auth"; +import { PlusCircle, RefreshCcw } from "lucide-react"; +import { usePathname } from "next/navigation"; +import { useToast } from "@/components/ui/use-toast"; import Combobox from "../components/ui/combobox"; import { Graph, Query } from "../api/graph/model"; -import UploadGraph from "../components/graph/UploadGraph"; import DialogComponent from "../components/DialogComponent"; import Button from "../components/ui/Button"; import Duplicate from "./Duplicate"; import SchemaView from "../schema/SchemaView"; import View from "./View"; +import CreateGraph from "../components/CreateGraph"; +import ExportGraph from "../components/ExportGraph"; -export default function Selector({ onChange, graphName, queries, runQuery, edgesCount, nodesCount, setGraph, graph, data: session }: { +interface Props { /* eslint-disable react/require-default-props */ onChange: (selectedGraphName: string) => void graphName: string + setGraphName: Dispatch> runQuery?: (query: string, setQueriesOpen: (open: boolean) => void) => Promise queries?: Query[] edgesCount: number @@ -27,30 +31,22 @@ export default function Selector({ onChange, graphName, queries, runQuery, edges setGraph: (graph: Graph) => void graph: Graph data: Session | null -}) { +} + +export default function Selector({ onChange, graphName, setGraphName, queries, runQuery, edgesCount, nodesCount, setGraph, graph, data: session }: Props) { const [options, setOptions] = useState([]); const [schema, setSchema] = useState(Graph.empty()); const [selectedValue, setSelectedValue] = useState(""); const [duplicateOpen, setDuplicateOpen] = useState(false); - const [dropOpen, setDropOpen] = useState(false); const [queriesOpen, setQueriesOpen] = useState(false); const [query, setQuery] = useState(); - const [reload, setReload] = useState(false); const editorRef = useRef(null) - - useEffect(() => { - const run = async () => { - const result = await securedFetch("api/graph", { - method: "GET" - }) - if (!result.ok) return - const res = (await result.json()).result as string[] - setOptions(!runQuery ? res.filter(name => name.includes("_schema")).map(name => name.split("_")[0]) : res.filter(name => !name.includes("_schema"))) - } - run() - }, [runQuery ,reload]) - + const pathname = usePathname() + const type = pathname.includes("/schema") ? "Schema" : "Graph" + const [isRotating, setIsRotating] = useState(false); + const { toast } = useToast() + useEffect(() => { if (!graphName) return setOptions(prev => { @@ -60,6 +56,19 @@ export default function Selector({ onChange, graphName, queries, runQuery, edges }) }, [graphName]) + const getOptions = async () => { + const result = await securedFetch("api/graph", { + method: "GET" + }, toast) + if (!result.ok) return + const res = (await result.json()).result as string[] + setOptions(!runQuery ? res.filter(name => name.includes("_schema")).map(name => name.split("_")[0]) : res.filter(name => !name.includes("_schema"))) + } + + useEffect(() => { + getOptions() + }, []) + const handleEditorDidMount = (e: editor.IStandaloneCodeEditor) => { editorRef.current = e } @@ -69,7 +78,7 @@ export default function Selector({ onChange, graphName, queries, runQuery, edges const q = 'MATCH (n)-[e]-(m) return n,e,m' const result = await securedFetch(`api/graph/${prepareArg(name)}_schema/?query=${prepareArg(q)}&create=false&role=${session?.user.role}`, { method: "GET" - }) + }, toast) if (!result.ok) return @@ -82,65 +91,55 @@ export default function Selector({ onChange, graphName, queries, runQuery, edges setSelectedValue(name) } - const onExport = async () => { - const name = `${selectedValue}${!runQuery ? "_schema" : ""}` - const result = await securedFetch(`api/graph/${prepareArg(name)}/export`, { - method: "GET" - }) - - if (!result.ok) return - - const blob = await result.blob() - const url = window.URL.createObjectURL(blob) - try { - const link = document.createElement('a') - link.href = url - link.setAttribute('download', `${name}.dump`) - document.body.appendChild(link) - link.click() - link.parentNode?.removeChild(link) - window.URL.revokeObjectURL(url) - } catch (e) { - Toast("Error while exporting data") - } - } - + const handleReloadClick = () => { + setIsRotating(true); + getOptions(); + setTimeout(() => setIsRotating(false), 1000); + }; return (
- -
- +
+ + + + } + /> +

|

+

|

+ +
+
+ - - -
-
+
{ selectedValue &&

Created on 2/2 24

- {nodesCount} Nodes -

|

- {edgesCount} Edges + {nodesCount} Nodes +

|

+ {edgesCount} Edges
} { runQuery &&
- - + - - -
- Queries -
+ } + title="Query History" + > +
+ Queries +
+
    { - queries && queries.length > 0 && -
      - { - queries.map((q, index) => ( - // eslint-disable-next-line react/no-array-index-key -
    • -
    • - )) - } -
    + queries && queries.map((q, index) => ( + // eslint-disable-next-line react/no-array-index-key +
  • +
  • + )) } -
    -
    - setQuery(({ text: q || "", metadata: query?.metadata || [] }))} - onMount={handleEditorDidMount} - /> -
    -
      - { - query?.metadata && - query.metadata.map((line, index) => ( - // eslint-disable-next-line react/no-array-index-key -
    • -

      {line}

      -
    • - )) - } -
    +
+
+
+ setQuery(({ text: q || "", metadata: query?.metadata || [] }))} + onMount={handleEditorDidMount} + />
-
-
-
- -
- - - +
+
+
+ + + }> + +
}
diff --git a/app/graph/TableView.tsx b/app/graph/TableView.tsx index bbba60a5..2db5f7ed 100644 --- a/app/graph/TableView.tsx +++ b/app/graph/TableView.tsx @@ -1,66 +1,24 @@ /* eslint-disable react/no-array-index-key */ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { JSONTree } from "react-json-tree" -import { cn } from "@/lib/utils" +import { Data } from "../api/graph/model" +import TableComponent from "../components/TableComponent" interface Props { - data: any[] + data: Data } export default function TableView({ data }: Props) { + return ( -
-
- { - Object.keys(data[0]).map((key, i) => ( -
- {key} -
- )) - } -
- { - data.map((row, i) => ( -
- { - Object.entries(row).map(([key, val], j) => ( -
-
-                                        {
-                                            typeof val === "object" ?
-                                                 false}
-                                                    keyPath={[key]}
-                                                    theme={{
-                                                        base00: !(i % 2) ? "#57577B" : "#272746", // background
-                                                        base01: '#000000',
-                                                        base02: '#CE9178',
-                                                        base03: '#CE9178', // open values
-                                                        base04: '#CE9178',
-                                                        base05: '#CE9178',
-                                                        base06: '#CE9178',
-                                                        base07: '#CE9178',
-                                                        base08: '#CE9178',
-                                                        base09: '#b5cea8', // numbers
-                                                        base0A: '#CE9178',
-                                                        base0B: '#CE9178', // close values
-                                                        base0C: '#CE9178',
-                                                        base0D: '#99E4E5', // * keys
-                                                        base0E: '#ae81ff',
-                                                        base0F: '#cc6633'
-                                                    }}
-                                                    data={val}
-                                                />
-                                                : val as any
-                                        }
-                                    
-
- )) - } -
- )) - } -
+ ({ + cells: Object.values(row).map((value) => ({ + value, + + })) + }))} + /> ) } \ No newline at end of file diff --git a/app/graph/Tutorial.tsx b/app/graph/Tutorial.tsx new file mode 100644 index 00000000..f907fd9c --- /dev/null +++ b/app/graph/Tutorial.tsx @@ -0,0 +1,72 @@ +import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel"; +import { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from "@/components/ui/drawer"; +import { Dispatch, SetStateAction, useEffect, useState } from "react"; +import { Checkbox } from "@/components/ui/checkbox"; +import { VisuallyHidden } from "@radix-ui/react-visually-hidden"; +import CreateGraph from "../components/CreateGraph"; + +interface Props { + onSetGraphName: Dispatch> +} + +export default function Tutorial({ onSetGraphName }: Props) { + + const [open, setOpen] = useState(false) + const [showAgain, setShowAgain] = useState(false) + + useEffect(() => { + setOpen(localStorage.getItem("tutorial") !== "false") + }, []) + + const handleSetGraphName = (name: string) => { + onSetGraphName(name) + setOpen(false) + } + + return ( + { + if (showAgain) { + localStorage.setItem("tutorial", "false") + } + setOpen(o) + }}> + + + + + + +
+ + + +

Our Browser allows you to visualize, manipulate and explore your data.

+
+ +

Easily interact with your data in our adaptive force canvas

+
+ +

Configure or export your graph with ease from the control center

+
+ + + +
+ + +
+
+
+ setShowAgain(checked as boolean)} + /> +

Don't show this again

+
+
+
+ ) +} \ No newline at end of file diff --git a/app/graph/View.tsx b/app/graph/View.tsx index 87eda1e2..201fa0af 100644 --- a/app/graph/View.tsx +++ b/app/graph/View.tsx @@ -3,12 +3,10 @@ import { ChevronDown, ChevronUp, FileCheck2, PlusCircle, RotateCcw, Trash2 } from "lucide-react" import { useEffect, useState } from "react" import { cn } from "@/lib/utils" -import { Dialog, DialogTrigger } from "@/components/ui/dialog" import { DEFAULT_COLORS, Graph } from "../api/graph/model" import Button from "../components/ui/Button" -import Input from "../components/ui/Input" import DialogComponent from "../components/DialogComponent" -import CloseDialog from "../components/CloseDialog" +import Input from "../components/ui/Input" export default function View({ graph, setGraph, selectedValue }: { graph: Graph, @@ -20,8 +18,8 @@ export default function View({ graph, setGraph, selectedValue }: { const [hover, setHover] = useState("") const [editable, setEditable] = useState("") - const handelPreferencesChange = (colors?: string[]) => { - setGraph(Graph.create(graph.Id, { data: graph.Data }, colors || colorsArr)) + const handlePreferencesChange = (colors?: string[]) => { + setGraph(Graph.create(graph.Id, { data: graph.Data, metadata: graph.Metadata }, colors || colorsArr)) if (colors) return localStorage.setItem(graph.Id, JSON.stringify(colorsArr)); } @@ -31,134 +29,140 @@ export default function View({ graph, setGraph, selectedValue }: { }, [graph.Colors]) return ( - !o && setColorsArr(graph.Colors)}> - + !o && setColorsArr(graph.Colors)} + trigger={ + } + { + i !== colorsArr.length - 1 && + + } +
+ { + c === newColor || c === editable ? + <> +
+ ref?.focus()} + className="w-24" + value={editable === c ? editable : newColor} + onChange={(e) => { setColorsArr(prev => { const newArr = [...prev]; - [newArr[i], newArr[i - 1]] = [newArr[i - 1], newArr[i]]; + newArr[i] = e.target.value; return newArr; }); + if (editable === c) { + setEditable(e.target.value) + } else setNewColor(e.target.value); + }} + onBlur={() => { + setNewColor(""); + colorsArr.splice(i, 1); + }} + onKeyDown={(e) => { + if (e.key !== "Enter") return + setNewColor(""); + setEditable(""); }} - icon={} - title="Up" /> - } - { - i !== colorsArr.length - 1 && + + : <> +
- { - c === newColor || c === editable ? - <> -
- ref?.focus()} - className="w-24" - variant="Small" - value={editable === c ? editable : newColor} - onChange={(e) => { - setColorsArr(prev => { - const newArr = [...prev]; - newArr[i] = e.target.value; - return newArr; - }); - if (editable === c) { - setEditable(e.target.value) - } else setNewColor(e.target.value); - }} - onBlur={() => { - setNewColor(""); - colorsArr.splice(i, 1); - }} - onKeyDown={(e) => { - if (e.key !== "Enter") return - setNewColor(""); - setEditable(""); - }} - /> - - : <> -
-
+ + } + { + hover === c && !(c === newColor || c === editable) && + + } + + )) + } + +
+ + +
- - +
+ ) } \ No newline at end of file diff --git a/app/graph/labels.tsx b/app/graph/labels.tsx index 0da1cf19..0a116454 100644 --- a/app/graph/labels.tsx +++ b/app/graph/labels.tsx @@ -20,7 +20,7 @@ export default function Labels({ graph, categories, onClick, label, className = const listRef = useRef(null) const isScrollable = listRef.current && listRef.current.scrollHeight > listRef.current.clientHeight - const handelScroll = (scrollTo: number) => { + const handleScroll = (scrollTo: number) => { listRef.current?.scrollBy({ behavior: "smooth", top: scrollTo, @@ -38,10 +38,11 @@ export default function Labels({ graph, categories, onClick, label, className = isScrollable && }
    { @@ -51,14 +52,13 @@ export default function Labels({ graph, categories, onClick, label, className = )) } @@ -67,10 +67,11 @@ export default function Labels({ graph, categories, onClick, label, className = isScrollable && }
diff --git a/app/graph/page.tsx b/app/graph/page.tsx index cd52c0f5..760ece24 100644 --- a/app/graph/page.tsx +++ b/app/graph/page.tsx @@ -1,12 +1,14 @@ 'use client' import { useCallback, useEffect, useState } from "react"; -import { Toast, prepareArg, securedFetch } from "@/lib/utils"; +import { prepareArg, securedFetch } from "@/lib/utils"; import { useSession } from "next-auth/react"; +import { useToast } from "@/components/ui/use-toast"; import Selector from "./Selector"; import Header from "../components/Header"; import { Graph, Link, Node, Query } from "../api/graph/model"; import GraphView from "./GraphView"; +import Tutorial from "./Tutorial"; export default function Page() { @@ -17,7 +19,9 @@ export default function Page() { const [queries, setQueries] = useState([]) const [historyQuery, setHistoryQuery] = useState("") const [selectedElement, setSelectedElement] = useState(); - const { data } = useSession() + const { data: session } = useSession() + const { toast } = useToast() + useEffect(() => { setQueries(JSON.parse(localStorage.getItem(`query history`) || "[]")) @@ -28,13 +32,13 @@ export default function Page() { const q1 = "MATCH (n) RETURN COUNT(n) as nodes" const q2 = "MATCH ()-[e]->() RETURN COUNT(e) as edges" - const nodes = await (await securedFetch(`api/graph/${prepareArg(graphName)}/?query=${q1}&role=${data?.user.role}`, { + const nodes = await (await securedFetch(`api/graph/${prepareArg(graphName)}/?query=${q1}&role=${session?.user.role}`, { method: "GET" - })).json() + }, toast)).json() - const edges = await (await securedFetch(`api/graph/${prepareArg(graphName)}/?query=${q2}&role=${data?.user.role}`, { + const edges = await (await securedFetch(`api/graph/${prepareArg(graphName)}/?query=${q2}&role=${session?.user.role}`, { method: "GET" - })).json() + }, toast)).json() if (!edges || !nodes) return @@ -56,14 +60,17 @@ export default function Page() { const run = async (query: string) => { if (!graphName) { - Toast("Select a graph first") + toast({ + title: "Error", + description: "Select a graph first", + variant: "destructive" + }) return null } - const result = await securedFetch(`api/graph/${prepareArg(graphName)}/?query=${prepareArg(query)}&role=${data?.user.role}`, { - + const result = await securedFetch(`api/graph/${prepareArg(graphName)}/?query=${prepareArg(query)}&role=${session?.user.role}`, { method: "GET" - }) + }, toast) if (!result.ok) return null @@ -77,7 +84,7 @@ export default function Page() { if (!query) return const result = await run(query) if (!result) return - const queryArr = [...queries, { text: query, metadata: result.metadata }] + const queryArr = queries.some(q => q.text === query) ? queries : [...queries, { text: query, metadata: result.metadata }] setQueries(queryArr) localStorage.setItem("query history", JSON.stringify(queryArr)) const g = Graph.create(graphName, result, graph.Colors) @@ -103,6 +110,7 @@ export default function Page() {
text)} fetchCount={fetchCount} - session={data} + session={session} /> +
) diff --git a/app/graph/toolbar.tsx b/app/graph/toolbar.tsx index 1ebd7c58..ba2762ec 100644 --- a/app/graph/toolbar.tsx +++ b/app/graph/toolbar.tsx @@ -3,10 +3,9 @@ /* eslint-disable react/require-default-props */ import { Link, PlusCircle, Shrink, Trash2, ZoomIn, ZoomOut } from "lucide-react"; -import { Dialog, DialogTrigger } from "@/components/ui/dialog"; -import { Dispatch, SetStateAction, useState } from "react"; +import { useState } from "react"; import Button from "../components/ui/Button"; -import DialogComponent from "../components/DialogComponent"; +import DeleteElement from "./DeleteElement"; interface Props { addDisabled?: boolean, @@ -17,9 +16,7 @@ interface Props { onAddEntity?: () => void, onAddRelation?: () => void, deleteDisabled?: boolean, - cooldownTime: number | undefined - setCooldownTime: Dispatch> - handelCooldown: () => void + selectedElementsLength: number } export default function Toolbar({ @@ -30,9 +27,7 @@ export default function Toolbar({ onAddEntity, onAddRelation, deleteDisabled, - cooldownTime, - setCooldownTime, - handelCooldown, + selectedElementsLength }: Props) { const [deleteOpen, setDeleteOpen] = useState(false) @@ -51,7 +46,7 @@ export default function Toolbar({ } } - const handelDeleteElement = async () => { + const handleDeleteElement = async () => { if (!onDeleteElement) return await onDeleteElement() setDeleteOpen(false) @@ -61,50 +56,41 @@ export default function Toolbar({
+ 1 ? "elements" : "element"}?`} + open={deleteOpen} + setOpen={setDeleteOpen} + onDeleteElement={handleDeleteElement} + trigger={
- - - + > + + + } + />
{ (onAddEntity || onAddRelation || onDeleteElement) && @@ -112,37 +98,32 @@ export default function Toolbar({ }
) diff --git a/app/layout.tsx b/app/layout.tsx index 30489ae0..141d0f53 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -2,9 +2,8 @@ import "./globals.css"; import { Inter } from "next/font/google"; -import { Toaster } from "@/components/ui/toaster"; -import { cn } from "@/lib/utils"; import { Metadata } from "next"; +import { Toaster } from "@/components/ui/toaster"; import NextAuthProvider from "./providers"; import GTM from "./GTM"; @@ -25,7 +24,7 @@ export default function RootLayout({ // caused by mismatched client/server content caused by next-themes return ( - + {children} diff --git a/app/login/LoginForm.tsx b/app/login/LoginForm.tsx index a54ebfe2..be315cb7 100644 --- a/app/login/LoginForm.tsx +++ b/app/login/LoginForm.tsx @@ -3,29 +3,68 @@ import { SignInOptions, SignInResponse, signIn } from "next-auth/react"; import { FormEvent, useEffect, useState } from "react"; import { useSearchParams, useRouter } from "next/navigation"; -import Dropzone from "@/app/components/ui/Dropzone"; -import { Checkbox } from "@/components/ui/checkbox"; -import { Eye } from "lucide-react"; -import Input from "@/app/components/ui/Input"; -import Button from "@/app/components/ui/Button"; import Image from "next/image"; +import { Checkbox } from "@/components/ui/checkbox"; import { cn } from "@/lib/utils"; +import FormComponent from "../components/FormComponent"; +import Dropzone from "../components/ui/Dropzone"; const DEFAULT_HOST = "localhost"; const DEFAULT_PORT = "6379"; export default function LoginForm() { const router = useRouter(); - const [error, setError] = useState(false); const [host, setHost] = useState(""); const [port, setPort] = useState(""); const [TLS, setTLS] = useState(false); const [CA, setCA] = useState(); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); - const [showPassword, setShowPassword] = useState(false); + const [error, setError] = useState<{ + message: string + show: boolean + }>({ + message: "Invalid credentials", + show: false + }); const searchParams = useSearchParams(); + const fields = [ + { + value: host, + onChange: (e: React.ChangeEvent) => setHost(e.target.value), + label: "Host", + type: "text", + placeholder: DEFAULT_HOST, + required: true + }, + { + value: port, + onChange: (e: React.ChangeEvent) => setPort(e.target.value), + label: "Port", + type: "text", + placeholder: DEFAULT_PORT, + required: true + }, + { + value: username, + onChange: (e: React.ChangeEvent) => setUsername(e.target.value), + label: "Username", + placeholder: "Default", + info: "You can skip entering your username when deploying a FalkorDB instance \n from localhost with default credentials.", + type: "text", + required: false + }, + { + value: password, + onChange: (e: React.ChangeEvent) => setPassword(e.target.value), + label: "Password", + placeholder: "Default", + info: "You can skip entering your password when deploying a FalkorDB instance \n from localhost with default credentials.", + type: "password", + required: false + } + ]; useEffect(() => { const hostParam = searchParams.get("host"); @@ -58,7 +97,10 @@ export default function LoginForm() { signIn("credentials", params).then((res?: SignInResponse) => { if (res?.error) { - setError(true); + setError(prev => ({ + ...prev, + show: true + })) } else { router.push("/graph"); } @@ -75,94 +117,34 @@ export default function LoginForm() { reader.readAsDataURL(acceptedFiles[0]) } - const onChangeSetError = (func: (val: string) => void, val: string) => { - func(val); - setError(false); - } return ( -
- -
-

Connect

-
-
-
-

* Host

- onChangeSetError(setHost, e.target.value)} - value={host} - /> -
-
-

* Port

- onChangeSetError(setPort, e.target.value)} - value={port} - /> -
+
+
+
+
+ Loading...
-
-

{host !== DEFAULT_HOST && "* "} User Name

- onChangeSetError(setUsername, e.target.value)} - value={username} - /> -
-
-

{host !== DEFAULT_HOST && "* "}Password

-
-
-
- setTLS(checked as boolean)} - /> -

TLS Secured Connection

+ +
+
+ setTLS(checked as boolean)} + /> +

TLS Secured Connection

+
+
- -
-
- -
+
+
+
); } diff --git a/app/loginVerification.tsx b/app/loginVerification.tsx index 0a477a08..4fc23288 100644 --- a/app/loginVerification.tsx +++ b/app/loginVerification.tsx @@ -12,8 +12,8 @@ export default function LoginVerification({ children }: { children: React.ReactN const { data } = useSession() useEffect(() => { - if (data) return - localStorage.clear() + if (data?.user || data === undefined) return + localStorage.removeItem("query history") }, [data]) useEffect(() => { diff --git a/app/monitor/page.tsx b/app/monitor/page.tsx index b896413e..a29f9463 100644 --- a/app/monitor/page.tsx +++ b/app/monitor/page.tsx @@ -3,18 +3,20 @@ import useSWR from 'swr' import React, { useState } from 'react' import { securedFetch } from '@/lib/utils' +import { useToast } from '@/components/ui/use-toast' import MonitorView from './MonitorView' export default function Page() { const [time, setTime] = useState(null) + const { toast } = useToast() const fetcher = (url: string) => securedFetch(url, { method: 'GET', headers: { 'Content-Type': 'application/json' } - }).then((result) => { + }, toast).then((result) => { if (result.ok) { setTime(new Date()) return result.json() diff --git a/app/page.tsx b/app/page.tsx index 7a813014..2fd5e7c6 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -3,7 +3,6 @@ import Spinning from "@/app/components/ui/spinning"; export default function Home() { - return (
diff --git a/app/schema/SchemaCreateElement.tsx b/app/schema/SchemaCreateElement.tsx index d92c8240..45e700aa 100644 --- a/app/schema/SchemaCreateElement.tsx +++ b/app/schema/SchemaCreateElement.tsx @@ -4,13 +4,14 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Dispatch, SetStateAction, useState } from "react"; -import { Toast } from "@/lib/utils"; -import { ArrowRight, ArrowRightLeft, Check, ChevronRight, Pencil, Trash2, X } from "lucide-react"; -import { Checkbox } from "@/components/ui/checkbox"; -import Input from "../components/ui/Input"; +import { ArrowRight, ArrowRightLeft, Check, CheckCircle, ChevronRight, Pencil, Plus, Trash2, X, XCircle } from "lucide-react"; +import { Switch } from "@/components/ui/switch"; +import { useToast } from "@/components/ui/use-toast"; import Button from "../components/ui/Button"; import Combobox from "../components/ui/combobox"; import { Node } from "../api/graph/model"; +import Input from "../components/ui/Input"; +import ToastButton from "../components/ToastButton"; interface Props { onCreate: (element: [string, string[]][], label?: string) => Promise @@ -36,31 +37,57 @@ export default function SchemaCreateElement({ onCreate, onExpand, selectedNodes, const [labelEditable, setLabelEditable] = useState(false) const [editable, setEditable] = useState("") const [hover, setHover] = useState("") + const { toast } = useToast() - const handelSetEditable = (att: [string, string[]] = getDefaultAttribute()) => { + const handleSetEditable = (att: [string, string[]] = getDefaultAttribute()) => { setAttribute(att) setEditable(att[0]) } - const handelAddAttribute = () => { - setAttributes(prev => [...prev, newAttribute]) + const handleAddAttribute = (att?: [string, string[]]) => { + const newAtt = att || newAttribute + + if (!newAtt[0] || newAtt[1].some((v) => !v)) { + toast({ + title: "Error", + description: "You must type a key, type and a description in order to add a new property", + variant: "destructive" + }) + + return + } + + setAttributes(prev => [...prev, newAtt]) setNewAttribute(getDefaultAttribute()) } - const handelSetAttributes = () => { - if (!attribute[0] || !attribute[1].some((v) => v === "")) { - Toast("Please fill the field") + const handleSetAttribute = (isUndo: boolean, att?: [string, string[]]) => { + const newAtt = att || attribute + + if (!newAtt[0] || newAtt[1].some((v) => !v)) { + toast({ + title: "Error", + description: "You must type a key, type and a description in order to edit a property", + variant: "destructive" + }) return } - setAttributes(prev => prev.map(([key, val]) => key === attribute[0] ? attribute : [key, val])) + const oldAttribute = attributes.find(([k]) => k === newAtt[0]) + setAttributes(prev => prev.map(([key, val]) => key === newAtt[0] ? newAtt : [key, val])) setAttribute(getDefaultAttribute()) + handleSetEditable() + toast({ + title: "Success", + description: "Attribute set", + action: isUndo ? handleSetAttribute(false, oldAttribute)} /> : undefined + }) } - const handelKeyDown = (e: React.KeyboardEvent, handel: () => void, setter: () => void) => { + const handleSetKeyDown = (e: React.KeyboardEvent) => { if (e.code === "Escape") { e.preventDefault() - setter() + handleSetEditable() return } @@ -68,12 +95,30 @@ export default function SchemaCreateElement({ onCreate, onExpand, selectedNodes, e.preventDefault() - handel() + handleSetAttribute(true) } - const handelOnCreate = async () => { + const handleAddKeyDown = (e: React.KeyboardEvent) => { + if (e.code === "Escape") { + e.preventDefault() + setNewAttribute(getDefaultAttribute()) + return + } + + if (e.key !== 'Enter') return + + e.preventDefault() + + handleAddAttribute() + } + + const handleOnCreate = async () => { if (!label && !type) { - Toast("Please fill the label") + toast({ + title: "Error", + description: "You must type a label", + variant: "destructive" + }) return } const ok = await onCreate(attributes, label) @@ -84,42 +129,65 @@ export default function SchemaCreateElement({ onCreate, onExpand, selectedNodes, setLabelEditable(false) } - const handelLabelCancel = () => { + const handleLabelCancel = () => { setLabel("") setLabelEditable(false) } - const onSetLabel = (e: React.KeyboardEvent) => { + const handleSetLabel = () => { + if (!newLabel) { + toast({ + title: "Error", + description: "You must type a label", + variant: "destructive" + }) + return + } + + setLabel(newLabel) + setLabelEditable(false) + } + + const handleSetLabelKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Escape") { - handelLabelCancel() + handleLabelCancel() } if (e.key !== "Enter") return - setLabel(newLabel) - setLabelEditable(false) + handleSetLabel() + } return (
-
+
{ labelEditable ? - ref?.focus()} - className="w-28" - variant="Small" - onChange={(e) => setNewLabel(e.target.value)} - value={newLabel} - onBlur={handelLabelCancel} - onKeyDown={onSetLabel} - /> : + +
+
:
}
-
diff --git a/app/schema/SchemaDataPanel.tsx b/app/schema/SchemaDataPanel.tsx index cde12ffb..bc36331d 100644 --- a/app/schema/SchemaDataPanel.tsx +++ b/app/schema/SchemaDataPanel.tsx @@ -1,14 +1,19 @@ +/* eslint-disable @typescript-eslint/no-use-before-define */ /* eslint-disable react/no-array-index-key */ -import { Check, ChevronRight, MinusCircle, Pencil, PlusCircle, Trash2, X } from "lucide-react"; -import { Toast } from "@/lib/utils"; + +"use client"; + +import { Check, ChevronRight, Pencil, PlusCircle, Trash2, X } from "lucide-react"; import { useEffect, useState } from "react"; -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; +import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Checkbox } from "@/components/ui/checkbox"; +import { useToast } from "@/components/ui/use-toast"; import Button from "../components/ui/Button"; import { ATTRIBUTES, getDefaultAttribute, OPTIONS } from "./SchemaCreateElement"; -import Input from "../components/ui/Input"; import Combobox from "../components/ui/combobox"; import { Link, Node } from "../api/graph/model"; +import Input from "../components/ui/Input"; +import ToastButton from "../components/ToastButton"; interface Props { obj: Node | Link @@ -26,13 +31,14 @@ export default function SchemaDataPanel({ obj, onExpand, onSetAttributes, onRemo const [editable, setEditable] = useState("") const [hover, setHover] = useState("") const [isAddValue, setIsAddValue] = useState(false) + const { toast } = useToast() useEffect(() => { setAttributes(Object.entries(obj.data).filter(([key, val]) => !(key === "name" && Number(val) === obj.id)).map(([key, val]) => [key, Array.isArray(val) ? val : (val as string).split(',')])) setLabel("source" in obj ? obj.label : obj.category) }, [obj]) - const handelSetEditable = ([key, val]: [string, string[]] = getDefaultAttribute()) => { + const handleSetEditable = ([key, val]: [string, string[]] = getDefaultAttribute()) => { if (key !== "") { setIsAddValue(false) } @@ -41,153 +47,144 @@ export default function SchemaDataPanel({ obj, onExpand, onSetAttributes, onRemo setEditable(key) } - const handelSetAttributes = async () => { - if (attribute[0] === "" || attribute[1].some(v => v === "")) { - Toast("Please fill all the fields") + const handleSetAttribute = async (isUndo: boolean, att?: [string, string[]]) => { + const newAttribute = att || attribute + + if (newAttribute[0] === "" || newAttribute[1].some(v => v === "")) { + toast({ + title: "Error", + description: "Please fill all the fields", + }) return } - const ok = await onSetAttributes(attribute) + const ok = await onSetAttributes(newAttribute) + const oldAttribute = attributes.find(([key]) => key === newAttribute[0]) if (ok) { - setAttributes(prev => prev.map((att) => att[0] === attribute[0] ? attribute : att)) - handelSetEditable() + setAttributes(prev => prev.map((attr) => attr[0] === newAttribute[0] ? newAttribute : attr)) + handleSetEditable() + toast({ + title: "Success", + description: `Property set`, + action: isUndo && oldAttribute ? handleSetAttribute(false, oldAttribute)} /> : undefined, + }) } } - const handelRemoveAttribute = async (key: string) => { + const handleRemoveAttribute = async (key: string) => { const ok = await onRemoveAttribute(key) if (ok) { + const att = attributes.find(([k]) => k === key) setAttributes(prev => prev.filter(([k]) => k !== key)) + toast({ + title: "Success", + description: "Attribute removed", + action: att && handleAddAttribute(att)} />, + }) + setAttribute(getDefaultAttribute()) } } - const handelAddAttribute = async () => { - if (attribute[0] === "" || attribute[1].some(v => v === "")) { - Toast("Please fill all the fields") + const handleAddAttribute = async (att?: [string, string[]]) => { + const newAttribute = att || attribute + if (newAttribute[0] === "" || newAttribute[1].some(v => v === "")) { + toast({ + title: "Error", + description: "Please fill all the fields", + variant: "destructive" + }) return } - const ok = await onSetAttributes(attribute) + const ok = await onSetAttributes(newAttribute) if (ok) { - setAttributes(prev => [...prev, attribute]) + setAttributes(prev => [...prev, newAttribute]) setAttribute(getDefaultAttribute()) setIsAddValue(false) } } - const handelKeyDown = (evt: React.KeyboardEvent, func: () => void) => { + const handleSetKeyDown = (evt: React.KeyboardEvent) => { + if (evt.code === "Escape") { + evt.preventDefault() + handleSetEditable() + } + + if (evt.code !== "Enter") return + + evt.preventDefault() + handleSetAttribute(true) + } + + const handleAddKeyDown = (evt: React.KeyboardEvent) => { if (evt.code === "Escape") { evt.preventDefault() - handelSetEditable() + handleSetEditable() } if (evt.code !== "Enter") return evt.preventDefault() - func() + handleAddAttribute() } return (
-
-
+
+

{label}

-
-

Attributes {attributes.length}

-
+

{attributes.length} Attributes

- +
- + { (attributes.length > 0 || isAddValue) && <> - - Key - {ATTRIBUTES.map((att) => ( - {att} - ))} + Key + { + ATTRIBUTES.map((att) => ( + {att} + )) + } + } - + { attributes.length > 0 && attributes.map(([key, val]) => ( { if (editable === key) return - handelSetEditable([key, [...val]]) + handleSetEditable([key, [...val]]) }} - // onBlur={(e) => !e.currentTarget.contains(e.relatedTarget as Node) && handelSetEditable()} + // onBlur={(e) => !e.currentTarget.contains(e.relatedTarget as Node) && handleSetEditable()} onMouseEnter={() => setHover(key)} onMouseLeave={() => setHover("")} key={key} tabIndex={0} // Added to make the row focusable > - -
- { - editable === key ? - <> -
-
- + {key}: { editable === key ? <> - + setAttribute(prev => { @@ -200,11 +197,10 @@ export default function SchemaDataPanel({ obj, onExpand, onSetAttributes, onRemo selectedValue={attribute[1][0]} /> - + handelKeyDown(e, handelSetAttributes)} - variant="Small" + className="w-full" + onKeyDown={handleSetKeyDown} onChange={(e) => setAttribute(prev => { const p: [string, string[]] = [...prev] p[1][1] = e.target.value @@ -213,7 +209,7 @@ export default function SchemaDataPanel({ obj, onExpand, onSetAttributes, onRemo value={attribute[1][1]} /> - + setAttribute(prev => { @@ -224,7 +220,7 @@ export default function SchemaDataPanel({ obj, onExpand, onSetAttributes, onRemo checked={attribute[1][2] === "true"} /> - + setAttribute(prev => { @@ -237,38 +233,76 @@ export default function SchemaDataPanel({ obj, onExpand, onSetAttributes, onRemo : val.map((v, i) => ( - {v} + {v} )) } + +
+ { + editable === key ? + <> + + + + : hover === key && + <> + + + + } +
+
)) } { isAddValue && - - - + + + }
+ + +
-
-
-
+
) diff --git a/app/schema/SchemaView.tsx b/app/schema/SchemaView.tsx index 9a95daca..ce23fc07 100644 --- a/app/schema/SchemaView.tsx +++ b/app/schema/SchemaView.tsx @@ -3,12 +3,14 @@ 'use client' import { ResizablePanel, ResizablePanelGroup, ResizableHandle } from "@/components/ui/resizable" -import { ChevronLeft, Maximize2, Minimize2 } from "lucide-react" +import { ChevronLeft, Maximize2, Minimize2, Pause, Play } from "lucide-react" import { ImperativePanelHandle } from "react-resizable-panels" import { useEffect, useRef, useState } from "react" -import { Toast, cn, prepareArg, securedFetch } from "@/lib/utils" +import { cn, prepareArg, securedFetch } from "@/lib/utils" import { Session } from "next-auth" import dynamic from "next/dynamic" +import { useToast } from "@/components/ui/use-toast" +import { Switch } from "@/components/ui/switch" import Toolbar from "../graph/toolbar" import SchemaDataPanel from "./SchemaDataPanel" import Labels from "../graph/labels" @@ -43,8 +45,8 @@ export default function SchemaView({ schema, fetchCount, session }: Props) { const [isAddEntity, setIsAddEntity] = useState(false) const [maximize, setMaximize] = useState(false) const [cooldownTicks, setCooldownTicks] = useState(0) - const [cooldownTime, setCooldownTime] = useState(2000) const [data, setData] = useState(schema.Elements) + const { toast } = useToast() useEffect(() => { setData({ ...schema.Elements }) @@ -63,8 +65,8 @@ export default function SchemaView({ schema, fetchCount, session }: Props) { setSelectedNodes([undefined, undefined]) }, [isAddRelation]) - const handelCooldown = () => { - setCooldownTicks(1000) + const handleCooldown = (ticks?: number) => { + setCooldownTicks(ticks) } const onCategoryClick = (category: Category) => { @@ -78,18 +80,18 @@ export default function SchemaView({ schema, fetchCount, session }: Props) { setData({ ...schema.Elements }) } - + const onLabelClick = (label: Category) => { label.show = !label.show schema.Elements.links.forEach((link) => { if (link.label !== label.name) return link.visible = label.show }) - + setData({ ...schema.Elements }) } - const handelSetSelectedElement = (element?: Node | Link | undefined) => { + const handleSetSelectedElement = (element?: Node | Link | undefined) => { setSelectedElement(element) if (isAddRelation || isAddEntity) return if (element) { @@ -111,7 +113,7 @@ export default function SchemaView({ schema, fetchCount, session }: Props) { } } - const handelDeleteElement = async () => { + const handleDeleteElement = async () => { const stateSelectedElements = Object.values(selectedElements) if (stateSelectedElements.length === 0 && selectedElement) { @@ -134,7 +136,7 @@ export default function SchemaView({ schema, fetchCount, session }: Props) { const q = `${conditionsNodes.length > 0 ? `MATCH (n) WHERE ${conditionsNodes.join(" OR ")} DELETE n` : ""}${conditionsEdges.length > 0 && conditionsNodes.length > 0 ? " WITH * " : ""}${conditionsEdges.length > 0 ? `MATCH ()-[e]-() WHERE ${conditionsEdges.join(" OR ")} DELETE e` : ""}` const result = await securedFetch(`api/graph/${prepareArg(schema.Id)}_schema/?query=${prepareArg(q)} `, { method: "GET" - }) + }, toast) if (!result.ok) return @@ -162,16 +164,16 @@ export default function SchemaView({ schema, fetchCount, session }: Props) { dataPanel.current?.collapse() } - const handelSetAttributes = async (attribute: [string, string[]]) => { - const [key, value] = attribute; + const handleSetAttributes = async (attribute: [string, string[]]) => { if (!selectedElement) return false + const [key, value] = attribute; const type = !("source" in selectedElement) const { id } = selectedElement const q = `MATCH ${type ? "(e)" : "()-[e]-()"} WHERE ID(e) = ${id} SET e.${key} = "${value.join(",")}"` const { ok } = await securedFetch(`api/graph/${prepareArg(schema.Id)}_schema/?query=${prepareArg(q)}`, { method: "GET" - }) + }, toast) if (ok) { if (type) { @@ -186,7 +188,11 @@ export default function SchemaView({ schema, fetchCount, session }: Props) { }) } } else { - Toast("Failed to set property") + toast({ + title: "Error", + description: "Failed to set property", + variant: "destructive" + }) } setData({ ...schema.Elements }) @@ -194,7 +200,7 @@ export default function SchemaView({ schema, fetchCount, session }: Props) { return ok } - // const handelSetCategory = async (category: string) => { + // const handleSetCategory = async (category: string) => { // if (!selectedElement) return false // const { id } = getElementId(selectedElement) @@ -233,7 +239,7 @@ export default function SchemaView({ schema, fetchCount, session }: Props) { // return success // } - const handelRemoveProperty = async (key: string) => { + const handleRemoveProperty = async (key: string) => { if (!selectedElement) return false const type = !("source" in selectedElement) @@ -241,7 +247,7 @@ export default function SchemaView({ schema, fetchCount, session }: Props) { const q = `MATCH ${type ? "(e)" : "()-[e]-()"} WHERE ID(e) = ${id} SET e.${key} = NULL` const { ok } = await securedFetch(`api/graph/${prepareArg(schema.Id)}_schema/?query=${prepareArg(q)}`, { method: "GET" - }) + }, toast) if (ok) { if (type) { @@ -270,13 +276,17 @@ export default function SchemaView({ schema, fetchCount, session }: Props) { const onCreateElement = async (attributes: [string, string[]][], label?: string) => { if (!isAddEntity && selectedNodes[0] === undefined && selectedNodes[1] === undefined) { - Toast("Select nodes to create a relation") + toast({ + title: "Error", + description: "Select nodes to create a relation", + variant: "destructive" + }) return false } const result = await securedFetch(`api/graph/${prepareArg(schema.Id)}_schema/?query=${getCreateQuery(isAddEntity, selectedNodes as [Node, Node], attributes, label)}`, { method: "GET" - }) + }, toast) if (result.ok) { const json = await result.json() @@ -300,15 +310,15 @@ export default function SchemaView({ schema, fetchCount, session }: Props) { return result.ok } - return (
{ @@ -325,53 +335,58 @@ export default function SchemaView({ schema, fetchCount, session }: Props) { if (dataPanel.current?.isExpanded()) return onExpand() }} - onDeleteElement={handelDeleteElement} + onDeleteElement={handleDeleteElement} chartRef={chartRef} addDisabled={session?.user.role === "Read-Only"} - setCooldownTime={setCooldownTime} - cooldownTime={cooldownTime} - handelCooldown={handelCooldown} /> { isCollapsed && }
- { - !maximize ? - +
+ {cooldownTicks === undefined ? : } + { + handleCooldown(cooldownTicks === undefined ? 0 : undefined) + }} + /> +
{ (schema.Categories.length > 0 || schema.Labels.length > 0) && @@ -382,12 +397,12 @@ export default function SchemaView({ schema, fetchCount, session }: Props) { }
- + setIsCollapsed(true)} @@ -398,9 +413,9 @@ export default function SchemaView({ schema, fetchCount, session }: Props) { : (isAddEntity || isAddRelation) && (0) const [nodesCount, setNodesCount] = useState(0) const { data: session } = useSession() + const { toast } = useToast() const fetchCount = useCallback(async () => { const name = `${schemaName}_schema` @@ -23,11 +25,11 @@ export default function Page() { const nodes = await (await securedFetch(`api/graph/${prepareArg(name)}/?query=${q1}&role=${session?.user.role}`, { method: "GET" - })).json() + }, toast)).json() const edges = await (await securedFetch(`api/graph/${prepareArg(name)}/?query=${q2}&role=${session?.user.role}`, { method: "GET" - })).json() + }, toast)).json() if (!edges || !nodes) return @@ -40,15 +42,12 @@ export default function Page() { const run = async () => { const result = await securedFetch(`/api/graph/${prepareArg(schemaName)}_schema/?query=${defaultQuery()}&role=${session?.user.role}`, { method: "GET" - }) - if (!result.ok) { - Toast("Failed fetching schema") - return - } + }, toast) + if (!result.ok) return const json = await result.json() const colors = localStorage.getItem(schemaName)?.split(/[[\]",]/).filter(c => c) setSchema(Graph.create(schemaName, json.result, colors)) - + fetchCount() } @@ -57,9 +56,10 @@ export default function Page() { return (
-
+
([]); + const { toast } = useToast(); + + // Memoize the config update handler + const handleSetConfig = useCallback(async (name: string, value: string, isUndo: boolean) => { + if (!value) { + toast({ + title: "Error", + description: "Please enter a value", + variant: "destructive" + }); + return false; + } - const [configs, setConfigs] = useState([]) - const [editable, setEditable] = useState("") - const [configValue, setConfigValue] = useState("") + const result = await securedFetch( + `api/graph/?config=${prepareArg(name)}&value=${prepareArg(value)}`, + { method: 'POST' }, + toast + ); - useEffect(() => { - const run = async () => { - setConfigs(await Promise.all(Configs.map(async (config: Config) => { - const result = await securedFetch(`api/graph/?config=${prepareArg(config.name)}`, { - method: 'GET', - }) + if (!result.ok) return false; - if (!result.ok) { - Toast(`Failed to fetch configurations value`) - return config - } + const configToUpdate = configs.find(row => row.cells[0].value === name); + const oldValue = configToUpdate?.cells[2].value; - let value = (await result.json()).config[1] - - if (config.name === "CMD_INFO") { - if(value === 0) { - value = "no" - } else value = "yes" - } - - return { - name: config.name, - description: config.description, - value - } - }))) - } - run() - }, []) + setConfigs(currentConfigs => { + const updatedConfigs = currentConfigs.map((config: Row) => { + if (config.cells[0].value !== name) return config; - const handelSetConfig = async (name: string) => { + const newConfig = { ...config } - if (!configValue) { - Toast(`Please enter a value`) - return - } + newConfig.cells[2].value = value; - const result = await securedFetch(`api/graph/?config=${prepareArg(name)}&value=${prepareArg(configValue)}`, { - method: 'POST', - }) + return newConfig; + }); - if (!result.ok) { - Toast(`Failed to set configuration value`) - return - } + return updatedConfigs; + }); - setConfigs(prev => prev.map((config: Config) => { - if (config.name !== name) return config - return { - ...config, - value: configValue - } - })) + toast({ + title: "Success", + description: "Configuration value set successfully", + action: oldValue && isUndo + ? handleSetConfig(name, oldValue.toString(), false)} /> + : undefined + }); - setEditable("") - setConfigValue("") - } + return true; + }, [configs, toast]); - const onKeyDown = (e: KeyboardEvent, name: string) => { + const fetchConfigs = useCallback(async () => { + const newConfigs = await Promise.all( + Configs.map(async (config) => { + const result = await securedFetch( + `api/graph/?config=${prepareArg(config.name)}`, + { method: 'GET' }, + toast + ); - if (e.code === "Escape") { - setEditable("") - setConfigValue("") - return - } - - if (e.code !== "Enter") return + if (!result.ok) { + return { + cells: [ + { value: config.name }, + { value: config.description }, + { value: config.value.toString() } + ] + }; + } - handelSetConfig(name) - } + const { config: [, value] } = await result.json(); + const formattedValue = config.name === "CMD_INFO" + ? (value === 0 ? "no" : "yes") + : value; - return ( -
- - - + return { + cells: [ + { value: config.name }, + { value: config.description }, { - ["Name", "Description", "Value"].map((header) => ( - {header} - )) + value: formattedValue.toString(), + onChange: !disableRunTimeConfigs.has(config.name) + ? (val: string) => handleSetConfig(config.name, val, true) + : undefined } - - - - { - configs.map(({ name, description, value }, index) => ( - - {name} - {description} - - { - editable === name && !disableRunTimeConfigs.has(name) ? -
- { - ref?.focus() - }} - className="w-20" - type={name === "CMD_INFO" ? "text" : "number"} - variant="Small" - onChange={(e) => setConfigValue(e.target.value)} - onKeyDown={(e) => onKeyDown(e, name)} - value={configValue} - style={{ - WebkitAppearance: 'none', - margin: 0, - }} - /> -
- :
-
+ useEffect(() => { + fetchConfigs(); + }, [fetchConfigs]); + + return ( + ); } \ No newline at end of file diff --git a/app/settings/page.tsx b/app/settings/page.tsx index 4a72ab93..7cd2c7f9 100644 --- a/app/settings/page.tsx +++ b/app/settings/page.tsx @@ -1,9 +1,9 @@ 'use client' import { useEffect, useState } from "react" -import { cn } from "@/lib/utils" import { useSession } from "next-auth/react" import { useRouter } from "next/navigation" +import { cn } from "@/lib/utils" import Header from "../components/Header" import Users from "./users/Users" import Configurations from "./Configurations" @@ -33,15 +33,15 @@ export default function Settings() {

Settings

-
+
diff --git a/app/settings/users/AddUser.tsx b/app/settings/users/AddUser.tsx index 5a0d1d31..71fa07ca 100644 --- a/app/settings/users/AddUser.tsx +++ b/app/settings/users/AddUser.tsx @@ -1,179 +1,148 @@ -import { Dispatch, FormEvent, SetStateAction, useState } from "react" -import { Toast, securedFetch } from "@/lib/utils"; -import { Eye, PlusCircle } from "lucide-react"; -import { User } from "@/app/api/user/model"; -import Button from "@/app/components/ui/Button"; -import Input from "@/app/components/ui/Input"; -import DialogComponent from "@/app/components/DialogComponent"; -import { Dialog, DialogTrigger } from "@/components/ui/dialog"; -import Combobox from "../../components/ui/combobox"; +/* eslint-disable no-param-reassign */ + +"use client" -// eslint-disable-next-line no-useless-escape -const PATTERN = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&#+]{8,}$" +import { FormEvent, useEffect, useState } from "react" +import { PlusCircle } from "lucide-react"; +import { CreateUser } from "@/app/api/user/model"; +import Button from "@/app/components/ui/Button"; +import FormComponent, { Field } from "@/app/components/FormComponent"; +import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet"; +import { VisuallyHidden } from "@radix-ui/react-visually-hidden"; -export default function AddUser({ setUsers }: { - setUsers: Dispatch> +export default function AddUser({ onAddUser }: { + onAddUser: (user: CreateUser) => void }) { const [open, setOpen] = useState(false) const [username, setUsername] = useState("") const [password, setPassword] = useState("") const [confirmPassword, setConfirmPassword] = useState("") - const [showPassword, setShowPassword] = useState(false) - const [showConfirmPassword, setConfirmShowPassword] = useState(false) const [role, setRole] = useState("") - const handelClose = () => { + const handleClose = () => { setPassword("") setConfirmPassword("") setUsername("") setRole("") - setConfirmShowPassword(false) - setShowPassword(false) } - const addUser = async (e: FormEvent) => { - e.preventDefault(); + useEffect(() => { + if (!open) handleClose() + }, [open]) - if (!role) { - Toast("select role is required") - return + const fields: Field[] = [ + { + value: username, + onChange: (e) => setUsername(e.target.value), + label: "Username", + type: "text", + required: true, + errors: [ + { + message: "Username is required", + condition: (value: string) => !value + } + ] + }, + { + value: password, + onChange: (e) => setPassword(e.target.value), + label: "Password", + type: "password", + required: true, + show: false, + errors: [ + { + message: "Password is required", + condition: (value: string) => !value + }, + { + message: "Password must be at least 8 characters long", + condition: (value: string) => value.length < 8 + }, + { + message: "Password must contain at least one uppercase letter", + condition: (value: string) => !/[A-Z]/.test(value) + }, + { + message: "Password must contain at least one lowercase letter", + condition: (value: string) => !/[a-z]/.test(value) + }, + { + message: "Password must contain at least one number", + condition: (value: string) => !/[0-9]/.test(value) + }, + { + message: "Password must contain at least one special character", + condition: (value: string) => !/[!@#$%^&*]/.test(value) + }, + ] + }, + { + value: confirmPassword, + onChange: (e) => setConfirmPassword(e.target.value), + label: "Confirm Password", + type: "password", + required: true, + show: false, + errors: [ + { + message: "Confirm password is required", + condition: (value: string) => !value + }, + { + message: "Password don't match", + condition: (value: string) => value !== password + }, + ] + }, + { + value: role, + onSelectedValue: (value) => setRole(value), + label: "Role", + type: "select", + options: ["Admin", "Read-Write", "Read-Only"], + required: true, + errors: [ + { + message: "Role is required", + condition: (value: string) => !value + } + ] } + ] - const response = await securedFetch('/api/user/', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ username, password, role }) - }) + const handleAddUser = async (e: FormEvent) => { + e.preventDefault(); + + onAddUser({ username, password, role }) - if (response.ok) { - Toast("User added successfully", "Success") - setUsers(prev => [...prev, { username, role, selected: false }]) - } setOpen(false) - handelClose() + handleClose() }; return ( - { - setOpen(o) - handelClose() - }} - > - + + + + + + + + + + - - -
- -
-

Username

- { - setUsername(e.target.value) - e.currentTarget.setCustomValidity("") - e.currentTarget.reportValidity() - }} - onInvalid={(e) => e.currentTarget.setCustomValidity("Username is required")} - required - /> -
-
-

Password

-
-
-

Confirm Password

-
-
-
- -
-
+ + ) } \ No newline at end of file diff --git a/app/settings/users/DeleteUser.tsx b/app/settings/users/DeleteUser.tsx index 7628ed53..6e3a6c98 100644 --- a/app/settings/users/DeleteUser.tsx +++ b/app/settings/users/DeleteUser.tsx @@ -3,30 +3,34 @@ import { User } from "@/app/api/user/model"; import { Trash2 } from "lucide-react"; import { Dispatch, SetStateAction } from "react"; import Button from "@/app/components/ui/Button"; -import { Toast, securedFetch } from "@/lib/utils"; +import { securedFetch } from "@/lib/utils"; +import { useToast } from "@/components/ui/use-toast"; interface DeleteUserProps { - // eslint-disable-next-line react/require-default-props - isDeleteSelected?: boolean users: User[] setUsers: Dispatch> } -export default function DeleteUser({ isDeleteSelected, users, setUsers }: DeleteUserProps) { - +export default function DeleteUser({ users, setUsers }: DeleteUserProps) { + + const { toast } = useToast() + const deleteSelected = async () => { if (!users) return - const response = await securedFetch('/api/user/?isDelete=true', { - method: 'POST', + const response = await securedFetch('/api/user/', { + method: 'DELETE', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ users }) - }) + }, toast) if (response.ok) { - Toast("Success", "User deleted successfully") + toast({ + title: "Success", + description: "User deleted successfully", + }) setUsers(prev => prev.filter(user => !users.find(u => user.username === u.username))) } } @@ -36,10 +40,11 @@ export default function DeleteUser({ isDeleteSelected, users, setUsers }: Delete diff --git a/app/settings/users/Users.tsx b/app/settings/users/Users.tsx index 3cebe6a7..dcedc96c 100644 --- a/app/settings/users/Users.tsx +++ b/app/settings/users/Users.tsx @@ -1,12 +1,14 @@ +/* eslint-disable @typescript-eslint/no-use-before-define */ + "use client"; import React, { useEffect, useState } from "react"; -import { Checkbox } from "@/components/ui/checkbox"; -import { CheckedState } from "@radix-ui/react-checkbox"; -import { User } from "@/app/api/user/model"; -import { cn, prepareArg, securedFetch } from "@/lib/utils"; -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; +import { CreateUser, User } from "@/app/api/user/model"; +import { prepareArg, securedFetch } from "@/lib/utils"; import Combobox from "@/app/components/ui/combobox"; +import TableComponent, { Row } from "@/app/components/TableComponent"; +import { useToast } from "@/components/ui/use-toast"; +import { ToastAction } from "@/components/ui/toast"; import DeleteUser from "./DeleteUser"; import AddUser from "./AddUser"; @@ -20,40 +22,60 @@ const ROLES = [ export default function Users() { const [users, setUsers] = useState([]) - const [checked, setChecked] = useState(false) - const [hover, setHover] = useState("") + const [rows, setRows] = useState([]) + const { toast } = useToast() + + useEffect(() => { + setRows(users.map((user) => ({ + cells: [{ + value: user.username, + }, { + value: user.role, + }], + checked: false, + }))) + }, [users]) useEffect(() => { - const run = async () => { + (async () => { const result = await securedFetch("api/user", { method: 'GET', headers: { 'Content-Type': 'application/json' } - }) + }, toast) if (result.ok) { const data = await result.json() - setUsers(data.result) + setUsers(data.result.map((user: User) => ({ ...user, selected: false }))) + setRows(data.result.map((user: User) => ({ + cells: [{ + value: user.username, + }, { + value: user.role, + onChange: (value: string) => handleSetRole([user.username], [value], true) + }], + checked: false, + }))) } - } - run() + })() + }, []) - const handelSetRole = async (role: string, username?: string) => { - const updatedUsers = await Promise.all(users.map(async user => { - const selected = username ? user.username === username : user.selected + const handleSetRole = async (usernames: string[], role: string[], isUndo: boolean) => { + const oldRoles = usernames.map(username => users.find(user => user.username === username)!.role) + const updatedUsers = await Promise.all(users.map(async (user, i) => { - if (!selected) return user + if (!usernames.includes(user.username)) return user const result = await securedFetch(`api/user/${prepareArg(user.username)}/?role=${role}`, { method: 'PATCH' - }) + }, toast) if (result.ok) { return { ...user, - role + role: role.length === 1 ? role[0] : role[i] } } @@ -61,89 +83,67 @@ export default function Users() { })) setUsers(updatedUsers) + setRows(rows.map(row => { + if (!usernames.includes(row.cells[0].value as string)) return row + return { + ...row, + cells: [{ ...row.cells[0], value: role.length === 1 ? role[0] : role[usernames.indexOf(row.cells[0].value as string)] }], + checked: false + } + })) + toast({ + title: "Success", + description: `${usernames.join(", ")} role updated successfully`, + action: isUndo ? handleSetRole(usernames, oldRoles, false)}>Undo : undefined + }) + return true } + const handleAddUser = async ({ username, password, role }: CreateUser) => { + if (!role) { + toast({ + title: "Error", + description: "Select role is required", + variant: "destructive" + }) + return + } + + const response = await securedFetch('/api/user/', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ username, password, role }) + }, toast) + + if (response.ok) { + toast({ + title: "Success", + description: "User added successfully", + }) + setUsers(prev => [...prev, { username, role, selected: false }]) + } + } return (
-
- - user.selected)} setUsers={setUsers} /> - user.selected).length === 0} - type="Role" - options={ROLES} - setSelectedValue={(role) => { - setChecked(false) - handelSetRole(role) - }} - /> -
-
- - - - { - [ { - setChecked(check === true) - setUsers(prev => prev.map(user => { - const u = user - u.selected = check === true - return u - })) - }} - />, "USERNAME", "ROLE", ""].map((header, index) => ( - // eslint-disable-next-line react/no-array-index-key - {header} - )) - } - - - - { - users.map(({ username, role, selected }, index) => ( - setHover(username)} onMouseLeave={() => setHover("")} data-username={username} key={username} className={cn("border-none", !(index % 2) && "bg-[#57577B] hover:bg-[#57577B]")}> - - { - setUsers(prev => prev.map(currentUser => { - if (username !== currentUser.username) return currentUser - const u = currentUser - u.selected = check === true - return u - })) - }} /> - - {username} - - handelSetRole(r, username)} /> - - - { - hover === username && username !== "default" && - - } - - - )) - } - -
-
+ +
+ + row.checked).map(row => users.find(user => user.username === row.cells[0].value)!)} setUsers={setUsers} /> + row.checked).length === 0} + type="Role" + options={ROLES} + setSelectedValue={(role) => { handleSetRole(rows.filter(row => row.checked).map(row => row.cells[0].value as string), [role], true) }} + /> +
+
); } \ No newline at end of file diff --git a/components/ui/carousel.tsx b/components/ui/carousel.tsx new file mode 100644 index 00000000..d75761f3 --- /dev/null +++ b/components/ui/carousel.tsx @@ -0,0 +1,262 @@ +"use client" + +import * as React from "react" +import useEmblaCarousel, { + type UseEmblaCarouselType, +} from "embla-carousel-react" +import { ArrowLeft, ArrowRight } from "lucide-react" + +import { cn } from "@/lib/utils" +import { Button } from "@/components/ui/button" + +type CarouselApi = UseEmblaCarouselType[1] +type UseCarouselParameters = Parameters +type CarouselOptions = UseCarouselParameters[0] +type CarouselPlugin = UseCarouselParameters[1] + +type CarouselProps = { + opts?: CarouselOptions + plugins?: CarouselPlugin + orientation?: "horizontal" | "vertical" + setApi?: (api: CarouselApi) => void +} + +type CarouselContextProps = { + carouselRef: ReturnType[0] + api: ReturnType[1] + scrollPrev: () => void + scrollNext: () => void + canScrollPrev: boolean + canScrollNext: boolean +} & CarouselProps + +const CarouselContext = React.createContext(null) + +function useCarousel() { + const context = React.useContext(CarouselContext) + + if (!context) { + throw new Error("useCarousel must be used within a ") + } + + return context +} + +const Carousel = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes & CarouselProps +>( + ( + { + orientation = "horizontal", + opts, + setApi, + plugins, + className, + children, + ...props + }, + ref + ) => { + const [carouselRef, api] = useEmblaCarousel( + { + ...opts, + axis: orientation === "horizontal" ? "x" : "y", + }, + plugins + ) + const [canScrollPrev, setCanScrollPrev] = React.useState(false) + const [canScrollNext, setCanScrollNext] = React.useState(false) + + const onSelect = React.useCallback((api: CarouselApi) => { + if (!api) { + return + } + + setCanScrollPrev(api.canScrollPrev()) + setCanScrollNext(api.canScrollNext()) + }, []) + + const scrollPrev = React.useCallback(() => { + api?.scrollPrev() + }, [api]) + + const scrollNext = React.useCallback(() => { + api?.scrollNext() + }, [api]) + + const handleKeyDown = React.useCallback( + (event: React.KeyboardEvent) => { + if (event.key === "ArrowLeft") { + event.preventDefault() + scrollPrev() + } else if (event.key === "ArrowRight") { + event.preventDefault() + scrollNext() + } + }, + [scrollPrev, scrollNext] + ) + + React.useEffect(() => { + if (!api || !setApi) { + return + } + + setApi(api) + }, [api, setApi]) + + React.useEffect(() => { + if (!api) { + return + } + + onSelect(api) + api.on("reInit", onSelect) + api.on("select", onSelect) + + return () => { + api?.off("select", onSelect) + } + }, [api, onSelect]) + + return ( + +
+ {children} +
+
+ ) + } +) +Carousel.displayName = "Carousel" + +const CarouselContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const { carouselRef, orientation } = useCarousel() + + return ( +
+
+
+ ) +}) +CarouselContent.displayName = "CarouselContent" + +const CarouselItem = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const { orientation } = useCarousel() + + return ( +
+ ) +}) +CarouselItem.displayName = "CarouselItem" + +const CarouselPrevious = React.forwardRef< + HTMLButtonElement, + React.ComponentProps +>(({ className, variant = "outline", size = "icon", ...props }, ref) => { + const { orientation, scrollPrev, canScrollPrev } = useCarousel() + + return ( + + ) +}) +CarouselPrevious.displayName = "CarouselPrevious" + +const CarouselNext = React.forwardRef< + HTMLButtonElement, + React.ComponentProps +>(({ className, variant = "outline", size = "icon", ...props }, ref) => { + const { orientation, scrollNext, canScrollNext } = useCarousel() + + return ( + + ) +}) +CarouselNext.displayName = "CarouselNext" + +export { + type CarouselApi, + Carousel, + CarouselContent, + CarouselItem, + CarouselPrevious, + CarouselNext, +} diff --git a/components/ui/drawer.tsx b/components/ui/drawer.tsx new file mode 100644 index 00000000..88ee3d98 --- /dev/null +++ b/components/ui/drawer.tsx @@ -0,0 +1,118 @@ +"use client" + +import * as React from "react" +import { Drawer as DrawerPrimitive } from "vaul" + +import { cn } from "@/lib/utils" + +const Drawer = ({ + shouldScaleBackground = true, + ...props +}: React.ComponentProps) => ( + +) +Drawer.displayName = "Drawer" + +const DrawerTrigger = DrawerPrimitive.Trigger + +const DrawerPortal = DrawerPrimitive.Portal + +const DrawerClose = DrawerPrimitive.Close + +const DrawerOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName + +const DrawerContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + +
+ {children} + + +)) +DrawerContent.displayName = "DrawerContent" + +const DrawerHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DrawerHeader.displayName = "DrawerHeader" + +const DrawerFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DrawerFooter.displayName = "DrawerFooter" + +const DrawerTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DrawerTitle.displayName = DrawerPrimitive.Title.displayName + +const DrawerDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DrawerDescription.displayName = DrawerPrimitive.Description.displayName + +export { + Drawer, + DrawerPortal, + DrawerOverlay, + DrawerTrigger, + DrawerClose, + DrawerContent, + DrawerHeader, + DrawerFooter, + DrawerTitle, + DrawerDescription, +} diff --git a/components/ui/navigation-menu.tsx b/components/ui/navigation-menu.tsx new file mode 100644 index 00000000..227807b9 --- /dev/null +++ b/components/ui/navigation-menu.tsx @@ -0,0 +1,128 @@ +import * as React from "react" +import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu" +import { cva } from "class-variance-authority" +import { ChevronDown } from "lucide-react" + +import { cn } from "@/lib/utils" + +const NavigationMenu = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + {children} + + +)) +NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName + +const NavigationMenuList = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName + +const NavigationMenuItem = NavigationMenuPrimitive.Item + +const navigationMenuTriggerStyle = cva( + "group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50" +) + +const NavigationMenuTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + {children}{" "} + +)) +NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName + +const NavigationMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName + +const NavigationMenuLink = NavigationMenuPrimitive.Link + +const NavigationMenuViewport = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( +
+ +
+)) +NavigationMenuViewport.displayName = + NavigationMenuPrimitive.Viewport.displayName + +const NavigationMenuIndicator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +
+ +)) +NavigationMenuIndicator.displayName = + NavigationMenuPrimitive.Indicator.displayName + +export { + navigationMenuTriggerStyle, + NavigationMenu, + NavigationMenuList, + NavigationMenuItem, + NavigationMenuContent, + NavigationMenuTrigger, + NavigationMenuLink, + NavigationMenuIndicator, + NavigationMenuViewport, +} diff --git a/components/ui/select.tsx b/components/ui/select.tsx new file mode 100644 index 00000000..cbe5a36b --- /dev/null +++ b/components/ui/select.tsx @@ -0,0 +1,160 @@ +"use client" + +import * as React from "react" +import * as SelectPrimitive from "@radix-ui/react-select" +import { Check, ChevronDown, ChevronUp } from "lucide-react" + +import { cn } from "@/lib/utils" + +const Select = SelectPrimitive.Root + +const SelectGroup = SelectPrimitive.Group + +const SelectValue = SelectPrimitive.Value + +const SelectTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + span]:line-clamp-1", + className + )} + {...props} + > + {children} + + + + +)) +SelectTrigger.displayName = SelectPrimitive.Trigger.displayName + +const SelectScrollUpButton = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName + +const SelectScrollDownButton = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +SelectScrollDownButton.displayName = + SelectPrimitive.ScrollDownButton.displayName + +const SelectContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, position = "popper", ...props }, ref) => ( + + + + + {children} + + + + +)) +SelectContent.displayName = SelectPrimitive.Content.displayName + +const SelectLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SelectLabel.displayName = SelectPrimitive.Label.displayName + +const SelectItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + + {children} + +)) +SelectItem.displayName = SelectPrimitive.Item.displayName + +const SelectSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SelectSeparator.displayName = SelectPrimitive.Separator.displayName + +export { + Select, + SelectGroup, + SelectValue, + SelectTrigger, + SelectContent, + SelectLabel, + SelectItem, + SelectSeparator, + SelectScrollUpButton, + SelectScrollDownButton, +} diff --git a/components/ui/sheet.tsx b/components/ui/sheet.tsx new file mode 100644 index 00000000..a37f17ba --- /dev/null +++ b/components/ui/sheet.tsx @@ -0,0 +1,140 @@ +"use client" + +import * as React from "react" +import * as SheetPrimitive from "@radix-ui/react-dialog" +import { cva, type VariantProps } from "class-variance-authority" +import { X } from "lucide-react" + +import { cn } from "@/lib/utils" + +const Sheet = SheetPrimitive.Root + +const SheetTrigger = SheetPrimitive.Trigger + +const SheetClose = SheetPrimitive.Close + +const SheetPortal = SheetPrimitive.Portal + +const SheetOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SheetOverlay.displayName = SheetPrimitive.Overlay.displayName + +const sheetVariants = cva( + "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500", + { + variants: { + side: { + top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top", + bottom: + "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom", + left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm", + right: + "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm", + }, + }, + defaultVariants: { + side: "right", + }, + } +) + +interface SheetContentProps + extends React.ComponentPropsWithoutRef, + VariantProps {} + +const SheetContent = React.forwardRef< + React.ElementRef, + SheetContentProps +>(({ side = "right", className, children, ...props }, ref) => ( + + + + {children} + + + Close + + + +)) +SheetContent.displayName = SheetPrimitive.Content.displayName + +const SheetHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +SheetHeader.displayName = "SheetHeader" + +const SheetFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +SheetFooter.displayName = "SheetFooter" + +const SheetTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SheetTitle.displayName = SheetPrimitive.Title.displayName + +const SheetDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SheetDescription.displayName = SheetPrimitive.Description.displayName + +export { + Sheet, + SheetPortal, + SheetOverlay, + SheetTrigger, + SheetClose, + SheetContent, + SheetHeader, + SheetFooter, + SheetTitle, + SheetDescription, +} diff --git a/components/ui/toast.tsx b/components/ui/toast.tsx index a8224775..7b26f633 100644 --- a/components/ui/toast.tsx +++ b/components/ui/toast.tsx @@ -27,7 +27,7 @@ const toastVariants = cva( { variants: { variant: { - default: "border bg-background text-foreground", + default: "bg-background", destructive: "destructive group border-destructive bg-destructive text-destructive-foreground", }, @@ -75,7 +75,7 @@ const ToastClose = React.forwardRef< ) => { @@ -18,9 +21,10 @@ const postRequest = async (url: string, body: any, availableRequest?: APIRequest }; const requestContext = availableRequest || (await request.newContext()); - return await requestContext.post(url, requestOptions); + const response = await requestContext.post(url, requestOptions); + return response; }; - + const deleteRequest = async (url: string, body?: any, headers?: Record) => { const requestOptions = { data: body, @@ -28,9 +32,10 @@ const deleteRequest = async (url: string, body?: any, headers?: Record(pageClass: new (page: Page) => T, url?: string) { + async createNewPage(PageClass: new (page: Page) => T, url?: string) { if (!this.browser) { this.browser = await chromium.launch(); } @@ -23,7 +23,7 @@ export default class BrowserWrapper { await this.navigateTo(url) } - const pageInstance = new pageClass(this.page); + const pageInstance = new PageClass(this.page); return pageInstance; } @@ -52,11 +52,15 @@ export default class BrowserWrapper { await this.page.goto(url); await this.page.waitForLoadState('networkidle'); } - + async closePage() { - this.page ? await this.page.close() : this.page = null; + if (this.page) { + await this.page.close(); + } else { + this.page = null; + } } - + async closeBrowser() { if (this.browser) { await this.browser.close(); diff --git a/e2e/infra/utils.ts b/e2e/infra/utils.ts index 4b3ed236..9175cc18 100644 --- a/e2e/infra/utils.ts +++ b/e2e/infra/utils.ts @@ -1,22 +1,24 @@ +/* eslint-disable no-param-reassign */ +/* eslint-disable no-await-in-loop */ import { Locator, Page } from "playwright"; -export const waitForElementToBeVisible = async (locator:Locator,time=400,retry=5):Promise => { +export function delay(ms: number) { + return new Promise(resolve => { setTimeout(resolve, ms) }); +} - while(retry >0){ - if(await locator.isVisible()){ - return true - } - retry = retry-1 - await delay(time) +export const waitForElementToBeVisible = async (locator: Locator, time = 400, retry = 5): Promise => { + + while (retry > 0) { + if (await locator.isVisible()) { + return true + } + retry -= 1 + await delay(time) } return false } -export function delay(ms: number) { - return new Promise( resolve => setTimeout(resolve, ms) ); -} - -export const waitForTimeOut = async (page: Page, time=500) => { +export const waitForTimeOut = async (page: Page, time = 500) => { await page.waitForTimeout(time); } @@ -28,7 +30,7 @@ export async function waitForURL(page: Page, expectedURL: string, timeout: numbe if (currentURL === expectedURL) { return; } - await new Promise(resolve => setTimeout(resolve, interval)); + await new Promise(resolve => { setTimeout(resolve, interval) }); elapsed += interval; } diff --git a/e2e/logic/POM/graphPage.ts b/e2e/logic/POM/graphPage.ts index ecdcd8d1..52261485 100644 --- a/e2e/logic/POM/graphPage.ts +++ b/e2e/logic/POM/graphPage.ts @@ -1,123 +1,119 @@ -import { Locator, Download } from "@playwright/test"; +import { Locator, Download } from "@playwright/test"; import BasePage from "@/e2e/infra/ui/basePage"; import { waitForTimeOut } from "@/e2e/infra/utils"; -export class graphPage extends BasePage { +export default class GraphPage extends BasePage { private get graphsMenu(): Locator { - return this.page.locator("//button[@data-type='selectGraph']"); - } - - private graphsMenuByName(graph: string): Locator { - return this.page.getByRole("button", { name : `${graph}`}); - } - - private get dropDownMenuGraphs(): Locator { - return this.page.locator("//div[@role='menuitem']"); + return this.page.getByRole("combobox"); } private get manageGraphBtn(): Locator { - return this.page.locator("//button[p[contains(text(), 'Manage Graphs')]]") - } - - private get threeDotsBtn(): Locator { - return this.page.locator("(//button[p[text()='...']])[1]") + return this.page.getByRole("button", { name: "Manage Graphs" }) } - private get deleteIconSvg(): Locator { - return this.page.locator("//div[@role='menuitem'][2]//button") - } - - private get confirmGraphDeleteBtn(): Locator { - return this.page.locator("//button[contains(text(), 'Continue')]") + private get deleteGraphBtn(): Locator { + return this.page.getByRole('button', { name: 'Delete' }) } private get addGraphBtnInNavBar(): Locator { - return this.page.getByRole("button", { name : "New Graph"}); + return this.page.getByText("Create New Graph"); } private get graphNameInput(): Locator { - return this.page.locator("//div/p[contains(text(), 'Name')]/following-sibling::input"); + return this.page.getByRole("textbox"); } private get createGraphBtn(): Locator { - return this.page.getByRole("button", { name : "Create"}); + return this.page.getByRole("button", { name: "Create your Graph" }); } private get exportDataBtn(): Locator { - return this.page.getByRole("button", { name : "Export Data"}); + return this.page.getByRole("button", { name: "Export Data" }); + } + + private get exportDataConfirmBtn(): Locator { + return this.page.getByRole("button", { name: "Download" }); } private get findGraphInMenu(): (graph: string) => Locator { - return (graph: string) => this.page.locator(`//tbody//tr/td[1][contains(text(), '${graph}')]`); + return (graph: string) => this.page.getByRole('row', { name: graph, exact: true }); + } + + private get checkGraphInMenu(): (graph: string) => Locator { + return (graph: string) => this.findGraphInMenu(graph).getByRole('checkbox') } - private get deleteGraphInMenu(): (graph: string) => Locator { - return (graph: string) => this.page.locator(`//tbody//tr/td[1][contains(text(), '${graph}')]/parent::tr//td[3]/button`); + private get deleteAllGraphInMenu(): Locator { + return this.page.getByRole('row', { name: 'Name', exact: true }).getByRole('checkbox') } private get graphMenuElements(): Locator { - return this.page.locator("//tbody/tr"); + return this.page.getByRole('row'); + } + + private get deleteGraphConfirmBtn(): Locator { + return this.page.getByRole('button', { name: 'Delete Graph' }) } async countGraphsInMenu(): Promise { await waitForTimeOut(this.page, 1000); - await this.graphsMenu.click(); - await this.manageGraphBtn.click(); - const count = await this.graphMenuElements.count(); - await this.refreshPage(); - return count; - } - - async removeGraph(): Promise { - await this.threeDotsBtn.click() - await this.deleteIconSvg.click() - await this.confirmGraphDeleteBtn.click() + + if (await this.graphsMenu.isEnabled()) { + await this.graphsMenu.click(); + await this.manageGraphBtn.click(); + const count = await this.graphMenuElements.count(); + await this.refreshPage(); + return count; + } + + return 0; } async removeAllGraphs(): Promise { await waitForTimeOut(this.page, 1000); - const graphCount = await this.countGraphsInMenu(); - await this.graphsMenu.click(); - await this.manageGraphBtn.click() - for(let i = graphCount; i >= 1; i--){ - await this.removeGraph(); + if (await this.graphsMenu.isEnabled()) { + await this.graphsMenu.click(); + await this.manageGraphBtn.click(); + await this.deleteAllGraphInMenu.click() + await this.deleteGraphBtn.click() + await this.deleteGraphConfirmBtn.click(); } } - async addGraph(graphName : string): Promise{ + async addGraph(graphName: string): Promise { await this.addGraphBtnInNavBar.click() await this.graphNameInput.fill(graphName); await this.createGraphBtn.click() } - async clickOnExportDataBtn(): Promise { - await this.page.waitForLoadState('networkidle'); + async exportGraph(): Promise { + await this.page.waitForLoadState('networkidle'); const [download] = await Promise.all([ this.page.waitForEvent('download'), - this.exportDataBtn.click() + this.exportDataBtn.click(), + this.exportDataConfirmBtn.click() ]); return download; } - async verifyGraphExists(graph : string): Promise{ + async verifyGraphExists(graph: string): Promise { + if (await this.graphsMenu.isDisabled()) return false; + await this.graphsMenu.click(); await this.manageGraphBtn.click(); - return await this.findGraphInMenu(graph).isVisible(); + const isVisible = await this.findGraphInMenu(graph).isVisible(); + + return isVisible; } - async verifyGraphExistsByName(graph : string): Promise{ - await this.graphsMenuByName(graph).click(); + async deleteGraph(graph: string): Promise { + await this.graphsMenu.click(); await this.manageGraphBtn.click(); - return await this.findGraphInMenu(graph).isVisible(); + await this.checkGraphInMenu(graph).click(); + await this.deleteGraphBtn.click(); + await this.deleteGraphConfirmBtn.click(); } - async deleteGraph(graph : string): Promise { - await this.graphsMenuByName(graph).click(); - await this.manageGraphBtn.click(); - await this.deleteGraphInMenu(graph).click(); - await this.deleteIconSvg.click() - await this.confirmGraphDeleteBtn.click() - } } \ No newline at end of file diff --git a/e2e/logic/POM/loginPage.ts b/e2e/logic/POM/loginPage.ts index a017ce12..3f32f09c 100644 --- a/e2e/logic/POM/loginPage.ts +++ b/e2e/logic/POM/loginPage.ts @@ -3,29 +3,39 @@ import BasePage from "@/e2e/infra/ui/basePage"; import { waitForURL } from "@/e2e/infra/utils"; import urls from '../../config/urls.json' -export class LoginPage extends BasePage { +export default class LoginPage extends BasePage { + private get connectBtn(): Locator { - return this.page.getByRole("button", { name : "Connect"}); + return this.page.getByRole("button", { name: "Log in" }); } private get usernameInput(): Locator { - return this.page.locator("//input[@id='username']"); + return this.page.locator("//input[@id='Username']"); } private get passwordInput(): Locator { - return this.page.locator("//input[@id='password']"); + return this.page.locator("//input[@id='Password']"); + } + + private get dissmissDialogCheckbox(): Locator { + return this.page.locator("//div[p[text()=\"Don't show this again\"]]//button"); } async clickOnConnect(): Promise { await this.connectBtn.click(); - await waitForURL(this.page, urls.graphUrl); + await waitForURL(this.page, urls.graphUrl); } async connectWithCredentials(username: string, password: string): Promise { await this.usernameInput.fill(username) await this.passwordInput.fill(password) await this.connectBtn.click(); - await waitForURL(this.page, urls.graphUrl); - } + await waitForURL(this.page, urls.graphUrl); + } + + async dismissDialogAtStart(): Promise{ + await this.dissmissDialogCheckbox.click(); + await this.page.mouse.click(10, 10); + } } \ No newline at end of file diff --git a/e2e/logic/POM/navBarComponent.ts b/e2e/logic/POM/navBarComponent.ts index 58d65158..1560d96e 100644 --- a/e2e/logic/POM/navBarComponent.ts +++ b/e2e/logic/POM/navBarComponent.ts @@ -1,45 +1,41 @@ import { Locator, Page } from "playwright"; import BasePage from "@/e2e/infra/ui/basePage"; -import { waitForTimeOut, waitForURL } from "@/e2e/infra/utils"; -import urls from '../../config/urls.json' +import { waitForURL } from "@/e2e/infra/utils"; +import urls from '../../config/urls.json' export default class NavBarComponent extends BasePage { private get falkorDBLogo(): Locator { - return this.page.locator("//a[@aria-label='FalkorDB']"); + return this.page.getByLabel("FalkorDB"); } - + private get graphsButton(): Locator { - return this.page.getByRole("button", { name: "Graphs"}); + return this.page.getByRole("button", { name: "Graphs" }); } - + private get schemaButton(): Locator { - return this.page.getByRole("button", { name: "Schemas"}); + return this.page.getByRole("button", { name: "Schemas" }); } private get helpButton(): Locator { - return this.page.getByRole("button", { name : "help"}) + return this.page.getByRole("button", { name: "Help" }) } private get documentationButton(): Locator { - return this.page.locator("//a[@title='Documentation']") + return this.page.getByRole("link", { name: "Documentation" }) } private get supportButton(): Locator { - return this.page.locator("//a[@title='Support']") + return this.page.getByRole("link", { name: "Support" }) } private get settingsButton(): Locator { - return this.page.locator("//button[@title='Settings']") + return this.page.getByRole("button", { name: "Settings" }) } - private get clickOnUser(): (user: string) => Locator { - return (user: string) => this.page.getByRole("button", { name : `${user}`}) - } - private get LogoutButton(): Locator { - return this.page.locator("//div[contains(text(), 'Logout')]") + return this.page.getByRole("button", { name: "Log Out" }) } async clickOnFalkorLogo(): Promise { @@ -48,8 +44,9 @@ export default class NavBarComponent extends BasePage { async clickOnGraphsButton(): Promise { await this.graphsButton.click(); + await waitForURL(this.page, urls.graphUrl); } - + async clickOnSchemasButton(): Promise { await this.schemaButton.click(); await waitForURL(this.page, urls.schemaUrl); @@ -72,19 +69,19 @@ export default class NavBarComponent extends BasePage { await waitForURL(this.page, urls.settingsUrl); } - async isSettingsButtonEnabled(): Promise { - return await this.settingsButton.isEnabled(); + async isSettingsButtonEnabled(): Promise { + const isEnabled = await this.settingsButton.isEnabled(); + return isEnabled; } - async Logout(user: string): Promise { - await this.page.waitForLoadState('networkidle'); - await this.clickOnUser(user).click() + async Logout(): Promise { + await this.page.waitForLoadState('networkidle'); await this.LogoutButton.click() await waitForURL(this.page, urls.loginUrl); } async clickOnFalkor(): Promise { - await this.page.waitForLoadState('networkidle'); + await this.page.waitForLoadState('networkidle'); const [newPage] = await Promise.all([ this.page.waitForEvent('popup'), this.clickOnFalkorLogo(), @@ -93,7 +90,7 @@ export default class NavBarComponent extends BasePage { } async clickOnDocumentation(): Promise { - await this.page.waitForLoadState('networkidle'); + await this.page.waitForLoadState('networkidle'); const [newPage] = await Promise.all([ this.page.waitForEvent('popup'), this.clickOnHelpBtn(), @@ -103,7 +100,7 @@ export default class NavBarComponent extends BasePage { } async clickOnSupport(): Promise { - await this.page.waitForLoadState('networkidle'); + await this.page.waitForLoadState('networkidle'); const [newPage] = await Promise.all([ this.page.waitForEvent('popup'), this.clickOnHelpBtn(), diff --git a/e2e/logic/POM/settingsConfigPage.ts b/e2e/logic/POM/settingsConfigPage.ts index df893f2e..3b6eea73 100644 --- a/e2e/logic/POM/settingsConfigPage.ts +++ b/e2e/logic/POM/settingsConfigPage.ts @@ -1,37 +1,36 @@ -import { Locator, Page } from "@playwright/test"; +import { Locator } from "@playwright/test"; import BasePage from "@/e2e/infra/ui/basePage"; export default class SettingsConfigPage extends BasePage { - private get roleContentValue() : (role : string) => Locator { - return (role : string) => this.page.locator(`//tbody/tr[@data-id='${role}']/td/button`) + private get roleContentValue(): (role: string) => Locator { + return (role: string) => this.page.locator(`//tbody/tr[@data-id='${role}']/td[3]/div/p`) } - async getRoleContentValue(role : string): Promise{ - return await this.roleContentValue(role).getAttribute('title') + async getRoleContentValue(role: string): Promise { + const value = await this.roleContentValue(role).getAttribute('title') + return value } - private get clickOnRoleValue() : (role : string) => Locator { - return (role : string) => this.page.locator(`//tbody//tr[@data-id='${role}']/td[3]/button`) + private get EditRoleButton(): (role: string) => Locator { + return (role: string) => this.page.locator(`//tbody//tr[@data-id='${role}']/td[3]/div/div/button`) } - private get roleValueInput() : (role : string) => Locator { - return (role : string) => this.page.locator(`//tbody//tr[@data-id='${role}']/td[3]/div/input`) + private get roleValueInput(): (role: string) => Locator { + return (role: string) => this.page.locator(`//tbody//tr[@data-id='${role}']/td[3]/div/input`) } - private get confirmValueInputBtn() : (role : string) => Locator { - return (role : string) => this.page.locator(`//tbody//tr[@data-id='${role}']/td[3]/div/button[2]`) + private get confirmValueInputBtn(): (role: string) => Locator { + return (role: string) => this.page.locator(`//tbody//tr[@data-id='${role}']/td[3]/div/div/button[1]`) } - private get getRoleValue() : (role : string) => Locator { - return (role : string) => this.page.locator(`//tbody//tr[@data-id='${role}']/td[3]/button/p`) - } - - async modifyRoleValue(role : string, input : string): Promise { - await this.clickOnRoleValue(role).click(); + async modifyRoleValue(role: string, input: string): Promise { + await this.roleContentValue(role).hover(); + await this.EditRoleButton(role).click(); await this.roleValueInput(role).fill(input); await this.confirmValueInputBtn(role).click(); - return await this.getRoleValue(role).getAttribute('title') + const value = await this.getRoleContentValue(role) + return value } } \ No newline at end of file diff --git a/e2e/logic/POM/settingsUsersPage.ts b/e2e/logic/POM/settingsUsersPage.ts index 9f9c1dd5..6e282435 100644 --- a/e2e/logic/POM/settingsUsersPage.ts +++ b/e2e/logic/POM/settingsUsersPage.ts @@ -1,6 +1,6 @@ -import { Locator, Page } from "@playwright/test"; +import { Locator } from "@playwright/test"; import BasePage from "@/e2e/infra/ui/basePage"; -import { waitForElementToBeVisible, waitForTimeOut } from '../../infra/utils' +import { waitForTimeOut } from '../../infra/utils' export default class SettingsUsersPage extends BasePage { @@ -12,134 +12,114 @@ export default class SettingsUsersPage extends BasePage { return this.page.getByRole("button", { name: "Add User" }); } + private get submitUserAddition(): Locator { + return this.page.getByRole("button", { name: "Submit" }); + } + + private get selectRoleBtnInAddUser(): Locator { + return this.page.locator("//div[@role='dialog']//button[span[text()='Select Role']]") + } + private get selectRoleBtn(): Locator { - return this.page.getByRole("button", {name: "Select Role"}) + return this.page.locator("//button[span[text()='Select Role']]") } - private get selectUserRoleInAddUser(): (role: string) => Locator { - return (role: string) => this.page.getByRole("button", { name: role }); + private get selectUserRole(): (role: string) => Locator { + return (role: string) => this.page.locator(`//ul//div[@role='option'][span[contains(text(), '${role}')]]`) } private get userNameField(): Locator { - return this.page.locator("//p[contains(text(), 'Username')]/following-sibling::input"); + return this.page.locator("//input[@id='Username']"); } private get passwordField(): Locator { - return this.page.locator("//p[normalize-space(text()) = 'Password']/following::input[1]"); + return this.page.locator("//input[@id='Password']"); } private get confirmPasswordField(): Locator { - return this.page.locator("//p[contains(text(), 'Confirm Password')]/following-sibling::input"); + return this.page.locator("//input[@id='Confirm Password']"); } private get confirmUserDeleteMsg(): Locator { return this.page.getByRole("button", { name: "Continue" }); } - private get userRoleBtnInTable(): (selectedUser: string) => Locator { - return (selectedUser: string) => this.page.locator(`//tbody/tr[@data-username='${selectedUser}']/td[3]/button`); - } - - private get selectUserRoleDropDownInTable(): (role : number) => Locator { - return (role: number) => this.page.locator(`//div[@role='menu']//div[@role='menuitem'][${role}]//button`); - } - - private get userRoleContentInTable(): (selectedUser: string) => Locator { - return (selectedUser: string) => this.page.locator(`//tbody/tr[@data-username='${selectedUser}']/td[3]/button/p`); + private get userRoleContent(): (selectedUser: string) => Locator { + return (selectedUser: string) => this.page.locator(`//tbody/tr[@data-id='${selectedUser}']/td[3]/div/p`); } private get userCheckboxBtn(): (selectedUser: string) => Locator { - return (selectedUser: string) => this.page.locator(`//tbody/tr[@data-username='${selectedUser}']/td[1]/button`); + return (selectedUser: string) => this.page.locator(`//tbody/tr[@data-id='${selectedUser}']/td[1]/button`); } - private get findUserNameInTable() : (selectedUser : string) => Locator { - return (selectedUser : string) => this.page.locator(`//tbody/tr[@data-username='${selectedUser}']/td[2]`) - } - - private get hoverDeleteBtnPerUserInTable() : (selectedUser : string) => Locator { - return (selectedUser : string) => this.page.locator(`//tbody/tr[@data-username='${selectedUser}']/td[4]/button`) + private get findUserNameInTable(): (selectedUser: string) => Locator { + return (selectedUser: string) => this.page.locator(`//tbody/tr[@data-id='${selectedUser}']/td[2]`) } private get deleteUsersBtn(): Locator { - return this.page.getByRole("button", {name: "Delete Users"}) + return this.page.getByRole("button", { name: "Delete Users" }) } - private get selectRoleInTable() : (role : string) => Locator { - return (role : string) => this.page.getByRole("button", { name: role }) - } - async navigateToUserTab(): Promise { await this.page.waitForLoadState('networkidle'); await this.usersTabBtn.click(); } - async verifyUserExists(selectedUser : string): Promise{ - await this.page.waitForLoadState('networkidle'); - return await this.findUserNameInTable(selectedUser).isVisible(); + async verifyUserExists(selectedUser: string): Promise { + await this.page.waitForLoadState('networkidle'); + const isVisible = await this.findUserNameInTable(selectedUser).isVisible(); + return isVisible; } async addUser(userDetails: { [key: string]: string }): Promise { - await this.page.waitForLoadState('networkidle'); + await this.page.waitForLoadState('networkidle'); await this.addUserButton.click(); - await this.selectRoleBtn.click(); - await this.selectUserRoleInAddUser(userDetails.role).click(); await this.userNameField.fill(userDetails.userName); await this.passwordField.fill(userDetails.password); await this.confirmPasswordField.fill(userDetails.confirmPassword); - await this.addUserButton.click(); + if (userDetails.role) { + await this.selectRoleBtnInAddUser.click(); + await this.selectUserRole(userDetails.role).click(); + } + await this.submitUserAddition.click(); await waitForTimeOut(this.page, 1500) } - async getUserRole(selectedUser : string): Promise { - await this.page.waitForLoadState('networkidle'); - return await this.userRoleContentInTable(selectedUser).textContent(); + async getUserRole(selectedUser: string): Promise { + await this.page.waitForLoadState('networkidle'); + const role = await this.userRoleContent(selectedUser).textContent(); + return role; } - async modifyUserRole(selectedUser : string, role : number): Promise { - await this.page.waitForLoadState('networkidle'); - await this.userRoleBtnInTable(selectedUser).click(); - await this.selectUserRoleDropDownInTable(role).click(); + async modifyUserRole(selectedUser: string, role: string): Promise { + await this.page.waitForLoadState('networkidle'); + await this.userCheckboxBtn(selectedUser).click(); + await this.selectRoleBtn.click(); + await this.selectUserRole(role).click(); await waitForTimeOut(this.page, 1500) } - async modifyTwoUsersRolesByCheckbox(selectedUser1 : string, selectedUser2 : string, role : string): Promise { - await this.page.waitForLoadState('networkidle'); + async modifyTwoUsersRoles(selectedUser1: string, selectedUser2: string, role: string): Promise { + await this.page.waitForLoadState('networkidle'); await this.userCheckboxBtn(selectedUser1).click(); await this.userCheckboxBtn(selectedUser2).click(); await this.selectRoleBtn.click(); - await this.selectRoleInTable(role).click() + await this.selectUserRole(role).click() } - async deleteTwoUsersByCheckbox(selectedUser1 : string, selectedUser2 : string): Promise { - await this.page.waitForLoadState('networkidle'); + async deleteTwoUsers(selectedUser1: string, selectedUser2: string): Promise { + await this.page.waitForLoadState('networkidle'); await this.userCheckboxBtn(selectedUser1).click() await this.userCheckboxBtn(selectedUser2).click() - await this.deleteUsersBtn.click() + await this.deleteUsersBtn.click() await this.confirmUserDeleteMsg.click() await waitForTimeOut(this.page, 1500) } - async attemptToAddUserWithoutRole(userDetails: { [key: string]: string }): Promise { - await this.page.waitForLoadState('networkidle'); - await this.addUserButton.click(); - await this.userNameField.fill(userDetails.userName); - await this.passwordField.fill(userDetails.password); - await this.confirmPasswordField.fill(userDetails.confirmPassword); - await this.addUserButton.click(); - } - - async removeUserByCheckbox(selectedUser : string): Promise{ + async removeUser(selectedUser: string): Promise { await this.page.waitForLoadState('networkidle'); await this.userCheckboxBtn(selectedUser).click(); await this.deleteUsersBtn.click(); await this.confirmUserDeleteMsg.click(); } - - async removeUserByHover(selectedUser : string): Promise { - await this.page.waitForLoadState('networkidle'); - await this.findUserNameInTable(selectedUser).hover(); - await this.hoverDeleteBtnPerUserInTable(selectedUser).click(); - await this.confirmUserDeleteMsg.click(); - } - } \ No newline at end of file diff --git a/e2e/logic/api/apiCalls.ts b/e2e/logic/api/apiCalls.ts index 852a9dba..26881060 100644 --- a/e2e/logic/api/apiCalls.ts +++ b/e2e/logic/api/apiCalls.ts @@ -1,3 +1,6 @@ +/* eslint-disable class-methods-use-this */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + import { deleteRequest, getRequest, postRequest } from "../../infra/api/apiRequests"; import urls from '../../config/urls.json' import { AddGraphResponse } from "./responses/addGraphResponse"; @@ -6,53 +9,54 @@ import { ModifySettingsRoleResponse } from "./responses/modifySettingsRoleRespon import { GetSettingsRoleValue } from "./responses/getSettingsRoleValue"; import { CreateUsersResponse } from "./responses/createUsersResponse"; import { DeleteUsersResponse } from "./responses/deleteUsersResponse"; -import { runQueryResponse } from "./responses/runQueryResponse"; +import { RunQueryResponse } from "./responses/runQueryResponse"; +import { GetUsersResponse } from "./responses/getUsersResponse"; -export class ApiCalls{ +export default class ApiCalls { - async addGraph(graphName: string, data? :any): Promise{ - const result = await getRequest(urls.api.addGraphUrl + graphName + "?query=RETURN%201" ,data) + async addGraph(graphName: string, data?: any): Promise { + const result = await getRequest(`${urls.api.addGraphUrl + graphName}?query=RETURN%201`, data) const jsonData = await result.json(); return jsonData } - - async removeGraph(graphName: string): Promise{ + + async removeGraph(graphName: string): Promise { const result = await deleteRequest(urls.api.deleteGraphUrl + graphName) const jsonData = await result.json(); return jsonData } - async modifySettingsRole(roleName: string, roleValue : string, data? :any): Promise{ - const result = await postRequest(urls.api.settingsConfig + roleName + "&value=" + roleValue, data) + async modifySettingsRole(roleName: string, roleValue: string, data?: any): Promise { + const result = await postRequest(`${urls.api.settingsConfig + roleName}&value=${roleValue}`, data) const jsonData = await result.json(); return jsonData } - async getSettingsRoleValue(roleName: string, data? :any): Promise{ + async getSettingsRoleValue(roleName: string, data?: any): Promise { const result = await getRequest(urls.api.settingsConfig + roleName, data) const jsonData = await result.json(); return jsonData } - async getUsers(data? :any): Promise{ + async getUsers(data?: any): Promise { const result = await getRequest(urls.api.settingsUsers, data) const jsonData = await result.json(); return jsonData } - async createUsers(data? :any): Promise{ + async createUsers(data?: any): Promise { const result = await postRequest(urls.api.settingsUsers, data) const jsonData = await result.json(); return jsonData } - async deleteUsers(data? :any): Promise{ + async deleteUsers(data?: any): Promise { const result = await postRequest(urls.api.settingsUsers, data) const jsonData = await result.json(); return jsonData } - async runQuery(query: string, data?: any): Promise{ + async runQuery(query: string, data?: any): Promise { const result = await getRequest(urls.api.runQueryUrl + query, data) const jsonData = await result.json(); return jsonData diff --git a/e2e/logic/api/responses/createUsersResponse.ts b/e2e/logic/api/responses/createUsersResponse.ts index bcba7093..e7125f94 100644 --- a/e2e/logic/api/responses/createUsersResponse.ts +++ b/e2e/logic/api/responses/createUsersResponse.ts @@ -1,3 +1,3 @@ export interface CreateUsersResponse { - message: string; - } \ No newline at end of file + message: string; +} \ No newline at end of file diff --git a/e2e/logic/api/responses/deleteUsersResponse.ts b/e2e/logic/api/responses/deleteUsersResponse.ts index 105d9334..b3847843 100644 --- a/e2e/logic/api/responses/deleteUsersResponse.ts +++ b/e2e/logic/api/responses/deleteUsersResponse.ts @@ -1,3 +1,3 @@ export interface DeleteUsersResponse { - message: string; - } \ No newline at end of file + message: string; +} \ No newline at end of file diff --git a/e2e/logic/api/responses/getUsersResponse.ts b/e2e/logic/api/responses/getUsersResponse.ts index d73cd68b..93be8f8e 100644 --- a/e2e/logic/api/responses/getUsersResponse.ts +++ b/e2e/logic/api/responses/getUsersResponse.ts @@ -1,8 +1,7 @@ -interface GetUsersResponse { - result: { - username: string; - role: string; - checked: boolean; - }[]; - } - \ No newline at end of file +export interface GetUsersResponse { + result: { + username: string; + role: string; + checked: boolean; + }[]; +} diff --git a/e2e/logic/api/responses/modifySettingsRoleResponse.ts b/e2e/logic/api/responses/modifySettingsRoleResponse.ts index cc871515..3b5b7067 100644 --- a/e2e/logic/api/responses/modifySettingsRoleResponse.ts +++ b/e2e/logic/api/responses/modifySettingsRoleResponse.ts @@ -1,3 +1,3 @@ export interface ModifySettingsRoleResponse { - config: string; - } + config: string; +} diff --git a/e2e/logic/api/responses/removeGraphResponse.ts b/e2e/logic/api/responses/removeGraphResponse.ts index 580ae15d..c1921821 100644 --- a/e2e/logic/api/responses/removeGraphResponse.ts +++ b/e2e/logic/api/responses/removeGraphResponse.ts @@ -1,4 +1,3 @@ export interface RemoveGraphResponse { - message: string; - } - \ No newline at end of file + message: string; +} diff --git a/e2e/logic/api/responses/runQueryResponse.ts b/e2e/logic/api/responses/runQueryResponse.ts index 68f99605..114da2aa 100644 --- a/e2e/logic/api/responses/runQueryResponse.ts +++ b/e2e/logic/api/responses/runQueryResponse.ts @@ -1,4 +1,6 @@ -export interface runQueryResponse { +/* eslint-disable @typescript-eslint/no-explicit-any */ + +export interface RunQueryResponse { result: { metadata: { "Labels added": number; diff --git a/e2e/tests/auth.setup.ts b/e2e/tests/auth.setup.ts index 424cda54..97c85499 100644 --- a/e2e/tests/auth.setup.ts +++ b/e2e/tests/auth.setup.ts @@ -1,8 +1,8 @@ import { test as setup } from "@playwright/test" import urls from '../config/urls.json' import BrowserWrapper from "../infra/ui/browserWrapper"; -import { LoginPage } from "../logic/POM/loginPage"; -import {user} from '../config/user.json' +import LoginPage from "../logic/POM/loginPage"; +import { user } from '../config/user.json' import SettingsUsersPage from "../logic/POM/settingsUsersPage"; const adminAuthFile = 'playwright/.auth/admin.json' @@ -14,13 +14,14 @@ setup("admin authentication", async () => { const browserWrapper = new BrowserWrapper(); const loginPage = await browserWrapper.createNewPage(LoginPage, urls.loginUrl); await loginPage.clickOnConnect(); + await loginPage.dismissDialogAtStart(); const context = browserWrapper.getContext(); await context!.storageState({ path: adminAuthFile }); const settings = await browserWrapper.createNewPage(SettingsUsersPage, urls.settingsUrl) await settings.navigateToUserTab(); - await settings.addUser({userName: "readwriteuser", role: user.ReadWrite, password: user.password , confirmPassword: user.confirmPassword}); - await settings.addUser({userName: "readonlyuser", role: user.ReadOnly, password: user.password , confirmPassword: user.confirmPassword}); + await settings.addUser({ userName: "readwriteuser", role: user.ReadWrite, password: user.password, confirmPassword: user.confirmPassword }); + await settings.addUser({ userName: "readonlyuser", role: user.ReadOnly, password: user.password, confirmPassword: user.confirmPassword }); } catch (error) { console.error("Error during authentication setup:", error); } @@ -37,6 +38,7 @@ userRoles.forEach(({ name, file, userName }) => { const browserWrapper = new BrowserWrapper(); const loginPage = await browserWrapper.createNewPage(LoginPage, urls.loginUrl); await loginPage.connectWithCredentials(userName, user.password); + await loginPage.dismissDialogAtStart(); const context = browserWrapper.getContext(); await context!.storageState({ path: file }); } catch (error) { diff --git a/e2e/tests/graph.spec.ts b/e2e/tests/graph.spec.ts index 7b5c3f6f..0f1e10e9 100644 --- a/e2e/tests/graph.spec.ts +++ b/e2e/tests/graph.spec.ts @@ -1,18 +1,18 @@ import { expect, test } from "@playwright/test"; -import BrowserWrapper from "../infra/ui/browserWrapper"; -import { ApiCalls } from "../logic/api/apiCalls"; -import { graphPage } from "../logic/POM/graphPage"; -import urls from '../config/urls.json' import fs from 'fs'; +import BrowserWrapper from "../infra/ui/browserWrapper"; +import ApiCalls from "../logic/api/apiCalls"; +import GraphPage from "../logic/POM/graphPage"; +import urls from '../config/urls.json' import queryData from '../config/queries.json' import roles from '../config/user.json' test.describe('Graph Tests', () => { - let browser : BrowserWrapper; + let browser: BrowserWrapper; test.beforeAll(async () => { browser = new BrowserWrapper(); - const graph = await browser.createNewPage(graphPage, urls.graphUrl) + const graph = await browser.createNewPage(GraphPage, urls.graphUrl) await graph.removeAllGraphs(); }) @@ -21,38 +21,37 @@ test.describe('Graph Tests', () => { }) roles.userRoles.slice(0, 2).forEach(role => { - test(`@${role.role} Add graph via API -> verify display in UI test`, async () => { - const graph = await browser.createNewPage(graphPage, urls.graphUrl); + test(`@${role.role} Add graph via API -> verify display in UI test -> remove graph via UI`, async () => { + const graph = await browser.createNewPage(GraphPage, urls.graphUrl); const apiCall = new ApiCalls(); const graphName = `graph_${Date.now()}`; await apiCall.addGraph(graphName); await graph.refreshPage(); - const isVisible = await graph.verifyGraphExistsByName(graphName); + expect(await graph.verifyGraphExists(graphName)).toBe(true); await graph.refreshPage(); await graph.deleteGraph(graphName); - expect(isVisible).toBe(true); }); - }); - + }); + roles.userRoles.slice(0, 2).forEach(role => { test(`@${role.role} Add graph via UI -> remove graph via API -> Verify graph removal in UI test`, async () => { - const graph = await browser.createNewPage(graphPage, urls.graphUrl); + const graph = await browser.createNewPage(GraphPage, urls.graphUrl); const graphName = `graph_${Date.now()}`; await graph.addGraph(graphName); + await new Promise(resolve => { setTimeout(resolve, 1000) }); const apiCall = new ApiCalls(); - await new Promise(resolve => setTimeout(resolve, 1000)); await apiCall.removeGraph(graphName); await graph.refreshPage(); expect(await graph.verifyGraphExists(graphName)).toBe(false); }); }); - + roles.userRoles.slice(0, 2).forEach(role => { test(`@${role.role} Create graph -> click the Export Data button -> verify the file has been successfully downloaded`, async () => { - const graph = await browser.createNewPage(graphPage, urls.graphUrl); + const graph = await browser.createNewPage(GraphPage, urls.graphUrl); const graphName = `graph_${Date.now()}`; await graph.addGraph(graphName); - const download = await graph.clickOnExportDataBtn(); + const download = await graph.exportGraph(); const downloadPath = await download.path(); expect(fs.existsSync(downloadPath)).toBe(true); }); @@ -64,13 +63,13 @@ test.describe('Graph Tests', () => { const graphName = `graph_${Date.now()}` await apiCall.addGraph(graphName) const query = graphName + queryData.queries[0].query - const res = await apiCall.runQuery(query) + const res = await apiCall.runQuery(query) expect( res.result && Array.isArray(res.result.metadata) && res.result.metadata.length >= 5 && Array.isArray(res.result.data) - ).toBe(true); + ).toBe(true); }) }); }) \ No newline at end of file diff --git a/e2e/tests/navBar.spec.ts b/e2e/tests/navBar.spec.ts index 48d063d4..7d181b7b 100644 --- a/e2e/tests/navBar.spec.ts +++ b/e2e/tests/navBar.spec.ts @@ -5,70 +5,69 @@ import NavBarComponent from "../logic/POM/navBarComponent"; const roles = [{ name: "admin" }, { name: "readwrite" }, { name: "readonly" }]; -roles.forEach((role) => { - test.describe(`@${role.name} role, Navbar tests`, () => { +test.describe(`Navbar tests`, () => { let browser: BrowserWrapper; test.beforeAll(async () => { - browser = new BrowserWrapper(); + browser = new BrowserWrapper(); }); test.afterAll(async () => { - await browser.closeBrowser(); + await browser.closeBrowser(); }); - test("Verify clicking on FalkorDB logo redirects to specified URL", async () => { - const navBar = await browser.createNewPage(NavBarComponent, urls.graphUrl) - const page = await navBar.clickOnFalkor() - expect(page.url()).toBe("https://www.falkordb.com/") - - }) - - test("Verify clicking on Graphs button redirects to specified URL", async () => { - const navBar = await browser.createNewPage(NavBarComponent, urls.graphUrl) - await navBar.clickOnGraphsButton() - const newUrl = navBar.getCurrentURL(); - expect(newUrl).toBe(urls.graphUrl) - + roles.forEach((role) => { + test(`@${role.name} Verify clicking on FalkorDB logo redirects to specified URL`, async () => { + const navBar = await browser.createNewPage(NavBarComponent, urls.graphUrl) + const page = await navBar.clickOnFalkor() + expect(page.url()).toBe("https://www.falkordb.com/") + + }) }) - - test("Verify clicking on Schemas button redirects to specified URL", async () => { - const navBar = await browser.createNewPage(NavBarComponent, urls.graphUrl) - await navBar.clickOnSchemasButton() - const newUrl = navBar.getCurrentURL(); - expect(newUrl).toBe(urls.schemaUrl) - + + roles.forEach((role) => { + test(`@${role.name} Verify clicking on Graphs button redirects to specified URL`, async () => { + const navBar = await browser.createNewPage(NavBarComponent, urls.graphUrl) + await navBar.clickOnGraphsButton() + const newUrl = navBar.getCurrentURL(); + expect(newUrl).toBe(urls.graphUrl) + + }) }) - test("Verify clicking on help -> Documentation redirects to specified URL", async () => { - const navBar = await browser.createNewPage(NavBarComponent, urls.graphUrl) - const page = await navBar.clickOnDocumentation() - expect(page.url()).toBe("https://docs.falkordb.com/") - + roles.forEach((role) => { + test(`@${role.name} Verify clicking on Schemas button redirects to specified URL`, async () => { + const navBar = await browser.createNewPage(NavBarComponent, urls.graphUrl) + await navBar.clickOnSchemasButton() + const newUrl = navBar.getCurrentURL(); + expect(newUrl).toBe(urls.schemaUrl) + + }) }) - test("Verify clicking on help -> Support redirects to specified URL", async () => { - const navBar = await browser.createNewPage(NavBarComponent, urls.graphUrl) - const page = await navBar.clickOnSupport() - expect(page.url()).toBe("https://www.falkordb.com/contact-us/") - + roles.forEach((role) => { + test(`@${role.name} Verify clicking on help -> Documentation redirects to specified URL`, async () => { + const navBar = await browser.createNewPage(NavBarComponent, urls.graphUrl) + const page = await navBar.clickOnDocumentation() + expect(page.url()).toBe("https://docs.falkordb.com/") + + }) }) - if(role.name === 'admin'){ - test("@admin Verify clicking on Settings redirects to specified URL", async () => { + roles.forEach((role) => { + test(`@${role.name} Verify clicking on help -> Support redirects to specified URL`, async () => { const navBar = await browser.createNewPage(NavBarComponent, urls.graphUrl) - await navBar.clickOnSettingsBtn() - const newUrl = navBar.getCurrentURL() - expect(newUrl).toBe(urls.settingsUrl) + const page = await navBar.clickOnSupport() + expect(page.url()).toBe("https://www.falkordb.com/contact-us/") + }) - } - - if(role.name === 'readwrite' || role.name === 'readonly'){ - test("Attempt to click on Settings does not result in a redirect", async () => { + }) + + roles.forEach((role) => { + test(`@${role.name} Verify clicking on Settings redirects to specified URL`, async () => { const navBar = await browser.createNewPage(NavBarComponent, urls.graphUrl) - const result = await navBar.isSettingsButtonEnabled() - expect(result).toBe(false) + const result = await navBar.isSettingsButtonEnabled() + expect(result).toBe(role.name === 'admin') }) - } - }); -}); \ No newline at end of file + }) +}) diff --git a/e2e/tests/settingsConfig.spec.ts b/e2e/tests/settingsConfig.spec.ts index 202f84c2..9b36bb4a 100644 --- a/e2e/tests/settingsConfig.spec.ts +++ b/e2e/tests/settingsConfig.spec.ts @@ -1,13 +1,13 @@ import { expect, test } from "@playwright/test"; -import urls from '../config/urls.json' +import urls from '../config/urls.json' import { roles } from '../config/roles.json' -import BrowserWrapper from "../infra/ui/browserWrapper"; +import BrowserWrapper from "../infra/ui/browserWrapper"; import SettingsConfigPage from "../logic/POM/settingsConfigPage"; -import { ApiCalls } from "../logic/api/apiCalls"; +import ApiCalls from "../logic/api/apiCalls"; import Data from '../config/settingsConfigData.json'; - + test.describe('Settings Tests', () => { - let browser : BrowserWrapper; + let browser: BrowserWrapper; test.beforeAll(async () => { browser = new BrowserWrapper(); @@ -16,25 +16,26 @@ test.describe('Settings Tests', () => { test.afterAll(async () => { await browser.closeBrowser(); }) - + Data.inputDataRejectsZero.forEach(({ input, description, expected }) => { test(`@admin Modify ${roles.maxQueuedQueries} via API validation via UI: Input value: ${input} description: ${description}`, async () => { const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) const apiCall = new ApiCalls() + await new Promise(resolve => { setTimeout(resolve, 1000) }); await apiCall.modifySettingsRole(roles.maxQueuedQueries, input) await settingsConfigPage.refreshPage() - const value = await settingsConfigPage.getRoleContentValue(roles.maxQueuedQueries) + const value = await settingsConfigPage.getRoleContentValue(roles.maxQueuedQueries) expect(value === input).toBe(expected) }); }) - + Data.maxTimeOut.forEach(({ input, description, expected }) => { test(`@admin Modify ${roles.maxTimeOut} via API validation via UI: Input value: ${input} description: ${description}`, async () => { const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) const apiCall = new ApiCalls() await apiCall.modifySettingsRole(roles.maxTimeOut, input) await settingsConfigPage.refreshPage() - const value = await settingsConfigPage.getRoleContentValue(roles.maxTimeOut) + const value = await settingsConfigPage.getRoleContentValue(roles.maxTimeOut) expect(value === input).toBe(expected) }); }) @@ -45,7 +46,7 @@ test.describe('Settings Tests', () => { const apiCall = new ApiCalls() await apiCall.modifySettingsRole(roles.defaultTimeOut, input) await settingsConfigPage.refreshPage() - const value = await settingsConfigPage.getRoleContentValue(roles.defaultTimeOut) + const value = await settingsConfigPage.getRoleContentValue(roles.defaultTimeOut) expect(value === input).toBe(expected) }); }) @@ -56,7 +57,7 @@ test.describe('Settings Tests', () => { const apiCall = new ApiCalls() await apiCall.modifySettingsRole(roles.resultSetSize, input) await settingsConfigPage.refreshPage() - const value = await settingsConfigPage.getRoleContentValue(roles.resultSetSize) + const value = await settingsConfigPage.getRoleContentValue(roles.resultSetSize) expect(value === input).toBe(expected) }); }) @@ -68,7 +69,7 @@ test.describe('Settings Tests', () => { await apiCall.modifySettingsRole(roles.queryMemCapacity, input) await settingsConfigPage.refreshPage() const value = await settingsConfigPage.getRoleContentValue(roles.queryMemCapacity) - await apiCall.modifySettingsRole(roles.queryMemCapacity, "0")//update to default values + await apiCall.modifySettingsRole(roles.queryMemCapacity, "0") // update to default values expect(value === input).toBe(expected) }); }) @@ -79,7 +80,7 @@ test.describe('Settings Tests', () => { const apiCall = new ApiCalls() await apiCall.modifySettingsRole(roles.vKeyMaxEntityCount, input) await settingsConfigPage.refreshPage() - const value = await settingsConfigPage.getRoleContentValue(roles.vKeyMaxEntityCount) + const value = await settingsConfigPage.getRoleContentValue(roles.vKeyMaxEntityCount) expect(value === input).toBe(expected) }); }) @@ -90,7 +91,7 @@ test.describe('Settings Tests', () => { const apiCall = new ApiCalls() await apiCall.modifySettingsRole(roles.cmdInfo, input) await settingsConfigPage.refreshPage() - const value = await settingsConfigPage.getRoleContentValue(roles.cmdInfo) + const value = await settingsConfigPage.getRoleContentValue(roles.cmdInfo) expect(value === input).toBe(expected) }); }) @@ -101,7 +102,7 @@ test.describe('Settings Tests', () => { const apiCall = new ApiCalls() await apiCall.modifySettingsRole(roles.maxInfoQueries, input) await settingsConfigPage.refreshPage() - const value = await settingsConfigPage.getRoleContentValue(roles.maxInfoQueries) + const value = await settingsConfigPage.getRoleContentValue(roles.maxInfoQueries) expect(value === input).toBe(expected) }); }) @@ -112,11 +113,16 @@ test.describe('Settings Tests', () => { await settingsConfigPage.modifyRoleValue(role, input) const apiCall = new ApiCalls() let value = String((await apiCall.getSettingsRoleValue(role)).config[1]); - value = value === '1' ? 'yes' : value === '0' ? 'no' : value; - await apiCall.modifySettingsRole(roles.queryMemCapacity, "0")//update to default values + // Convert numeric values to yes/no for boolean settings + if (value === '1') { + value = 'yes'; + } else if (value === '0') { + value = 'no'; + } + await apiCall.modifySettingsRole(roles.queryMemCapacity, "0") // update to default values expect(value === input).toBe(expected) }); }) - + }) \ No newline at end of file diff --git a/e2e/tests/settingsUsers.spec.ts b/e2e/tests/settingsUsers.spec.ts index bf35d6d3..71953bb8 100644 --- a/e2e/tests/settingsUsers.spec.ts +++ b/e2e/tests/settingsUsers.spec.ts @@ -1,12 +1,12 @@ import { expect, test } from "@playwright/test"; -import urls from '../config/urls.json' -import BrowserWrapper from "../infra/ui/browserWrapper"; -import SettingsUsersPage from "../logic/POM/settingsUsersPage"; +import urls from '../config/urls.json' +import BrowserWrapper from "../infra/ui/browserWrapper"; +import SettingsUsersPage from "../logic/POM/settingsUsersPage"; import { user } from '../config/user.json' -import { ApiCalls } from "../logic/api/apiCalls"; +import ApiCalls from "../logic/api/apiCalls"; test.describe('Settings Tests', () => { - let browser : BrowserWrapper; + let browser: BrowserWrapper; test.beforeAll(async () => { browser = new BrowserWrapper(); @@ -20,25 +20,25 @@ test.describe('Settings Tests', () => { const settingsUsersPage = await browser.createNewPage(SettingsUsersPage, urls.settingsUrl) await settingsUsersPage.navigateToUserTab(); const username = `user_${Date.now()}` - await settingsUsersPage.addUser({userName: username, role: user.ReadWrite, password: user.password , confirmPassword: user.confirmPassword}); + await settingsUsersPage.addUser({ userName: username, role: user.ReadWrite, password: user.password, confirmPassword: user.confirmPassword }); const isVisible = await settingsUsersPage.verifyUserExists(username) - await settingsUsersPage.removeUserByHover(username) + await settingsUsersPage.removeUser(username) expect(isVisible).toBe(true) }) - test("@admin Add one user -> remove one user by hover -> Validate that the user has been removed", async () => { + test("@admin Add one user -> remove one user -> Validate that the user has been removed", async () => { // Adding one user const settingsUsersPage = await browser.createNewPage(SettingsUsersPage, urls.settingsUrl) await settingsUsersPage.navigateToUserTab(); const username = `user_${Date.now()}` - await settingsUsersPage.addUser({userName: username, role: user.ReadWrite, password: user.password , confirmPassword: user.confirmPassword}); + await settingsUsersPage.addUser({ userName: username, role: user.ReadWrite, password: user.password, confirmPassword: user.confirmPassword }); // Deleting one user - await settingsUsersPage.removeUserByHover(username) + await settingsUsersPage.removeUser(username) await settingsUsersPage.refreshPage() await settingsUsersPage.navigateToUserTab() const isVisible = await settingsUsersPage.verifyUserExists(username) expect(isVisible).toBe(false) - + }) test("@admin Add one user -> change the role -> Validate that the user role have been changed", async () => { @@ -46,14 +46,14 @@ test.describe('Settings Tests', () => { const settingsUsersPage = await browser.createNewPage(SettingsUsersPage, urls.settingsUrl) await settingsUsersPage.navigateToUserTab(); const username = `user_${Date.now()}` - await settingsUsersPage.addUser({userName: username, role: user.ReadWrite, password: user.password , confirmPassword: user.confirmPassword}); - + await settingsUsersPage.addUser({ userName: username, role: user.ReadWrite, password: user.password, confirmPassword: user.confirmPassword }); + // modify user role - await settingsUsersPage.modifyUserRole(username, user.role.readOnly) + await settingsUsersPage.modifyUserRole(username, user.ReadOnly) const newUserRole = await settingsUsersPage.getUserRole(username) - await settingsUsersPage.removeUserByHover(username) + await settingsUsersPage.removeUser(username) expect(newUserRole).toBe("Read-Only") - + }) test("@admin Add two users -> change their roles via checkbox -> Validate that the users roles have been changed", async () => { @@ -61,20 +61,20 @@ test.describe('Settings Tests', () => { const settingsUsersPage = await browser.createNewPage(SettingsUsersPage, urls.settingsUrl) await settingsUsersPage.navigateToUserTab(); const username1 = `user_${Date.now()}` - await settingsUsersPage.addUser({userName: username1, role: user.ReadWrite, password: user.password , confirmPassword: user.confirmPassword}); + await settingsUsersPage.addUser({ userName: username1, role: user.ReadWrite, password: user.password, confirmPassword: user.confirmPassword }); const username2 = `user_${Date.now()}` - await settingsUsersPage.addUser({userName: username2, role: user.ReadWrite, password: user.password , confirmPassword: user.confirmPassword}); - + await settingsUsersPage.addUser({ userName: username2, role: user.ReadWrite, password: user.password, confirmPassword: user.confirmPassword }); + // modify users roles const userRole = user.ReadOnly; - await settingsUsersPage.modifyTwoUsersRolesByCheckbox(username1, username2, userRole) + await settingsUsersPage.modifyTwoUsersRoles(username1, username2, userRole) await settingsUsersPage.refreshPage() await settingsUsersPage.navigateToUserTab() const userName1Role = await settingsUsersPage.getUserRole(username1) const userName2Role = await settingsUsersPage.getUserRole(username2) - await settingsUsersPage.deleteTwoUsersByCheckbox(username1, username2) - - expect([userName1Role, userName2Role]).toEqual(["Read-Only", "Read-Only"]) + await settingsUsersPage.deleteTwoUsers(username1, username2) + + expect([userName1Role, userName2Role]).toEqual(["Read-Only", "Read-Only"]) }) test("@admin Add two users -> delete the two users by checkbox -> Validate that the users have been deleted", async () => { @@ -82,27 +82,27 @@ test.describe('Settings Tests', () => { const settingsUsersPage = await browser.createNewPage(SettingsUsersPage, urls.settingsUrl) await settingsUsersPage.navigateToUserTab(); const username1 = `user_${Date.now()}` - await settingsUsersPage.addUser({userName: username1, role: user.ReadWrite, password: user.password , confirmPassword: user.confirmPassword}); + await settingsUsersPage.addUser({ userName: username1, role: user.ReadWrite, password: user.password, confirmPassword: user.confirmPassword }); await settingsUsersPage.refreshPage() await settingsUsersPage.navigateToUserTab() const username2 = `user_${Date.now()}` - await settingsUsersPage.addUser({userName: username2, role: user.ReadWrite, password: user.password , confirmPassword: user.confirmPassword}); - + await settingsUsersPage.addUser({ userName: username2, role: user.ReadWrite, password: user.password, confirmPassword: user.confirmPassword }); + // delete two users - await settingsUsersPage.deleteTwoUsersByCheckbox(username1, username2) + await settingsUsersPage.deleteTwoUsers(username1, username2) const isVisible1 = await settingsUsersPage.verifyUserExists(username1) const isVisible2 = await settingsUsersPage.verifyUserExists(username2) expect([isVisible1, isVisible2]).toEqual([false, false]) - + }) const searchData = [ - { invalidPassword: 'Test123', description: "short password"}, - { invalidPassword: 'Test1234', description: "without special character"}, - { invalidPassword: 'Testtes@', description: "without digits"}, - { invalidPassword: 'TESTES1@', description: "without lowercase letters"}, - { invalidPassword: 'testte1@', description: "without uppercase letters"}, - { invalidPassword: '', description: "without password"} + { invalidPassword: 'Test123', description: "short password" }, + { invalidPassword: 'Test1234', description: "without special character" }, + { invalidPassword: 'Testtes@', description: "without digits" }, + { invalidPassword: 'TESTES1@', description: "without lowercase letters" }, + { invalidPassword: 'testte1@', description: "without uppercase letters" }, + { invalidPassword: '', description: "without password" } ]; searchData.forEach(({ invalidPassword, description }) => { @@ -110,7 +110,7 @@ test.describe('Settings Tests', () => { const settingsUsersPage = await browser.createNewPage(SettingsUsersPage, urls.settingsUrl) await settingsUsersPage.navigateToUserTab(); const username = `user_${Date.now()}` - await settingsUsersPage.addUser({userName: username, role: user.ReadWrite, password: invalidPassword, confirmPassword: invalidPassword}); + await settingsUsersPage.addUser({ userName: username, role: user.ReadWrite, password: invalidPassword, confirmPassword: invalidPassword }); await settingsUsersPage.refreshPage() await settingsUsersPage.navigateToUserTab(); const isVisible = await settingsUsersPage.verifyUserExists(username) @@ -122,7 +122,7 @@ test.describe('Settings Tests', () => { const settingsUsersPage = await browser.createNewPage(SettingsUsersPage, urls.settingsUrl) await settingsUsersPage.navigateToUserTab(); const username = `user_${Date.now()}` - await settingsUsersPage.attemptToAddUserWithoutRole({userName: username, password: user.password , confirmPassword: user.confirmPassword}); + await settingsUsersPage.addUser({ userName: username, password: user.password, confirmPassword: user.confirmPassword }); await settingsUsersPage.refreshPage() await settingsUsersPage.navigateToUserTab() const isVisible = await settingsUsersPage.verifyUserExists(username) @@ -132,45 +132,45 @@ test.describe('Settings Tests', () => { test("@admin Attempt to delete the default admin user -> Verify that the user has not been deleted.", async () => { const settingsUsersPage = await browser.createNewPage(SettingsUsersPage, urls.settingsUrl) await settingsUsersPage.navigateToUserTab(); - await settingsUsersPage.removeUserByCheckbox('default') + await settingsUsersPage.removeUser('default') const isVisible = await settingsUsersPage.verifyUserExists('default'); expect(isVisible).toBe(true) }) test("@admin API Test:Add user via API -> Validated user existing via API -> Delete user via API.", async () => { const apiCall = new ApiCalls() - const username = `user_${Date.now()}` - await apiCall.createUsers({username, password: user.password, role: user.ReadOnly}) + const username = `user_${Date.now()}` + await apiCall.createUsers({ username, password: user.password, role: user.ReadOnly }) const users = await apiCall.getUsers() - await apiCall.deleteUsers({"users":[{"username":`${username}`}]}) - const User = users.result.find(user => user.username === username); + await apiCall.deleteUsers({ users: [{ username }] }) + const User = users.result.find(u => u.username === username); expect(User?.username === username).toBe(true) }) // fail tests test(`@admin API Test: without passing a username, Attempt to add a user and validate the user was not added`, async () => { const apiCall = new ApiCalls() const username = '' - await apiCall.createUsers({ username: username, password: user.password, role: user.ReadOnly }); + await apiCall.createUsers({ username, password: user.password, role: user.ReadOnly }); const users = await apiCall.getUsers() - const User = users.result.find(user => user.username === username); + const User = users.result.find(u => u.username === username); expect(User).toBeUndefined(); }); test(`@admin API Test: without passing a role, Attempt to add a user and validate the user was not added`, async () => { const apiCall = new ApiCalls() - const username = `user_${Date.now()}` - await apiCall.createUsers({ username: username, password: '', role: user.ReadOnly }); + const username = `user_${Date.now()}` + await apiCall.createUsers({ username, password: user.password, role: '' }) const users = await apiCall.getUsers() - const User = users.result.find(user => user.username === username); + const User = users.result.find(u => u.username === username); expect(User).toBeUndefined(); }); - + test(`@admin API Test: without passing a password, Attempt to add a user and validate the user was not added`, async () => { const apiCall = new ApiCalls() - const username = `user_${Date.now()}` - await apiCall.createUsers({username: username, password: user.password, role: ''}) + const username = `user_${Date.now()}` + await apiCall.createUsers({ username, password: '', role: user.ReadOnly }); const users = await apiCall.getUsers() - const User = users.result.find(user => user.username === username); + const User = users.result.find(u => u.username === username); expect(User).toBeUndefined(); }); diff --git a/e2e/tests/signOut.spec.ts b/e2e/tests/signOut.spec.ts index 9ce11b5c..278da294 100644 --- a/e2e/tests/signOut.spec.ts +++ b/e2e/tests/signOut.spec.ts @@ -1,12 +1,12 @@ import { expect, test } from "@playwright/test"; -import urls from '../config/urls.json' +import urls from '../config/urls.json' import BrowserWrapper from "../infra/ui/browserWrapper"; import navBarComponent from '../logic/POM/navBarComponent' import roles from '../config/user.json' roles.userRoles.forEach((role) => { test.describe(`@${role.role} SignOut Test`, () => { - let browser : BrowserWrapper; + let browser: BrowserWrapper; test.beforeAll(async () => { browser = new BrowserWrapper(); @@ -18,7 +18,7 @@ roles.userRoles.forEach((role) => { test("Sign out Test", async () => { const navBar = await browser.createNewPage(navBarComponent, urls.graphUrl) - await navBar.Logout(role.name); + await navBar.Logout(); const newUrl = navBar.getCurrentURL(); expect(newUrl).toBe(urls.loginUrl) }) diff --git a/lib/utils.ts b/lib/utils.ts index 36bba62e..059aa9d6 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -1,27 +1,33 @@ -import { toast } from "@/components/ui/use-toast" +/* eslint-disable @typescript-eslint/no-explicit-any */ +// eslint-disable-next-line import/prefer-default-export + +"use client" + import { type ClassValue, clsx } from "clsx" import { signOut } from "next-auth/react" import { twMerge } from "tailwind-merge" -// eslint-disable-next-line import/prefer-default-export export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) } -// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/default-param-last -export function Toast(message?: string, type?: string) { - toast({ - title: type || "Error", - description: message || "Something Went Wrong", - }) -} - -export async function securedFetch(input: string | URL | globalThis.Request, init?: RequestInit): Promise { +export async function securedFetch( + input: string | URL | globalThis.Request, + init: RequestInit, + toast?: any, +): Promise { const response = await fetch(input, init) const { status } = response + if (status >= 300) { - response.text().then((message) => { - Toast(message) + response.json().then((err) => { + if (toast) { + toast({ + title: "Error", + description: err.message, + variant: "destructive" + }) + } }).then(() => { if (status === 401 || status >= 500) { signOut({ callbackUrl: '/login' }) diff --git a/package-lock.json b/package-lock.json index 63d7c7d7..248e5481 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.9.1", "dependencies": { "-": "^0.0.1", + "@hookform/resolvers": "^3.9.1", "@monaco-editor/react": "^4.6.0", "@radix-ui/react-alert-dialog": "^1.1.4", "@radix-ui/react-avatar": "^1.1.2", @@ -17,14 +18,17 @@ "@radix-ui/react-dropdown-menu": "^2.1.4", "@radix-ui/react-hover-card": "^1.1.4", "@radix-ui/react-label": "^2.1.1", + "@radix-ui/react-navigation-menu": "^1.2.3", "@radix-ui/react-popover": "^1.1.4", "@radix-ui/react-progress": "^1.1.1", + "@radix-ui/react-select": "^2.1.4", "@radix-ui/react-separator": "^1.1.1", "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-switch": "^1.1.2", "@radix-ui/react-tabs": "^1.1.2", "@radix-ui/react-toast": "^1.2.4", "@radix-ui/react-tooltip": "^1.0.7", + "@radix-ui/react-visually-hidden": "^1.1.1", "autoprefixer": "^10.4.20", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", @@ -34,6 +38,7 @@ "depcheck": "^1.4.7", "echarts": "^5.5.0", "echarts-for-react": "^3.0.2", + "embla-carousel-react": "^8.5.1", "eslint-config-airbnb": "^19.0.4", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.29.1", @@ -54,13 +59,15 @@ "react-dropzone": "^14.2.3", "react-force-graph-2d": "^1.26.1", "react-gtm-module": "^2.0.11", - "react-hook-form": "^7.49.3", + "react-hook-form": "^7.54.2", "react-json-tree": "^0.19.0", "react-resizable-panels": "^1.0.9", "redis": "^4.6.14", "swr": "^2.2.5", "tailwind-merge": "^2.2.0", - "tailwindcss": "^3.4.1" + "tailwindcss": "^3.4.1", + "vaul": "^1.1.2", + "zod": "^3.24.1" }, "devDependencies": { "@playwright/test": "^1.46.1", @@ -82,14 +89,12 @@ "node_modules/-": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/-/-/--0.0.1.tgz", - "integrity": "sha512-3HfneK3DGAm05fpyj20sT3apkNcvPpCuccOThOPdzz8sY7GgQGe0l93XH9bt+YzibcTIgUAIMoyVJI740RtgyQ==", - "license": "UNLICENSED" + "integrity": "sha512-3HfneK3DGAm05fpyj20sT3apkNcvPpCuccOThOPdzz8sY7GgQGe0l93XH9bt+YzibcTIgUAIMoyVJI740RtgyQ==" }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "license": "MIT", "engines": { "node": ">=10" }, @@ -156,10 +161,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", - "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", - "license": "MIT", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -219,25 +223,26 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "license": "MIT", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", - "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", - "license": "MIT", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -246,7 +251,6 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -265,11 +269,15 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -279,7 +287,6 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -290,11 +297,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -306,7 +323,6 @@ "version": "8.57.1", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", - "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -315,16 +331,14 @@ "version": "1.6.8", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz", "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==", - "license": "MIT", "dependencies": { "@floating-ui/utils": "^0.2.8" } }, "node_modules/@floating-ui/dom": { - "version": "1.6.11", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.11.tgz", - "integrity": "sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==", - "license": "MIT", + "version": "1.6.12", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz", + "integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==", "dependencies": { "@floating-ui/core": "^1.6.0", "@floating-ui/utils": "^0.2.8" @@ -334,7 +348,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", - "license": "MIT", "dependencies": { "@floating-ui/dom": "^1.0.0" }, @@ -346,15 +359,21 @@ "node_modules/@floating-ui/utils": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", - "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==", - "license": "MIT" + "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==" + }, + "node_modules/@hookform/resolvers": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.9.1.tgz", + "integrity": "sha512-ud2HqmGBM0P0IABqoskKWI6PEf6ZDDBZkFqe2Vnl+mTHCEHzr3ISjjZyCwTjC/qpL25JC9aIDkloQejvMeq0ug==", + "peerDependencies": { + "react-hook-form": "^7.0.0" + } }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "deprecated": "Use @eslint/config-array instead", - "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", @@ -368,7 +387,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -378,7 +396,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -390,7 +407,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -403,8 +419,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "license": "BSD-3-Clause" + "deprecated": "Use @eslint/object-schema instead" }, "node_modules/@img/sharp-darwin-arm64": { "version": "0.33.5", @@ -752,7 +767,6 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -769,7 +783,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", "engines": { "node": ">=12" }, @@ -781,7 +794,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "license": "MIT", "engines": { "node": ">=12" }, @@ -793,7 +805,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -810,7 +821,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -825,7 +835,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -839,10 +848,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "license": "MIT", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -856,7 +864,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -865,7 +872,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -873,14 +879,12 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "license": "MIT" + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -890,7 +894,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz", "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==", - "license": "MIT", "dependencies": { "state-local": "^1.0.6" }, @@ -902,7 +905,6 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz", "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==", - "license": "MIT", "dependencies": { "@monaco-editor/loader": "^1.4.0" }, @@ -913,14 +915,14 @@ } }, "node_modules/@next/env": { - "version": "15.1.2", - "resolved": "https://registry.npmjs.org/@next/env/-/env-15.1.2.tgz", - "integrity": "sha512-Hm3jIGsoUl6RLB1vzY+dZeqb+/kWPZ+h34yiWxW0dV87l8Im/eMOwpOA+a0L78U0HM04syEjXuRlCozqpwuojQ==" + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.1.4.tgz", + "integrity": "sha512-2fZ5YZjedi5AGaeoaC0B20zGntEHRhi2SdWcu61i48BllODcAmmtj8n7YarSPt4DaTsJaBFdxQAVEVzgmx2Zpw==" }, "node_modules/@next/eslint-plugin-next": { - "version": "15.1.2", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.1.2.tgz", - "integrity": "sha512-sgfw3+WdaYOGPKCvM1L+UucBmRfh8V2Ygefp7ELON0+0vY7uohQwXXnVWg3rY7mXDKharQR3o7uedpfvnU2hlQ==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.1.4.tgz", + "integrity": "sha512-HwlEXwCK3sr6zmVGEvWBjW9tBFs1Oe6hTmTLoFQtpm4As5HCdu8jfSE0XJOp7uhfEGLniIx8yrGxEWwNnY0fmQ==", "dev": true, "dependencies": { "fast-glob": "3.3.1" @@ -955,9 +957,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "15.1.2", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.1.2.tgz", - "integrity": "sha512-b9TN7q+j5/7+rGLhFAVZiKJGIASuo8tWvInGfAd8wsULjB1uNGRCj1z1WZwwPWzVQbIKWFYqc+9L7W09qwt52w==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.1.4.tgz", + "integrity": "sha512-wBEMBs+np+R5ozN1F8Y8d/Dycns2COhRnkxRc+rvnbXke5uZBHkUGFgWxfTXn5rx7OLijuUhyfB+gC/ap58dDw==", "cpu": [ "arm64" ], @@ -970,9 +972,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "15.1.2", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.1.2.tgz", - "integrity": "sha512-caR62jNDUCU+qobStO6YJ05p9E+LR0EoXh1EEmyU69cYydsAy7drMcOlUlRtQihM6K6QfvNwJuLhsHcCzNpqtA==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.1.4.tgz", + "integrity": "sha512-7sgf5rM7Z81V9w48F02Zz6DgEJulavC0jadab4ZsJ+K2sxMNK0/BtF8J8J3CxnsJN3DGcIdC260wEKssKTukUw==", "cpu": [ "x64" ], @@ -985,9 +987,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "15.1.2", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.1.2.tgz", - "integrity": "sha512-fHHXBusURjBmN6VBUtu6/5s7cCeEkuGAb/ZZiGHBLVBXMBy4D5QpM8P33Or8JD1nlOjm/ZT9sEE5HouQ0F+hUA==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.1.4.tgz", + "integrity": "sha512-JaZlIMNaJenfd55kjaLWMfok+vWBlcRxqnRoZrhFQrhM1uAehP3R0+Aoe+bZOogqlZvAz53nY/k3ZyuKDtT2zQ==", "cpu": [ "arm64" ], @@ -1000,9 +1002,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "15.1.2", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.1.2.tgz", - "integrity": "sha512-9CF1Pnivij7+M3G74lxr+e9h6o2YNIe7QtExWq1KUK4hsOLTBv6FJikEwCaC3NeYTflzrm69E5UfwEAbV2U9/g==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.1.4.tgz", + "integrity": "sha512-7EBBjNoyTO2ipMDgCiORpwwOf5tIueFntKjcN3NK+GAQD7OzFJe84p7a2eQUeWdpzZvhVXuAtIen8QcH71ZCOQ==", "cpu": [ "arm64" ], @@ -1015,9 +1017,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "15.1.2", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.1.2.tgz", - "integrity": "sha512-tINV7WmcTUf4oM/eN3Yuu/f8jQ5C6AkueZPKeALs/qfdfX57eNv4Ij7rt0SA6iZ8+fMobVfcFVv664Op0caCCg==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.1.4.tgz", + "integrity": "sha512-9TGEgOycqZFuADyFqwmK/9g6S0FYZ3tphR4ebcmCwhL8Y12FW8pIBKJvSwV+UBjMkokstGNH+9F8F031JZKpHw==", "cpu": [ "x64" ], @@ -1030,9 +1032,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "15.1.2", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.1.2.tgz", - "integrity": "sha512-jf2IseC4WRsGkzeUw/cK3wci9pxR53GlLAt30+y+B+2qAQxMw6WAC3QrANIKxkcoPU3JFh/10uFfmoMDF9JXKg==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.1.4.tgz", + "integrity": "sha512-0578bLRVDJOh+LdIoKvgNDz77+Bd85c5JrFgnlbI1SM3WmEQvsjxTA8ATu9Z9FCiIS/AliVAW2DV/BDwpXbtiQ==", "cpu": [ "x64" ], @@ -1045,9 +1047,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "15.1.2", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.1.2.tgz", - "integrity": "sha512-wvg7MlfnaociP7k8lxLX4s2iBJm4BrNiNFhVUY+Yur5yhAJHfkS8qPPeDEUH8rQiY0PX3u/P7Q/wcg6Mv6GSAA==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.1.4.tgz", + "integrity": "sha512-JgFCiV4libQavwII+kncMCl30st0JVxpPOtzWcAI2jtum4HjYaclobKhj+JsRu5tFqMtA5CJIa0MvYyuu9xjjQ==", "cpu": [ "arm64" ], @@ -1060,9 +1062,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "15.1.2", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.1.2.tgz", - "integrity": "sha512-D3cNA8NoT3aWISWmo7HF5Eyko/0OdOO+VagkoJuiTk7pyX3P/b+n8XA/MYvyR+xSVcbKn68B1rY9fgqjNISqzQ==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.1.4.tgz", + "integrity": "sha512-xxsJy9wzq7FR5SqPCUqdgSXiNXrMuidgckBa8nH9HtjjxsilgcN6VgXF6tZ3uEWuVEadotQJI8/9EQ6guTC4Yw==", "cpu": [ "x64" ], @@ -1078,7 +1080,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1091,7 +1092,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "license": "MIT", "engines": { "node": ">= 8" } @@ -1100,7 +1100,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1114,7 +1113,6 @@ "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", "dev": true, - "license": "MIT", "engines": { "node": ">=12.4.0" } @@ -1123,7 +1121,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.2.1.tgz", "integrity": "sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -1132,20 +1129,18 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "license": "MIT", "optional": true, "engines": { "node": ">=14" } }, "node_modules/@playwright/test": { - "version": "1.47.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.47.1.tgz", - "integrity": "sha512-dbWpcNQZ5nj16m+A5UNScYx7HX5trIy7g4phrcitn+Nk83S32EBX/CLU4hiF4RGKX/yRc93AAqtfaXB7JWBd4Q==", + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.1.tgz", + "integrity": "sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==", "devOptional": true, - "license": "Apache-2.0", "dependencies": { - "playwright": "1.47.1" + "playwright": "1.49.1" }, "bin": { "playwright": "cli.js" @@ -1154,11 +1149,15 @@ "node": ">=18" } }, - "node_modules/@radix-ui/primitive": { + "node_modules/@radix-ui/number": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", - "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.0.tgz", + "integrity": "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", + "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==" }, "node_modules/@radix-ui/react-alert-dialog": { "version": "1.1.4", @@ -1187,68 +1186,12 @@ } } }, - "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", - "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==" - }, - "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", - "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-context": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", - "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", - "dependencies": { - "@radix-ui/react-slot": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-arrow": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", - "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", - "license": "MIT", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.1.tgz", + "integrity": "sha512-NaVpZfmv8SKeZbn4ijN2V3jlHA9ngBG16VnIIm22nUR0Yk8KUALyBxT3KYEUnNuch9sTE8UTsS3whzBgKOL30w==", "dependencies": { - "@radix-ui/react-primitive": "2.0.0" + "@radix-ui/react-primitive": "2.0.1" }, "peerDependencies": { "@types/react": "*", @@ -1290,26 +1233,19 @@ } } }, - "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-context": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", - "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", + "node_modules/@radix-ui/react-checkbox": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.3.tgz", + "integrity": "sha512-HD7/ocp8f1B3e6OHygH0n7ZKjONkhciy1Nh0yuBgObqThc3oyx+vuMfFHKAknXRHHWVE9XvXStxJFyjUmB8PIw==", "dependencies": { - "@radix-ui/react-slot": "1.1.1" + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -1326,19 +1262,15 @@ } } }, - "node_modules/@radix-ui/react-checkbox": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.3.tgz", - "integrity": "sha512-HD7/ocp8f1B3e6OHygH0n7ZKjONkhciy1Nh0yuBgObqThc3oyx+vuMfFHKAknXRHHWVE9XvXStxJFyjUmB8PIw==", + "node_modules/@radix-ui/react-collection": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.1.tgz", + "integrity": "sha512-LwT3pSho9Dljg+wY2KN2mrrh6y3qELfftINERIzBUO9e0N+t0oMTyn3k9iv+ZqgrwGkRnLpNJrsMv9BZlt2yuA==", "dependencies": { - "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-controllable-state": "1.1.0", - "@radix-ui/react-use-previous": "1.1.0", - "@radix-ui/react-use-size": "1.1.0" + "@radix-ui/react-slot": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1355,12 +1287,7 @@ } } }, - "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", - "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==" - }, - "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-compose-refs": { + "node_modules/@radix-ui/react-compose-refs": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", @@ -1374,7 +1301,7 @@ } } }, - "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-context": { + "node_modules/@radix-ui/react-context": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", @@ -1388,13 +1315,25 @@ } } }, - "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-presence": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", - "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.4.tgz", + "integrity": "sha512-Ur7EV1IwQGCyaAuyDRiOLA5JIUZxELJljF+MbM/2NC0BYwfuRrbpS30BiQBJrVruscgUkieKkqXYDOoByaxIoA==", "dependencies": { + "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.0" + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-slot": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "^2.6.1" }, "peerDependencies": { "@types/react": "*", @@ -1411,12 +1350,30 @@ } } }, - "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", + "node_modules/@radix-ui/react-direction": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.3.tgz", + "integrity": "sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==", "dependencies": { - "@radix-ui/react-slot": "1.1.1" + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-escape-keydown": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -1433,15 +1390,18 @@ } } }, - "node_modules/@radix-ui/react-collection": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.1.tgz", - "integrity": "sha512-LwT3pSho9Dljg+wY2KN2mrrh6y3qELfftINERIzBUO9e0N+t0oMTyn3k9iv+ZqgrwGkRnLpNJrsMv9BZlt2yuA==", + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.4.tgz", + "integrity": "sha512-iXU1Ab5ecM+yEepGAWK8ZhMyKX4ubFdCNtol4sT9D0OVErG9PNElfx3TQhjw7n7BC5nFVz68/5//clWy+8TXzA==", "dependencies": { + "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-menu": "2.1.4", "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-slot": "1.1.1" + "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -1458,10 +1418,10 @@ } } }, - "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-compose-refs": { + "node_modules/@radix-ui/react-focus-guards": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", - "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz", + "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -1472,26 +1432,44 @@ } } }, - "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-context": { + "node_modules/@radix-ui/react-focus-scope": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", - "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.1.tgz", + "integrity": "sha512-01omzJAYRxXdG2/he/+xy+c8a8gCydoQ1yOxnWNcRhrrBW5W+RQJ22EK1SaO8tb3WoUsuEw7mJjBozPzihDFjA==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0" + }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", + "node_modules/@radix-ui/react-hover-card": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.4.tgz", + "integrity": "sha512-QSUUnRA3PQ2UhvoCv3eYvMnCAgGQW+sTu86QPuNb+ZMi+ZENd6UWpiXbcWDQ4AEaKF9KKpCHBeaJz9Rw6lRlaQ==", "dependencies": { - "@radix-ui/react-slot": "1.1.1" + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-popper": "1.2.1", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -1508,11 +1486,13 @@ } } }, - "node_modules/@radix-ui/react-compose-refs": { + "node_modules/@radix-ui/react-id": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", - "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -1523,38 +1503,49 @@ } } }, - "node_modules/@radix-ui/react-context": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", - "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", - "license": "MIT", + "node_modules/@radix-ui/react-label": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.1.tgz", + "integrity": "sha512-UUw5E4e/2+4kFMH7+YxORXGWggtY6sM8WIwh5RZchhLuUg2H1hc98Py+pr8HMz6rdaYrK2t296ZEjYLOCO5uUw==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.1" + }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-dialog": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.4.tgz", - "integrity": "sha512-Ur7EV1IwQGCyaAuyDRiOLA5JIUZxELJljF+MbM/2NC0BYwfuRrbpS30BiQBJrVruscgUkieKkqXYDOoByaxIoA==", + "node_modules/@radix-ui/react-menu": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.4.tgz", + "integrity": "sha512-BnOgVoL6YYdHAG6DtXONaR29Eq4nvbi8rutrV/xlr3RQCMMb3yqP85Qiw/3NReozrSW+4dfLkK+rc1hb4wPU/A==", "dependencies": { "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", "@radix-ui/react-dismissable-layer": "1.1.3", "@radix-ui/react-focus-guards": "1.1.1", "@radix-ui/react-focus-scope": "1.1.1", "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.1", "@radix-ui/react-portal": "1.1.3", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-roving-focus": "1.1.1", "@radix-ui/react-slot": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-callback-ref": "1.1.0", "aria-hidden": "^1.1.1", "react-remove-scroll": "^2.6.1" }, @@ -1573,72 +1564,25 @@ } } }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", - "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==" - }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", - "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-context": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", - "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.3.tgz", - "integrity": "sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==", + "node_modules/@radix-ui/react-navigation-menu": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.3.tgz", + "integrity": "sha512-IQWAsQ7dsLIYDrn0WqPU+cdM7MONTv9nqrLVYoie3BPiabSfUVDe6Fr+oEt0Cofsr9ONDcDe9xhmJbL1Uq1yKg==", "dependencies": { "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.1", "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-escape-keydown": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-portal": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz", - "integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-layout-effect": "1.1.0" + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1655,76 +1599,26 @@ } } }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-presence": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", - "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", + "node_modules/@radix-ui/react-popover": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.4.tgz", + "integrity": "sha512-aUACAkXx8LaFymDma+HQVji7WhvEhpFJ7+qPz17Nf4lLZqtreGOFRiNQWQmhzp7kEWg9cOyyQJpdIMUMPc/CPw==", "dependencies": { + "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", - "dependencies": { - "@radix-ui/react-slot": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-direction": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", - "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz", - "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-escape-keydown": "1.1.0" + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.1", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-slot": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "^2.6.1" }, "peerDependencies": { "@types/react": "*", @@ -1741,18 +1635,21 @@ } } }, - "node_modules/@radix-ui/react-dropdown-menu": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.4.tgz", - "integrity": "sha512-iXU1Ab5ecM+yEepGAWK8ZhMyKX4ubFdCNtol4sT9D0OVErG9PNElfx3TQhjw7n7BC5nFVz68/5//clWy+8TXzA==", + "node_modules/@radix-ui/react-popper": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.1.tgz", + "integrity": "sha512-3kn5Me69L+jv82EKRuQCXdYyf1DqHwD2U/sxoNgBGCB7K9TRc3bQamQ+5EPM9EvyPdli0W41sROd+ZU1dTCztw==", "dependencies": { - "@radix-ui/primitive": "1.1.1", + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-menu": "2.1.4", "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-controllable-state": "1.1.0" + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -1769,45 +1666,13 @@ } } }, - "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", - "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==" - }, - "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", - "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-context": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", - "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", + "node_modules/@radix-ui/react-portal": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz", + "integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==", "dependencies": { - "@radix-ui/react-slot": "1.1.1" + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -1824,28 +1689,13 @@ } } }, - "node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz", - "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-focus-scope": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.1.tgz", - "integrity": "sha512-01omzJAYRxXdG2/he/+xy+c8a8gCydoQ1yOxnWNcRhrrBW5W+RQJ22EK1SaO8tb3WoUsuEw7mJjBozPzihDFjA==", + "node_modules/@radix-ui/react-presence": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", + "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", "dependencies": { "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-callback-ref": "1.1.0" + "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -1862,21 +1712,7 @@ } } }, - "node_modules/@radix-ui/react-focus-scope/node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", - "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-focus-scope/node_modules/@radix-ui/react-primitive": { + "node_modules/@radix-ui/react-primitive": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", @@ -1898,1204 +1734,13 @@ } } }, - "node_modules/@radix-ui/react-hover-card": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.4.tgz", - "integrity": "sha512-QSUUnRA3PQ2UhvoCv3eYvMnCAgGQW+sTu86QPuNb+ZMi+ZENd6UWpiXbcWDQ4AEaKF9KKpCHBeaJz9Rw6lRlaQ==", - "dependencies": { - "@radix-ui/primitive": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.3", - "@radix-ui/react-popper": "1.2.1", - "@radix-ui/react-portal": "1.1.3", - "@radix-ui/react-presence": "1.1.2", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-controllable-state": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", - "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==" - }, - "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-arrow": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.1.tgz", - "integrity": "sha512-NaVpZfmv8SKeZbn4ijN2V3jlHA9ngBG16VnIIm22nUR0Yk8KUALyBxT3KYEUnNuch9sTE8UTsS3whzBgKOL30w==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", - "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-context": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", - "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.3.tgz", - "integrity": "sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==", - "dependencies": { - "@radix-ui/primitive": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-escape-keydown": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-popper": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.1.tgz", - "integrity": "sha512-3kn5Me69L+jv82EKRuQCXdYyf1DqHwD2U/sxoNgBGCB7K9TRc3bQamQ+5EPM9EvyPdli0W41sROd+ZU1dTCztw==", - "dependencies": { - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0", - "@radix-ui/react-use-rect": "1.1.0", - "@radix-ui/react-use-size": "1.1.0", - "@radix-ui/rect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-portal": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz", - "integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-presence": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", - "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", - "dependencies": { - "@radix-ui/react-slot": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-id": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", - "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-label": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.1.tgz", - "integrity": "sha512-UUw5E4e/2+4kFMH7+YxORXGWggtY6sM8WIwh5RZchhLuUg2H1hc98Py+pr8HMz6rdaYrK2t296ZEjYLOCO5uUw==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", - "dependencies": { - "@radix-ui/react-slot": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-menu": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.4.tgz", - "integrity": "sha512-BnOgVoL6YYdHAG6DtXONaR29Eq4nvbi8rutrV/xlr3RQCMMb3yqP85Qiw/3NReozrSW+4dfLkK+rc1hb4wPU/A==", - "dependencies": { - "@radix-ui/primitive": "1.1.1", - "@radix-ui/react-collection": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-dismissable-layer": "1.1.3", - "@radix-ui/react-focus-guards": "1.1.1", - "@radix-ui/react-focus-scope": "1.1.1", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-popper": "1.2.1", - "@radix-ui/react-portal": "1.1.3", - "@radix-ui/react-presence": "1.1.2", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-roving-focus": "1.1.1", - "@radix-ui/react-slot": "1.1.1", - "@radix-ui/react-use-callback-ref": "1.1.0", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "^2.6.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", - "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==" - }, - "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-arrow": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.1.tgz", - "integrity": "sha512-NaVpZfmv8SKeZbn4ijN2V3jlHA9ngBG16VnIIm22nUR0Yk8KUALyBxT3KYEUnNuch9sTE8UTsS3whzBgKOL30w==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", - "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-context": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", - "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.3.tgz", - "integrity": "sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==", - "dependencies": { - "@radix-ui/primitive": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-escape-keydown": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-popper": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.1.tgz", - "integrity": "sha512-3kn5Me69L+jv82EKRuQCXdYyf1DqHwD2U/sxoNgBGCB7K9TRc3bQamQ+5EPM9EvyPdli0W41sROd+ZU1dTCztw==", - "dependencies": { - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0", - "@radix-ui/react-use-rect": "1.1.0", - "@radix-ui/react-use-size": "1.1.0", - "@radix-ui/rect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-portal": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz", - "integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-presence": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", - "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", - "dependencies": { - "@radix-ui/react-slot": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.4.tgz", - "integrity": "sha512-aUACAkXx8LaFymDma+HQVji7WhvEhpFJ7+qPz17Nf4lLZqtreGOFRiNQWQmhzp7kEWg9cOyyQJpdIMUMPc/CPw==", - "dependencies": { - "@radix-ui/primitive": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.3", - "@radix-ui/react-focus-guards": "1.1.1", - "@radix-ui/react-focus-scope": "1.1.1", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-popper": "1.2.1", - "@radix-ui/react-portal": "1.1.3", - "@radix-ui/react-presence": "1.1.2", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-slot": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.1.0", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "^2.6.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", - "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==" - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-arrow": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.1.tgz", - "integrity": "sha512-NaVpZfmv8SKeZbn4ijN2V3jlHA9ngBG16VnIIm22nUR0Yk8KUALyBxT3KYEUnNuch9sTE8UTsS3whzBgKOL30w==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", - "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-context": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", - "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.3.tgz", - "integrity": "sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==", - "dependencies": { - "@radix-ui/primitive": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-escape-keydown": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-popper": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.1.tgz", - "integrity": "sha512-3kn5Me69L+jv82EKRuQCXdYyf1DqHwD2U/sxoNgBGCB7K9TRc3bQamQ+5EPM9EvyPdli0W41sROd+ZU1dTCztw==", - "dependencies": { - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0", - "@radix-ui/react-use-rect": "1.1.0", - "@radix-ui/react-use-size": "1.1.0", - "@radix-ui/rect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-portal": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz", - "integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-presence": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", - "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", - "dependencies": { - "@radix-ui/react-slot": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popper": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", - "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", - "license": "MIT", - "dependencies": { - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0", - "@radix-ui/react-use-rect": "1.1.0", - "@radix-ui/react-use-size": "1.1.0", - "@radix-ui/rect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-portal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz", - "integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-presence": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz", - "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", - "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-slot": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", - "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-progress": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.1.tgz", - "integrity": "sha512-6diOawA84f/eMxFHcWut0aE1C2kyE9dOyCTQOMRR2C/qPiXz/X0SaiA/RLbapQaXUCmy0/hLMf9meSccD1N0pA==", - "dependencies": { - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-primitive": "2.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-progress/node_modules/@radix-ui/react-context": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", - "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-progress/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", - "dependencies": { - "@radix-ui/react-slot": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-roving-focus": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.1.tgz", - "integrity": "sha512-QE1RoxPGJ/Nm8Qmk0PxP8ojmoaS67i0s7hVssS7KuI2FQoc/uzVlZsqKfQvxPE6D8hICCPHJ4D88zNhT3OOmkw==", - "dependencies": { - "@radix-ui/primitive": "1.1.1", - "@radix-ui/react-collection": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", - "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==" - }, - "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", - "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-context": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", - "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", - "dependencies": { - "@radix-ui/react-slot": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-separator": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.1.tgz", - "integrity": "sha512-RRiNRSrD8iUiXriq/Y5n4/3iE8HzqgLHsusUSg5jVpU2+3tqcUFPJXHDymwEypunc2sWxDUS3UC+rkZRlHedsw==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", - "dependencies": { - "@radix-ui/react-slot": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-slot": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz", - "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-slot/node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", - "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-switch": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.1.2.tgz", - "integrity": "sha512-zGukiWHjEdBCRyXvKR6iXAQG6qXm2esuAD6kDOi9Cn+1X6ev3ASo4+CsYaD6Fov9r/AQFekqnD/7+V0Cs6/98g==", - "dependencies": { - "@radix-ui/primitive": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-controllable-state": "1.1.0", - "@radix-ui/react-use-previous": "1.1.0", - "@radix-ui/react-use-size": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", - "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==" - }, - "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", - "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-context": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", - "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", - "dependencies": { - "@radix-ui/react-slot": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tabs": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.2.tgz", - "integrity": "sha512-9u/tQJMcC2aGq7KXpGivMm1mgq7oRJKXphDwdypPd/j21j/2znamPU8WkXgnhUaTrSFNIt8XhOyCAupg8/GbwQ==", - "dependencies": { - "@radix-ui/primitive": "1.1.1", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-presence": "1.1.2", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-roving-focus": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", - "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==" - }, - "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", - "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-context": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", - "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-presence": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", - "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", + "node_modules/@radix-ui/react-progress": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.1.tgz", + "integrity": "sha512-6diOawA84f/eMxFHcWut0aE1C2kyE9dOyCTQOMRR2C/qPiXz/X0SaiA/RLbapQaXUCmy0/hLMf9meSccD1N0pA==", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.0" + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.1" }, "peerDependencies": { "@types/react": "*", @@ -3112,12 +1757,20 @@ } } }, - "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.1.tgz", + "integrity": "sha512-QE1RoxPGJ/Nm8Qmk0PxP8ojmoaS67i0s7hVssS7KuI2FQoc/uzVlZsqKfQvxPE6D8hICCPHJ4D88zNhT3OOmkw==", "dependencies": { - "@radix-ui/react-slot": "1.1.1" + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -3134,23 +1787,32 @@ } } }, - "node_modules/@radix-ui/react-toast": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.4.tgz", - "integrity": "sha512-Sch9idFJHJTMH9YNpxxESqABcAFweJG4tKv+0zo0m5XBvUSL8FM5xKcJLFLXononpePs8IclyX1KieL5SDUNgA==", + "node_modules/@radix-ui/react-select": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.4.tgz", + "integrity": "sha512-pOkb2u8KgO47j/h7AylCj7dJsm69BXcjkrvTqMptFqsE2i0p8lHkfgneXKjAgPzBMivnoMyt8o4KiV4wYzDdyQ==", "dependencies": { + "@radix-ui/number": "1.1.0", "@radix-ui/primitive": "1.1.1", "@radix-ui/react-collection": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.1", "@radix-ui/react-portal": "1.1.3", - "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-slot": "1.1.1", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-controllable-state": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0", - "@radix-ui/react-visually-hidden": "1.1.1" + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "^2.6.1" }, "peerDependencies": { "@types/react": "*", @@ -3167,49 +1829,12 @@ } } }, - "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", - "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==" - }, - "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", - "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-context": { + "node_modules/@radix-ui/react-separator": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", - "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.3.tgz", - "integrity": "sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.1.tgz", + "integrity": "sha512-RRiNRSrD8iUiXriq/Y5n4/3iE8HzqgLHsusUSg5jVpU2+3tqcUFPJXHDymwEypunc2sWxDUS3UC+rkZRlHedsw==", "dependencies": { - "@radix-ui/primitive": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-escape-keydown": "1.1.0" + "@radix-ui/react-primitive": "2.0.1" }, "peerDependencies": { "@types/react": "*", @@ -3226,36 +1851,35 @@ } } }, - "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-portal": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz", - "integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==", + "node_modules/@radix-ui/react-slot": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz", + "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==", "dependencies": { - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-layout-effect": "1.1.0" + "@radix-ui/react-compose-refs": "1.1.1" }, "peerDependencies": { "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true - }, - "@types/react-dom": { - "optional": true } } }, - "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-presence": { + "node_modules/@radix-ui/react-switch": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", - "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.1.2.tgz", + "integrity": "sha512-zGukiWHjEdBCRyXvKR6iXAQG6qXm2esuAD6kDOi9Cn+1X6ev3ASo4+CsYaD6Fov9r/AQFekqnD/7+V0Cs6/98g==", "dependencies": { + "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.0" + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -3272,12 +1896,19 @@ } } }, - "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.2.tgz", + "integrity": "sha512-9u/tQJMcC2aGq7KXpGivMm1mgq7oRJKXphDwdypPd/j21j/2znamPU8WkXgnhUaTrSFNIt8XhOyCAupg8/GbwQ==", "dependencies": { - "@radix-ui/react-slot": "1.1.1" + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-roving-focus": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -3294,12 +1925,23 @@ } } }, - "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-visually-hidden": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.1.tgz", - "integrity": "sha512-vVfA2IZ9q/J+gEamvj761Oq1FpWgCDaNOOIfbPVp2MVPLEomUr5+Vf7kJGwQ24YxZSlQVar7Bes8kyTo5Dshpg==", + "node_modules/@radix-ui/react-toast": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.4.tgz", + "integrity": "sha512-Sch9idFJHJTMH9YNpxxESqABcAFweJG4tKv+0zo0m5XBvUSL8FM5xKcJLFLXononpePs8IclyX1KieL5SDUNgA==", "dependencies": { - "@radix-ui/react-primitive": "2.0.1" + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -3317,23 +1959,22 @@ } }, "node_modules/@radix-ui/react-tooltip": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.2.tgz", - "integrity": "sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-dismissable-layer": "1.1.0", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.6.tgz", + "integrity": "sha512-TLB5D8QLExS1uDn7+wH/bjEmRurNMTzNrtq7IjaS4kjion9NtzsTGkvR5+i7yc9q01Pi2KMM2cN3f8UG4IvvXA==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.3", "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-popper": "1.2.0", - "@radix-ui/react-portal": "1.1.1", - "@radix-ui/react-presence": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-popper": "1.2.1", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-slot": "1.1.1", "@radix-ui/react-use-controllable-state": "1.1.0", - "@radix-ui/react-visually-hidden": "1.1.0" + "@radix-ui/react-visually-hidden": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -3350,28 +1991,10 @@ } } }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", - "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-use-callback-ref": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", - "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -3386,7 +2009,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", - "license": "MIT", "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.0" }, @@ -3404,7 +2026,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", - "license": "MIT", "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.0" }, @@ -3422,7 +2043,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", - "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -3437,7 +2057,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", - "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -3452,7 +2071,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", - "license": "MIT", "dependencies": { "@radix-ui/rect": "1.1.0" }, @@ -3470,7 +2088,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", - "license": "MIT", "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.0" }, @@ -3485,12 +2102,11 @@ } }, "node_modules/@radix-ui/react-visually-hidden": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", - "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==", - "license": "MIT", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.1.tgz", + "integrity": "sha512-vVfA2IZ9q/J+gEamvj761Oq1FpWgCDaNOOIfbPVp2MVPLEomUr5+Vf7kJGwQ24YxZSlQVar7Bes8kyTo5Dshpg==", "dependencies": { - "@radix-ui/react-primitive": "2.0.0" + "@radix-ui/react-primitive": "2.0.1" }, "peerDependencies": { "@types/react": "*", @@ -3510,14 +2126,12 @@ "node_modules/@radix-ui/rect": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", - "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==", - "license": "MIT" + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" }, "node_modules/@redis/bloom": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", - "license": "MIT", "peerDependencies": { "@redis/client": "^1.0.0" } @@ -3526,7 +2140,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.0.tgz", "integrity": "sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg==", - "license": "MIT", "dependencies": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", @@ -3540,7 +2153,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz", "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==", - "license": "MIT", "peerDependencies": { "@redis/client": "^1.0.0" } @@ -3549,7 +2161,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.7.tgz", "integrity": "sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==", - "license": "MIT", "peerDependencies": { "@redis/client": "^1.0.0" } @@ -3558,7 +2169,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.2.0.tgz", "integrity": "sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==", - "license": "MIT", "peerDependencies": { "@redis/client": "^1.0.0" } @@ -3567,7 +2177,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.1.0.tgz", "integrity": "sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==", - "license": "MIT", "peerDependencies": { "@redis/client": "^1.0.0" } @@ -3575,15 +2184,13 @@ "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", - "license": "MIT" + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==" }, "node_modules/@rushstack/eslint-patch": { "version": "1.10.4", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz", "integrity": "sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@swc/counter": { "version": "0.1.3", @@ -3607,15 +2214,13 @@ "version": "3.21.8", "resolved": "https://registry.npmjs.org/@types/cytoscape/-/cytoscape-3.21.8.tgz", "integrity": "sha512-6Bo9ZDrv0vfwe8Sg/ERc5VL0yU0gYvP4dgZi0fAXYkKHfyHaNqWRMcwYm3mu4sLsXbB8ZuXE75sR7qnaOL5JgQ==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@types/cytoscape-fcose": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/@types/cytoscape-fcose/-/cytoscape-fcose-2.2.4.tgz", "integrity": "sha512-QwWtnT8HI9h+DHhG5krGc1ZY0Ex+cn85MvX96ZNAjSxuXiZDnjIZW/ypVkvvubTjIY4rSdkJY1D/Nsn8NDpmAw==", "dev": true, - "license": "MIT", "dependencies": { "@types/cytoscape": "*" } @@ -3624,20 +2229,17 @@ "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "license": "MIT" + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, "node_modules/@types/lodash": { - "version": "4.17.7", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", - "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==", - "license": "MIT" + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.14.tgz", + "integrity": "sha512-jsxagdikDiDBeIRaPYtArcT8my4tN1og7MtMRquFT3XNA6axxyHDRUemqDz/taRDdOUn0GnGHRCuff4q48sW9A==" }, "node_modules/@types/minimatch": { "version": "3.0.5", @@ -3645,11 +2247,10 @@ "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==" }, "node_modules/@types/node": { - "version": "20.16.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz", - "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==", + "version": "20.17.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.11.tgz", + "integrity": "sha512-Ept5glCK35R8yeyIeYlRIZtX6SLRyqMhOFTgj5SOkMpLTdw3SEHI9fHx60xaUZ+V1aJxQJODE+7/j5ocZydYTg==", "dev": true, - "license": "MIT", "dependencies": { "undici-types": "~6.19.2" } @@ -3660,16 +2261,14 @@ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" }, "node_modules/@types/prop-types": { - "version": "15.7.13", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", - "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", - "license": "MIT" + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==" }, "node_modules/@types/react": { - "version": "18.3.8", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.8.tgz", - "integrity": "sha512-syBUrW3/XpnW4WJ41Pft+I+aPoDVbrBVQGEnbD7NijDGlVC+8gV/XKRY+7vMDlfPpbwYt0l1vd/Sj8bJGMbs9Q==", - "license": "MIT", + "version": "18.3.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz", + "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -3680,20 +2279,18 @@ "resolved": "https://registry.npmjs.org/@types/react-cytoscapejs/-/react-cytoscapejs-1.2.5.tgz", "integrity": "sha512-G9VcGQOlER3njklOu5D0FDGHYfkQJ3yEL95kGbgI/MR08N5dQ7IbLSZI8WqaB4fG0zOURIg0BUtOCrbE5HRZEQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/cytoscape": "*", "@types/react": "*" } }, "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "version": "18.3.5", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", + "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", "devOptional": true, - "license": "MIT", - "dependencies": { - "@types/react": "*" + "peerDependencies": { + "@types/react": "^18.0.0" } }, "node_modules/@types/react-gtm-module": { @@ -3706,15 +2303,13 @@ "version": "7.5.8", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "6.21.0", @@ -3745,25 +2340,11 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/parser": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", @@ -3792,7 +2373,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/types": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0" @@ -3810,7 +2390,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/typescript-estree": "6.21.0", "@typescript-eslint/utils": "6.21.0", @@ -3838,7 +2417,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, - "license": "MIT", "engines": { "node": "^16.0.0 || >=18.0.0" }, @@ -3852,7 +2430,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0", @@ -3876,25 +2453,11 @@ } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/utils": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", @@ -3915,25 +2478,11 @@ "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/visitor-keys": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" @@ -3947,10 +2496,9 @@ } }, "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "license": "ISC" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", + "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==" }, "node_modules/@vue/compiler-core": { "version": "3.5.13", @@ -4012,10 +2560,9 @@ } }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "license": "MIT", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "bin": { "acorn": "bin/acorn" }, @@ -4027,7 +2574,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -4036,7 +2582,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4052,7 +2597,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", "engines": { "node": ">=8" } @@ -4074,14 +2618,12 @@ "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "license": "MIT" + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -4093,20 +2635,20 @@ "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "license": "MIT" + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } }, "node_modules/aria-hidden": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", - "license": "MIT", "dependencies": { "tslib": "^2.0.0" }, @@ -4115,12 +2657,11 @@ } }, "node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "license": "Apache-2.0", - "dependencies": { - "deep-equal": "^2.0.5" + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "engines": { + "node": ">= 0.4" } }, "node_modules/array-buffer-byte-length": { @@ -4150,7 +2691,6 @@ "version": "3.1.8", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -4170,7 +2710,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "license": "MIT", "engines": { "node": ">=8" } @@ -4179,7 +2718,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -4199,7 +2737,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -4216,15 +2753,14 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "license": "MIT", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4234,15 +2770,14 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "license": "MIT", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4255,7 +2790,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -4298,14 +2832,12 @@ "node_modules/ast-types-flow": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", - "license": "MIT" + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==" }, "node_modules/attr-accept": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", - "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==", - "license": "MIT", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz", + "integrity": "sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==", "engines": { "node": ">=4" } @@ -4350,7 +2882,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -4362,10 +2893,9 @@ } }, "node_modules/axe-core": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.0.tgz", - "integrity": "sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==", - "license": "MPL-2.0", + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz", + "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==", "engines": { "node": ">=4" } @@ -4374,7 +2904,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", - "license": "Apache-2.0", "engines": { "node": ">= 0.4" } @@ -4382,8 +2911,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/bezier-js": { "version": "6.1.4", @@ -4398,7 +2926,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "license": "MIT", "engines": { "node": ">=8" }, @@ -4410,7 +2937,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -4419,7 +2945,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -4428,9 +2953,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz", + "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==", "funding": [ { "type": "opencollective", @@ -4446,9 +2971,9 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": { @@ -4525,7 +3050,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", "engines": { "node": ">=6" } @@ -4545,15 +3069,14 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001684", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001684.tgz", - "integrity": "sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==", + "version": "1.0.30001690", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", + "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", "funding": [ { "type": "opencollective", @@ -4574,17 +3097,31 @@ "resolved": "https://registry.npmjs.org/canvas-color-tracker/-/canvas-color-tracker-1.3.1.tgz", "integrity": "sha512-eNycxGS7oQ3IS/9QQY41f/aQjiO9Y/MtedhCgSdsbLSxC9EyUD8L3ehl/Q3Kfmvt8um79S45PBV+5Rxm5ztdSw==", "dependencies": { - "tinycolor2": "^1.6.0" + "tinycolor2": "^1.6.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=12" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -4608,7 +3145,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -4617,31 +3153,20 @@ } }, "node_modules/class-variance-authority": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz", - "integrity": "sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==", - "license": "Apache-2.0", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", "dependencies": { - "clsx": "2.0.0" + "clsx": "^2.1.1" }, "funding": { - "url": "https://joebell.co.uk" - } - }, - "node_modules/class-variance-authority/node_modules/clsx": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", - "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", - "license": "MIT", - "engines": { - "node": ">=6" + "url": "https://polar.sh/cva" } }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", - "license": "MIT" + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, "node_modules/cliui": { "version": "7.0.4", @@ -4657,7 +3182,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "license": "MIT", "engines": { "node": ">=6" } @@ -4666,7 +3190,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", - "license": "Apache-2.0", "engines": { "node": ">=0.10.0" } @@ -4675,7 +3198,6 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-0.2.1.tgz", "integrity": "sha512-U6//9lQ6JvT47+6OF6Gi8BvkxYQ8SCRRSKIJkthIMsFsLZRG0cKvTtuTaefyIKMQb8rvvXy0wGdpTNq/jPtm+g==", - "license": "MIT", "dependencies": { "@radix-ui/react-dialog": "1.0.0" }, @@ -4688,7 +3210,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", "integrity": "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==", - "license": "MIT", "dependencies": { "@babel/runtime": "^7.13.10" } @@ -4697,7 +3218,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz", "integrity": "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==", - "license": "MIT", "dependencies": { "@babel/runtime": "^7.13.10" }, @@ -4709,7 +3229,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.0.tgz", "integrity": "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==", - "license": "MIT", "dependencies": { "@babel/runtime": "^7.13.10" }, @@ -4721,7 +3240,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.0.tgz", "integrity": "sha512-Yn9YU+QlHYLWwV1XfKiqnGVpWYWk6MeBVM6x/bcoyPvxgjQGoeT35482viLPctTMWoMw0PoHgqfSox7Ig+957Q==", - "license": "MIT", "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.0", @@ -4748,7 +3266,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.0.tgz", "integrity": "sha512-n7kDRfx+LB1zLueRDvZ1Pd0bxdJWDUZNQ/GWoxDn2prnuJKRdxsjulejX/ePkOsLi2tTm6P24mDqlMSgQpsT6g==", - "license": "MIT", "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.0", @@ -4766,7 +3283,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.0.tgz", "integrity": "sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ==", - "license": "MIT", "dependencies": { "@babel/runtime": "^7.13.10" }, @@ -4778,7 +3294,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.0.tgz", "integrity": "sha512-C4SWtsULLGf/2L4oGeIHlvWQx7Rf+7cX/vKOAD2dXW0A1b5QXwi3wWeaEgW+wn+SEVrraMUk05vLU9fZZz5HbQ==", - "license": "MIT", "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0", @@ -4794,7 +3309,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.0.tgz", "integrity": "sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==", - "license": "MIT", "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-layout-effect": "1.0.0" @@ -4807,7 +3321,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.0.tgz", "integrity": "sha512-a8qyFO/Xb99d8wQdu4o7qnigNjTPG123uADNecz0eX4usnQEj7o+cG4ZX4zkqq98NYekT7UoEQIjxBNWIFuqTA==", - "license": "MIT", "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-primitive": "1.0.0" @@ -4821,7 +3334,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.0.tgz", "integrity": "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==", - "license": "MIT", "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0", @@ -4836,7 +3348,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", - "license": "MIT", "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-slot": "1.0.0" @@ -4850,7 +3361,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", - "license": "MIT", "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0" @@ -4863,7 +3373,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz", "integrity": "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==", - "license": "MIT", "dependencies": { "@babel/runtime": "^7.13.10" }, @@ -4875,7 +3384,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz", "integrity": "sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==", - "license": "MIT", "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-callback-ref": "1.0.0" @@ -4888,7 +3396,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.0.tgz", "integrity": "sha512-JwfBCUIfhXRxKExgIqGa4CQsiMemo1Xt0W/B4ei3fpzpvPENKpMKQ8mZSB6Acj3ebrAEgi2xiQvcI1PAAodvyg==", - "license": "MIT", "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-callback-ref": "1.0.0" @@ -4901,7 +3408,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz", "integrity": "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==", - "license": "MIT", "dependencies": { "@babel/runtime": "^7.13.10" }, @@ -4913,7 +3419,6 @@ "version": "2.5.4", "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.4.tgz", "integrity": "sha512-xGVKJJr0SJGQVirVFAUZ2k1QLyO6m+2fy0l8Qawbp5Jgrv3DeLalrfMNBFSlmz5kriGGzsVBtGVnf4pTKIhhWA==", - "license": "MIT", "dependencies": { "react-remove-scroll-bar": "^2.3.3", "react-style-singleton": "^2.2.1", @@ -4971,23 +3476,28 @@ "simple-swizzle": "^0.2.2" } }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/confusing-browser-globals": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "license": "MIT" + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" }, "node_modules/cookie": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "license": "MIT", "engines": { "node": ">= 0.6" } @@ -4996,7 +3506,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", - "license": "MIT", "dependencies": { "layout-base": "^2.0.0" } @@ -5016,19 +3525,10 @@ "node": ">=10" } }, - "node_modules/cosmiconfig/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" - } - }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -5042,7 +3542,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "license": "MIT", "bin": { "cssesc": "bin/cssesc" }, @@ -5053,14 +3552,12 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT" + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/cytoscape": { - "version": "3.30.2", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.2.tgz", - "integrity": "sha512-oICxQsjW8uSaRmn4UK/jkczKOqTrVqt5/1WL0POiJUT2EKNc9STM4hYFHv917yu55aTBMFNRzymlJhVAiWPCxw==", - "license": "MIT", + "version": "3.30.4", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.4.tgz", + "integrity": "sha512-OxtlZwQl1WbwMmLiyPSEBuzeTIQnwZhJYYWFzZ2PhEHVFwpeaqNIkUzSiso00D98qk60l8Gwon2RP304d3BJ1A==", "engines": { "node": ">=0.10" } @@ -5069,7 +3566,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", - "license": "MIT", "dependencies": { "cose-base": "^2.2.0" }, @@ -5164,9 +3660,9 @@ } }, "node_modules/d3-octree": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/d3-octree/-/d3-octree-1.0.2.tgz", - "integrity": "sha512-Qxg4oirJrNXauiuC94uKMbgxwnhdda9xRLl9ihq45srlJ4Ga3CSgqGcAL8iW7N5CIv4Oz8x3E734ulxyvHPvwA==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-octree/-/d3-octree-1.1.0.tgz", + "integrity": "sha512-F8gPlqpP+HwRPMO/8uOu5wjH110+6q4cgJvgJT6vlpy3BEaDIKlTZrgHKZSp/i1InRpVfh4puY/kvL6MxK930A==" }, "node_modules/d3-quadtree": { "version": "3.0.1", @@ -5277,8 +3773,7 @@ "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "license": "BSD-2-Clause" + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" }, "node_modules/data-view-buffer": { "version": "1.0.2", @@ -5329,10 +3824,9 @@ } }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "license": "MIT", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dependencies": { "ms": "^2.1.3" }, @@ -5345,49 +3839,15 @@ } } }, - "node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "license": "MIT" + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -5404,7 +3864,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -5453,26 +3912,6 @@ "node": ">=10" } }, - "node_modules/depcheck/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/depcheck/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/depcheck/node_modules/minimatch": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", @@ -5487,30 +3926,19 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/depcheck/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/depcheck/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/deps-regex": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/deps-regex/-/deps-regex-0.2.0.tgz", "integrity": "sha512-PwuBojGMQAYbWkMXOY9Pd/NWCDNHVH12pnS7WHqZkTSeMESe4hwnKKRp0yR87g37113x4JPbo/oIvXY+s/f56Q==" }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, "node_modules/detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", @@ -5531,21 +3959,18 @@ "node_modules/detect-node-es": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", - "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", - "license": "MIT" + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "license": "Apache-2.0" + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -5556,14 +3981,12 @@ "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "license": "MIT" + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -5587,24 +4010,21 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "license": "MIT" + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/echarts": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.5.1.tgz", - "integrity": "sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==", - "license": "Apache-2.0", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.6.0.tgz", + "integrity": "sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==", "dependencies": { "tslib": "2.3.0", - "zrender": "5.6.0" + "zrender": "5.6.1" } }, "node_modules/echarts-for-react": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/echarts-for-react/-/echarts-for-react-3.0.2.tgz", "integrity": "sha512-DRwIiTzx8JfwPOVgGttDytBqdp5VzCSyMRIxubgU/g2n9y3VLUmF2FK7Icmg/sNVkv4+rktmrLN9w22U2yy3fA==", - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "size-sensor": "^1.0.1" @@ -5617,26 +4037,48 @@ "node_modules/echarts/node_modules/tslib": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", - "license": "0BSD" + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" }, "node_modules/electron-to-chromium": { - "version": "1.5.67", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.67.tgz", - "integrity": "sha512-nz88NNBsD7kQSAGGJyp8hS6xSPtWwqNogA0mjtc2nUYeEf3nURK9qpV18TuBdDmEDgVWotS8Wkzf+V52dSQ/LQ==" + "version": "1.5.76", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.76.tgz", + "integrity": "sha512-CjVQyG7n7Sr+eBXE86HIulnL5N8xZY1sgmOPGuq/F0Rr0FJq63lg0kEtOIDfZBk44FnDLf6FUJ+dsJcuiUDdDQ==" + }, + "node_modules/embla-carousel": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.5.1.tgz", + "integrity": "sha512-JUb5+FOHobSiWQ2EJNaueCNT/cQU9L6XWBbWmorWPQT9bkbk+fhsuLr8wWrzXKagO3oWszBO7MSx+GfaRk4E6A==" + }, + "node_modules/embla-carousel-react": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.5.1.tgz", + "integrity": "sha512-z9Y0K84BJvhChXgqn2CFYbfEi6AwEr+FFVVKm/MqbTQ2zIzO1VQri6w67LcfpVF0AjbhwVMywDZqY4alYkjW5w==", + "dependencies": { + "embla-carousel": "8.5.1", + "embla-carousel-reactive-utils": "8.5.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/embla-carousel-reactive-utils": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.5.1.tgz", + "integrity": "sha512-n7VSoGIiiDIc4MfXF3ZRTO59KDp820QDuyBDGlt5/65+lumPHxX2JLz0EZ23hZ4eg4vZGUXwMkYv02fw2JVo/A==", + "peerDependencies": { + "embla-carousel": "8.5.1" + } }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "license": "MIT" + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, "node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", + "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==", "dev": true, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -5664,15 +4106,10 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/error-ex/node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, "node_modules/es-abstract": { - "version": "1.23.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.7.tgz", - "integrity": "sha512-OygGC8kIcDhXX+6yAZRGLqwi2CmEXCbLQixeGUgYeR+Qwlppqmo7DIDr8XibtEBZp+fJcoYpoatp5qwLMEdcqQ==", + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", @@ -5685,10 +4122,11 @@ "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", + "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.2.6", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", @@ -5709,9 +4147,12 @@ "object-inspect": "^1.13.3", "object-keys": "^1.1.1", "object.assign": "^4.1.7", + "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.3", "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", @@ -5741,31 +4182,10 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", "engines": { "node": ">= 0.4" } }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/es-iterator-helpers": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", @@ -5796,7 +4216,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, @@ -5805,14 +4224,14 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "license": "MIT", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dependencies": { - "get-intrinsic": "^1.2.4", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -5822,7 +4241,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "license": "MIT", "dependencies": { "hasown": "^2.0.0" } @@ -5851,11 +4269,22 @@ "node": ">=6" } }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint": { "version": "8.57.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "license": "MIT", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -5910,7 +4339,6 @@ "version": "19.0.4", "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz", "integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==", - "license": "MIT", "dependencies": { "eslint-config-airbnb-base": "^15.0.0", "object.assign": "^4.1.2", @@ -5931,7 +4359,6 @@ "version": "15.0.0", "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", - "license": "MIT", "dependencies": { "confusing-browser-globals": "^1.0.10", "object.assign": "^4.1.2", @@ -5946,12 +4373,19 @@ "eslint-plugin-import": "^2.25.2" } }, + "node_modules/eslint-config-airbnb-base/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-config-airbnb-typescript": { "version": "17.1.0", "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-17.1.0.tgz", "integrity": "sha512-GPxI5URre6dDpJ0CtcthSZVBAfI+Uw7un5OYNVxP2EYi3H81Jw701yFP7AU+/vCE7xBtFmjge7kfhhk4+RAiig==", "dev": true, - "license": "MIT", "dependencies": { "eslint-config-airbnb-base": "^15.0.0" }, @@ -5963,12 +4397,12 @@ } }, "node_modules/eslint-config-next": { - "version": "15.1.2", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-15.1.2.tgz", - "integrity": "sha512-PrMm1/4zWSJ689wd/ypWIR5ZF1uvmp3EkgpgBV1Yu6PhEobBjXMGgT8bVNelwl17LXojO8D5ePFRiI4qXjsPRA==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-15.1.4.tgz", + "integrity": "sha512-u9+7lFmfhKNgGjhQ9tBeyCFsPJyq0SvGioMJBngPC7HXUpR0U+ckEwQR48s7TrRNHra1REm6evGL2ie38agALg==", "dev": true, "dependencies": { - "@next/eslint-plugin-next": "15.1.2", + "@next/eslint-plugin-next": "15.1.4", "@rushstack/eslint-patch": "^1.10.3", "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", @@ -6005,7 +4439,6 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", - "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -6017,7 +4450,6 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "license": "MIT", "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", @@ -6028,26 +4460,24 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-import-resolver-typescript": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.3.tgz", - "integrity": "sha512-ud9aw4szY9cCT1EWWdGv1L1XR6hh2PaRWif0j2QjQ0pgTY/69iw+W0Z4qZv5wHahOl8isEr+k/JnyAqNQkLkIA==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.7.0.tgz", + "integrity": "sha512-Vrwyi8HHxY97K5ebydMtffsWAn1SCR9eol49eCd5fJS4O1WV7PaAjbcjmbfJJSMz/t4Mal212Uz/fQZrOB8mow==", "dev": true, - "license": "ISC", "dependencies": { "@nolyfill/is-core-module": "1.0.39", - "debug": "^4.3.5", + "debug": "^4.3.7", "enhanced-resolve": "^5.15.0", - "eslint-module-utils": "^2.8.1", "fast-glob": "^3.3.2", "get-tsconfig": "^4.7.5", "is-bun-module": "^1.0.2", - "is-glob": "^4.0.3" + "is-glob": "^4.0.3", + "stable-hash": "^0.0.4" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -6089,7 +4519,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "license": "MIT", "dependencies": { "ms": "^2.1.1" } @@ -6130,7 +4559,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6140,7 +4568,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "license": "MIT", "dependencies": { "ms": "^2.1.1" } @@ -6149,7 +4576,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -6161,7 +4587,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6169,13 +4594,20 @@ "node": "*" } }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.0.tgz", - "integrity": "sha512-ySOHvXX8eSN6zz8Bywacm7CvGNhUtdjvqfQDVe6020TUK34Cywkw7m0KsCCk1Qtm9G1FayfTN1/7mMYnYO2Bhg==", - "license": "MIT", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", "dependencies": { - "aria-query": "~5.1.3", + "aria-query": "^5.3.2", "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", @@ -6183,14 +4615,13 @@ "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", - "es-iterator-helpers": "^1.0.19", "hasown": "^2.0.2", "jsx-ast-utils": "^3.3.5", "language-tags": "^1.0.9", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "safe-regex-test": "^1.0.3", - "string.prototype.includes": "^2.0.0" + "string.prototype.includes": "^2.0.1" }, "engines": { "node": ">=4.0" @@ -6203,7 +4634,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6213,7 +4643,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6222,27 +4651,27 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.37.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz", - "integrity": "sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==", + "version": "7.37.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.3.tgz", + "integrity": "sha512-DomWuTQPFYZwF/7c9W2fkKkStqZmBd3uugfqBYLdkZ3Hii23WzZuOLUskGxB8qkSKqftxEeGL1TB2kMhrce0jA==", "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", - "array.prototype.flatmap": "^1.3.2", + "array.prototype.flatmap": "^1.3.3", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.1.0", + "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.8", "object.fromentries": "^2.0.8", - "object.values": "^1.2.0", + "object.values": "^1.2.1", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.11", + "string.prototype.matchall": "^4.0.12", "string.prototype.repeat": "^1.0.0" }, "engines": { @@ -6256,7 +4685,6 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", - "license": "MIT", "engines": { "node": ">=10" }, @@ -6268,7 +4696,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6278,7 +4705,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -6290,7 +4716,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6302,7 +4727,6 @@ "version": "2.0.0-next.5", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", - "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -6315,11 +4739,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -6335,7 +4766,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -6343,49 +4773,24 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/eslint/node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -6396,20 +4801,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6417,23 +4823,10 @@ "node": "*" } }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -6462,7 +4855,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -6474,7 +4866,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -6486,7 +4877,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -6500,7 +4890,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -6517,9 +4906,9 @@ } }, "node_modules/falkordb": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/falkordb/-/falkordb-6.2.3.tgz", - "integrity": "sha512-2JTKO6d8vCTtQiOd/MgxW6XnxBK1AfjPQx4yPQITKx6ULHDbymldTNqN5Rea+wPcGHprk4DLkGwFAO4Mdr1zkw==", + "version": "6.2.7", + "resolved": "https://registry.npmjs.org/falkordb/-/falkordb-6.2.7.tgz", + "integrity": "sha512-PQpQv76r6VnS/u2jjlSAeJ5Oq89Eqi9YKIMTwIls/NVy2Tet/M/HP/MFH1XIXAMjxySrQ7bFaRCKCq+c98kjKA==", "dependencies": { "@redis/client": "^1.6.0", "cluster-key-slot": "1.1.2", @@ -6531,20 +4920,18 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "license": "MIT", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -6554,7 +4941,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -6565,20 +4951,17 @@ "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "license": "MIT" + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "license": "ISC", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", + "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", "dependencies": { "reusify": "^1.0.4" } @@ -6587,7 +4970,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -6596,12 +4978,11 @@ } }, "node_modules/file-selector": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz", - "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==", - "license": "MIT", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-2.1.2.tgz", + "integrity": "sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==", "dependencies": { - "tslib": "^2.4.0" + "tslib": "^2.7.0" }, "engines": { "node": ">= 12" @@ -6611,7 +4992,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -6623,7 +5003,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -6653,7 +5032,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -6664,24 +5042,22 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "license": "ISC" + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==" }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "license": "MIT", "dependencies": { "is-callable": "^1.1.3" } }, "node_modules/force-graph": { - "version": "1.47.1", - "resolved": "https://registry.npmjs.org/force-graph/-/force-graph-1.47.1.tgz", - "integrity": "sha512-NF0prpR8tNGq7oCE/aFImT/6/3wSk585bcp39UAj6SNSPjvKbX6ktCH6cZnjfsnPNx/DYj1rn+cvvjH814HCFA==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/force-graph/-/force-graph-1.47.2.tgz", + "integrity": "sha512-JGAURlgNGH2FrQGa6KcTiA2zreEW32ED6Mfh5UZHxERhyo3RabcftAVnVfgMziOtSl44bHuwdCuI4/afSTUZuQ==", "dependencies": { "@tweenjs/tween.js": "18 - 25", "accessor-fn": "1", @@ -6706,7 +5082,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -6733,14 +5108,12 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -6768,7 +5141,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -6777,7 +5149,6 @@ "version": "3.9.0", "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==", - "license": "MIT", "engines": { "node": ">= 4" } @@ -6791,20 +5162,20 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", - "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", + "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", "dependencies": { "call-bind-apply-helpers": "^1.0.1", - "dunder-proto": "^1.0.0", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "function-bind": "^1.1.2", + "get-proto": "^1.0.0", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "math-intrinsics": "^1.0.0" + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -6817,11 +5188,22 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", - "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-symbol-description": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", @@ -6843,7 +5225,6 @@ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", "dev": true, - "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" }, @@ -6856,7 +5237,6 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "deprecated": "Glob versions prior to v9 are no longer supported", - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6876,7 +5256,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -6888,7 +5267,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6898,7 +5276,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6957,7 +5334,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "license": "MIT", "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" @@ -6974,7 +5350,6 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, - "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -7005,29 +5380,36 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "license": "MIT" + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" }, "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "license": "MIT", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -7064,7 +5446,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, @@ -7079,7 +5460,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -7102,7 +5482,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "license": "MIT", "engines": { "node": ">= 4" } @@ -7111,7 +5490,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -7123,11 +5501,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -7145,7 +5530,6 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -7154,8 +5538,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "1.3.8", @@ -7183,22 +5566,6 @@ "node": ">=12" } }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-array-buffer": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", @@ -7216,16 +5583,19 @@ } }, "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "node_modules/is-async-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.0.tgz", + "integrity": "sha512-GExz9MtyhlZyXYLxzlJRj5WUCE661zhDa1Yna52CN57AJsymh+DvXXjyveSioqSRdxvUrdKdvqB1b5cVKsNpWQ==", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -7252,7 +5622,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -7276,33 +5645,18 @@ } }, "node_modules/is-bun-module": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.2.1.tgz", - "integrity": "sha512-AmidtEM6D6NmUiLOvvU7+IePxjEjOzra2h0pSrsfSAcXwl/83zLLXDByafUJy9k/rKK0pvXMLdwKwGHlX2Ke6Q==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.3.0.tgz", + "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==", "dev": true, - "license": "MIT", "dependencies": { "semver": "^7.6.3" } }, - "node_modules/is-bun-module/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -7311,10 +5665,9 @@ } }, "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", - "license": "MIT", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dependencies": { "hasown": "^2.0.2" }, @@ -7360,7 +5713,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7383,17 +5735,19 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -7406,7 +5760,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -7418,7 +5771,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -7430,7 +5782,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -7454,7 +5805,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "license": "MIT", "engines": { "node": ">=8" } @@ -7480,7 +5830,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -7551,7 +5900,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -7574,13 +5922,12 @@ } }, "node_modules/is-weakset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", - "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", - "license": "MIT", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4" + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -7600,25 +5947,23 @@ "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "license": "MIT" + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/iterator.prototype": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.4.tgz", - "integrity": "sha512-x4WH0BWmrMmg4oHHl+duwubhrvczGlyuGAZu3nvrf0UXOfPu8IhZObFEr7DE/iv01YgVZrsOiRcqw2srkKEDIA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", "dependencies": { "define-data-property": "^1.1.4", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", "has-symbols": "^1.1.0", - "reflect.getprototypeof": "^1.0.8", "set-function-name": "^2.0.2" }, "engines": { @@ -7629,7 +5974,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -7649,10 +5993,9 @@ } }, "node_modules/jiti": { - "version": "1.21.6", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", - "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", - "license": "MIT", + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "bin": { "jiti": "bin/jiti.js" } @@ -7661,7 +6004,6 @@ "version": "4.15.9", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -7669,16 +6011,15 @@ "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dependencies": { - "argparse": "^2.0.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" @@ -7698,8 +6039,7 @@ "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "license": "MIT" + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", @@ -7709,14 +6049,12 @@ "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "license": "MIT" + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "node_modules/json5": { "version": "2.2.3", @@ -7733,7 +6071,6 @@ "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", - "license": "MIT", "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", @@ -7759,7 +6096,6 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } @@ -7767,14 +6103,12 @@ "node_modules/language-subtag-registry": { "version": "0.3.23", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", - "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", - "license": "CC0-1.0" + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==" }, "node_modules/language-tags": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", - "license": "MIT", "dependencies": { "language-subtag-registry": "^0.3.20" }, @@ -7785,14 +6119,12 @@ "node_modules/layout-base": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", - "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==", - "license": "MIT" + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==" }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -7802,25 +6134,25 @@ } }, "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "license": "MIT", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" } }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "license": "MIT" + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -7834,8 +6166,7 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash-es": { "version": "4.17.21", @@ -7845,14 +6176,12 @@ "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "license": "MIT" + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -7860,11 +6189,21 @@ "loose-envify": "cli.js" } }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/lucide-react": { "version": "0.301.0", "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.301.0.tgz", "integrity": "sha512-ZMbsXSv8qg3u0wqGngW+dG2Tu20fBqQAu3e0MikjGIx6KUN+4TrL2j3XwWZCcpHEfH9Tw+gqnQXRhHVne5DzJQ==", - "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0" } @@ -7889,7 +6228,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "license": "MIT", "engines": { "node": ">= 8" } @@ -7898,7 +6236,6 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -7912,7 +6249,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -7927,7 +6263,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7936,7 +6271,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } @@ -7944,14 +6278,12 @@ "node_modules/monaco-editor": { "version": "0.47.0", "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.47.0.tgz", - "integrity": "sha512-VabVvHvQ9QmMwXu4du008ZDuyLnHs9j7ThVFsiJoXSOQk18+LF89N4ADzPbFenm0W4V2bGHnFBztIRQTgBfxzw==", - "license": "MIT" + "integrity": "sha512-VabVvHvQ9QmMwXu4du008ZDuyLnHs9j7ThVFsiJoXSOQk18+LF89N4ADzPbFenm0W4V2bGHnFBztIRQTgBfxzw==" }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/multimatch": { "version": "5.0.0", @@ -7995,7 +6327,6 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "license": "MIT", "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -8012,7 +6343,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -8023,15 +6353,14 @@ "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "license": "MIT" + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, "node_modules/next": { - "version": "15.1.2", - "resolved": "https://registry.npmjs.org/next/-/next-15.1.2.tgz", - "integrity": "sha512-nLJDV7peNy+0oHlmY2JZjzMfJ8Aj0/dd3jCwSZS8ZiO5nkQfcZRqDrRN3U5rJtqVTQneIOGZzb6LCNrk7trMCQ==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/next/-/next-15.1.4.tgz", + "integrity": "sha512-mTaq9dwaSuwwOrcu3ebjDYObekkxRnXpuVL21zotM8qE2W0HBOdVIdg2Li9QjMEZrj73LN96LcWcz62V19FjAg==", "dependencies": { - "@next/env": "15.1.2", + "@next/env": "15.1.4", "@swc/counter": "0.1.3", "@swc/helpers": "0.5.15", "busboy": "1.6.0", @@ -8046,14 +6375,14 @@ "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "15.1.2", - "@next/swc-darwin-x64": "15.1.2", - "@next/swc-linux-arm64-gnu": "15.1.2", - "@next/swc-linux-arm64-musl": "15.1.2", - "@next/swc-linux-x64-gnu": "15.1.2", - "@next/swc-linux-x64-musl": "15.1.2", - "@next/swc-win32-arm64-msvc": "15.1.2", - "@next/swc-win32-x64-msvc": "15.1.2", + "@next/swc-darwin-arm64": "15.1.4", + "@next/swc-darwin-x64": "15.1.4", + "@next/swc-linux-arm64-gnu": "15.1.4", + "@next/swc-linux-arm64-musl": "15.1.4", + "@next/swc-linux-x64-gnu": "15.1.4", + "@next/swc-linux-x64-musl": "15.1.4", + "@next/swc-win32-arm64-msvc": "15.1.4", + "@next/swc-win32-x64-msvc": "15.1.4", "sharp": "^0.33.5" }, "peerDependencies": { @@ -8083,7 +6412,6 @@ "version": "4.24.11", "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.24.11.tgz", "integrity": "sha512-pCFXzIDQX7xmHFs4KVH4luCjaCbuPRtZ9oBUjUhOk84mZ9WVPf94n87TxYI4rSRf9HmfHEF8Yep3JrYDVOo3Cw==", - "license": "ISC", "dependencies": { "@babel/runtime": "^7.20.13", "@panva/hkdf": "^1.0.2", @@ -8115,7 +6443,6 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.2.1.tgz", "integrity": "sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==", - "license": "MIT", "peerDependencies": { "next": "*", "react": "*", @@ -8140,7 +6467,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -8151,15 +6477,14 @@ } }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==" }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8175,14 +6500,12 @@ "node_modules/oauth": { "version": "0.9.15", "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", - "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==", - "license": "MIT" + "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==" }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8191,7 +6514,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", - "license": "MIT", "engines": { "node": ">= 6" } @@ -8207,27 +6529,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "license": "MIT", "engines": { "node": ">= 0.4" } @@ -8255,7 +6560,6 @@ "version": "1.1.8", "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -8269,7 +6573,6 @@ "version": "2.0.8", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -8287,7 +6590,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -8298,12 +6600,12 @@ } }, "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "license": "MIT", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, @@ -8318,7 +6620,6 @@ "version": "5.0.3", "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz", "integrity": "sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==", - "license": "MIT", "engines": { "node": "^10.13.0 || >=12.0.0" } @@ -8327,16 +6628,14 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/openid-client": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.7.0.tgz", - "integrity": "sha512-4GCCGZt1i2kTHpwvaC/sCpTpQqDnBzDzuJcJMbH+y1Q5qI8U8RBvoSh28svarXszZHR5BAMXbJPX1PGPRE3VOA==", - "license": "MIT", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.7.1.tgz", + "integrity": "sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew==", "dependencies": { "jose": "^4.15.9", "lru-cache": "^6.0.0", @@ -8347,23 +6646,10 @@ "url": "https://github.com/sponsors/panva" } }, - "node_modules/openid-client/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -8376,11 +6662,26 @@ "node": ">= 0.8.0" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -8395,7 +6696,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -8407,16 +6707,14 @@ } }, "node_modules/package-json-from-dist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", - "license": "BlueOak-1.0.0" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -8453,7 +6751,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "license": "MIT", "engines": { "node": ">=8" } @@ -8462,7 +6759,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8471,7 +6767,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", "engines": { "node": ">=8" } @@ -8479,14 +6774,12 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "license": "MIT" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -8501,14 +6794,12 @@ "node_modules/path-scurry/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "license": "MIT", "engines": { "node": ">=8" } @@ -8522,7 +6813,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", "engines": { "node": ">=8.6" }, @@ -8534,7 +6824,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8543,18 +6832,16 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/playwright": { - "version": "1.47.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.47.1.tgz", - "integrity": "sha512-SUEKi6947IqYbKxRiqnbUobVZY4bF1uu+ZnZNJX9DfU1tlf2UhWfvVjLf01pQx9URsOr18bFVUKXmanYWhbfkw==", - "license": "Apache-2.0", + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.1.tgz", + "integrity": "sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==", "dependencies": { - "playwright-core": "1.47.1" + "playwright-core": "1.49.1" }, "bin": { "playwright": "cli.js" @@ -8567,10 +6854,9 @@ } }, "node_modules/playwright-core": { - "version": "1.47.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.47.1.tgz", - "integrity": "sha512-i1iyJdLftqtt51mEk6AhYFaAJCDx0xQ/O5NU8EKaWFgMjItPVma542Nh/Aq8aLCjIJSzjaiEQGW/nyqLkGF1OQ==", - "license": "Apache-2.0", + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.1.tgz", + "integrity": "sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==", "bin": { "playwright-core": "cli.js" }, @@ -8590,7 +6876,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "license": "MIT", "engines": { "node": ">= 0.4" } @@ -8626,7 +6911,6 @@ "version": "15.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "license": "MIT", "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -8643,7 +6927,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "license": "MIT", "dependencies": { "camelcase-css": "^2.0.1" }, @@ -8672,7 +6955,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "lilconfig": "^3.0.0", "yaml": "^2.3.4" @@ -8693,16 +6975,15 @@ } } }, - "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", - "license": "MIT", - "engines": { - "node": ">=14" + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "bin": { + "yaml": "bin.mjs" }, - "funding": { - "url": "https://github.com/sponsors/antonk52" + "engines": { + "node": ">= 14" } }, "node_modules/postcss-nested": { @@ -8719,7 +7000,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.1.1" }, @@ -8734,7 +7014,6 @@ "version": "6.1.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "license": "MIT", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -8746,14 +7025,12 @@ "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "license": "MIT" + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/preact": { - "version": "10.24.0", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.0.tgz", - "integrity": "sha512-aK8Cf+jkfyuZ0ZZRG9FbYqwmEiGQ4y/PUO4SuTWoyWL244nZZh7bd5h2APd4rSNDYTBNghg1L+5iJN3Skxtbsw==", - "license": "MIT", + "version": "10.25.4", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.25.4.tgz", + "integrity": "sha512-jLdZDb+Q+odkHJ+MpW/9U5cODzqnB+fy2EiHSZES7ldV5LK7yjlVzTp7R8Xy6W6y75kfK8iWYtFVH7lvjwrCMA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -8763,7 +7040,6 @@ "version": "5.2.6", "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz", "integrity": "sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==", - "license": "MIT", "dependencies": { "pretty-format": "^3.8.0" }, @@ -8775,7 +7051,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -8783,14 +7058,12 @@ "node_modules/pretty-format": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", - "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==", - "license": "MIT" + "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==" }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -8801,7 +7074,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", "engines": { "node": ">=6" } @@ -8823,14 +7095,12 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" }, @@ -8853,7 +7123,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/react-cytoscapejs/-/react-cytoscapejs-2.0.0.tgz", "integrity": "sha512-t3SSl1DQy7+JQjN+8QHi1anEJlM3i3aAeydHTsJwmjo/isyKK7Rs7oCvU6kZsB9NwZidzZQR21Vm2PcBLG/Tjg==", - "license": "MIT", "dependencies": { "prop-types": "^15.8.1" }, @@ -8866,7 +7135,6 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -8876,13 +7144,12 @@ } }, "node_modules/react-dropzone": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.3.tgz", - "integrity": "sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==", - "license": "MIT", + "version": "14.3.5", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.3.5.tgz", + "integrity": "sha512-9nDUaEEpqZLOz5v5SUcFA0CjM4vq8YbqO0WRls+EYT7+DvxUdzDPKNCPLqGfj3YL9MsniCLCD4RFA6M95V6KMQ==", "dependencies": { - "attr-accept": "^2.2.2", - "file-selector": "^0.6.0", + "attr-accept": "^2.2.4", + "file-selector": "^2.1.0", "prop-types": "^15.8.1" }, "engines": { @@ -8914,10 +7181,9 @@ "integrity": "sha512-8gyj4TTxeP7eEyc2QKawEuQoAZdjKvMY4pgWfycGmqGByhs17fR+zEBs0JUDq4US/l+vbTl+6zvUIx27iDo/Vw==" }, "node_modules/react-hook-form": { - "version": "7.53.0", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.53.0.tgz", - "integrity": "sha512-M1n3HhqCww6S2hxLxciEXy2oISPnAzxY7gvwVPrtlczTM/1dDadXgUxDpHMrMTblDOcm/AXtXxHwZ3jpg1mqKQ==", - "license": "MIT", + "version": "7.54.2", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.54.2.tgz", + "integrity": "sha512-eHpAUgUjWbZocoQYUHposymRb4ZP6d0uwUnooL2uOybA9/3tPUvoAKqEWK1WaSiTxxOfTpffNZP7QwlnM3/gEg==", "engines": { "node": ">=18.0.0" }, @@ -8932,8 +7198,7 @@ "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT" + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-json-tree": { "version": "0.19.0", @@ -9011,7 +7276,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-1.0.10.tgz", "integrity": "sha512-0+g0CNqregkuocr+Mi+e6wgWVARnKTYIX3U1QK7GlkLQKCmbymZakx80YGwcRO7HNnKJTQ5v38HlBos/cGxWvg==", - "license": "MIT", "peerDependencies": { "react": "^16.14.0 || ^17.0.0 || ^18.0.0", "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0" @@ -9042,7 +7306,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "license": "MIT", "dependencies": { "pify": "^2.3.0" } @@ -9051,7 +7314,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -9063,10 +7325,6 @@ "version": "4.7.0", "resolved": "https://registry.npmjs.org/redis/-/redis-4.7.0.tgz", "integrity": "sha512-zvmkHEAdGMn+hMRXuMBtu4Vo5P6rHQjLoHftu+lBqq8ZTA3RCVC/WzD790bkKKiNFp7d5/9PcSD19fJyyRvOdQ==", - "license": "MIT", - "workspaces": [ - "./packages/*" - ], "dependencies": { "@redis/bloom": "1.2.0", "@redis/client": "1.6.0", @@ -9077,17 +7335,17 @@ } }, "node_modules/reflect.getprototypeof": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.9.tgz", - "integrity": "sha512-r0Ay04Snci87djAsI4U+WNRcSw5S4pOH7qFjd/veA5gC7TbqESR3tcj28ia95L/fYUDw11JKP7uqUKUAfVvV5Q==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "dunder-proto": "^1.0.1", - "es-abstract": "^1.23.6", + "es-abstract": "^1.23.9", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "gopd": "^1.2.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", "which-builtin-type": "^1.2.1" }, "engines": { @@ -9100,17 +7358,18 @@ "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "license": "MIT" + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/regexp.prototype.flags": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", - "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", "set-function-name": "^2.0.2" }, "engines": { @@ -9134,18 +7393,20 @@ "integrity": "sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==" }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "license": "MIT", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -9163,12 +7424,11 @@ } }, "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/resolve-pkg-maps": { @@ -9176,7 +7436,6 @@ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } @@ -9185,7 +7444,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -9196,7 +7454,6 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", - "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -9225,7 +7482,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -9248,6 +7504,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-regex-test": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", @@ -9268,18 +7539,19 @@ "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" } }, "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/semver-compare": { @@ -9291,7 +7563,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -9308,7 +7579,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -9319,6 +7589,19 @@ "node": ">= 0.4" } }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/sharp": { "version": "0.33.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", @@ -9358,23 +7641,10 @@ "@img/sharp-win32-x64": "0.33.5" } }, - "node_modules/sharp/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "optional": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -9386,7 +7656,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", "engines": { "node": ">=8" } @@ -9463,7 +7732,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", "engines": { "node": ">=14" }, @@ -9479,18 +7747,21 @@ "is-arrayish": "^0.3.1" } }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/size-sensor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/size-sensor/-/size-sensor-1.0.2.tgz", - "integrity": "sha512-2NCmWxY7A9pYKGXNBfteo4hy14gWu47rg5692peVMst6lQLPKrVjhY+UTEsPI5ceFRJSl3gVgMYaUi/hKuaiKw==", - "license": "ISC" + "integrity": "sha512-2NCmWxY7A9pYKGXNBfteo4hy14gWu47rg5692peVMst6lQLPKrVjhY+UTEsPI5ceFRJSl3gVgMYaUi/hKuaiKw==" }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -9499,7 +7770,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -9509,23 +7779,16 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, + "node_modules/stable-hash": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", + "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", + "dev": true + }, "node_modules/state-local": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", - "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==", - "license": "MIT" - }, - "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", - "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", - "license": "MIT", - "dependencies": { - "internal-slot": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==" }, "node_modules/streamsearch": { "version": "1.1.0", @@ -9539,7 +7802,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -9554,7 +7816,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -9567,43 +7828,44 @@ "node_modules/string-width-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/string-width/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/string.prototype.includes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", - "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", - "license": "MIT", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/string.prototype.matchall": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", - "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", - "license": "MIT", + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", + "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "regexp.prototype.flags": "^1.5.2", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", "set-function-name": "^2.0.2", - "side-channel": "^1.0.6" + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -9616,7 +7878,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", - "license": "MIT", "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" @@ -9663,7 +7924,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -9680,7 +7940,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -9693,7 +7952,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -9705,7 +7963,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "license": "MIT", "engines": { "node": ">=4" } @@ -9714,7 +7971,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "license": "MIT", "engines": { "node": ">=8" }, @@ -9748,7 +8004,6 @@ "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", @@ -9766,20 +8021,10 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/sucrase/node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/sucrase/node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -9799,7 +8044,6 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -9810,11 +8054,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -9823,56 +8077,53 @@ } }, "node_modules/swr": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/swr/-/swr-2.2.5.tgz", - "integrity": "sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==", - "license": "MIT", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.0.tgz", + "integrity": "sha512-NyZ76wA4yElZWBHzSgEJc28a0u6QZvhb6w0azeL2k7+Q1gAzVK+IqQYXhVOC/mzi+HZIozrZvBVeSeOZNR2bqA==", "dependencies": { - "client-only": "^0.0.1", - "use-sync-external-store": "^1.2.0" + "dequal": "^2.0.3", + "use-sync-external-store": "^1.4.0" }, "peerDependencies": { - "react": "^16.11.0 || ^17.0.0 || ^18.0.0" + "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/tailwind-merge": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.2.tgz", - "integrity": "sha512-kjEBm+pvD+6eAwzJL2Bi+02/9LFLal1Gs61+QB7HvTfQQ0aXwC5LGT8PEt1gS0CWKktKe6ysPTAy3cBC5MeiIg==", - "license": "MIT", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz", + "integrity": "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==", "funding": { "type": "github", "url": "https://github.com/sponsors/dcastil" } }, "node_modules/tailwindcss": { - "version": "3.4.12", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.12.tgz", - "integrity": "sha512-Htf/gHj2+soPb9UayUNci/Ja3d8pTmu9ONTfh4QY8r3MATTZOzmv6UYWF7ZwikEIC8okpfqmGqrmDehua8mF8w==", - "license": "MIT", + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", - "chokidar": "^3.5.3", + "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", - "fast-glob": "^3.3.0", + "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "jiti": "^1.21.0", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", @@ -9886,7 +8137,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "license": "MIT", "engines": { "node": ">= 6" } @@ -9896,7 +8146,6 @@ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -9904,14 +8153,12 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "license": "MIT" + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "license": "MIT", "dependencies": { "any-promise": "^1.0.0" } @@ -9920,7 +8167,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "license": "MIT", "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -9937,7 +8183,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -9946,11 +8191,10 @@ } }, "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", "dev": true, - "license": "MIT", "engines": { "node": ">=16" }, @@ -9961,14 +8205,12 @@ "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "license": "Apache-2.0" + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "license": "MIT", "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -9980,7 +8222,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "license": "MIT", "dependencies": { "minimist": "^1.2.0" }, @@ -9997,7 +8238,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -10009,7 +8249,6 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -10088,11 +8327,10 @@ } }, "node_modules/typescript": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -10122,8 +8360,7 @@ "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/update-browserslist-db": { "version": "1.1.1", @@ -10158,7 +8395,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -10184,10 +8420,9 @@ } }, "node_modules/use-sidecar": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", - "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", - "license": "MIT", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" @@ -10196,8 +8431,8 @@ "node": ">=10" }, "peerDependencies": { - "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -10206,34 +8441,42 @@ } }, "node_modules/use-sync-external-store": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", - "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", - "license": "MIT", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz", + "integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==", "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, + "node_modules/vaul": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz", + "integrity": "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==", + "dependencies": { + "@radix-ui/react-dialog": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -10292,7 +8535,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "license": "MIT", "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", @@ -10329,7 +8571,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10355,7 +8596,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -10371,8 +8611,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/y18n": { "version": "5.0.8", @@ -10385,19 +8624,14 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yaml": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", - "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "engines": { - "node": ">= 14" + "node": ">= 6" } }, "node_modules/yargs": { @@ -10429,7 +8663,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "license": "MIT", "engines": { "node": ">=10" }, @@ -10437,11 +8670,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zod": { + "version": "3.24.1", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", + "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "node_modules/zrender": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.6.0.tgz", - "integrity": "sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==", - "license": "BSD-3-Clause", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.6.1.tgz", + "integrity": "sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==", "dependencies": { "tslib": "2.3.0" } @@ -10449,8 +8689,7 @@ "node_modules/zrender/node_modules/tslib": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", - "license": "0BSD" + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" } } } diff --git a/package.json b/package.json index b34e0345..d5972990 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ }, "dependencies": { "-": "^0.0.1", + "@hookform/resolvers": "^3.9.1", "@monaco-editor/react": "^4.6.0", "@radix-ui/react-alert-dialog": "^1.1.4", "@radix-ui/react-avatar": "^1.1.2", @@ -21,14 +22,17 @@ "@radix-ui/react-dropdown-menu": "^2.1.4", "@radix-ui/react-hover-card": "^1.1.4", "@radix-ui/react-label": "^2.1.1", + "@radix-ui/react-navigation-menu": "^1.2.3", "@radix-ui/react-popover": "^1.1.4", "@radix-ui/react-progress": "^1.1.1", + "@radix-ui/react-select": "^2.1.4", "@radix-ui/react-separator": "^1.1.1", "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-switch": "^1.1.2", "@radix-ui/react-tabs": "^1.1.2", "@radix-ui/react-toast": "^1.2.4", "@radix-ui/react-tooltip": "^1.0.7", + "@radix-ui/react-visually-hidden": "^1.1.1", "autoprefixer": "^10.4.20", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", @@ -38,6 +42,7 @@ "depcheck": "^1.4.7", "echarts": "^5.5.0", "echarts-for-react": "^3.0.2", + "embla-carousel-react": "^8.5.1", "eslint-config-airbnb": "^19.0.4", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.29.1", @@ -58,13 +63,15 @@ "react-dropzone": "^14.2.3", "react-force-graph-2d": "^1.26.1", "react-gtm-module": "^2.0.11", - "react-hook-form": "^7.49.3", + "react-hook-form": "^7.54.2", "react-json-tree": "^0.19.0", "react-resizable-panels": "^1.0.9", "redis": "^4.6.14", "swr": "^2.2.5", "tailwind-merge": "^2.2.0", - "tailwindcss": "^3.4.1" + "tailwindcss": "^3.4.1", + "vaul": "^1.1.2", + "zod": "^3.24.1" }, "devDependencies": { "@playwright/test": "^1.46.1", diff --git a/public/BrowserLogo.svg b/public/BrowserLogo.svg new file mode 100644 index 00000000..5016d2f6 --- /dev/null +++ b/public/BrowserLogo.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/fonts/oswald.ttf b/public/fonts/oswald.ttf new file mode 100644 index 00000000..938e912a Binary files /dev/null and b/public/fonts/oswald.ttf differ diff --git a/tailwind.config.js b/tailwind.config.js index 79fbadd9..55f8a705 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -14,69 +14,87 @@ module.exports = { ], prefix: "", theme: { - container: { - center: true, - padding: "2rem", - screens: { - "2xl": "1400px", - }, - }, - extend: { - colors: { - border: "hsl(var(--border))", - input: "hsl(var(--input))", - ring: "hsl(var(--ring))", - background: "hsl(var(--background))", - foreground: "hsl(var(--foreground))", - primary: { - DEFAULT: "hsl(var(--primary))", - foreground: "hsl(var(--primary-foreground))", - }, - secondary: { - DEFAULT: "hsl(var(--secondary))", - foreground: "hsl(var(--secondary-foreground))", - }, - destructive: { - DEFAULT: "hsl(var(--destructive))", - foreground: "hsl(var(--destructive-foreground))", - }, - muted: { - DEFAULT: "hsl(var(--muted))", - foreground: "hsl(var(--muted-foreground))", - }, - accent: { - DEFAULT: "hsl(var(--accent))", - foreground: "hsl(var(--accent-foreground))", - }, - popover: { - DEFAULT: "hsl(var(--popover))", - foreground: "hsl(var(--popover-foreground))", - }, - card: { - DEFAULT: "hsl(var(--card))", - foreground: "hsl(var(--card-foreground))", - }, - }, - borderRadius: { - lg: "var(--radius)", - md: "calc(var(--radius) - 2px)", - sm: "calc(var(--radius) - 4px)", - }, - keyframes: { - "accordion-down": { - from: { height: "0" }, - to: { height: "var(--radix-accordion-content-height)" }, - }, - "accordion-up": { - from: { height: "var(--radix-accordion-content-height)" }, - to: { height: "0" }, - }, - }, - animation: { - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out", - }, - }, + container: { + center: true, + padding: '2rem', + screens: { + '2xl': '1400px' + } + }, + extend: { + colors: { + border: 'hsl(var(--border))', + input: 'hsl(var(--input))', + ring: 'hsl(var(--ring))', + background: 'hsl(var(--background))', + foreground: 'hsl(var(--foreground))', + primary: { + DEFAULT: 'hsl(var(--primary))', + foreground: 'hsl(var(--primary-foreground))' + }, + secondary: { + DEFAULT: 'hsl(var(--secondary))', + foreground: 'hsl(var(--secondary-foreground))' + }, + destructive: { + DEFAULT: 'hsl(var(--destructive))', + foreground: 'hsl(var(--destructive-foreground))' + }, + muted: { + DEFAULT: 'hsl(var(--muted))', + foreground: 'hsl(var(--muted-foreground))' + }, + accent: { + DEFAULT: 'hsl(var(--accent))', + foreground: 'hsl(var(--accent-foreground))' + }, + popover: { + DEFAULT: 'hsl(var(--popover))', + foreground: 'hsl(var(--popover-foreground))' + }, + card: { + DEFAULT: 'hsl(var(--card))', + foreground: 'hsl(var(--card-foreground))' + }, + sidebar: { + DEFAULT: 'hsl(var(--sidebar-background))', + foreground: 'hsl(var(--sidebar-foreground))', + primary: 'hsl(var(--sidebar-primary))', + 'primary-foreground': 'hsl(var(--sidebar-primary-foreground))', + accent: 'hsl(var(--sidebar-accent))', + 'accent-foreground': 'hsl(var(--sidebar-accent-foreground))', + border: 'hsl(var(--sidebar-border))', + ring: 'hsl(var(--sidebar-ring))' + } + }, + borderRadius: { + lg: 'var(--radius)', + md: 'calc(var(--radius) - 2px)', + sm: 'calc(var(--radius) - 4px)' + }, + keyframes: { + 'accordion-down': { + from: { + height: '0' + }, + to: { + height: 'var(--radix-accordion-content-height)' + } + }, + 'accordion-up': { + from: { + height: 'var(--radix-accordion-content-height)' + }, + to: { + height: '0' + } + } + }, + animation: { + 'accordion-down': 'accordion-down 0.2s ease-out', + 'accordion-up': 'accordion-up 0.2s ease-out' + } + } }, plugins: [], } \ No newline at end of file