diff --git a/.changeset/gentle-foxes-destroy.md b/.changeset/gentle-foxes-destroy.md new file mode 100644 index 000000000..4e36ee34f --- /dev/null +++ b/.changeset/gentle-foxes-destroy.md @@ -0,0 +1,5 @@ +--- +'@yeger/debounce': minor +--- + +add optional args to callback diff --git a/packages/debounce/src/main.ts b/packages/debounce/src/main.ts index c12d681a6..2193161bd 100644 --- a/packages/debounce/src/main.ts +++ b/packages/debounce/src/main.ts @@ -4,12 +4,15 @@ * @param delay - A delay after which the callback will be invoked. * @returns The debounced callback. */ -export function debounce(cb: () => void, delay?: number) { +export function debounce( + cb: (...args: Args) => void, + delay?: number, +) { let timeout: any - return () => { + return (...args: Args) => { if (timeout !== undefined) { clearTimeout(timeout) } - timeout = setTimeout(() => cb(), delay) + timeout = setTimeout(() => cb(...args), delay) } } diff --git a/packages/streams/package.json b/packages/streams/package.json index 0b73629a2..5298fe557 100644 --- a/packages/streams/package.json +++ b/packages/streams/package.json @@ -14,8 +14,8 @@ "exports": { ".": { "types": "./dist/types/index.d.ts", - "require": "./dist/index.umd.js", - "import": "./dist/index.mjs" + "import": "./dist/index.mjs", + "require": "./dist/index.umd.js" } }, "main": "dist/index.umd.js", @@ -38,7 +38,7 @@ "devDependencies": { "@yeger/tsconfig": "workspace:*", "typescript": "5.1.6", - "vite": "4.4.4", + "vite": "4.4.9", "vite-plugin-lib": "workspace:*" }, "publishConfig": { diff --git a/packages/streams/src/sync.ts b/packages/streams/src/sync.ts index 64c2dd7f4..472b52763 100644 --- a/packages/streams/src/sync.ts +++ b/packages/streams/src/sync.ts @@ -28,8 +28,11 @@ export abstract class Stream implements Iterable { return new Map(stream) } - public toRecord(fn: Processor): Record { - return Object.fromEntries(this.map((x) => [fn(x), x] as const)) + public toRecord( + key: Processor, + value: Processor, + ): Record { + return Object.fromEntries(this.map((x) => [key(x), value?.(x)] as const)) } public abstract [Symbol.iterator](): IterableIterator diff --git a/packages/tsconfig/cli.json b/packages/tsconfig/cli.json index 4f5f86b09..52f5089a7 100644 --- a/packages/tsconfig/cli.json +++ b/packages/tsconfig/cli.json @@ -3,6 +3,7 @@ "compilerOptions": { "declaration": false, "module": "CommonJS", + "noEmit": false, "sourceMap": false } } diff --git a/packages/tsconfig/next.json b/packages/tsconfig/next.json index f4bc40de7..189a59083 100644 --- a/packages/tsconfig/next.json +++ b/packages/tsconfig/next.json @@ -2,6 +2,7 @@ "extends": "./web.json", "compilerOptions": { "noEmit": true, - "incremental": true + "incremental": true, + "plugins": [{ "name": "next" }] } } diff --git a/packages/turbo-graph-ui/app/globals.css b/packages/turbo-graph-ui/app/globals.css new file mode 100644 index 000000000..a992fbfd8 --- /dev/null +++ b/packages/turbo-graph-ui/app/globals.css @@ -0,0 +1,80 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 222.2 84% 4.9%; + + --card: 0 0% 100%; + --card-foreground: 222.2 84% 4.9%; + + --popover: 0 0% 100%; + --popover-foreground: 222.2 84% 4.9%; + + --primary: 222.2 47.4% 11.2%; + --primary-foreground: 210 40% 98%; + + --secondary: 210 40% 96.1%; + --secondary-foreground: 222.2 47.4% 11.2%; + + --muted: 210 40% 96.1%; + --muted-foreground: 215.4 16.3% 46.9%; + + --accent: 210 40% 96.1%; + --accent-foreground: 222.2 47.4% 11.2%; + + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 210 40% 98%; + + --border: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 91.4%; + --ring: 222.2 84% 4.9%; + + --radius: 0.5rem; + } + + .dark { + --background: 222.2 84% 4.9%; + --foreground: 210 40% 98%; + + --card: 222.2 84% 4.9%; + --card-foreground: 210 40% 98%; + + --popover: 222.2 84% 4.9%; + --popover-foreground: 210 40% 98%; + + --primary: 210 40% 98%; + --primary-foreground: 222.2 47.4% 11.2%; + + --secondary: 217.2 32.6% 17.5%; + --secondary-foreground: 210 40% 98%; + + --muted: 217.2 32.6% 17.5%; + --muted-foreground: 215 20.2% 65.1%; + + --accent: 217.2 32.6% 17.5%; + --accent-foreground: 210 40% 98%; + + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 210 40% 98%; + + --border: 217.2 32.6% 17.5%; + --input: 217.2 32.6% 17.5%; + --ring: hsl(212.7, 26.8%, 83.9); + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} + +.react-flow__edge { + pointer-events: none !important; +} diff --git a/packages/turbo-graph-ui/app/layout.tsx b/packages/turbo-graph-ui/app/layout.tsx new file mode 100644 index 000000000..45e1c2e43 --- /dev/null +++ b/packages/turbo-graph-ui/app/layout.tsx @@ -0,0 +1,26 @@ +import { FilterInput, TaskInput } from '../components/GraphInputs' +import './globals.css' + +export default function RootLayout({ + // Layouts must accept a children prop. + // This will be populated with nested layouts or pages + children, +}: { + children: React.ReactNode +}) { + return ( + + +
+
+
+ + +
+ {children} +
+
+ + + ) +} diff --git a/packages/turbo-graph-ui/app/loading.tsx b/packages/turbo-graph-ui/app/loading.tsx new file mode 100644 index 000000000..f84bed2af --- /dev/null +++ b/packages/turbo-graph-ui/app/loading.tsx @@ -0,0 +1,4 @@ +export default function Loading() { + // You can add any UI inside Loading, including a Skeleton. + return Loading +} diff --git a/packages/turbo-graph-ui/app/page.tsx b/packages/turbo-graph-ui/app/page.tsx new file mode 100644 index 000000000..b65bc9bf0 --- /dev/null +++ b/packages/turbo-graph-ui/app/page.tsx @@ -0,0 +1,33 @@ +import type { Metadata } from 'next' + +import { Graph } from '../components/Graph' + +export const metadata: Metadata = { + title: 'Turbo Graph', + // m + // + // + // +} + +// TODO: Add error boundary +// TODO: Add loading state +export default async function Home({ + searchParams, +}: { + searchParams?: { [key: string]: string | string[] | undefined } +}) { + const rawTasks = searchParams?.tasks + const tasks = Array.isArray(rawTasks) + ? rawTasks + : rawTasks?.split(' ') ?? ['build'] + const filter = searchParams?.filter + if (filter && Array.isArray(filter)) { + throw new Error(`Unsupported filter ${filter}`) + } + + return +} diff --git a/packages/turbo-graph-ui/components/FlowGraph.tsx b/packages/turbo-graph-ui/components/FlowGraph.tsx new file mode 100644 index 000000000..1e220d66a --- /dev/null +++ b/packages/turbo-graph-ui/components/FlowGraph.tsx @@ -0,0 +1,132 @@ +'use client' + +import { Stream } from '@yeger/streams' +import { scaleOrdinal } from 'd3-scale' +import { schemeSet3 } from 'd3-scale-chromatic' +import { useEffect, useMemo } from 'react' +import { + Background, + Controls, + Handle, + MiniMap, + Position, + ReactFlow, + useReactFlow, +} from 'reactflow' + +import 'reactflow/dist/style.css' +import { + type FlowNode, + TASK_HEIGHT_VAR, + TASK_WIDTH_VAR, + convertGraph, + getTaskColorVar, +} from '../lib/flow' +import type { TurboGraph } from '../lib/turbo' +import { useGraphSettings } from '../lib/utils' + +export interface Props { + graph: TurboGraph + uniqueTasks: Set +} + +interface TaskProps { + data: FlowNode +} + +function Task({ data }: TaskProps) { + const { task, workspace, isTerminal, isOrigin } = data + return ( +
+ {isOrigin ? null : ( + + )} +
+
{task}
+
{workspace}
+
+ {isTerminal ? null : ( + + )} +
+ ) +} + +const nodeTypes = { + task: Task, +} + +export function FlowGraph({ graph, uniqueTasks }: Props) { + const { flowGraph, taskCssVars } = useMemo(() => { + const flowGraph = convertGraph(graph) + const getColor = scaleOrdinal(schemeSet3).domain(uniqueTasks) + const taskColors = Stream.from(uniqueTasks).toRecord( + (task) => getTaskColorVar(task), + (task) => getColor(task), + ) + const taskSize: Record = { + [TASK_WIDTH_VAR]: `${flowGraph.sizeConfig.width}px`, + [TASK_HEIGHT_VAR]: `${flowGraph.sizeConfig.height}px`, + } + const taskCssVars = { ...taskColors, ...taskSize } + return { + flowGraph, + taskColors, + taskCssVars, + } + }, [graph, uniqueTasks]) + + const { setParameter } = useGraphSettings() + + const onNodeClicked = (_: unknown, { data }: { data: FlowNode }) => { + setParameter('filter', data.workspace) + } + + return ( + + + + + `var(${getTaskColorVar(data.task)})` + } + nodeStrokeColor="#000000" + /> + + + ) +} + +function ViewFitter({ graph }: { graph: TurboGraph }) { + const reactFlow = useReactFlow() + useEffect(() => { + setTimeout(() => { + reactFlow.fitView({ duration: 200, padding: 0.3 }) + }, 200) + }, [reactFlow, graph]) + return null +} diff --git a/packages/turbo-graph-ui/components/Graph.tsx b/packages/turbo-graph-ui/components/Graph.tsx new file mode 100644 index 000000000..3d86f85d9 --- /dev/null +++ b/packages/turbo-graph-ui/components/Graph.tsx @@ -0,0 +1,38 @@ +import { Stream } from '@yeger/streams' + +import { getGraph } from '../lib/turbo' + +import { FlowGraph } from './FlowGraph' + +export interface GraphProps { + tasks: string[] + filter?: string +} + +// TODO: Add error boundary +// TODO: Add loading state +export async function Graph({ tasks, filter }: GraphProps) { + const graphResult = await getGraph(tasks, filter) + + if (graphResult.isError) { + // TODO: Improve error message + return ( +
+ + {graphResult.getError().message} + +
+ ) + } + + const graph = graphResult.get() + const uniqueTasks = Stream.from(graph.nodes) + .map(({ task }) => task) + .toSet() + + return ( +
+ +
+ ) +} diff --git a/packages/turbo-graph-ui/components/GraphInputs.tsx b/packages/turbo-graph-ui/components/GraphInputs.tsx new file mode 100644 index 000000000..3228b42ae --- /dev/null +++ b/packages/turbo-graph-ui/components/GraphInputs.tsx @@ -0,0 +1,56 @@ +'use client' + +import { debounce } from '@yeger/debounce' +import { type ChangeEventHandler, useEffect, useRef } from 'react' + +import { Input } from '../components/Input' +import type { GraphParameter } from '../lib/utils' +import { useGraphSettings } from '../lib/utils' + +interface QueryParamInputProps { + param: GraphParameter + placeholder: string + defaultValue?: string +} + +function GraphParameterInput({ + param, + placeholder, + defaultValue, +}: QueryParamInputProps) { + const { getParameter, setParameter } = useGraphSettings() + const urlParameter = getParameter(param) + const onChange: ChangeEventHandler = debounce( + (event) => setParameter(param, event.target.value), + 500, + ) + const ref = useRef(null) + useEffect(() => { + const newValue = urlParameter ?? defaultValue + if (newValue !== undefined) { + ref.current?.setAttribute('value', newValue) + } + }, [ref, param, defaultValue, urlParameter]) + return ( + + ) +} + +export function TaskInput() { + return ( + + ) +} + +export function FilterInput() { + return +} diff --git a/packages/turbo-graph-ui/components/Input.tsx b/packages/turbo-graph-ui/components/Input.tsx new file mode 100644 index 000000000..1188d98b5 --- /dev/null +++ b/packages/turbo-graph-ui/components/Input.tsx @@ -0,0 +1,25 @@ +import { forwardRef } from 'react' + +import { cn } from '../lib/utils' + +export interface InputProps + extends React.InputHTMLAttributes {} + +const Input = forwardRef( + ({ className, type, ...props }, ref) => { + return ( + + ) + }, +) +Input.displayName = 'Input' + +export { Input } diff --git a/packages/turbo-graph-ui/lib/flow.ts b/packages/turbo-graph-ui/lib/flow.ts new file mode 100644 index 000000000..96d7a3e24 --- /dev/null +++ b/packages/turbo-graph-ui/lib/flow.ts @@ -0,0 +1,102 @@ +import { Stream } from '@yeger/streams' +import { graphStratify, sugiyama } from 'd3-dag' +import { type Edge, type Node } from 'reactflow' + +import type { TurboEdge, TurboGraph, TurboNode } from './turbo' + +export type FlowGraph = ReturnType + +export interface SizeConfig { + width: number + height: number + horizontalSpacing: number + verticalSpacing: number +} + +export function convertGraph(graph: TurboGraph) { + const hierarchy = createHierarchy(graph) + const longestLine = getLongestLineLength(graph) + const sizeConfig = createSizeConfig(longestLine) + return createFlowGraph(hierarchy, graph.edges, sizeConfig) +} + +function createHierarchy(graph: TurboGraph) { + const stratify = graphStratify() + return stratify([ + ...graph.nodes.map((node) => ({ + ...node, + id: node.id, + parentIds: graph.edges + .filter((edge) => edge.target === node.id) + .map(({ source }) => source), + })), + ]) +} + +function getLongestLineLength({ nodes }: TurboGraph) { + const length = Math.max( + ...Stream.from(nodes).flatMap(({ task, workspace }) => [ + task.length, + workspace.length, + ]), + ) + if (length < 0) { + return 1 + } + return length +} + +function createSizeConfig(longestLine: number): SizeConfig { + return { + width: longestLine * 10, + height: 64, + horizontalSpacing: 128, + verticalSpacing: 128, + } +} + +export interface FlowNode extends TurboNode { + isOrigin: boolean + isTerminal: boolean +} + +function createFlowGraph( + hierarchy: ReturnType, + turboEdges: TurboEdge[], + sizeConfig: SizeConfig, +) { + const { width, height, horizontalSpacing, verticalSpacing } = sizeConfig + const layout = sugiyama().nodeSize([ + width + horizontalSpacing, + height + verticalSpacing, + ]) + const layoutResult = layout(hierarchy) + const nodes = Stream.from(hierarchy.nodes()) + .map>( + (node) => + ({ + id: node.data.id, + data: { + ...node.data, + isTerminal: node.nchildren() === 0, + isOrigin: node.nparents() === 0, + }, + position: { x: node.x, y: node.y }, + type: 'task', + }) as const, + ) + .toArray() + const edges = turboEdges.map>((edge) => ({ + id: `edge-${edge.source}-${edge.target}`, + source: edge.source, + target: edge.target, + animated: true, + })) + return { nodes, edges, sizeConfig, layoutResult } +} +export function getTaskColorVar(task: string) { + return `--task-color-${task.replace(':', '-')}` +} + +export const TASK_WIDTH_VAR = '--task-width' +export const TASK_HEIGHT_VAR = '--task-height' diff --git a/packages/turbo-graph-ui/pages/api/graph.ts b/packages/turbo-graph-ui/lib/turbo.ts similarity index 59% rename from packages/turbo-graph-ui/pages/api/graph.ts rename to packages/turbo-graph-ui/lib/turbo.ts index 4d70806a7..7fa75abb5 100644 --- a/packages/turbo-graph-ui/pages/api/graph.ts +++ b/packages/turbo-graph-ui/lib/turbo.ts @@ -1,9 +1,9 @@ -// Next.js API route support: https://nextjs.org/docs/api-routes/introduction import fs from 'node:fs/promises' import path from 'node:path' import { execa } from 'execa' -import type { NextApiRequest, NextApiResponse } from 'next' +import type { Result } from 'resumon' +import { err, ok } from 'resumon' interface Data { dir: string @@ -14,38 +14,41 @@ interface Config { pipeline: Record } -export default async function handler( - _: NextApiRequest, - res: NextApiResponse, -) { - const { dir, config } = await findTurboConfig() - const tasks = getTask(config) - const stdout = await executeCommand(tasks, dir) - const graph = await processResult(stdout) - res.status(200).json(graph) +export async function getGraph( + tasks: string[], + filter?: string, +): Promise> { + const filteredTasks = tasks.filter(Boolean) + if (filteredTasks.length === 0) { + return ok({ nodes: [], edges: [] }) + } + const { dir } = await findTurboConfig() + const stdout = await executeCommand(dir, filteredTasks, filter) + return stdout.map(createGraph) } -async function executeCommand(tasks: string[], dir: string): Promise { +async function executeCommand( + dir: string, + tasks: string[], + filter?: string, +): Promise> { // TODO: Get .bin dir location from package manager - const { stdout } = await execa( - `node_modules${path.sep}.bin${path.sep}turbo`, - ['run', ...tasks, '--concurrency=100%', '--graph'], - { - cwd: dir, - }, - ) - return stdout -} - -function getTask(config: Config): string[] { - const pipeline = Object.keys(config.pipeline).map((entry) => { - if (!entry.includes('#')) { - return entry + try { + const args = ['run', ...tasks, '--concurrency=100%', '--graph'] + if (filter) { + args.push(`--filter=${filter}`) } - return entry.substring(entry.indexOf('#') + 1) - }) - - return [...new Set(pipeline)] + const { stdout } = await execa( + `node_modules${path.sep}.bin${path.sep}turbo`, + args, + { + cwd: dir, + }, + ) + return ok(stdout) + } catch (error) { + return err(error as Error) + } } async function findTurboConfig(currentPath = '.'): Promise { @@ -76,13 +79,13 @@ export interface TurboGraph { edges: TurboEdge[] } -async function processResult(input: string): Promise { +function createGraph(input: string): TurboGraph { const edges: TurboEdge[] = input .split('\n') .filter((line) => line.includes('->') && !line.includes('___ROOT___')) .map((line) => line.substring(line.indexOf('"') + 1, line.lastIndexOf('"'))) .map((line) => { - const [source, target] = line.split('" -> "', 2) + const [target, source] = line.split('" -> "', 2) return { source: source!, target: target! } }) const nodes: TurboNode[] = [...new Set(edges.flatMap(Object.values))].map( diff --git a/packages/turbo-graph-ui/lib/utils.ts b/packages/turbo-graph-ui/lib/utils.ts new file mode 100644 index 000000000..00fe39c91 --- /dev/null +++ b/packages/turbo-graph-ui/lib/utils.ts @@ -0,0 +1,30 @@ +import { Stream } from '@yeger/streams' +import { type ClassValue, clsx } from 'clsx' +import { useRouter, useSearchParams } from 'next/navigation' +import { twMerge } from 'tailwind-merge' + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} + +export type GraphParameter = 'tasks' | 'filter' + +export function useGraphSettings() { + const router = useRouter() + const searchParams = useSearchParams() + + function setParameter(param: GraphParameter, newValue: string | null) { + const newSearchParams = Stream.from(searchParams.entries()) + .filter(([key]) => key !== param) + .concat(newValue ? [[param, newValue]] : []) + .map(([key, value]) => `${key}=${value}`) + .join('&') + router.push(`/?${newSearchParams}`) + } + + function getParameter(param: GraphParameter) { + return searchParams.get(param) + } + + return { setParameter, getParameter } +} diff --git a/packages/turbo-graph-ui/next.config.js b/packages/turbo-graph-ui/next.config.js index 1160d3cd4..ae887958d 100644 --- a/packages/turbo-graph-ui/next.config.js +++ b/packages/turbo-graph-ui/next.config.js @@ -1,4 +1,3 @@ -// eslint-disable-next-line tsdoc/syntax /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, diff --git a/packages/turbo-graph-ui/package.json b/packages/turbo-graph-ui/package.json index ae9728709..da602164a 100644 --- a/packages/turbo-graph-ui/package.json +++ b/packages/turbo-graph-ui/package.json @@ -20,20 +20,30 @@ "scripts": { "build": "next build", "check:publish": "publint run --strict", - "dev": "next dev", - "lint": "next lint" + "dev": "next dev --turbo", + "lint": "next lint", + "preview": "next start" }, "peerDependencies": { "turbo": "^1.0.0" }, "dependencies": { - "@tanstack/react-query": "4.32.6", + "@yeger/debounce": "workspace:*", + "@yeger/streams": "workspace:*", + "class-variance-authority": "0.7.0", + "clsx": "2.0.0", + "d3-dag": "1.0.0", "d3-graph-controller": "workspace:*", "d3-scale": "4.0.2", "d3-scale-chromatic": "3.0.0", "execa": "7.2.0", + "lucide-react": "^0.268.0", "react": "18.2.0", - "react-dom": "18.2.0" + "react-dom": "18.2.0", + "reactflow": "11.8.1", + "resumon": "workspace:*", + "tailwind-merge": "^1.14.0", + "tailwindcss-animate": "^1.0.6" }, "devDependencies": { "@types/d3-scale": "4.0.3", @@ -44,7 +54,7 @@ "@yeger/tsconfig": "workspace:*", "autoprefixer": "10.4.14", "eslint-config-next": "13.4.13", - "next": "13.4.13", + "next": "13.4.16", "postcss": "8.4.27", "tailwindcss": "3.3.3", "typescript": "5.1.6" diff --git a/packages/turbo-graph-ui/pages/_app.tsx b/packages/turbo-graph-ui/pages/_app.tsx deleted file mode 100644 index b9a713549..000000000 --- a/packages/turbo-graph-ui/pages/_app.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import '../styles/globals.css' -import { QueryClient, QueryClientProvider } from '@tanstack/react-query' -import type { AppProps } from 'next/app' -import 'd3-graph-controller/default.css' - -const queryClient = new QueryClient() - -export default function App({ Component, pageProps }: AppProps) { - return ( - - - - ) -} diff --git a/packages/turbo-graph-ui/pages/index.tsx b/packages/turbo-graph-ui/pages/index.tsx deleted file mode 100644 index 2958b3451..000000000 --- a/packages/turbo-graph-ui/pages/index.tsx +++ /dev/null @@ -1,170 +0,0 @@ -import { useQuery } from '@tanstack/react-query' -import { - GraphController, - Markers, - PositionInitializers, - defineGraph, - defineGraphConfig, - defineLink, - defineNodeWithDefaults, -} from 'd3-graph-controller' -import { scaleOrdinal } from 'd3-scale' -import { schemeSet3 } from 'd3-scale-chromatic' -import Head from 'next/head' -import { useEffect, useMemo, useRef, useState } from 'react' - -import type { TurboGraph } from './api/graph' - -export default function Home() { - const [, setTrigger] = useState(0) - const trigger = () => setTrigger((val) => val + 1) - const query = useQuery({ - queryKey: ['graph'], - queryFn: async () => { - const res = await fetch('/api/graph') - return (await res.json()) as TurboGraph - }, - }) - - const graphRef = useRef(null) - const graphData = query.data - - const colors = useMemo(() => { - const tasks = [ - ...new Set(graphData?.nodes.map(({ task }) => task) ?? []), - ].sort() - return scaleOrdinal(schemeSet3).domain(tasks) - }, [graphData]) - - const graphController = useMemo(() => { - const container = graphRef.current - if (!container || !graphData) { - return undefined - } - const nodes = graphData.nodes.map((node) => - defineNodeWithDefaults({ - id: node.id, - type: node.task, - color: colors(node.task), - label: { text: node.workspace, color: 'black', fontSize: '0.875rem' }, - }), - ) - const links = graphData.edges.map((edge) => { - const source = nodes.find((node) => node.id === edge.source)! - const target = nodes.find((node) => node.id === edge.target)! - return defineLink({ - source, - target, - color: '#aaa', - label: false, - }) - }) - - return new GraphController( - container, - defineGraph({ nodes, links }), - defineGraphConfig({ - autoResize: true, - hooks: { - afterZoom(scale: number, xOffset: number, yOffset: number) { - container.style.setProperty('--offset-x', `${xOffset}px`) - container.style.setProperty('--offset-y', `${yOffset}px`) - container.style.setProperty('--dot-size', `${scale}rem`) - }, - }, - marker: Markers.Arrow(4), - positionInitializer: - nodes.length > 1 - ? PositionInitializers.Randomized - : PositionInitializers.Centered, - simulation: { - forces: { - link: { length: 200 }, - charge: { - strength: 200, - }, - collision: { - radiusMultiplier: 10, - strength: 300, - }, - }, - }, - zoom: { - min: 0.3, - max: 2, - }, - }), - ) - }, [colors, graphRef, graphData]) - - useEffect(() => { - return () => { - graphController?.shutdown() - } - }, [graphController]) - - const tasks = graphController?.nodeTypes.sort() ?? [] - - return ( -
- - Turbo Graph - - - - -
-
-
- {tasks.map((task) => ( -
- { - graphController?.filterNodesByType( - event.target.checked, - task, - ) - trigger() - }} - /> - -
-
- ))} -
-
-
- - -
-
-
- {!graphController ? ( -
- Loading -
- ) : null} -
-
-
-
- ) -} diff --git a/packages/turbo-graph-ui/styles/globals.css b/packages/turbo-graph-ui/styles/globals.css deleted file mode 100644 index e2545e4d4..000000000 --- a/packages/turbo-graph-ui/styles/globals.css +++ /dev/null @@ -1,39 +0,0 @@ -html, -body { - padding: 0; - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, - Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; -} - -html, -body, -#__next { - width: 100vw; - height: 100vh; -} - -.bg-dotted { - --color-dots: #eeee; - --dot-size: 1rem; - background-image: radial-gradient(var(--color-dots) 15%, transparent 16%); - background-size: var(--dot-size) var(--dot-size); - background-position: var(--offset-x, 0) var(--offset-y, 0); -} - -a { - color: inherit; - text-decoration: none; -} - -* { - box-sizing: border-box; -} - -.node__label { - transform: translateY(-1.5rem); -} - -@tailwind base; -@tailwind components; -@tailwind utilities; diff --git a/packages/turbo-graph-ui/tailwind.config.js b/packages/turbo-graph-ui/tailwind.config.js index cc2cb9261..0377ea1de 100644 --- a/packages/turbo-graph-ui/tailwind.config.js +++ b/packages/turbo-graph-ui/tailwind.config.js @@ -1,12 +1,76 @@ -// eslint-disable-next-line tsdoc/syntax /** @type {import('tailwindcss').Config} */ module.exports = { + darkMode: ["class"], content: [ - './pages/**/*.{js,ts,jsx,tsx}', - './components/**/*.{js,ts,jsx,tsx}', - ], + './pages/**/*.{ts,tsx}', + './components/**/*.{ts,tsx}', + './app/**/*.{ts,tsx}', + './src/**/*.{ts,tsx}', + ], theme: { - extend: {}, + 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", + }, + }, }, - plugins: [], -} + plugins: [require("tailwindcss-animate")], +} \ No newline at end of file diff --git a/packages/turbo-graph-ui/tsconfig.json b/packages/turbo-graph-ui/tsconfig.json index aec81db77..312d932ec 100644 --- a/packages/turbo-graph-ui/tsconfig.json +++ b/packages/turbo-graph-ui/tsconfig.json @@ -1,5 +1,5 @@ { "extends": "@yeger/tsconfig/next", - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": ["node_modules"] } diff --git a/packages/turbo-graph/package.json b/packages/turbo-graph/package.json index 90d5499c0..30732d8cc 100644 --- a/packages/turbo-graph/package.json +++ b/packages/turbo-graph/package.json @@ -29,7 +29,7 @@ "dependencies": { "@yeger/turbo-graph-ui": "workspace:*", "cac": "6.7.14", - "next": "13.4.13", + "next": "13.4.16", "open": "8.4.2", "picocolors": "1.0.0" }, diff --git a/packages/turbo-graph/src/index.ts b/packages/turbo-graph/src/index.ts index b6e17e78e..f05eb1dbb 100644 --- a/packages/turbo-graph/src/index.ts +++ b/packages/turbo-graph/src/index.ts @@ -1,5 +1,6 @@ import { createServer } from 'node:http' import path from 'node:path' +import process from 'node:process' import { cac } from 'cac' import next from 'next' @@ -15,6 +16,7 @@ interface Options { const source = path.dirname(require.resolve('@yeger/turbo-graph-ui')) +const hostname = 'localhost' const defaultPort = 29312 const cli = cac('turbo-graph') @@ -29,17 +31,22 @@ cli.command('').action(startServer) cli.parse() function startServer(options: Options) { - const app = next({ dev: false, dir: source }) + const app = next({ dev: false, dir: source, port: options.port }) const handle = app.getRequestHandler() - createServer(handle).listen(options.port) - - const url = `http://localhost:${options.port}` - - // eslint-disable-next-line no-console - console.log(`${c.green('turbo-graph:')} Listening on ${c.cyan(url)}`) - - if (options.open) { - open(url) - } + app.prepare().then(() => { + createServer(handle) + .once('error', (err) => { + console.error(err) + process.exit(1) + }) + .listen(options.port, () => { + const url = `http://${hostname}:${options.port}` + // eslint-disable-next-line no-console + console.log(`${c.green('turbo-graph:')} Listening on ${c.cyan(url)}`) + if (options.open) { + open(url) + } + }) + }) } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 783608a21..4624af33b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -550,8 +550,8 @@ importers: specifier: 5.1.6 version: 5.1.6 vite: - specifier: 4.4.4 - version: 4.4.4(@types/node@18.16.19) + specifier: 4.4.9 + version: 4.4.9(@types/node@18.17.5) vite-plugin-lib: specifier: workspace:* version: link:../vite-plugin-lib @@ -567,8 +567,8 @@ importers: specifier: 6.7.14 version: 6.7.14 next: - specifier: 13.4.13 - version: 13.4.13(react-dom@18.2.0)(react@18.2.0) + specifier: 13.4.16 + version: 13.4.16(react-dom@18.2.0)(react@18.2.0) open: specifier: 8.4.2 version: 8.4.2 @@ -591,9 +591,21 @@ importers: packages/turbo-graph-ui: dependencies: - '@tanstack/react-query': - specifier: 4.32.6 - version: 4.32.6(react-dom@18.2.0)(react@18.2.0) + '@yeger/debounce': + specifier: workspace:* + version: link:../debounce + '@yeger/streams': + specifier: workspace:* + version: link:../streams + class-variance-authority: + specifier: 0.7.0 + version: 0.7.0 + clsx: + specifier: 2.0.0 + version: 2.0.0 + d3-dag: + specifier: 1.0.0 + version: 1.0.0 d3-graph-controller: specifier: workspace:* version: link:../d3-graph-controller @@ -606,12 +618,27 @@ importers: execa: specifier: 7.2.0 version: 7.2.0 + lucide-react: + specifier: ^0.268.0 + version: 0.268.0(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 react-dom: specifier: 18.2.0 version: 18.2.0(react@18.2.0) + reactflow: + specifier: 11.8.1 + version: 11.8.1(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0) + resumon: + specifier: workspace:* + version: link:../resumon + tailwind-merge: + specifier: ^1.14.0 + version: 1.14.0 + tailwindcss-animate: + specifier: ^1.0.6 + version: 1.0.6(tailwindcss@3.3.3) turbo: specifier: ^1.0.0 version: 1.8.8 @@ -641,8 +668,8 @@ importers: specifier: 13.4.13 version: 13.4.13(eslint@8.47.0)(typescript@5.1.6) next: - specifier: 13.4.13 - version: 13.4.13(react-dom@18.2.0)(react@18.2.0) + specifier: 13.4.16 + version: 13.4.16(react-dom@18.2.0)(react@18.2.0) postcss: specifier: 8.4.27 version: 8.4.27 @@ -2781,8 +2808,8 @@ packages: is-promise: 4.0.0 dev: true - /@next/env@13.4.13: - resolution: {integrity: sha512-fwz2QgVg08v7ZL7KmbQBLF2PubR/6zQdKBgmHEl3BCyWTEDsAQEijjw2gbFhI1tcKfLdOOJUXntz5vZ4S0Polg==} + /@next/env@13.4.16: + resolution: {integrity: sha512-pCU0sJBqdfKP9mwDadxvZd+eLz3fZrTlmmDHY12Hdpl3DD0vy8ou5HWKVfG0zZS6tqhL4wnQqRbspdY5nqa7MA==} /@next/eslint-plugin-next@13.4.13: resolution: {integrity: sha512-RpZeXlPxQ9FLeYN84XHDqRN20XxmVNclYCraLYdifRsmibtcWUWdwE/ANp2C8kgesFRsvwfsw6eOkYNl9sLJ3A==} @@ -2790,72 +2817,72 @@ packages: glob: 7.1.7 dev: true - /@next/swc-darwin-arm64@13.4.13: - resolution: {integrity: sha512-ZptVhHjzUuivnXMNCJ6lER33HN7lC+rZ01z+PM10Ows21NHFYMvGhi5iXkGtBDk6VmtzsbqnAjnx4Oz5um0FjA==} + /@next/swc-darwin-arm64@13.4.16: + resolution: {integrity: sha512-Rl6i1uUq0ciRa3VfEpw6GnWAJTSKo9oM2OrkGXPsm7rMxdd2FR5NkKc0C9xzFCI4+QtmBviWBdF2m3ur3Nqstw==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] requiresBuild: true optional: true - /@next/swc-darwin-x64@13.4.13: - resolution: {integrity: sha512-t9nTiWCLApw8W4G1kqJyYP7y6/7lyal3PftmRturIxAIBlZss9wrtVN8nci50StDHmIlIDxfguYIEGVr9DbFTg==} + /@next/swc-darwin-x64@13.4.16: + resolution: {integrity: sha512-o1vIKYbZORyDmTrPV1hApt9NLyWrS5vr2p5hhLGpOnkBY1cz6DAXjv8Lgan8t6X87+83F0EUDlu7klN8ieZ06A==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] requiresBuild: true optional: true - /@next/swc-linux-arm64-gnu@13.4.13: - resolution: {integrity: sha512-xEHUqC8eqR5DHe8SOmMnDU1K3ggrJ28uIKltrQAwqFSSSmzjnN/XMocZkcVhuncuxYrpbri0iMQstRyRVdQVWg==} + /@next/swc-linux-arm64-gnu@13.4.16: + resolution: {integrity: sha512-JRyAl8lCfyTng4zoOmE6hNI2f1MFUr7JyTYCHl1RxX42H4a5LMwJhDVQ7a9tmDZ/yj+0hpBn+Aan+d6lA3v0UQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@next/swc-linux-arm64-musl@13.4.13: - resolution: {integrity: sha512-sNf3MnLAm8rquSSAoeD9nVcdaDeRYOeey4stOWOyWIgbBDtP+C93amSgH/LPTDoUV7gNiU6f+ghepTjTjRgIUQ==} + /@next/swc-linux-arm64-musl@13.4.16: + resolution: {integrity: sha512-9gqVqNzUMWbUDgDiND18xoUqhwSm2gmksqXgCU0qaOKt6oAjWz8cWYjgpPVD0WICKFylEY/gvPEP1fMZDVFZ/g==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@next/swc-linux-x64-gnu@13.4.13: - resolution: {integrity: sha512-WhcRaJJSHyx9OWmKjjz+OWHumiPZWRqmM/09Bt7Up4UqUJFFhGExeztR4trtv3rflvULatu9IH/nTV8fUUgaMA==} + /@next/swc-linux-x64-gnu@13.4.16: + resolution: {integrity: sha512-KcQGwchAKmZVPa8i5PLTxvTs1/rcFnSltfpTm803Tr/BtBV3AxCkHLfhtoyVtVzx/kl/oue8oS+DSmbepQKwhw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] requiresBuild: true optional: true - /@next/swc-linux-x64-musl@13.4.13: - resolution: {integrity: sha512-+Y4LLhOWWZQIDKVwr2R17lq2KSN0F1c30QVgGIWfnjjHpH8nrIWHEndhqYU+iFuW8It78CiJjQKTw4f51HD7jA==} + /@next/swc-linux-x64-musl@13.4.16: + resolution: {integrity: sha512-2RbMZNxYnJmW8EPHVBsGZPq5zqWAyBOc/YFxq/jIQ/Yn3RMFZ1dZVCjtIcsiaKmgh7mjA/W0ApbumutHNxRqqQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] requiresBuild: true optional: true - /@next/swc-win32-arm64-msvc@13.4.13: - resolution: {integrity: sha512-rWurdOR20uxjfqd1X9vDAgv0Jb26KjyL8akF9CBeFqX8rVaBAnW/Wf6A2gYEwyYY4Bai3T7p1kro6DFrsvBAAw==} + /@next/swc-win32-arm64-msvc@13.4.16: + resolution: {integrity: sha512-thDcGonELN7edUKzjzlHrdoKkm7y8IAdItQpRvvMxNUXa4d9r0ElofhTZj5emR7AiXft17hpen+QAkcWpqG7Jg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] requiresBuild: true optional: true - /@next/swc-win32-ia32-msvc@13.4.13: - resolution: {integrity: sha512-E8bSPwRuY5ibJ3CzLQmJEt8qaWrPYuUTwnrwygPUEWoLzD5YRx9SD37oXRdU81TgGwDzCxpl7z5Nqlfk50xAog==} + /@next/swc-win32-ia32-msvc@13.4.16: + resolution: {integrity: sha512-f7SE1Mo4JAchUWl0LQsbtySR9xCa+x55C0taetjUApKtcLR3AgAjASrrP+oE1inmLmw573qRnE1eZN8YJfEBQw==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] requiresBuild: true optional: true - /@next/swc-win32-x64-msvc@13.4.13: - resolution: {integrity: sha512-4KlyC6jWRubPnppgfYsNTPeWfGCxtWLh5vaOAW/kdzAk9widqho8Qb5S4K2vHmal1tsURi7Onk2MMCV1phvyqA==} + /@next/swc-win32-x64-msvc@13.4.16: + resolution: {integrity: sha512-WamDZm1M/OEM4QLce3lOmD1XdLEl37zYZwlmOLhmF7qYJ2G6oYm9+ejZVv+LakQIsIuXhSpVlOvrxIAHqwRkPQ==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -2930,7 +2957,7 @@ packages: scule: 1.0.0 semver: 7.5.4 unctx: 2.3.1 - unimport: 3.0.14(rollup@3.26.3) + unimport: 3.0.14 untyped: 1.3.2 transitivePeerDependencies: - rollup @@ -2956,7 +2983,7 @@ packages: scule: 1.0.0 semver: 7.5.4 unctx: 2.3.1 - unimport: 3.0.14(rollup@3.26.3) + unimport: 3.0.14 untyped: 1.3.2 transitivePeerDependencies: - rollup @@ -2982,7 +3009,7 @@ packages: scule: 1.0.0 semver: 7.5.4 unctx: 2.3.1 - unimport: 3.0.14(rollup@3.26.3) + unimport: 3.0.14 untyped: 1.3.2 transitivePeerDependencies: - rollup @@ -3004,7 +3031,7 @@ packages: scule: 1.0.0 std-env: 3.3.3 ufo: 1.2.0 - unimport: 3.0.14(rollup@3.26.3) + unimport: 3.0.14 untyped: 1.3.2 transitivePeerDependencies: - rollup @@ -3022,7 +3049,7 @@ packages: postcss-import-resolver: 2.0.0 std-env: 3.3.3 ufo: 1.2.0 - unimport: 3.0.14(rollup@3.26.3) + unimport: 3.0.14 untyped: 1.3.2 transitivePeerDependencies: - rollup @@ -3040,7 +3067,7 @@ packages: postcss-import-resolver: 2.0.0 std-env: 3.3.3 ufo: 1.2.0 - unimport: 3.0.14(rollup@3.26.3) + unimport: 3.0.14 untyped: 1.3.2 transitivePeerDependencies: - rollup @@ -3058,7 +3085,7 @@ packages: postcss-import-resolver: 2.0.0 std-env: 3.3.3 ufo: 1.2.0 - unimport: 3.0.14(rollup@3.26.3) + unimport: 3.0.14 untyped: 1.3.2 transitivePeerDependencies: - rollup @@ -3105,7 +3132,7 @@ packages: vue: ^3.3.4 dependencies: '@nuxt/kit': 3.5.3 - '@rollup/plugin-replace': 5.0.2(rollup@3.26.3) + '@rollup/plugin-replace': 5.0.2 '@vitejs/plugin-vue': 4.2.3(vite@4.3.9)(vue@3.3.4) '@vitejs/plugin-vue-jsx': 3.0.1(vite@4.3.9)(vue@3.3.4) autoprefixer: 10.4.14(postcss@8.4.27) @@ -3130,7 +3157,7 @@ packages: postcss: 8.4.27 postcss-import: 15.1.0(postcss@8.4.27) postcss-url: 10.1.3(postcss@8.4.27) - rollup-plugin-visualizer: 5.9.2(rollup@3.26.3) + rollup-plugin-visualizer: 5.9.2(rollup@3.28.0) std-env: 3.3.3 strip-literal: 1.0.1 ufo: 1.2.0 @@ -3208,6 +3235,114 @@ packages: resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} dev: true + /@reactflow/background@11.2.6(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-SoBArxNk/NygB6ztCR2RWVcx7yRh+zuSKh37bLbW+hdFcTx6ZgC4vs5+HX2xGY9ZIyR9ipg4Z3+l11ubyzr/lw==} + peerDependencies: + react: '>=17' + react-dom: '>=17' + dependencies: + '@reactflow/core': 11.8.1(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0) + classcat: 5.0.4 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + zustand: 4.4.1(@types/react@18.2.20)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - immer + dev: false + + /@reactflow/controls@11.1.17(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-iMMuTwF5QEqlgqKr+3wg3YS0wyEQOX2DV1AQJUaZ9WSW17cjH/pH1B7iNAS1giWyyvpYvd1HiXG2zpJIS/NQDg==} + peerDependencies: + react: '>=17' + react-dom: '>=17' + dependencies: + '@reactflow/core': 11.8.1(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0) + classcat: 5.0.4 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + zustand: 4.4.1(@types/react@18.2.20)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - immer + dev: false + + /@reactflow/core@11.8.1(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Ob/21U3Wnugq10zbBESwUxH6NMBoJGvBmJdLJB8ux/w4mzGUMxTR78gFXAsPGsuO3J/pf9MVMPrhTsPA0rApCw==} + peerDependencies: + react: '>=17' + react-dom: '>=17' + dependencies: + '@types/d3': 7.4.0 + '@types/d3-drag': 3.0.2 + '@types/d3-selection': 3.0.5 + '@types/d3-zoom': 3.0.3 + classcat: 5.0.4 + d3-drag: 3.0.0 + d3-selection: 3.0.0 + d3-zoom: 3.0.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + zustand: 4.4.1(@types/react@18.2.20)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - immer + dev: false + + /@reactflow/minimap@11.6.1(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-158m6x0f7es5cmmkfhZYVNI7Yc5gxo+9aHqNDFwu9SR5HeyOU5ezJ6CDsSdHuM6xUNq3kXY1f0Ds6YxvyfRmGg==} + peerDependencies: + react: '>=17' + react-dom: '>=17' + dependencies: + '@reactflow/core': 11.8.1(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0) + '@types/d3-selection': 3.0.5 + '@types/d3-zoom': 3.0.3 + classcat: 5.0.4 + d3-selection: 3.0.0 + d3-zoom: 3.0.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + zustand: 4.4.1(@types/react@18.2.20)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - immer + dev: false + + /@reactflow/node-resizer@2.1.3(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-wwEcftxG4BBQGpIfPdsSyDTM5XxwXBkihcoVJRY92t71qNi9CzSuX1xoFO2jvP8thwk8MiWdppVuCKs+1QVAXA==} + peerDependencies: + react: '>=17' + react-dom: '>=17' + dependencies: + '@reactflow/core': 11.8.1(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0) + classcat: 5.0.4 + d3-drag: 3.0.0 + d3-selection: 3.0.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + zustand: 4.4.1(@types/react@18.2.20)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - immer + dev: false + + /@reactflow/node-toolbar@1.2.5(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-VrnlzumrnTYGhX5CDylSuPgONexTbI5rnnI+NJWeW+9LXm1mkn3A9DUbIn3jWKcBYdzKW8GPyuPFzaCw0EyVZw==} + peerDependencies: + react: '>=17' + react-dom: '>=17' + dependencies: + '@reactflow/core': 11.8.1(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0) + classcat: 5.0.4 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + zustand: 4.4.1(@types/react@18.2.20)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - immer + dev: false + /@rollup/plugin-alias@5.0.0(rollup@3.26.3): resolution: {integrity: sha512-l9hY5chSCjuFRPsnRm16twWBiSApl2uYFLsepQYwtBuAxNMQ/1dJqADld40P0Jkqm65GRTLy/AC6hnpVebtLsA==} engines: {node: '>=14.0.0'} @@ -3221,7 +3356,20 @@ packages: slash: 4.0.0 dev: true - /@rollup/plugin-commonjs@25.0.2(rollup@3.26.3): + /@rollup/plugin-alias@5.0.0(rollup@3.28.0): + resolution: {integrity: sha512-l9hY5chSCjuFRPsnRm16twWBiSApl2uYFLsepQYwtBuAxNMQ/1dJqADld40P0Jkqm65GRTLy/AC6hnpVebtLsA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + rollup: 3.28.0 + slash: 4.0.0 + dev: true + + /@rollup/plugin-commonjs@25.0.2(rollup@3.28.0): resolution: {integrity: sha512-NGTwaJxIO0klMs+WSFFtBP7b9TdTJ3K76HZkewT8/+yHzMiUGVQgaPtLQxNVYIgT5F7lxkEyVID+yS3K7bhCow==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3230,13 +3378,13 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2(rollup@3.26.3) + '@rollup/pluginutils': 5.0.2(rollup@3.28.0) commondir: 1.0.1 estree-walker: 2.0.2 glob: 8.1.0 is-reference: 1.2.1 magic-string: 0.27.0 - rollup: 3.26.3 + rollup: 3.28.0 dev: true /@rollup/plugin-commonjs@25.0.3(rollup@3.26.3): @@ -3257,7 +3405,7 @@ packages: rollup: 3.26.3 dev: true - /@rollup/plugin-inject@5.0.3(rollup@3.26.3): + /@rollup/plugin-inject@5.0.3(rollup@3.28.0): resolution: {integrity: sha512-411QlbL+z2yXpRWFXSmw/teQRMkXcAAC8aYTemc15gwJRpvEVDQwoe+N/HTFD8RFG8+88Bme9DK2V9CVm7hJdA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3266,10 +3414,10 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2(rollup@3.26.3) + '@rollup/pluginutils': 5.0.2(rollup@3.28.0) estree-walker: 2.0.2 magic-string: 0.27.0 - rollup: 3.26.3 + rollup: 3.28.0 dev: true /@rollup/plugin-json@6.0.0(rollup@3.26.3): @@ -3285,6 +3433,19 @@ packages: rollup: 3.26.3 dev: true + /@rollup/plugin-json@6.0.0(rollup@3.28.0): + resolution: {integrity: sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.0.2(rollup@3.28.0) + rollup: 3.28.0 + dev: true + /@rollup/plugin-node-resolve@15.1.0(rollup@3.26.3): resolution: {integrity: sha512-xeZHCgsiZ9pzYVgAo9580eCGqwh/XCEUM9q6iQfGNocjgkufHAqC3exA+45URvhiYV8sBF9RlBai650eNs7AsA==} engines: {node: '>=14.0.0'} @@ -3303,6 +3464,37 @@ packages: rollup: 3.26.3 dev: true + /@rollup/plugin-node-resolve@15.1.0(rollup@3.28.0): + resolution: {integrity: sha512-xeZHCgsiZ9pzYVgAo9580eCGqwh/XCEUM9q6iQfGNocjgkufHAqC3exA+45URvhiYV8sBF9RlBai650eNs7AsA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.0.2(rollup@3.28.0) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-builtin-module: 3.2.1 + is-module: 1.0.0 + resolve: 1.22.3 + rollup: 3.28.0 + dev: true + + /@rollup/plugin-replace@5.0.2: + resolution: {integrity: sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.0.2(rollup@3.26.3) + magic-string: 0.27.0 + dev: true + /@rollup/plugin-replace@5.0.2(rollup@3.26.3): resolution: {integrity: sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==} engines: {node: '>=14.0.0'} @@ -3317,7 +3509,21 @@ packages: rollup: 3.26.3 dev: true - /@rollup/plugin-terser@0.4.3(rollup@3.26.3): + /@rollup/plugin-replace@5.0.2(rollup@3.28.0): + resolution: {integrity: sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.0.2(rollup@3.28.0) + magic-string: 0.27.0 + rollup: 3.28.0 + dev: true + + /@rollup/plugin-terser@0.4.3(rollup@3.28.0): resolution: {integrity: sha512-EF0oejTMtkyhrkwCdg0HJ0IpkcaVg1MMSf2olHb2Jp+1mnLM04OhjpJWGma4HobiDTF0WCyViWuvadyE9ch2XA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3326,13 +3532,13 @@ packages: rollup: optional: true dependencies: - rollup: 3.26.3 + rollup: 3.28.0 serialize-javascript: 6.0.1 smob: 1.4.0 terser: 5.18.0 dev: true - /@rollup/plugin-wasm@6.1.3(rollup@3.26.3): + /@rollup/plugin-wasm@6.1.3(rollup@3.28.0): resolution: {integrity: sha512-7ItTTeyauE6lwdDtQWceEHZ9+txbi4RRy0mYPFn9BW7rD7YdgBDu7HTHsLtHrRzJc313RM/1m6GKgV3np/aEaw==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3341,7 +3547,7 @@ packages: rollup: optional: true dependencies: - rollup: 3.26.3 + rollup: 3.28.0 dev: true /@rollup/pluginutils@4.2.1: @@ -3366,6 +3572,21 @@ packages: picomatch: 2.3.1 rollup: 3.26.3 + /@rollup/pluginutils@5.0.2(rollup@3.28.0): + resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.0 + estree-walker: 2.0.2 + picomatch: 2.3.1 + rollup: 3.28.0 + dev: true + /@rushstack/eslint-patch@1.2.0: resolution: {integrity: sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==} dev: true @@ -3417,28 +3638,6 @@ packages: dependencies: tslib: 2.5.0 - /@tanstack/query-core@4.32.6: - resolution: {integrity: sha512-YVB+mVWENQwPyv+40qO7flMgKZ0uI41Ph7qXC2Zf1ft5AIGfnXnMZyifB2ghhZ27u+5wm5mlzO4Y6lwwadzxCA==} - dev: false - - /@tanstack/react-query@4.32.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-AITu/IKJJJXsHHeXNBy5bclu12t08usMCY0vFC2dh9SP/w6JAk5U9GwfjOIPj3p+ATADZvxQPe8UiCtMLNeQbg==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-native: '*' - peerDependenciesMeta: - react-dom: - optional: true - react-native: - optional: true - dependencies: - '@tanstack/query-core': 4.32.6 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - use-sync-external-store: 1.2.0(react@18.2.0) - dev: false - /@tootallnate/once@2.0.0: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} @@ -3511,50 +3710,175 @@ packages: resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==} dev: true + /@types/d3-array@3.0.5: + resolution: {integrity: sha512-Qk7fpJ6qFp+26VeQ47WY0mkwXaiq8+76RJcncDEfMc2ocRzXLO67bLFRNI4OX1aGBoPzsM5Y2T+/m1pldOgD+A==} + dev: false + + /@types/d3-axis@3.0.2: + resolution: {integrity: sha512-uGC7DBh0TZrU/LY43Fd8Qr+2ja1FKmH07q2FoZFHo1eYl8aj87GhfVoY1saJVJiq24rp1+wpI6BvQJMKgQm8oA==} + dependencies: + '@types/d3-selection': 3.0.5 + dev: false + + /@types/d3-brush@3.0.2: + resolution: {integrity: sha512-2TEm8KzUG3N7z0TrSKPmbxByBx54M+S9lHoP2J55QuLU0VSQ9mE96EJSAOVNEqd1bbynMjeTS9VHmz8/bSw8rA==} + dependencies: + '@types/d3-selection': 3.0.5 + dev: false + + /@types/d3-chord@3.0.2: + resolution: {integrity: sha512-abT/iLHD3sGZwqMTX1TYCMEulr+wBd0SzyOQnjYNLp7sngdOHYtNkMRI5v3w5thoN+BWtlHVDx2Osvq6fxhZWw==} + dev: false + /@types/d3-color@3.1.0: resolution: {integrity: sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==} - dev: true + + /@types/d3-contour@3.0.2: + resolution: {integrity: sha512-k6/bGDoAGJZnZWaKzeB+9glgXCYGvh6YlluxzBREiVo8f/X2vpTEdgPy9DN7Z2i42PZOZ4JDhVdlTSTSkLDPlQ==} + dependencies: + '@types/d3-array': 3.0.5 + '@types/geojson': 7946.0.10 + dev: false + + /@types/d3-delaunay@6.0.1: + resolution: {integrity: sha512-tLxQ2sfT0p6sxdG75c6f/ekqxjyYR0+LwPrsO1mbC9YDBzPJhs2HbJJRrn8Ez1DBoHRo2yx7YEATI+8V1nGMnQ==} + dev: false + + /@types/d3-dispatch@3.0.2: + resolution: {integrity: sha512-rxN6sHUXEZYCKV05MEh4z4WpPSqIw+aP7n9ZN6WYAAvZoEAghEK1WeVZMZcHRBwyaKflU43PCUAJNjFxCzPDjg==} + dev: false /@types/d3-drag@3.0.2: resolution: {integrity: sha512-qmODKEDvyKWVHcWWCOVcuVcOwikLVsyc4q4EBJMREsoQnR2Qoc2cZQUyFUPgO9q4S3qdSqJKBsuefv+h0Qy+tw==} dependencies: '@types/d3-selection': 3.0.5 - dev: true + + /@types/d3-dsv@3.0.1: + resolution: {integrity: sha512-76pBHCMTvPLt44wFOieouXcGXWOF0AJCceUvaFkxSZEu4VDUdv93JfpMa6VGNFs01FHfuP4a5Ou68eRG1KBfTw==} + dev: false + + /@types/d3-ease@3.0.0: + resolution: {integrity: sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==} + dev: false + + /@types/d3-fetch@3.0.2: + resolution: {integrity: sha512-gllwYWozWfbep16N9fByNBDTkJW/SyhH6SGRlXloR7WdtAaBui4plTP+gbUgiEot7vGw/ZZop1yDZlgXXSuzjA==} + dependencies: + '@types/d3-dsv': 3.0.1 + dev: false /@types/d3-force@3.0.4: resolution: {integrity: sha512-q7xbVLrWcXvSBBEoadowIUJ7sRpS1yvgMWnzHJggFy5cUZBq2HZL5k/pBSm0GdYWS1vs5/EDwMjSKF55PDY4Aw==} - dev: true + + /@types/d3-format@3.0.1: + resolution: {integrity: sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==} + dev: false + + /@types/d3-geo@3.0.3: + resolution: {integrity: sha512-bK9uZJS3vuDCNeeXQ4z3u0E7OeJZXjUgzFdSOtNtMCJCLvDtWDwfpRVWlyt3y8EvRzI0ccOu9xlMVirawolSCw==} + dependencies: + '@types/geojson': 7946.0.10 + dev: false + + /@types/d3-hierarchy@3.1.2: + resolution: {integrity: sha512-9hjRTVoZjRFR6xo8igAJyNXQyPX6Aq++Nhb5ebrUF414dv4jr2MitM2fWiOY475wa3Za7TOS2Gh9fmqEhLTt0A==} + dev: false /@types/d3-interpolate@3.0.1: resolution: {integrity: sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==} dependencies: '@types/d3-color': 3.1.0 - dev: true + + /@types/d3-path@3.0.0: + resolution: {integrity: sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==} + dev: false + + /@types/d3-polygon@3.0.0: + resolution: {integrity: sha512-D49z4DyzTKXM0sGKVqiTDTYr+DHg/uxsiWDAkNrwXYuiZVd9o9wXZIo+YsHkifOiyBkmSWlEngHCQme54/hnHw==} + dev: false + + /@types/d3-quadtree@3.0.2: + resolution: {integrity: sha512-QNcK8Jguvc8lU+4OfeNx+qnVy7c0VrDJ+CCVFS9srBo2GL9Y18CnIxBdTF3v38flrGy5s1YggcoAiu6s4fLQIw==} + dev: false + + /@types/d3-random@3.0.1: + resolution: {integrity: sha512-IIE6YTekGczpLYo/HehAy3JGF1ty7+usI97LqraNa8IiDur+L44d0VOjAvFQWJVdZOJHukUJw+ZdZBlgeUsHOQ==} + dev: false /@types/d3-scale-chromatic@3.0.0: resolution: {integrity: sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw==} - dev: true /@types/d3-scale@4.0.3: resolution: {integrity: sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ==} dependencies: '@types/d3-time': 3.0.0 - dev: true /@types/d3-selection@3.0.5: resolution: {integrity: sha512-xCB0z3Hi8eFIqyja3vW8iV01+OHGYR2di/+e+AiOcXIOrY82lcvWW8Ke1DYE/EUVMsBl4Db9RppSBS3X1U6J0w==} - dev: true + + /@types/d3-shape@3.1.1: + resolution: {integrity: sha512-6Uh86YFF7LGg4PQkuO2oG6EMBRLuW9cbavUW46zkIO5kuS2PfTqo2o9SkgtQzguBHbLgNnU90UNsITpsX1My+A==} + dependencies: + '@types/d3-path': 3.0.0 + dev: false + + /@types/d3-time-format@4.0.0: + resolution: {integrity: sha512-yjfBUe6DJBsDin2BMIulhSHmr5qNR5Pxs17+oW4DoVPyVIXZ+m6bs7j1UVKP08Emv6jRmYrYqxYzO63mQxy1rw==} + dev: false /@types/d3-time@3.0.0: resolution: {integrity: sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==} - dev: true + + /@types/d3-timer@3.0.0: + resolution: {integrity: sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==} + dev: false + + /@types/d3-transition@3.0.3: + resolution: {integrity: sha512-/S90Od8Id1wgQNvIA8iFv9jRhCiZcGhPd2qX0bKF/PS+y0W5CrXKgIiELd2CvG1mlQrWK/qlYh3VxicqG1ZvgA==} + dependencies: + '@types/d3-selection': 3.0.5 + dev: false /@types/d3-zoom@3.0.3: resolution: {integrity: sha512-OWk1yYIIWcZ07+igN6BeoG6rqhnJ/pYe+R1qWFM2DtW49zsoSjgb9G5xB0ZXA8hh2jAzey1XuRmMSoXdKw8MDA==} dependencies: '@types/d3-interpolate': 3.0.1 '@types/d3-selection': 3.0.5 - dev: true + + /@types/d3@7.4.0: + resolution: {integrity: sha512-jIfNVK0ZlxcuRDKtRS/SypEyOQ6UHaFQBKv032X45VvxSJ6Yi5G9behy9h6tNTHTDGh5Vq+KbmBjUWLgY4meCA==} + dependencies: + '@types/d3-array': 3.0.5 + '@types/d3-axis': 3.0.2 + '@types/d3-brush': 3.0.2 + '@types/d3-chord': 3.0.2 + '@types/d3-color': 3.1.0 + '@types/d3-contour': 3.0.2 + '@types/d3-delaunay': 6.0.1 + '@types/d3-dispatch': 3.0.2 + '@types/d3-drag': 3.0.2 + '@types/d3-dsv': 3.0.1 + '@types/d3-ease': 3.0.0 + '@types/d3-fetch': 3.0.2 + '@types/d3-force': 3.0.4 + '@types/d3-format': 3.0.1 + '@types/d3-geo': 3.0.3 + '@types/d3-hierarchy': 3.1.2 + '@types/d3-interpolate': 3.0.1 + '@types/d3-path': 3.0.0 + '@types/d3-polygon': 3.0.0 + '@types/d3-quadtree': 3.0.2 + '@types/d3-random': 3.0.1 + '@types/d3-scale': 4.0.3 + '@types/d3-scale-chromatic': 3.0.0 + '@types/d3-selection': 3.0.5 + '@types/d3-shape': 3.1.1 + '@types/d3-time': 3.0.0 + '@types/d3-time-format': 4.0.0 + '@types/d3-timer': 3.0.0 + '@types/d3-transition': 3.0.3 + '@types/d3-zoom': 3.0.3 + dev: false /@types/eslint-scope@3.7.4: resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==} @@ -3576,6 +3900,10 @@ packages: /@types/estree@1.0.0: resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==} + /@types/geojson@7946.0.10: + resolution: {integrity: sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==} + dev: false + /@types/glob@7.2.0: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} dependencies: @@ -3653,7 +3981,6 @@ packages: /@types/prop-types@15.7.5: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} - dev: true /@types/react-dom@18.2.7: resolution: {integrity: sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==} @@ -3667,7 +3994,6 @@ packages: '@types/prop-types': 15.7.5 '@types/scheduler': 0.16.3 csstype: 3.1.2 - dev: true /@types/resize-observer-browser@0.1.7: resolution: {integrity: sha512-G9eN0Sn0ii9PWQ3Vl72jDPgeJwRWhv2Qk/nQkJuWmRmOB4HX3/BhD5SE1dZs/hzPZL/WKnvF0RHdTSG54QJFyg==} @@ -3679,7 +4005,6 @@ packages: /@types/scheduler@0.16.3: resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} - dev: true /@types/semver@7.5.0: resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} @@ -5973,6 +6298,16 @@ packages: consola: 3.2.3 dev: true + /class-variance-authority@0.7.0: + resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==} + dependencies: + clsx: 2.0.0 + dev: false + + /classcat@5.0.4: + resolution: {integrity: sha512-sbpkOw6z413p+HDGcBENe498WM9woqWHiJxCq7nvmxe9WmrUmqfAcxpIwAiMtM5Q3AhYkzXcNQHqsWq0mND51g==} + dev: false + /clean-css@4.2.4: resolution: {integrity: sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==} engines: {node: '>= 4.0'} @@ -6073,6 +6408,11 @@ packages: engines: {node: '>=0.8'} dev: true + /clsx@2.0.0: + resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==} + engines: {node: '>=6'} + dev: false + /cluster-key-slot@1.1.2: resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} engines: {node: '>=0.10.0'} @@ -6745,11 +7085,27 @@ packages: internmap: 2.0.3 dev: false + /d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + dependencies: + internmap: 2.0.3 + dev: false + /d3-color@3.1.0: resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} engines: {node: '>=12'} dev: false + /d3-dag@1.0.0: + resolution: {integrity: sha512-OJaaYqd9tSu0TB8QWfAVO74btk7xWH4g8pJissMnSC12JnUU87HDBSGJ6ebriPvLS9Rt8PFGgkqXdg/fYdPovQ==} + dependencies: + d3-array: 3.2.4 + javascript-lp-solver: 0.4.24 + quadprog: 1.6.1 + stringify-object: 5.0.0 + dev: false + /d3-dispatch@3.0.1: resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} engines: {node: '>=12'} @@ -8367,7 +8723,7 @@ packages: optionator: 0.8.3 progress: 2.0.3 regexpp: 2.0.1 - semver: 6.3.0 + semver: 6.3.1 strip-ansi: 5.2.0 strip-json-comments: 3.1.1 table: 5.4.6 @@ -8996,6 +9352,11 @@ packages: has-proto: 1.0.1 has-symbols: 1.0.3 + /get-own-enumerable-keys@1.0.0: + resolution: {integrity: sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA==} + engines: {node: '>=14.16'} + dev: false + /get-port-please@3.0.1: resolution: {integrity: sha512-R5pcVO8Z1+pVDu8Ml3xaJCEkBiiy1VQN9za0YqH8GIi1nIqD4IzQhzY6dDzMRtdS1lyiGlucRzm8IN8wtLIXng==} dev: true @@ -9940,6 +10301,11 @@ packages: engines: {node: '>=8'} dev: true + /is-obj@3.0.0: + resolution: {integrity: sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==} + engines: {node: '>=12'} + dev: false + /is-path-cwd@2.2.0: resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} engines: {node: '>=6'} @@ -9985,6 +10351,11 @@ packages: call-bind: 1.0.2 has-tostringtag: 1.0.0 + /is-regexp@3.1.0: + resolution: {integrity: sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==} + engines: {node: '>=12'} + dev: false + /is-set@2.0.2: resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} @@ -10155,6 +10526,10 @@ packages: '@pkgjs/parseargs': 0.11.0 dev: true + /javascript-lp-solver@0.4.24: + resolution: {integrity: sha512-5edoDKnMrt/u3M6GnZKDDIPxOyFOg+WrwDv8mjNiMC2DePhy2H9/FFQgf4ggywaXT1utvkxusJcjQUER72cZmA==} + dev: false + /jest-worker@27.5.1: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} @@ -10702,6 +11077,14 @@ packages: engines: {node: 14 || >=16.14} dev: true + /lucide-react@0.268.0(react@18.2.0): + resolution: {integrity: sha512-XP/xY3ASJAViqNqVnDRcEfdxfRB7uNST8sqTLwZhL983ikmHMQ7qQak7ZxrnXOVhB3QDBawdr3ANq0P+iWHP/g==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + dev: false + /magic-string-ast@0.1.2: resolution: {integrity: sha512-P53AZrzq7hclCU6HWj88xNZHmP15DKjMmK/vBytO1qnpYP3ul4IEZlyCE0aU3JRnmgWmZPmoTKj4Bls7v0pMyA==} engines: {node: '>=14.19.0'} @@ -11155,8 +11538,8 @@ packages: engines: {node: '>= 0.4.0'} dev: true - /next@13.4.13(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-A3YVbVDNeXLhWsZ8Nf6IkxmNlmTNz0yVg186NJ97tGZqPDdPzTrHotJ+A1cuJm2XfuWPrKOUZILl5iBQkIf8Jw==} + /next@13.4.16(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-1xaA/5DrfpPu0eV31Iro7JfPeqO8uxQWb1zYNTe+KDKdzqkAGapLcDYHMLNKXKB7lHjZ7LfKUOf9dyuzcibrhA==} engines: {node: '>=16.8.0'} hasBin: true peerDependencies: @@ -11170,7 +11553,7 @@ packages: sass: optional: true dependencies: - '@next/env': 13.4.13 + '@next/env': 13.4.16 '@swc/helpers': 0.5.1 busboy: 1.6.0 caniuse-lite: 1.0.30001477 @@ -11181,15 +11564,15 @@ packages: watchpack: 2.4.0 zod: 3.21.4 optionalDependencies: - '@next/swc-darwin-arm64': 13.4.13 - '@next/swc-darwin-x64': 13.4.13 - '@next/swc-linux-arm64-gnu': 13.4.13 - '@next/swc-linux-arm64-musl': 13.4.13 - '@next/swc-linux-x64-gnu': 13.4.13 - '@next/swc-linux-x64-musl': 13.4.13 - '@next/swc-win32-arm64-msvc': 13.4.13 - '@next/swc-win32-ia32-msvc': 13.4.13 - '@next/swc-win32-x64-msvc': 13.4.13 + '@next/swc-darwin-arm64': 13.4.16 + '@next/swc-darwin-x64': 13.4.16 + '@next/swc-linux-arm64-gnu': 13.4.16 + '@next/swc-linux-arm64-musl': 13.4.16 + '@next/swc-linux-x64-gnu': 13.4.16 + '@next/swc-linux-x64-musl': 13.4.16 + '@next/swc-win32-arm64-msvc': 13.4.16 + '@next/swc-win32-ia32-msvc': 13.4.16 + '@next/swc-win32-x64-msvc': 13.4.16 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -11205,15 +11588,15 @@ packages: dependencies: '@cloudflare/kv-asset-handler': 0.3.0 '@netlify/functions': 1.6.0 - '@rollup/plugin-alias': 5.0.0(rollup@3.26.3) - '@rollup/plugin-commonjs': 25.0.2(rollup@3.26.3) - '@rollup/plugin-inject': 5.0.3(rollup@3.26.3) - '@rollup/plugin-json': 6.0.0(rollup@3.26.3) - '@rollup/plugin-node-resolve': 15.1.0(rollup@3.26.3) - '@rollup/plugin-replace': 5.0.2(rollup@3.26.3) - '@rollup/plugin-terser': 0.4.3(rollup@3.26.3) - '@rollup/plugin-wasm': 6.1.3(rollup@3.26.3) - '@rollup/pluginutils': 5.0.2(rollup@3.26.3) + '@rollup/plugin-alias': 5.0.0(rollup@3.28.0) + '@rollup/plugin-commonjs': 25.0.2(rollup@3.28.0) + '@rollup/plugin-inject': 5.0.3(rollup@3.28.0) + '@rollup/plugin-json': 6.0.0(rollup@3.28.0) + '@rollup/plugin-node-resolve': 15.1.0(rollup@3.28.0) + '@rollup/plugin-replace': 5.0.2(rollup@3.28.0) + '@rollup/plugin-terser': 0.4.3(rollup@3.28.0) + '@rollup/plugin-wasm': 6.1.3(rollup@3.28.0) + '@rollup/pluginutils': 5.0.2(rollup@3.28.0) '@types/http-proxy': 1.17.11 '@vercel/nft': 0.22.6 archiver: 5.3.1 @@ -11254,8 +11637,8 @@ packages: pkg-types: 1.0.3 pretty-bytes: 6.1.1 radix3: 1.0.1 - rollup: 3.26.3 - rollup-plugin-visualizer: 5.9.2(rollup@3.26.3) + rollup: 3.28.0 + rollup-plugin-visualizer: 5.9.2(rollup@3.28.0) scule: 1.0.0 semver: 7.5.4 serve-placeholder: 2.0.1 @@ -11265,7 +11648,7 @@ packages: ufo: 1.2.0 uncrypto: 0.1.3 unenv: 1.5.1 - unimport: 3.0.14(rollup@3.26.3) + unimport: 3.0.14(rollup@3.28.0) unstorage: 1.7.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -12786,6 +13169,11 @@ packages: resolution: {integrity: sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==} dev: true + /quadprog@1.6.1: + resolution: {integrity: sha512-fN5Jkcjlln/b3pJkseDKREf89JkKIyu6cKIVXisgL6ocKPQ0yTp9n6NZUAq3otEPPw78WZMG9K0o9WsfKyMWJw==} + engines: {node: '>=8.x'} + dev: false + /querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} dev: true @@ -12854,6 +13242,25 @@ packages: dependencies: loose-envify: 1.4.0 + /reactflow@11.8.1(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-OuhsSCiefrCAUZqjuYJNVhhUpLrNQNzBz1rORCMXYO2j7y0FQ02oZLoMT/5mhCmNGMqR7BZwwvOMCSZM7wAn5A==} + peerDependencies: + react: '>=17' + react-dom: '>=17' + dependencies: + '@reactflow/background': 11.2.6(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/controls': 11.1.17(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.8.1(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/minimap': 11.6.1(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/node-resizer': 2.1.3(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/node-toolbar': 1.2.5(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - immer + dev: false + /read-cache@1.0.0: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} dependencies: @@ -13644,7 +14051,7 @@ packages: '@babel/code-frame': 7.21.4 dev: true - /rollup-plugin-visualizer@5.9.2(rollup@3.26.3): + /rollup-plugin-visualizer@5.9.2(rollup@3.28.0): resolution: {integrity: sha512-waHktD5mlWrYFrhOLbti4YgQCn1uR24nYsNuXxg7LkPH8KdTXVWR9DNY1WU0QqokyMixVXJS4J04HNrVTMP01A==} engines: {node: '>=14'} hasBin: true @@ -13656,7 +14063,7 @@ packages: dependencies: open: 8.4.2 picomatch: 2.3.1 - rollup: 3.26.3 + rollup: 3.28.0 source-map: 0.7.4 yargs: 17.7.2 dev: true @@ -14260,6 +14667,15 @@ packages: is-hexadecimal: 1.0.4 dev: false + /stringify-object@5.0.0: + resolution: {integrity: sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg==} + engines: {node: '>=14.16'} + dependencies: + get-own-enumerable-keys: 1.0.0 + is-obj: 3.0.0 + is-regexp: 3.1.0 + dev: false + /strip-ansi@5.2.0: resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} engines: {node: '>=6'} @@ -14472,6 +14888,18 @@ packages: string-width: 3.1.0 dev: false + /tailwind-merge@1.14.0: + resolution: {integrity: sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ==} + dev: false + + /tailwindcss-animate@1.0.6(tailwindcss@3.3.3): + resolution: {integrity: sha512-4WigSGMvbl3gCCact62ZvOngA+PRqhAn7si3TQ3/ZuPuQZcIEtVap+ENSXbzWhpojKB8CpvnIsrwBu8/RnHtuw==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + dependencies: + tailwindcss: 3.3.3(ts-node@10.9.1) + dev: false + /tailwindcss@3.3.3(ts-node@10.9.1): resolution: {integrity: sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==} engines: {node: '>=14.0.0'} @@ -15223,7 +15651,7 @@ packages: vfile: 4.2.1 dev: false - /unimport@3.0.14(rollup@3.26.3): + /unimport@3.0.14: resolution: {integrity: sha512-67Rh/sGpEuVqdHWkXaZ6NOq+I7sKt86o+DUtKeGB6dh4Hk1A8AQrzyVGg2+LaVEYotStH7HwvV9YSaRjyT7Uqg==} dependencies: '@rollup/pluginutils': 5.0.2(rollup@3.26.3) @@ -15241,6 +15669,24 @@ packages: - rollup dev: true + /unimport@3.0.14(rollup@3.28.0): + resolution: {integrity: sha512-67Rh/sGpEuVqdHWkXaZ6NOq+I7sKt86o+DUtKeGB6dh4Hk1A8AQrzyVGg2+LaVEYotStH7HwvV9YSaRjyT7Uqg==} + dependencies: + '@rollup/pluginutils': 5.0.2(rollup@3.28.0) + escape-string-regexp: 5.0.0 + fast-glob: 3.3.0 + local-pkg: 0.4.3 + magic-string: 0.30.1 + mlly: 1.4.0 + pathe: 1.1.1 + pkg-types: 1.0.3 + scule: 1.0.0 + strip-literal: 1.0.1 + unplugin: 1.3.2 + transitivePeerDependencies: + - rollup + dev: true + /unimport@3.0.6: resolution: {integrity: sha512-GYxGJ1Bri1oqx8VFDjdgooGzeK7jBk3bvhXmamTIpu3nONOcUMGwZbX7X0L5RA7OWMXpR4vzpSQP7pXUzJg1/Q==} dependencies: @@ -15826,7 +16272,7 @@ packages: '@types/node': 18.17.5 esbuild: 0.17.19 postcss: 8.4.27 - rollup: 3.26.3 + rollup: 3.28.0 optionalDependencies: fsevents: 2.3.2 dev: true @@ -16573,3 +17019,23 @@ packages: /zod@3.21.4: resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==} + + /zustand@4.4.1(@types/react@18.2.20)(react@18.2.0): + resolution: {integrity: sha512-QCPfstAS4EBiTQzlaGP1gmorkh/UL1Leaj2tdj+zZCZ/9bm0WS7sI2wnfD5lpOszFqWJ1DcPnGoY8RDL61uokw==} + engines: {node: '>=12.7.0'} + peerDependencies: + '@types/react': '>=16.8' + immer: '>=9.0' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + dependencies: + '@types/react': 18.2.20 + react: 18.2.0 + use-sync-external-store: 1.2.0(react@18.2.0) + dev: false