From 909819516bb1d8a74aefeed3c898b9818bb11fdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Mu=CC=88ller?= Date: Fri, 11 Aug 2023 16:11:29 +0200 Subject: [PATCH] feat: improve ui --- packages/tsconfig/cli.json | 1 + packages/tsconfig/next.json | 1 + packages/turbo-graph-ui/app/converter.ts | 100 ++++ .../{pages/api/graph.ts => app/data.ts} | 27 +- packages/turbo-graph-ui/app/flow.tsx | 73 +++ .../{styles => app}/globals.css | 0 packages/turbo-graph-ui/app/graph.tsx | 112 +++++ packages/turbo-graph-ui/app/input.tsx | 11 + packages/turbo-graph-ui/app/layout.tsx | 15 + packages/turbo-graph-ui/app/page.tsx | 50 ++ packages/turbo-graph-ui/package.json | 8 +- packages/turbo-graph-ui/pages/_app.tsx | 14 - packages/turbo-graph-ui/pages/index.tsx | 170 ------- packages/turbo-graph-ui/tailwind.config.js | 2 +- packages/turbo-graph-ui/tsconfig.json | 11 +- pnpm-lock.yaml | 426 ++++++++++++++++-- 16 files changed, 769 insertions(+), 252 deletions(-) create mode 100644 packages/turbo-graph-ui/app/converter.ts rename packages/turbo-graph-ui/{pages/api/graph.ts => app/data.ts} (74%) create mode 100644 packages/turbo-graph-ui/app/flow.tsx rename packages/turbo-graph-ui/{styles => app}/globals.css (100%) create mode 100644 packages/turbo-graph-ui/app/graph.tsx create mode 100644 packages/turbo-graph-ui/app/input.tsx create mode 100644 packages/turbo-graph-ui/app/layout.tsx create mode 100644 packages/turbo-graph-ui/app/page.tsx delete mode 100644 packages/turbo-graph-ui/pages/_app.tsx delete mode 100644 packages/turbo-graph-ui/pages/index.tsx 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..f73e9a2c3 100644 --- a/packages/tsconfig/next.json +++ b/packages/tsconfig/next.json @@ -1,5 +1,6 @@ { "extends": "./web.json", + "plugins": [{ "name": "next" }], "compilerOptions": { "noEmit": true, "incremental": true diff --git a/packages/turbo-graph-ui/app/converter.ts b/packages/turbo-graph-ui/app/converter.ts new file mode 100644 index 000000000..d8c6e2f28 --- /dev/null +++ b/packages/turbo-graph-ui/app/converter.ts @@ -0,0 +1,100 @@ +import { Stream } from '@yeger/streams' +import { graphStratify, sugiyama } from 'd3-dag' +import { type Edge, type Node } from 'reactflow' + +import type { TurboEdge, TurboGraph, TurboNode } from './data' + +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) { + return Math.max( + ...Stream.from(nodes).flatMap(({ task, workspace }) => [ + task.length, + workspace.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, + ]) + 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', + draggable: false, + selectable: false, + connectable: false, + deletable: false, + focusable: false, + }) as const, + ) + .toArray() + const edges = turboEdges.map>((edge) => ({ + id: `edge-${edge.source}-${edge.target}`, + source: edge.source, + target: edge.target, + animated: true, + deletable: false, + focusable: false, + updatable: false, + })) + return { nodes, edges, sizeConfig } +} diff --git a/packages/turbo-graph-ui/pages/api/graph.ts b/packages/turbo-graph-ui/app/data.ts similarity index 74% rename from packages/turbo-graph-ui/pages/api/graph.ts rename to packages/turbo-graph-ui/app/data.ts index 4d70806a7..96aba0192 100644 --- a/packages/turbo-graph-ui/pages/api/graph.ts +++ b/packages/turbo-graph-ui/app/data.ts @@ -3,7 +3,6 @@ import fs from 'node:fs/promises' import path from 'node:path' import { execa } from 'execa' -import type { NextApiRequest, NextApiResponse } from 'next' interface Data { dir: string @@ -14,22 +13,17 @@ interface Config { pipeline: Record } -export default async function handler( - _: NextApiRequest, - res: NextApiResponse, -) { - const { dir, config } = await findTurboConfig() - const tasks = getTask(config) +export async function getGraph(tasks: string[]) { + const { dir } = await findTurboConfig() const stdout = await executeCommand(tasks, dir) - const graph = await processResult(stdout) - res.status(200).json(graph) + return processResult(stdout) } async function executeCommand(tasks: string[], dir: 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'], + ['run', ...tasks, '--concurrency=100%', '--graph', '--filter=formi...'], { cwd: dir, }, @@ -37,17 +31,6 @@ async function executeCommand(tasks: string[], dir: string): Promise { return stdout } -function getTask(config: Config): string[] { - const pipeline = Object.keys(config.pipeline).map((entry) => { - if (!entry.includes('#')) { - return entry - } - return entry.substring(entry.indexOf('#') + 1) - }) - - return [...new Set(pipeline)] -} - async function findTurboConfig(currentPath = '.'): Promise { const files = await fs.readdir(currentPath) const turboConfig = files.find((file) => file === 'turbo.json') @@ -82,7 +65,7 @@ async function processResult(input: string): Promise { .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/app/flow.tsx b/packages/turbo-graph-ui/app/flow.tsx new file mode 100644 index 000000000..8ea48a108 --- /dev/null +++ b/packages/turbo-graph-ui/app/flow.tsx @@ -0,0 +1,73 @@ +'use client' + +import { scaleOrdinal } from 'd3-scale' +import { schemeSet3 } from 'd3-scale-chromatic' +import { useMemo } from 'react' +import { Background, Controls, Handle, Position, ReactFlow } from 'reactflow' + +import 'reactflow/dist/style.css' +import type { FlowGraph, FlowNode } from './converter' + +export interface Props { + graph: FlowGraph + uniqueTasks: Set +} + +interface TaskProps { + data: FlowNode +} + +// TODO: Omit source and target handles if not needed +export function Flow({ graph, uniqueTasks }: Props) { + const { sizeConfig } = graph + const nodeTypes = useMemo(() => { + const getColor = scaleOrdinal(schemeSet3).domain(uniqueTasks) + return { + task: function Task({ data }: TaskProps) { + const { task, workspace, isTerminal, isOrigin } = data + return ( +
+ {isOrigin ? null : ( + + )} +
+
{task}
+
{workspace}
+
+ {isTerminal ? null : ( + + )} +
+ ) + }, + } + }, [sizeConfig, uniqueTasks]) + return ( +
+ + + + +
+ ) +} diff --git a/packages/turbo-graph-ui/styles/globals.css b/packages/turbo-graph-ui/app/globals.css similarity index 100% rename from packages/turbo-graph-ui/styles/globals.css rename to packages/turbo-graph-ui/app/globals.css diff --git a/packages/turbo-graph-ui/app/graph.tsx b/packages/turbo-graph-ui/app/graph.tsx new file mode 100644 index 000000000..e29fbe32f --- /dev/null +++ b/packages/turbo-graph-ui/app/graph.tsx @@ -0,0 +1,112 @@ +'use client' + +import { + GraphController, + Markers, + PositionInitializers, + defineGraph, + defineGraphConfig, + defineLink, + defineNodeWithDefaults, +} from 'd3-graph-controller' +import { scaleOrdinal } from 'd3-scale' +import { schemeSet3 } from 'd3-scale-chromatic' +import { useEffect, useMemo, useRef } from 'react' +import 'd3-graph-controller/default.css' + +import type { TurboGraph } from './data' + +export interface Props { + graph: TurboGraph +} + +export function Graph({ graph }: Props) { + const graphRef = useRef(null) + + const colors = useMemo(() => { + const tasks = [ + ...new Set(graph?.nodes.map(({ task }) => task) ?? []), + ].sort() + return scaleOrdinal(schemeSet3).domain(tasks) + }, [graph]) + + const graphController = useMemo(() => { + const container = graphRef.current + if (!container || !graph) { + return undefined + } + const nodes = graph.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 = graph.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, graph]) + + useEffect(() => { + return () => { + graphController?.shutdown() + } + }, [graphController]) + + // const tasks = graphController?.nodeTypes.sort() ?? [] + + return ( +
+ {!graphController ? ( +
+ Loading +
+ ) : null} +
+
+ ) +} diff --git a/packages/turbo-graph-ui/app/input.tsx b/packages/turbo-graph-ui/app/input.tsx new file mode 100644 index 000000000..898167de9 --- /dev/null +++ b/packages/turbo-graph-ui/app/input.tsx @@ -0,0 +1,11 @@ +'use client' + +import { useRouter } from 'next/navigation' +import type { ChangeEventHandler } from 'react' + +export function TaskInput() { + const router = useRouter() + const onChange: ChangeEventHandler = (event) => + router.push(`/?tasks=${event.target.value}`) + return +} diff --git a/packages/turbo-graph-ui/app/layout.tsx b/packages/turbo-graph-ui/app/layout.tsx new file mode 100644 index 000000000..0c8306a69 --- /dev/null +++ b/packages/turbo-graph-ui/app/layout.tsx @@ -0,0 +1,15 @@ +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/page.tsx b/packages/turbo-graph-ui/app/page.tsx new file mode 100644 index 000000000..01439d193 --- /dev/null +++ b/packages/turbo-graph-ui/app/page.tsx @@ -0,0 +1,50 @@ +import { Stream } from '@yeger/streams' +import type { Metadata } from 'next' + +import { convertGraph } from './converter' +import { getGraph } from './data' +import { Flow } from './flow' +import { TaskInput } from './input' + +export const metadata: Metadata = { + title: 'Turbo Graph', + // m + // + // + // +} + +// TODO: Add input for task names to include +// TODO: Add input for --filter arg of turbo +export default async function Home({ + params, + searchParams, +}: { + params: { slug: string } + searchParams?: { [key: string]: string | string[] | undefined } +}) { + console.log({ params, searchParams }) + const taskParam = searchParams?.tasks + const tasks = Array.isArray(taskParam) + ? taskParam + : taskParam?.split(' ') ?? ['build'] + const data = await getGraph(tasks) + const graph = convertGraph(data) + const uniqueTasks = Stream.from(graph.nodes) + .map(({ data }) => data.task) + .toSet() + + return ( +
+
+
+ +
+ +
+
+ ) +} diff --git a/packages/turbo-graph-ui/package.json b/packages/turbo-graph-ui/package.json index 2b784191b..1a1d1985e 100644 --- a/packages/turbo-graph-ui/package.json +++ b/packages/turbo-graph-ui/package.json @@ -20,20 +20,22 @@ "scripts": { "build": "next build", "check:publish": "publint run --strict", - "dev": "next dev", + "dev": "next dev --turbo", "lint": "next lint" }, "peerDependencies": { "turbo": "^1.0.0" }, "dependencies": { - "@tanstack/react-query": "4.32.6", + "@yeger/streams": "workspace:*", + "d3-dag": "1.0.0", "d3-graph-controller": "workspace:*", "d3-scale": "4.0.2", "d3-scale-chromatic": "3.0.0", "execa": "7.2.0", "react": "18.2.0", - "react-dom": "18.2.0" + "react-dom": "18.2.0", + "reactflow": "11.8.1" }, "devDependencies": { "@types/d3-scale": "4.0.3", 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/tailwind.config.js b/packages/turbo-graph-ui/tailwind.config.js index cc2cb9261..f48cd5823 100644 --- a/packages/turbo-graph-ui/tailwind.config.js +++ b/packages/turbo-graph-ui/tailwind.config.js @@ -1,7 +1,7 @@ -// eslint-disable-next-line tsdoc/syntax /** @type {import('tailwindcss').Config} */ module.exports = { content: [ + './app/**/*.{js,ts,jsx,tsx}', './pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}', ], diff --git a/packages/turbo-graph-ui/tsconfig.json b/packages/turbo-graph-ui/tsconfig.json index aec81db77..9c4a1bc89 100644 --- a/packages/turbo-graph-ui/tsconfig.json +++ b/packages/turbo-graph-ui/tsconfig.json @@ -1,5 +1,12 @@ { "extends": "@yeger/tsconfig/next", - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], - "exclude": ["node_modules"] + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 30fb9ebcc..00c9862b6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -551,7 +551,7 @@ importers: version: 5.1.6 vite: specifier: 4.4.4 - version: 4.4.4(@types/node@18.16.19) + version: 4.4.4(@types/node@18.17.4) vite-plugin-lib: specifier: workspace:* version: link:../vite-plugin-lib @@ -591,9 +591,12 @@ 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/streams': + specifier: workspace:* + version: link:../streams + d3-dag: + specifier: 1.0.0 + version: 1.0.0 d3-graph-controller: specifier: workspace:* version: link:../d3-graph-controller @@ -612,6 +615,9 @@ importers: 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) turbo: specifier: ^1.0.0 version: 1.8.8 @@ -3208,6 +3214,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'} @@ -3417,28 +3531,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 +3603,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 +3793,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 +3874,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 +3887,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 +3898,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 +6191,10 @@ packages: consola: 3.2.3 dev: true + /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'} @@ -6745,11 +6967,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 +8605,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 +9234,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 +10183,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 +10233,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 +10408,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'} @@ -12786,6 +13043,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 +13116,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: @@ -14259,6 +14540,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'} @@ -15825,7 +16115,43 @@ packages: '@types/node': 18.17.4 esbuild: 0.17.19 postcss: 8.4.27 - rollup: 3.26.3 + rollup: 3.28.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vite@4.4.4(@types/node@18.17.4): + resolution: {integrity: sha512-4mvsTxjkveWrKDJI70QmelfVqTm+ihFAb6+xf4sjEU2TmUCTlVX87tmg/QooPEMQb/lM9qGHT99ebqPziEd3wg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 18.17.4 + esbuild: 0.18.17 + postcss: 8.4.27 + rollup: 3.28.0 optionalDependencies: fsevents: 2.3.2 dev: true @@ -16572,3 +16898,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