diff --git a/docs/source/_static/visualization/Debugging.png b/docs/source/_static/visualization/Debugging.png new file mode 100644 index 000000000..a09725353 Binary files /dev/null and b/docs/source/_static/visualization/Debugging.png differ diff --git a/docs/source/_static/visualization/Expanded.png b/docs/source/_static/visualization/Expanded.png new file mode 100644 index 000000000..8787945c6 Binary files /dev/null and b/docs/source/_static/visualization/Expanded.png differ diff --git a/docs/source/_static/visualization/node_states.png b/docs/source/_static/visualization/node_states.png new file mode 100644 index 000000000..3a0787bd1 Binary files /dev/null and b/docs/source/_static/visualization/node_states.png differ diff --git a/docs/source/_static/visualization/overview.png b/docs/source/_static/visualization/overview.png new file mode 100644 index 000000000..78445e1eb Binary files /dev/null and b/docs/source/_static/visualization/overview.png differ diff --git a/docs/source/visualization.md b/docs/source/visualization.md index a98560791..a1f0cf41b 100644 --- a/docs/source/visualization.md +++ b/docs/source/visualization.md @@ -23,20 +23,20 @@ The visualizer is browser based and can be accessed at: Programmatically the server can be run from python -```python -import tierkreis-visualization +```py +from tierkreis_visualization.main import start -tierkreis_visualziation.main.start() +start() ``` Alternatively in you can use `visualize_graph` ```py from tierkreis.builder import GraphBuilder -import tierkreis-visualization +from tierkreis_visualization.main import visualize_graph graph = GraphBuilder() -tierkreis_visualziation.main.visualize_graph(graph.get_data()) +visualize_graph(graph.get_data()) ``` which can also visualize partial graphs. @@ -45,6 +45,7 @@ This is very helpful during development, but currently does not provide a hot re ## Usage The visualizer provides plenty information about the graphs in the system. +![visualizer overview](./_static/visualization/overview.png) ### General Functionality @@ -54,6 +55,8 @@ At the bottom left of the main view there are three control buttons from top to - Centering the view - Hiding the navigation bar - Recalculation the graph layout +- Reset Local storage, sometimes graph changes are not update correctly, clearing the storage and reloading resets the view +- Showing/Hiding all node ports ### Available Graphs @@ -62,22 +65,25 @@ Available graphs are listed in the sidebar by their name. ### Node Types The visualizer will show the different node types with their heading. -Tasks will be displayed by their function names and constant values have their values attached. +Tasks will be displayed by their function names and constant values, inputs and outputs have their values attached. ### Node Status The node status is indicated by the border color of the nodes: -- White/No border: Node has not been started yet +![node state example](./_static/visualization/node_states.png) + - Yellow: Node is currently running - Green: Node is finished - Red: An error has occurred in the node (or one of its nested nodes) +- White/No border: Node has not been started yet ### Ports & Values -Inputs and outputs of nodes are indicated by black circles (ports) on the nodes border. +Inputs and outputs of nodes are indicated by black circles (handles) on the nodes border. Inputs are at the top, outputs at the bottom. Hovering a port will show the port name. +By using the control button, all ports can be shown simultaneously. The values in a graph are only visible once the graph has run, indicated on the edges connecting a port. Small values will be displayed, larger values are truncated with a `{}` symbol. Hovering the symbol shows the entire value in json format. @@ -87,12 +93,17 @@ The graph symbol indicates a value is a constant subgraph supplied as a nested g The higher order nodes `eval`, `map`, and `loop` can be expanded by pressing the `+` button. This will show their nested structure. + +![node state example](./_static/visualization/Expanded.png) For `eval` nodes this will immediately be the nested graph; For `map`/`loop` nodes this will show the individual elements/iterations which each contain their own subgraph. For unevaluated graphs, this will only show a placeholder evaluation. +To hide the graph again use the `-` button at the top right. ### Logs & Errors Logs can be accessed by double-clicking a node. If an error has occurred on a node, it will have a `!` button. Pressing it will show the error information. + +![error logs](./_static/visualization/Debugging.png) diff --git a/tierkreis/tierkreis/controller/storage/filestorage.py b/tierkreis/tierkreis/controller/storage/filestorage.py index 8a46bad8c..0cdec1a36 100644 --- a/tierkreis/tierkreis/controller/storage/filestorage.py +++ b/tierkreis/tierkreis/controller/storage/filestorage.py @@ -169,9 +169,17 @@ def read_output(self, node_location: Loc, output_name: PortID) -> bytes: def read_errors(self, node_location: Loc) -> str: if not self._error_logs_path(node_location).exists(): + if self._error_path(node_location).exists(): + with open(self._error_path(node_location), "r") as fh: + return fh.read() return "" with open(self._error_logs_path(node_location), "r") as fh: - return fh.read() + errors = fh.read() + if errors == "": + if self._error_path(node_location).exists(): + with open(self._error_path(node_location), "r") as fh: + return fh.read() + return errors def write_node_errors(self, node_location: Loc, error_logs: str) -> None: with open(self._error_logs_path(node_location), "w+") as fh: @@ -208,3 +216,17 @@ def write_metadata(self, node_location: Loc) -> None: def read_metadata(self, node_location: Loc) -> dict[str, Any]: with open(self._metadata_path(node_location)) as fh: return json.load(fh) + + def read_started_time(self, node_location: Loc) -> str | None: + node_def = Path(self._nodedef_path(node_location)) + if not node_def.exists(): + return None + since_epoch = node_def.stat().st_mtime + return datetime.fromtimestamp(since_epoch).isoformat() + + def read_finished_time(self, node_location: Loc) -> str | None: + done = Path(self._done_path(node_location)) + if not done.exists(): + return None + since_epoch = done.stat().st_mtime + return datetime.fromtimestamp(since_epoch).isoformat() diff --git a/tierkreis/tierkreis/controller/storage/graphdata.py b/tierkreis/tierkreis/controller/storage/graphdata.py index a58ba6400..51bef9169 100644 --- a/tierkreis/tierkreis/controller/storage/graphdata.py +++ b/tierkreis/tierkreis/controller/storage/graphdata.py @@ -114,6 +114,12 @@ def read_metadata(self, node_location: Loc) -> dict[str, Any]: def write_metadata(self, node_location: Loc) -> None: raise NotImplementedError("GraphDataStorage is read only storage.") + def read_started_time(self, node_location: Loc) -> str | None: + return None + + def read_finished_time(self, node_location: Loc) -> str | None: + return None + def _build_node_outputs(node: NodeDef) -> dict[PortID, None | bytes]: outputs: dict[PortID, None | bytes] = {val: None for val in node.outputs} diff --git a/tierkreis/tierkreis/controller/storage/in_memory.py b/tierkreis/tierkreis/controller/storage/in_memory.py index 21a3a1ac4..89339e952 100644 --- a/tierkreis/tierkreis/controller/storage/in_memory.py +++ b/tierkreis/tierkreis/controller/storage/in_memory.py @@ -29,6 +29,8 @@ class NodeData(BaseModel): metadata: dict[str, Any] = Field(default_factory=dict) error_logs: str = "" outputs: dict[PortID, bytes | None] = Field(default_factory=dict) + started: str | None = None + finished: str | None = None class ControllerInMemoryStorage: @@ -72,6 +74,7 @@ def path_to_loc(self, path: Path) -> tuple[Loc, PortID | None]: def write_node_def(self, node_location: Loc, node: NodeDef) -> None: self.nodes[self.loc_to_path(node_location)].definition = node + self.nodes[self.loc_to_path(node_location)].started = datetime.now().isoformat() def read_node_def(self, node_location: Loc) -> NodeDef: if result := self.nodes[self.loc_to_path(node_location)].definition: @@ -126,6 +129,9 @@ def write_node_errors(self, node_location: Loc, error_logs: str) -> None: def mark_node_finished(self, node_location: Loc) -> None: self.nodes[self.loc_to_path(node_location)].is_done = True + self.nodes[ + self.loc_to_path(node_location) + ].finished = datetime.now().isoformat() def is_node_finished(self, node_location: Loc) -> bool: return self.nodes[self.loc_to_path(node_location)].is_done @@ -176,6 +182,12 @@ def write_metadata(self, node_location: Loc) -> None: "start_time": datetime.now().isoformat(), } + def read_started_time(self, node_location: Loc) -> str | None: + return self.nodes[self.loc_to_path(node_location)].started + + def read_finished_time(self, node_location: Loc) -> str | None: + return self.nodes[self.loc_to_path(node_location)].finished + def clean_graph_files(self) -> None: uid = os.getuid() tmp_dir = Path(f"/tmp/{uid}/tierkreis/archive/{time_ns()}") diff --git a/tierkreis/tierkreis/controller/storage/protocol.py b/tierkreis/tierkreis/controller/storage/protocol.py index 0867a0f2f..68f637d83 100644 --- a/tierkreis/tierkreis/controller/storage/protocol.py +++ b/tierkreis/tierkreis/controller/storage/protocol.py @@ -239,3 +239,23 @@ def write_metadata(self, node_location: Loc) -> None: :type node_location: Loc """ ... + + def read_started_time(self, node_location: Loc) -> str | None: + """Reads the start time of a node + + :param node_location: The location of the node + :type node_location: Loc + :return: A time string when node has started, else None. + :rtype: str | None + """ + ... + + def read_finished_time(self, node_location: Loc) -> str | None: + """Reads the finish time of a node + + :param node_location: The location of the node + :type node_location: Loc + :return: A time string when node is completed, else None. + :rtype: str | None + """ + ... diff --git a/tierkreis_visualization/frontend/bun.lock b/tierkreis_visualization/frontend/bun.lock index f86c772bb..1c2695fa8 100644 --- a/tierkreis_visualization/frontend/bun.lock +++ b/tierkreis_visualization/frontend/bun.lock @@ -29,12 +29,12 @@ "@types/react-dom": "^18.2.18", "@typescript-eslint/eslint-plugin": "^6.20.0", "@typescript-eslint/parser": "^6.20.0", - "@vitejs/plugin-react": "^4.6.0", + "@vitejs/plugin-react": "^5.0.0", "eslint": "^8.56.0", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.5", "typescript": "^5.3.3", - "vite": "^7.0.4", + "vite": "^7.1.0", }, }, }, @@ -47,9 +47,9 @@ "@babel/compat-data": ["@babel/compat-data@7.28.0", "", {}, "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw=="], - "@babel/core": ["@babel/core@7.28.0", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.0", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.27.3", "@babel/helpers": "^7.27.6", "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.0", "@babel/types": "^7.28.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ=="], + "@babel/core": ["@babel/core@7.28.3", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.3", "@babel/parser": "^7.28.3", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ=="], - "@babel/generator": ["@babel/generator@7.28.0", "", { "dependencies": { "@babel/parser": "^7.28.0", "@babel/types": "^7.28.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg=="], + "@babel/generator": ["@babel/generator@7.28.3", "", { "dependencies": { "@babel/parser": "^7.28.3", "@babel/types": "^7.28.2", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw=="], "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.27.2", "", { "dependencies": { "@babel/compat-data": "^7.27.2", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ=="], @@ -57,7 +57,7 @@ "@babel/helper-module-imports": ["@babel/helper-module-imports@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w=="], - "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.27.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.27.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg=="], + "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="], "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.27.1", "", {}, "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw=="], @@ -67,9 +67,9 @@ "@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="], - "@babel/helpers": ["@babel/helpers@7.28.2", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.2" } }, "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw=="], + "@babel/helpers": ["@babel/helpers@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.2" } }, "sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw=="], - "@babel/parser": ["@babel/parser@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.0" }, "bin": "./bin/babel-parser.js" }, "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g=="], + "@babel/parser": ["@babel/parser@7.28.3", "", { "dependencies": { "@babel/types": "^7.28.2" }, "bin": "./bin/babel-parser.js" }, "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA=="], "@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw=="], @@ -77,7 +77,7 @@ "@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], - "@babel/traverse": ["@babel/traverse@7.28.0", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", "@babel/types": "^7.28.0", "debug": "^4.3.1" } }, "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg=="], + "@babel/traverse": ["@babel/traverse@7.28.3", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.3", "@babel/template": "^7.27.2", "@babel/types": "^7.28.2", "debug": "^4.3.1" } }, "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ=="], "@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="], @@ -229,7 +229,7 @@ "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="], - "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.27", "", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="], + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.34", "", {}, "sha512-LyAREkZHP5pMom7c24meKmJCdhf2hEyvam2q0unr3or9ydwDL+DJ8chTF6Av/RFPb3rH8UFBdMzO5MxTZW97oA=="], "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.46.2", "", { "os": "android", "cpu": "arm" }, "sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA=="], @@ -363,7 +363,7 @@ "@ungap/structured-clone": ["@ungap/structured-clone@1.2.0", "", {}, "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ=="], - "@vitejs/plugin-react": ["@vitejs/plugin-react@4.7.0", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.27", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA=="], + "@vitejs/plugin-react": ["@vitejs/plugin-react@5.0.2", "", { "dependencies": { "@babel/core": "^7.28.3", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.34", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-tmyFgixPZCx2+e6VO9TNITWcCQl8+Nl/E8YbAyPVv85QCc7/A3JrdfG2A8gIzvVhWuzMOVrFW1aReaNxrI6tbw=="], "@xyflow/react": ["@xyflow/react@12.7.0", "", { "dependencies": { "@xyflow/system": "0.0.62", "classcat": "^5.0.3", "zustand": "^4.4.0" }, "peerDependencies": { "react": ">=17", "react-dom": ">=17" } }, "sha512-U6VMEbYjiCg1byHrR7S+b5ZdHTjgCFX4KpBc634G/WtEBUvBLoMQdlCD6uJHqodnOAxpt3+G2wiDeTmXAFJzgQ=="], @@ -755,6 +755,10 @@ "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "@babel/helper-module-imports/@babel/traverse": ["@babel/traverse@7.28.0", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", "@babel/types": "^7.28.0", "debug": "^4.3.1" } }, "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg=="], + + "@babel/template/@babel/parser": ["@babel/parser@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.0" }, "bin": "./bin/babel-parser.js" }, "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g=="], + "@eslint/eslintrc/globals": ["globals@13.24.0", "", { "dependencies": { "type-fest": "^0.20.2" } }, "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ=="], "@jridgewell/gen-mapping/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.4.15", "", {}, "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="], @@ -795,6 +799,10 @@ "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + "@babel/helper-module-imports/@babel/traverse/@babel/generator": ["@babel/generator@7.28.0", "", { "dependencies": { "@babel/parser": "^7.28.0", "@babel/types": "^7.28.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg=="], + + "@babel/helper-module-imports/@babel/traverse/@babel/parser": ["@babel/parser@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.0" }, "bin": "./bin/babel-parser.js" }, "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g=="], + "@types/babel__core/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.23.4", "", {}, "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ=="], "@types/babel__core/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.22.20", "", {}, "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A=="], @@ -812,5 +820,9 @@ "@types/babel__traverse/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.22.20", "", {}, "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A=="], "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], + + "@babel/helper-module-imports/@babel/traverse/@babel/generator/@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg=="], + + "@babel/helper-module-imports/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.29", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ=="], } } diff --git a/tierkreis_visualization/frontend/index.html b/tierkreis_visualization/frontend/index.html index 233b2cceb..2fdda2d9b 100644 --- a/tierkreis_visualization/frontend/index.html +++ b/tierkreis_visualization/frontend/index.html @@ -2,7 +2,7 @@ - + Tierkreis Frontend diff --git a/tierkreis_visualization/frontend/public/favicon.ico b/tierkreis_visualization/frontend/public/favicon.ico deleted file mode 100644 index 9ef0fbfd6..000000000 Binary files a/tierkreis_visualization/frontend/public/favicon.ico and /dev/null differ diff --git a/tierkreis_visualization/frontend/public/favicon.svg b/tierkreis_visualization/frontend/public/favicon.svg new file mode 100644 index 000000000..d7063b2ab --- /dev/null +++ b/tierkreis_visualization/frontend/public/favicon.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/tierkreis_visualization/frontend/src/App.tsx b/tierkreis_visualization/frontend/src/App.tsx index ee9d24b4c..23319b9d4 100644 --- a/tierkreis_visualization/frontend/src/App.tsx +++ b/tierkreis_visualization/frontend/src/App.tsx @@ -17,7 +17,7 @@ import { URL } from "@/data/constants"; import { parseGraph } from "@/graph/parseGraph"; import { Background, ControlButton, Controls } from "@xyflow/react"; import "@xyflow/react/dist/style.css"; -import { Network } from "lucide-react"; +import { Eye, EyeClosed, FolderSync, Network } from "lucide-react"; import React, { useCallback, useState } from "react"; import { SidebarTrigger } from "@/components/ui/sidebar"; @@ -77,71 +77,99 @@ const Main = (props: { setInfo: (arg: InfoProps) => void; }) => { // Client node state (not definition) - const [nodes, setNodes] = useState(props.initialNodes); - const [edges, setEdges] = useState(props.initialEdges); + + const reactFlowInstance = useReactFlow(); + const [tooltipsOpen, setAreTooltipsOpen] = useState(false); + props.initialNodes.map((node) => { + node.data.setInfo = props.setInfo; + node.data.onTooltipOpenChange = setAreTooltipsOpen; + node.data.isTooltipOpen = tooltipsOpen; + }); + const handleToggleTooltips = () => { + setAreTooltipsOpen((prev) => !prev); + reactFlowInstance.getNodes().forEach((node) => { + reactFlowInstance.updateNodeData(node.id, { + isTooltipOpen: tooltipsOpen, + }); + }); + }; React.useEffect(() => { saveGraph({ key: props.workflow_id, - nodes, - edges, + nodes: reactFlowInstance.getNodes(), + edges: reactFlowInstance.getEdges(), start_time: props.workflow_start, }); - }, [edges, nodes, props.workflow_id, props.workflow_start]); + }, [reactFlowInstance, props.workflow_id, props.workflow_start]); const onNodesChange: OnNodesChange = useCallback( (changes) => - setNodes((nodesSnapshot) => applyNodeChanges(changes, nodesSnapshot)), - [] + reactFlowInstance.setNodes((nodesSnapshot) => + applyNodeChanges(changes, nodesSnapshot) + ), + [reactFlowInstance] ); const onEdgesChange: OnEdgesChange = useCallback( (changes) => - setEdges((edgesSnapshot) => applyEdgeChanges(changes, edgesSnapshot)), - [] + reactFlowInstance.setEdges((edgesSnapshot) => + applyEdgeChanges(changes, edgesSnapshot) + ), + [reactFlowInstance] ); const onNodeDrag: OnNodeDrag = useCallback((_, node) => { node.data.pinned = true; }, []); - const reactFlowInstance = useReactFlow(); React.useEffect(() => { const url = `${URL}/${props.workflow_id}/nodes/-`; const ws = new WebSocket(url); - const edges = reactFlowInstance.getEdges(); - const nodes = reactFlowInstance.getNodes() as BackendNode[]; ws.onmessage = (event) => { - const graph = parseGraph( - JSON.parse(event.data), - props.workflow_id, - props.setInfo - ); - const nodesMap = new Map(nodes.map((node) => [node.id, node])); + console.log("Received WebSocket message:"); + const nodes = reactFlowInstance.getNodes(); + const edges = reactFlowInstance.getEdges(); + console.log({ edges, nodes }); + const graph = parseGraph(JSON.parse(event.data), props.workflow_id); + let nodesMap = new Map(); + if (nodes) { + nodesMap = new Map(nodes.map((node) => [node.id, node])); + } const newNodes = bottomUpLayout(graph.nodes, graph.edges); + const hiddenEdges = new Set(); newNodes.forEach((node) => { const existingNode = nodesMap.get(node.id); if (existingNode) { + if (existingNode.type === "group") { + hiddenEdges.add(existingNode.id); + return; + } existingNode.data = { ...existingNode.data, status: node.data.status, }; existingNode.position = { - ...(reactFlowInstance.getNode(node.id)?.position ?? node.position), + ...(nodes.find((n) => n.id === node.id)?.position ?? node.position), }; } else { + node.data.setInfo = props.setInfo; nodesMap.set(node.id, node); } }); - setNodes(Array.from(nodesMap.values())); + const edgeIds = new Set(edges.map((edge) => edge.id)); const newEdges = graph.edges.filter((edge) => !edgeIds.has(edge.id)); - if (newEdges.length > 0) { - setEdges([...edges, ...newEdges]); - } + console.log(hiddenEdges); + const oldEdges = [...edges, ...newEdges].filter( + (edge) => !hiddenEdges.has(edge.source) && !hiddenEdges.has(edge.target) + ); + console.log("new nodes", Array.from(nodesMap.values())); + console.log("old edges", oldEdges); + reactFlowInstance.setNodes(Array.from(nodesMap.values())); + reactFlowInstance.setEdges([...oldEdges]); }; return () => { if (ws.readyState == WebSocket.OPEN) { ws.close(); } }; - }, [props, reactFlowInstance, setNodes, setEdges]); - + }, [props, reactFlowInstance, props.setInfo]); return ( - nodes={nodes} - edges={edges} - defaultNodes={nodes} - defaultEdges={edges} + defaultNodes={props.initialNodes} + defaultEdges={props.initialEdges} nodeTypes={nodeTypes} edgeTypes={edgeTypes} onEdgesChange={onEdgesChange} @@ -165,13 +191,32 @@ const Main = (props: { { - setEdges(edges); - setNodes(bottomUpLayout(nodes, reactFlowInstance.getEdges())); + reactFlowInstance.setEdges(reactFlowInstance.getEdges()); + reactFlowInstance.setNodes( + bottomUpLayout( + reactFlowInstance.getNodes(), + reactFlowInstance.getEdges() + ) + ); reactFlowInstance.fitView({ padding: 0.1 }); }} > + { + localStorage.clear(); + }} + > + + + + {tooltipsOpen ? ( + + ) : ( + + )} + @@ -180,13 +225,13 @@ const Main = (props: { export default function App() { const { workflowId: workflow_id_url } = useParams(); - const workflowsQuery = useSuspenseQuery({ queryKey: ["workflows", URL], queryFn: async () => { const response = await fetch(`${URL}/all`); if (!response.ok) { - throw new Error("Network response was not ok"); + const text = await response.json(); + throw new Error(`${text}`); } return response.json(); }, @@ -221,7 +266,6 @@ export default function App() { type: "Logs", content: logs.data, }); - const graphQuery = useSuspenseQuery({ queryKey: ["workflowGraph", workflow_id], queryFn: async () => { @@ -234,13 +278,13 @@ export default function App() { } return response.json(); }, - select: (data) => parseGraph(data, workflow_id, setInfo), + select: (data) => parseGraph(data, workflow_id), }); const remoteGraph = graphQuery.data; - const workflow_start = workflowsQuery.data.find( - (workflow) => workflow.id == workflow_id - )?.start_time || ""; + const workflow_start = + workflowsQuery.data.find((workflow) => workflow.id == workflow_id) + ?.start_time || ""; const localGraph = loadGraph({ key: workflow_id }); if (workflow_start && workflow_start != localGraph?.start_time) { deleteGraph({ key: workflow_id }); @@ -277,7 +321,6 @@ export default function App() { edges: mergedEdges, }; })(); - return (
{ +export const InputHandleArray = ({ + handles, + id, + isOpen, + onOpenChange, +}: HandleProps) => { return (
{ }} > <> - + { ); }; -export const OutputHandleArray = ({ handles, id }: HandleProps) => { +export const OutputHandleArray = ({ + handles, + id, + isOpen, + onOpenChange, +}: HandleProps) => { return (
{ }} > <> - + void; } diff --git a/tierkreis_visualization/frontend/src/error.tsx b/tierkreis_visualization/frontend/src/error.tsx new file mode 100644 index 000000000..8cabff294 --- /dev/null +++ b/tierkreis_visualization/frontend/src/error.tsx @@ -0,0 +1,57 @@ +import { Link, useRouteError, isRouteErrorResponse } from "react-router"; +import MyLogo from "./quantinuum_logo.svg"; // + +export default function ErrorPage() { + const error = useRouteError(); + let errorMessage: string; + if (isRouteErrorResponse(error)) { + errorMessage = error.statusText; + } else if (error instanceof Error) { + errorMessage = error.message; + } else if (typeof error === "string") { + errorMessage = error; + } else { + errorMessage = "An unknown error occurred"; + } + + return ( +
+
+

Oops! 😱

+

Sorry, an unexpected error has occurred.

+

+ {errorMessage} +

+ Go back to the homepage +
+
+ Company Logo +
+
+ ); +} + +// Basic inline styles for layout +// In a real app, you'd likely use CSS classes +const containerStyle: React.CSSProperties = { + display: "flex", + flexDirection: "column", + alignItems: "center", + justifyContent: "center", + minHeight: "100vh", + textAlign: "center", + padding: "20px", + boxSizing: "border-box", +}; + +const contentStyle: React.CSSProperties = { + flexGrow: 1, + display: "flex", + flexDirection: "column", + justifyContent: "center", +}; + +const footerStyle: React.CSSProperties = { + marginTop: "auto", + padding: "20px 0", +}; diff --git a/tierkreis_visualization/frontend/src/graph/parseGraph.ts b/tierkreis_visualization/frontend/src/graph/parseGraph.ts index 33b3e8d25..eb958ef51 100644 --- a/tierkreis_visualization/frontend/src/graph/parseGraph.ts +++ b/tierkreis_visualization/frontend/src/graph/parseGraph.ts @@ -4,7 +4,6 @@ import dagre from "@dagrejs/dagre"; import { Edge } from "@xyflow/react"; import { nodeHeight, nodeWidth } from "@/data/constants"; import { CSSProperties } from "react"; -import { InfoProps } from "@/components/types"; function nodeType(function_name: string) { if (function_name.match(/^L?\d+$/)) { @@ -71,8 +70,8 @@ function parseNodeValue(value: unknown): string | null { return null; } if (typeof value === "string") { - if (value.length > 5) { - return value.slice(0, 5) + "..."; + if (value.length > 10) { + return value.slice(0, 10) + "..."; } return value; } @@ -86,7 +85,6 @@ export function parseNodes( nodes: PyNode[], edges: PyEdge[], workflowId: string, - setInfo: (arg: InfoProps) => void, parentId?: string ): AppNode[] { // child nodes prepend their parents id eg. [0,1,2] => [0:0,0:1,0:2] @@ -98,14 +96,21 @@ export function parseNodes( name: node.function_name, status: node.status, handles: getHandlesFromEdges(Number(node.id), edges), + hidden_handles: undefined, + hidden_edges: undefined, workflowId: workflowId, node_location: node.node_location, title: getTitle(node.function_name), id: (parentId ? `${parentId}:` : "") + node.id.toString(), label: node.function_name, - setInfo: setInfo, pinned: false, value: parseNodeValue(node.value), + setInfo: undefined, + is_expanded: false, + isTooltipOpen: false, + onTooltipOpenChange: () => {}, + started_time: node.started_time, + finished_time: node.finished_time, }, parentId: parentId ? `${parentId}` : undefined, })); @@ -162,16 +167,9 @@ export function parseEdges(edges: PyEdge[], parentId?: string): Edge[] { export function parseGraph( data: { nodes: PyNode[]; edges: PyEdge[] }, workflowId: string, - setInfo: (arg: InfoProps) => void, parentId?: string ) { - const nodes = parseNodes( - data.nodes, - data.edges, - workflowId, - setInfo, - parentId - ); + const nodes = parseNodes(data.nodes, data.edges, workflowId, parentId); const edges = parseEdges(data.edges, parentId); return { nodes, edges }; } diff --git a/tierkreis_visualization/frontend/src/main.tsx b/tierkreis_visualization/frontend/src/main.tsx index da4e2a450..c3c77db12 100644 --- a/tierkreis_visualization/frontend/src/main.tsx +++ b/tierkreis_visualization/frontend/src/main.tsx @@ -13,6 +13,7 @@ import App from "./App"; import { ReactFlowProvider } from "@xyflow/react"; import "@xyflow/react/dist/style.css"; import "./index.css"; +import ErrorPage from "./error"; const queryClient = new QueryClient(); @@ -33,20 +34,24 @@ const router = createBrowserRouter([ { path: "/", element: element, + errorElement: , }, { path: "/:workflowId", element: element, loader: workflowId, + errorElement: , }, { path: "*/:workflowId", element: element, loader: workflowId, + errorElement: , }, { path: "*", element: element, + errorElement: , }, ]); diff --git a/tierkreis_visualization/frontend/src/nodes/default.tsx b/tierkreis_visualization/frontend/src/nodes/default.tsx index 904f50ce9..cf2935715 100644 --- a/tierkreis_visualization/frontend/src/nodes/default.tsx +++ b/tierkreis_visualization/frontend/src/nodes/default.tsx @@ -1,5 +1,4 @@ import { InputHandleArray, OutputHandleArray } from "@/components/handles"; -import { NodeStatusIndicator } from "@/components/StatusIndicator"; import { Button } from "@/components/ui/button"; import { Card, @@ -25,46 +24,61 @@ export function DefaultNode({ data }: NodeProps) { data.node_location, data.status ); + let name = data.title; + if (name == "Function") { + name = data.name; + } else if (data.value) { + name = data.value; + } + const bg_color = (status: string) => { + switch (status) { + case "Started": + return "bg-chart-4"; + case "Finished": + return "bg-emerald-600"; + case "Error": + return "bg-red-400"; + default: + return "bg-white"; + } + }; + return ( - - - -
{ - //workaround to render errors - const target = event.target as HTMLElement; - if (target.closest("button") === null) { - if (data.title == "Function") { - data.setInfo({ type: "Logs", content: logs ? logs : "" }); - } + + +
{ + //workaround to render errors + const target = event.target as HTMLElement; + if (target.closest("button") === null) { + if (data.title == "Function") { + data.setInfo?.({ type: "Logs", content: logs ? logs : "" }); } - }} - > - - - {data.title == "Function" ? data.name : data.title} - {data.value && ( - - {" "} - - {data.value} - - )} - - - - - - - + } + }} + > + + + {name} + + + + +
{data.status == "Error" && ( )} - -
- - - +
+ + + +
+
+
); } diff --git a/tierkreis_visualization/frontend/src/nodes/eval.tsx b/tierkreis_visualization/frontend/src/nodes/eval.tsx index a91270d88..5df2ba52a 100644 --- a/tierkreis_visualization/frontend/src/nodes/eval.tsx +++ b/tierkreis_visualization/frontend/src/nodes/eval.tsx @@ -1,4 +1,10 @@ -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { + Card, + CardContent, + CardFooter, + CardHeader, + CardTitle, +} from "@/components/ui/card"; import { Edge, getOutgoers, type NodeProps, useReactFlow } from "@xyflow/react"; import { InputHandleArray, OutputHandleArray } from "@/components/handles"; @@ -8,7 +14,8 @@ import { URL } from "@/data/constants"; import { parseEdges, parseNodes } from "@/graph/parseGraph"; import { bottomUpLayout } from "@/graph/layoutGraph"; import { type BackendNode } from "./types"; -import { Plus } from "lucide-react"; +import { hideChildren } from "./hide_children"; +import { Minus, Plus } from "lucide-react"; function replaceEval( nodeId: string, @@ -20,7 +27,7 @@ function replaceEval( // replaces an eval node with its nested subgraph const oldEdgesCopy: Edge[] = JSON.parse(JSON.stringify(oldEdges)); // we only care about the last part of the id as number - const nodesToRemove = [nodeId]; + const nodesToRemove: string[] = []; newNodes.sort( (a, b) => Number(a.id.substring(a.id.lastIndexOf(":"), a.id.length)) - @@ -90,25 +97,74 @@ function replaceEval( } } }); - const groupNode = { - id: nodeId, - type: "group", - position: { x: 0, y: 0 }, - data: {}, - parentId: oldNodes.find((node) => node.id === nodeId)?.parentId, - } as BackendNode; - oldNodes = oldNodes.filter((node) => !nodesToRemove.includes(node.id)); + // remove the body nodes (might not want to do that in the future) + // update the internal state of the eval node + oldNodes = oldNodes + .map((node) => { + if (nodesToRemove.includes(node.id)) { + return undefined; + } + if (node.id === nodeId) { + const handles = node.data.handles.inputs.filter( + (handle) => !handle.includes("body") + ); + node.position = { x: 0, y: 0 }; + node.data.hidden_handles = { + inputs: handles, + outputs: node.data.handles.outputs, + }; + node.data.hidden_edges = oldEdges.filter( + (edge) => + (edge.target === nodeId || edge.source === nodeId) && + edge.label !== "Graph Body" + ); + node.data.handles = { inputs: [], outputs: [] }; + node.data.is_expanded = true; + } + return node; + }) + .filter((node): node is BackendNode => node !== undefined); const tmpEdges = oldEdgesCopy.filter( (edge) => edge.target !== nodeId && edge.source !== nodeId ); return { - nodes: [groupNode, ...oldNodes, ...newNodes], + nodes: [...oldNodes, ...newNodes], edges: [...tmpEdges, ...newEdges], }; } export function EvalNode({ data: node_data }: NodeProps) { const reactFlowInstance = useReactFlow(); + if (node_data.is_expanded) { + const collapseSelf = (nodeId: string) => { + const oldEdges = reactFlowInstance.getEdges(); + const oldNodes = reactFlowInstance.getNodes(); + const { nodes: newNodes, edges: newEdges } = hideChildren( + nodeId, + oldNodes, + oldEdges + ); + const positionedNodes = bottomUpLayout(newNodes, newEdges); + reactFlowInstance.setNodes(positionedNodes); + reactFlowInstance.setEdges(newEdges); + }; + return ( + +
+ +
+
+ ); + } const loadChildren = async ( workflowId: string, node_location: string, @@ -118,13 +174,7 @@ export function EvalNode({ data: node_data }: NodeProps) { fetch(url, { method: "GET", headers: { Accept: "application/json" } }) .then((response) => response.json()) .then((data) => { - const nodes = parseNodes( - data.nodes, - data.edges, - workflowId, - node_data.setInfo, - parentId - ); + const nodes = parseNodes(data.nodes, data.edges, workflowId, parentId); const edges = parseEdges(data.edges, parentId); const oldEdges = reactFlowInstance.getEdges(); const oldNodes = reactFlowInstance.getNodes(); @@ -143,38 +193,51 @@ export function EvalNode({ data: node_data }: NodeProps) { reactFlowInstance.setEdges(newEdges); }); }; + return ( - + - {node_data.title} + + {node_data.title} + - +
+ {node_data.status != "Not started" && ( + + )} +
-
- -
+
); diff --git a/tierkreis_visualization/frontend/src/nodes/hide_children.ts b/tierkreis_visualization/frontend/src/nodes/hide_children.ts new file mode 100644 index 000000000..3d8467ca2 --- /dev/null +++ b/tierkreis_visualization/frontend/src/nodes/hide_children.ts @@ -0,0 +1,41 @@ +import { BackendNode } from "./types"; +import { Edge } from "@xyflow/react"; + +export function hideChildren( + nodeId: string, + oldNodes: BackendNode[], + oldEdges: Edge[] +) { + let hidden_edges: Edge[] = []; + oldNodes = oldNodes + .map((node) => { + if (node.parentId?.startsWith(nodeId)) { + return undefined; + } + if (node.id === nodeId) { + hidden_edges = node.data.hidden_edges ?? []; + node.position = { x: 0, y: 0 }; + node.data.handles = node.data.hidden_handles ?? { + inputs: [], + outputs: [], + }; + node.data.is_expanded = false; + node.style = { + width: 180, + height: 130, + }; + } + return node; + }) + .filter((node): node is BackendNode => node !== undefined); + + oldEdges.filter( + (edge) => + edge.target.startsWith(nodeId + ":") && + edge.source.startsWith(nodeId + ":") + ); + return { + nodes: [...oldNodes], + edges: [...oldEdges, ...hidden_edges], + }; +} diff --git a/tierkreis_visualization/frontend/src/nodes/map.tsx b/tierkreis_visualization/frontend/src/nodes/map.tsx index ab8fcdb07..4127f1b9f 100644 --- a/tierkreis_visualization/frontend/src/nodes/map.tsx +++ b/tierkreis_visualization/frontend/src/nodes/map.tsx @@ -1,4 +1,10 @@ -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { + Card, + CardContent, + CardFooter, + CardHeader, + CardTitle, +} from "@/components/ui/card"; import { Edge, useReactFlow, type NodeProps } from "@xyflow/react"; import { InputHandleArray, OutputHandleArray } from "@/components/handles"; @@ -7,8 +13,9 @@ import { Button } from "@/components/ui/button"; import { URL } from "@/data/constants"; import { parseNodes } from "@/graph/parseGraph"; import { type BackendNode } from "@/nodes/types"; -import { Plus } from "lucide-react"; +import { Plus, Minus } from "lucide-react"; import { bottomUpLayout } from "@/graph/layoutGraph"; +import { hideChildren } from "./hide_children"; function replaceMap( nodeId: string, @@ -18,7 +25,7 @@ function replaceMap( ) { // copy over all the inputs and outputs from the map node to its children let edges: Edge[] = JSON.parse(JSON.stringify(oldEdges)); - const nodesToRemove = [nodeId]; + const nodesToRemove: string[] = []; const edgesToRemove: string[] = []; const newEdges: Edge[] = []; edges.forEach((edge) => { @@ -59,24 +66,65 @@ function replaceMap( }); } }); - const groupNode = { - id: nodeId, - type: "group", - position: { x: 0, y: 0 }, - data: {}, - parentId: oldNodes.find((node) => node.id === nodeId)?.parentId, - } as BackendNode; - oldNodes = oldNodes.filter((node) => !nodesToRemove.includes(node.id)); + // remove the body nodes (might not want to do that in the future) + // update the internal state of the map node + oldNodes = oldNodes + .map((node) => { + if (nodesToRemove.includes(node.id)) { + return undefined; + } + if (node.id === nodeId) { + node.position = { x: 0, y: 0 }; + node.data.hidden_handles = node.data.handles; + node.data.hidden_edges = edges.filter( + (edge) => edge.target === nodeId || edge.source === nodeId + ); + node.data.handles = { inputs: [], outputs: [] }; + node.data.is_expanded = true; + } + return node; + }) + .filter((node): node is BackendNode => node !== undefined); edges = edges.filter((edge) => !edgesToRemove.includes(edge.id)); // there are no edges between the newNodes return { - nodes: [groupNode, ...oldNodes, ...newNodes], + nodes: [...oldNodes, ...newNodes], edges: [...edges, ...newEdges], }; } export function MapNode({ data: node_data }: NodeProps) { const reactFlowInstance = useReactFlow(); + if (node_data.is_expanded) { + const collapseSelf = (nodeId: string) => { + const oldEdges = reactFlowInstance.getEdges(); + const oldNodes = reactFlowInstance.getNodes(); + const { nodes: newNodes, edges: newEdges } = hideChildren( + nodeId, + oldNodes, + oldEdges + ); + const positionedNodes = bottomUpLayout(newNodes, newEdges); + reactFlowInstance.setNodes(positionedNodes); + reactFlowInstance.setEdges(newEdges); + }; + return ( + +
+ +
+
+ ); + } const loadChildren = async ( workflowId: string, node_location: string, @@ -86,13 +134,7 @@ export function MapNode({ data: node_data }: NodeProps) { fetch(url, { method: "GET", headers: { Accept: "application/json" } }) .then((response) => response.json()) .then((data) => { - const nodes = parseNodes( - data.nodes, - data.edges, - workflowId, - node_data.setInfo, - parentId - ); + const nodes = parseNodes(data.nodes, data.edges, workflowId, parentId); const oldEdges = reactFlowInstance.getEdges(); const oldNodes = reactFlowInstance.getNodes(); const { nodes: newNodes, edges: newEdges } = replaceMap( @@ -111,7 +153,8 @@ export function MapNode({ data: node_data }: NodeProps) { }; return ( - + {} + {node_data.title} @@ -135,12 +178,20 @@ export function MapNode({ data: node_data }: NodeProps) { + ); diff --git a/tierkreis_visualization/frontend/src/nodes/types.ts b/tierkreis_visualization/frontend/src/nodes/types.ts index 1efa65e89..641750395 100644 --- a/tierkreis_visualization/frontend/src/nodes/types.ts +++ b/tierkreis_visualization/frontend/src/nodes/types.ts @@ -1,5 +1,5 @@ import { InfoProps } from "@/components/types"; -import { type Node } from "@xyflow/react"; +import { Edge, type Node } from "@xyflow/react"; export type PyNode = { id: string | number; @@ -7,6 +7,8 @@ export type PyNode = { function_name: string; node_location: string; value?: unknown; + started_time: string; + finished_time: string; }; export type BackendNode = Node<{ name: string; @@ -15,13 +17,23 @@ export type BackendNode = Node<{ inputs: string[]; outputs: string[]; }; + hidden_handles?: { + inputs: string[]; + outputs: string[]; + }; + hidden_edges?: Edge[]; workflowId: string; node_location: string; id: string; title: string; - setInfo: (arg: InfoProps) => void; label?: string; pinned: boolean; value: string | null; + setInfo?: (info: InfoProps) => void; + is_expanded: boolean; + isTooltipOpen: boolean; + onTooltipOpenChange: (open: boolean) => void; + started_time: string; + finished_time: string; }>; export type AppNode = BackendNode; diff --git a/tierkreis_visualization/frontend/src/quantinuum_logo.svg b/tierkreis_visualization/frontend/src/quantinuum_logo.svg new file mode 100644 index 000000000..e84cd38ab --- /dev/null +++ b/tierkreis_visualization/frontend/src/quantinuum_logo.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/tierkreis_visualization/frontend/yarn.lock b/tierkreis_visualization/frontend/yarn.lock new file mode 100644 index 000000000..a0cc20787 --- /dev/null +++ b/tierkreis_visualization/frontend/yarn.lock @@ -0,0 +1,2595 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 +# bun ./bun.lockb --hash: 0000000000000000-0000000000000000-0000000000000000-0000000000000000 + + +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@ampproject/remapping@^2.2.0", "@ampproject/remapping@^2.3.0": + version "2.3.0" + resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz" + integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + +"@babel/code-frame@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz" + integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== + dependencies: + "@babel/helper-validator-identifier" "^7.27.1" + js-tokens "^4.0.0" + picocolors "^1.1.1" + +"@babel/compat-data@^7.27.2": + version "7.28.0" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz" + integrity sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw== + +"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.28.3": + version "7.28.3" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.28.3.tgz" + integrity sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.28.3" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-module-transforms" "^7.28.3" + "@babel/helpers" "^7.28.3" + "@babel/parser" "^7.28.3" + "@babel/template" "^7.27.2" + "@babel/traverse" "^7.28.3" + "@babel/types" "^7.28.2" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.28.0": + version "7.28.0" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz" + integrity sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg== + dependencies: + "@babel/parser" "^7.28.0" + "@babel/types" "^7.28.0" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" + +"@babel/generator@^7.28.3": + version "7.28.3" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz" + integrity sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw== + dependencies: + "@babel/parser" "^7.28.3" + "@babel/types" "^7.28.2" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" + +"@babel/helper-compilation-targets@^7.27.2": + version "7.27.2" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz" + integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ== + dependencies: + "@babel/compat-data" "^7.27.2" + "@babel/helper-validator-option" "^7.27.1" + browserslist "^4.24.0" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-globals@^7.28.0": + version "7.28.0" + resolved "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz" + integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== + +"@babel/helper-module-imports@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz" + integrity sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w== + dependencies: + "@babel/traverse" "^7.27.1" + "@babel/types" "^7.27.1" + +"@babel/helper-module-transforms@^7.28.3": + version "7.28.3" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz" + integrity sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw== + dependencies: + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + "@babel/traverse" "^7.28.3" + +"@babel/helper-plugin-utils@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz" + integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== + +"@babel/helper-string-parser@^7.23.4": + version "7.23.4" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz" + integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== + +"@babel/helper-string-parser@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz" + integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/helper-validator-identifier@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz" + integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== + +"@babel/helper-validator-option@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz" + integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== + +"@babel/helpers@^7.28.3": + version "7.28.3" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.3.tgz" + integrity sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw== + dependencies: + "@babel/template" "^7.27.2" + "@babel/types" "^7.28.2" + +"@babel/parser@^7.1.0", "@babel/parser@^7.20.7": + version "7.23.9" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz" + integrity sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA== + +"@babel/parser@^7.27.2", "@babel/parser@^7.28.0": + version "7.28.0" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz" + integrity sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g== + dependencies: + "@babel/types" "^7.28.0" + +"@babel/parser@^7.28.3": + version "7.28.3" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.28.3.tgz" + integrity sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA== + dependencies: + "@babel/types" "^7.28.2" + +"@babel/plugin-transform-react-jsx-self@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz" + integrity sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-react-jsx-source@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz" + integrity sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/template@^7.27.2": + version "7.27.2" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz" + integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/parser" "^7.27.2" + "@babel/types" "^7.27.1" + +"@babel/traverse@^7.27.1": + version "7.28.0" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz" + integrity sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.28.0" + "@babel/helper-globals" "^7.28.0" + "@babel/parser" "^7.28.0" + "@babel/template" "^7.27.2" + "@babel/types" "^7.28.0" + debug "^4.3.1" + +"@babel/traverse@^7.28.3": + version "7.28.3" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.3.tgz" + integrity sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.28.3" + "@babel/helper-globals" "^7.28.0" + "@babel/parser" "^7.28.3" + "@babel/template" "^7.27.2" + "@babel/types" "^7.28.2" + debug "^4.3.1" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7": + version "7.23.9" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz" + integrity sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + +"@babel/types@^7.27.1", "@babel/types@^7.28.0", "@babel/types@^7.28.2": + version "7.28.2" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz" + integrity sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + +"@dagrejs/dagre@^1.1.4": + version "1.1.4" + resolved "https://registry.npmjs.org/@dagrejs/dagre/-/dagre-1.1.4.tgz" + integrity sha512-QUTc54Cg/wvmlEUxB+uvoPVKFazM1H18kVHBQNmK2NbrDR5ihOCR6CXLnDSZzMcSQKJtabPUWridBOlJM3WkDg== + dependencies: + "@dagrejs/graphlib" "2.2.4" + +"@dagrejs/graphlib@2.2.4": + version "2.2.4" + resolved "https://registry.npmjs.org/@dagrejs/graphlib/-/graphlib-2.2.4.tgz" + integrity sha512-mepCf/e9+SKYy1d02/UkvSy6+6MoyXhVxP8lLDfA7BPE1X1d4dR0sZznmbM8/XVJ1GPM+Svnx7Xj6ZweByWUkw== + +"@emnapi/core@^1.4.3": + version "1.4.3" + resolved "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz" + integrity sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g== + dependencies: + "@emnapi/wasi-threads" "1.0.2" + tslib "^2.4.0" + +"@emnapi/runtime@^1.4.3": + version "1.4.3" + resolved "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz" + integrity sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ== + dependencies: + tslib "^2.4.0" + +"@emnapi/wasi-threads@1.0.2", "@emnapi/wasi-threads@^1.0.2": + version "1.0.2" + resolved "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz" + integrity sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA== + dependencies: + tslib "^2.4.0" + +"@esbuild/aix-ppc64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz" + integrity sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA== + +"@esbuild/android-arm@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz" + integrity sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw== + +"@esbuild/android-arm64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz" + integrity sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w== + +"@esbuild/android-x64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz" + integrity sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA== + +"@esbuild/darwin-arm64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz" + integrity sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw== + +"@esbuild/darwin-x64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz" + integrity sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg== + +"@esbuild/freebsd-arm64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz" + integrity sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA== + +"@esbuild/freebsd-x64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz" + integrity sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw== + +"@esbuild/linux-arm@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz" + integrity sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg== + +"@esbuild/linux-arm64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz" + integrity sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w== + +"@esbuild/linux-ia32@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz" + integrity sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg== + +"@esbuild/linux-loong64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz" + integrity sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ== + +"@esbuild/linux-mips64el@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz" + integrity sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw== + +"@esbuild/linux-ppc64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz" + integrity sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ== + +"@esbuild/linux-riscv64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz" + integrity sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg== + +"@esbuild/linux-s390x@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz" + integrity sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg== + +"@esbuild/linux-x64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz" + integrity sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ== + +"@esbuild/netbsd-arm64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz" + integrity sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw== + +"@esbuild/netbsd-x64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz" + integrity sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg== + +"@esbuild/openbsd-arm64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz" + integrity sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ== + +"@esbuild/openbsd-x64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz" + integrity sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ== + +"@esbuild/openharmony-arm64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz" + integrity sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg== + +"@esbuild/sunos-x64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz" + integrity sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w== + +"@esbuild/win32-arm64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz" + integrity sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ== + +"@esbuild/win32-ia32@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz" + integrity sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg== + +"@esbuild/win32-x64@0.25.8": + version "0.25.8" + resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz" + integrity sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw== + +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.4.0" + resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": + version "4.10.0" + resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz" + integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== + +"@eslint/eslintrc@^2.1.4": + version "2.1.4" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz" + integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@8.56.0": + version "8.56.0" + resolved "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz" + integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== + +"@floating-ui/core@^1.7.0": + version "1.7.0" + resolved "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.0.tgz" + integrity sha512-FRdBLykrPPA6P76GGGqlex/e7fbe0F1ykgxHYNXQsH/iTEtjMj/f9bpY5oQqbjt5VgZvgz/uKXbGuROijh3VLA== + dependencies: + "@floating-ui/utils" "^0.2.9" + +"@floating-ui/dom@^1.0.0": + version "1.7.0" + resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.0.tgz" + integrity sha512-lGTor4VlXcesUMh1cupTUTDoCxMb0V6bm3CnxHzQcw8Eaf1jQbgQX4i02fYgT0vJ82tb5MZ4CZk1LRGkktJCzg== + dependencies: + "@floating-ui/core" "^1.7.0" + "@floating-ui/utils" "^0.2.9" + +"@floating-ui/react-dom@^2.0.0": + version "2.1.2" + resolved "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz" + integrity sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A== + dependencies: + "@floating-ui/dom" "^1.0.0" + +"@floating-ui/utils@^0.2.9": + version "0.2.9" + resolved "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz" + integrity sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg== + +"@humanwhocodes/config-array@^0.11.13": + version "0.11.13" + resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz" + integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ== + dependencies: + "@humanwhocodes/object-schema" "^2.0.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^2.0.1": + version "2.0.1" + resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz" + integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== + +"@isaacs/fs-minipass@^4.0.0": + version "4.0.1" + resolved "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz" + integrity sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w== + dependencies: + minipass "^7.0.4" + +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.8" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz" + integrity sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/gen-mapping@^0.3.12": + version "0.3.12" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz" + integrity sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.0" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@jridgewell/trace-mapping@^0.3.24": + version "0.3.25" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.28": + version "0.3.29" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz" + integrity sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@napi-rs/wasm-runtime@^0.2.9": + version "0.2.10" + resolved "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.10.tgz" + integrity sha512-bCsCyeZEwVErsGmyPNSzwfwFn4OdxBj0mmv6hOFucB/k81Ojdu68RbZdxYsRQUPc9l6SU5F/cG+bXgWs3oUgsQ== + dependencies: + "@emnapi/core" "^1.4.3" + "@emnapi/runtime" "^1.4.3" + "@tybys/wasm-util" "^0.9.0" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@radix-ui/primitive@1.1.2": + version "1.1.2" + resolved "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz" + integrity sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA== + +"@radix-ui/react-arrow@1.1.7": + version "1.1.7" + resolved "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz" + integrity sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w== + dependencies: + "@radix-ui/react-primitive" "2.1.3" + +"@radix-ui/react-compose-refs@1.1.2": + version "1.1.2" + resolved "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz" + integrity sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg== + +"@radix-ui/react-context@1.1.2": + version "1.1.2" + resolved "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz" + integrity sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA== + +"@radix-ui/react-dialog@^1.1.14": + version "1.1.14" + resolved "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.14.tgz" + integrity sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-dismissable-layer" "1.1.10" + "@radix-ui/react-focus-guards" "1.1.2" + "@radix-ui/react-focus-scope" "1.1.7" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-portal" "1.1.9" + "@radix-ui/react-presence" "1.1.4" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-slot" "1.2.3" + "@radix-ui/react-use-controllable-state" "1.2.2" + aria-hidden "^1.2.4" + react-remove-scroll "^2.6.3" + +"@radix-ui/react-dismissable-layer@1.1.10": + version "1.1.10" + resolved "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz" + integrity sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-escape-keydown" "1.1.1" + +"@radix-ui/react-focus-guards@1.1.2": + version "1.1.2" + resolved "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz" + integrity sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA== + +"@radix-ui/react-focus-scope@1.1.7": + version "1.1.7" + resolved "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz" + integrity sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw== + dependencies: + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + +"@radix-ui/react-hover-card@^1.1.14": + version "1.1.14" + resolved "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.14.tgz" + integrity sha512-CPYZ24Mhirm+g6D8jArmLzjYu4Eyg3TTUHswR26QgzXBHBe64BO/RHOJKzmF/Dxb4y4f9PKyJdwm/O/AhNkb+Q== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-dismissable-layer" "1.1.10" + "@radix-ui/react-popper" "1.2.7" + "@radix-ui/react-portal" "1.1.9" + "@radix-ui/react-presence" "1.1.4" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-controllable-state" "1.2.2" + +"@radix-ui/react-id@1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz" + integrity sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg== + dependencies: + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-popper@1.2.7": + version "1.2.7" + resolved "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.7.tgz" + integrity sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ== + dependencies: + "@floating-ui/react-dom" "^2.0.0" + "@radix-ui/react-arrow" "1.1.7" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-layout-effect" "1.1.1" + "@radix-ui/react-use-rect" "1.1.1" + "@radix-ui/react-use-size" "1.1.1" + "@radix-ui/rect" "1.1.1" + +"@radix-ui/react-portal@1.1.9": + version "1.1.9" + resolved "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz" + integrity sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ== + dependencies: + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-presence@1.1.4": + version "1.1.4" + resolved "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz" + integrity sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA== + dependencies: + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-primitive@2.1.3": + version "2.1.3" + resolved "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz" + integrity sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ== + dependencies: + "@radix-ui/react-slot" "1.2.3" + +"@radix-ui/react-separator@^1.1.7": + version "1.1.7" + resolved "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz" + integrity sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA== + dependencies: + "@radix-ui/react-primitive" "2.1.3" + +"@radix-ui/react-slot@1.2.3", "@radix-ui/react-slot@^1.2.3": + version "1.2.3" + resolved "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz" + integrity sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A== + dependencies: + "@radix-ui/react-compose-refs" "1.1.2" + +"@radix-ui/react-tooltip@^1.2.7": + version "1.2.7" + resolved "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.7.tgz" + integrity sha512-Ap+fNYwKTYJ9pzqW+Xe2HtMRbQ/EeWkj2qykZ6SuEV4iS/o1bZI5ssJbk4D2r8XuDuOBVz/tIx2JObtuqU+5Zw== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-dismissable-layer" "1.1.10" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-popper" "1.2.7" + "@radix-ui/react-portal" "1.1.9" + "@radix-ui/react-presence" "1.1.4" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-slot" "1.2.3" + "@radix-ui/react-use-controllable-state" "1.2.2" + "@radix-ui/react-visually-hidden" "1.2.3" + +"@radix-ui/react-use-callback-ref@1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz" + integrity sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg== + +"@radix-ui/react-use-controllable-state@1.2.2": + version "1.2.2" + resolved "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz" + integrity sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg== + dependencies: + "@radix-ui/react-use-effect-event" "0.0.2" + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-use-effect-event@0.0.2": + version "0.0.2" + resolved "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz" + integrity sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA== + dependencies: + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-use-escape-keydown@1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz" + integrity sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g== + dependencies: + "@radix-ui/react-use-callback-ref" "1.1.1" + +"@radix-ui/react-use-layout-effect@1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz" + integrity sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ== + +"@radix-ui/react-use-rect@1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz" + integrity sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w== + dependencies: + "@radix-ui/rect" "1.1.1" + +"@radix-ui/react-use-size@1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz" + integrity sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ== + dependencies: + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-visually-hidden@1.2.3": + version "1.2.3" + resolved "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz" + integrity sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug== + dependencies: + "@radix-ui/react-primitive" "2.1.3" + +"@radix-ui/rect@1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz" + integrity sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw== + +"@rolldown/pluginutils@1.0.0-beta.34": + version "1.0.0-beta.34" + resolved "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.34.tgz" + integrity sha512-LyAREkZHP5pMom7c24meKmJCdhf2hEyvam2q0unr3or9ydwDL+DJ8chTF6Av/RFPb3rH8UFBdMzO5MxTZW97oA== + +"@rollup/rollup-android-arm-eabi@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.2.tgz" + integrity sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA== + +"@rollup/rollup-android-arm64@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.2.tgz" + integrity sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ== + +"@rollup/rollup-darwin-arm64@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.2.tgz" + integrity sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ== + +"@rollup/rollup-darwin-x64@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.2.tgz" + integrity sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA== + +"@rollup/rollup-freebsd-arm64@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.2.tgz" + integrity sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg== + +"@rollup/rollup-freebsd-x64@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.2.tgz" + integrity sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw== + +"@rollup/rollup-linux-arm-gnueabihf@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.2.tgz" + integrity sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA== + +"@rollup/rollup-linux-arm-musleabihf@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.2.tgz" + integrity sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ== + +"@rollup/rollup-linux-arm64-gnu@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.2.tgz" + integrity sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng== + +"@rollup/rollup-linux-arm64-musl@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.2.tgz" + integrity sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg== + +"@rollup/rollup-linux-loongarch64-gnu@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.2.tgz" + integrity sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA== + +"@rollup/rollup-linux-ppc64-gnu@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.2.tgz" + integrity sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw== + +"@rollup/rollup-linux-riscv64-gnu@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.2.tgz" + integrity sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ== + +"@rollup/rollup-linux-riscv64-musl@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.2.tgz" + integrity sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw== + +"@rollup/rollup-linux-s390x-gnu@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.2.tgz" + integrity sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA== + +"@rollup/rollup-linux-x64-gnu@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.2.tgz" + integrity sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA== + +"@rollup/rollup-linux-x64-musl@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.2.tgz" + integrity sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA== + +"@rollup/rollup-win32-arm64-msvc@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.2.tgz" + integrity sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g== + +"@rollup/rollup-win32-ia32-msvc@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.2.tgz" + integrity sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ== + +"@rollup/rollup-win32-x64-msvc@4.46.2": + version "4.46.2" + resolved "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.2.tgz" + integrity sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg== + +"@tailwindcss/node@4.1.7": + version "4.1.7" + resolved "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.7.tgz" + integrity sha512-9rsOpdY9idRI2NH6CL4wORFY0+Q6fnx9XP9Ju+iq/0wJwGD5IByIgFmwVbyy4ymuyprj8Qh4ErxMKTUL4uNh3g== + dependencies: + "@ampproject/remapping" "^2.3.0" + enhanced-resolve "^5.18.1" + jiti "^2.4.2" + lightningcss "1.30.1" + magic-string "^0.30.17" + source-map-js "^1.2.1" + tailwindcss "4.1.7" + +"@tailwindcss/oxide@4.1.7": + version "4.1.7" + resolved "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.7.tgz" + integrity sha512-5SF95Ctm9DFiUyjUPnDGkoKItPX/k+xifcQhcqX5RA85m50jw1pT/KzjdvlqxRja45Y52nR4MR9fD1JYd7f8NQ== + optionalDependencies: + "@tailwindcss/oxide-android-arm64" "4.1.7" + "@tailwindcss/oxide-darwin-arm64" "4.1.7" + "@tailwindcss/oxide-darwin-x64" "4.1.7" + "@tailwindcss/oxide-freebsd-x64" "4.1.7" + "@tailwindcss/oxide-linux-arm-gnueabihf" "4.1.7" + "@tailwindcss/oxide-linux-arm64-gnu" "4.1.7" + "@tailwindcss/oxide-linux-arm64-musl" "4.1.7" + "@tailwindcss/oxide-linux-x64-gnu" "4.1.7" + "@tailwindcss/oxide-linux-x64-musl" "4.1.7" + "@tailwindcss/oxide-wasm32-wasi" "4.1.7" + "@tailwindcss/oxide-win32-arm64-msvc" "4.1.7" + "@tailwindcss/oxide-win32-x64-msvc" "4.1.7" + dependencies: + detect-libc "^2.0.4" + tar "^7.4.3" + +"@tailwindcss/oxide-android-arm64@4.1.7": + version "4.1.7" + resolved "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.7.tgz" + integrity sha512-IWA410JZ8fF7kACus6BrUwY2Z1t1hm0+ZWNEzykKmMNM09wQooOcN/VXr0p/WJdtHZ90PvJf2AIBS/Ceqx1emg== + +"@tailwindcss/oxide-darwin-arm64@4.1.7": + version "4.1.7" + resolved "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.7.tgz" + integrity sha512-81jUw9To7fimGGkuJ2W5h3/oGonTOZKZ8C2ghm/TTxbwvfSiFSDPd6/A/KE2N7Jp4mv3Ps9OFqg2fEKgZFfsvg== + +"@tailwindcss/oxide-darwin-x64@4.1.7": + version "4.1.7" + resolved "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.7.tgz" + integrity sha512-q77rWjEyGHV4PdDBtrzO0tgBBPlQWKY7wZK0cUok/HaGgbNKecegNxCGikuPJn5wFAlIywC3v+WMBt0PEBtwGw== + +"@tailwindcss/oxide-freebsd-x64@4.1.7": + version "4.1.7" + resolved "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.7.tgz" + integrity sha512-RfmdbbK6G6ptgF4qqbzoxmH+PKfP4KSVs7SRlTwcbRgBwezJkAO3Qta/7gDy10Q2DcUVkKxFLXUQO6J3CRvBGw== + +"@tailwindcss/oxide-linux-arm-gnueabihf@4.1.7": + version "4.1.7" + resolved "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.7.tgz" + integrity sha512-OZqsGvpwOa13lVd1z6JVwQXadEobmesxQ4AxhrwRiPuE04quvZHWn/LnihMg7/XkN+dTioXp/VMu/p6A5eZP3g== + +"@tailwindcss/oxide-linux-arm64-gnu@4.1.7": + version "4.1.7" + resolved "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.7.tgz" + integrity sha512-voMvBTnJSfKecJxGkoeAyW/2XRToLZ227LxswLAwKY7YslG/Xkw9/tJNH+3IVh5bdYzYE7DfiaPbRkSHFxY1xA== + +"@tailwindcss/oxide-linux-arm64-musl@4.1.7": + version "4.1.7" + resolved "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.7.tgz" + integrity sha512-PjGuNNmJeKHnP58M7XyjJyla8LPo+RmwHQpBI+W/OxqrwojyuCQ+GUtygu7jUqTEexejZHr/z3nBc/gTiXBj4A== + +"@tailwindcss/oxide-linux-x64-gnu@4.1.7": + version "4.1.7" + resolved "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.7.tgz" + integrity sha512-HMs+Va+ZR3gC3mLZE00gXxtBo3JoSQxtu9lobbZd+DmfkIxR54NO7Z+UQNPsa0P/ITn1TevtFxXTpsRU7qEvWg== + +"@tailwindcss/oxide-linux-x64-musl@4.1.7": + version "4.1.7" + resolved "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.7.tgz" + integrity sha512-MHZ6jyNlutdHH8rd+YTdr3QbXrHXqwIhHw9e7yXEBcQdluGwhpQY2Eku8UZK6ReLaWtQ4gijIv5QoM5eE+qlsA== + +"@tailwindcss/oxide-wasm32-wasi@4.1.7": + version "4.1.7" + resolved "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.7.tgz" + integrity sha512-ANaSKt74ZRzE2TvJmUcbFQ8zS201cIPxUDm5qez5rLEwWkie2SkGtA4P+GPTj+u8N6JbPrC8MtY8RmJA35Oo+A== + dependencies: + "@emnapi/core" "^1.4.3" + "@emnapi/runtime" "^1.4.3" + "@emnapi/wasi-threads" "^1.0.2" + "@napi-rs/wasm-runtime" "^0.2.9" + "@tybys/wasm-util" "^0.9.0" + tslib "^2.8.0" + +"@tailwindcss/oxide-win32-arm64-msvc@4.1.7": + version "4.1.7" + resolved "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.7.tgz" + integrity sha512-HUiSiXQ9gLJBAPCMVRk2RT1ZrBjto7WvqsPBwUrNK2BcdSxMnk19h4pjZjI7zgPhDxlAbJSumTC4ljeA9y0tEw== + +"@tailwindcss/oxide-win32-x64-msvc@4.1.7": + version "4.1.7" + resolved "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.7.tgz" + integrity sha512-rYHGmvoHiLJ8hWucSfSOEmdCBIGZIq7SpkPRSqLsH2Ab2YUNgKeAPT1Fi2cx3+hnYOrAb0jp9cRyode3bBW4mQ== + +"@tailwindcss/vite@^4.1.7": + version "4.1.7" + resolved "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.7.tgz" + integrity sha512-tYa2fO3zDe41I7WqijyVbRd8oWT0aEID1Eokz5hMT6wShLIHj3yvwj9XbfuloHP9glZ6H+aG2AN/+ZrxJ1Y5RQ== + dependencies: + "@tailwindcss/node" "4.1.7" + "@tailwindcss/oxide" "4.1.7" + tailwindcss "4.1.7" + +"@tanstack/query-core@5.81.5": + version "5.81.5" + resolved "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.81.5.tgz" + integrity sha512-ZJOgCy/z2qpZXWaj/oxvodDx07XcQa9BF92c0oINjHkoqUPsmm3uG08HpTaviviZ/N9eP1f9CM7mKSEkIo7O1Q== + +"@tanstack/query-devtools@5.81.2": + version "5.81.2" + resolved "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.81.2.tgz" + integrity sha512-jCeJcDCwKfoyyBXjXe9+Lo8aTkavygHHsUHAlxQKKaDeyT0qyQNLKl7+UyqYH2dDF6UN/14873IPBHchcsU+Zg== + +"@tanstack/react-query@^5.81.5", "@tanstack/react-query@^5.82.0": + version "5.81.5" + resolved "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.81.5.tgz" + integrity sha512-lOf2KqRRiYWpQT86eeeftAGnjuTR35myTP8MXyvHa81VlomoAWNEd8x5vkcAfQefu0qtYCvyqLropFZqgI2EQw== + dependencies: + "@tanstack/query-core" "5.81.5" + +"@tanstack/react-query-devtools@^5.82.0": + version "5.82.0" + resolved "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.82.0.tgz" + integrity sha512-MC05Zq3zr/59jhgF7dL6JSGPg1krbasDSizmRxjNcvxgh/sUTwRFD9CGN10YYX7LB6jq0ZpFtCjSVGdLiFrKAA== + dependencies: + "@tanstack/query-devtools" "5.81.2" + +"@tybys/wasm-util@^0.9.0": + version "0.9.0" + resolved "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz" + integrity sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw== + dependencies: + tslib "^2.4.0" + +"@types/babel__core@^7.20.5": + version "7.20.5" + resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.8" + resolved "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.4" + resolved "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*": + version "7.20.5" + resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz" + integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== + dependencies: + "@babel/types" "^7.20.7" + +"@types/d3-color@*": + version "3.1.3" + resolved "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz" + integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== + +"@types/d3-drag@^3.0.7": + version "3.0.7" + resolved "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz" + integrity sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-interpolate@*", "@types/d3-interpolate@^3.0.4": + version "3.0.4" + resolved "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz" + integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA== + dependencies: + "@types/d3-color" "*" + +"@types/d3-selection@*", "@types/d3-selection@^3.0.10": + version "3.0.11" + resolved "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz" + integrity sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w== + +"@types/d3-transition@^3.0.8": + version "3.0.9" + resolved "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz" + integrity sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-zoom@^3.0.8": + version "3.0.8" + resolved "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz" + integrity sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw== + dependencies: + "@types/d3-interpolate" "*" + "@types/d3-selection" "*" + +"@types/estree@1.0.8": + version "1.0.8" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== + +"@types/json-schema@^7.0.12": + version "7.0.15" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/node@^20.19.0 || >=22.12.0", "@types/node@^22.15.23": + version "22.15.23" + resolved "https://registry.npmjs.org/@types/node/-/node-22.15.23.tgz" + integrity sha512-7Ec1zaFPF4RJ0eXu1YT/xgiebqwqoJz8rYPDi/O2BcZ++Wpt0Kq9cl0eg6NN6bYbPnR67ZLo7St5Q3UK0SnARw== + dependencies: + undici-types "~6.21.0" + +"@types/prop-types@*": + version "15.7.9" + resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.9.tgz" + integrity sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g== + +"@types/react@*", "@types/react@>=16.8", "@types/react@^18.2.53": + version "18.2.53" + resolved "https://registry.npmjs.org/@types/react/-/react-18.2.53.tgz" + integrity sha512-52IHsMDT8qATp9B9zoOyobW8W3/0QhaJQTw1HwRj0UY2yBpCAQ7+S/CqHYQ8niAm3p4ji+rWUQ9UCib0GxQ60w== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/react-dom@*", "@types/react-dom@^18.2.18": + version "18.2.18" + resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz" + integrity sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw== + dependencies: + "@types/react" "*" + +"@types/scheduler@*": + version "0.16.5" + resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.5.tgz" + integrity sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw== + +"@types/semver@^7.5.0": + version "7.5.6" + resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz" + integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== + +"@typescript-eslint/eslint-plugin@^6.20.0": + version "6.20.0" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.20.0.tgz" + integrity sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg== + dependencies: + "@eslint-community/regexpp" "^4.5.1" + "@typescript-eslint/scope-manager" "6.20.0" + "@typescript-eslint/type-utils" "6.20.0" + "@typescript-eslint/utils" "6.20.0" + "@typescript-eslint/visitor-keys" "6.20.0" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/parser@^6.0.0 || ^6.0.0-alpha", "@typescript-eslint/parser@^6.20.0": + version "6.20.0" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.20.0.tgz" + integrity sha512-bYerPDF/H5v6V76MdMYhjwmwgMA+jlPVqjSDq2cRqMi8bP5sR3Z+RLOiOMad3nsnmDVmn2gAFCyNgh/dIrfP/w== + dependencies: + "@typescript-eslint/scope-manager" "6.20.0" + "@typescript-eslint/types" "6.20.0" + "@typescript-eslint/typescript-estree" "6.20.0" + "@typescript-eslint/visitor-keys" "6.20.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@6.20.0": + version "6.20.0" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.20.0.tgz" + integrity sha512-p4rvHQRDTI1tGGMDFQm+GtxP1ZHyAh64WANVoyEcNMpaTFn3ox/3CcgtIlELnRfKzSs/DwYlDccJEtr3O6qBvA== + dependencies: + "@typescript-eslint/types" "6.20.0" + "@typescript-eslint/visitor-keys" "6.20.0" + +"@typescript-eslint/type-utils@6.20.0": + version "6.20.0" + resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.20.0.tgz" + integrity sha512-qnSobiJQb1F5JjN0YDRPHruQTrX7ICsmltXhkV536mp4idGAYrIyr47zF/JmkJtEcAVnIz4gUYJ7gOZa6SmN4g== + dependencies: + "@typescript-eslint/typescript-estree" "6.20.0" + "@typescript-eslint/utils" "6.20.0" + debug "^4.3.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/types@6.20.0": + version "6.20.0" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.20.0.tgz" + integrity sha512-MM9mfZMAhiN4cOEcUOEx+0HmuaW3WBfukBZPCfwSqFnQy0grXYtngKCqpQN339X3RrwtzspWJrpbrupKYUSBXQ== + +"@typescript-eslint/typescript-estree@6.20.0": + version "6.20.0" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.20.0.tgz" + integrity sha512-RnRya9q5m6YYSpBN7IzKu9FmLcYtErkDkc8/dKv81I9QiLLtVBHrjz+Ev/crAqgMNW2FCsoZF4g2QUylMnJz+g== + dependencies: + "@typescript-eslint/types" "6.20.0" + "@typescript-eslint/visitor-keys" "6.20.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "9.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/utils@6.20.0": + version "6.20.0" + resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.20.0.tgz" + integrity sha512-/EKuw+kRu2vAqCoDwDCBtDRU6CTKbUmwwI7SH7AashZ+W+7o8eiyy6V2cdOqN49KsTcASWsC5QeghYuRDTyOOg== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.20.0" + "@typescript-eslint/types" "6.20.0" + "@typescript-eslint/typescript-estree" "6.20.0" + semver "^7.5.4" + +"@typescript-eslint/visitor-keys@6.20.0": + version "6.20.0" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.20.0.tgz" + integrity sha512-E8Cp98kRe4gKHjJD4NExXKz/zOJ1A2hhZc+IMVD6i7w4yjIvh6VyuRI0gRtxAsXtoC35uGMaQ9rjI2zJaXDEAw== + dependencies: + "@typescript-eslint/types" "6.20.0" + eslint-visitor-keys "^3.4.1" + +"@ungap/structured-clone@^1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + +"@vitejs/plugin-react@^5.0.0": + version "5.0.2" + resolved "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.0.2.tgz" + integrity sha512-tmyFgixPZCx2+e6VO9TNITWcCQl8+Nl/E8YbAyPVv85QCc7/A3JrdfG2A8gIzvVhWuzMOVrFW1aReaNxrI6tbw== + dependencies: + "@babel/core" "^7.28.3" + "@babel/plugin-transform-react-jsx-self" "^7.27.1" + "@babel/plugin-transform-react-jsx-source" "^7.27.1" + "@rolldown/pluginutils" "1.0.0-beta.34" + "@types/babel__core" "^7.20.5" + react-refresh "^0.17.0" + +"@xyflow/react@^12.7.0": + version "12.7.0" + resolved "https://registry.npmjs.org/@xyflow/react/-/react-12.7.0.tgz" + integrity sha512-U6VMEbYjiCg1byHrR7S+b5ZdHTjgCFX4KpBc634G/WtEBUvBLoMQdlCD6uJHqodnOAxpt3+G2wiDeTmXAFJzgQ== + dependencies: + "@xyflow/system" "0.0.62" + classcat "^5.0.3" + zustand "^4.4.0" + +"@xyflow/system@0.0.62": + version "0.0.62" + resolved "https://registry.npmjs.org/@xyflow/system/-/system-0.0.62.tgz" + integrity sha512-Z2ufbnvuYxIOCGyzE/8eX8TAEM8Lpzc/JafjD1Tzy6ZJs/E7KGVU17Q1F5WDHVW+dbztJAdyXMG0ejR9bwSUAA== + dependencies: + "@types/d3-drag" "^3.0.7" + "@types/d3-interpolate" "^3.0.4" + "@types/d3-selection" "^3.0.10" + "@types/d3-transition" "^3.0.8" + "@types/d3-zoom" "^3.0.8" + d3-drag "^3.0.0" + d3-interpolate "^3.0.1" + d3-selection "^3.0.0" + d3-zoom "^3.0.0" + +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.9.0: + version "8.11.3" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +aria-hidden@^1.2.4: + version "1.2.6" + resolved "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz" + integrity sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA== + dependencies: + tslib "^2.0.0" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +"browserslist@>= 4.21.0", browserslist@^4.24.0: + version "4.25.1" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz" + integrity sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw== + dependencies: + caniuse-lite "^1.0.30001726" + electron-to-chromium "^1.5.173" + node-releases "^2.0.19" + update-browserslist-db "^1.1.3" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +caniuse-lite@^1.0.30001726: + version "1.0.30001731" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz" + integrity sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg== + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chownr@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz" + integrity sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g== + +class-variance-authority@^0.7.1: + version "0.7.1" + resolved "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz" + integrity sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg== + dependencies: + clsx "^2.1.1" + +classcat@^5.0.3: + version "5.0.5" + resolved "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz" + integrity sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w== + +clsx@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz" + integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +cookie@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz" + integrity sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA== + +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +csstype@^3.0.2: + version "3.1.2" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== + +"d3-color@1 - 3": + version "3.1.0" + resolved "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz" + integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== + +"d3-dispatch@1 - 3": + version "3.0.1" + resolved "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz" + integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg== + +"d3-drag@2 - 3", d3-drag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz" + integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg== + dependencies: + d3-dispatch "1 - 3" + d3-selection "3" + +"d3-ease@1 - 3": + version "3.0.1" + resolved "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz" + integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== + +"d3-interpolate@1 - 3", d3-interpolate@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz" + integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== + dependencies: + d3-color "1 - 3" + +"d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz" + integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== + +"d3-timer@1 - 3": + version "3.0.1" + resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz" + integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== + +"d3-transition@2 - 3": + version "3.0.1" + resolved "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz" + integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w== + dependencies: + d3-color "1 - 3" + d3-dispatch "1 - 3" + d3-ease "1 - 3" + d3-interpolate "1 - 3" + d3-timer "1 - 3" + +d3-zoom@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz" + integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw== + dependencies: + d3-dispatch "1 - 3" + d3-drag "2 - 3" + d3-interpolate "1 - 3" + d3-selection "2 - 3" + d3-transition "2 - 3" + +debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +detect-libc@^2.0.3, detect-libc@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz" + integrity sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA== + +detect-node-es@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz" + integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +electron-to-chromium@^1.5.173: + version "1.5.198" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.198.tgz" + integrity sha512-G5COfnp3w+ydVu80yprgWSfmfQaYRh9DOxfhAxstLyetKaLyl55QrNjx8C38Pc/C+RaDmb1M0Lk8wPEMQ+bGgQ== + +enhanced-resolve@^5.18.1: + version "5.18.1" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz" + integrity sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +esbuild@^0.25.0: + version "0.25.8" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz" + integrity sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q== + optionalDependencies: + "@esbuild/aix-ppc64" "0.25.8" + "@esbuild/android-arm" "0.25.8" + "@esbuild/android-arm64" "0.25.8" + "@esbuild/android-x64" "0.25.8" + "@esbuild/darwin-arm64" "0.25.8" + "@esbuild/darwin-x64" "0.25.8" + "@esbuild/freebsd-arm64" "0.25.8" + "@esbuild/freebsd-x64" "0.25.8" + "@esbuild/linux-arm" "0.25.8" + "@esbuild/linux-arm64" "0.25.8" + "@esbuild/linux-ia32" "0.25.8" + "@esbuild/linux-loong64" "0.25.8" + "@esbuild/linux-mips64el" "0.25.8" + "@esbuild/linux-ppc64" "0.25.8" + "@esbuild/linux-riscv64" "0.25.8" + "@esbuild/linux-s390x" "0.25.8" + "@esbuild/linux-x64" "0.25.8" + "@esbuild/netbsd-arm64" "0.25.8" + "@esbuild/netbsd-x64" "0.25.8" + "@esbuild/openbsd-arm64" "0.25.8" + "@esbuild/openbsd-x64" "0.25.8" + "@esbuild/openharmony-arm64" "0.25.8" + "@esbuild/sunos-x64" "0.25.8" + "@esbuild/win32-arm64" "0.25.8" + "@esbuild/win32-ia32" "0.25.8" + "@esbuild/win32-x64" "0.25.8" + +escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint@>=7, "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", eslint@^8.56.0: + version "8.56.0" + resolved "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz" + integrity sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.4" + "@eslint/js" "8.56.0" + "@humanwhocodes/config-array" "^0.11.13" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + "@ungap/structured-clone" "^1.2.0" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +eslint-plugin-react-hooks@^4.6.0: + version "4.6.0" + resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz" + integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== + +eslint-plugin-react-refresh@^0.4.5: + version "0.4.5" + resolved "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.5.tgz" + integrity sha512-D53FYKJa+fDmZMtriODxvhwrO+IOqrxoEo21gMA0sjHdU6dPVH4OhyFip9ypl8HOF5RV5KdTo+rBQLvnY2cO8w== + +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== + dependencies: + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.9: + version "3.3.2" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +fdir@^6.4.4, fdir@^6.4.6: + version "6.4.6" + resolved "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz" + integrity sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w== + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.1.1" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz" + integrity sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q== + dependencies: + flatted "^3.2.9" + keyv "^4.5.3" + rimraf "^3.0.2" + +flatted@^3.2.9: + version "3.2.9" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz" + integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +"gensync@^1.0.0-beta.2": + version "1.0.0-beta.2" + resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-nonce@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz" + integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +globals@^13.19.0: + version "13.23.0" + resolved "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz" + integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA== + dependencies: + type-fest "^0.20.2" + +globals@^13.19.0: + version "13.24.0" + resolved "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz" + integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== + dependencies: + type-fest "^0.20.2" + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +graceful-fs@^4.2.4: + version "4.2.11" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +ignore@^5.2.0, ignore@^5.2.4: + version "5.2.4" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +jiti@>=1.21.0, jiti@^2.4.2: + version "2.4.2" + resolved "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz" + integrity sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsesc@^3.0.2: + version "3.1.0" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz" + integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lightningcss@1.30.1, lightningcss@^1.21.0: + version "1.30.1" + resolved "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz" + integrity sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg== + optionalDependencies: + lightningcss-darwin-arm64 "1.30.1" + lightningcss-darwin-x64 "1.30.1" + lightningcss-freebsd-x64 "1.30.1" + lightningcss-linux-arm-gnueabihf "1.30.1" + lightningcss-linux-arm64-gnu "1.30.1" + lightningcss-linux-arm64-musl "1.30.1" + lightningcss-linux-x64-gnu "1.30.1" + lightningcss-linux-x64-musl "1.30.1" + lightningcss-win32-arm64-msvc "1.30.1" + lightningcss-win32-x64-msvc "1.30.1" + dependencies: + detect-libc "^2.0.3" + +lightningcss-darwin-arm64@1.30.1: + version "1.30.1" + resolved "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz" + integrity sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ== + +lightningcss-darwin-x64@1.30.1: + version "1.30.1" + resolved "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz" + integrity sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA== + +lightningcss-freebsd-x64@1.30.1: + version "1.30.1" + resolved "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz" + integrity sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig== + +lightningcss-linux-arm-gnueabihf@1.30.1: + version "1.30.1" + resolved "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz" + integrity sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q== + +lightningcss-linux-arm64-gnu@1.30.1: + version "1.30.1" + resolved "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz" + integrity sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw== + +lightningcss-linux-arm64-musl@1.30.1: + version "1.30.1" + resolved "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz" + integrity sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ== + +lightningcss-linux-x64-gnu@1.30.1: + version "1.30.1" + resolved "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz" + integrity sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw== + +lightningcss-linux-x64-musl@1.30.1: + version "1.30.1" + resolved "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz" + integrity sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ== + +lightningcss-win32-arm64-msvc@1.30.1: + version "1.30.1" + resolved "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz" + integrity sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA== + +lightningcss-win32-x64-msvc@1.30.1: + version "1.30.1" + resolved "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz" + integrity sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg== + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +loose-envify@^1.1.0: + version "1.4.0" + resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lucide-react@^0.511.0: + version "0.511.0" + resolved "https://registry.npmjs.org/lucide-react/-/lucide-react-0.511.0.tgz" + integrity sha512-VK5a2ydJ7xm8GvBeKLS9mu1pVK6ucef9780JVUjw6bAjJL/QXnd4Y0p7SPeOUMC27YhzNCZvm5d/QX0Tp3rc0w== + +magic-string@^0.30.17: + version "0.30.17" + resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz" + integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@9.0.3: + version "9.0.3" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + +minipass@^7.0.4, minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== + +minizlib@^3.0.1: + version "3.0.2" + resolved "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz" + integrity sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA== + dependencies: + minipass "^7.1.2" + +mkdirp@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz" + integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +nanoid@^3.3.11: + version "3.3.11" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz" + integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +node-releases@^2.0.19: + version "2.0.19" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz" + integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +"picomatch@^3 || ^4", picomatch@^4.0.2, picomatch@^4.0.3: + version "4.0.3" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz" + integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== + +postcss@^8.5.6: + version "8.5.6" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz" + integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== + dependencies: + nanoid "^3.3.11" + picocolors "^1.1.1" + source-map-js "^1.2.1" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +react@>=16.8, react@>=17, react@>=18, "react@^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react@^18 || ^19", react@^18.2.0: + version "18.2.0" + resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== + dependencies: + loose-envify "^1.1.0" + +react-dom@>=16.8.0, react-dom@>=17, react-dom@>=18, "react-dom@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", react-dom@^18.2.0: + version "18.2.0" + resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.0" + +react-refresh@^0.17.0: + version "0.17.0" + resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz" + integrity sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ== + +react-remove-scroll@^2.6.3: + version "2.7.0" + resolved "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.0.tgz" + integrity sha512-sGsQtcjMqdQyijAHytfGEELB8FufGbfXIsvUTe+NLx1GDRJCXtCFLBLUI1eyZCKXXvbEU2C6gai0PZKoIE9Vbg== + dependencies: + react-remove-scroll-bar "^2.3.7" + react-style-singleton "^2.2.3" + tslib "^2.1.0" + use-callback-ref "^1.3.3" + use-sidecar "^1.1.3" + +react-remove-scroll-bar@^2.3.7: + version "2.3.8" + resolved "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz" + integrity sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q== + dependencies: + react-style-singleton "^2.2.2" + tslib "^2.0.0" + +react-router@^7.6.2: + version "7.6.2" + resolved "https://registry.npmjs.org/react-router/-/react-router-7.6.2.tgz" + integrity sha512-U7Nv3y+bMimgWjhlT5CRdzHPu2/KVmqPwKUCChW8en5P3znxUqwlYFlbmyj8Rgp1SF6zs5X4+77kBVknkg6a0w== + dependencies: + cookie "^1.0.1" + set-cookie-parser "^2.6.0" + +react-style-singleton@^2.2.2, react-style-singleton@^2.2.3: + version "2.2.3" + resolved "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz" + integrity sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ== + dependencies: + get-nonce "^1.0.0" + tslib "^2.0.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rollup@^4.43.0: + version "4.46.2" + resolved "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz" + integrity sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg== + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.46.2" + "@rollup/rollup-android-arm64" "4.46.2" + "@rollup/rollup-darwin-arm64" "4.46.2" + "@rollup/rollup-darwin-x64" "4.46.2" + "@rollup/rollup-freebsd-arm64" "4.46.2" + "@rollup/rollup-freebsd-x64" "4.46.2" + "@rollup/rollup-linux-arm-gnueabihf" "4.46.2" + "@rollup/rollup-linux-arm-musleabihf" "4.46.2" + "@rollup/rollup-linux-arm64-gnu" "4.46.2" + "@rollup/rollup-linux-arm64-musl" "4.46.2" + "@rollup/rollup-linux-loongarch64-gnu" "4.46.2" + "@rollup/rollup-linux-ppc64-gnu" "4.46.2" + "@rollup/rollup-linux-riscv64-gnu" "4.46.2" + "@rollup/rollup-linux-riscv64-musl" "4.46.2" + "@rollup/rollup-linux-s390x-gnu" "4.46.2" + "@rollup/rollup-linux-x64-gnu" "4.46.2" + "@rollup/rollup-linux-x64-musl" "4.46.2" + "@rollup/rollup-win32-arm64-msvc" "4.46.2" + "@rollup/rollup-win32-ia32-msvc" "4.46.2" + "@rollup/rollup-win32-x64-msvc" "4.46.2" + fsevents "~2.3.2" + dependencies: + "@types/estree" "1.0.8" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== + dependencies: + loose-envify "^1.1.0" + +semver@^6.3.1: + version "6.3.1" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.5.4: + version "7.5.4" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +set-cookie-parser@^2.6.0: + version "2.7.1" + resolved "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz" + integrity sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +tailwind-merge@^3.3.0: + version "3.3.0" + resolved "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.0.tgz" + integrity sha512-fyW/pEfcQSiigd5SNn0nApUOxx0zB/dm6UDU/rEwc2c3sX2smWUNbapHv+QRqLGVp9GWX3THIa7MUGPo+YkDzQ== + +tailwindcss@4.1.7: + version "4.1.7" + resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.7.tgz" + integrity sha512-kr1o/ErIdNhTz8uzAYL7TpaUuzKIE6QPQ4qmSdxnoX/lo+5wmUHQA6h3L5yIqEImSRnAAURDirLu/BgiXGPAhg== + +tapable@^2.2.0: + version "2.2.2" + resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz" + integrity sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg== + +tar@^7.4.3: + version "7.4.3" + resolved "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz" + integrity sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw== + dependencies: + "@isaacs/fs-minipass" "^4.0.0" + chownr "^3.0.0" + minipass "^7.1.2" + minizlib "^3.0.1" + mkdirp "^3.0.1" + yallist "^5.0.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +tinyglobby@^0.2.14: + version "0.2.14" + resolved "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz" + integrity sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ== + dependencies: + fdir "^6.4.4" + picomatch "^4.0.2" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +ts-api-utils@^1.0.1: + version "1.0.3" + resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz" + integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== + +tslib@^2.0.0, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.8.0: + version "2.8.1" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + +tw-animate-css@^1.3.5: + version "1.3.5" + resolved "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.3.5.tgz" + integrity sha512-t3u+0YNoloIhj1mMXs779P6MO9q3p3mvGn4k1n3nJPqJw/glZcuijG2qTSN4z4mgNRfW5ZC3aXJFLwDtiipZXA== + +type-check@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +typescript@>=4.2.0, typescript@^5.3.3: + version "5.3.3" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz" + integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== + +undici-types@~6.21.0: + version "6.21.0" + resolved "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz" + integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== + +update-browserslist-db@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz" + integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== + dependencies: + escalade "^3.2.0" + picocolors "^1.1.1" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +use-callback-ref@^1.3.3: + version "1.3.3" + resolved "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz" + integrity sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg== + dependencies: + tslib "^2.0.0" + +use-sidecar@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz" + integrity sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ== + dependencies: + detect-node-es "^1.1.0" + tslib "^2.0.0" + +use-sync-external-store@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== + +"vite@^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", "vite@^5.2.0 || ^6", vite@^7.1.0: + version "7.1.0" + resolved "https://registry.npmjs.org/vite/-/vite-7.1.0.tgz" + integrity sha512-3jdAy3NhBJYsa/lCFcnRfbK4kNkO/bhijFCnv5ByUQk/eekYagoV2yQSISUrhpV+5JiY5hmwOh7jNnQ68dFMuQ== + optionalDependencies: + fsevents "~2.3.3" + dependencies: + esbuild "^0.25.0" + fdir "^6.4.6" + picomatch "^4.0.3" + postcss "^8.5.6" + rollup "^4.43.0" + tinyglobby "^0.2.14" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yallist@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz" + integrity sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zustand@^4.4.0: + version "4.5.2" + resolved "https://registry.npmjs.org/zustand/-/zustand-4.5.2.tgz" + integrity sha512-2cN1tPkDVkwCy5ickKrI7vijSjPksFRfqS6237NzT0vqSsztTNnQdHw9mmN7uBdk3gceVXU0a+21jFzFzAc9+g== + dependencies: + use-sync-external-store "1.2.0" diff --git a/tierkreis_visualization/tierkreis_visualization/data/eval.py b/tierkreis_visualization/tierkreis_visualization/data/eval.py index e6e80afd0..71f312503 100644 --- a/tierkreis_visualization/tierkreis_visualization/data/eval.py +++ b/tierkreis_visualization/tierkreis_visualization/data/eval.py @@ -85,6 +85,8 @@ def get_eval_node( definition = None status = node_status(is_finished, definition, has_error) + started_time = storage.read_started_time(new_location) or "" + finished_time = storage.read_finished_time(new_location) or "" value: str | None = None match node.type: case "function": @@ -92,7 +94,7 @@ def get_eval_node( case "ifelse": name = node.type add_conditional_edges(storage, node_location, i, node, py_edges) - case "map" | "eval" | "input" | "loop" | "eifelse": + case "map" | "eval" | "loop" | "eifelse": name = node.type case "const": name = node.type @@ -105,6 +107,9 @@ def get_eval_node( value = json.loads(storage.read_output(node_location.N(idx), p)) except (FileNotFoundError, TierkreisError): value = None + case "input": + name = node.type + value = node.name case _: assert_never(node) @@ -114,6 +119,8 @@ def get_eval_node( function_name=name, node_location=new_location, value=value, + started_time=started_time, + finished_time=finished_time, ) pynodes.append(pynode) diff --git a/tierkreis_visualization/tierkreis_visualization/data/loop.py b/tierkreis_visualization/tierkreis_visualization/data/loop.py index 06bcd4775..6007d00c2 100644 --- a/tierkreis_visualization/tierkreis_visualization/data/loop.py +++ b/tierkreis_visualization/tierkreis_visualization/data/loop.py @@ -27,6 +27,8 @@ def get_loop_node( status="Finished", function_name=f"L{n}", node_location=node_location.L(n), + started_time=storage.read_started_time(node_location.L(n)) or "", + finished_time=storage.read_finished_time(node_location.L(n)) or "", ) for n in range(i) ] @@ -39,7 +41,12 @@ def get_loop_node( last_status = "Started" nodes.append( PyNode( - id=i, status=last_status, function_name=f"L{i}", node_location=new_location + id=i, + status=last_status, + function_name=f"L{i}", + node_location=new_location, + started_time=storage.read_started_time(new_location) or "", + finished_time=storage.read_finished_time(new_location) or "", ) ) edges = [] diff --git a/tierkreis_visualization/tierkreis_visualization/data/map.py b/tierkreis_visualization/tierkreis_visualization/data/map.py index b77a1eb66..94cb2bb75 100644 --- a/tierkreis_visualization/tierkreis_visualization/data/map.py +++ b/tierkreis_visualization/tierkreis_visualization/data/map.py @@ -24,7 +24,14 @@ def get_map_node( map_eles = outputs_iter(storage, parent.N(first_ref[0])) nodes: list[PyNode] = [] for i, ele in map_eles: - node = PyNode(id=i, status="Started", function_name=ele, node_location=loc.M(i)) + node = PyNode( + id=i, + status="Started", + function_name=ele, + node_location=loc.M(i), + started_time=storage.read_started_time(loc.M(i)) or "", + finished_time=storage.read_finished_time(loc.M(i)) or "", + ) if check_error(loc.M(i), errored_nodes): node.status = "Error" elif storage.is_node_finished(loc.M(i)): diff --git a/tierkreis_visualization/tierkreis_visualization/data/models.py b/tierkreis_visualization/tierkreis_visualization/data/models.py index 0e7d0be28..36750d8d2 100644 --- a/tierkreis_visualization/tierkreis_visualization/data/models.py +++ b/tierkreis_visualization/tierkreis_visualization/data/models.py @@ -10,6 +10,8 @@ class PyNode(BaseModel): function_name: str node_location: str = "" value: Any | None = None + started_time: str + finished_time: str class PyEdge(BaseModel): diff --git a/tierkreis_visualization/tierkreis_visualization/routers/workflows.py b/tierkreis_visualization/tierkreis_visualization/routers/workflows.py index 08e3f3b9f..e9674fe96 100644 --- a/tierkreis_visualization/tierkreis_visualization/routers/workflows.py +++ b/tierkreis_visualization/tierkreis_visualization/routers/workflows.py @@ -3,7 +3,7 @@ from typing import Any, assert_never from uuid import UUID -from fastapi import APIRouter, Request +from fastapi import APIRouter, Request, status from fastapi.responses import StreamingResponse from pydantic import BaseModel from starlette.responses import JSONResponse, PlainTextResponse @@ -70,8 +70,16 @@ def list_workflows(request: Request): @router.get("/all") def list_all_workflows(request: Request): storage_type = request.app.state.storage_type - workflows = get_workflows(storage_type) - return JSONResponse([workflow.model_dump(mode="json") for workflow in workflows]) + try: + workflows = get_workflows(storage_type) + return JSONResponse( + [workflow.model_dump(mode="json") for workflow in workflows] + ) + except FileNotFoundError: + return JSONResponse( + "Workflow not found, make sure the workflow exists in the workflow directory.", + status_code=status.HTTP_404_NOT_FOUND, + ) class NodeResponse(BaseModel):