From 8d968a3315dccc095e14f732f2888519866d7169 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 7 Nov 2022 13:26:46 +0100 Subject: [PATCH 01/22] Fix: Fix multiple maps issue (#33) --- src/views/map-view.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/views/map-view.ts b/src/views/map-view.ts index efd3e6d..24a6269 100644 --- a/src/views/map-view.ts +++ b/src/views/map-view.ts @@ -30,9 +30,11 @@ const osmAttribution = 'Leaflet | ' + 'Map data © OpenStreetMap contributors'; -const DEFAULT_MAP_TILE: ILeafletMapTile = { - instance: new L.TileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'), - attribution: osmAttribution, +const getDefaultMapTile = () => { + return { + instance: new L.TileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'), + attribution: osmAttribution, + }; }; const DEFAULT_ZOOM_LEVEL = 2; @@ -82,7 +84,7 @@ export class MapView implements IOrbVi ...settings, map: { zoomLevel: settings.map?.zoomLevel ?? DEFAULT_ZOOM_LEVEL, - tile: settings.map?.tile ?? DEFAULT_MAP_TILE, + tile: settings.map?.tile ?? getDefaultMapTile(), }, render: { type: RendererType.CANVAS, From 60d0721e68ec90ad92c2417de283536218ff602d Mon Sep 17 00:00:00 2001 From: Toni Lastre Date: Mon, 7 Nov 2022 13:28:20 +0100 Subject: [PATCH 02/22] Chore: Update package.json version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cc1d340..70928e0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@memgraph/orb", - "version": "0.1.4", + "version": "0.2.0", "description": "Graph visualization library", "engines": { "node": ">=16.0.0" From ab9ba316cee355f8683d92dfc437c9d415181898 Mon Sep 17 00:00:00 2001 From: Toni Date: Wed, 9 Nov 2022 17:23:44 +0100 Subject: [PATCH 03/22] New: Change the API to handle OrbView and OrbMapView (#34) * New: Change the API to handle OrbView and OrbMapView * New: Change the API for select/hover strategies --- README.md | 14 +- docs/data.md | 20 +- docs/events.md | 90 ++++---- docs/styles.md | 36 ++-- docs/view-default.md | 146 ++++++++----- docs/view-map.md | 163 ++++++++++----- examples/example-custom-styled-graph.html | 6 +- examples/example-fixed-coordinates-graph.html | 9 +- examples/example-graph-data-changes.html | 10 +- examples/example-graph-events.html | 6 +- examples/example-graph-on-map.html | 9 +- examples/example-simple-graph.html | 6 +- examples/playground.html | 111 ++++++---- examples/simulator-scenarios.html | 47 +++-- src/events.ts | 87 +++++--- src/index.ts | 28 ++- src/models/strategy.ts | 51 +++-- src/orb.ts | 71 ------- src/views/index.ts | 6 +- src/views/{map-view.ts => orb-map-view.ts} | 193 +++++++++++------- src/views/{default-view.ts => orb-view.ts} | 190 ++++++++++------- src/views/shared.ts | 17 +- 22 files changed, 752 insertions(+), 564 deletions(-) delete mode 100644 src/orb.ts rename src/views/{map-view.ts => orb-map-view.ts} (65%) rename src/views/{default-view.ts => orb-view.ts} (73%) diff --git a/README.md b/README.md index f7c4b2f..0043168 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Below you can find a simple Typescript example using Orb to visualize a small gr free to check other Javascript examples in `examples/` directory. ```typescript -import { Orb } from '@memgraph/orb'; +import { OrbView } from '@memgraph/orb'; const container = document.getElementById('graph'); const nodes: MyNode[] = [ @@ -56,14 +56,14 @@ const edges: MyEdge[] = [ { id: 2, start: 2, end: 3, label: 'ON' }, ]; -const orb = new Orb(container); +const orb = new OrbView(container); // Initialize nodes and edges orb.data.setup({ nodes, edges }); // Render and recenter the view -orb.view.render(() => { - orb.view.recenter(); +orb.render(() => { + orb.recenter(); }); ``` @@ -118,14 +118,14 @@ free to check other Javascript examples in `examples/` directory. ]; // First `Orb` is just a namespace of the JS package - const orb = new Orb.Orb(container); + const orb = new Orb.OrbView(container); // Initialize nodes and edges orb.data.setup({ nodes, edges }); // Render and recenter the view - orb.view.render(() => { - orb.view.recenter(); + orb.render(() => { + orb.recenter(); }); diff --git a/docs/data.md b/docs/data.md index d0c15c5..f694692 100644 --- a/docs/data.md +++ b/docs/data.md @@ -15,7 +15,9 @@ To initialize graph data structure use `orb.data.setup` function that receives ` `edges`. Here is a simple example of it: ```typescript -const orb = new Orb(container); +import { OrbView } from "@memgraph/orb"; + +const orb = new OrbView(container); const nodes: MyNode[] = [ { id: 0, text: "Node A", myField: 12 }, @@ -65,7 +67,9 @@ There are some useful node functions that you can use such as: Check the example to get to know node handling better: ```typescript -const orb = new Orb(container); +import { OrbView } from "@memgraph/orb"; + +const orb = new OrbView(container); const nodes: MyNode[] = [ { id: 0, text: "Node A", myField: 12 }, @@ -116,7 +120,9 @@ There are some useful node functions that you can use such as: Check the example to get to know edge handling better: ```typescript -const orb = new Orb(container); +import { OrbView } from "@memgraph/orb"; + +const orb = new OrbView(container); const nodes: MyNode[] = [ { id: 0, text: "Node A", myField: 12 }, @@ -148,7 +154,9 @@ ones. An update of a node or edge will happen if a node or edge with the same un exists in the graph structure. Check the example below: ```typescript -const orb = new Orb(container); +import { OrbView } from "@memgraph/orb"; + +const orb = new OrbView(container); const nodes: MyNode[] = [ { id: 0, text: "Node A", myField: 12 }, @@ -191,7 +199,9 @@ To remove nodes or edges from a graph, you just need the `id`. Removing a node w remove all inbound and outbound edges to that node. Removing an edge will just remove that edge. ```typescript -const orb = new Orb(container); +import { OrbView } from "@memgraph/orb"; + +const orb = new OrbView(container); const nodes: MyNode[] = [ { id: 0, text: "Node A" }, diff --git a/docs/events.md b/docs/events.md index af5bff4..996395a 100644 --- a/docs/events.md +++ b/docs/events.md @@ -75,9 +75,9 @@ Event data for `OrbEventType.RENDER_START` is undefined. Event is emitted on each render call after the renderer completes drawing the graph on canvas. ```typescript -import { OrbEventType } from '@memgraph/orb'; +import { OrbEventType, IOrbEventRenderEnd } from '@memgraph/orb'; -orb.events.on(OrbEventType.RENDER_END, (event) => { +orb.events.on(OrbEventType.RENDER_END, (event: IOrbEventRenderEnd) => { console.log(`Render ended in ${event.durationMs} ms`); }); ``` @@ -85,7 +85,7 @@ orb.events.on(OrbEventType.RENDER_END, (event) => { Event data for `OrbEventType.RENDER_END` has the following properties: ```typescript -interface Event { +interface IOrbEventRenderEnd { durationMs: number; } ``` @@ -116,9 +116,9 @@ Event `OrbEventType.SIMULATION_STEP` is emitted on each simulation step. `d3` si node positioning in iterations where each iteration is one simulation step. ```typescript -import { OrbEventType } from '@memgraph/orb'; +import { OrbEventType, IOrbEventSimulationStep } from '@memgraph/orb'; -orb.events.on(OrbEventType.SIMULATION_STEP, (event) => { +orb.events.on(OrbEventType.SIMULATION_STEP, (event: IOrbEventSimulationStep) => { console.log(`Simulation progress: ${event.progress}`); // If you want to see each step of the simulation, add render here orb.view.render(); @@ -128,7 +128,7 @@ orb.events.on(OrbEventType.SIMULATION_STEP, (event) => { Event data for `OrbEventType.SIMULATION_STEP` has the following properties: ```typescript -interface Event { +interface IOrbEventSimulationStep { progress: number; } ``` @@ -138,9 +138,9 @@ interface Event { Event `OrbEventType.SIMULATION_END` is emitted once the simulator ends with the final node positions. ```typescript -import { OrbEventType } from '@memgraph/orb'; +import { OrbEventType, IOrbEventSimulationEnd } from '@memgraph/orb'; -orb.events.on(OrbEventType.SIMULATION_END, (event) => { +orb.events.on(OrbEventType.SIMULATION_END, (event: IOrbEventSimulationEnd) => { console.log(`Simulation ended in ${event.durationMs} ms`); }); ``` @@ -148,7 +148,7 @@ orb.events.on(OrbEventType.SIMULATION_END, (event) => { Event data for `OrbEventType.SIMULATION_END` has the following properties: ```typescript -interface Event { +interface IOrbEventSimulationEnd { durationMs: number; } ``` @@ -161,9 +161,9 @@ Event is emitted on mouse click that selects the node. The event `OrbEventType.M triggered. ```typescript -import { OrbEventType } from '@memgraph/orb'; +import { OrbEventType, IOrbEventNodeClick } from '@memgraph/orb'; -orb.events.on(OrbEventType.NODE_CLICK, (event) => { +orb.events.on(OrbEventType.NODE_CLICK, (event: IOrbEventNodeClick) => { console.log(`Node clicked`, event.node); }); ``` @@ -171,7 +171,7 @@ orb.events.on(OrbEventType.NODE_CLICK, (event) => { Event data for `OrbEventType.NODE_CLICK` has the following properties: ```typescript -interface Event { +interface IOrbEventNodeClick { node: INode; event: PointerEvent; localPoint: { x: number; y: number }; @@ -188,9 +188,9 @@ Event is emitted on mouse move that hovers the node. The event `OrbEventType.MOU triggered. ```typescript -import { OrbEventType } from '@memgraph/orb'; +import { OrbEventType, IOrbEventNodeHover } from '@memgraph/orb'; -orb.events.on(OrbEventType.NODE_HOVER, (event) => { +orb.events.on(OrbEventType.NODE_HOVER, (event: IOrbEventNodeHover) => { console.log(`Node hovered`, event.node); }); ``` @@ -198,7 +198,7 @@ orb.events.on(OrbEventType.NODE_HOVER, (event) => { Event data for `OrbEventType.NODE_HOVER` has the following properties: ```typescript -interface Event { +interface IOrbEventNodeHover { node: INode; event: MouseEvent; localPoint: { x: number; y: number }; @@ -215,9 +215,9 @@ Event is emitted on mouse click that selects the edge. The event `OrbEventType.M triggered. ```typescript -import { OrbEventType } from '@memgraph/orb'; +import { OrbEventType, IOrbEventEdgeClick } from '@memgraph/orb'; -orb.events.on(OrbEventType.EDGE_CLICK, (event) => { +orb.events.on(OrbEventType.EDGE_CLICK, (event: IOrbEventEdgeClick) => { console.log(`Edge clicked`, event.edge); }); ``` @@ -225,7 +225,7 @@ orb.events.on(OrbEventType.EDGE_CLICK, (event) => { Event data for `OrbEventType.EDGE_CLICK` has the following properties: ```typescript -interface Event { +interface IOrbEventEdgeClick { edge: IEdge; event: PointerEvent; localPoint: { x: number; y: number }; @@ -245,9 +245,9 @@ triggered. > the distance to the closest edge to hover it. ```typescript -import { OrbEventType } from '@memgraph/orb'; +import { OrbEventType, IOrbEventEdgeHover } from '@memgraph/orb'; -orb.events.on(OrbEventType.EDGE_HOVER, (event) => { +orb.events.on(OrbEventType.EDGE_HOVER, (event: IOrbEventEdgeHover) => { console.log(`Edge hovered`, event.node); }); ``` @@ -255,7 +255,7 @@ orb.events.on(OrbEventType.EDGE_HOVER, (event) => { Event data for `OrbEventType.EDGE_HOVER` has the following properties: ```typescript -interface Event { +interface IOrbEventEdgeHover { edge: IEdge; event: MouseEvent; localPoint: { x: number; y: number }; @@ -273,9 +273,9 @@ edge) at the mouse click position, `OrbEventType.NODE_CLICK` and `OrbEventType.E will be triggered too. ```typescript -import { OrbEventType } from '@memgraph/orb'; +import { OrbEventType, IOrbEventMouseClick } from '@memgraph/orb'; -orb.events.on(OrbEventType.MOUSE_CLICK, (event) => { +orb.events.on(OrbEventType.MOUSE_CLICK, (event: IOrbEventMouseClick) => { console.log(`Mouse clicked`, event); }); ``` @@ -283,7 +283,7 @@ orb.events.on(OrbEventType.MOUSE_CLICK, (event) => { Event data for `OrbEventType.MOUSE_CLICK` has the following properties: ```typescript -interface Event { +interface IOrbEventMouseClick { subject?: INode | IEdge; event: PointerEvent; localPoint: { x: number; y: number }; @@ -299,9 +299,9 @@ the events `OrbEventType.NODE_CLICK` and `OrbEventType.EDGE_CLICK`. If you need to check if `subject` is a `INode` or `IEdge` use type check functions from orb: ```typescript -import { isNode, isEdge, OrbEventType } from '@memgraph/orb'; +import { isNode, isEdge, OrbEventType, IOrbEventMouseClick } from '@memgraph/orb'; -orb.events.on(OrbEventType.MOUSE_CLICK, (event) => { +orb.events.on(OrbEventType.MOUSE_CLICK, (event: IOrbEventMouseClick) => { if (event.subject && isNode(event.subject)) { console.log(`Mouse clicked on top of the node`, event.subject); } @@ -318,7 +318,9 @@ edge) at the mouse position, `OrbEventType.NODE_HOVER` and `OrbEventType.EDGE_HO be triggered too. ```typescript -orb.events.on(OrbEventType.MOUSE_MOVE, (event) => { +import { OrbEventType, IOrbEventMouseMove } from '@memgraph/orb'; + +orb.events.on(OrbEventType.MOUSE_MOVE, (event: IOrbEventMouseMove) => { console.log(`Mouse moved`, event); }); ``` @@ -326,7 +328,7 @@ orb.events.on(OrbEventType.MOUSE_MOVE, (event) => { Event data for `OrbEventType.MOUSE_MOVE` has the following properties: ```typescript -interface Event { +interface IOrbEventMouseMove { subject?: INode | IEdge; event: MouseEvent; localPoint: { x: number; y: number }; @@ -342,9 +344,9 @@ events `OrbEventType.NODE_CLICK` and `OrbEventType.EDGE_CLICK`. If you need to check if `subject` is a `INode` or `IEdge` use type check functions from orb: ```typescript -import { isNode, isEdge, OrbEventType } from '@memgraph/orb'; +import { isNode, isEdge, OrbEventType, IOrbEventMouseMove } from '@memgraph/orb'; -orb.events.on(OrbEventType.MOUSE_MOVE, (event) => { +orb.events.on(OrbEventType.MOUSE_MOVE, (event: IOrbEventMouseMove) => { if (event.subject && isNode(event.subject)) { console.log(`Mouse moved over the node`, event.subject); } @@ -361,9 +363,9 @@ orb.events.on(OrbEventType.MOUSE_MOVE, (event) => { Event is emitted on any zoom or pan event. ```typescript -import { OrbEventType } from '@memgraph/orb'; +import { OrbEventType, IOrbEventTransform } from '@memgraph/orb'; -orb.events.on(OrbEventType.TRANSFORM, (event) => { +orb.events.on(OrbEventType.TRANSFORM, (event: IOrbEventTransform) => { console.log(`Zoom or pan event`, event); }); ``` @@ -371,12 +373,12 @@ orb.events.on(OrbEventType.TRANSFORM, (event) => { Event data for `OrbEventType.TRANSFORM` has the following properties: ```typescript -interface Event { +interface IOrbEventTransform { transform: { x: number; y: number, k: number }; } ``` -Properties `x` and `y` are translation coordinates while `k` stands for zoom scale. If `DefaultView` +Properties `x` and `y` are translation coordinates while `k` stands for zoom scale. If `OrbView` is used, `transform` data is actually same as `ZoomTransform` type from `d3` library. ## Node dragging events @@ -384,7 +386,7 @@ is used, `transform` data is actually same as `ZoomTransform` type from `d3` lib Node dragging events are events that are emitted on node dragging which starts with a mouse click and hold, mouse movement, and ends with mouse click release. -> Note: Node dragging events might not be enabled on some views, e.g. `MapView` which currently +> Note: Node dragging events might not be enabled on some views, e.g. `OrbMapView` which currently > has a fixed position for each node by `latitude` and `longitude` values. ### Event `OrbEventType.NODE_DRAG_START` @@ -395,9 +397,9 @@ and `OrbEventType.MOUSE_CLICK`. If you want to listen just for drag then combine with `OrbEventType.NODE_DRAG_(START|END)`. ```typescript -import { OrbEventType } from '@memgraph/orb'; +import { OrbEventType, IOrbEventNodeDragStart } from '@memgraph/orb'; -orb.events.on(OrbEventType.NODE_DRAG_START, (event) => { +orb.events.on(OrbEventType.NODE_DRAG_START, (event: IOrbEventNodeDragStart) => { console.log(`Node drag started`, event); }); ``` @@ -405,7 +407,7 @@ orb.events.on(OrbEventType.NODE_DRAG_START, (event) => { Event data for `OrbEventType.NODE_DRAG_START` has the following properties: ```typescript -interface Event { +interface IOrbEventNodeDragStart { node: INode; event: MouseEvent; localPoint: { x: number; y: number }; @@ -422,9 +424,9 @@ Event is emitted on every mouse movement which is dragging a node with it. Event will also be triggered. ```typescript -import { OrbEventType } from '@memgraph/orb'; +import { OrbEventType, IOrbEventNodeDrag } from '@memgraph/orb'; -orb.events.on(OrbEventType.NODE_DRAG, (event) => { +orb.events.on(OrbEventType.NODE_DRAG, (event: IOrbEventNodeDrag) => { console.log(`Node dragged`, event); }); ``` @@ -432,7 +434,7 @@ orb.events.on(OrbEventType.NODE_DRAG, (event) => { Event data for `OrbEventType.NODE_DRAG` has the following properties: ```typescript -interface Event { +interface IOrbEventNodeDrag { node: INode; event: MouseEvent; localPoint: { x: number; y: number }; @@ -451,9 +453,9 @@ and `OrbEventType.MOUSE_CLICK`. If you want to listen just for drag then combine with `OrbEventType.NODE_DRAG_(START|END)`. ```typescript -import { OrbEventType } from '@memgraph/orb'; +import { OrbEventType, IOrbEventNodeDragEnd } from '@memgraph/orb'; -orb.events.on(OrbEventType.NODE_DRAG_END, (event) => { +orb.events.on(OrbEventType.NODE_DRAG_END, (event: IOrbEventNodeDragEnd) => { console.log(`Node drag ended`, event); }); ``` @@ -461,7 +463,7 @@ orb.events.on(OrbEventType.NODE_DRAG_END, (event) => { Event data for `OrbEventType.NODE_DRAG_END` has the following properties: ```typescript -interface Event { +interface IOrbEventNodeDragEnd { node: INode; event: MouseEvent; localPoint: { x: number; y: number }; diff --git a/docs/styles.md b/docs/styles.md index 98358d6..83648cf 100644 --- a/docs/styles.md +++ b/docs/styles.md @@ -84,13 +84,16 @@ const DEFAULT_NODE_STYLE: INodeStyle = { > below: ```typescript +import { OrbView } from "@memgraph/orb"; + const nodes: MyNode[] = [ { id: 1, name: "First" }, { id: 1, name: "Second" }, ]; -const orb = new Orb(container); -orb.setDefaultStyle({ +const orb = new OrbView(container); + +orb.data.setDefaultStyle({ getNodeStyle: (node) => { return { ...node.style, @@ -98,6 +101,7 @@ orb.setDefaultStyle({ }; }, }); + orb.data.setup({ nodes }); ``` @@ -269,9 +273,9 @@ node (`INode`) or edge (`IEdge`) object. Using those objects, you can change the any time: ```typescript -import { OrbEventType } from '@memgraph/orb'; +import { OrbView, OrbEventType } from '@memgraph/orb'; -const orb = new Orb(container); +const orb = new OrbView(container); orb.data.setup({ nodes, edges }); const node = orb.data.getNodeById(0); @@ -308,16 +312,18 @@ without setting `(node|edge).style.label = ""` or `(node|edge).style.fontSize = each node/edge, you can use the view settings to enable/disable labels globally: ```typescript +import { OrbView } from '@memgraph/orb'; + // Change on view init -orb.setView((context) => new DefaultView(context, { +const orb = new OrbView(container, { render: { labelsIsEnabled: true, labelsOnEventIsEnabled: true, }, -})); +}); // Change anytime for the current view -orb.view.setSettings({ +orb.setSettings({ render: { labelsIsEnabled: true, labelsOnEventIsEnabled: true, @@ -336,16 +342,18 @@ for the large number of nodes/edges. To simplify the way to disable/enable shado whole graph you can use the view settings to enable/disable shadows globally: ```typescript +import { OrbView } from '@memgraph/orb'; + // Change on view init -orb.setView((context) => new DefaultView(context, { +const orb = new OrbView(container, { render: { shadowsIsEnabled: true, shadowsOnEventIsEnabled: true, }, -})); +}); // Change anytime for the current view -orb.view.setSettings({ +orb.setSettings({ render: { shadowsIsEnabled: true, shadowsOnEventIsEnabled: true, @@ -371,16 +379,18 @@ You can configure the transparency with the following two properties: The default is `true`. ```typescript +import { OrbView } from '@memgraph/orb'; + // Change on view init -orb.setView((context) => new DefaultView(context, { +const orb = new OrbView(container, { render: { contextAlphaOnEvent: 0.3, contextAlphaOnEventIsEnabled: true, }, -})); +}); // Change anytime for the current view -orb.view.setSettings({ +orb.setSettings({ render: { contextAlphaOnEvent: 0.3, contextAlphaOnEventIsEnabled: true, diff --git a/docs/view-default.md b/docs/view-default.md index ddf9171..6f2be30 100644 --- a/docs/view-default.md +++ b/docs/view-default.md @@ -4,26 +4,20 @@ This is the default view that Orb uses to render a basic graph. ## Initialization -The `DefaultView` is assigned to every instance of Orb by default. You don't need to -provide any additional configuration to use it. - -You can, however, explicitly provide it in the factory function as you would any -other type of `IOrbView`. This will be necessary if you want to assign fixed node -coordinates, which you can read about further below. +The `OrbView` doesn't need any additional configuration. You can, however, explicitly provide +if you want to assign fixed node coordinates, which you can read about further below. ```typescript -import { DefaultView } from "@memgraph/orb"; - -const orb = new Orb(container); +import { OrbView } from "@memgraph/orb"; -orb.setView((context) => new DefaultView(context, optionalSettings)); +const orb = new OrbView(container, optionalSettings); ``` -You can set settings on view initialization or afterward with `orb.view.setSettings`. Below +You can set settings on view initialization or afterward with `orb.setSettings`. Below you can see the list of all settings' parameters: ```typescript -interface IDefaultViewSettings { +interface IOrbViewSettings { // For custom node positions getPosition(node: INode): { x: number; y: number } | undefined; // For node positioning simulation (d3-force parameters) @@ -80,6 +74,11 @@ interface IDefaultViewSettings { contextAlphaOnEvent: number; contextAlphaOnEventIsEnabled: boolean; }; + // For select and hover look-and-feel + strategy: { + isDefaultSelectEnabled: boolean; + isDefaultHoverEnabled: boolean; + }; // Other default view parameters zoomFitTransitionMs: number; isOutOfBoundsDragEnabled: boolean; @@ -89,7 +88,7 @@ interface IDefaultViewSettings { } ``` -The default settings that `DefaultView` uses is: +The default settings that `OrbView` uses is: ```typescript const defaultSettings = { @@ -144,6 +143,10 @@ const defaultSettings = { contextAlphaOnEvent: 0.3, contextAlphaOnEventIsEnabled: true, }, + strategy: { + isDefaultSelectEnabled: true, + isDefaultHoverEnabled: true, + }, zoomFitTransitionMs: 200, isOutOfBoundsDragEnabled: false, areCoordinatesRounded: true, @@ -156,7 +159,7 @@ You can read more about each property down below and on [Styles guide](./styles. ### Property `getPosition` -There are two basic ways to use the `DefaultView` API based on the node positions: +There are two basic ways to use the `OrbView` API based on the node positions: - **Simulated node positions** - Orb internally calculates and assigns coordinates to your nodes. @@ -165,7 +168,7 @@ There are two basic ways to use the `DefaultView` API based on the node position #### Simulated node positions -In this mode, the `DefaultView` arranges node positions by internally calculating their +In this mode, the `OrbView` arranges node positions by internally calculating their coordinates using the [D3.js](https://d3js.org/) library, or more specifically, [`d3-force`](https://github.com/d3/d3-force). This method is applied by default - you don't need to initialize Orb with any additional configuration. @@ -173,6 +176,8 @@ need to initialize Orb with any additional configuration. ![](./assets/view-default-simulated.png) ```typescript +import { OrbView } from "@memgraph/orb"; + const nodes: MyNode[] = [ { id: 0, label: "Node A" }, { id: 1, label: "Node B" }, @@ -187,14 +192,14 @@ const edges: MyEdge[] = [ { id: 5, start: 0, end: 1, label: "Edge V" }, ]; -const orb = new Orb(container); +const orb = new OrbView(container); // Initialize nodes and edges orb.data.setup({ nodes, edges }); // Render and recenter the view -orb.view.render(() => { - orb.view.recenter(); +orb.render(() => { + orb.recenter(); }); ``` @@ -208,7 +213,7 @@ that allows Orb to position the nodes. ![](./assets/view-default-fixed.png) ```typescript -import { DefaultView } from "@memgraph/orb"; +import { OrbView } from "@memgraph/orb"; const container = document.getElementById("graph"); const nodes: MyNode[] = [ @@ -225,20 +230,16 @@ const edges: MyEdge[] = [ { id: 5, start: 0, end: 1, label: "Edge V" }, ]; -const orb = new Orb(container); -orb.setView( - (context) => - new DefaultView(context, { - getPosition: (node) => ({ x: node.data.posX, y: node.data.posY }), - }) -); +const orb = new OrbView(container, { + getPosition: (node) => ({ x: node.data.posX, y: node.data.posY }), +}); // Initialize nodes and edges orb.data.setup({ nodes, edges }); // Render and recenter the view -orb.view.render(() => { - orb.view.recenter(); +orb.render(() => { + orb.recenter(); }); ``` @@ -257,6 +258,58 @@ Here you can use your original properties to indicate which ones represent your Optional property `render` has several rendering options that you can tweak. Read more about them on [Styling guide](./styles.md). +### Property `strategy` + +The optional property `strategy` has two properties that you can enable/disable: + +* `isDefaultSelectEnabled` - when `true`, the default selection strategy is used on mouse click: + * If there is a node at the mouse click point, the node, its edges, and adjacent nodes will change + its state to `GraphObjectState.SELECTED`. Style properties that end with `...Selected` will be + applied to all the selected objects (e.g. `borderColorSelected`). + * If there is an edge at the mouse click point, the edge and its starting and ending nodes will change + its state to `GraphObjectState.SELECTED`. +* `isDefaultHoverEnabled` - when `true`, the default hover strategy is used on mouse move: + * If there is a node at the mouse pointer, the node, its edges, and adjacent nodes will change its state to + `GraphObjectState.HOVERED`. Style properties that end with `...Hovered` will be applied to all the + hovered objects (e.g. `borderColorHovered`). + +With property `strategy` you can disable the above behavior and implement your select/hover strategy on +top of events `OrbEventType.MOUSE_CLICK` and `OrbEventType.MOUSE_MOVE`, e.g: + +```typescript +import { isNode, OrbEventType, GraphObjectState } from '@memgraph/orb'; + +// Disable default select and hover strategy +orb.setSettings({ + strategy: { + isDefaultSelectEnabled: false, + isDefaultHoverEnabled: false, + }, +}); + +// Create custom select strategy which selects just clicked node +orb.events.on(OrbEventType.MOUSE_CLICK, (event) => { + // Clicked on blank canvas + if (!event.subject) { + // Deselect the previously selected nodes and render if there are changes + const selectedNodes = orb.data.getNodes((node) => node.isSelected()); + if (selectedNodes) { + selectedNodes.forEach((node) => node.clearState()); + orb.render(); + } + } + + // Clicked on unselected node + if (event.subject && isNode(event.subject) && !event.subject.isSelected()) { + // Deselect the previously selected nodes + orb.data.getNodes((node) => node.isSelected()).forEach((node) => node.clearState()); + // Select the new node + event.subject.state = GraphObjectState.SELECTED; + orb.render(); + } +}); +``` + ### Property `simulation` Fine-grained D3 simulation engine settings. They include `isPhysicsEnabled`, `alpha`, @@ -294,38 +347,33 @@ Disabled by default (`false`). ## Settings -The above settings of the `DefaultView` can be defined on view initialization, but also anytime +The above settings of the `OrbView` can be defined on view initialization, but also anytime after the initialization with a view function `setSettings`: ```typescript -import { DefaultView } from "@memgraph/orb"; - -const orb = new Orb(container); - -orb.setView( - (context) => - new DefaultView(context, { - getPosition: (node) => ({ x: node.data.posY, y: node.data.posX }), - zoomFitTransformMs: 1000, - render: { - shadowIsEnabled: false, - shadowOnEventIsEnabled: false, - }, - }) -); +import { OrbView } from "@memgraph/orb"; + +const orb = new OrbView(container, { + getPosition: (node) => ({ x: node.data.posY, y: node.data.posX }), + zoomFitTransformMs: 1000, + render: { + shadowIsEnabled: false, + shadowOnEventIsEnabled: false, + }, +}); ``` ```typescript // If you want to see all the current view settings -const settings = orb.view.getSettings(); +const settings = orb.getSettings(); // Change the x and y axis -orb.view.setSettings({ +orb.setSettings({ getPosition: (node) => ({ x: node.data.posY, y: node.data.posX }), }); // Change the zoom fit and transform time while recentering and disable shadows -orb.view.setSettings({ +orb.setSettings({ zoomFitTransformMs: 1000, render: { shadowIsEnabled: false, @@ -340,7 +388,7 @@ Just like other Orb views, use `render` to render the view and `recenter` to fit the rendered graph. ```typescript -orb.view.render(() => { - orb.view.recenter(); +orb.render(() => { + orb.recenter(); }); ``` diff --git a/docs/view-map.md b/docs/view-map.md index 721962d..6383447 100644 --- a/docs/view-map.md +++ b/docs/view-map.md @@ -1,6 +1,6 @@ # Orb views: Map view -By default, Orb offers a `MapView` which is a graph view with a map as a background. Map rendering is +By default, Orb offers a `OrbMapView` which is a graph view with a map as a background. Map rendering is done with a library [leaflet](https://leafletjs.com/). To render maps, make sure to add the following CSS to your project: @@ -11,12 +11,13 @@ following CSS to your project: /> ``` -Here is a simple example of `MapView` usage: +Here is a simple example of `OrbMapView` usage: ![](./assets/view-map-example.png) ```typescript -import { MapView } from "@memgraph/orb"; +import { OrbMapView } from "@memgraph/orb"; + const container = document.getElementById(""); const nodes: MyNode[] = [ @@ -30,13 +31,9 @@ const edges: MyEdge[] = [ { id: 2, start: "hamilton", end: "miami" }, ]; -const orb = new Orb(container); -orb.setView( - (context) => - new MapView(context, { - getGeoPosition: (node) => ({ lat: node.data.lat, lng: node.data.lng }), - }) -); +const orb = new OrbMapView(container, { + getGeoPosition: (node) => ({ lat: node.data.lat, lng: node.data.lng }), +}); // Assign a default style orb.data.setDefaultStyle({ @@ -63,61 +60,58 @@ orb.data.setDefaultStyle({ orb.data.setup({ nodes, edges }); // Render and recenter the view -orb.view.render(() => { - orb.view.recenter(); +orb.render(() => { + orb.recenter(); }); ``` ## Initialization -On `MapView` initialization, you must provide an implementation for `getGeoPosition` which is used +On `OrbMapView` initialization, you must provide an implementation for `getGeoPosition` which is used to get `latitude` and `longitude` for each node. Here is the example of settings (required and optional) -initialized on the new `MapView`: +initialized on the new `OrbMapView`: ```typescript import * as L from "leaflet"; -import { MapView } from "@memgraph/orb"; +import { OrbMapView } from "@memgraph/orb"; const mapAttribution = 'Leaflet | ' + 'Map data © OpenStreetMap contributors'; -orb.setView( - (context) => - new MapView(context, { - getGeoPosition: (node) => ({ - lat: node.data.latitude, - lng: node.data.longitude, - }), - map: { - zoomLevel: 5, - tile: { - instance: new L.TileLayer( - "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" - ), - attribution: mapAttribution, - }, - render: { - labelsIsEnabled: true, - labelsOnEventIsEnabled: true, - shadowIsEnabled: true, - shadowOnEventIsEnabled: true, - contextAlphaOnEvent: 0.3, - contextAlphaOnEventIsEnabled: true, - }, - }, - areCollapsedContainerDimensionsAllowed: false; - }) -); +const orb = new OrbMapView(container, { + getGeoPosition: (node) => ({ + lat: node.data.latitude, + lng: node.data.longitude, + }), + map: { + zoomLevel: 5, + tile: { + instance: new L.TileLayer( + "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" + ), + attribution: mapAttribution, + }, + }, + render: { + labelsIsEnabled: true, + labelsOnEventIsEnabled: true, + shadowIsEnabled: true, + shadowOnEventIsEnabled: true, + contextAlphaOnEvent: 0.3, + contextAlphaOnEventIsEnabled: true, + }, + areCollapsedContainerDimensionsAllowed: false, +}); ``` -You can set settings on view initialization or afterward with `orb.view.setSettings`. Below +You can set settings on view initialization or afterward with `orb.setSettings`. Below you can see the list of all settings' parameters: ```typescript import * as L from "leaflet"; -interface IMapViewSettings { +interface IOrbMapViewSettings { // For map node positions getGeoPosition(node: INode): { lat: number; lng: number } | undefined; // For canvas rendering and events @@ -133,6 +127,11 @@ interface IMapViewSettings { contextAlphaOnEvent: number; contextAlphaOnEventIsEnabled: boolean; }; + // For select and hover look-and-feel + strategy: { + isDefaultSelectEnabled: boolean; + isDefaultHoverEnabled: boolean; + }; // Other map view parameters map: { zoomLevel: number; @@ -142,7 +141,7 @@ interface IMapViewSettings { } ``` -The default settings that `MapView` uses is: +The default settings that `OrbMapView` uses is: ```typescript const defaultSettings = { @@ -158,6 +157,10 @@ const defaultSettings = { contextAlphaOnEvent: 0.3, contextAlphaOnEventIsEnabled: true, }, + strategy: { + isDefaultSelectEnabled: true, + isDefaultHoverEnabled: true, + }, map: { zoomLevel: 2, // Default map zoom level tile: new L.TileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"), // OpenStreetMaps @@ -186,6 +189,58 @@ Optional property `map` has two properties that you can set which are: Optional property `render` has several rendering options that you can tweak. Read more about them on [Styling guide](./styles.md). +### Property `strategy` + +The optional property `strategy` has two properties that you can enable/disable: + +* `isDefaultSelectEnabled` - when `true`, the default selection strategy is used on mouse click: + * If there is a node at the mouse click point, the node, its edges, and adjacent nodes will change + its state to `GraphObjectState.SELECTED`. Style properties that end with `...Selected` will be + applied to all the selected objects (e.g. `borderColorSelected`). + * If there is an edge at the mouse click point, the edge and its starting and ending nodes will change + its state to `GraphObjectState.SELECTED`. +* `isDefaultHoverEnabled` - when `true`, the default hover strategy is used on mouse move: + * If there is a node at the mouse pointer, the node, its edges, and adjacent nodes will change its state to + `GraphObjectState.HOVERED`. Style properties that end with `...Hovered` will be applied to all the + hovered objects (e.g. `borderColorHovered`). + +With property `strategy` you can disable the above behavior and implement your select/hover strategy on +top of events `OrbEventType.MOUSE_CLICK` and `OrbEventType.MOUSE_MOVE`, e.g: + +```typescript +import { isNode, OrbEventType, GraphObjectState } from '@memgraph/orb'; + +// Disable default select and hover strategy +orb.setSettings({ + strategy: { + isDefaultSelectEnabled: false, + isDefaultHoverEnabled: false, + }, +}); + +// Create custom select strategy which selects just clicked node +orb.events.on(OrbEventType.MOUSE_CLICK, (event) => { + // Clicked on blank canvas + if (!event.subject) { + // Deselect the previously selected nodes and render if there are changes + const selectedNodes = orb.data.getNodes((node) => node.isSelected()); + if (selectedNodes) { + selectedNodes.forEach((node) => node.clearState()); + orb.render(); + } + } + + // Clicked on unselected node + if (event.subject && isNode(event.subject) && !event.subject.isSelected()) { + // Deselect the previously selected nodes + orb.data.getNodes((node) => node.isSelected()).forEach((node) => node.clearState()); + // Select the new node + event.subject.state = GraphObjectState.SELECTED; + orb.render(); + } +}); +``` + ### Property `areCollapsedContainerDimensionsAllowed` Enables setting the dimensions of the Orb container element to zero. @@ -197,20 +252,20 @@ Disabled by default (`false`). ## Settings -The above settings of `MapView` can be defined on view initialization, but also anytime after the +The above settings of `OrbMapView` can be defined on view initialization, but also anytime after the initialization with a view function `setSettings`: ```typescript // If you want to see all the current view settings -const settings = orb.view.getSettings(); +const settings = orb.getSettings(); // Change the way how geo coordinates are defined on nodes -orb.view.setSettings({ +orb.setSettings({ getGeoPosition: (node) => ({ lat: node.data.lat, lng: node.data.lng }), }); // Change the zoom level and disable shadows -orb.view.setSettings({ +orb.setSettings({ map: { zoomLevel: 7, }, @@ -227,8 +282,8 @@ Just like other Orb views, use `render` to render the view and `recenter` to fit the rendered graph. ```typescript -orb.view.render(() => { - orb.view.recenter(); +orb.render(() => { + orb.recenter(); }); ``` @@ -238,8 +293,8 @@ If you need a reference to the internal map reference from `leaflet` library, ju following example: ```typescript -import { MapView } from "@memgraph/orb"; +import { OrbMapView } from "@memgraph/orb"; -// It will only work on MapView -const leaflet = (orb.view as MapView).leaflet; +// It will only work on OrbMapView +const leaflet = (orb.view as OrbMapView).leaflet; ``` diff --git a/examples/example-custom-styled-graph.html b/examples/example-custom-styled-graph.html index d7678d0..8e4c8c3 100644 --- a/examples/example-custom-styled-graph.html +++ b/examples/example-custom-styled-graph.html @@ -42,7 +42,7 @@

Example 2 - Basic + Custom default style

{ id: 5, start: 0, end: 1, label: 'A -> B' }, ] - const orb = new Orb.Orb(container); + const orb = new Orb.OrbView(container); // Assign a basic style orb.data.setDefaultStyle({ @@ -87,8 +87,8 @@

Example 2 - Basic + Custom default style

// Initialize nodes and edges orb.data.setup({ nodes, edges }); - orb.view.render(() => { - orb.view.recenter(); + orb.render(() => { + orb.recenter(); }); diff --git a/examples/example-fixed-coordinates-graph.html b/examples/example-fixed-coordinates-graph.html index 0819d27..55998c7 100644 --- a/examples/example-fixed-coordinates-graph.html +++ b/examples/example-fixed-coordinates-graph.html @@ -42,10 +42,9 @@

Example 3 - Fixed coordinates

{ id: 5, start: 0, end: 1, label: 'A -> B' }, ]; - const orb = new Orb.Orb(container); - orb.setView((context) => new Orb.DefaultView(context, { + const orb = new Orb.OrbView(container, { getPosition: (node) => ({ x: node.data.x, y: node.data.y }) - })) + }); // Initialize nodes and edges orb.data.setup({ nodes, edges }); @@ -78,8 +77,8 @@

Example 3 - Fixed coordinates

}, }); - orb.view.render(() => { - orb.view.recenter(); + orb.render(() => { + orb.recenter(); }); diff --git a/examples/example-graph-data-changes.html b/examples/example-graph-data-changes.html index a80d95b..6537bbd 100644 --- a/examples/example-graph-data-changes.html +++ b/examples/example-graph-data-changes.html @@ -46,7 +46,7 @@

Example 5 - Dynamics

}; } - const orb = new Orb.Orb(container); + const orb = new Orb.OrbView(container); orb.data.setDefaultStyle({ getNodeStyle(node) { @@ -106,7 +106,7 @@

Example 5 - Dynamics

n += 1; orb.data.merge(graphUpdates); - orb.view.render(); + orb.render(); randomlyExpandGraph(); }, 3000); }; @@ -116,12 +116,12 @@

Example 5 - Dynamics

orb.events.on(Orb.OrbEventType.NODE_CLICK, (event) => { console.log('Node clicked: ', event.node); orb.data.remove({ nodeIds: [event.node.id] }); - orb.view.render(); + orb.render(); }); // Render and recenter the view - orb.view.render(() => { - orb.view.recenter(); + orb.render(() => { + orb.recenter(); }); diff --git a/examples/example-graph-events.html b/examples/example-graph-events.html index bf40ae0..0a0d2d9 100644 --- a/examples/example-graph-events.html +++ b/examples/example-graph-events.html @@ -53,7 +53,7 @@

Example 4 - Events

}; } - const orb = new Orb.Orb(container); + const orb = new Orb.OrbView(container); // Assign a basic style orb.data.setDefaultStyle({ @@ -87,8 +87,8 @@

Example 4 - Events

orb.data.setup({ nodes, edges }); // Render and recenter the view - orb.view.render(() => { - orb.view.recenter(() => { + orb.render(() => { + orb.recenter(() => { output.innerHTML = '< Click on any of the nodes or edges >'; }); }); diff --git a/examples/example-graph-on-map.html b/examples/example-graph-on-map.html index 0e45ddb..db11d4d 100644 --- a/examples/example-graph-on-map.html +++ b/examples/example-graph-on-map.html @@ -44,10 +44,9 @@

Example 6 - Map

{ id: 5, start: 0, end: 1 }, ]; - const orb = new Orb.Orb(container); - orb.setView((context) => new Orb.MapView(context, { + const orb = new Orb.OrbMapView(container, { getGeoPosition: (node) => ({ lat: node.data.lat, lng: node.data.lng, }), - })); + }); // Assign a basic style orb.data.setDefaultStyle({ @@ -81,8 +80,8 @@

Example 6 - Map

orb.data.setup({ nodes, edges }); // Render and recenter the view - orb.view.render(() => { - orb.view.recenter(); + orb.render(() => { + orb.recenter(); }); diff --git a/examples/example-simple-graph.html b/examples/example-simple-graph.html index 6607610..b1cf701 100644 --- a/examples/example-simple-graph.html +++ b/examples/example-simple-graph.html @@ -40,13 +40,13 @@

Example 1 - Basic

{ id: 5, start: 0, end: 1, label: 'A -> B' }, ]; - const orb = new Orb.Orb(container); + const orb = new Orb.OrbView(container); // Initialize nodes and edges orb.data.setup({ nodes, edges }); - orb.view.render(() => { - orb.view.recenter(); + orb.render(() => { + orb.recenter(); }); diff --git a/examples/playground.html b/examples/playground.html index 1905d4b..9bb17b5 100644 --- a/examples/playground.html +++ b/examples/playground.html @@ -31,63 +31,84 @@ { id: 15, start: 0, end: 1, label: 'Edge V', properties: { test: 3 } }, ]; - const orb = new Orb.Orb(container); - orb.setView((context) => new Orb.MapView(context, { - getGeoPosition: (node) => ({ lat: node.data.lat, lng: node.data.lng, }), - })); + const getDefaultStyle = () => { + return { + getNodeStyle(node) { + return { + borderColor: '#1d1d1d', + borderWidth: 0.6, + color: '#DD2222', + colorHover: '#e7644e', + colorSelected: '#e7644e', + fontSize: 3, + label: node.data.labels[0], + size: 6, + }; + }, + getEdgeStyle(edge) { + return { + color: '#999999', + colorHover: '#1d1d1d', + colorSelected: '#1d1d1d', + fontSize: 3, + width: 0.3, + widthHover: 0.9, + widthSelected: 0.9, + label: edge.data.label, + }; + }, + }; + }; - // Initialize nodes and edges - orb.data.setup({ nodes, edges }); + const getOrbMapView = (container) => { + const view = new Orb.OrbMapView(container, { + getGeoPosition: (node) => ({ lat: node.data.lat, lng: node.data.lng, }), + }); - // Assign a basic style - orb.data.setStyle({ - getNodeStyle(node) { - return { - borderColor: '#1d1d1d', - borderWidth: 0.6, - color: '#DD2222', - colorHover: '#e7644e', - colorSelected: '#e7644e', - fontSize: 3, - label: node.data.labels[0], - size: 6, - }; - }, - getEdgeStyle(edge) { - return { - color: '#999999', - colorHover: '#1d1d1d', - colorSelected: '#1d1d1d', - fontSize: 3, - width: 0.3, - widthHover: 0.9, - widthSelected: 0.9, - label: edge.data.label, - }; - }, - }); + // Assign a basic style + view.data.setDefaultStyle(getDefaultStyle()); + + // Initialize nodes and edges + view.data.setup({ nodes, edges }); + return view; + } + + const getOrbView = (container) => { + const view = new Orb.OrbView(container); + + // Assign a basic style + view.data.setDefaultStyle(getDefaultStyle()); + + // Initialize nodes and edges + view.data.setup({ nodes, edges }); + return view; + } + + const orb1 = getOrbMapView(container); // Render and recenter the view - orb.view.render(() => { - orb.view.recenter(); + orb1.render(() => { + orb1.recenter(); }); setTimeout(() => { - orb.setView((context) => new Orb.DefaultView(context)); - orb.view.render(() => { + orb1.destroy(); + const orb2 = getOrbView(container); + + orb2.render(() => { setTimeout(() => { - orb.data.clearPositions(); - orb.view.render(() => { - orb.view.recenter(); + orb2.data.clearPositions(); + orb2.render(() => { + orb2.recenter(); }); setTimeout(() => { - orb.setView((context) => new Orb.MapView(context, { - getGeoPosition: (node) => ({ lat: node.data.lat, lng: node.data.lng, }), - })); - orb.view.render(() => { - orb.view.recenter(); + orb2.destroy(); + + const orb3 = getOrbMapView(container); + orb3.render(() => { + orb3.recenter(); }); }, 2000); }, 2000); diff --git a/examples/simulator-scenarios.html b/examples/simulator-scenarios.html index dbbacee..81ba062 100644 --- a/examples/simulator-scenarios.html +++ b/examples/simulator-scenarios.html @@ -159,13 +159,9 @@

Simulator Scenarios

const initialSetup = (graphContainerId, nodes, edges, callback) => { const container = document.getElementById(graphContainerId); - const orb = new Orb.Orb(container); - orb.setView((context) => new Orb.DefaultView(context, { + const orb = new Orb.OrbView(container, { getPosition: (node) => ({ x: node.data.x, y: node.data.y }) - })) - - // Initialize nodes and edges - orb.data.setup({ nodes, edges }); + }); // Assign a basic style orb.data.setDefaultStyle({ @@ -199,10 +195,13 @@

Simulator Scenarios

}, }); + // Initialize nodes and edges + orb.data.setup({ nodes, edges }); + // Render and recenter the view - orb.view.render(() => { + orb.render(() => { setTimeout(() => { - orb.view.recenter(); + orb.recenter(); }, 1000); if (callback) { callback(orb); @@ -221,12 +220,12 @@

Simulator Scenarios

const globalPhysicsCheckbox = document.getElementById('globalPhysicsCheckbox'); globalPhysicsCheckbox.addEventListener('click', () => { - orb.view.setSettings({ simulation: { isPhysicsEnabled: globalPhysicsCheckbox.checked } }); + orb.setSettings({ simulation: { isPhysicsEnabled: globalPhysicsCheckbox.checked } }); }); const containerPhysicsCheckbox = container.getElementsByClassName('checkbox')[0]; containerPhysicsCheckbox.addEventListener('click', () => { - orb.view.setSettings({ simulation: { isPhysicsEnabled: containerPhysicsCheckbox.checked } }); + orb.setSettings({ simulation: { isPhysicsEnabled: containerPhysicsCheckbox.checked } }); }); } @@ -270,7 +269,7 @@

Simulator Scenarios

initialSetupFree('oldNodesFixedNewNodesFree1', (orb) => { setTimeout(() => { - orb.view.fixNodes(); + orb.fixNodes(); orb.data.merge({ nodes: [ { id: 4, labels: ['Node E'] }, @@ -279,9 +278,9 @@

Simulator Scenarios

{ id: 14, start: 0, end: 4, label: 'Edge R' } ] }); - orb.view.render(() => { + orb.render(() => { setTimeout(() => { - orb.view.recenter(); + orb.recenter(); }, 1000); }); }, 2000); @@ -297,9 +296,9 @@

Simulator Scenarios

{ id: 14, start: 0, end: 4, label: 'Edge R' } ] }); - orb.view.render(() => { + orb.render(() => { setTimeout(() => { - orb.view.recenter(); + orb.recenter(); }, 1000); }); }, 2000); @@ -315,9 +314,9 @@

Simulator Scenarios

{ id: 14, start: 0, end: 4, label: 'Edge R' } ] }); - orb.view.render(() => { + orb.render(() => { setTimeout(() => { - orb.view.recenter(); + orb.recenter(); }, 1000); }); }, 2000); @@ -333,9 +332,9 @@

Simulator Scenarios

{ id: 14, start: 0, end: 4, label: 'Edge R' } ] }); - orb.view.render(() => { + orb.render(() => { setTimeout(() => { - orb.view.recenter(); + orb.recenter(); }, 1000); }); }, 2000); @@ -351,9 +350,9 @@

Simulator Scenarios

{ id: 14, start: 0, end: 4, label: 'Edge R' } ] }); - orb.view.render(() => { + orb.render(() => { setTimeout(() => { - orb.view.recenter(); + orb.recenter(); }, 1000); }); }, 2000); @@ -361,7 +360,7 @@

Simulator Scenarios

initialSetupFixed('oldNodesFreeNewNodesFixed2', (orb) => { setTimeout(() => { - orb.view.releaseNodes(); + orb.releaseNodes(); orb.data.merge({ nodes: [ { id: 4, labels: ['Node E'], x: -100, y: -50 }, @@ -372,9 +371,9 @@

Simulator Scenarios

{ id: 15, start: 0, end: 5, label: 'Edge T' } ] }); - orb.view.render(() => { + orb.render(() => { setTimeout(() => { - orb.view.recenter(); + orb.recenter(); }, 1000); }); }, 2000); diff --git a/src/events.ts b/src/events.ts index 4240f7d..5d1b1ef 100644 --- a/src/events.ts +++ b/src/events.ts @@ -26,61 +26,94 @@ export enum OrbEventType { NODE_DRAG_END = 'node-drag-end', } -export interface IOrbEventDuration { +interface IOrbEventDuration { durationMs: number; } -export interface IOrbEventProgress { +interface IOrbEventProgress { progress: number; } -export interface IOrbEventTransform { - transform: { - x: number; - y: number; - k: number; - }; -} - interface IOrbEventMousePosition { localPoint: IPosition; globalPoint: IPosition; } -export interface IOrbEventMouseClickEvent extends IOrbEventMousePosition { +interface IOrbEventMouseClickEvent extends IOrbEventMousePosition { event: PointerEvent; } -export interface IOrbEventMouseMoveEvent extends IOrbEventMousePosition { +interface IOrbEventMouseMoveEvent extends IOrbEventMousePosition { event: MouseEvent; } -export interface IOrbEventMouseEvent extends IOrbEventMousePosition { +interface IOrbEventMouseEvent extends IOrbEventMousePosition { subject?: INode | IEdge; } -export interface IOrbEventMouseNodeEvent { +interface IOrbEventMouseNodeEvent { node: INode; } -export interface IOrbEventMouseEdgeEvent { +interface IOrbEventMouseEdgeEvent { edge: IEdge; } +export type IOrbEventRenderEnd = IOrbEventDuration; + +export type IOrbEventSimulationStep = IOrbEventProgress; + +export type IOrbEventSimulationEnd = IOrbEventDuration; + +export type IOrbEventNodeClick = IOrbEventMouseNodeEvent & + IOrbEventMouseClickEvent; + +export type IOrbEventNodeHover = IOrbEventMouseNodeEvent & + IOrbEventMouseMoveEvent; + +export type IOrbEventEdgeClick = IOrbEventMouseEdgeEvent & + IOrbEventMouseClickEvent; + +export type IOrbEventEdgeHover = IOrbEventMouseEdgeEvent & + IOrbEventMouseMoveEvent; + +export type IOrbEventMouseClick = IOrbEventMouseEvent & + IOrbEventMouseClickEvent; + +export type IOrbEventMouseMove = IOrbEventMouseEvent & + IOrbEventMouseMoveEvent; + +export interface IOrbEventTransform { + transform: { + x: number; + y: number; + k: number; + }; +} + +export type IOrbEventNodeDragStart = IOrbEventMouseNodeEvent & + IOrbEventMouseMoveEvent; + +export type IOrbEventNodeDrag = IOrbEventMouseNodeEvent & + IOrbEventMouseMoveEvent; + +export type IOrbEventNodeDragEnd = IOrbEventMouseNodeEvent & + IOrbEventMouseMoveEvent; + export class OrbEmitter extends Emitter<{ [OrbEventType.RENDER_START]: undefined; - [OrbEventType.RENDER_END]: IOrbEventDuration; + [OrbEventType.RENDER_END]: IOrbEventRenderEnd; [OrbEventType.SIMULATION_START]: undefined; - [OrbEventType.SIMULATION_STEP]: IOrbEventProgress; - [OrbEventType.SIMULATION_END]: IOrbEventDuration; - [OrbEventType.NODE_CLICK]: IOrbEventMouseNodeEvent & IOrbEventMouseClickEvent; - [OrbEventType.NODE_HOVER]: IOrbEventMouseNodeEvent & IOrbEventMouseMoveEvent; - [OrbEventType.EDGE_CLICK]: IOrbEventMouseEdgeEvent & IOrbEventMouseClickEvent; - [OrbEventType.EDGE_HOVER]: IOrbEventMouseEdgeEvent & IOrbEventMouseMoveEvent; - [OrbEventType.MOUSE_CLICK]: IOrbEventMouseEvent & IOrbEventMouseClickEvent; - [OrbEventType.MOUSE_MOVE]: IOrbEventMouseEvent & IOrbEventMouseMoveEvent; + [OrbEventType.SIMULATION_STEP]: IOrbEventSimulationStep; + [OrbEventType.SIMULATION_END]: IOrbEventSimulationEnd; + [OrbEventType.NODE_CLICK]: IOrbEventNodeClick; + [OrbEventType.NODE_HOVER]: IOrbEventNodeHover; + [OrbEventType.EDGE_CLICK]: IOrbEventEdgeClick; + [OrbEventType.EDGE_HOVER]: IOrbEventEdgeHover; + [OrbEventType.MOUSE_CLICK]: IOrbEventMouseClick; + [OrbEventType.MOUSE_MOVE]: IOrbEventMouseMove; [OrbEventType.TRANSFORM]: IOrbEventTransform; - [OrbEventType.NODE_DRAG_START]: IOrbEventMouseNodeEvent & IOrbEventMouseMoveEvent; - [OrbEventType.NODE_DRAG]: IOrbEventMouseNodeEvent & IOrbEventMouseMoveEvent; - [OrbEventType.NODE_DRAG_END]: IOrbEventMouseNodeEvent & IOrbEventMouseMoveEvent; + [OrbEventType.NODE_DRAG_START]: IOrbEventNodeDragStart; + [OrbEventType.NODE_DRAG]: IOrbEventNodeDrag; + [OrbEventType.NODE_DRAG_END]: IOrbEventNodeDragEnd; }> {} diff --git a/src/index.ts b/src/index.ts index 30e61bf..b81444b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,18 +1,24 @@ -export { Orb, IOrbSettings } from './orb'; -export { OrbEventType } from './events'; -export { OrbError } from './exceptions'; export { - DefaultView, - MapView, - IOrbView, - IOrbViewContext, - IOrbViewFactory, - IMapViewSettings, - IDefaultViewSettings, -} from './views'; + OrbEventType, + IOrbEventRenderEnd, + IOrbEventSimulationStep, + IOrbEventSimulationEnd, + IOrbEventNodeClick, + IOrbEventNodeHover, + IOrbEventEdgeClick, + IOrbEventEdgeHover, + IOrbEventMouseClick, + IOrbEventMouseMove, + IOrbEventTransform, + IOrbEventNodeDragStart, + IOrbEventNodeDrag, + IOrbEventNodeDragEnd, +} from './events'; +export { OrbError } from './exceptions'; export { IGraph, IGraphData, INodeFilter, IEdgeFilter } from './models/graph'; export { GraphObjectState } from './models/state'; export { INode, INodeBase, INodePosition, INodeStyle, isNode, NodeShapeType } from './models/node'; export { IEdge, IEdgeBase, IEdgePosition, IEdgeStyle, isEdge, EdgeType } from './models/edge'; export { IGraphStyle, getDefaultGraphStyle } from './models/style'; export { ICircle, IPosition, IRectangle, Color, IColorRGB } from './common'; +export { OrbView, OrbMapView, IOrbView, IOrbMapViewSettings, IOrbViewSettings } from './views'; diff --git a/src/models/strategy.ts b/src/models/strategy.ts index dbd951f..c24f58a 100644 --- a/src/models/strategy.ts +++ b/src/models/strategy.ts @@ -4,27 +4,39 @@ import { IGraph } from './graph'; import { IPosition } from '../common'; import { GraphObjectState } from './state'; +export interface IEventStrategySettings { + isDefaultSelectEnabled: boolean; + isDefaultHoverEnabled: boolean; +} + export interface IEventStrategyResponse { isStateChanged: boolean; changedSubject?: INode | IEdge; } export interface IEventStrategy { - onMouseClick: ((graph: IGraph, point: IPosition) => IEventStrategyResponse) | null; - onMouseMove: ((graph: IGraph, point: IPosition) => IEventStrategyResponse) | null; + isSelectEnabled: boolean; + isHoverEnabled: boolean; + onMouseClick: (graph: IGraph, point: IPosition) => IEventStrategyResponse; + onMouseMove: (graph: IGraph, point: IPosition) => IEventStrategyResponse; } -export const getDefaultEventStrategy = (): IEventStrategy => { - return new DefaultEventStrategy(); -}; +export class DefaultEventStrategy implements IEventStrategy { + private _lastHoveredNode?: INode; + public isSelectEnabled: boolean; + public isHoverEnabled: boolean; -class DefaultEventStrategy implements IEventStrategy { - lastHoveredNode?: INode; + constructor(settings: IEventStrategySettings) { + this.isSelectEnabled = settings.isDefaultSelectEnabled; + this.isHoverEnabled = settings.isDefaultHoverEnabled; + } onMouseClick(graph: IGraph, point: IPosition): IEventStrategyResponse { const node = graph.getNearestNode(point); if (node) { - selectNode(graph, node); + if (this.isSelectEnabled) { + selectNode(graph, node); + } return { isStateChanged: true, changedSubject: node, @@ -33,13 +45,19 @@ class DefaultEventStrategy implements const edge = graph.getNearestEdge(point); if (edge) { - selectEdge(graph, edge); + if (this.isSelectEnabled) { + selectEdge(graph, edge); + } return { isStateChanged: true, changedSubject: edge, }; } + if (!this.isSelectEnabled) { + return { isStateChanged: false }; + } + const { changedCount } = unselectAll(graph); return { isStateChanged: changedCount > 0, @@ -48,24 +66,27 @@ class DefaultEventStrategy implements onMouseMove(graph: IGraph, point: IPosition): IEventStrategyResponse { const node = graph.getNearestNode(point); - if (node && !node.isSelected()) { - if (node === this.lastHoveredNode) { + if (node && (!this.isSelectEnabled || (this.isSelectEnabled && !node.isSelected()))) { + if (node === this._lastHoveredNode) { return { changedSubject: node, isStateChanged: false, }; } - hoverNode(graph, node); - this.lastHoveredNode = node; + if (this.isHoverEnabled) { + hoverNode(graph, node); + } + + this._lastHoveredNode = node; return { isStateChanged: true, changedSubject: node, }; } - this.lastHoveredNode = undefined; - if (!node) { + this._lastHoveredNode = undefined; + if (!node && this.isHoverEnabled) { const { changedCount } = unhoverAll(graph); return { isStateChanged: changedCount > 0, diff --git a/src/orb.ts b/src/orb.ts deleted file mode 100644 index 5b8cb29..0000000 --- a/src/orb.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { Graph, IGraph } from './models/graph'; -import { INodeBase } from './models/node'; -import { IEdgeBase } from './models/edge'; -import { DefaultView, IOrbViewFactory, IOrbView, IOrbViewContext } from './views'; -import { getDefaultEventStrategy, IEventStrategy } from './models/strategy'; -import { OrbEmitter } from './events'; -import { getDefaultGraphStyle } from './models/style'; - -export interface IOrbSettings { - view: IOrbViewFactory; - strategy: IEventStrategy; -} - -// TODO: Change the Orb API to be a single view instance to support non-any -// @see: https://stackoverflow.com/questions/73429628/how-to-setup-typescript-generics-in-class-constructors-and-functions -export class Orb { - private _view: IOrbView; - private readonly _events: OrbEmitter; - private readonly _graph: IGraph; - private readonly _context: IOrbViewContext; - - constructor(private container: HTMLElement, settings?: Partial>) { - this._events = new OrbEmitter(); - this._graph = new Graph(undefined, { - onLoadedImages: () => { - // Not to call render() before user's .render() - if (this._view.isInitiallyRendered()) { - this._view.render(); - } - }, - }); - this._graph.setDefaultStyle(getDefaultGraphStyle()); - - this._context = { - container: this.container, - graph: this._graph, - events: this._events, - strategy: settings?.strategy ?? getDefaultEventStrategy(), - }; - - if (settings?.view) { - this._view = settings.view(this._context); - } else { - this._view = new DefaultView(this._context); - } - } - - get data(): IGraph { - return this._graph; - } - - get view(): IOrbView { - return this._view; - } - - get events(): OrbEmitter { - return this._events; - } - - setView(factory: IOrbViewFactory) { - // Reset the existing graph in case of switching between different view types. - if (this._graph.getNodeCount() > 0) { - this._graph.clearPositions(); - } - - if (this._view) { - this._view.destroy(); - } - this._view = factory(this._context); - } -} diff --git a/src/views/index.ts b/src/views/index.ts index 146209d..cefda53 100644 --- a/src/views/index.ts +++ b/src/views/index.ts @@ -1,3 +1,3 @@ -export { DefaultView, IDefaultViewSettings } from './default-view'; -export { MapView, IMapViewSettings } from './map-view'; -export { IOrbView, IOrbViewFactory, IOrbViewContext } from './shared'; +export { OrbView, IOrbViewSettings } from './orb-view'; +export { OrbMapView, IOrbMapViewSettings } from './orb-map-view'; +export { IOrbView } from './shared'; diff --git a/src/views/map-view.ts b/src/views/orb-map-view.ts similarity index 65% rename from src/views/map-view.ts rename to src/views/orb-map-view.ts index 24a6269..2838ba5 100644 --- a/src/views/map-view.ts +++ b/src/views/orb-map-view.ts @@ -1,15 +1,17 @@ import * as L from 'leaflet'; import { IEdgeBase, isEdge } from '../models/edge'; import { INode, INodeBase, isNode } from '../models/node'; -import { IGraph } from '../models/graph'; -import { IOrbView, IOrbViewContext } from './shared'; +import { Graph, IGraph } from '../models/graph'; +import { IOrbView } from './shared'; import { IPosition } from '../common'; -import { IEventStrategy } from '../models/strategy'; +import { DefaultEventStrategy, IEventStrategy, IEventStrategySettings } from '../models/strategy'; import { copyObject } from '../utils/object.utils'; import { OrbEmitter, OrbEventType } from '../events'; import { IRenderer, RendererType, RenderEventType, IRendererSettingsInit, IRendererSettings } from '../renderer/shared'; import { RendererFactory } from '../renderer/factory'; import { setupContainer } from '../utils/html.utils'; +import { getDefaultGraphStyle } from '../models/style'; +import { isBoolean } from '../utils/type.utils'; export interface ILeafletMapTile { instance: L.TileLayer; @@ -44,28 +46,32 @@ export interface IMapSettings { tile: ILeafletMapTile; } -export interface IMapViewSettings { +export interface IOrbMapViewSettings { getGeoPosition(node: INode): { lat: number; lng: number } | undefined; map: IMapSettings; render: Partial; + strategy: Partial; areCollapsedContainerDimensionsAllowed: boolean; } -export interface IMapViewSettingsInit { +export interface IOrbMapViewSettingsInit { getGeoPosition(node: INode): { lat: number; lng: number } | undefined; map?: Partial; render?: Partial; + strategy?: Partial; } -export type IMapViewSettingsUpdate = Partial>; +export type IOrbMapViewSettingsUpdate = Partial< + IOrbMapViewSettingsInit +>; -export class MapView implements IOrbView> { +export class OrbMapView implements IOrbView> { private _container: HTMLElement; private _graph: IGraph; private _events: OrbEmitter; private _strategy: IEventStrategy; - private _settings: IMapViewSettings; + private _settings: IOrbMapViewSettings; private _canvas: HTMLCanvasElement; private _map: HTMLDivElement; @@ -73,11 +79,18 @@ export class MapView implements IOrbVi private readonly _renderer: IRenderer; private readonly _leaflet: L.Map; - constructor(context: IOrbViewContext, settings: IMapViewSettingsInit) { - this._container = context.container; - this._graph = context.graph; - this._events = context.events; - this._strategy = context.strategy; + constructor(container: HTMLElement, settings: IOrbMapViewSettingsInit) { + this._container = container; + this._graph = new Graph(undefined, { + onLoadedImages: () => { + // Not to call render() before user's .render() + if (this._renderer.isInitiallyRendered) { + this.render(); + } + }, + }); + this._graph.setDefaultStyle(getDefaultGraphStyle()); + this._events = new OrbEmitter(); this._settings = { areCollapsedContainerDimensionsAllowed: false, @@ -90,8 +103,18 @@ export class MapView implements IOrbVi type: RendererType.CANVAS, ...settings.render, }, + strategy: { + isDefaultHoverEnabled: true, + isDefaultSelectEnabled: true, + ...settings?.strategy, + }, }; + this._strategy = new DefaultEventStrategy({ + isDefaultSelectEnabled: this._settings.strategy.isDefaultSelectEnabled ?? false, + isDefaultHoverEnabled: this._settings.strategy.isDefaultHoverEnabled ?? false, + }); + setupContainer(this._container); this._canvas = this._initCanvas(); this._map = this._initMap(); @@ -117,19 +140,23 @@ export class MapView implements IOrbVi this._handleTileChange(); } - get leaflet(): L.Map { - return this._leaflet; + get data(): IGraph { + return this._graph; + } + + get events(): OrbEmitter { + return this._events; } - isInitiallyRendered(): boolean { - return this._renderer.isInitiallyRendered; + get leaflet(): L.Map { + return this._leaflet; } - getSettings(): IMapViewSettings { + getSettings(): IOrbMapViewSettings { return copyObject(this._settings); } - setSettings(settings: IMapViewSettingsUpdate) { + setSettings(settings: IOrbMapViewSettingsUpdate) { if (settings.getGeoPosition) { this._settings.getGeoPosition = settings.getGeoPosition; this._updateGraphPositions(); @@ -151,6 +178,18 @@ export class MapView implements IOrbVi this._renderer.setSettings(settings.render); this._settings.render = this._renderer.getSettings(); } + + if (settings.strategy) { + if (isBoolean(settings.strategy.isDefaultHoverEnabled)) { + this._settings.strategy.isDefaultHoverEnabled = settings.strategy.isDefaultHoverEnabled; + this._strategy.isHoverEnabled = this._settings.strategy.isDefaultHoverEnabled; + } + + if (isBoolean(settings.strategy.isDefaultSelectEnabled)) { + this._settings.strategy.isDefaultSelectEnabled = settings.strategy.isDefaultSelectEnabled; + this._strategy.isSelectEnabled = this._settings.strategy.isDefaultSelectEnabled; + } + } } render(onRendered?: () => void) { @@ -216,39 +255,37 @@ export class MapView implements IOrbVi const point: IPosition = { x: event.layerPoint.x, y: event.layerPoint.y }; const containerPoint: IPosition = { x: event.containerPoint.x, y: event.containerPoint.y }; - if (this._strategy.onMouseMove) { - const response = this._strategy.onMouseMove(this._graph, point); - const subject = response.changedSubject; - - if (subject && response.isStateChanged) { - if (isNode(subject)) { - this._events.emit(OrbEventType.NODE_HOVER, { - node: subject, - event: event.originalEvent, - localPoint: point, - globalPoint: containerPoint, - }); - } - if (isEdge(subject)) { - this._events.emit(OrbEventType.EDGE_HOVER, { - edge: subject, - event: event.originalEvent, - localPoint: point, - globalPoint: containerPoint, - }); - } + const response = this._strategy.onMouseMove(this._graph, point); + const subject = response.changedSubject; + + if (subject && response.isStateChanged) { + if (isNode(subject)) { + this._events.emit(OrbEventType.NODE_HOVER, { + node: subject, + event: event.originalEvent, + localPoint: point, + globalPoint: containerPoint, + }); + } + if (isEdge(subject)) { + this._events.emit(OrbEventType.EDGE_HOVER, { + edge: subject, + event: event.originalEvent, + localPoint: point, + globalPoint: containerPoint, + }); } + } - this._events.emit(OrbEventType.MOUSE_MOVE, { - subject, - event: event.originalEvent, - localPoint: point, - globalPoint: containerPoint, - }); + this._events.emit(OrbEventType.MOUSE_MOVE, { + subject, + event: event.originalEvent, + localPoint: point, + globalPoint: containerPoint, + }); - if (response.isStateChanged) { - this._renderer.render(this._graph); - } + if (response.isStateChanged) { + this._renderer.render(this._graph); } }); @@ -258,39 +295,37 @@ export class MapView implements IOrbVi const point: IPosition = { x: event.layerPoint.x, y: event.layerPoint.y }; const containerPoint: IPosition = { x: event.containerPoint.x, y: event.containerPoint.y }; - if (this._strategy.onMouseClick) { - const response = this._strategy.onMouseClick(this._graph, point); - const subject = response.changedSubject; - - if (subject) { - if (isNode(subject)) { - this._events.emit(OrbEventType.NODE_CLICK, { - node: subject, - event: event.originalEvent, - localPoint: point, - globalPoint: containerPoint, - }); - } - if (isEdge(subject)) { - this._events.emit(OrbEventType.EDGE_CLICK, { - edge: subject, - event: event.originalEvent, - localPoint: point, - globalPoint: containerPoint, - }); - } + const response = this._strategy.onMouseClick(this._graph, point); + const subject = response.changedSubject; + + if (subject) { + if (isNode(subject)) { + this._events.emit(OrbEventType.NODE_CLICK, { + node: subject, + event: event.originalEvent, + localPoint: point, + globalPoint: containerPoint, + }); + } + if (isEdge(subject)) { + this._events.emit(OrbEventType.EDGE_CLICK, { + edge: subject, + event: event.originalEvent, + localPoint: point, + globalPoint: containerPoint, + }); } + } - this._events.emit(OrbEventType.MOUSE_CLICK, { - subject, - event: event.originalEvent, - localPoint: point, - globalPoint: containerPoint, - }); + this._events.emit(OrbEventType.MOUSE_CLICK, { + subject, + event: event.originalEvent, + localPoint: point, + globalPoint: containerPoint, + }); - if (response.isStateChanged || response.changedSubject) { - this._renderer.render(this._graph); - } + if (response.isStateChanged || response.changedSubject) { + this._renderer.render(this._graph); } }); diff --git a/src/views/default-view.ts b/src/views/orb-view.ts similarity index 73% rename from src/views/default-view.ts rename to src/views/orb-view.ts index 3a7b5ca..c146a72 100644 --- a/src/views/default-view.ts +++ b/src/views/orb-view.ts @@ -8,23 +8,26 @@ import { D3ZoomEvent, zoom, ZoomBehavior } from 'd3-zoom'; import { select } from 'd3-selection'; import { IPosition, isEqualPosition } from '../common'; import { ISimulator, SimulatorFactory } from '../simulator'; -import { IGraph } from '../models/graph'; +import { Graph, IGraph } from '../models/graph'; import { INode, INodeBase, isNode } from '../models/node'; import { IEdgeBase, isEdge } from '../models/edge'; -import { IOrbView, IOrbViewContext } from './shared'; -import { IEventStrategy } from '../models/strategy'; -import { ID3SimulatorEngineSettingsUpdate } from '../simulator/engine/d3-simulator-engine'; +import { IOrbView } from './shared'; +import { DefaultEventStrategy, IEventStrategy, IEventStrategySettings } from '../models/strategy'; +import { ID3SimulatorEngineSettings } from '../simulator/engine/d3-simulator-engine'; import { copyObject } from '../utils/object.utils'; import { OrbEmitter, OrbEventType } from '../events'; import { IRenderer, RenderEventType, IRendererSettingsInit, IRendererSettings } from '../renderer/shared'; import { RendererFactory } from '../renderer/factory'; import { setupContainer } from '../utils/html.utils'; import { SimulatorEventType } from '../simulator/shared'; +import { getDefaultGraphStyle } from '../models/style'; +import { isBoolean } from '../utils/type.utils'; -export interface IDefaultViewSettings { +export interface IOrbViewSettings { getPosition?(node: INode): IPosition | undefined; - simulation: ID3SimulatorEngineSettingsUpdate; + simulation: Partial; render: Partial; + strategy: Partial; zoomFitTransitionMs: number; isOutOfBoundsDragEnabled: boolean; areCoordinatesRounded: boolean; @@ -32,17 +35,17 @@ export interface IDefaultViewSettings areCollapsedContainerDimensionsAllowed: boolean; } -export type IDefaultViewSettingsInit = Omit< - Partial>, +export type IOrbViewSettingsInit = Omit< + Partial>, 'render' > & { render?: Partial }; -export class DefaultView implements IOrbView> { +export class OrbView implements IOrbView> { private _container: HTMLElement; private _graph: IGraph; private _events: OrbEmitter; private _strategy: IEventStrategy; - private _settings: IDefaultViewSettings; + private _settings: IOrbViewSettings; private _canvas: HTMLCanvasElement; private readonly _renderer: IRenderer; @@ -54,11 +57,18 @@ export class DefaultView implements IO private _d3Zoom: ZoomBehavior; private _dragStartPosition: IPosition | undefined; - constructor(context: IOrbViewContext, settings?: Partial>) { - this._container = context.container; - this._graph = context.graph; - this._events = context.events; - this._strategy = context.strategy; + constructor(container: HTMLElement, settings?: Partial>) { + this._container = container; + this._graph = new Graph(undefined, { + onLoadedImages: () => { + // Not to call render() before user's .render() + if (this._renderer.isInitiallyRendered) { + this.render(); + } + }, + }); + this._graph.setDefaultStyle(getDefaultGraphStyle()); + this._events = new OrbEmitter(); this._settings = { getPosition: settings?.getPosition, @@ -75,8 +85,18 @@ export class DefaultView implements IO render: { ...settings?.render, }, + strategy: { + isDefaultHoverEnabled: true, + isDefaultSelectEnabled: true, + ...settings?.strategy, + }, }; + this._strategy = new DefaultEventStrategy({ + isDefaultSelectEnabled: this._settings.strategy.isDefaultSelectEnabled ?? false, + isDefaultHoverEnabled: this._settings.strategy.isDefaultHoverEnabled ?? false, + }); + setupContainer(this._container, this._settings.areCollapsedContainerDimensionsAllowed); this._canvas = this._initCanvas(); @@ -149,15 +169,19 @@ export class DefaultView implements IO this._simulator.setSettings(this._settings.simulation); } - isInitiallyRendered(): boolean { - return this._renderer.isInitiallyRendered; + get data(): IGraph { + return this._graph; + } + + get events(): OrbEmitter { + return this._events; } - getSettings(): IDefaultViewSettings { + getSettings(): IOrbViewSettings { return copyObject(this._settings); } - setSettings(settings: Partial>) { + setSettings(settings: Partial>) { if (settings.getPosition) { this._settings.getPosition = settings.getPosition; } @@ -174,6 +198,18 @@ export class DefaultView implements IO this._renderer.setSettings(settings.render); this._settings.render = this._renderer.getSettings(); } + + if (settings.strategy) { + if (isBoolean(settings.strategy.isDefaultHoverEnabled)) { + this._settings.strategy.isDefaultHoverEnabled = settings.strategy.isDefaultHoverEnabled; + this._strategy.isHoverEnabled = this._settings.strategy.isDefaultHoverEnabled; + } + + if (isBoolean(settings.strategy.isDefaultSelectEnabled)) { + this._settings.strategy.isDefaultSelectEnabled = settings.strategy.isDefaultSelectEnabled; + this._strategy.isSelectEnabled = this._settings.strategy.isDefaultSelectEnabled; + } + } } render(onRendered?: () => void) { @@ -309,39 +345,37 @@ export class DefaultView implements IO const mousePoint = this.getCanvasMousePosition(event); const simulationPoint = this._renderer.getSimulationPosition(mousePoint); - if (this._strategy.onMouseMove) { - const response = this._strategy.onMouseMove(this._graph, simulationPoint); - const subject = response.changedSubject; - - if (subject && response.isStateChanged) { - if (isNode(subject)) { - this._events.emit(OrbEventType.NODE_HOVER, { - node: subject, - event, - localPoint: simulationPoint, - globalPoint: mousePoint, - }); - } - if (isEdge(subject)) { - this._events.emit(OrbEventType.EDGE_HOVER, { - edge: subject, - event, - localPoint: simulationPoint, - globalPoint: mousePoint, - }); - } + const response = this._strategy.onMouseMove(this._graph, simulationPoint); + const subject = response.changedSubject; + + if (subject && response.isStateChanged) { + if (isNode(subject)) { + this._events.emit(OrbEventType.NODE_HOVER, { + node: subject, + event, + localPoint: simulationPoint, + globalPoint: mousePoint, + }); + } + if (isEdge(subject)) { + this._events.emit(OrbEventType.EDGE_HOVER, { + edge: subject, + event, + localPoint: simulationPoint, + globalPoint: mousePoint, + }); } + } - this._events.emit(OrbEventType.MOUSE_MOVE, { - subject, - event, - localPoint: simulationPoint, - globalPoint: mousePoint, - }); + this._events.emit(OrbEventType.MOUSE_MOVE, { + subject, + event, + localPoint: simulationPoint, + globalPoint: mousePoint, + }); - if (response.isStateChanged) { - this._renderer.render(this._graph); - } + if (response.isStateChanged) { + this._renderer.render(this._graph); } }; @@ -349,39 +383,37 @@ export class DefaultView implements IO const mousePoint = this.getCanvasMousePosition(event); const simulationPoint = this._renderer.getSimulationPosition(mousePoint); - if (this._strategy.onMouseClick) { - const response = this._strategy.onMouseClick(this._graph, simulationPoint); - const subject = response.changedSubject; - - if (subject) { - if (isNode(subject)) { - this._events.emit(OrbEventType.NODE_CLICK, { - node: subject, - event, - localPoint: simulationPoint, - globalPoint: mousePoint, - }); - } - if (isEdge(subject)) { - this._events.emit(OrbEventType.EDGE_CLICK, { - edge: subject, - event, - localPoint: simulationPoint, - globalPoint: mousePoint, - }); - } + const response = this._strategy.onMouseClick(this._graph, simulationPoint); + const subject = response.changedSubject; + + if (subject) { + if (isNode(subject)) { + this._events.emit(OrbEventType.NODE_CLICK, { + node: subject, + event, + localPoint: simulationPoint, + globalPoint: mousePoint, + }); + } + if (isEdge(subject)) { + this._events.emit(OrbEventType.EDGE_CLICK, { + edge: subject, + event, + localPoint: simulationPoint, + globalPoint: mousePoint, + }); } + } - this._events.emit(OrbEventType.MOUSE_CLICK, { - subject, - event, - localPoint: simulationPoint, - globalPoint: mousePoint, - }); + this._events.emit(OrbEventType.MOUSE_CLICK, { + subject, + event, + localPoint: simulationPoint, + globalPoint: mousePoint, + }); - if (response.isStateChanged || response.changedSubject) { - this._renderer.render(this._graph); - } + if (response.isStateChanged || response.changedSubject) { + this._renderer.render(this._graph); } }; diff --git a/src/views/shared.ts b/src/views/shared.ts index 88b771e..98c28aa 100644 --- a/src/views/shared.ts +++ b/src/views/shared.ts @@ -2,24 +2,13 @@ import { INodeBase } from '../models/node'; import { IEdgeBase } from '../models/edge'; import { IGraph } from '../models/graph'; import { OrbEmitter } from '../events'; -import { IEventStrategy } from '../models/strategy'; -export interface IOrbView { - isInitiallyRendered(): boolean; +export interface IOrbView { + data: IGraph; + events: OrbEmitter; getSettings(): S; setSettings(settings: Partial): void; render(onRendered?: () => void): void; recenter(onRendered?: () => void): void; destroy(): void; } - -export interface IOrbViewContext { - container: HTMLElement; - graph: IGraph; - events: OrbEmitter; - strategy: IEventStrategy; -} - -export type IOrbViewFactory = ( - context: IOrbViewContext, -) => IOrbView; From 2cfe2bb82c0e8c51e140dcb9e3d9adba2dba8d81 Mon Sep 17 00:00:00 2001 From: Toni Lastre Date: Tue, 4 Apr 2023 16:53:06 +0200 Subject: [PATCH 04/22] Chore: Release/1.0.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ddae81f..69050ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@memgraph/orb", - "version": "0.1.4", + "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@memgraph/orb", - "version": "0.1.4", + "version": "1.0.0", "license": "Apache-2.0", "dependencies": { "d3-drag": "3.0.0", diff --git a/package.json b/package.json index 70928e0..38c2c04 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@memgraph/orb", - "version": "0.2.0", + "version": "1.0.0", "description": "Graph visualization library", "engines": { "node": ">=16.0.0" From 0e9ffb63871142d68219f852d1b126c415708caa Mon Sep 17 00:00:00 2001 From: Abhinv Singh Parmar Date: Fri, 9 Jun 2023 21:26:36 +0530 Subject: [PATCH 05/22] New: Add support to get selected/hovered nodes and edges (#61) * New: Added support to get selected nodes and edges * New: Added support to get hovered nodes and edges --------- Co-authored-by: Abhinav Singh Parmar --- src/models/graph.ts | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/models/graph.ts b/src/models/graph.ts index 97e03ff..ff9c9ea 100644 --- a/src/models/graph.ts +++ b/src/models/graph.ts @@ -22,6 +22,10 @@ export interface IGraph { getEdgeCount(): number; getNodeById(id: any): INode | undefined; getEdgeById(id: any): IEdge | undefined; + getSelectedNodes(): INode[]; + getSelectedEdges(): IEdge[]; + getHoveredNodes(): INode[]; + getHoveredEdges(): IEdge[]; getNodePositions(): INodePosition[]; setNodePositions(positions: INodePosition[]): void; getEdgePositions(): IEdgePosition[]; @@ -118,6 +122,42 @@ export class Graph implements IGraph[] { + return this.getNodes((node) => node.isSelected()); + } + + /** + * Returns a list of selected edges. + * + * @return {IEdge[]} List of selected edges + */ + getSelectedEdges(): IEdge[] { + return this.getEdges((edge) => edge.isSelected()); + } + + /** + * Returns a list of hovered nodes. + * + * @return {INode[]} List of hovered nodes + */ + getHoveredNodes(): INode[] { + return this.getNodes((node) => node.isHovered()); + } + + /** + * Returns a list of hovered edges. + * + * @return {IEdge[]} List of hovered edges + */ + getHoveredEdges(): IEdge[] { + return this.getEdges((edge) => edge.isHovered()); + } + /** * Returns a list of current node positions (x, y). * From 21e18b4dadd01dbf2ee61fe391bc8f169452aa00 Mon Sep 17 00:00:00 2001 From: Abhinv Singh Parmar Date: Tue, 18 Jul 2023 21:09:01 +0530 Subject: [PATCH 06/22] New: Add support for enabling and disabling dragging of nodes (fixes #62) (#69) * New: Add feature to enable/disable node dragging (fixes #62) * New: Added support to modify interaction from setSettings * New: Updated documentation for interaction property --- docs/view-default.md | 20 ++++++++++++++++++++ src/views/orb-view.ts | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/docs/view-default.md b/docs/view-default.md index fc8f96a..e9abed0 100644 --- a/docs/view-default.md +++ b/docs/view-default.md @@ -80,6 +80,10 @@ interface IOrbViewSettings { isDefaultSelectEnabled: boolean; isDefaultHoverEnabled: boolean; }; + // For graph interaction + interaction: { + isDragEnabled: boolean; + }; // Other default view parameters zoomFitTransitionMs: number; isOutOfBoundsDragEnabled: boolean; @@ -149,6 +153,9 @@ const defaultSettings = { isDefaultSelectEnabled: true, isDefaultHoverEnabled: true, }, + interaction: { + isDragEnabled: true; + }, zoomFitTransitionMs: 200, isOutOfBoundsDragEnabled: false, areCoordinatesRounded: true, @@ -312,6 +319,19 @@ orb.events.on(OrbEventType.MOUSE_CLICK, (event) => { }); ``` +### Property `interaction` + +The optional property `interaction` has one property that you can enable/disable: + +* `isDragEnabled` - property controls the dragging behavior within the application. When it is set to `true`, dragging is enabled, allowing users to interact with nodes and edges by dragging them to different positions within the graph. On the other hand, when `isDragEnabled`` is set to false, dragging functionality is disabled, preventing users from moving or repositioning nodes and edges through dragging interactions. + +This property provides a straightforward way to enable or disable the dragging feature based on the needs and requirements of your application. By toggling the value of `isDragEnabled`, you can easily control whether users are allowed to interactively reposition elements within the graph by dragging them. e.g: + +```typescript +// Disable default drag interaction +orb.setSettings({ interaction: { isDragEnabled: false } }); +``` + ### Property `simulation` Fine-grained D3 simulation engine settings. They include `isPhysicsEnabled`, `alpha`, diff --git a/src/views/orb-view.ts b/src/views/orb-view.ts index 5d311f8..76b27d9 100644 --- a/src/views/orb-view.ts +++ b/src/views/orb-view.ts @@ -23,11 +23,16 @@ import { SimulatorEventType } from '../simulator/shared'; import { getDefaultGraphStyle } from '../models/style'; import { isBoolean } from '../utils/type.utils'; +export interface IGraphInteractionSettings { + isDragEnabled: boolean; +} + export interface IOrbViewSettings { getPosition?(node: INode): IPosition | undefined; simulation: Partial; render: Partial; strategy: Partial; + interaction: Partial; zoomFitTransitionMs: number; isOutOfBoundsDragEnabled: boolean; areCoordinatesRounded: boolean; @@ -90,6 +95,10 @@ export class OrbView implements IOrbVi isDefaultSelectEnabled: true, ...settings?.strategy, }, + interaction: { + isDragEnabled: true, + ...settings?.interaction + } }; this._strategy = new DefaultEventStrategy({ @@ -212,6 +221,16 @@ export class OrbView implements IOrbVi this._strategy.isSelectEnabled = this._settings.strategy.isDefaultSelectEnabled; } } + + // Check if interaction settings are provided + if (settings.interaction) { + // Check if isDragEnabled is a boolean value + if (isBoolean(settings.interaction.isDragEnabled)) { + // Update the internal isDragEnabled setting based on the provided value + this._settings.interaction.isDragEnabled = + settings.interaction.isDragEnabled; + } + } } render(onRendered?: () => void) { @@ -263,6 +282,11 @@ export class OrbView implements IOrbVi }; dragStarted = (event: D3DragEvent>) => { + // If drag is disabled then return + if(!this._settings.interaction.isDragEnabled) { + return; + } + const mousePoint = this.getCanvasMousePosition(event.sourceEvent); const simulationPoint = this._renderer.getSimulationPosition(mousePoint); @@ -278,6 +302,11 @@ export class OrbView implements IOrbVi }; dragged = (event: D3DragEvent>) => { + // If drag is disabled then return + if(!this._settings.interaction.isDragEnabled) { + return; + } + const mousePoint = this.getCanvasMousePosition(event.sourceEvent); const simulationPoint = this._renderer.getSimulationPosition(mousePoint); @@ -296,6 +325,11 @@ export class OrbView implements IOrbVi }; dragEnded = (event: D3DragEvent>) => { + // If drag is disabled then return + if(!this._settings.interaction.isDragEnabled) { + return; + } + const mousePoint = this.getCanvasMousePosition(event.sourceEvent); const simulationPoint = this._renderer.getSimulationPosition(mousePoint); From 985295931ae36b80a04ac12726f2e9e60f05f289 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Parmar Date: Tue, 18 Jul 2023 22:43:37 +0530 Subject: [PATCH 07/22] New: Add feature to enable/disable zoom (fixes memgraph#62) --- src/views/orb-view.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/views/orb-view.ts b/src/views/orb-view.ts index 76b27d9..f935b34 100644 --- a/src/views/orb-view.ts +++ b/src/views/orb-view.ts @@ -25,6 +25,7 @@ import { isBoolean } from '../utils/type.utils'; export interface IGraphInteractionSettings { isDragEnabled: boolean; + isZoomEnabled: boolean; } export interface IOrbViewSettings { @@ -97,6 +98,7 @@ export class OrbView implements IOrbVi }, interaction: { isDragEnabled: true, + isZoomEnabled: true, ...settings?.interaction } }; @@ -230,6 +232,13 @@ export class OrbView implements IOrbVi this._settings.interaction.isDragEnabled = settings.interaction.isDragEnabled; } + + // Check if isZoomEnabled is a boolean value + if (isBoolean(settings.interaction.isZoomEnabled)) { + // Update the internal isZoomEnabled setting based on the provided value + this._settings.interaction.isZoomEnabled = + settings.interaction.isZoomEnabled; + } } } @@ -346,6 +355,10 @@ export class OrbView implements IOrbVi }; zoomed = (event: D3ZoomEvent) => { + // If zoom is disabled then return + if(!this._settings.interaction.isZoomEnabled) { + return; + } this._renderer.transform = event.transform; setTimeout(() => { this._renderer.render(this._graph); From cceb75686ccbf067383853d4874aeef0231c8774 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Parmar Date: Tue, 18 Jul 2023 22:53:26 +0530 Subject: [PATCH 08/22] NEW: Updated documentation for interaction property --- docs/view-default.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/view-default.md b/docs/view-default.md index e9abed0..178efbb 100644 --- a/docs/view-default.md +++ b/docs/view-default.md @@ -321,15 +321,17 @@ orb.events.on(OrbEventType.MOUSE_CLICK, (event) => { ### Property `interaction` -The optional property `interaction` has one property that you can enable/disable: +The optional property `interaction` has two properties that you can enable/disable: * `isDragEnabled` - property controls the dragging behavior within the application. When it is set to `true`, dragging is enabled, allowing users to interact with nodes and edges by dragging them to different positions within the graph. On the other hand, when `isDragEnabled`` is set to false, dragging functionality is disabled, preventing users from moving or repositioning nodes and edges through dragging interactions. -This property provides a straightforward way to enable or disable the dragging feature based on the needs and requirements of your application. By toggling the value of `isDragEnabled`, you can easily control whether users are allowed to interactively reposition elements within the graph by dragging them. e.g: +* `isZoomEnabled` - This property controls the zooming behavior within the application. Setting it to `true` enables zooming, allowing users to interactively zoom in and out of the graph. Setting it to `false` disables zooming, restricting the user's ability to change the zoom level. + +These properties provide a straightforward way to enable or disable dragging and zooming features based on the needs and requirements of your application. By toggling the values of isDragEnabled and isZoomEnabled, you can easily control the interactivity options available to users. e.g: ```typescript -// Disable default drag interaction -orb.setSettings({ interaction: { isDragEnabled: false } }); +// Disable default drag interaction and enable zooming +orb.setSettings({ interaction: { isDragEnabled: false, isZoomEnabled: true } }); ``` ### Property `simulation` From e3a1f2461c99e967c8273064ec079dfff8728a4a Mon Sep 17 00:00:00 2001 From: Abhinav Singh Parmar Date: Fri, 21 Jul 2023 17:33:52 +0530 Subject: [PATCH 09/22] NEW: Updated documentation to include isDragEnabled --- docs/view-default.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/view-default.md b/docs/view-default.md index 178efbb..e564205 100644 --- a/docs/view-default.md +++ b/docs/view-default.md @@ -83,6 +83,7 @@ interface IOrbViewSettings { // For graph interaction interaction: { isDragEnabled: boolean; + isZoomEnabled: boolean; }; // Other default view parameters zoomFitTransitionMs: number; @@ -155,6 +156,7 @@ const defaultSettings = { }, interaction: { isDragEnabled: true; + isZoomEnabled: true; }, zoomFitTransitionMs: 200, isOutOfBoundsDragEnabled: false, From 900f989663bc72a25e5d4bf84ff2c2f6a88d5798 Mon Sep 17 00:00:00 2001 From: Abhinv Singh Parmar Date: Mon, 4 Sep 2023 19:08:42 +0530 Subject: [PATCH 10/22] New: Add support for custom edge line style (#77) * New Added support for custom edges * Refactor: Streamline edge rendering code and optimize line style handling --- docs/styles.md | 1 + src/models/edge.ts | 37 +++++++++++++++++++ src/renderer/canvas/edge/types/edge-curved.ts | 4 ++ .../canvas/edge/types/edge-loopback.ts | 4 ++ .../canvas/edge/types/edge-straight.ts | 4 ++ src/utils/type.utils.ts | 13 +++++++ 6 files changed, 63 insertions(+) diff --git a/docs/styles.md b/docs/styles.md index 9846ea3..b44e4e9 100644 --- a/docs/styles.md +++ b/docs/styles.md @@ -142,6 +142,7 @@ style properties: | `widthHover` | number | Edge line width on mouse hover event. If not defined `width` is used. | | `widthSelected` | number | Edge line width on mouse click event. If not defined `width` is used. | | `zIndex` | number | Specifies the stack order of an element during rendering. The default is `0`. | +| `lineStyle` | object | Allows to customize the style of edges in the graph visualization. The default is `{type: 'solid'}` | ## Default style values diff --git a/src/models/edge.ts b/src/models/edge.ts index 8fda65e..cb818b6 100644 --- a/src/models/edge.ts +++ b/src/models/edge.ts @@ -1,9 +1,12 @@ import { INodeBase, INode } from './node'; import { GraphObjectState } from './state'; import { Color, IPosition, ICircle, getDistanceToLine } from '../common'; +import { isArrayOfNumbers } from '../utils/type.utils'; const CURVED_CONTROL_POINT_OFFSET_MIN_SIZE = 4; const CURVED_CONTROL_POINT_OFFSET_MULTIPLIER = 4; +const DEFAULT_DASHED_LINE_PATTERN: number[] = [5, 5]; +const DEFAULT_DOTTED_LINE_PATTERN: number[] = [1, 1]; /** * Edge baseline object with required fields @@ -25,6 +28,19 @@ export interface IEdgePosition { target: any; } +export enum EdgeLineStyleType { + SOLID = 'solid', + DASHED = 'dashed', + DOTTED = 'dotted', + CUSTOM = 'custom', +} + +export type IEdgeLineStyle = + | { type: EdgeLineStyleType.SOLID } + | { type: EdgeLineStyleType.DASHED } + | { type: EdgeLineStyleType.DOTTED } + | { type: EdgeLineStyleType.CUSTOM; pattern: number[] }; + /** * Edge style properties used to style the edge (color, width, label, etc.). */ @@ -46,6 +62,7 @@ export type IEdgeStyle = Partial<{ widthHover: number; widthSelected: number; zIndex: number; + lineStyle: IEdgeLineStyle; }>; export interface IEdgeData { @@ -89,6 +106,7 @@ export interface IEdge { hasShadow(): boolean; getWidth(): number; getColor(): Color | string | undefined; + getLineDashPattern(): number[] | null; } export class EdgeFactory { @@ -256,6 +274,25 @@ abstract class Edge implements IEdge(data: IEdgeData): EdgeType => { diff --git a/src/renderer/canvas/edge/types/edge-curved.ts b/src/renderer/canvas/edge/types/edge-curved.ts index 184d1e8..5da1859 100644 --- a/src/renderer/canvas/edge/types/edge-curved.ts +++ b/src/renderer/canvas/edge/types/edge-curved.ts @@ -18,6 +18,10 @@ export const drawCurvedLine = ( context.beginPath(); context.moveTo(sourcePoint.x, sourcePoint.y); context.quadraticCurveTo(controlPoint.x, controlPoint.y, targetPoint.x, targetPoint.y); + + const lineDashPattern = edge.getLineDashPattern(); + context.setLineDash(lineDashPattern ?? []); + context.stroke(); }; diff --git a/src/renderer/canvas/edge/types/edge-loopback.ts b/src/renderer/canvas/edge/types/edge-loopback.ts index a283be8..6aaaaaa 100644 --- a/src/renderer/canvas/edge/types/edge-loopback.ts +++ b/src/renderer/canvas/edge/types/edge-loopback.ts @@ -13,6 +13,10 @@ export const drawLoopbackLine = ( context.beginPath(); context.arc(x, y, radius, 0, 2 * Math.PI, false); context.closePath(); + + const lineDashPattern = edge.getLineDashPattern(); + context.setLineDash(lineDashPattern ?? []); + context.stroke(); }; diff --git a/src/renderer/canvas/edge/types/edge-straight.ts b/src/renderer/canvas/edge/types/edge-straight.ts index 353e504..67cafdc 100644 --- a/src/renderer/canvas/edge/types/edge-straight.ts +++ b/src/renderer/canvas/edge/types/edge-straight.ts @@ -17,6 +17,10 @@ export const drawStraightLine = ( context.beginPath(); context.moveTo(sourcePoint.x, sourcePoint.y); context.lineTo(targetPoint.x, targetPoint.y); + + const lineDashPattern = edge.getLineDashPattern(); + context.setLineDash(lineDashPattern ?? []); + context.stroke(); }; diff --git a/src/utils/type.utils.ts b/src/utils/type.utils.ts index aea6dbc..8289cb7 100644 --- a/src/utils/type.utils.ts +++ b/src/utils/type.utils.ts @@ -87,3 +87,16 @@ export const isNull = (value: any): value is null => { export const isFunction = (value: any): value is Function => { return typeof value === 'function'; }; + +/** + * Type check for an array of numbers + * + * @param {any} value Any value + * @return {boolean} True if it is an array of numbers, false otherwise + */ +export const isArrayOfNumbers = (value: any): value is number[] => { + if (!isArray(value)) { + return false; + } + return value.every((element) => isNumber(element)); +}; From cdb3a6d49b9cdeb60a94f33587d24eebeb7ae2b7 Mon Sep 17 00:00:00 2001 From: Toni Date: Tue, 20 Feb 2024 11:48:29 +0100 Subject: [PATCH 11/22] New: Add support for handling device pixel ratio (#45) * Chore: Move container and canvas creation from the view to the renderer * New: Add devicePixelRatio render property and handler * Fix: Add default DPR for older browsers * Chore: Remove useless check for automatic DPR --- docs/view-default.md | 35 +++++--- docs/view-map.md | 31 +++++-- src/renderer/canvas/canvas-renderer.ts | 117 +++++++++++++++++++++---- src/renderer/factory.ts | 16 +--- src/renderer/shared.ts | 20 +++-- src/renderer/webgl/webgl-renderer.ts | 49 +++++++++-- src/utils/html.utils.ts | 35 ++++++++ src/views/orb-map-view.ts | 55 ++++-------- src/views/orb-view.ts | 58 ++++-------- 9 files changed, 272 insertions(+), 144 deletions(-) diff --git a/docs/view-default.md b/docs/view-default.md index 598dae6..12ea901 100644 --- a/docs/view-default.md +++ b/docs/view-default.md @@ -63,6 +63,7 @@ interface IOrbViewSettings { }; // For canvas rendering and events render: { + devicePixelRatio: number | null; fps: number; minZoom: number; maxZoom: number; @@ -74,6 +75,7 @@ interface IOrbViewSettings { contextAlphaOnEvent: number; contextAlphaOnEventIsEnabled: boolean; backgroundColor: Color | string | null; + areCollapsedContainerDimensionsAllowed: boolean; }; // For select and hover look-and-feel strategy: { @@ -90,7 +92,6 @@ interface IOrbViewSettings { isOutOfBoundsDragEnabled: boolean; areCoordinatesRounded: boolean; isSimulationAnimated: boolean; - areCollapsedContainerDimensionsAllowed: boolean; } ``` @@ -138,6 +139,7 @@ const defaultSettings = { }, }, render: { + devicePixelRatio: window.devicePixelRatio, fps: 60, minZoom: 0.25, maxZoom: 8, @@ -149,6 +151,7 @@ const defaultSettings = { contextAlphaOnEvent: 0.3, contextAlphaOnEventIsEnabled: true, backgroundColor: null, + areCollapsedContainerDimensionsAllowed: false, }, strategy: { isDefaultSelectEnabled: true, @@ -162,7 +165,6 @@ const defaultSettings = { isOutOfBoundsDragEnabled: false, areCoordinatesRounded: true, isSimulationAnimated: true, - areCollapsedContainerDimensionsAllowed: false; } ``` @@ -269,6 +271,26 @@ Here you can use your original properties to indicate which ones represent your Optional property `render` has several rendering options that you can tweak. Read more about them on [Styling guide](./styles.md). +#### Property `render.devicePixelRatio` + +`devicePixelRatio` is useful when dealing with the difference between rendering on a standard +display versus a HiDPI or Retina display, which uses more screen pixels to draw the same +objects, resulting in a sharper image. ([Reference: MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio)). +Orb will listen for `devicePixelRatio` changes and handles them by default. You can override the +value with a settings property `render.devicePixelRatio`. Once a custom value is provided, Orb will +stop listening for `devicePixelRatio` changes. +If you want to return automatic `devicePixelRatio` handling, just set `render.devicePixelRatio` +to `null`. + +#### Property `render.areCollapsedContainerDimensionsAllowed` + +Enables setting the dimensions of the Orb container element to zero. +If the container element of Orb has collapsed dimensions (`width: 0;` or `height: 0;`), +Orb will expand the container by setting the values to `100%`. +If that doesn't work (the parent of the container also has collapsed dimensions), +Orb will set an arbitrary fixed dimension to the container. +Disabled by default (`false`). + ### Property `strategy` The optional property `strategy` has two properties that you can enable/disable: @@ -362,15 +384,6 @@ Shows the process of simulation where the nodes are moved by the physics engine converge to a stable position. If disabled, the graph will suddenly appear in its final position. Enabled by default (`true`). -### Property `areCollapsedContainerDimensionsAllowed` - -Enables setting the dimensions of the Orb container element to zero. -If the container element of Orb has collapsed dimensions (`width: 0;` or `height: 0;`), -Orb will expand the container by setting the values to `100%`. -If that doesn't work (the parent of the container also has collapsed dimensions), -Orb will set an arbitrary fixed dimension to the container. -Disabled by default (`false`). - ## Settings The above settings of the `OrbView` can be defined on view initialization, but also anytime diff --git a/docs/view-map.md b/docs/view-map.md index f5dc6c9..26c1cb8 100644 --- a/docs/view-map.md +++ b/docs/view-map.md @@ -116,6 +116,7 @@ interface IOrbMapViewSettings { getGeoPosition(node: INode): { lat: number; lng: number } | undefined; // For canvas rendering and events render: { + devicePixelRatio: number | null; fps: number; minZoom: number; maxZoom: number; @@ -147,6 +148,7 @@ The default settings that `OrbMapView` uses is: ```typescript const defaultSettings = { render: { + devicePixelRatio: window.devicePixelRatio, fps: 60, minZoom: 0.25, maxZoom: 8, @@ -191,6 +193,26 @@ Optional property `map` has two properties that you can set which are: Optional property `render` has several rendering options that you can tweak. Read more about them on [Styling guide](./styles.md). +#### Property `render.devicePixelRatio` + +`devicePixelRatio` is useful when dealing with the difference between rendering on a standard +display versus a HiDPI or Retina display, which uses more screen pixels to draw the same +objects, resulting in a sharper image. ([Reference: MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio)). +Orb will listen for `devicePixelRatio` changes and handles them by default. You can override the +value with a settings property `render.devicePixelRatio`. Once a custom value is provided, Orb will +stop listening for `devicePixelRatio` changes. +If you want to return automatic `devicePixelRatio` handling, just set `render.devicePixelRatio` +to `null`. + +#### Property `render.areCollapsedContainerDimensionsAllowed` + +Enables setting the dimensions of the Orb container element to zero. +If the container element of Orb has collapsed dimensions (`width: 0;` or `height: 0;`), +Orb will expand the container by setting the values to `100%`. +If that doesn't work (the parent of the container also has collapsed dimensions), +Orb will set an arbitrary fixed dimension to the container. +Disabled by default (`false`). + ### Property `strategy` The optional property `strategy` has two properties that you can enable/disable: @@ -243,15 +265,6 @@ orb.events.on(OrbEventType.MOUSE_CLICK, (event) => { }); ``` -### Property `areCollapsedContainerDimensionsAllowed` - -Enables setting the dimensions of the Orb container element to zero. -If the container element of Orb has collapsed dimensions (`width: 0;` or `height: 0;`), -Orb will expand the container by setting the values to `100%`. -If that doesn't work (the parent of the container also has collapsed dimensions), -Orb will set an arbitrary fixed dimension to the container. -Disabled by default (`false`). - ## Settings The above settings of `OrbMapView` can be defined on view initialization, but also anytime after the diff --git a/src/renderer/canvas/canvas-renderer.ts b/src/renderer/canvas/canvas-renderer.ts index 0625c9b..9265d93 100644 --- a/src/renderer/canvas/canvas-renderer.ts +++ b/src/renderer/canvas/canvas-renderer.ts @@ -18,6 +18,14 @@ import { import { throttle } from '../../utils/function.utils'; import { getThrottleMsFromFPS } from '../../utils/math.utils'; import { copyObject } from '../../utils/object.utils'; +import { + appendCanvas, + IObserveDPRUnsubscribe, + observeDevicePixelRatioChanges, + setupContainer, +} from '../../utils/html.utils'; +import { OrbError } from '../../exceptions'; +import { isNumber } from '../../utils/type.utils'; const DEBUG = false; const DEBUG_RED = '#FF5733'; @@ -26,12 +34,16 @@ const DEBUG_BLUE = '#3383FF'; const DEBUG_PINK = '#F333FF'; export class CanvasRenderer extends Emitter implements IRenderer { + private readonly _container: HTMLElement; + private readonly _canvas: HTMLCanvasElement; + private _resizeObs: ResizeObserver; + // Contains the HTML5 Canvas element which is used for drawing nodes and edges. private readonly _context: CanvasRenderingContext2D; // Width and height of the canvas. Used for clearing - public width: number; - public height: number; + private _width: number; + private _height: number; private _settings: IRendererSettings; // Includes translation (pan) in the x and y direction @@ -45,23 +57,58 @@ export class CanvasRenderer extends Em private _isInitiallyRendered = false; private _throttleRender: (graph: IGraph) => void; + private _dprObserveUnsubscribe?: IObserveDPRUnsubscribe; - constructor(context: CanvasRenderingContext2D, settings?: Partial) { + constructor(container: HTMLElement, settings?: Partial) { super(); + setupContainer(container, settings?.areCollapsedContainerDimensionsAllowed); + this._container = container; + this._canvas = appendCanvas(container); + + const context = this._canvas.getContext('2d'); + if (!context) { + throw new OrbError('Failed to create Canvas context.'); + } + this._context = context; - this.width = DEFAULT_RENDERER_WIDTH; - this.height = DEFAULT_RENDERER_HEIGHT; + this._width = DEFAULT_RENDERER_WIDTH; + this._height = DEFAULT_RENDERER_HEIGHT; this.transform = zoomIdentity; this._settings = { ...DEFAULT_RENDERER_SETTINGS, ...settings, }; + // Resize the canvas based on the dimensions of its parent container
. + this._resizeObs = new ResizeObserver(() => this._resize()); + this._resizeObs.observe(this._container); + this._resize(); + + if (!isNumber(settings?.devicePixelRatio)) { + this._dprObserveUnsubscribe = observeDevicePixelRatioChanges(() => this._resize()); + } + this._throttleRender = throttle((graph: IGraph) => { this._render(graph); }, getThrottleMsFromFPS(this._settings.fps)); } + get width(): number { + return this._width; + } + + get height(): number { + return this._height; + } + + get container(): HTMLElement { + return this._container; + } + + get canvas(): HTMLCanvasElement { + return this._canvas; + } + get isInitiallyRendered(): boolean { return this._isInitiallyRendered; } @@ -72,6 +119,9 @@ export class CanvasRenderer extends Em setSettings(settings: Partial) { const isFpsChanged = settings.fps && settings.fps !== this._settings.fps; + const previousDprValue = this._settings.devicePixelRatio; + const newDprValue = settings.devicePixelRatio; + this._settings = { ...this._settings, ...settings, @@ -82,6 +132,17 @@ export class CanvasRenderer extends Em this._render(graph); }, getThrottleMsFromFPS(this._settings.fps)); } + + // Change DPR from automatic to manual handling or change DPR value manually + if (!isNumber(previousDprValue) && isNumber(newDprValue)) { + this._dprObserveUnsubscribe?.(); + this._resize(); + } + + // Change DPR from manual to automatic handling + if (isNumber(previousDprValue) && newDprValue === null) { + this._dprObserveUnsubscribe = observeDevicePixelRatioChanges(() => this._resize()); + } } render(graph: IGraph) { @@ -97,30 +158,30 @@ export class CanvasRenderer extends Em const renderStartedAt = Date.now(); // Clear drawing. - this._context.clearRect(0, 0, this.width, this.height); + this._context.clearRect(0, 0, this._width, this._height); if (this._settings.backgroundColor) { this._context.fillStyle = this._settings.backgroundColor.toString(); - this._context.fillRect(0, 0, this.width, this.height); + this._context.fillRect(0, 0, this._width, this._height); } this._context.save(); if (DEBUG) { this._context.lineWidth = 3; this._context.fillStyle = DEBUG_RED; - this._context.fillRect(0, 0, this.width, this.height); + this._context.fillRect(0, 0, this._width, this._height); } // Apply any scaling (zoom) or translation (pan) transformations. this._context.translate(this.transform.x, this.transform.y); if (DEBUG) { this._context.fillStyle = DEBUG_BLUE; - this._context.fillRect(0, 0, this.width, this.height); + this._context.fillRect(0, 0, this._width, this._height); } this._context.scale(this.transform.k, this.transform.k); if (DEBUG) { this._context.fillStyle = DEBUG_GREEN; - this._context.fillRect(0, 0, this.width, this.height); + this._context.fillRect(0, 0, this._width, this._height); } // Move coordinates (0, 0) to canvas center. @@ -129,11 +190,11 @@ export class CanvasRenderer extends Em // relative to (0, 0), so any source mouse event position needs to take this // offset into account. (Handled in getMousePos()) if (this._isOriginCentered) { - this._context.translate(this.width / 2, this.height / 2); + this._context.translate(this._width / 2, this._height / 2); } if (DEBUG) { this._context.fillStyle = DEBUG_PINK; - this._context.fillRect(0, 0, this.width, this.height); + this._context.fillRect(0, 0, this._width, this._height); } this.drawObjects(graph.getEdges()); @@ -195,6 +256,23 @@ export class CanvasRenderer extends Em } } + private _resize() { + const dpr = this._settings.devicePixelRatio || window.devicePixelRatio || 1; + + const containerSize = this._container.getBoundingClientRect(); + this._canvas.style.width = `${containerSize.width}px`; + this._canvas.style.height = `${containerSize.height}px`; + this._canvas.width = containerSize.width * dpr; + this._canvas.height = containerSize.height * dpr; + + // Normalize coordinate system to use CSS pixels + this._context.scale(dpr, dpr); + + this._width = containerSize.width; + this._height = containerSize.height; + this.emit(RenderEventType.RESIZE, undefined); + } + private drawObject(obj: INode | IEdge, options?: Partial | Partial) { if (isNode(obj)) { drawNode(this._context, obj, options); @@ -207,7 +285,7 @@ export class CanvasRenderer extends Em this.transform = zoomIdentity; // Clear drawing. - this._context.clearRect(0, 0, this.width, this.height); + this._context.clearRect(0, 0, this._width, this._height); this._context.save(); } @@ -252,8 +330,8 @@ export class CanvasRenderer extends Em // simulation coordinates (O) when dragging and hovering nodes. const [x, y] = this.transform.invert([canvasPoint.x, canvasPoint.y]); return { - x: x - this.width / 2, - y: y - this.height / 2, + x: x - this._width / 2, + y: y - this._height / 2, }; } @@ -264,7 +342,7 @@ export class CanvasRenderer extends Em */ getSimulationViewRectangle(): IRectangle { const topLeftPosition = this.getSimulationPosition({ x: 0, y: 0 }); - const bottomRightPosition = this.getSimulationPosition({ x: this.width, y: this.height }); + const bottomRightPosition = this.getSimulationPosition({ x: this._width, y: this._height }); return { x: topLeftPosition.x, y: topLeftPosition.y, @@ -276,4 +354,11 @@ export class CanvasRenderer extends Em translateOriginToCenter() { this._isOriginCentered = true; } + + destroy(): void { + this._resizeObs.unobserve(this._container); + this._dprObserveUnsubscribe?.(); + this.removeAllListeners(); + this._canvas.outerHTML = ''; + } } diff --git a/src/renderer/factory.ts b/src/renderer/factory.ts index 9cc76a9..4fd245c 100644 --- a/src/renderer/factory.ts +++ b/src/renderer/factory.ts @@ -1,28 +1,18 @@ import { CanvasRenderer } from './canvas/canvas-renderer'; import { IRenderer, IRendererSettings, RendererType } from './shared'; import { WebGLRenderer } from './webgl/webgl-renderer'; -import { OrbError } from '../exceptions'; import { INodeBase } from '../models/node'; import { IEdgeBase } from '../models/edge'; export class RendererFactory { static getRenderer( - canvas: HTMLCanvasElement, + container: HTMLElement, type: RendererType = RendererType.CANVAS, settings?: Partial, ): IRenderer { if (type === RendererType.WEBGL) { - const context = canvas.getContext('webgl2'); - if (!context) { - throw new OrbError('Failed to create WebGL context.'); - } - return new WebGLRenderer(context, settings); + return new WebGLRenderer(container, settings); } - - const context = canvas.getContext('2d'); - if (!context) { - throw new OrbError('Failed to create Canvas context.'); - } - return new CanvasRenderer(context, settings); + return new CanvasRenderer(container, settings); } } diff --git a/src/renderer/shared.ts b/src/renderer/shared.ts index fe945b0..a5719bc 100644 --- a/src/renderer/shared.ts +++ b/src/renderer/shared.ts @@ -11,11 +11,13 @@ export enum RendererType { } export enum RenderEventType { + RESIZE = 'resize', RENDER_START = 'render-start', RENDER_END = 'render-end', } export interface IRendererSettings { + devicePixelRatio: number | null; fps: number; minZoom: number; maxZoom: number; @@ -27,6 +29,7 @@ export interface IRendererSettings { contextAlphaOnEvent: number; contextAlphaOnEventIsEnabled: boolean; backgroundColor: Color | string | null; + areCollapsedContainerDimensionsAllowed: boolean; } export interface IRendererSettingsInit extends IRendererSettings { @@ -34,31 +37,30 @@ export interface IRendererSettingsInit extends IRendererSettings { } export type RendererEvents = { + [RenderEventType.RESIZE]: undefined; [RenderEventType.RENDER_START]: undefined; [RenderEventType.RENDER_END]: { durationMs: number }; }; export interface IRenderer extends IEmitter { - // Width and height of the canvas. Used for clearing. - width: number; - height: number; - // Includes translation (pan) in the x and y direction // as well as scaling (level of zoom). transform: ZoomTransform; + // Width and height of the canvas + get width(): number; + get height(): number; + get container(): HTMLElement; + get canvas(): HTMLCanvasElement; get isInitiallyRendered(): boolean; getSettings(): IRendererSettings; - setSettings(settings: Partial): void; render(graph: IGraph): void; - reset(): void; getFitZoomTransform(graph: IGraph): ZoomTransform; - getSimulationPosition(canvasPoint: IPosition): IPosition; /** @@ -69,9 +71,12 @@ export interface IRenderer extends IEm getSimulationViewRectangle(): IRectangle; translateOriginToCenter(): void; + + destroy(): void; } export const DEFAULT_RENDERER_SETTINGS: IRendererSettings = { + devicePixelRatio: null, fps: 60, minZoom: 0.25, maxZoom: 8, @@ -83,6 +88,7 @@ export const DEFAULT_RENDERER_SETTINGS: IRendererSettings = { contextAlphaOnEvent: 0.3, contextAlphaOnEventIsEnabled: true, backgroundColor: null, + areCollapsedContainerDimensionsAllowed: false, }; export const DEFAULT_RENDERER_WIDTH = 640; diff --git a/src/renderer/webgl/webgl-renderer.ts b/src/renderer/webgl/webgl-renderer.ts index 9f7115f..52ba3a1 100644 --- a/src/renderer/webgl/webgl-renderer.ts +++ b/src/renderer/webgl/webgl-renderer.ts @@ -13,28 +13,58 @@ import { IRendererSettings, } from '../shared'; import { copyObject } from '../../utils/object.utils'; +import { appendCanvas, setupContainer } from '../../utils/html.utils'; +import { OrbError } from '../../exceptions'; export class WebGLRenderer extends Emitter implements IRenderer { + private readonly _container: HTMLElement; + private readonly _canvas: HTMLCanvasElement; + // Contains the HTML5 Canvas element which is used for drawing nodes and edges. private readonly _context: WebGL2RenderingContext; - width: number; - height: number; + private _width: number; + private _height: number; private _settings: IRendererSettings; transform: ZoomTransform; - constructor(context: WebGL2RenderingContext, settings?: Partial) { + constructor(container: HTMLElement, settings?: Partial) { super(); - this._context = context; - console.log('context', this._context); + setupContainer(container, settings?.areCollapsedContainerDimensionsAllowed); + this._container = container; + this._canvas = appendCanvas(container); + const context = this._canvas.getContext('webgl2'); - this.width = DEFAULT_RENDERER_WIDTH; - this.height = DEFAULT_RENDERER_HEIGHT; + if (!context) { + throw new OrbError('Failed to create WebGL context.'); + } + + this._context = context; + this._width = DEFAULT_RENDERER_WIDTH; + this._height = DEFAULT_RENDERER_HEIGHT; this.transform = zoomIdentity; this._settings = { ...DEFAULT_RENDERER_SETTINGS, ...settings, }; + + console.log('context', this._context); + } + + get width(): number { + return this._width; + } + + get height(): number { + return this._height; + } + + get container(): HTMLElement { + return this._container; + } + + get canvas(): HTMLCanvasElement { + return this._canvas; } get isInitiallyRendered(): boolean { @@ -78,4 +108,9 @@ export class WebGLRenderer extends Emi translateOriginToCenter(): void { throw new Error('Method not implemented.'); } + + destroy(): void { + this.removeAllListeners(); + this._canvas.outerHTML = ''; + } } diff --git a/src/utils/html.utils.ts b/src/utils/html.utils.ts index 0b02415..deef5b1 100644 --- a/src/utils/html.utils.ts +++ b/src/utils/html.utils.ts @@ -48,3 +48,38 @@ export const isCollapsedDimension = (dimension: string | null | undefined) => { return collapsedDimensionRegex.test(dimension); }; + +export const appendCanvas = (container: HTMLElement): HTMLCanvasElement => { + const canvas = document.createElement('canvas'); + canvas.style.position = 'absolute'; + canvas.style.top = '0'; + canvas.style.left = '0'; + container.appendChild(canvas); + return canvas; +}; + +export type IObserveDPRCallback = (devicePixelRatio: number) => void; +export type IObserveDPRUnsubscribe = () => void; + +export const observeDevicePixelRatioChanges = (callback: IObserveDPRCallback): IObserveDPRUnsubscribe => { + let currentDpr = window.devicePixelRatio; + let unsubscribe: IObserveDPRUnsubscribe = () => { + return; + }; + + const listenForDPRChanges = () => { + unsubscribe(); + + const media = matchMedia(`(resolution: ${currentDpr}dppx)`); + media.addEventListener('change', listenForDPRChanges); + unsubscribe = () => media.removeEventListener('change', listenForDPRChanges); + + if (window.devicePixelRatio !== currentDpr) { + currentDpr = window.devicePixelRatio; + callback(currentDpr); + } + }; + + listenForDPRChanges(); + return () => unsubscribe(); +}; diff --git a/src/views/orb-map-view.ts b/src/views/orb-map-view.ts index 83f994a..01211ab 100644 --- a/src/views/orb-map-view.ts +++ b/src/views/orb-map-view.ts @@ -9,7 +9,6 @@ import { copyObject } from '../utils/object.utils'; import { OrbEmitter, OrbEventType } from '../events'; import { IRenderer, RendererType, RenderEventType, IRendererSettingsInit, IRendererSettings } from '../renderer/shared'; import { RendererFactory } from '../renderer/factory'; -import { setupContainer } from '../utils/html.utils'; import { getDefaultGraphStyle } from '../models/style'; import { isBoolean } from '../utils/type.utils'; @@ -67,14 +66,11 @@ export type IOrbMapViewSettingsUpdate export class OrbMapView implements IOrbView> { private _container: HTMLElement; - private _resizeObs: ResizeObserver; private _graph: IGraph; private _events: OrbEmitter; private _strategy: IEventStrategy; private _settings: IOrbMapViewSettings; - - private _canvas: HTMLCanvasElement; private _map: HTMLDivElement; private readonly _renderer: IRenderer; @@ -116,12 +112,12 @@ export class OrbMapView implements IOr isDefaultHoverEnabled: this._settings.strategy.isDefaultHoverEnabled ?? false, }); - setupContainer(this._container); - this._canvas = this._initCanvas(); - this._map = this._initMap(); - try { - this._renderer = RendererFactory.getRenderer(this._canvas, settings?.render?.type, this._settings.render); + this._renderer = RendererFactory.getRenderer( + this._container, + settings?.render?.type, + this._settings.render, + ); } catch (error: any) { this._container.textContent = error.message; throw error; @@ -129,12 +125,18 @@ export class OrbMapView implements IOr this._renderer.on(RenderEventType.RENDER_END, (data) => { this._events.emit(OrbEventType.RENDER_END, data); }); + this._renderer.on(RenderEventType.RESIZE, () => { + if (this._renderer.isInitiallyRendered) { + this._leaflet.invalidateSize(false); + this._renderer.render(this._graph); + } + }); + this._settings.render = this._renderer.getSettings(); + this._renderer.canvas.style.zIndex = '2'; + this._renderer.canvas.style.pointerEvents = 'none'; - // Resize the canvas based on the dimensions of it's parent container
. - this._resizeObs = new ResizeObserver(() => this._handleResize()); - this._resizeObs.observe(this._container); - this._handleResize(); + this._map = this._initMap(); this._leaflet = this._initLeaflet(); // Setting up leaflet map tile @@ -208,23 +210,10 @@ export class OrbMapView implements IOr } destroy() { - this._resizeObs.unobserve(this._container); - this._renderer.removeAllListeners(); + this._renderer.destroy(); this._leaflet.off(); this._leaflet.remove(); this._leaflet.getContainer().outerHTML = ''; - this._canvas.outerHTML = ''; - } - - private _initCanvas() { - const canvas = document.createElement('canvas'); - canvas.style.position = 'absolute'; - canvas.style.width = '100%'; - canvas.style.zIndex = '2'; - canvas.style.pointerEvents = 'none'; - - this._container.appendChild(canvas); - return canvas; } private _initMap() { @@ -442,18 +431,6 @@ export class OrbMapView implements IOr } } - private _handleResize() { - const containerSize = this._container.getBoundingClientRect(); - this._canvas.width = containerSize.width; - this._canvas.height = containerSize.height; - this._renderer.width = containerSize.width; - this._renderer.height = containerSize.height; - if (this._renderer.isInitiallyRendered) { - this._leaflet.invalidateSize(false); - this._renderer.render(this._graph); - } - } - private _handleTileChange() { const newTile: ILeafletMapTile = this._settings.map.tile; diff --git a/src/views/orb-view.ts b/src/views/orb-view.ts index 932cb6a..d4832b6 100644 --- a/src/views/orb-view.ts +++ b/src/views/orb-view.ts @@ -18,7 +18,6 @@ import { copyObject } from '../utils/object.utils'; import { OrbEmitter, OrbEventType } from '../events'; import { IRenderer, RenderEventType, IRendererSettingsInit, IRendererSettings } from '../renderer/shared'; import { RendererFactory } from '../renderer/factory'; -import { setupContainer } from '../utils/html.utils'; import { SimulatorEventType } from '../simulator/shared'; import { getDefaultGraphStyle } from '../models/style'; import { isBoolean } from '../utils/type.utils'; @@ -38,7 +37,6 @@ export interface IOrbViewSettings { isOutOfBoundsDragEnabled: boolean; areCoordinatesRounded: boolean; isSimulationAnimated: boolean; - areCollapsedContainerDimensionsAllowed: boolean; } export type IOrbViewSettingsInit = Omit< @@ -48,12 +46,10 @@ export type IOrbViewSettingsInit = Omi export class OrbView implements IOrbView> { private _container: HTMLElement; - private _resizeObs: ResizeObserver; private _graph: IGraph; private _events: OrbEmitter; private _strategy: IEventStrategy; private _settings: IOrbViewSettings; - private _canvas: HTMLCanvasElement; private readonly _renderer: IRenderer; private readonly _simulator: ISimulator; @@ -83,7 +79,6 @@ export class OrbView implements IOrbVi isOutOfBoundsDragEnabled: false, areCoordinatesRounded: true, isSimulationAnimated: true, - areCollapsedContainerDimensionsAllowed: false, ...settings, simulation: { isPhysicsEnabled: false, @@ -109,11 +104,12 @@ export class OrbView implements IOrbVi isDefaultHoverEnabled: this._settings.strategy.isDefaultHoverEnabled ?? false, }); - setupContainer(this._container, this._settings.areCollapsedContainerDimensionsAllowed); - this._canvas = this._initCanvas(); - try { - this._renderer = RendererFactory.getRenderer(this._canvas, settings?.render?.type, this._settings.render); + this._renderer = RendererFactory.getRenderer( + this._container, + settings?.render?.type, + this._settings.render, + ); } catch (error: any) { this._container.textContent = error.message; throw error; @@ -124,22 +120,23 @@ export class OrbView implements IOrbVi this._renderer.on(RenderEventType.RENDER_END, (data) => { this._events.emit(OrbEventType.RENDER_END, data); }); + this._renderer.on(RenderEventType.RESIZE, () => { + if (this._renderer.isInitiallyRendered) { + this._renderer.render(this._graph); + } + }); + this._renderer.translateOriginToCenter(); this._settings.render = this._renderer.getSettings(); - // Resize the canvas based on the dimensions of its parent container
. - this._resizeObs = new ResizeObserver(() => this._handleResize()); - this._resizeObs.observe(this._container); - this._handleResize(); - this._d3Zoom = zoom() .scaleExtent([this._renderer.getSettings().minZoom, this._renderer.getSettings().maxZoom]) .on('zoom', this.zoomed); - select(this._canvas) + select(this._renderer.canvas) .call( drag() - .container(this._canvas) + .container(this._renderer.canvas) .subject(this.dragSubject) .on('start', this.dragStarted) .on('drag', this.dragged) @@ -266,7 +263,7 @@ export class OrbView implements IOrbVi recenter(onRendered?: () => void) { const fitZoomTransform = this._renderer.getFitZoomTransform(this._graph); - select(this._canvas) + select(this._renderer.canvas) .transition() .duration(this._settings.zoomFitTransitionMs) .ease(easeLinear) @@ -278,10 +275,8 @@ export class OrbView implements IOrbVi } destroy() { - this._resizeObs.unobserve(this._container); - this._renderer.removeAllListeners(); + this._renderer.destroy(); this._simulator.terminate(); - this._canvas.outerHTML = ''; } dragSubject = (event: D3DragEvent>) => { @@ -367,7 +362,7 @@ export class OrbView implements IOrbVi }; getCanvasMousePosition(event: MouseEvent): IPosition { - const rect = this._canvas.getBoundingClientRect(); + const rect = this._renderer.canvas.getBoundingClientRect(); let x = event.clientX ?? event.pageX ?? event.x; let y = event.clientY ?? event.pageY ?? event.y; @@ -542,27 +537,6 @@ export class OrbView implements IOrbVi } }; - private _initCanvas(): HTMLCanvasElement { - const canvas = document.createElement('canvas'); - canvas.style.position = 'absolute'; - canvas.style.top = '0'; - canvas.style.left = '0'; - - this._container.appendChild(canvas); - return canvas; - } - - private _handleResize() { - const containerSize = this._container.getBoundingClientRect(); - this._canvas.width = containerSize.width; - this._canvas.height = containerSize.height; - this._renderer.width = containerSize.width; - this._renderer.height = containerSize.height; - if (this._renderer.isInitiallyRendered) { - this._renderer.render(this._graph); - } - } - private _startSimulation() { const nodePositions = this._graph.getNodePositions(); const edgePositions = this._graph.getEdgePositions(); From 2530739140b3053566bbc21b5cd00fbfbe69140f Mon Sep 17 00:00:00 2001 From: Toni Date: Wed, 27 Mar 2024 12:43:18 +0100 Subject: [PATCH 12/22] New: Add new simulator (#56) (#57) * New: Add new simulator (#56) * New: Add simulator scenarios for manual testing * New: Refactor simulator (WIP) * New: Add progress overlay, Update descriptions * Fix: Introduce new simulator event, Fix main-thread behavior * Fix: Rearrange class methods based on visibility * Fix: Improve naming * Chore(release): 0.2.0 * Fix: Tweak simulator, adjust API slightly * Fix: Temporarily patch some physics behavior * Fix: Adjust re-heating parameters * Fix: tweak physics behavior -> immediately stop sim when disabling * Chore: Remove the beta from release branches --------- Co-authored-by: dlozic * New: Add zoom and recenter functions (#74) * New: Add zoom and recenter functions * Fix: Reduce excessive recentering (#75) * Fix: Remove excessive recenterings * Fix: Remove unused code * Fix: New simulator (#92) * Chore: Refactor naming * New: Add new events * Chore: Refactor code styling * Docs: Remove unused flags * Chore: Remove unused simulation functions * Chore: Refactor view render function calls * Chore: Add missing tests * New: Add removal functions (#96) * New: Add removal functions * Fix: Add missing callback data * Chore: Refactor remove return values * Chore: Refactor remove function type usage * Fix: Default settings for node placement (#98) * New: Add properties setters and getters (#93) * New: Add node properties setters * New: Add edge properties setters * New: Add properties getters * New: Add patch for nodes and edges * Fix: Make getters return copies * Fix: Edge factory listeners copying * Fix: Jest outdated tests * Fix: Github actions node version * Chore: Refactor observer interface * Chore: Refactor node/edge constructor settings * Chore: Refactor node/edge function grouping * Chore: Refactor node/edge function grouping * Fix: Listeners behaviour * Chore: Refactor property copying * Chore: Refactor subject implementation * Fix: Set position behaviour on node drag * Chore: Upgrade node version * Chore: Refactor function type check * Fix: Remove listener behaviour * Chore: Refactor util naming * Chore: Remove unused type assertion * Chore: Refactor position setter options * Chore: Refactor property patch function * Fix: Set map node position behaviour * Chore: Refactor simulator data patching * Chore: Change observers to callbacks * New: Add state setters with options (#95) * New: Add state setters with options * Chore: Remove leftover comments * Chore: Refactor state setter logic * Chore: Refactor state types * Fix: Rename merged function usage * Fix: Merged variable naming * Chore: Fix tests --------- Co-authored-by: dlozic Co-authored-by: Oleksandr Ichenskyi <55350107+AlexIchenskiy@users.noreply.github.com> Co-authored-by: AlexIchenskiy --- .github/workflows/build.yml | 2 +- .github/workflows/release.yml | 2 +- .releaserc | 6 +- README.md | 12 +- docs/view-default.md | 35 +- examples/example-custom-styled-graph.html | 6 +- examples/example-fixed-coordinates-graph.html | 6 +- examples/example-graph-data-changes.html | 8 +- examples/example-graph-events.html | 18 +- examples/example-graph-on-map.html | 6 +- examples/playground.html | 6 +- examples/simulator-scenarios.html | 3077 +++- package-lock.json | 12973 ++-------------- package.json | 19 +- src/events.ts | 16 +- src/models/edge.ts | 245 +- src/models/graph.ts | 233 +- src/models/node.ts | 304 +- src/models/state.ts | 18 + src/models/strategy.ts | 18 +- src/models/style.ts | 3 +- src/renderer/canvas/canvas-renderer.ts | 4 - src/renderer/canvas/edge/base.ts | 40 +- src/renderer/canvas/edge/types/edge-curved.ts | 4 +- .../canvas/edge/types/edge-loopback.ts | 2 +- .../canvas/edge/types/edge-straight.ts | 4 +- src/renderer/canvas/node.ts | 40 +- src/simulator/engine/d3-simulator-engine.ts | 560 +- src/simulator/factory.ts | 3 +- src/simulator/layout/layout.ts | 29 + src/simulator/layout/layouts/circle.ts | 11 + src/simulator/shared.ts | 44 +- src/simulator/types/main-thread-simulator.ts | 82 +- .../types/web-worker-simulator/index.ts | 2 +- .../message/worker-input.ts | 51 +- .../message/worker-output.ts | 11 + ...{process.worker.ts => simulator.worker.ts} | 48 +- .../{simulator.ts => web-worker-simulator.ts} | 67 +- src/utils/array.utils.ts | 5 + src/utils/object.utils.ts | 8 + src/utils/observer.utils.ts | 50 + src/views/orb-map-view.ts | 20 +- src/views/orb-view.ts | 141 +- test/models/graph.spec.ts | 236 +- webpack.config.js | 4 +- 45 files changed, 5722 insertions(+), 12757 deletions(-) create mode 100644 src/simulator/layout/layout.ts create mode 100644 src/simulator/layout/layouts/circle.ts rename src/simulator/types/web-worker-simulator/{process.worker.ts => simulator.worker.ts} (68%) rename src/simulator/types/web-worker-simulator/{simulator.ts => web-worker-simulator.ts} (63%) create mode 100644 src/utils/observer.utils.ts diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9a57469..6ce3f17 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,7 +9,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 with: - node-version: "16.x" + node-version: "18.x" - name: 'Install' run: npm ci diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ae29e61..1954f5f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 with: - node-version: "16.x" + node-version: "18.x" - name: 'Install' run: npm ci diff --git a/.releaserc b/.releaserc index 657424e..036ab65 100644 --- a/.releaserc +++ b/.releaserc @@ -8,10 +8,10 @@ }], "@semantic-release/changelog", "@semantic-release/npm", - '@semantic-release/github', + "@semantic-release/github", ["@semantic-release/git", { "assets": ["package.json", "CHANGELOG.md"], "message": "Chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" - }], - ], + }] + ] } diff --git a/README.md b/README.md index 991cc2a..2d5cd1a 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Orb is a graph visualization library. Read more about Orb in the following guide * [Styling nodes and edges](./docs/styles.md) * [Handling events](./docs/events.md) * Using different views - * [Default view](./docs/view-default.md) + * [Default view](./docs/view-default.md) * [Map view](./docs/view-map.md) ## Install @@ -106,7 +106,7 @@ free to check other JavaScript examples in `examples/` directory.
diff --git a/package-lock.json b/package-lock.json index 47222a8..97f8586 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "@memgraph/orb", "version": "1.0.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -28,7 +28,7 @@ "@types/d3-selection": "3.0.1", "@types/d3-transition": "3.0.1", "@types/d3-zoom": "3.0.1", - "@types/jest": "27.4.1", + "@types/jest": "29.5.12", "@types/leaflet": "1.7.9", "@types/resize-observer-browser": "^0.1.7", "@typescript-eslint/eslint-plugin": "5.24.0", @@ -42,10 +42,10 @@ "eslint-plugin-prettier": "4.0.0", "http-server": "^14.1.1", "husky": "^8.0.1", - "jest": "27.5.1", + "jest": "29.7.0", "prettier": "^2.7.1", "semantic-release": "19.0.3", - "ts-jest": "27.1.4", + "ts-jest": "29.1.2", "ts-loader": "^9.3.1", "ts-node": "10.8.0", "typescript": "4.6.3", @@ -54,16 +54,16 @@ "webpack-dev-server": "^4.9.3" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { @@ -71,47 +71,119 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/compat-data": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.8.tgz", - "integrity": "sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.9.tgz", - "integrity": "sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.9", - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-module-transforms": "^7.18.9", - "@babel/helpers": "^7.18.9", - "@babel/parser": "^7.18.9", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9", - "convert-source-map": "^1.7.0", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", + "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.9", + "@babel/parser": "^7.23.9", + "@babel/template": "^7.23.9", + "@babel/traverse": "^7.23.9", + "@babel/types": "^7.23.9", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -131,49 +203,43 @@ } }, "node_modules/@babel/generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.9.tgz", - "integrity": "sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dev": true, "dependencies": { - "@babel/types": "^7.18.9", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { - "node": ">=6.0.0" + "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz", - "integrity": "sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==", + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.18.8", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.20.2", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "yallist": "^3.0.2" } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { @@ -185,144 +251,159 @@ "semver": "bin/semver.js" } }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz", - "integrity": "sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/template": "^7.18.6", - "@babel/types": "^7.18.9" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz", - "integrity": "sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz", - "integrity": "sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/helper-string-parser": { + "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==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", + "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==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.9.tgz", - "integrity": "sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", + "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", "dev": true, "dependencies": { - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/template": "^7.23.9", + "@babel/traverse": "^7.23.9", + "@babel/types": "^7.23.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -401,9 +482,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.9.tgz", - "integrity": "sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", + "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -472,6 +553,21 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", @@ -560,12 +656,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", - "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -575,34 +671,34 @@ } }, "node_modules/@babel/template": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.6.tgz", - "integrity": "sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", + "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.23.9", + "@babel/types": "^7.23.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.9.tgz", - "integrity": "sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.9", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.18.9", - "@babel/types": "^7.18.9", - "debug": "^4.1.0", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", + "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.9", + "@babel/types": "^7.23.9", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -619,12 +715,13 @@ } }, "node_modules/@babel/types": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.9.tgz", - "integrity": "sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", + "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1148,59 +1245,59 @@ } }, "node_modules/@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, "dependencies": { - "@jest/types": "^27.5.1", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, "dependencies": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "emittery": "^0.8.1", + "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", "micromatch": "^4.0.4", - "rimraf": "^3.0.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -1211,101 +1308,111 @@ } } }, - "node_modules/@jest/core/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, "dependencies": { - "glob": "^7.1.3" + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" }, - "bin": { - "rimraf": "bin.js" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" + "jest-get-type": "^29.6.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, "dependencies": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", - "glob": "^7.1.2", + "glob": "^7.1.3", "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "slash": "^3.0.0", - "source-map": "^0.6.0", "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -1316,100 +1423,144 @@ } } }, + "node_modules/@jest/reporters/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" + "graceful-fs": "^4.2.9" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, "dependencies": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, "dependencies": { - "@jest/test-result": "^27.5.1", + "@jest/test-result": "^29.7.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" + "write-file-atomic": "^4.0.2" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, "dependencies": { + "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "@types/yargs": "^16.0.0", + "@types/yargs": "^17.0.8", "chalk": "^4.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", + "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { "node": ">=6.0.0" @@ -1443,20 +1594,6 @@ "@jridgewell/trace-mapping": "^0.3.9" } }, - "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", @@ -1929,31 +2066,28 @@ "semantic-release": ">=18.0.0-beta.1" } }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true, - "engines": { - "node": ">= 6" + "@sinonjs/commons": "^3.0.0" } }, "node_modules/@tsconfig/node10": { @@ -1981,31 +2115,31 @@ "dev": true }, "node_modules/@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "node_modules/@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "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==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -2013,12 +2147,12 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.17.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.1.tgz", - "integrity": "sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", + "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", "dev": true, "dependencies": { - "@babel/types": "^7.3.0" + "@babel/types": "^7.20.7" } }, "node_modules/@types/body-parser": { @@ -2176,9 +2310,9 @@ "dev": true }, "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "dev": true, "dependencies": { "@types/node": "*" @@ -2194,37 +2328,37 @@ } }, "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", "dev": true }, "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "*" } }, "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" } }, "node_modules/@types/jest": { - "version": "27.4.1", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", - "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", + "version": "29.5.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", "dev": true, "dependencies": { - "jest-matcher-utils": "^27.0.0", - "pretty-format": "^27.0.0" + "expect": "^29.0.0", + "pretty-format": "^29.0.0" } }, "node_modules/@types/json-schema": { @@ -2272,12 +2406,6 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, - "node_modules/@types/prettier": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz", - "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==", - "dev": true - }, "node_modules/@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", @@ -2331,9 +2459,9 @@ } }, "node_modules/@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "dev": true }, "node_modules/@types/ws": { @@ -2346,18 +2474,18 @@ } }, "node_modules/@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", "dev": true, "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { @@ -2738,12 +2866,6 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "dev": true - }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -2769,28 +2891,6 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/acorn-import-assertions": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", @@ -2809,15 +2909,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -3027,12 +3118,6 @@ "lodash": "^4.17.14" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, "node_modules/at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", @@ -3043,22 +3128,21 @@ } }, "node_modules/babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, "dependencies": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", + "babel-preset-jest": "^29.6.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "@babel/core": "^7.8.0" @@ -3080,25 +3164,50 @@ "node": ">=8" } }, - "node_modules/babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=8" } }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", @@ -3119,16 +3228,16 @@ } }, "node_modules/babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^27.5.1", + "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -3276,16 +3385,10 @@ "node": ">=8" } }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, "node_modules/browserslist": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.2.tgz", - "integrity": "sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, "funding": [ { @@ -3295,13 +3398,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001366", - "electron-to-chromium": "^1.4.188", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.4" + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -3395,9 +3502,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001368", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001368.tgz", - "integrity": "sha512-wgfRYa9DenEomLG/SdWgQxpIyvdtH3NW8Vq+tB6AwR9e56iOIcu1im5F/wNdDf04XlKHXqIx4N8Jo0PemeBenQ==", + "version": "1.0.30001591", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz", + "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==", "dev": true, "funding": [ { @@ -3407,6 +3514,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ] }, @@ -3497,15 +3608,24 @@ } }, "node_modules/ci-info": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", - "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==", - "dev": true + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } }, "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", "dev": true }, "node_modules/clean-stack": { @@ -3580,9 +3700,9 @@ } }, "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", "dev": true }, "node_modules/color-convert": { @@ -3609,18 +3729,6 @@ "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", "dev": true }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -3853,13 +3961,10 @@ } }, "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } + "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==", + "dev": true }, "node_modules/cookie": { "version": "0.5.0", @@ -3978,6 +4083,27 @@ "typescript": ">=3" } }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -4007,30 +4133,6 @@ "node": ">=8" } }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - }, "node_modules/d3-color": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", @@ -4157,20 +4259,6 @@ "node": ">=8" } }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -4228,17 +4316,19 @@ "node": ">=0.10.0" } }, - "node_modules/decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", - "dev": true - }, "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } }, "node_modules/deep-extend": { "version": "0.6.0", @@ -4256,9 +4346,9 @@ "dev": true }, "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, "engines": { "node": ">=0.10.0" @@ -4322,30 +4412,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/del/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -4396,12 +4462,12 @@ } }, "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/dir-glob": { @@ -4446,27 +4512,6 @@ "node": ">=6.0.0" } }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -4495,18 +4540,18 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.196", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.196.tgz", - "integrity": "sha512-uxMa/Dt7PQsLBVXwH+t6JvpHJnrsYBaxWKi/J6HE+/nBtoHENhwBoNkgkm226/Kfxeg0z1eMQLBRPPKcDH8xWA==", + "version": "1.4.685", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.685.tgz", + "integrity": "sha512-yDYeobbTEe4TNooEzOQO6xFqg9XnAkVy2Lod1C1B2it8u47JNLYvl9nLDWBamqUakWB8Jc1hhS1uHUNYTNQdfw==", "dev": true }, "node_modules/emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sindresorhus/emittery?sponsor=1" @@ -4608,88 +4653,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/eslint": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz", @@ -5048,18 +5011,19 @@ } }, "node_modules/expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, "dependencies": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/express": { @@ -5243,9 +5207,9 @@ } }, "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, "dependencies": { "bser": "2.1.1" @@ -5376,21 +5340,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/flatted": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz", @@ -5417,20 +5366,6 @@ } } }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -5826,24 +5761,6 @@ "node": ">=10" } }, - "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/hosted-git-info/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", @@ -5856,18 +5773,6 @@ "wbuf": "^1.1.0" } }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/html-entities": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", @@ -5922,20 +5827,6 @@ "node": ">=8.0.0" } }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/http-proxy-middleware": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", @@ -6410,12 +6301,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -6440,12 +6325,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -6496,75 +6375,57 @@ } }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", + "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", "dev": true, "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" + "semver": "^7.5.4" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "dependencies": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/istanbul-lib-report/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "node": ">=10" } }, "node_modules/istanbul-lib-source-maps": { @@ -6582,9 +6443,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -6604,20 +6465,21 @@ } }, "node_modules/jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "dependencies": { - "@jest/core": "^27.5.1", + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", "import-local": "^3.0.2", - "jest-cli": "^27.5.1" + "jest-cli": "^29.7.0" }, "bin": { "jest": "bin/jest.js" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -6629,73 +6491,103 @@ } }, "node_modules/jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, "dependencies": { - "@jest/types": "^27.5.1", "execa": "^5.0.0", - "throat": "^6.0.1" + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-changed-files/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", + "dedent": "^1.0.0", "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, "dependencies": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", + "create-jest": "^29.7.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" }, "bin": { "jest": "bin/jest.js" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -6706,282 +6598,241 @@ } } }, - "node_modules/jest-cli/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-cli/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, "dependencies": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", - "glob": "^7.1.1", + "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { + "@types/node": "*", "ts-node": ">=9.0.0" }, "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, "ts-node": { "optional": true } } }, "node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, "dependencies": { "detect-newline": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, "dependencies": { - "@jest/types": "^27.5.1", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, "dependencies": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "micromatch": "^4.0.4", - "walker": "^1.0.7" + "walker": "^1.0.8" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "optionalDependencies": { "fsevents": "^2.3.2" } }, - "node_modules/jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "node_modules/jest-haste-map/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, "dependencies": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", + "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "engines": { "node": ">=6" @@ -6996,167 +6847,220 @@ } }, "node_modules/jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, "dependencies": { - "@jest/types": "^27.5.1", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", + "jest-haste-map": "^29.7.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", + "resolve.exports": "^2.0.0", "slash": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, "dependencies": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, "dependencies": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "emittery": "^0.8.1", + "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "node_modules/jest-runner/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", + "node_modules/jest-runner/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-runner/node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/jest-runner/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "graceful-fs": "^4.2.9" + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, "dependencies": { - "@babel/core": "^7.7.2", + "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.5.1", + "expect": "^29.7.0", "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" } }, "node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, "dependencies": { - "@jest/types": "^27.5.1", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -7164,24 +7068,24 @@ "picomatch": "^2.2.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, "dependencies": { - "@jest/types": "^27.5.1", + "@jest/types": "^29.6.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", + "jest-get-type": "^29.6.3", "leven": "^3.1.0", - "pretty-format": "^27.5.1" + "pretty-format": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-validate/node_modules/camelcase": { @@ -7197,21 +7101,22 @@ } }, "node_modules/jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, "dependencies": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^27.5.1", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", "string-length": "^4.0.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-worker": { @@ -7261,52 +7166,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -7585,24 +7444,66 @@ "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", "dev": true }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "dependencies": { - "tmpl": "1.0.5" + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true, "engines": { @@ -8007,9 +7908,9 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, "node_modules/normalize-package-data": { @@ -10626,12 +10527,6 @@ "inBundle": true, "license": "ISC" }, - "node_modules/nwsapi": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.1.tgz", - "integrity": "sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg==", - "dev": true - }, "node_modules/object-inspect": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", @@ -10883,12 +10778,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -10965,9 +10854,9 @@ } }, "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, "engines": { "node": ">= 6" @@ -11113,17 +11002,17 @@ } }, "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.1", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" + "react-is": "^18.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/pretty-format/node_modules/ansi-styles": { @@ -11185,12 +11074,6 @@ "node": ">= 0.10" } }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -11200,6 +11083,22 @@ "node": ">=6" } }, + "node_modules/pure-rand": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", + "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -11225,12 +11124,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -11327,9 +11220,9 @@ } }, "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, "node_modules/read-pkg": { @@ -11606,9 +11499,9 @@ } }, "node_modules/resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", "dev": true, "engines": { "node": ">=10" @@ -11633,6 +11526,21 @@ "node": ">=0.10.0" } }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -11668,18 +11576,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/schema-utils": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", @@ -11840,24 +11736,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -12330,9 +12208,9 @@ "dev": true }, "node_modules/stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -12496,12 +12374,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -12551,22 +12423,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/terser": { "version": "5.17.1", "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz", @@ -12697,12 +12553,6 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true - }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -12774,42 +12624,6 @@ "node": ">=0.6" } }, - "node_modules/tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", - "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/traverse": { "version": "0.6.6", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", @@ -12826,38 +12640,38 @@ } }, "node_modules/ts-jest": { - "version": "27.1.4", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.4.tgz", - "integrity": "sha512-qjkZlVPWVctAezwsOD1OPzbZ+k7zA5z3oxII4dGdZo5ggX/PL7kvwTM0pXTr10fAtbiVpJaL3bWd502zAhpgSQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.2.tgz", + "integrity": "sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==", "dev": true, "dependencies": { "bs-logger": "0.x", "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", "lodash.memoize": "4.x", "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" }, "bin": { "ts-jest": "cli.js" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^16.10.0 || ^18.0.0 || >=20.0.0" }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", - "@types/jest": "^27.0.0", - "babel-jest": ">=27.0.0 <28", - "jest": "^27.0.0", - "typescript": ">=3.8 <5.0" + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" }, "peerDependenciesMeta": { "@babel/core": { "optional": true }, - "@types/jest": { + "@jest/types": { "optional": true }, "babel-jest": { @@ -12868,6 +12682,30 @@ } } }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/ts-loader": { "version": "9.3.1", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.3.1.tgz", @@ -13006,15 +12844,6 @@ "node": ">= 0.6" } }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, "node_modules/typescript": { "version": "4.6.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", @@ -13090,9 +12919,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz", - "integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, "funding": [ { @@ -13102,6 +12931,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { @@ -13109,7 +12942,7 @@ "picocolors": "^1.0.0" }, "bin": { - "browserslist-lint": "cli.js" + "update-browserslist-db": "cli.js" }, "peerDependencies": { "browserslist": ">= 4.21.0" @@ -13130,16 +12963,6 @@ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", "dev": true }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -13177,28 +13000,19 @@ "dev": true }, "node_modules/v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", "dev": true, "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" + "convert-source-map": "^2.0.0" }, "engines": { "node": ">=10.12.0" } }, - "node_modules/v8-to-istanbul/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -13218,27 +13032,6 @@ "node": ">= 0.8" } }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -13270,15 +13063,6 @@ "minimalistic-assert": "^1.0.0" } }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true, - "engines": { - "node": ">=10.4" - } - }, "node_modules/webpack": { "version": "5.80.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.80.0.tgz", @@ -13460,21 +13244,6 @@ } } }, - "node_modules/webpack-dev-server/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/webpack-dev-server/node_modules/ws": { "version": "8.8.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", @@ -13590,35 +13359,6 @@ "node": ">=0.8.0" } }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -13679,59 +13419,33 @@ "dev": true }, "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, "dependencies": { "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true, "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "node": ">=0.4" } }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, "node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", @@ -13807,10324 +13521,5 @@ "url": "https://github.com/sponsors/sindresorhus" } } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/compat-data": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.8.tgz", - "integrity": "sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==", - "dev": true - }, - "@babel/core": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.9.tgz", - "integrity": "sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.9", - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-module-transforms": "^7.18.9", - "@babel/helpers": "^7.18.9", - "@babel/parser": "^7.18.9", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.9.tgz", - "integrity": "sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug==", - "dev": true, - "requires": { - "@babel/types": "^7.18.9", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } - } - }, - "@babel/helper-compilation-targets": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz", - "integrity": "sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.18.8", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.20.2", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz", - "integrity": "sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==", - "dev": true, - "requires": { - "@babel/template": "^7.18.6", - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-transforms": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz", - "integrity": "sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz", - "integrity": "sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==", - "dev": true - }, - "@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true - }, - "@babel/helpers": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.9.tgz", - "integrity": "sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==", - "dev": true, - "requires": { - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" - } - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.9.tgz", - "integrity": "sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==", - "dev": true - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", - "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/template": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.6.tgz", - "integrity": "sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.6", - "@babel/types": "^7.18.6" - } - }, - "@babel/traverse": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.9.tgz", - "integrity": "sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.9", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.18.9", - "@babel/types": "^7.18.9", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.9.tgz", - "integrity": "sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, - "optional": true - }, - "@commitlint/cli": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.0.0.tgz", - "integrity": "sha512-Np6slCdVVG1XwMvwbZrXIzS1INPAD5QmN4L6al04AmCd4nAPU63gxgxC5Mz0Fmx7va23Uvb0S7yEFV1JPhvPUQ==", - "dev": true, - "requires": { - "@commitlint/format": "^17.0.0", - "@commitlint/lint": "^17.0.0", - "@commitlint/load": "^17.0.0", - "@commitlint/read": "^17.0.0", - "@commitlint/types": "^17.0.0", - "lodash": "^4.17.19", - "resolve-from": "5.0.0", - "resolve-global": "1.0.0", - "yargs": "^17.0.0" - } - }, - "@commitlint/config-conventional": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-17.0.0.tgz", - "integrity": "sha512-jttJXBIq3AuQCvUVwxSctCwKfHxxbALE0IB9OIHYCu/eQdOzPxN72pugeZsWDo1VK/T9iFx+MZoPb6Rb1/ylsw==", - "dev": true, - "requires": { - "conventional-changelog-conventionalcommits": "^4.3.1" - } - }, - "@commitlint/config-validator": { - "version": "17.4.4", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.4.4.tgz", - "integrity": "sha512-bi0+TstqMiqoBAQDvdEP4AFh0GaKyLFlPPEObgI29utoKEYoPQTvF0EYqIwYYLEoJYhj5GfMIhPHJkTJhagfeg==", - "dev": true, - "requires": { - "@commitlint/types": "^17.4.4", - "ajv": "^8.11.0" - } - }, - "@commitlint/ensure": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.0.0.tgz", - "integrity": "sha512-M2hkJnNXvEni59S0QPOnqCKIK52G1XyXBGw51mvh7OXDudCmZ9tZiIPpU882p475Mhx48Ien1MbWjCP1zlyC0A==", - "dev": true, - "requires": { - "@commitlint/types": "^17.0.0", - "lodash": "^4.17.19" - } - }, - "@commitlint/execute-rule": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz", - "integrity": "sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==", - "dev": true - }, - "@commitlint/format": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.0.0.tgz", - "integrity": "sha512-MZzJv7rBp/r6ZQJDEodoZvdRM0vXu1PfQvMTNWFb8jFraxnISMTnPBWMMjr2G/puoMashwaNM//fl7j8gGV5lA==", - "dev": true, - "requires": { - "@commitlint/types": "^17.0.0", - "chalk": "^4.1.0" - } - }, - "@commitlint/is-ignored": { - "version": "17.6.7", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.6.7.tgz", - "integrity": "sha512-vqyNRqtbq72P2JadaoWiuoLtXIs9SaAWDqdtef6G2zsoXqKFc7vqj1f+thzVgosXG3X/5K9jNp+iYijmvOfc/g==", - "dev": true, - "requires": { - "@commitlint/types": "^17.4.4", - "semver": "7.5.2" - } - }, - "@commitlint/lint": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.0.3.tgz", - "integrity": "sha512-2o1fk7JUdxBUgszyt41sHC/8Nd5PXNpkmuOo9jvGIjDHzOwXyV0PSdbEVTH3xGz9NEmjohFHr5l+N+T9fcxong==", - "dev": true, - "requires": { - "@commitlint/is-ignored": "^17.0.3", - "@commitlint/parse": "^17.0.0", - "@commitlint/rules": "^17.0.0", - "@commitlint/types": "^17.0.0" - } - }, - "@commitlint/load": { - "version": "17.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.5.0.tgz", - "integrity": "sha512-l+4W8Sx4CD5rYFsrhHH8HP01/8jEP7kKf33Xlx2Uk2out/UKoKPYMOIRcDH5ppT8UXLMV+x6Wm5osdRKKgaD1Q==", - "dev": true, - "requires": { - "@commitlint/config-validator": "^17.4.4", - "@commitlint/execute-rule": "^17.4.0", - "@commitlint/resolve-extends": "^17.4.4", - "@commitlint/types": "^17.4.4", - "@types/node": "*", - "chalk": "^4.1.0", - "cosmiconfig": "^8.0.0", - "cosmiconfig-typescript-loader": "^4.0.0", - "lodash.isplainobject": "^4.0.6", - "lodash.merge": "^4.6.2", - "lodash.uniq": "^4.5.0", - "resolve-from": "^5.0.0", - "ts-node": "^10.8.1", - "typescript": "^4.6.4 || ^5.0.0" - }, - "dependencies": { - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - }, - "cosmiconfig": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz", - "integrity": "sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==", - "dev": true, - "requires": { - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0" - } - }, - "ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } - }, - "typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "dev": true - } - } - }, - "@commitlint/message": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-17.0.0.tgz", - "integrity": "sha512-LpcwYtN+lBlfZijHUdVr8aNFTVpHjuHI52BnfoV01TF7iSLnia0jttzpLkrLmI8HNQz6Vhr9UrxDWtKZiMGsBw==", - "dev": true - }, - "@commitlint/parse": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.0.0.tgz", - "integrity": "sha512-cKcpfTIQYDG1ywTIr5AG0RAiLBr1gudqEsmAGCTtj8ffDChbBRxm6xXs2nv7GvmJN7msOt7vOKleLvcMmRa1+A==", - "dev": true, - "requires": { - "@commitlint/types": "^17.0.0", - "conventional-changelog-angular": "^5.0.11", - "conventional-commits-parser": "^3.2.2" - } - }, - "@commitlint/read": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.0.0.tgz", - "integrity": "sha512-zkuOdZayKX3J6F6mPnVMzohK3OBrsEdOByIqp4zQjA9VLw1hMsDEFQ18rKgUc2adkZar+4S01QrFreDCfZgbxA==", - "dev": true, - "requires": { - "@commitlint/top-level": "^17.0.0", - "@commitlint/types": "^17.0.0", - "fs-extra": "^10.0.0", - "git-raw-commits": "^2.0.0" - } - }, - "@commitlint/resolve-extends": { - "version": "17.4.4", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.4.4.tgz", - "integrity": "sha512-znXr1S0Rr8adInptHw0JeLgumS11lWbk5xAWFVno+HUFVN45875kUtqjrI6AppmD3JI+4s0uZlqqlkepjJd99A==", - "dev": true, - "requires": { - "@commitlint/config-validator": "^17.4.4", - "@commitlint/types": "^17.4.4", - "import-fresh": "^3.0.0", - "lodash.mergewith": "^4.6.2", - "resolve-from": "^5.0.0", - "resolve-global": "^1.0.0" - } - }, - "@commitlint/rules": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.0.0.tgz", - "integrity": "sha512-45nIy3dERKXWpnwX9HeBzK5SepHwlDxdGBfmedXhL30fmFCkJOdxHyOJsh0+B0RaVsLGT01NELpfzJUmtpDwdQ==", - "dev": true, - "requires": { - "@commitlint/ensure": "^17.0.0", - "@commitlint/message": "^17.0.0", - "@commitlint/to-lines": "^17.0.0", - "@commitlint/types": "^17.0.0", - "execa": "^5.0.0" - } - }, - "@commitlint/to-lines": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-17.0.0.tgz", - "integrity": "sha512-nEi4YEz04Rf2upFbpnEorG8iymyH7o9jYIVFBG1QdzebbIFET3ir+8kQvCZuBE5pKCtViE4XBUsRZz139uFrRQ==", - "dev": true - }, - "@commitlint/top-level": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-17.0.0.tgz", - "integrity": "sha512-dZrEP1PBJvodNWYPOYiLWf6XZergdksKQaT6i1KSROLdjf5Ai0brLOv5/P+CPxBeoj3vBxK4Ax8H1Pg9t7sHIQ==", - "dev": true, - "requires": { - "find-up": "^5.0.0" - } - }, - "@commitlint/types": { - "version": "17.4.4", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.4.4.tgz", - "integrity": "sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==", - "dev": true, - "requires": { - "chalk": "^4.1.0" - } - }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } - } - }, - "@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.15.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" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - } - } - }, - "@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", - "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" - } - }, - "@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - } - }, - "@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" - } - }, - "@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - } - }, - "@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" - } - }, - "@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", - "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", - "dev": true, - "requires": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - } - }, - "@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - } - }, - "@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true - }, - "@jridgewell/source-map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", - "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } - } - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", - "dev": true - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@octokit/auth-token": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.0.tgz", - "integrity": "sha512-MDNFUBcJIptB9At7HiV7VCvU3NcL4GnfCQaP8C5lrxWrRPMJBnemYtehaKSOlaM7AYxeRyj9etenu8LVpSpVaQ==", - "dev": true, - "requires": { - "@octokit/types": "^6.0.3" - } - }, - "@octokit/core": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.0.4.tgz", - "integrity": "sha512-sUpR/hc4Gc7K34o60bWC7WUH6Q7T6ftZ2dUmepSyJr9PRF76/qqkWjE2SOEzCqLA5W83SaISymwKtxks+96hPQ==", - "dev": true, - "requires": { - "@octokit/auth-token": "^3.0.0", - "@octokit/graphql": "^5.0.0", - "@octokit/request": "^6.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^6.0.3", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/endpoint": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.0.tgz", - "integrity": "sha512-Kz/mIkOTjs9rV50hf/JK9pIDl4aGwAtT8pry6Rpy+hVXkAPhXanNQRxMoq6AeRgDCZR6t/A1zKniY2V1YhrzlQ==", - "dev": true, - "requires": { - "@octokit/types": "^6.0.3", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/graphql": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.0.tgz", - "integrity": "sha512-1ZZ8tX4lUEcLPvHagfIVu5S2xpHYXAmgN0+95eAOPoaVPzCfUXJtA5vASafcpWcO86ze0Pzn30TAx72aB2aguQ==", - "dev": true, - "requires": { - "@octokit/request": "^6.0.0", - "@octokit/types": "^6.0.3", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/openapi-types": { - "version": "12.10.1", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.10.1.tgz", - "integrity": "sha512-P+SukKanjFY0ZhsK6wSVnQmxTP2eVPPE8OPSNuxaMYtgVzwJZgfGdwlYjf4RlRU4vLEw4ts2fsE2icG4nZ5ddQ==", - "dev": true - }, - "@octokit/plugin-paginate-rest": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-3.0.0.tgz", - "integrity": "sha512-fvw0Q5IXnn60D32sKeLIxgXCEZ7BTSAjJd8cFAE6QU5qUp0xo7LjFUjjX1J5D7HgN355CN4EXE4+Q1/96JaNUA==", - "dev": true, - "requires": { - "@octokit/types": "^6.39.0" - } - }, - "@octokit/plugin-request-log": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", - "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", - "dev": true, - "requires": {} - }, - "@octokit/plugin-rest-endpoint-methods": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.1.2.tgz", - "integrity": "sha512-sAfSKtLHNq0UQ2iFuI41I6m5SK6bnKFRJ5kUjDRVbmQXiRVi4aQiIcgG4cM7bt+bhSiWL4HwnTxDkWFlKeKClA==", - "dev": true, - "requires": { - "@octokit/types": "^6.40.0", - "deprecation": "^2.3.1" - } - }, - "@octokit/request": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.0.tgz", - "integrity": "sha512-7IAmHnaezZrgUqtRShMlByJK33MT9ZDnMRgZjnRrRV9a/jzzFwKGz0vxhFU6i7VMLraYcQ1qmcAOin37Kryq+Q==", - "dev": true, - "requires": { - "@octokit/endpoint": "^7.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^6.16.1", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/request-error": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.0.tgz", - "integrity": "sha512-WBtpzm9lR8z4IHIMtOqr6XwfkGvMOOILNLxsWvDwtzm/n7f5AWuqJTXQXdDtOvPfTDrH4TPhEvW2qMlR4JFA2w==", - "dev": true, - "requires": { - "@octokit/types": "^6.0.3", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "@octokit/rest": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.3.tgz", - "integrity": "sha512-5arkTsnnRT7/sbI4fqgSJ35KiFaN7zQm0uQiQtivNQLI8RQx8EHwJCajcTUwmaCMNDg7tdCvqAnc7uvHHPxrtQ==", - "dev": true, - "requires": { - "@octokit/core": "^4.0.0", - "@octokit/plugin-paginate-rest": "^3.0.0", - "@octokit/plugin-request-log": "^1.0.4", - "@octokit/plugin-rest-endpoint-methods": "^6.0.0" - } - }, - "@octokit/types": { - "version": "6.40.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.40.0.tgz", - "integrity": "sha512-MFZOU5r8SwgJWDMhrLUSvyJPtVsqA6VnbVI3TNbsmw+Jnvrktzvq2fYES/6RiJA/5Ykdwq4mJmtlYUfW7CGjmw==", - "dev": true, - "requires": { - "@octokit/openapi-types": "^12.10.0" - } - }, - "@pnpm/config.env-replace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", - "dev": true - }, - "@pnpm/network.ca-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", - "dev": true, - "requires": { - "graceful-fs": "4.2.10" - } - }, - "@pnpm/npm-conf": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", - "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", - "dev": true, - "requires": { - "@pnpm/config.env-replace": "^1.1.0", - "@pnpm/network.ca-file": "^1.0.1", - "config-chain": "^1.1.11" - } - }, - "@semantic-release/changelog": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-6.0.1.tgz", - "integrity": "sha512-FT+tAGdWHr0RCM3EpWegWnvXJ05LQtBkQUaQRIExONoXjVjLuOILNm4DEKNaV+GAQyJjbLRVs57ti//GypH6PA==", - "dev": true, - "requires": { - "@semantic-release/error": "^3.0.0", - "aggregate-error": "^3.0.0", - "fs-extra": "^9.0.0", - "lodash": "^4.17.4" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - } - } - }, - "@semantic-release/commit-analyzer": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-9.0.2.tgz", - "integrity": "sha512-E+dr6L+xIHZkX4zNMe6Rnwg4YQrWNXK+rNsvwOPpdFppvZO1olE2fIgWhv89TkQErygevbjsZFSIxp+u6w2e5g==", - "dev": true, - "requires": { - "conventional-changelog-angular": "^5.0.0", - "conventional-commits-filter": "^2.0.0", - "conventional-commits-parser": "^3.2.3", - "debug": "^4.0.0", - "import-from": "^4.0.0", - "lodash": "^4.17.4", - "micromatch": "^4.0.2" - } - }, - "@semantic-release/error": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", - "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", - "dev": true - }, - "@semantic-release/git": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-10.0.1.tgz", - "integrity": "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==", - "dev": true, - "requires": { - "@semantic-release/error": "^3.0.0", - "aggregate-error": "^3.0.0", - "debug": "^4.0.0", - "dir-glob": "^3.0.0", - "execa": "^5.0.0", - "lodash": "^4.17.4", - "micromatch": "^4.0.0", - "p-reduce": "^2.0.0" - } - }, - "@semantic-release/github": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-8.0.5.tgz", - "integrity": "sha512-9pGxRM3gv1hgoZ/muyd4pWnykdIUVfCiev6MXE9lOyGQof4FQy95GFE26nDcifs9ZG7bBzV8ue87bo/y1zVf0g==", - "dev": true, - "requires": { - "@octokit/rest": "^19.0.0", - "@semantic-release/error": "^2.2.0", - "aggregate-error": "^3.0.0", - "bottleneck": "^2.18.1", - "debug": "^4.0.0", - "dir-glob": "^3.0.0", - "fs-extra": "^10.0.0", - "globby": "^11.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "issue-parser": "^6.0.0", - "lodash": "^4.17.4", - "mime": "^3.0.0", - "p-filter": "^2.0.0", - "p-retry": "^4.0.0", - "url-join": "^4.0.0" - }, - "dependencies": { - "@semantic-release/error": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", - "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", - "dev": true - }, - "@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true - }, - "http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - } - }, - "mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "dev": true - } - } - }, - "@semantic-release/npm": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-9.0.2.tgz", - "integrity": "sha512-zgsynF6McdzxPnFet+a4iO9HpAlARXOM5adz7VGVCvj0ne8wtL2ZOQoDV2wZPDmdEotDIbVeJjafhelZjs9j6g==", - "dev": true, - "requires": { - "@semantic-release/error": "^3.0.0", - "aggregate-error": "^3.0.0", - "execa": "^5.0.0", - "fs-extra": "^11.0.0", - "lodash": "^4.17.15", - "nerf-dart": "^1.0.0", - "normalize-url": "^6.0.0", - "npm": "^8.3.0", - "rc": "^1.2.8", - "read-pkg": "^5.0.0", - "registry-auth-token": "^5.0.0", - "semver": "^7.1.2", - "tempy": "^1.0.0" - }, - "dependencies": { - "fs-extra": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", - "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - } - } - }, - "@semantic-release/release-notes-generator": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-10.0.3.tgz", - "integrity": "sha512-k4x4VhIKneOWoBGHkx0qZogNjCldLPRiAjnIpMnlUh6PtaWXp/T+C9U7/TaNDDtgDa5HMbHl4WlREdxHio6/3w==", - "dev": true, - "requires": { - "conventional-changelog-angular": "^5.0.0", - "conventional-changelog-writer": "^5.0.0", - "conventional-commits-filter": "^2.0.0", - "conventional-commits-parser": "^3.2.3", - "debug": "^4.0.0", - "get-stream": "^6.0.0", - "import-from": "^4.0.0", - "into-stream": "^6.0.0", - "lodash": "^4.17.4", - "read-pkg-up": "^7.0.0" - } - }, - "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true - }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true - }, - "@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.17.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.1.tgz", - "integrity": "sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dev": true, - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/bonjour": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", - "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/connect-history-api-fallback": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", - "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", - "dev": true, - "requires": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "@types/d3-color": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==", - "dev": true - }, - "@types/d3-drag": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.1.tgz", - "integrity": "sha512-o1Va7bLwwk6h03+nSM8dpaGEYnoIG19P0lKqlic8Un36ymh9NSkNFX1yiXMKNMx8rJ0Kfnn2eovuFaL6Jvj0zA==", - "dev": true, - "requires": { - "@types/d3-selection": "*" - } - }, - "@types/d3-ease": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.0.tgz", - "integrity": "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==", - "dev": true - }, - "@types/d3-force": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.3.tgz", - "integrity": "sha512-z8GteGVfkWJMKsx6hwC3SiTSLspL98VNpmvLpEFJQpZPq6xpA1I8HNBDNSpukfK0Vb0l64zGFhzunLgEAcBWSA==", - "dev": true - }, - "@types/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", - "dev": true, - "requires": { - "@types/d3-color": "*" - } - }, - "@types/d3-selection": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.1.tgz", - "integrity": "sha512-aJ1d1SCUtERHH65bB8NNoLpUOI3z8kVcfg2BGm4rMMUwuZF4x6qnIEKjT60Vt0o7gP/a/xkRVs4D9CpDifbyRA==", - "dev": true - }, - "@types/d3-transition": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.1.tgz", - "integrity": "sha512-Sv4qEI9uq3bnZwlOANvYK853zvpdKEm1yz9rcc8ZTsxvRklcs9Fx4YFuGA3gXoQN/c/1T6QkVNjhaRO/cWj94g==", - "dev": true, - "requires": { - "@types/d3-selection": "*" - } - }, - "@types/d3-zoom": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.1.tgz", - "integrity": "sha512-7s5L9TjfqIYQmQQEUcpMAcBOahem7TRoSO/+Gkz02GbMVuULiZzjF2BOdw291dbO2aNon4m2OdFsRGaCq2caLQ==", - "dev": true, - "requires": { - "@types/d3-interpolate": "*", - "@types/d3-selection": "*" - } - }, - "@types/eslint": { - "version": "8.4.5", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.5.tgz", - "integrity": "sha512-dhsC09y1gpJWnK+Ff4SGvCuSnk9DaU0BJZSzOwa6GVSg65XtTugLBITDAAzRU5duGBoXBHpdR/9jHGxJjNflJQ==", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", - "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true - }, - "@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", - "dev": true, - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.29", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz", - "integrity": "sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "@types/geojson": { - "version": "7946.0.10", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz", - "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==", - "dev": true - }, - "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/http-proxy": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", - "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "27.4.1", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", - "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", - "dev": true, - "requires": { - "jest-matcher-utils": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, - "@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true - }, - "@types/leaflet": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.7.9.tgz", - "integrity": "sha512-H8vPgD49HKzqM41ArHGZM70g/tfhp8W+JcPxfnF+5H/Xvp+xiP+KQOUNWU8U89fqS1Jj3cpRY/+nbnaHFzwnFA==", - "dev": true, - "requires": { - "@types/geojson": "*" - } - }, - "@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", - "dev": true - }, - "@types/minimist": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", - "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", - "dev": true - }, - "@types/node": { - "version": "18.0.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.6.tgz", - "integrity": "sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw==", - "dev": true - }, - "@types/normalize-package-data": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", - "dev": true - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, - "@types/prettier": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz", - "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==", - "dev": true - }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true - }, - "@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", - "dev": true - }, - "@types/resize-observer-browser": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz", - "integrity": "sha512-G9eN0Sn0ii9PWQ3Vl72jDPgeJwRWhv2Qk/nQkJuWmRmOB4HX3/BhD5SE1dZs/hzPZL/WKnvF0RHdTSG54QJFyg==", - "dev": true - }, - "@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "dev": true - }, - "@types/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", - "dev": true, - "requires": { - "@types/express": "*" - } - }, - "@types/serve-static": { - "version": "1.13.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", - "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", - "dev": true, - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@types/sockjs": { - "version": "0.3.33", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", - "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "@types/ws": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", - "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.24.0.tgz", - "integrity": "sha512-6bqFGk6wa9+6RrU++eLknKyDqXU1Oc8nyoLu5a1fU17PNRJd9UBr56rMF7c4DRaRtnarlkQ4jwxUbvBo8cNlpw==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.24.0", - "@typescript-eslint/type-utils": "5.24.0", - "@typescript-eslint/utils": "5.24.0", - "debug": "^4.3.4", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.2.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/parser": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.24.0.tgz", - "integrity": "sha512-4q29C6xFYZ5B2CXqSBBdcS0lPyfM9M09DoQLtHS5kf+WbpV8pBBhHDLNhXfgyVwFnhrhYzOu7xmg02DzxeF2Uw==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.24.0", - "@typescript-eslint/types": "5.24.0", - "@typescript-eslint/typescript-estree": "5.24.0", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.24.0.tgz", - "integrity": "sha512-WpMWipcDzGmMzdT7NtTjRXFabx10WleLUGrJpuJLGaxSqpcyq5ACpKSD5VE40h2nz3melQ91aP4Du7lh9FliCA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.24.0", - "@typescript-eslint/visitor-keys": "5.24.0" - } - }, - "@typescript-eslint/type-utils": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.24.0.tgz", - "integrity": "sha512-uGi+sQiM6E5CeCZYBXiaIvIChBXru4LZ1tMoeKbh1Lze+8BO9syUG07594C4lvN2YPT4KVeIupOJkVI+9/DAmQ==", - "dev": true, - "requires": { - "@typescript-eslint/utils": "5.24.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/types": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.24.0.tgz", - "integrity": "sha512-Tpg1c3shTDgTmZd3qdUyd+16r/pGmVaVEbLs+ufuWP0EruVbUiEOmpBBQxBb9a8iPRxi8Rb2oiwOxuZJzSq11A==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.24.0.tgz", - "integrity": "sha512-zcor6vQkQmZAQfebSPVwUk/FD+CvnsnlfKXYeQDsWXRF+t7SBPmIfNia/wQxCSeu1h1JIjwV2i9f5/DdSp/uDw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.24.0", - "@typescript-eslint/visitor-keys": "5.24.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/utils": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.24.0.tgz", - "integrity": "sha512-K05sbWoeCBJH8KXu6hetBJ+ukG0k2u2KlgD3bN+v+oBKm8adJqVHpSSLHNzqyuv0Lh4GVSAUgZ5lB4icmPmWLw==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.24.0", - "@typescript-eslint/types": "5.24.0", - "@typescript-eslint/typescript-estree": "5.24.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.24.0.tgz", - "integrity": "sha512-qzGwSXMyMnogcAo+/2fU+jhlPPVMXlIH2PeAonIKjJSoDKl1+lJVvG5Z5Oud36yU0TWK2cs1p/FaSN5J2OUFYA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.24.0", - "eslint-visitor-keys": "^3.3.0" - } - }, - "@webassemblyjs/ast": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.5.tgz", - "integrity": "sha512-LHY/GSAZZRpsNQH+/oHqhRQ5FT7eoULcBqgfyTB5nQHogFnK3/7QoN7dLnwSE/JkUAF0SrRuclT7ODqMFtWxxQ==", - "dev": true, - "requires": { - "@webassemblyjs/helper-numbers": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.5.tgz", - "integrity": "sha512-1j1zTIC5EZOtCplMBG/IEwLtUojtwFVwdyVMbL/hwWqbzlQoJsWCOavrdnLkemwNoC/EOwtUFch3fuo+cbcXYQ==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.5.tgz", - "integrity": "sha512-L65bDPmfpY0+yFrsgz8b6LhXmbbs38OnwDCf6NpnMUYqa+ENfE5Dq9E42ny0qz/PdR0LJyq/T5YijPnU8AXEpA==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.5.tgz", - "integrity": "sha512-fDKo1gstwFFSfacIeH5KfwzjykIE6ldh1iH9Y/8YkAZrhmu4TctqYjSh7t0K2VyDSXOZJ1MLhht/k9IvYGcIxg==", - "dev": true - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.5.tgz", - "integrity": "sha512-DhykHXM0ZABqfIGYNv93A5KKDw/+ywBFnuWybZZWcuzWHfbp21wUfRkbtz7dMGwGgT4iXjWuhRMA2Mzod6W4WA==", - "dev": true, - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.5", - "@webassemblyjs/helper-api-error": "1.11.5", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.5.tgz", - "integrity": "sha512-oC4Qa0bNcqnjAowFn7MPCETQgDYytpsfvz4ujZz63Zu/a/v71HeCAAmZsgZ3YVKec3zSPYytG3/PrRCqbtcAvA==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.5.tgz", - "integrity": "sha512-uEoThA1LN2NA+K3B9wDo3yKlBfVtC6rh0i4/6hvbz071E8gTNZD/pT0MsBf7MeD6KbApMSkaAK0XeKyOZC7CIA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-buffer": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5", - "@webassemblyjs/wasm-gen": "1.11.5" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.5.tgz", - "integrity": "sha512-37aGq6qVL8A8oPbPrSGMBcp38YZFXcHfiROflJn9jxSdSMMM5dS5P/9e2/TpaJuhE+wFrbukN2WI6Hw9MH5acg==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.5.tgz", - "integrity": "sha512-ajqrRSXaTJoPW+xmkfYN6l8VIeNnR4vBOTQO9HzR7IygoCcKWkICbKFbVTNMjMgMREqXEr0+2M6zukzM47ZUfQ==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.5.tgz", - "integrity": "sha512-WiOhulHKTZU5UPlRl53gHR8OxdGsSOxqfpqWeA2FmcwBMaoEdz6b2x2si3IwC9/fSPLfe8pBMRTHVMk5nlwnFQ==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.5.tgz", - "integrity": "sha512-C0p9D2fAu3Twwqvygvf42iGCQ4av8MFBLiTb+08SZ4cEdwzWx9QeAHDo1E2k+9s/0w1DM40oflJOpkZ8jW4HCQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-buffer": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5", - "@webassemblyjs/helper-wasm-section": "1.11.5", - "@webassemblyjs/wasm-gen": "1.11.5", - "@webassemblyjs/wasm-opt": "1.11.5", - "@webassemblyjs/wasm-parser": "1.11.5", - "@webassemblyjs/wast-printer": "1.11.5" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.5.tgz", - "integrity": "sha512-14vteRlRjxLK9eSyYFvw1K8Vv+iPdZU0Aebk3j6oB8TQiQYuO6hj9s4d7qf6f2HJr2khzvNldAFG13CgdkAIfA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5", - "@webassemblyjs/ieee754": "1.11.5", - "@webassemblyjs/leb128": "1.11.5", - "@webassemblyjs/utf8": "1.11.5" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.5.tgz", - "integrity": "sha512-tcKwlIXstBQgbKy1MlbDMlXaxpucn42eb17H29rawYLxm5+MsEmgPzeCP8B1Cl69hCice8LeKgZpRUAPtqYPgw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-buffer": "1.11.5", - "@webassemblyjs/wasm-gen": "1.11.5", - "@webassemblyjs/wasm-parser": "1.11.5" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.5.tgz", - "integrity": "sha512-SVXUIwsLQlc8srSD7jejsfTU83g7pIGr2YYNb9oHdtldSxaOhvA5xwvIiWIfcX8PlSakgqMXsLpLfbbJ4cBYew==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-api-error": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5", - "@webassemblyjs/ieee754": "1.11.5", - "@webassemblyjs/leb128": "1.11.5", - "@webassemblyjs/utf8": "1.11.5" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.5.tgz", - "integrity": "sha512-f7Pq3wvg3GSPUPzR0F6bmI89Hdb+u9WXrSKc4v+N0aV0q6r42WoF92Jp2jEorBEBRoRNXgjp53nBniDXcqZYPA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.5", - "@xtuc/long": "4.2.2" - } - }, - "@webpack-cli/configtest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", - "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", - "dev": true, - "requires": {} - }, - "@webpack-cli/info": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", - "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", - "dev": true, - "requires": { - "envinfo": "^7.7.3" - } - }, - "@webpack-cli/serve": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", - "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", - "dev": true, - "requires": {} - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "dev": true - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", - "dev": true - }, - "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - } - } - }, - "acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true, - "requires": {} - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "requires": { - "ajv": "^8.0.0" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, - "ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "ansicolors": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", - "dev": true - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "argv-formatter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", - "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", - "dev": true - }, - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true - }, - "array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true - }, - "async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, - "babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", - "dev": true, - "requires": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" - } - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "dev": true - }, - "before-after-hook": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", - "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", - "dev": true, - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - } - } - }, - "bonjour-service": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.13.tgz", - "integrity": "sha512-LWKRU/7EqDUC9CTAQtuZl5HzBALoCYwtLhffW3et7vZMwv3bWLpJf8bRYlMD5OCcDpTfnPgNCV4yo9ZIaJGMiA==", - "dev": true, - "requires": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "bottleneck": { - "version": "2.19.5", - "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", - "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "browserslist": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.2.tgz", - "integrity": "sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001366", - "electron-to-chromium": "^1.4.188", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.4" - } - }, - "bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "requires": { - "fast-json-stable-stringify": "2.x" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "dev": true - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - } - }, - "caniuse-lite": { - "version": "1.0.30001368", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001368.tgz", - "integrity": "sha512-wgfRYa9DenEomLG/SdWgQxpIyvdtH3NW8Vq+tB6AwR9e56iOIcu1im5F/wNdDf04XlKHXqIx4N8Jo0PemeBenQ==", - "dev": true - }, - "cardinal": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", - "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", - "dev": true, - "requires": { - "ansicolors": "~0.3.2", - "redeyed": "~2.1.0" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true - }, - "ci-info": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", - "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==", - "dev": true - }, - "cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cli-table3": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", - "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", - "dev": true, - "requires": { - "@colors/colors": "1.5.0", - "string-width": "^4.2.0" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "dependencies": { - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", - "dev": true, - "requires": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" - } - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "dev": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "dev": true - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "requires": { - "safe-buffer": "5.2.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "conventional-changelog-angular": { - "version": "5.0.13", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", - "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", - "dev": true, - "requires": { - "compare-func": "^2.0.0", - "q": "^1.5.1" - } - }, - "conventional-changelog-conventionalcommits": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz", - "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==", - "dev": true, - "requires": { - "compare-func": "^2.0.0", - "lodash": "^4.17.15", - "q": "^1.5.1" - } - }, - "conventional-changelog-eslint": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz", - "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==", - "dev": true, - "requires": { - "q": "^1.5.1" - } - }, - "conventional-changelog-writer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz", - "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==", - "dev": true, - "requires": { - "conventional-commits-filter": "^2.0.7", - "dateformat": "^3.0.0", - "handlebars": "^4.7.7", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "semver": "^6.0.0", - "split": "^1.0.0", - "through2": "^4.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "conventional-commits-filter": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", - "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", - "dev": true, - "requires": { - "lodash.ismatch": "^4.4.0", - "modify-values": "^1.0.0" - } - }, - "conventional-commits-parser": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", - "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", - "dev": true, - "requires": { - "is-text-path": "^1.0.1", - "JSONStream": "^1.0.4", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "split2": "^3.0.0", - "through2": "^4.0.0" - } - }, - "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true - }, - "copy-webpack-plugin": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", - "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", - "dev": true, - "requires": { - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.1", - "globby": "^13.1.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" - }, - "dependencies": { - "globby": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.2.tgz", - "integrity": "sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==", - "dev": true, - "requires": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.11", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^4.0.0" - } - }, - "slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "dev": true - } - } - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "corser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", - "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", - "dev": true - }, - "cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - }, - "cosmiconfig-typescript-loader": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.3.0.tgz", - "integrity": "sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==", - "dev": true, - "requires": {} - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true - }, - "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - } - } - }, - "d3-color": { - "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": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", - "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==" - }, - "d3-drag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", - "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", - "requires": { - "d3-dispatch": "1 - 3", - "d3-selection": "3" - } - }, - "d3-ease": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", - "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==" - }, - "d3-force": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", - "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", - "requires": { - "d3-dispatch": "1 - 3", - "d3-quadtree": "1 - 3", - "d3-timer": "1 - 3" - } - }, - "d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", - "requires": { - "d3-color": "1 - 3" - } - }, - "d3-quadtree": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", - "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==" - }, - "d3-selection": { - "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": { - "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": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", - "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", - "requires": { - "d3-color": "1 - 3", - "d3-dispatch": "1 - 3", - "d3-ease": "1 - 3", - "d3-interpolate": "1 - 3", - "d3-timer": "1 - 3" - } - }, - "d3-zoom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", - "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", - "requires": { - "d3-dispatch": "1 - 3", - "d3-drag": "2 - 3", - "d3-interpolate": "1 - 3", - "d3-selection": "2 - 3", - "d3-transition": "2 - 3" - } - }, - "dargs": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", - "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", - "dev": true - }, - "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - } - }, - "dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, - "decamelize-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==", - "dev": true, - "requires": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "dependencies": { - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true - } - } - }, - "decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", - "dev": true - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true - }, - "default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "dev": true, - "requires": { - "execa": "^5.0.0" - } - }, - "define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true - }, - "del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "dev": true, - "requires": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - }, - "dependencies": { - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true - }, - "deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true - }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==", - "dev": true - }, - "dns-packet": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz", - "integrity": "sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==", - "dev": true, - "requires": { - "@leichtgewicht/ip-codec": "^2.0.1" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } - } - }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "requires": { - "is-obj": "^2.0.0" - } - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.4.196", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.196.tgz", - "integrity": "sha512-uxMa/Dt7PQsLBVXwH+t6JvpHJnrsYBaxWKi/J6HE+/nBtoHENhwBoNkgkm226/Kfxeg0z1eMQLBRPPKcDH8xWA==", - "dev": true - }, - "emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true - }, - "enhanced-resolve": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.13.0.tgz", - "integrity": "sha512-eyV8f0y1+bzyfh8xAwW/WTSZpLbjhqc4ne9eGSH4Zo2ejdyiNG9pU6mf9DG8a7+Auk6MFTlNOT4Y2y/9k8GKVg==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "env-ci": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-5.5.0.tgz", - "integrity": "sha512-o0JdWIbOLP+WJKIUt36hz1ImQQFuN92nhsfTkHHap+J8CiI8WgGpH/a9jEGHh4/TU5BUUGjlnKXNoDb57+ne+A==", - "dev": true, - "requires": { - "execa": "^5.0.0", - "fromentries": "^1.3.2", - "java-properties": "^1.0.0" - } - }, - "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-module-lexer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.1.tgz", - "integrity": "sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - } - } - }, - "eslint": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz", - "integrity": "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.2.3", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", - "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.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "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.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - } - } - }, - "eslint-config-google": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", - "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", - "dev": true, - "requires": {} - }, - "eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", - "dev": true, - "requires": {} - }, - "eslint-plugin-jest": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.2.2.tgz", - "integrity": "sha512-etSFZ8VIFX470aA6kTqDPhIq7YWe0tjBcboFNV3WeiC18PJ/AVonGhuTwlmuz2fBkH8FJHA7JQ4k7GsQIj1Gew==", - "dev": true, - "requires": { - "@typescript-eslint/utils": "^5.10.0" - } - }, - "eslint-plugin-prettier": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", - "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", - "dev": true, - "requires": { - "prettier-linter-helpers": "^1.0.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - }, - "espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", - "dev": true, - "requires": { - "acorn": "^8.7.1", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true - }, - "expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - } - }, - "express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", - "dev": true, - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.0", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.10.3", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", - "dev": true, - "requires": { - "@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" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fastest-levenshtein": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.14.tgz", - "integrity": "sha512-tFfWHjnuUfKE186Tfgr+jtaFc0mZTApEgKDOeyN+FwOqRkO/zK/3h1AiRd8u8CY53owL3CUmGr/oI9p/RdyLTA==", - "dev": true - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - }, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - } - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "find-versions": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", - "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", - "dev": true, - "requires": { - "semver-regex": "^3.1.2" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "flatted": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz", - "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", - "dev": true - }, - "follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", - "dev": true - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true - }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "gensync": { - "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==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "git-log-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz", - "integrity": "sha512-rnCVNfkTL8tdNryFuaY0fYiBWEBcgF748O6ZI61rslBvr2o7U65c2/6npCRqH40vuAhtgtDiqLTJjBVdrejCzA==", - "dev": true, - "requires": { - "argv-formatter": "~1.0.0", - "spawn-error-forwarder": "~1.0.0", - "split2": "~1.0.0", - "stream-combiner2": "~1.1.1", - "through2": "~2.0.0", - "traverse": "~0.6.6" - }, - "dependencies": { - "split2": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", - "integrity": "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==", - "dev": true, - "requires": { - "through2": "~2.0.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "git-raw-commits": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", - "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", - "dev": true, - "requires": { - "dargs": "^7.0.0", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "split2": "^3.0.0", - "through2": "^4.0.0" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "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": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", - "dev": true, - "requires": { - "ini": "^1.3.4" - } - }, - "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "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": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true - }, - "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "dev": true, - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - } - }, - "hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "hook-std": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-2.0.0.tgz", - "integrity": "sha512-zZ6T5WcuBMIUVh49iPQS9t977t7C0l7OtHrpeMb5uk48JdflRX0NSFvCekfYNmGQETnLq9W/isMyHl69kxGi8g==", - "dev": true - }, - "hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.5" - } - }, - "html-entities": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", - "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==", - "dev": true - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "dev": true - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "dev": true - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", - "dev": true, - "requires": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "dependencies": { - "is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "dev": true - } - } - }, - "http-server": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", - "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", - "dev": true, - "requires": { - "basic-auth": "^2.0.1", - "chalk": "^4.1.2", - "corser": "^2.0.1", - "he": "^1.2.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy": "^1.18.1", - "mime": "^1.6.0", - "minimist": "^1.2.6", - "opener": "^1.5.1", - "portfinder": "^1.0.28", - "secure-compare": "3.0.1", - "union": "~0.5.0", - "url-join": "^4.0.1" - }, - "dependencies": { - "html-encoding-sniffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", - "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", - "dev": true, - "requires": { - "whatwg-encoding": "^2.0.0" - } - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "whatwg-encoding": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", - "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", - "dev": true, - "requires": { - "iconv-lite": "0.6.3" - } - } - } - }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "husky": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.1.tgz", - "integrity": "sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - } - } - }, - "import-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-4.0.0.tgz", - "integrity": "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==", - "dev": true - }, - "import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - } - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true - }, - "into-stream": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz", - "integrity": "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==", - "dev": true, - "requires": { - "from2": "^2.3.0", - "p-is-promise": "^3.0.0" - } - }, - "ipaddr.js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", - "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-inside": { - "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==", - "dev": true - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - }, - "is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-text-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", - "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", - "dev": true, - "requires": { - "text-extensions": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true - }, - "issue-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", - "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", - "dev": true, - "requires": { - "lodash.capitalize": "^4.2.1", - "lodash.escaperegexp": "^4.1.2", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.uniqby": "^4.7.0" - } - }, - "istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "java-properties": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", - "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", - "dev": true - }, - "jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "dev": true, - "requires": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - } - }, - "jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - } - }, - "jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - } - }, - "jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", - "dev": true, - "requires": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "dependencies": { - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", - "dev": true, - "requires": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - } - }, - "jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" - } - }, - "jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - } - }, - "jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true - }, - "jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - } - }, - "jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", - "dev": true, - "requires": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*" - } - }, - "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "dev": true - }, - "jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" - } - }, - "jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", - "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - } - }, - "jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - } - }, - "jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", - "dev": true, - "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - } - }, - "jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", - "dev": true, - "requires": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - } - }, - "jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - } - } - }, - "jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", - "dev": true, - "requires": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "requires": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true - }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true - }, - "leaflet": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.8.0.tgz", - "integrity": "sha512-gwhMjFCQiYs3x/Sf+d49f10ERXaEFCPr+nVTryhAW8DWbMGqJqt9G4XuIaHmFW08zYvhgdzqXGr8AlW8v8dQkA==" - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - } - } - }, - "loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.capitalize": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", - "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", - "dev": true - }, - "lodash.escaperegexp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", - "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", - "dev": true - }, - "lodash.ismatch": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", - "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", - "dev": true - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.mergewith": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", - "dev": true - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true - }, - "lodash.uniqby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", - "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", - "dev": true - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "requires": { - "tmpl": "1.0.5" - } - }, - "map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true - }, - "marked": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.18.tgz", - "integrity": "sha512-wbLDJ7Zh0sqA0Vdg6aqlbT+yPxqLblpAZh1mK2+AO2twQkPywvvqQNfEPVwSSRjZ7dZcdeVBIAgiO7MMp3Dszw==", - "dev": true - }, - "marked-terminal": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-5.1.1.tgz", - "integrity": "sha512-+cKTOx9P4l7HwINYhzbrBSyzgxO2HaHKGZGuB1orZsMIgXYaJyfidT81VXRdpelW/PcHEWxywscePVgI/oUF6g==", - "dev": true, - "requires": { - "ansi-escapes": "^5.0.0", - "cardinal": "^2.1.1", - "chalk": "^5.0.0", - "cli-table3": "^0.6.1", - "node-emoji": "^1.11.0", - "supports-hyperlinks": "^2.2.0" - }, - "dependencies": { - "ansi-escapes": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", - "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", - "dev": true, - "requires": { - "type-fest": "^1.0.2" - } - }, - "chalk": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", - "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", - "dev": true - }, - "type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "dev": true - } - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true - }, - "memfs": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.7.tgz", - "integrity": "sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw==", - "dev": true, - "requires": { - "fs-monkey": "^1.0.3" - } - }, - "meow": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", - "dev": true, - "requires": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" - }, - "dependencies": { - "type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", - "dev": true - } - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "requires": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - } - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "modify-values": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", - "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "dev": true, - "requires": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "nerf-dart": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", - "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", - "dev": true - }, - "node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, - "requires": { - "lodash": "^4.17.21" - } - }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - }, - "dependencies": { - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - } - } - }, - "node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "dev": true - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true - }, - "normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, - "requires": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true - }, - "npm": { - "version": "8.19.4", - "resolved": "https://registry.npmjs.org/npm/-/npm-8.19.4.tgz", - "integrity": "sha512-3HANl8i9DKnUA89P4KEgVNN28EjSeDCmvEqbzOAuxCFDzdBZzjUl99zgnGpOUumvW5lvJo2HKcjrsc+tfyv1Hw==", - "dev": true, - "requires": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^5.6.3", - "@npmcli/ci-detect": "^2.0.0", - "@npmcli/config": "^4.2.1", - "@npmcli/fs": "^2.1.0", - "@npmcli/map-workspaces": "^2.0.3", - "@npmcli/package-json": "^2.0.0", - "@npmcli/run-script": "^4.2.1", - "abbrev": "~1.1.1", - "archy": "~1.0.0", - "cacache": "^16.1.3", - "chalk": "^4.1.2", - "chownr": "^2.0.0", - "cli-columns": "^4.0.0", - "cli-table3": "^0.6.2", - "columnify": "^1.6.0", - "fastest-levenshtein": "^1.0.12", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "graceful-fs": "^4.2.10", - "hosted-git-info": "^5.2.1", - "ini": "^3.0.1", - "init-package-json": "^3.0.2", - "is-cidr": "^4.0.2", - "json-parse-even-better-errors": "^2.3.1", - "libnpmaccess": "^6.0.4", - "libnpmdiff": "^4.0.5", - "libnpmexec": "^4.0.14", - "libnpmfund": "^3.0.5", - "libnpmhook": "^8.0.4", - "libnpmorg": "^4.0.4", - "libnpmpack": "^4.1.3", - "libnpmpublish": "^6.0.5", - "libnpmsearch": "^5.0.4", - "libnpmteam": "^4.0.4", - "libnpmversion": "^3.0.7", - "make-fetch-happen": "^10.2.0", - "minimatch": "^5.1.0", - "minipass": "^3.1.6", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "mkdirp-infer-owner": "^2.0.0", - "ms": "^2.1.2", - "node-gyp": "^9.1.0", - "nopt": "^6.0.0", - "npm-audit-report": "^3.0.0", - "npm-install-checks": "^5.0.0", - "npm-package-arg": "^9.1.0", - "npm-pick-manifest": "^7.0.2", - "npm-profile": "^6.2.0", - "npm-registry-fetch": "^13.3.1", - "npm-user-validate": "^1.0.1", - "npmlog": "^6.0.2", - "opener": "^1.5.2", - "p-map": "^4.0.0", - "pacote": "^13.6.2", - "parse-conflict-json": "^2.0.2", - "proc-log": "^2.0.1", - "qrcode-terminal": "^0.12.0", - "read": "~1.0.7", - "read-package-json": "^5.0.2", - "read-package-json-fast": "^2.0.3", - "readdir-scoped-modules": "^1.1.0", - "rimraf": "^3.0.2", - "semver": "^7.3.7", - "ssri": "^9.0.1", - "tar": "^6.1.11", - "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", - "treeverse": "^2.0.0", - "validate-npm-package-name": "^4.0.0", - "which": "^2.0.2", - "write-file-atomic": "^4.0.1" - }, - "dependencies": { - "@colors/colors": { - "version": "1.5.0", - "bundled": true, - "dev": true, - "optional": true - }, - "@gar/promisify": { - "version": "1.1.3", - "bundled": true, - "dev": true - }, - "@isaacs/string-locale-compare": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "@npmcli/arborist": { - "version": "5.6.3", - "bundled": true, - "dev": true, - "requires": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/installed-package-contents": "^1.0.7", - "@npmcli/map-workspaces": "^2.0.3", - "@npmcli/metavuln-calculator": "^3.0.1", - "@npmcli/move-file": "^2.0.0", - "@npmcli/name-from-folder": "^1.0.1", - "@npmcli/node-gyp": "^2.0.0", - "@npmcli/package-json": "^2.0.0", - "@npmcli/query": "^1.2.0", - "@npmcli/run-script": "^4.1.3", - "bin-links": "^3.0.3", - "cacache": "^16.1.3", - "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^5.2.1", - "json-parse-even-better-errors": "^2.3.1", - "json-stringify-nice": "^1.1.4", - "minimatch": "^5.1.0", - "mkdirp": "^1.0.4", - "mkdirp-infer-owner": "^2.0.0", - "nopt": "^6.0.0", - "npm-install-checks": "^5.0.0", - "npm-package-arg": "^9.0.0", - "npm-pick-manifest": "^7.0.2", - "npm-registry-fetch": "^13.0.0", - "npmlog": "^6.0.2", - "pacote": "^13.6.1", - "parse-conflict-json": "^2.0.1", - "proc-log": "^2.0.0", - "promise-all-reject-late": "^1.0.0", - "promise-call-limit": "^1.0.1", - "read-package-json-fast": "^2.0.2", - "readdir-scoped-modules": "^1.1.0", - "rimraf": "^3.0.2", - "semver": "^7.3.7", - "ssri": "^9.0.0", - "treeverse": "^2.0.0", - "walk-up-path": "^1.0.0" - } - }, - "@npmcli/ci-detect": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "@npmcli/config": { - "version": "4.2.2", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/map-workspaces": "^2.0.2", - "ini": "^3.0.0", - "mkdirp-infer-owner": "^2.0.0", - "nopt": "^6.0.0", - "proc-log": "^2.0.0", - "read-package-json-fast": "^2.0.3", - "semver": "^7.3.5", - "walk-up-path": "^1.0.0" - } - }, - "@npmcli/disparity-colors": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^4.3.0" - } - }, - "@npmcli/fs": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "requires": { - "@gar/promisify": "^1.1.3", - "semver": "^7.3.5" - } - }, - "@npmcli/git": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/promise-spawn": "^3.0.0", - "lru-cache": "^7.4.4", - "mkdirp": "^1.0.4", - "npm-pick-manifest": "^7.0.0", - "proc-log": "^2.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^2.0.2" - } - }, - "@npmcli/installed-package-contents": { - "version": "1.0.7", - "bundled": true, - "dev": true, - "requires": { - "npm-bundled": "^1.1.1", - "npm-normalize-package-bin": "^1.0.1" - }, - "dependencies": { - "npm-bundled": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - } - } - }, - "@npmcli/map-workspaces": { - "version": "2.0.4", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/name-from-folder": "^1.0.1", - "glob": "^8.0.1", - "minimatch": "^5.0.1", - "read-package-json-fast": "^2.0.3" - } - }, - "@npmcli/metavuln-calculator": { - "version": "3.1.1", - "bundled": true, - "dev": true, - "requires": { - "cacache": "^16.0.0", - "json-parse-even-better-errors": "^2.3.1", - "pacote": "^13.0.3", - "semver": "^7.3.5" - } - }, - "@npmcli/move-file": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - } - }, - "@npmcli/name-from-folder": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "@npmcli/node-gyp": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "@npmcli/package-json": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "json-parse-even-better-errors": "^2.3.1" - } - }, - "@npmcli/promise-spawn": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "infer-owner": "^1.0.4" - } - }, - "@npmcli/query": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "requires": { - "npm-package-arg": "^9.1.0", - "postcss-selector-parser": "^6.0.10", - "semver": "^7.3.7" - } - }, - "@npmcli/run-script": { - "version": "4.2.1", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/node-gyp": "^2.0.0", - "@npmcli/promise-spawn": "^3.0.0", - "node-gyp": "^9.0.0", - "read-package-json-fast": "^2.0.3", - "which": "^2.0.2" - } - }, - "@tootallnate/once": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "bundled": true, - "dev": true, - "requires": { - "debug": "4" - } - }, - "agentkeepalive": { - "version": "4.2.1", - "bundled": true, - "dev": true, - "requires": { - "debug": "^4.1.0", - "depd": "^1.1.2", - "humanize-ms": "^1.2.1" - } - }, - "aggregate-error": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ansi-regex": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "bundled": true, - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "aproba": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "archy": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "are-we-there-yet": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - } - }, - "asap": { - "version": "2.0.6", - "bundled": true, - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "bin-links": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "requires": { - "cmd-shim": "^5.0.0", - "mkdirp-infer-owner": "^2.0.0", - "npm-normalize-package-bin": "^2.0.0", - "read-cmd-shim": "^3.0.0", - "rimraf": "^3.0.0", - "write-file-atomic": "^4.0.0" - }, - "dependencies": { - "npm-normalize-package-bin": { - "version": "2.0.0", - "bundled": true, - "dev": true - } - } - }, - "binary-extensions": { - "version": "2.2.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "builtins": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "requires": { - "semver": "^7.0.0" - } - }, - "cacache": { - "version": "16.1.3", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/fs": "^2.1.0", - "@npmcli/move-file": "^2.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "infer-owner": "^1.0.4", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11", - "unique-filename": "^2.0.0" - } - }, - "chalk": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "chownr": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "cidr-regex": { - "version": "3.1.1", - "bundled": true, - "dev": true, - "requires": { - "ip-regex": "^4.1.0" - } - }, - "clean-stack": { - "version": "2.2.0", - "bundled": true, - "dev": true - }, - "cli-columns": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - } - }, - "cli-table3": { - "version": "0.6.2", - "bundled": true, - "dev": true, - "requires": { - "@colors/colors": "1.5.0", - "string-width": "^4.2.0" - } - }, - "clone": { - "version": "1.0.4", - "bundled": true, - "dev": true - }, - "cmd-shim": { - "version": "5.0.0", - "bundled": true, - "dev": true, - "requires": { - "mkdirp-infer-owner": "^2.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "bundled": true, - "dev": true - }, - "color-support": { - "version": "1.1.3", - "bundled": true, - "dev": true - }, - "columnify": { - "version": "1.6.0", - "bundled": true, - "dev": true, - "requires": { - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.0" - } - }, - "common-ancestor-path": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "cssesc": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "debug": { - "version": "4.3.4", - "bundled": true, - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true - } - } - }, - "debuglog": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "defaults": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "requires": { - "clone": "^1.0.2" - } - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "depd": { - "version": "1.1.2", - "bundled": true, - "dev": true - }, - "dezalgo": { - "version": "1.0.4", - "bundled": true, - "dev": true, - "requires": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, - "diff": { - "version": "5.1.0", - "bundled": true, - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "bundled": true, - "dev": true - }, - "encoding": { - "version": "0.1.13", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "iconv-lite": "^0.6.2" - } - }, - "env-paths": { - "version": "2.2.1", - "bundled": true, - "dev": true - }, - "err-code": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "fastest-levenshtein": { - "version": "1.0.12", - "bundled": true, - "dev": true - }, - "fs-minipass": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "gauge": { - "version": "4.0.4", - "bundled": true, - "dev": true, - "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - } - }, - "glob": { - "version": "8.0.3", - "bundled": true, - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - } - }, - "graceful-fs": { - "version": "4.2.10", - "bundled": true, - "dev": true - }, - "has": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "hosted-git-info": { - "version": "5.2.1", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^7.5.1" - } - }, - "http-cache-semantics": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "http-proxy-agent": { - "version": "5.0.0", - "bundled": true, - "dev": true, - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - } - }, - "https-proxy-agent": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "humanize-ms": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "requires": { - "ms": "^2.0.0" - } - }, - "iconv-lite": { - "version": "0.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "ignore-walk": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "requires": { - "minimatch": "^5.0.1" - } - }, - "imurmurhash": { - "version": "0.1.4", - "bundled": true, - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "bundled": true, - "dev": true - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true, - "dev": true - }, - "ini": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "init-package-json": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "requires": { - "npm-package-arg": "^9.0.1", - "promzard": "^0.3.0", - "read": "^1.0.7", - "read-package-json": "^5.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^4.0.0" - } - }, - "ip": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "ip-regex": { - "version": "4.3.0", - "bundled": true, - "dev": true - }, - "is-cidr": { - "version": "4.0.2", - "bundled": true, - "dev": true, - "requires": { - "cidr-regex": "^3.1.1" - } - }, - "is-core-module": { - "version": "2.10.0", - "bundled": true, - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "is-lambda": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "bundled": true, - "dev": true - }, - "json-stringify-nice": { - "version": "1.1.4", - "bundled": true, - "dev": true - }, - "jsonparse": { - "version": "1.3.1", - "bundled": true, - "dev": true - }, - "just-diff": { - "version": "5.1.1", - "bundled": true, - "dev": true - }, - "just-diff-apply": { - "version": "5.4.1", - "bundled": true, - "dev": true - }, - "libnpmaccess": { - "version": "6.0.4", - "bundled": true, - "dev": true, - "requires": { - "aproba": "^2.0.0", - "minipass": "^3.1.1", - "npm-package-arg": "^9.0.1", - "npm-registry-fetch": "^13.0.0" - } - }, - "libnpmdiff": { - "version": "4.0.5", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/disparity-colors": "^2.0.0", - "@npmcli/installed-package-contents": "^1.0.7", - "binary-extensions": "^2.2.0", - "diff": "^5.1.0", - "minimatch": "^5.0.1", - "npm-package-arg": "^9.0.1", - "pacote": "^13.6.1", - "tar": "^6.1.0" - } - }, - "libnpmexec": { - "version": "4.0.14", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/arborist": "^5.6.3", - "@npmcli/ci-detect": "^2.0.0", - "@npmcli/fs": "^2.1.1", - "@npmcli/run-script": "^4.2.0", - "chalk": "^4.1.0", - "mkdirp-infer-owner": "^2.0.0", - "npm-package-arg": "^9.0.1", - "npmlog": "^6.0.2", - "pacote": "^13.6.1", - "proc-log": "^2.0.0", - "read": "^1.0.7", - "read-package-json-fast": "^2.0.2", - "semver": "^7.3.7", - "walk-up-path": "^1.0.0" - } - }, - "libnpmfund": { - "version": "3.0.5", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/arborist": "^5.6.3" - } - }, - "libnpmhook": { - "version": "8.0.4", - "bundled": true, - "dev": true, - "requires": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^13.0.0" - } - }, - "libnpmorg": { - "version": "4.0.4", - "bundled": true, - "dev": true, - "requires": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^13.0.0" - } - }, - "libnpmpack": { - "version": "4.1.3", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/run-script": "^4.1.3", - "npm-package-arg": "^9.0.1", - "pacote": "^13.6.1" - } - }, - "libnpmpublish": { - "version": "6.0.5", - "bundled": true, - "dev": true, - "requires": { - "normalize-package-data": "^4.0.0", - "npm-package-arg": "^9.0.1", - "npm-registry-fetch": "^13.0.0", - "semver": "^7.3.7", - "ssri": "^9.0.0" - } - }, - "libnpmsearch": { - "version": "5.0.4", - "bundled": true, - "dev": true, - "requires": { - "npm-registry-fetch": "^13.0.0" - } - }, - "libnpmteam": { - "version": "4.0.4", - "bundled": true, - "dev": true, - "requires": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^13.0.0" - } - }, - "libnpmversion": { - "version": "3.0.7", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/git": "^3.0.0", - "@npmcli/run-script": "^4.1.3", - "json-parse-even-better-errors": "^2.3.1", - "proc-log": "^2.0.0", - "semver": "^7.3.7" - } - }, - "lru-cache": { - "version": "7.13.2", - "bundled": true, - "dev": true - }, - "make-fetch-happen": { - "version": "10.2.1", - "bundled": true, - "dev": true, - "requires": { - "agentkeepalive": "^4.2.1", - "cacache": "^16.1.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^2.0.3", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^9.0.0" - } - }, - "minimatch": { - "version": "5.1.0", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "minipass": { - "version": "3.3.4", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "minipass-collect": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-fetch": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "encoding": "^0.1.13", - "minipass": "^3.1.6", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - } - }, - "minipass-flush": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-json-stream": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - } - }, - "minipass-pipeline": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-sized": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "bundled": true, - "dev": true - }, - "mkdirp-infer-owner": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "chownr": "^2.0.0", - "infer-owner": "^1.0.4", - "mkdirp": "^1.0.3" - } - }, - "ms": { - "version": "2.1.3", - "bundled": true, - "dev": true - }, - "mute-stream": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "negotiator": { - "version": "0.6.3", - "bundled": true, - "dev": true - }, - "node-gyp": { - "version": "9.1.0", - "bundled": true, - "dev": true, - "requires": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^10.0.3", - "nopt": "^5.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "glob": { - "version": "7.2.3", - "bundled": true, - "dev": true, - "requires": { - "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" - } - }, - "minimatch": { - "version": "3.1.2", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "nopt": { - "version": "5.0.0", - "bundled": true, - "dev": true, - "requires": { - "abbrev": "1" - } - } - } - }, - "nopt": { - "version": "6.0.0", - "bundled": true, - "dev": true, - "requires": { - "abbrev": "^1.0.0" - } - }, - "normalize-package-data": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "requires": { - "hosted-git-info": "^5.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - } - }, - "npm-audit-report": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "chalk": "^4.0.0" - } - }, - "npm-bundled": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "npm-normalize-package-bin": "^2.0.0" - }, - "dependencies": { - "npm-normalize-package-bin": { - "version": "2.0.0", - "bundled": true, - "dev": true - } - } - }, - "npm-install-checks": { - "version": "5.0.0", - "bundled": true, - "dev": true, - "requires": { - "semver": "^7.1.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "npm-package-arg": { - "version": "9.1.0", - "bundled": true, - "dev": true, - "requires": { - "hosted-git-info": "^5.0.0", - "proc-log": "^2.0.1", - "semver": "^7.3.5", - "validate-npm-package-name": "^4.0.0" - } - }, - "npm-packlist": { - "version": "5.1.3", - "bundled": true, - "dev": true, - "requires": { - "glob": "^8.0.1", - "ignore-walk": "^5.0.1", - "npm-bundled": "^2.0.0", - "npm-normalize-package-bin": "^2.0.0" - }, - "dependencies": { - "npm-normalize-package-bin": { - "version": "2.0.0", - "bundled": true, - "dev": true - } - } - }, - "npm-pick-manifest": { - "version": "7.0.2", - "bundled": true, - "dev": true, - "requires": { - "npm-install-checks": "^5.0.0", - "npm-normalize-package-bin": "^2.0.0", - "npm-package-arg": "^9.0.0", - "semver": "^7.3.5" - }, - "dependencies": { - "npm-normalize-package-bin": { - "version": "2.0.0", - "bundled": true, - "dev": true - } - } - }, - "npm-profile": { - "version": "6.2.1", - "bundled": true, - "dev": true, - "requires": { - "npm-registry-fetch": "^13.0.1", - "proc-log": "^2.0.0" - } - }, - "npm-registry-fetch": { - "version": "13.3.1", - "bundled": true, - "dev": true, - "requires": { - "make-fetch-happen": "^10.0.6", - "minipass": "^3.1.6", - "minipass-fetch": "^2.0.3", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^9.0.1", - "proc-log": "^2.0.0" - } - }, - "npm-user-validate": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "npmlog": { - "version": "6.0.2", - "bundled": true, - "dev": true, - "requires": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opener": { - "version": "1.5.2", - "bundled": true, - "dev": true - }, - "p-map": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "pacote": { - "version": "13.6.2", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/git": "^3.0.0", - "@npmcli/installed-package-contents": "^1.0.7", - "@npmcli/promise-spawn": "^3.0.0", - "@npmcli/run-script": "^4.1.0", - "cacache": "^16.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "infer-owner": "^1.0.4", - "minipass": "^3.1.6", - "mkdirp": "^1.0.4", - "npm-package-arg": "^9.0.0", - "npm-packlist": "^5.1.0", - "npm-pick-manifest": "^7.0.0", - "npm-registry-fetch": "^13.0.1", - "proc-log": "^2.0.0", - "promise-retry": "^2.0.1", - "read-package-json": "^5.0.0", - "read-package-json-fast": "^2.0.3", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11" - } - }, - "parse-conflict-json": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "json-parse-even-better-errors": "^2.3.1", - "just-diff": "^5.0.1", - "just-diff-apply": "^5.2.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "postcss-selector-parser": { - "version": "6.0.10", - "bundled": true, - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "proc-log": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "promise-all-reject-late": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "promise-call-limit": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "promise-retry": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - } - }, - "promzard": { - "version": "0.3.0", - "bundled": true, - "dev": true, - "requires": { - "read": "1" - } - }, - "qrcode-terminal": { - "version": "0.12.0", - "bundled": true, - "dev": true - }, - "read": { - "version": "1.0.7", - "bundled": true, - "dev": true, - "requires": { - "mute-stream": "~0.0.4" - } - }, - "read-cmd-shim": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "read-package-json": { - "version": "5.0.2", - "bundled": true, - "dev": true, - "requires": { - "glob": "^8.0.1", - "json-parse-even-better-errors": "^2.3.1", - "normalize-package-data": "^4.0.0", - "npm-normalize-package-bin": "^2.0.0" - }, - "dependencies": { - "npm-normalize-package-bin": { - "version": "2.0.0", - "bundled": true, - "dev": true - } - } - }, - "read-package-json-fast": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "requires": { - "json-parse-even-better-errors": "^2.3.0", - "npm-normalize-package-bin": "^1.0.1" - } - }, - "readable-stream": { - "version": "3.6.0", - "bundled": true, - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdir-scoped-modules": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" - } - }, - "retry": { - "version": "0.12.0", - "bundled": true, - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "glob": { - "version": "7.2.3", - "bundled": true, - "dev": true, - "requires": { - "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" - } - }, - "minimatch": { - "version": "3.1.2", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "safe-buffer": { - "version": "5.2.1", - "bundled": true, - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "7.3.7", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "signal-exit": { - "version": "3.0.7", - "bundled": true, - "dev": true - }, - "smart-buffer": { - "version": "4.2.0", - "bundled": true, - "dev": true - }, - "socks": { - "version": "2.7.0", - "bundled": true, - "dev": true, - "requires": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - } - }, - "socks-proxy-agent": { - "version": "7.0.0", - "bundled": true, - "dev": true, - "requires": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - } - }, - "spdx-correct": { - "version": "3.1.1", - "bundled": true, - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "bundled": true, - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.11", - "bundled": true, - "dev": true - }, - "ssri": { - "version": "9.0.1", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.1.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "4.2.3", - "bundled": true, - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "bundled": true, - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "tar": { - "version": "6.1.11", - "bundled": true, - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "text-table": { - "version": "0.2.0", - "bundled": true, - "dev": true - }, - "tiny-relative-date": { - "version": "1.3.0", - "bundled": true, - "dev": true - }, - "treeverse": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "unique-filename": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "unique-slug": "^3.0.0" - } - }, - "unique-slug": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "validate-npm-package-name": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "builtins": "^5.0.0" - } - }, - "walk-up-path": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "wcwidth": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "defaults": "^1.0.3" - } - }, - "which": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wide-align": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "write-file-atomic": { - "version": "4.0.2", - "bundled": true, - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - } - }, - "yallist": { - "version": "4.0.0", - "bundled": true, - "dev": true - } - } - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "nwsapi": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.1.tgz", - "integrity": "sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg==", - "dev": true - }, - "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", - "dev": true - }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "open": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", - "dev": true, - "requires": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - } - }, - "opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "dev": true - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "p-each-series": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", - "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", - "dev": true - }, - "p-filter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", - "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", - "dev": true, - "requires": { - "p-map": "^2.0.0" - } - }, - "p-is-promise": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", - "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "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==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - }, - "dependencies": { - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - } - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-reduce": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", - "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", - "dev": true - }, - "p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "dev": true, - "requires": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true - }, - "pkg-conf": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", - "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "load-json-file": "^4.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - } - } - }, - "portfinder": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", - "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", - "dev": true, - "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true - }, - "prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "requires": { - "fast-diff": "^1.1.2" - } - }, - "pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "dev": true - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "dependencies": { - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true - } - } - }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "dev": true - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dev": true, - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true - } - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true - } - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - }, - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", - "dev": true, - "requires": { - "resolve": "^1.9.0" - } - }, - "redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "requires": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - } - }, - "redeyed": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", - "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", - "dev": true, - "requires": { - "esprima": "~4.0.0" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "registry-auth-token": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", - "dev": true, - "requires": { - "@pnpm/npm-conf": "^2.1.0" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "resolve-global": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", - "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", - "dev": true, - "requires": { - "global-dirs": "^0.1.1" - } - }, - "resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true - }, - "retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "requires": { - "xmlchars": "^2.2.0" - } - }, - "schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } - }, - "secure-compare": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", - "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", - "dev": true - }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", - "dev": true - }, - "selfsigned": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.0.1.tgz", - "integrity": "sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ==", - "dev": true, - "requires": { - "node-forge": "^1" - } - }, - "semantic-release": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-19.0.3.tgz", - "integrity": "sha512-HaFbydST1cDKZHuFZxB8DTrBLJVK/AnDExpK0s3EqLIAAUAHUgnd+VSJCUtTYQKkAkauL8G9CucODrVCc7BuAA==", - "dev": true, - "requires": { - "@semantic-release/commit-analyzer": "^9.0.2", - "@semantic-release/error": "^3.0.0", - "@semantic-release/github": "^8.0.0", - "@semantic-release/npm": "^9.0.0", - "@semantic-release/release-notes-generator": "^10.0.0", - "aggregate-error": "^3.0.0", - "cosmiconfig": "^7.0.0", - "debug": "^4.0.0", - "env-ci": "^5.0.0", - "execa": "^5.0.0", - "figures": "^3.0.0", - "find-versions": "^4.0.0", - "get-stream": "^6.0.0", - "git-log-parser": "^1.2.0", - "hook-std": "^2.0.0", - "hosted-git-info": "^4.0.0", - "lodash": "^4.17.21", - "marked": "^4.0.10", - "marked-terminal": "^5.0.0", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "p-reduce": "^2.0.0", - "read-pkg-up": "^7.0.0", - "resolve-from": "^5.0.0", - "semver": "^7.3.2", - "semver-diff": "^3.1.1", - "signale": "^1.2.1", - "yargs": "^16.2.0" - }, - "dependencies": { - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, - "requires": { - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "semver-regex": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz", - "integrity": "sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==", - "dev": true - }, - "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - } - } - }, - "serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "dev": true - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true - } - } - }, - "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - } - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "signale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz", - "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==", - "dev": true, - "requires": { - "chalk": "^2.3.2", - "figures": "^2.0.0", - "pkg-conf": "^2.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "dev": true, - "requires": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "spawn-error-forwarder": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", - "integrity": "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==", - "dev": true - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", - "dev": true - }, - "spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - } - }, - "spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dev": true, - "requires": { - "through": "2" - } - }, - "split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", - "dev": true, - "requires": { - "readable-stream": "^3.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - }, - "stream-combiner2": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", - "dev": true, - "requires": { - "duplexer2": "~0.1.0", - "readable-stream": "^2.0.2" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "requires": { - "min-indent": "^1.0.0" - } - }, - "strip-json-comments": { - "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==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", - "dev": true, - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, - "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true - }, - "temp-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "dev": true - }, - "tempy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-1.0.1.tgz", - "integrity": "sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w==", - "dev": true, - "requires": { - "del": "^6.0.0", - "is-stream": "^2.0.0", - "temp-dir": "^2.0.0", - "type-fest": "^0.16.0", - "unique-string": "^2.0.0" - }, - "dependencies": { - "type-fest": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", - "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", - "dev": true - } - } - }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - } - }, - "terser": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz", - "integrity": "sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==", - "dev": true, - "requires": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - } - }, - "terser-webpack-plugin": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz", - "integrity": "sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.17", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.16.5" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "requires": {} - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "schema-utils": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", - "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-extensions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", - "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", - "dev": true - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "requires": { - "readable-stream": "3" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true - }, - "tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "to-fast-properties": { - "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==", - "dev": true - }, - "to-regex-range": { - "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==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true - }, - "tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", - "dev": true, - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "dependencies": { - "universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true - } - } - }, - "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "requires": { - "punycode": "^2.1.1" - } - }, - "traverse": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", - "integrity": "sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw==", - "dev": true - }, - "trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true - }, - "ts-jest": { - "version": "27.1.4", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.4.tgz", - "integrity": "sha512-qjkZlVPWVctAezwsOD1OPzbZ+k7zA5z3oxII4dGdZo5ggX/PL7kvwTM0pXTr10fAtbiVpJaL3bWd502zAhpgSQ==", - "dev": true, - "requires": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - } - }, - "ts-loader": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.3.1.tgz", - "integrity": "sha512-OkyShkcZTsTwyS3Kt7a4rsT/t2qvEVQuKCTg4LJmpj9fhFR7ukGdZwV6Qq3tRUkqcXtfGpPR7+hFKHCG/0d3Lw==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4" - } - }, - "ts-node": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.0.tgz", - "integrity": "sha512-/fNd5Qh+zTt8Vt1KbYZjRHCE9sI5i7nqfD/dzBBRDeVXZXS6kToW6R7tTU6Nd4XavFs0mAVCg29Q//ML7WsZYA==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "dependencies": { - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - } - } - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "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==", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", - "dev": true - }, - "uglify-js": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.2.tgz", - "integrity": "sha512-AaQNokTNgExWrkEYA24BTNMSjyqEXPSfhqoS0AxmHkCJ4U+Dyy5AvbGV/sqxuxficEfGGoX3zWw9R7QpLFfEsg==", - "dev": true, - "optional": true - }, - "union": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", - "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", - "dev": true, - "requires": { - "qs": "^6.4.0" - } - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "universal-user-agent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", - "dev": true - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true - }, - "update-browserslist-db": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz", - "integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "url-join": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", - "dev": true - }, - "url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "dependencies": { - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true - } - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true - }, - "w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "requires": { - "browser-process-hrtime": "^1.0.0" - } - }, - "w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "requires": { - "xml-name-validator": "^3.0.0" - } - }, - "walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "requires": { - "makeerror": "1.0.12" - } - }, - "watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", - "dev": true, - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true - }, - "webpack": { - "version": "5.80.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.80.0.tgz", - "integrity": "sha512-OIMiq37XK1rWO8mH9ssfFKZsXg4n6klTEDL7S8/HqbAOBBaiy8ABvXvz0dDCXeEF9gqwxSvVk611zFPjS8hJxA==", - "dev": true, - "requires": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.13.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.2", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "requires": {} - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "schema-utils": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", - "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "webpack-cli": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", - "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", - "dev": true, - "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.2.0", - "@webpack-cli/info": "^1.5.0", - "@webpack-cli/serve": "^1.7.0", - "colorette": "^2.0.14", - "commander": "^7.0.0", - "cross-spawn": "^7.0.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "webpack-merge": "^5.7.3" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - } - } - }, - "webpack-dev-middleware": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", - "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", - "dev": true, - "requires": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - } - }, - "webpack-dev-server": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.9.3.tgz", - "integrity": "sha512-3qp/eoboZG5/6QgiZ3llN8TUzkSpYg1Ko9khWX1h40MIEUNS2mDoIa8aXsPfskER+GbTvs/IJZ1QTBBhhuetSw==", - "dev": true, - "requires": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.1", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.0.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.4.2" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ws": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", - "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", - "dev": true, - "requires": {} - } - } - }, - "webpack-merge": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", - "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", - "dev": true, - "requires": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - } - }, - "webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true - }, - "websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dev": true, - "requires": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true - }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "requires": { - "iconv-lite": "0.4.24" - } - }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", - "dev": true - }, - "word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, - "requires": {} - }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true - }, - "yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" - }, - "dependencies": { - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } } } diff --git a/package.json b/package.json index 38c2c04..9e2f4ed 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "description": "Graph visualization library", "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "repository": { "type": "git", @@ -28,12 +28,12 @@ "build:release": "tsc && webpack", "webpack": "webpack", "webpack:watch": "webpack --watch", - "serve": "http-server ./dist/browser/", + "serve": "http-server ./dist/browser/ -o -c-1 -p 8082", "test": "jest --runInBand --detectOpenHandles --forceExit --verbose --useStderr", "coverage": "npm test -- --coverage --collectCoverageFrom='./src/**'", "lint": "eslint .", "lint:fix": "eslint --fix .", - "release": "semantic-release --branches main", + "release": "semantic-release", "prepare": "husky install" }, "dependencies": { @@ -64,7 +64,7 @@ "@types/d3-selection": "3.0.1", "@types/d3-transition": "3.0.1", "@types/d3-zoom": "3.0.1", - "@types/jest": "27.4.1", + "@types/jest": "29.5.12", "@types/leaflet": "1.7.9", "@types/resize-observer-browser": "^0.1.7", "@typescript-eslint/eslint-plugin": "5.24.0", @@ -78,10 +78,10 @@ "eslint-plugin-prettier": "4.0.0", "http-server": "^14.1.1", "husky": "^8.0.1", - "jest": "27.5.1", + "jest": "29.7.0", "prettier": "^2.7.1", "semantic-release": "19.0.3", - "ts-jest": "27.1.4", + "ts-jest": "29.1.2", "ts-loader": "^9.3.1", "ts-node": "10.8.0", "typescript": "4.6.3", @@ -103,5 +103,10 @@ "coverageDirectory": "coverage", "testEnvironment": "node", "testTimeout": 5000 + }, + "release": { + "branches": [ + "main" + ] } -} +} \ No newline at end of file diff --git a/src/events.ts b/src/events.ts index 03e790d..22e5924 100644 --- a/src/events.ts +++ b/src/events.ts @@ -33,36 +33,36 @@ export enum OrbEventType { MOUSE_DOUBLE_CLICK = 'mouse-double-click', } -interface IOrbEventDuration { +export interface IOrbEventDuration { durationMs: number; } -interface IOrbEventProgress { +export interface IOrbEventProgress { progress: number; } -interface IOrbEventMousePosition { +export interface IOrbEventMousePosition { localPoint: IPosition; globalPoint: IPosition; } -interface IOrbEventMouseClickEvent extends IOrbEventMousePosition { +export interface IOrbEventMouseClickEvent extends IOrbEventMousePosition { event: PointerEvent; } -interface IOrbEventMouseMoveEvent extends IOrbEventMousePosition { +export interface IOrbEventMouseMoveEvent extends IOrbEventMousePosition { event: MouseEvent; } -interface IOrbEventMouseEvent extends IOrbEventMousePosition { +export interface IOrbEventMouseEvent extends IOrbEventMousePosition { subject?: INode | IEdge; } -interface IOrbEventMouseNodeEvent { +export interface IOrbEventMouseNodeEvent { node: INode; } -interface IOrbEventMouseEdgeEvent { +export interface IOrbEventMouseEdgeEvent { edge: IEdge; } diff --git a/src/models/edge.ts b/src/models/edge.ts index cb818b6..4b36145 100644 --- a/src/models/edge.ts +++ b/src/models/edge.ts @@ -1,7 +1,9 @@ import { INodeBase, INode } from './node'; -import { GraphObjectState } from './state'; +import { GraphObjectState, IGraphObjectStateOptions, IGraphObjectStateParameters } from './state'; import { Color, IPosition, ICircle, getDistanceToLine } from '../common'; -import { isArrayOfNumbers } from '../utils/type.utils'; +import { isArrayOfNumbers, isFunction, isNumber, isPlainObject } from '../utils/type.utils'; +import { IObserver, ISubject, Subject } from '../utils/observer.utils'; +import { patchProperties } from '../utils/object.utils'; const CURVED_CONTROL_POINT_OFFSET_MIN_SIZE = 4; const CURVED_CONTROL_POINT_OFFSET_MULTIPLIER = 4; @@ -81,11 +83,7 @@ export enum EdgeType { CURVED = 'curved', } -export interface IEdge { - data: E; - position: IEdgePosition; - style: IEdgeStyle; - state: number; +export interface IEdge extends ISubject { readonly id: any; readonly offset: number; readonly start: any; @@ -93,6 +91,12 @@ export interface IEdge { readonly end: any; readonly endNode: INode; readonly type: EdgeType; + getId(): any; + getData(): E; + getPosition(): IEdgePosition; + getStyle(): IEdgeStyle; + getState(): number; + getListeners(): IObserver[]; hasStyle(): boolean; isSelected(): boolean; isHovered(): boolean; @@ -107,20 +111,39 @@ export interface IEdge { getWidth(): number; getColor(): Color | string | undefined; getLineDashPattern(): number[] | null; + setData(data: E): void; + setData(callback: (edge: IEdge) => E): void; + patchData(data: Partial): void; + patchData(callback: (edge: IEdge) => Partial): void; + setStyle(style: IEdgeStyle): void; + setStyle(callback: (edge: IEdge) => IEdgeStyle): void; + patchStyle(style: IEdgeStyle): void; + patchStyle(callback: (edge: IEdge) => IEdgeStyle): void; + setState(state: number): void; + setState(state: IGraphObjectStateParameters): void; + setState(callback: (edge: IEdge) => number): void; + setState(callback: (edge: IEdge) => IGraphObjectStateParameters): void; +} + +export interface IEdgeSettings { + listeners: IObserver[]; } export class EdgeFactory { - static create(data: IEdgeData): IEdge { + static create( + data: IEdgeData, + settings?: IEdgeSettings, + ): IEdge { const type = getEdgeType(data); switch (type) { case EdgeType.STRAIGHT: - return new EdgeStraight(data); + return new EdgeStraight(data, settings); case EdgeType.LOOPBACK: - return new EdgeLoopback(data); + return new EdgeLoopback(data, settings); case EdgeType.CURVED: - return new EdgeCurved(data); + return new EdgeCurved(data, settings); default: - return new EdgeStraight(data); + return new EdgeStraight(data, settings); } } @@ -129,13 +152,18 @@ export class EdgeFactory { data?: Omit, 'data' | 'startNode' | 'endNode'>, ): IEdge { const newEdge = EdgeFactory.create({ - data: edge.data, + data: edge.getData(), offset: data?.offset !== undefined ? data.offset : edge.offset, startNode: edge.startNode, endNode: edge.endNode, }); - newEdge.state = edge.state; - newEdge.style = edge.style; + newEdge.setState(edge.getState()); + newEdge.setStyle(edge.getStyle()); + const listeners = edge.getListeners(); + + for (let i = 0; i < listeners.length; i++) { + newEdge.addListener(listeners[i]); + } return newEdge; } @@ -145,31 +173,56 @@ export const isEdge = (obj: any): obj return obj instanceof EdgeStraight || obj instanceof EdgeCurved || obj instanceof EdgeLoopback; }; -abstract class Edge implements IEdge { - public data: E; +abstract class Edge extends Subject implements IEdge { + protected _data: E; public readonly id: number; public readonly offset: number; public readonly startNode: INode; public readonly endNode: INode; - public style: IEdgeStyle = {}; - public state = GraphObjectState.NONE; - public position: IEdgePosition; + protected _style: IEdgeStyle = {}; + protected _state = GraphObjectState.NONE; + protected _position: IEdgePosition; private _type: EdgeType = EdgeType.STRAIGHT; - constructor(data: IEdgeData) { + constructor(data: IEdgeData, settings?: IEdgeSettings) { + super(); this.id = data.data.id; - this.data = data.data; + this._data = data.data; this.offset = data.offset ?? 0; this.startNode = data.startNode; this.endNode = data.endNode; this._type = getEdgeType(data); - this.position = { id: this.id, source: this.startNode.id, target: this.endNode.id }; + this._position = { id: this.id, source: this.startNode.getId(), target: this.endNode.getId() }; this.startNode.addEdge(this); this.endNode.addEdge(this); + + if (settings && settings.listeners) { + this.listeners = settings.listeners; + } + } + + getId(): number { + return this.id; + } + + getData(): E { + return structuredClone(this._data); + } + + getPosition(): IEdgePosition { + return structuredClone(this._position); + } + + getStyle(): IEdgeStyle { + return structuredClone(this._style); + } + + getState(): number { + return this._state; } get type(): EdgeType { @@ -177,27 +230,27 @@ abstract class Edge implements IEdge 0; + return this._style && Object.keys(this._style).length > 0; } isSelected(): boolean { - return this.state === GraphObjectState.SELECTED; + return this._state === GraphObjectState.SELECTED; } isHovered(): boolean { - return this.state === GraphObjectState.HOVERED; + return this._state === GraphObjectState.HOVERED; } clearState(): void { - this.state = GraphObjectState.NONE; + this._state = GraphObjectState.NONE; } isLoopback(): boolean { @@ -236,25 +289,25 @@ abstract class Edge implements IEdge 0 || (this.style.shadowOffsetX ?? 0) > 0 || (this.style.shadowOffsetY ?? 0) > 0 + (this._style.shadowSize ?? 0) > 0 || (this._style.shadowOffsetX ?? 0) > 0 || (this._style.shadowOffsetY ?? 0) > 0 ); } getWidth(): number { let width = 0; - if (this.style.width !== undefined) { - width = this.style.width; + if (this._style.width !== undefined) { + width = this._style.width; } - if (this.isHovered() && this.style.widthHover !== undefined) { - width = this.style.widthHover; + if (this.isHovered() && this._style.widthHover !== undefined) { + width = this._style.widthHover; } - if (this.isSelected() && this.style.widthSelected !== undefined) { - width = this.style.widthSelected; + if (this.isSelected() && this._style.widthSelected !== undefined) { + width = this._style.widthSelected; } return width; } @@ -262,21 +315,21 @@ abstract class Edge implements IEdge implements IEdge) => E): void; + setData(arg: E | ((edge: IEdge) => E)) { + if (isFunction(arg)) { + this._data = (arg as (edge: IEdge) => E)(this); + } else { + this._data = arg as E; + } + this.notifyListeners(); + } + + patchData(data: Partial): void; + patchData(callback: (edge: IEdge) => Partial): void; + patchData(arg: Partial | ((edge: IEdge) => Partial)) { + let data: Partial; + + if (isFunction(arg)) { + data = (arg as (edge: IEdge) => Partial)(this); + } else { + data = arg as Partial; + } + + patchProperties(this._data, data); + + this.notifyListeners(); + } + + setStyle(style: IEdgeStyle): void; + setStyle(callback: (edge: IEdge) => IEdgeStyle): void; + setStyle(arg: IEdgeStyle | ((edge: IEdge) => IEdgeStyle)): void { + if (isFunction(arg)) { + this._style = (arg as (edge: IEdge) => IEdgeStyle)(this); + } else { + this._style = arg as IEdgeStyle; + } + this.notifyListeners(); + } + + patchStyle(style: IEdgeStyle): void; + patchStyle(callback: (edge: IEdge) => IEdgeStyle): void; + patchStyle(arg: IEdgeStyle | ((edge: IEdge) => IEdgeStyle)) { + let style: IEdgeStyle; + + if (isFunction(arg)) { + style = (arg as (edge: IEdge) => IEdgeStyle)(this); + } else { + style = arg as IEdgeStyle; + } + + patchProperties(this._style, style); + + this.notifyListeners(); + } + + setState(state: number): void; + setState(state: IGraphObjectStateParameters): void; + setState(callback: (edge: IEdge) => number): void; + setState(callback: (edge: IEdge) => IGraphObjectStateParameters): void; + setState( + arg: + | number + | IGraphObjectStateParameters + | ((edge: IEdge) => number) + | ((edge: IEdge) => IGraphObjectStateParameters), + ): void { + let result: number | IGraphObjectStateParameters; + + if (isFunction(arg)) { + result = (arg as (edge: IEdge) => number | IGraphObjectStateParameters)(this); + } else { + result = arg; + } + + if (isNumber(result)) { + this._state = result; + } else if (isPlainObject(result)) { + const options = result.options; + + this._state = this._handleState(result.state, options); + + if (options) { + this.notifyListeners({ + id: this.id, + type: 'edge', + options: options, + }); + + return; + } + } + + this.notifyListeners(); + } + + private _handleState(state: number, options?: Partial): number { + if (options?.isToggle && this._state === state) { + return GraphObjectState.NONE; + } else { + return state; + } + } } const getEdgeType = (data: IEdgeData): EdgeType => { - if (data.startNode.id === data.endNode.id) { + if (data.startNode.getId() === data.endNode.getId()) { return EdgeType.LOOPBACK; } return (data.offset ?? 0) === 0 ? EdgeType.STRAIGHT : EdgeType.CURVED; diff --git a/src/models/graph.ts b/src/models/graph.ts index b80a5b7..071612f 100644 --- a/src/models/graph.ts +++ b/src/models/graph.ts @@ -5,66 +5,93 @@ import { IGraphStyle } from './style'; import { ImageHandler } from '../services/images'; import { getEdgeOffsets } from './topology'; import { IEntityState, EntityState } from '../utils/entity.utils'; +import { IObserver, IObserverDataPayload, ISubject, Subject } from '../utils/observer.utils'; +import { patchProperties } from '../utils/object.utils'; +import { dedupArrays } from '../utils/array.utils'; export interface IGraphData { nodes: N[]; edges: E[]; } +export interface IGraphObjectsIds { + nodeIds: any[]; + edgeIds: any[]; +} + export type IEdgeFilter = (edge: IEdge) => boolean; export type INodeFilter = (node: INode) => boolean; -export interface IGraph { +export interface IGraph extends ISubject { getNodes(filterBy?: INodeFilter): INode[]; getEdges(filterBy?: IEdgeFilter): IEdge[]; getNodeCount(): number; getEdgeCount(): number; getNodeById(id: any): INode | undefined; getEdgeById(id: any): IEdge | undefined; + getNodePositions(filterBy?: INodeFilter): INodePosition[]; getSelectedNodes(): INode[]; getSelectedEdges(): IEdge[]; getHoveredNodes(): INode[]; getHoveredEdges(): IEdge[]; - getNodePositions(): INodePosition[]; setNodePositions(positions: INodePosition[]): void; - getEdgePositions(): IEdgePosition[]; + getEdgePositions(filterBy?: IEdgeFilter): IEdgePosition[]; setDefaultStyle(style: Partial>): void; setup(data: Partial>): void; clearPositions(): void; merge(data: Partial>): void; - remove(data: Partial<{ nodeIds: number[]; edgeIds: number[] }>): void; + remove(data: Partial): void; + removeAll(): void; + removeAllNodes(): void; + removeAllEdges(): void; isEqual(graph: Graph): boolean; getBoundingBox(): IRectangle; getNearestNode(point: IPosition): INode | undefined; getNearestEdge(point: IPosition, minDistance?: number): IEdge | undefined; + setSettings(settings: Partial>): void; } -// TODO: Move this to node events when image listening will be on node level -// TODO: Add global events user can listen for: images-load-start, images-load-end -export interface IGraphSettings { - onLoadedImages: () => void; +export interface IGraphSettings { + // TODO(tlastre): Move this to node events when image listening will be on node level + // TODO(tlastre): Add global events user can listen for: images-load-start, images-load-end + onLoadedImages?: () => void; + onSetupData?: (data: Partial>) => void; + onMergeData?: (data: Partial>) => void; + onRemoveData?: (data: Partial) => void; + listeners?: IObserver[]; } -export class Graph implements IGraph { +export class Graph extends Subject implements IGraph { private _nodes: IEntityState> = new EntityState>({ - getId: (node) => node.id, - sortBy: (node1, node2) => (node1.style.zIndex ?? 0) - (node2.style.zIndex ?? 0), + getId: (node) => node.getId(), + sortBy: (node1, node2) => (node1.getStyle().zIndex ?? 0) - (node2.getStyle().zIndex ?? 0), }); private _edges: IEntityState> = new EntityState>({ - getId: (edge) => edge.id, - sortBy: (edge1, edge2) => (edge1.style.zIndex ?? 0) - (edge2.style.zIndex ?? 0), + getId: (edge) => edge.getId(), + sortBy: (edge1, edge2) => (edge1.getStyle().zIndex ?? 0) - (edge2.getStyle().zIndex ?? 0), }); private _defaultStyle?: Partial>; - private _onLoadedImages?: () => void; + private _settings: IGraphSettings; - constructor(data?: Partial>, settings?: Partial) { - this._onLoadedImages = settings?.onLoadedImages; + constructor(data?: Partial>, settings?: Partial>) { + // TODO(dlozic): How to use object assign here? If I add add and export a default const here, it needs N, E. + super(); + this._settings = settings || {}; const nodes = data?.nodes ?? []; const edges = data?.edges ?? []; + if (settings && settings.listeners) { + this.listeners = settings.listeners; + } + this.notifyListeners = this.notifyListeners.bind(this); this.setup({ nodes, edges }); } + setSettings(settings: Partial>) { + patchProperties(this._settings, settings); + this.notifyListeners(); + } + /** * Returns a list of nodes. * @@ -162,13 +189,14 @@ export class Graph implements IGraph): INodePosition[] { + const nodes = this.getNodes(filterBy); const positions: INodePosition[] = new Array(nodes.length); for (let i = 0; i < nodes.length; i++) { - positions[i] = nodes[i].position; + positions[i] = nodes[i].getPosition(); } return positions; } @@ -182,7 +210,7 @@ export class Graph implements IGraph implements IGraph): IEdgePosition[] { + const edges = this.getEdges(filterBy); const positions: IEdgePosition[] = new Array(edges.length); for (let i = 0; i < edges.length; i++) { - positions[i] = edges[i].position; + positions[i] = edges[i].getPosition(); } return positions; } @@ -225,6 +254,8 @@ export class Graph implements IGraph implements IGraph) { + remove(data: Partial) { const nodeIds = data.nodeIds ?? []; const edgeIds = data.edgeIds ?? []; - this._removeNodes(nodeIds); - this._removeEdges(edgeIds); + const removedNodesData = this._removeNodes(nodeIds); + const removedEdgesData = this._removeEdges(edgeIds); this._applyEdgeOffsets(); this._applyStyle(); + + if (this._settings && this._settings.onRemoveData) { + const removedData: IGraphObjectsIds = { + nodeIds: dedupArrays(removedNodesData.nodeIds, removedEdgesData.nodeIds), + edgeIds: dedupArrays(removedNodesData.edgeIds, removedEdgesData.edgeIds), + }; + + this._settings.onRemoveData(removedData); + } + } + + removeAll() { + const nodeIds = this._nodes.getAll().map((node) => node.id); + const edgeIds = this._edges.getAll().map((edge) => edge.id); + + this.remove({ nodeIds, edgeIds }); + } + + removeAllEdges() { + const edgeIds = this._edges.getAll().map((edge) => edge.id); + + this.remove({ edgeIds }); + } + + removeAllNodes() { + this.removeAll(); } isEqual(graph: Graph): boolean { @@ -267,14 +326,14 @@ export class Graph implements IGraph implements IGraph { + if (data && 'type' in data && 'options' in data && 'isSingle' in data.options) { + if (data.type === 'node' && data.options.isSingle) { + const nodes = this._nodes.getAll(); + + for (let i = 0; i < nodes.length; i++) { + if (nodes[i].id !== data.id) { + nodes[i].clearState(); + } + } + } + + if (data.type === 'edge' && data.options.isSingle) { + const edges = this._edges.getAll(); + + for (let i = 0; i < edges.length; i++) { + if (edges[i].id !== data.id) { + edges[i].clearState(); + } + } + } + } + + this.notifyListeners(data); + }; + private _insertNodes(nodes: N[]) { const newNodes: INode[] = new Array>(nodes.length); for (let i = 0; i < nodes.length; i++) { - newNodes[i] = NodeFactory.create({ data: nodes[i] }, { onLoadedImage: () => this._onLoadedImages?.() }); + newNodes[i] = NodeFactory.create( + { data: nodes[i] }, + { onLoadedImage: () => this._settings?.onLoadedImages?.(), listeners: [this._update] }, + ); } this._nodes.setMany(newNodes); } @@ -367,11 +457,16 @@ export class Graph implements IGraph({ - data: edges[i], - startNode, - endNode, - }), + EdgeFactory.create( + { + data: edges[i], + startNode, + endNode, + }, + { + listeners: [this._update], + }, + ), ); } } @@ -383,11 +478,17 @@ export class Graph implements IGraph({ data: nodes[i] }, { onLoadedImage: () => this._onLoadedImages?.() })); + newNodes.push( + NodeFactory.create( + { data: nodes[i] }, + { onLoadedImage: () => this._settings?.onLoadedImages?.(), listeners: [this._update] }, + ), + ); } this._nodes.setMany(newNodes); } @@ -406,11 +507,16 @@ export class Graph implements IGraph({ - data: newEdgeData, - startNode, - endNode, - }); + const edge = EdgeFactory.create( + { + data: newEdgeData, + startNode, + endNode, + }, + { + listeners: [this._update], + }, + ); newEdges.push(edge); } continue; @@ -418,7 +524,7 @@ export class Graph implements IGraph implements IGraph({ - data: newEdgeData, - offset: existingEdge.offset, - startNode, - endNode, - }); - edge.state = existingEdge.state; - edge.style = existingEdge.style; + const edge = EdgeFactory.create( + { + data: newEdgeData, + offset: existingEdge.offset, + startNode, + endNode, + }, + { + listeners: [this._update], + }, + ); + edge.setState(existingEdge.getState()); + edge.setStyle(existingEdge.getStyle()); newEdges.push(edge); } @@ -448,7 +559,7 @@ export class Graph implements IGraph implements IGraph implements IGraph implements IGraph implements IGraph { - this._onLoadedImages?.(); + this._settings?.onLoadedImages?.(); }); } diff --git a/src/models/node.ts b/src/models/node.ts index 320ddb6..78afeaa 100644 --- a/src/models/node.ts +++ b/src/models/node.ts @@ -1,7 +1,10 @@ import { IEdge, IEdgeBase } from './edge'; import { Color, IPosition, IRectangle, isPointInRectangle } from '../common'; import { ImageHandler } from '../services/images'; -import { GraphObjectState } from './state'; +import { GraphObjectState, IGraphObjectStateOptions, IGraphObjectStateParameters } from './state'; +import { IObserver, ISubject, Subject } from '../utils/observer.utils'; +import { patchProperties } from '../utils/object.utils'; +import { isFunction, isNumber, isPlainObject } from '../utils/type.utils'; /** * Node baseline object with required fields @@ -21,6 +24,15 @@ export interface INodePosition { y?: number; } +export interface INodeCoordinates { + x: number; + y: number; +} + +export interface INodeSetPositionOptions { + isNotifySkipped: boolean; +} + export enum NodeShapeType { CIRCLE = 'circle', DOT = 'dot', @@ -65,12 +77,13 @@ export interface INodeData { data: N; } -export interface INode { - data: N; - position: INodePosition; - style: INodeStyle; - state: number; - readonly id: any; +export interface INode extends ISubject { + id: number; + getId(): number; + getData(): N; + getPosition(): INodePosition; + getStyle(): INodeStyle; + getState(): number; clearPosition(): void; getCenter(): IPosition; getRadius(): number; @@ -95,12 +108,30 @@ export interface INode { getBorderWidth(): number; getBorderColor(): Color | string | undefined; getBackgroundImage(): HTMLImageElement | undefined; + setData(data: N): void; + setData(callback: (node: INode) => N): void; + patchData(data: Partial): void; + patchData(callback: (node: INode) => Partial): void; + setPosition(position: INodeCoordinates | INodePosition, options?: INodeSetPositionOptions): void; + setPosition( + callback: (node: INode) => INodeCoordinates | INodePosition, + options?: INodeSetPositionOptions, + ): void; + setStyle(style: INodeStyle): void; + setStyle(callback: (node: INode) => INodeStyle): void; + patchStyle(style: INodeStyle): void; + patchStyle(callback: (node: INode) => INodeStyle): void; + setState(state: number): void; + setState(state: IGraphObjectStateParameters): void; + setState(callback: (node: INode) => number): void; + setState(callback: (node: INode) => IGraphObjectStateParameters): void; } // TODO: Dirty solution: Find another way to listen for global images, maybe through // events that user can listen for: images-load-start, images-load-end export interface INodeSettings { onLoadedImage: () => void; + listeners: IObserver[]; } export class NodeFactory { @@ -116,40 +147,66 @@ export const isNode = (obj: any): obj return obj instanceof Node; }; -export class Node implements INode { +export class Node extends Subject implements INode { public readonly id: number; - public data: N; - public position: INodePosition; - public style: INodeStyle = {}; - public state = GraphObjectState.NONE; + protected _data: N; + protected _position: INodePosition; + protected _style: INodeStyle = {}; + protected _state = GraphObjectState.NONE; private readonly _inEdgesById: { [id: number]: IEdge } = {}; private readonly _outEdgesById: { [id: number]: IEdge } = {}; private readonly _onLoadedImage?: () => void; constructor(data: INodeData, settings?: Partial) { + super(); this.id = data.data.id; - this.data = data.data; - this.position = { id: this.id }; + this._data = data.data; + this._position = { id: this.id }; this._onLoadedImage = settings?.onLoadedImage; + if (settings && settings.listeners) { + this.listeners = settings.listeners; + } + } + + getId(): number { + return this.id; + } + + getData(): N { + return structuredClone(this._data); + } + + getPosition(): INodePosition { + return structuredClone(this._position); + } + + getStyle(): INodeStyle { + return structuredClone(this._style); + } + + getState(): number { + return this._state; } clearPosition() { - this.position.x = undefined; - this.position.y = undefined; + this._position.x = undefined; + this._position.y = undefined; + + this.notifyListeners(); } getCenter(): IPosition { // This should not be called in the render because nodes without position will be // filtered out - if (this.position.x === undefined || this.position.y === undefined) { + if (this._position.x === undefined || this._position.y === undefined) { return { x: 0, y: 0 }; } - return { x: this.position.x, y: this.position.y }; + return { x: this._position.x, y: this._position.y }; } getRadius(): number { - return this.style.size ?? 0; + return this._style.size ?? 0; } getBorderedRadius(): number { @@ -181,13 +238,13 @@ export class Node implements INode implements INode implements INode implements INode 0; + return this._style && Object.keys(this._style).length > 0; } addEdge(edge: IEdge) { if (edge.start === this.id) { - this._outEdgesById[edge.id] = edge; + this._outEdgesById[edge.getId()] = edge; } if (edge.end === this.id) { - this._inEdgesById[edge.id] = edge; + this._inEdgesById[edge.getId()] = edge; } } removeEdge(edge: IEdge) { - delete this._outEdgesById[edge.id]; - delete this._inEdgesById[edge.id]; + delete this._outEdgesById[edge.getId()]; + delete this._inEdgesById[edge.getId()]; } isSelected(): boolean { - return this.state === GraphObjectState.SELECTED; + return this._state === GraphObjectState.SELECTED; } isHovered(): boolean { - return this.state === GraphObjectState.HOVERED; + return this._state === GraphObjectState.HOVERED; } clearState(): void { - this.state = GraphObjectState.NONE; + this.setState(GraphObjectState.NONE); + + this.notifyListeners(); } getDistanceToBorder(): number { @@ -257,7 +316,7 @@ export class Node implements INode implements INode 0 || (this.style.shadowOffsetX ?? 0) > 0 || (this.style.shadowOffsetY ?? 0) > 0 + (this._style.shadowSize ?? 0) > 0 || (this._style.shadowOffsetX ?? 0) > 0 || (this._style.shadowOffsetY ?? 0) > 0 ); } hasBorder(): boolean { - const hasBorderWidth = (this.style.borderWidth ?? 0) > 0; - const hasBorderWidthSelected = (this.style.borderWidthSelected ?? 0) > 0; + const hasBorderWidth = (this._style.borderWidth ?? 0) > 0; + const hasBorderWidthSelected = (this._style.borderWidthSelected ?? 0) > 0; return hasBorderWidth || (this.isSelected() && hasBorderWidthSelected); } getLabel(): string | undefined { - return this.style.label; + return this._style.label; } getColor(): Color | string | undefined { let color: Color | string | undefined = undefined; - if (this.style.color) { - color = this.style.color; + if (this._style.color) { + color = this._style.color; } - if (this.isHovered() && this.style.colorHover) { - color = this.style.colorHover; + if (this.isHovered() && this._style.colorHover) { + color = this._style.colorHover; } - if (this.isSelected() && this.style.colorSelected) { - color = this.style.colorSelected; + if (this.isSelected() && this._style.colorSelected) { + color = this._style.colorSelected; } return color; @@ -304,11 +363,11 @@ export class Node implements INode 0) { - borderWidth = this.style.borderWidth; + if (this._style.borderWidth && this._style.borderWidth > 0) { + borderWidth = this._style.borderWidth; } - if (this.isSelected() && this.style.borderWidthSelected && this.style.borderWidthSelected > 0) { - borderWidth = this.style.borderWidthSelected; + if (this.isSelected() && this._style.borderWidthSelected && this._style.borderWidthSelected > 0) { + borderWidth = this._style.borderWidthSelected; } return borderWidth; } @@ -320,31 +379,31 @@ export class Node implements INode implements INode) => N): void; + setData(arg: N | ((node: INode) => N)) { + if (isFunction(arg)) { + this._data = (arg as (node: INode) => N)(this); + } else { + this._data = arg as N; + } + this.notifyListeners(); + } + + patchData(data: Partial): void; + patchData(callback: (node: INode) => Partial): void; + patchData(arg: Partial | ((node: INode) => Partial)) { + let data: Partial; + + if (isFunction(arg)) { + data = (arg as (node: INode) => Partial)(this); + } else { + data = arg as Partial; + } + + patchProperties(this._data, data); + + this.notifyListeners(); + } + + setPosition(position: INodeCoordinates | INodePosition, options?: INodeSetPositionOptions): void; + setPosition( + callback: (node: INode) => INodeCoordinates | INodePosition, + options?: INodeSetPositionOptions, + ): void; + setPosition( + arg: INodeCoordinates | INodePosition | ((node: INode) => INodeCoordinates | INodePosition), + options?: INodeSetPositionOptions, + ) { + let position: INodeCoordinates | INodePosition; + if (isFunction(arg)) { + position = (arg as (node: INode) => INodeCoordinates)(this); + } else { + position = arg; + } + + if ('x' in position && 'y' in position) { + this._position.x = position.x; + this._position.y = position.y; + if ('id' in position) { + this._position.id = position.id; + } + } + + if (!options?.isNotifySkipped) { + this.notifyListeners({ id: this.id, ...position }); + } + } + + setStyle(style: INodeStyle): void; + setStyle(callback: (node: INode) => INodeStyle): void; + setStyle(arg: INodeStyle | ((node: INode) => INodeStyle)): void { + if (isFunction(arg)) { + this._style = (arg as (node: INode) => INodeStyle)(this); + } else { + this._style = arg as INodeStyle; + } + this.notifyListeners(); + } + + patchStyle(style: INodeStyle): void; + patchStyle(callback: (node: INode) => INodeStyle): void; + patchStyle(arg: INodeStyle | ((node: INode) => INodeStyle)) { + let style: INodeStyle; + + if (isFunction(arg)) { + style = (arg as (node: INode) => INodeStyle)(this); + } else { + style = arg as INodeStyle; + } + + patchProperties(this._style, style); + + this.notifyListeners(); + } + + setState(state: number): void; + setState(state: IGraphObjectStateParameters): void; + setState(callback: (node: INode) => number): void; + setState(callback: (node: INode) => IGraphObjectStateParameters): void; + setState( + arg: + | number + | IGraphObjectStateParameters + | ((node: INode) => number) + | ((node: INode) => IGraphObjectStateParameters), + ): void { + let result: number | IGraphObjectStateParameters; + + if (isFunction(arg)) { + result = (arg as (node: INode) => number | IGraphObjectStateParameters)(this); + } else { + result = arg; + } + + if (isNumber(result)) { + this._state = result; + } else if (isPlainObject(result)) { + const options = result.options; + + this._state = this._handleState(result.state, options); + + if (options) { + this.notifyListeners({ + id: this.id, + type: 'node', + options: options, + }); + + return; + } + } + + this.notifyListeners(); + } + protected _isPointInBoundingBox(point: IPosition): boolean { return isPointInRectangle(this.getBoundingBox(), point); } + + private _handleState(state: number, options?: Partial): number { + if (options?.isToggle && this._state === state) { + return GraphObjectState.NONE; + } else { + return state; + } + } } diff --git a/src/models/state.ts b/src/models/state.ts index a2f6a38..6a06839 100644 --- a/src/models/state.ts +++ b/src/models/state.ts @@ -1,6 +1,24 @@ +import { GraphObject } from '../utils/observer.utils'; + // Enum is dismissed so user can define custom additional events (numbers) export const GraphObjectState = { NONE: 0, SELECTED: 1, HOVERED: 2, }; + +export interface IGraphObjectStateOptions { + isToggle: boolean; + isSingle: boolean; +} + +export interface IGraphObjectStateParameters { + state: number; + options?: Partial; +} + +export interface ISetStateDataPayload { + id: any; + type: GraphObject; + options: Partial; +} diff --git a/src/models/strategy.ts b/src/models/strategy.ts index ed8fb08..d1fe4a6 100644 --- a/src/models/strategy.ts +++ b/src/models/strategy.ts @@ -229,24 +229,24 @@ const setNodeState = ( options?: ISetShapeStateOptions, ): void => { if (isStateChangeable(node, options)) { - node.state = state; + node.setState(state); } node.getInEdges().forEach((edge) => { if (edge && isStateChangeable(edge, options)) { - edge.state = state; + edge.setState(state); } if (edge.startNode && isStateChangeable(edge.startNode, options)) { - edge.startNode.state = state; + edge.startNode.setState(state); } }); node.getOutEdges().forEach((edge) => { if (edge && isStateChangeable(edge, options)) { - edge.state = state; + edge.setState(state); } if (edge.endNode && isStateChangeable(edge.endNode, options)) { - edge.endNode.state = state; + edge.endNode.setState(state); } }); }; @@ -257,15 +257,15 @@ const setEdgeState = ( options?: ISetShapeStateOptions, ): void => { if (isStateChangeable(edge, options)) { - edge.state = state; + edge.setState(state); } if (edge.startNode && isStateChangeable(edge.startNode, options)) { - edge.startNode.state = state; + edge.startNode.setState(state); } if (edge.endNode && isStateChangeable(edge.endNode, options)) { - edge.endNode.state = state; + edge.endNode.setState(state); } }; @@ -274,5 +274,5 @@ const isStateChangeable = ( options?: ISetShapeStateOptions, ): boolean => { const isOverride = options?.isStateOverride; - return isOverride || (!isOverride && !graphObject.state); + return isOverride || (!isOverride && !graphObject.getState()); }; diff --git a/src/models/style.ts b/src/models/style.ts index 358d2d5..e5bf506 100644 --- a/src/models/style.ts +++ b/src/models/style.ts @@ -33,8 +33,9 @@ export const getDefaultGraphStyle = () const getPredefinedLabel = ( obj: INode | IEdge, ): string | undefined => { + const objData = obj.getData(); for (let i = 0; i < LABEL_PROPERTY_NAMES.length; i++) { - const value = (obj.data as any)[LABEL_PROPERTY_NAMES[i]]; + const value = (objData as any)[LABEL_PROPERTY_NAMES[i]]; if (value !== undefined && value !== null) { return `${value}`; } diff --git a/src/renderer/canvas/canvas-renderer.ts b/src/renderer/canvas/canvas-renderer.ts index 9265d93..3e1eed8 100644 --- a/src/renderer/canvas/canvas-renderer.ts +++ b/src/renderer/canvas/canvas-renderer.ts @@ -150,10 +150,6 @@ export class CanvasRenderer extends Em } private _render(graph: IGraph) { - if (!graph.getNodeCount()) { - return; - } - this.emit(RenderEventType.RENDER_START, undefined); const renderStartedAt = Date.now(); diff --git a/src/renderer/canvas/edge/base.ts b/src/renderer/canvas/edge/base.ts index f6fd2f5..fc338b7 100644 --- a/src/renderer/canvas/edge/base.ts +++ b/src/renderer/canvas/edge/base.ts @@ -52,14 +52,16 @@ const drawEdgeLabel = ( return; } + const edgeStyle = edge.getStyle(); + const label = new Label(edgeLabel, { position: edge.getCenter(), textBaseline: LabelTextBaseline.MIDDLE, properties: { - fontBackgroundColor: edge.style.fontBackgroundColor, - fontColor: edge.style.fontColor, - fontFamily: edge.style.fontFamily, - fontSize: edge.style.fontSize, + fontBackgroundColor: edgeStyle.fontBackgroundColor, + fontColor: edgeStyle.fontColor, + fontFamily: edgeStyle.fontFamily, + fontSize: edgeStyle.fontSize, }, }); drawLabel(context, label); @@ -80,7 +82,7 @@ const drawLine = (context: CanvasRende }; const drawArrow = (context: CanvasRenderingContext2D, edge: IEdge) => { - if (edge.style.arrowSize === 0) { + if (edge.getStyle().arrowSize === 0) { return; } @@ -145,17 +147,19 @@ const setupShadow = ( context: CanvasRenderingContext2D, edge: IEdge, ) => { - if (edge.style.shadowColor) { - context.shadowColor = edge.style.shadowColor.toString(); + const edgeStyle = edge.getStyle(); + + if (edgeStyle.shadowColor) { + context.shadowColor = edgeStyle.shadowColor.toString(); } - if (edge.style.shadowSize) { - context.shadowBlur = edge.style.shadowSize; + if (edgeStyle.shadowSize) { + context.shadowBlur = edgeStyle.shadowSize; } - if (edge.style.shadowOffsetX) { - context.shadowOffsetX = edge.style.shadowOffsetX; + if (edgeStyle.shadowOffsetX) { + context.shadowOffsetX = edgeStyle.shadowOffsetX; } - if (edge.style.shadowOffsetY) { - context.shadowOffsetY = edge.style.shadowOffsetY; + if (edgeStyle.shadowOffsetY) { + context.shadowOffsetY = edgeStyle.shadowOffsetY; } }; @@ -163,16 +167,18 @@ const clearShadow = ( context: CanvasRenderingContext2D, edge: IEdge, ) => { - if (edge.style.shadowColor) { + const edgeStyle = edge.getStyle(); + + if (edgeStyle.shadowColor) { context.shadowColor = 'rgba(0,0,0,0)'; } - if (edge.style.shadowSize) { + if (edgeStyle.shadowSize) { context.shadowBlur = 0; } - if (edge.style.shadowOffsetX) { + if (edgeStyle.shadowOffsetX) { context.shadowOffsetX = 0; } - if (edge.style.shadowOffsetY) { + if (edgeStyle.shadowOffsetY) { context.shadowOffsetY = 0; } }; diff --git a/src/renderer/canvas/edge/types/edge-curved.ts b/src/renderer/canvas/edge/types/edge-curved.ts index 5da1859..0feaabc 100644 --- a/src/renderer/canvas/edge/types/edge-curved.ts +++ b/src/renderer/canvas/edge/types/edge-curved.ts @@ -32,7 +32,7 @@ export const drawCurvedLine = ( * @return {IEdgeArrow} Arrow shape */ export const getCurvedArrowShape = (edge: EdgeCurved): IEdgeArrow => { - const scaleFactor = edge.style.arrowSize ?? 1; + const scaleFactor = edge.getStyle().arrowSize ?? 1; const lineWidth = edge.getWidth() ?? 1; const guideOffset = -0.1; // const source = this.data.source; @@ -104,7 +104,7 @@ const findBorderPoint = ( const viaNode = edge.getCurvedControlPoint(); let node = edge.endNode; let from = false; - if (nearNode.id === edge.startNode.id) { + if (nearNode.getId() === edge.startNode.getId()) { node = edge.startNode; from = true; } diff --git a/src/renderer/canvas/edge/types/edge-loopback.ts b/src/renderer/canvas/edge/types/edge-loopback.ts index 6aaaaaa..7c84808 100644 --- a/src/renderer/canvas/edge/types/edge-loopback.ts +++ b/src/renderer/canvas/edge/types/edge-loopback.ts @@ -29,7 +29,7 @@ export const drawLoopbackLine = ( export const getLoopbackArrowShape = ( edge: EdgeLoopback, ): IEdgeArrow => { - const scaleFactor = edge.style.arrowSize ?? 1; + const scaleFactor = edge.getStyle().arrowSize ?? 1; const lineWidth = edge.getWidth() ?? 1; const source = edge.startNode; // const target = this.data.target; diff --git a/src/renderer/canvas/edge/types/edge-straight.ts b/src/renderer/canvas/edge/types/edge-straight.ts index 67cafdc..c011410 100644 --- a/src/renderer/canvas/edge/types/edge-straight.ts +++ b/src/renderer/canvas/edge/types/edge-straight.ts @@ -33,7 +33,7 @@ export const drawStraightLine = ( export const getStraightArrowShape = ( edge: EdgeStraight, ): IEdgeArrow => { - const scaleFactor = edge.style.arrowSize ?? 1; + const scaleFactor = edge.getStyle().arrowSize ?? 1; const lineWidth = edge.getWidth() ?? 1; const sourcePoint = edge.startNode.getCenter(); const targetPoint = edge.endNode.getCenter(); @@ -63,7 +63,7 @@ const findBorderPoint = ( ): IBorderPosition => { let endNode = edge.endNode; let startNode = edge.startNode; - if (nearNode.id === edge.startNode.id) { + if (nearNode.getId() === edge.startNode.getId()) { endNode = edge.startNode; startNode = edge.endNode; } diff --git a/src/renderer/canvas/node.ts b/src/renderer/canvas/node.ts index 814d7a6..ee4c202 100644 --- a/src/renderer/canvas/node.ts +++ b/src/renderer/canvas/node.ts @@ -2,6 +2,7 @@ import { INodeBase, INode, NodeShapeType } from '../../models/node'; import { IEdgeBase } from '../../models/edge'; import { drawDiamond, drawHexagon, drawSquare, drawStar, drawTriangleDown, drawTriangleUp, drawCircle } from './shapes'; import { drawLabel, Label, LabelTextBaseline } from './label'; +import { Color } from '../../common'; // The label will be `X` of the size below the Node const DEFAULT_LABEL_DISTANCE_SIZE_FROM_NODE = 0.2; @@ -53,7 +54,7 @@ const drawShape = (context: CanvasRend const center = node.getCenter(); const radius = node.getRadius(); - switch (node.style.shape) { + switch (node.getStyle().shape) { case NodeShapeType.SQUARE: { drawSquare(context, center.x, center.y, radius); break; @@ -96,15 +97,16 @@ const drawNodeLabel = ( const center = node.getCenter(); const distance = node.getBorderedRadius() * (1 + DEFAULT_LABEL_DISTANCE_SIZE_FROM_NODE); + const nodeStyle = node.getStyle(); const label = new Label(nodeLabel, { position: { x: center.x, y: center.y + distance }, textBaseline: LabelTextBaseline.TOP, properties: { - fontBackgroundColor: node.style.fontBackgroundColor, - fontColor: node.style.fontColor, - fontFamily: node.style.fontFamily, - fontSize: node.style.fontSize, + fontBackgroundColor: nodeStyle.fontBackgroundColor, + fontColor: nodeStyle.fontColor, + fontFamily: nodeStyle.fontFamily, + fontSize: nodeStyle.fontSize, }, }); drawLabel(context, label); @@ -156,17 +158,19 @@ const setupShadow = ( context: CanvasRenderingContext2D, node: INode, ) => { - if (node.style.shadowColor) { - context.shadowColor = node.style.shadowColor.toString(); + const nodeStyle = node.getStyle(); + + if (nodeStyle.shadowColor) { + context.shadowColor = (nodeStyle.shadowColor as string | Color).toString(); } - if (node.style.shadowSize) { - context.shadowBlur = node.style.shadowSize; + if (nodeStyle.shadowSize) { + context.shadowBlur = nodeStyle.shadowSize as number; } - if (node.style.shadowOffsetX) { - context.shadowOffsetX = node.style.shadowOffsetX; + if (nodeStyle.shadowOffsetX) { + context.shadowOffsetX = nodeStyle.shadowOffsetX as number; } - if (node.style.shadowOffsetY) { - context.shadowOffsetY = node.style.shadowOffsetY; + if (nodeStyle.shadowOffsetY) { + context.shadowOffsetY = nodeStyle.shadowOffsetY as number; } }; @@ -174,16 +178,18 @@ const clearShadow = ( context: CanvasRenderingContext2D, node: INode, ) => { - if (node.style.shadowColor) { + const nodeStyle = node.getStyle(); + + if (nodeStyle.shadowColor) { context.shadowColor = 'rgba(0,0,0,0)'; } - if (node.style.shadowSize) { + if (nodeStyle.shadowSize) { context.shadowBlur = 0; } - if (node.style.shadowOffsetX) { + if (nodeStyle.shadowOffsetX) { context.shadowOffsetX = 0; } - if (node.style.shadowOffsetY) { + if (nodeStyle.shadowOffsetY) { context.shadowOffsetY = 0; } }; diff --git a/src/simulator/engine/d3-simulator-engine.ts b/src/simulator/engine/d3-simulator-engine.ts index 1eb27d5..225fd67 100644 --- a/src/simulator/engine/d3-simulator-engine.ts +++ b/src/simulator/engine/d3-simulator-engine.ts @@ -11,21 +11,22 @@ import { SimulationLinkDatum, } from 'd3-force'; import { IPosition } from '../../common'; -import { ISimulationNode, ISimulationEdge } from '../shared'; +import { ISimulationNode, ISimulationEdge, ISimulationGraph } from '../shared'; import { Emitter } from '../../utils/emitter.utils'; import { isObjectEqual, copyObject } from '../../utils/object.utils'; const MANY_BODY_MAX_DISTANCE_TO_LINK_DISTANCE_RATIO = 100; -const DEFAULT_LINK_DISTANCE = 30; +const DEFAULT_LINK_DISTANCE = 50; export enum D3SimulatorEngineEventType { - TICK = 'tick', - END = 'end', SIMULATION_START = 'simulation-start', SIMULATION_PROGRESS = 'simulation-progress', SIMULATION_END = 'simulation-end', + SIMULATION_TICK = 'simulation-tick', + SIMULATION_RESET = 'simulation-reset', NODE_DRAG = 'node-drag', SETTINGS_UPDATE = 'settings-update', + DATA_CLEARED = 'data-cleared', } export interface ID3SimulatorEngineSettingsAlpha { @@ -72,6 +73,9 @@ export interface ID3SimulatorEngineSettingsPositioning { } export interface ID3SimulatorEngineSettings { + isSimulatingOnDataUpdate: boolean; + isSimulatingOnSettingsUpdate: boolean; + isSimulatingOnUnstick: boolean; isPhysicsEnabled: boolean; alpha: ID3SimulatorEngineSettingsAlpha; centering: ID3SimulatorEngineSettingsCentering | null; @@ -89,12 +93,15 @@ export const getManyBodyMaxDistance = (linkDistance: number) => { }; export const DEFAULT_SETTINGS: ID3SimulatorEngineSettings = { + isSimulatingOnDataUpdate: true, + isSimulatingOnSettingsUpdate: true, + isSimulatingOnUnstick: true, isPhysicsEnabled: false, alpha: { alpha: 1, alphaMin: 0.001, alphaDecay: 0.0228, - alphaTarget: 0.1, + alphaTarget: 0, }, centering: { x: 0, @@ -108,7 +115,7 @@ export const DEFAULT_SETTINGS: ID3SimulatorEngineSettings = { }, links: { distance: DEFAULT_LINK_DISTANCE, - strength: undefined, + strength: 1, iterations: 1, }, manyBody: { @@ -133,11 +140,6 @@ export interface ID3SimulatorProgress { progress: number; } -export interface ID3SimulatorGraph { - nodes: ISimulationNode[]; - edges: ISimulationEdge[]; -} - export interface ID3SimulatorNodeId { id: number; } @@ -151,19 +153,20 @@ interface IRunSimulationOptions { } export type D3SimulatorEvents = { - [D3SimulatorEngineEventType.TICK]: ID3SimulatorGraph; - [D3SimulatorEngineEventType.END]: ID3SimulatorGraph; [D3SimulatorEngineEventType.SIMULATION_START]: undefined; - [D3SimulatorEngineEventType.SIMULATION_PROGRESS]: ID3SimulatorGraph & ID3SimulatorProgress; - [D3SimulatorEngineEventType.SIMULATION_END]: ID3SimulatorGraph; - [D3SimulatorEngineEventType.NODE_DRAG]: ID3SimulatorGraph; + [D3SimulatorEngineEventType.SIMULATION_PROGRESS]: ISimulationGraph & ID3SimulatorProgress; + [D3SimulatorEngineEventType.SIMULATION_END]: ISimulationGraph; + [D3SimulatorEngineEventType.SIMULATION_TICK]: ISimulationGraph; + [D3SimulatorEngineEventType.SIMULATION_RESET]: ISimulationGraph; + [D3SimulatorEngineEventType.NODE_DRAG]: ISimulationGraph; [D3SimulatorEngineEventType.SETTINGS_UPDATE]: ID3SimulatorSettings; + [D3SimulatorEngineEventType.DATA_CLEARED]: ISimulationGraph; }; export class D3SimulatorEngine extends Emitter { - protected readonly linkForce: ForceLink>; - protected readonly simulation: Simulation; - protected readonly settings: ID3SimulatorEngineSettings; + protected _linkForce!: ForceLink>; + protected _simulation!: Simulation; + protected _settings: ID3SimulatorEngineSettings; protected _edges: ISimulationEdge[] = []; protected _nodes: ISimulationNode[] = []; @@ -172,53 +175,69 @@ export class D3SimulatorEngine extends Emitter { protected _isDragging = false; protected _isStabilizing = false; + // These are settings provided during construction if they are specified, + // or during the first call of setSettings if unspecified during construction. + protected _initialSettings: ID3SimulatorEngineSettings | undefined; + constructor(settings?: ID3SimulatorEngineSettings) { super(); - this.linkForce = forceLink>(this._edges).id( - (node) => node.id, - ); - this.simulation = forceSimulation(this._nodes).force('link', this.linkForce).stop(); - - this.settings = Object.assign(copyObject(DEFAULT_SETTINGS), settings); - this.initSimulation(this.settings); - - this.simulation.on('tick', () => { - this.emit(D3SimulatorEngineEventType.TICK, { nodes: this._nodes, edges: this._edges }); - }); + if (settings !== undefined) { + this._initialSettings = Object.assign(copyObject(DEFAULT_SETTINGS), settings); + } - this.simulation.on('end', () => { - this._isDragging = false; - this._isStabilizing = false; - this.emit(D3SimulatorEngineEventType.END, { nodes: this._nodes, edges: this._edges }); - }); + this._settings = this.resetSettings(); + this.clearData(); } getSettings(): ID3SimulatorEngineSettings { - return copyObject(this.settings); + return copyObject(this._settings); } + /** + * Applies the specified settings to the D3 simulator engine. + * + * @param {ID3SimulatorEngineSettingsUpdate} settings Partial D3 simulator engine settings (any property of settings) + */ setSettings(settings: ID3SimulatorEngineSettingsUpdate) { + if (!this._initialSettings) { + this._initialSettings = Object.assign(copyObject(DEFAULT_SETTINGS), settings); + } + const previousSettings = this.getSettings(); - Object.keys(settings).forEach((key) => { - // @ts-ignore - this.settings[key] = settings[key]; - }); + Object.assign(this._settings, settings); - if (isObjectEqual(this.settings, previousSettings)) { + if (isObjectEqual(this._settings, previousSettings)) { return; } - this.initSimulation(settings); - this.emit(D3SimulatorEngineEventType.SETTINGS_UPDATE, { settings: this.settings }); + this._applySettingsToSimulation(settings); + this.emit(D3SimulatorEngineEventType.SETTINGS_UPDATE, { settings: this._settings }); + + const hasPhysicsBeenDisabled = previousSettings.isPhysicsEnabled && !settings.isPhysicsEnabled; + + if (hasPhysicsBeenDisabled) { + this._simulation.stop(); + } else if (this._settings.isSimulatingOnSettingsUpdate) { + // this.runSimulation({ isUpdatingSettings: true }); + this.activateSimulation(); + } + } - this.runSimulation({ isUpdatingSettings: true }); + /** + * Restores simulator engine settings to the initial settings provided during construction. + * + * @return {ID3SimulatorEngineSettings} The default settings patched with the specified parameters in the + * initial settings provided in the constructor or during the first settings update. + */ + resetSettings(): ID3SimulatorEngineSettings { + return Object.assign(copyObject(DEFAULT_SETTINGS), this._initialSettings); } startDragNode() { this._isDragging = true; - if (!this._isStabilizing && this.settings.isPhysicsEnabled) { + if (!this._isStabilizing && this._settings.isPhysicsEnabled) { this.activateSimulation(); } } @@ -236,183 +255,377 @@ export class D3SimulatorEngine extends Emitter { node.fx = data.x; node.fy = data.y; - if (!this.settings.isPhysicsEnabled) { + if (!this._settings.isPhysicsEnabled) { node.x = data.x; node.y = data.y; - - // Notify the client that the node position changed. - // This is otherwise handled by the simulation tick if physics is enabled. - this.emit(D3SimulatorEngineEventType.NODE_DRAG, { nodes: this._nodes, edges: this._edges }); } + + // Notify the client that the node position changed. + this.emit(D3SimulatorEngineEventType.NODE_DRAG, { nodes: this._nodes, edges: this._edges }); } endDragNode(data: ID3SimulatorNodeId) { this._isDragging = false; - this.simulation.alphaTarget(0); + if (this._settings.isPhysicsEnabled) { + this._simulation.alphaTarget(0); + } const node = this._nodes[this._nodeIndexByNodeId[data.id]]; - if (node && this.settings.isPhysicsEnabled) { - releaseNode(node); + // TODO(dlozic): Add special behavior for sticky nodes that have been dragged + if (node && this._settings.isPhysicsEnabled) { + this.unfixNode(node); } } - // Re-heat simulation. - // This does not count as "stabilization" and won't emit any progress. + /** + * Activates the simulation and "re-heats" the nodes so that they converge to a new layout. + * This does not count as "stabilization" and won't emit any progress. + */ activateSimulation() { - if (this.settings.isPhysicsEnabled) { - this.simulation.alphaTarget(this.settings.alpha.alphaTarget).restart(); - this.releaseNodes(); + this.unfixNodes(); // If physics is disabled, the nodes get fixed in the callback from the initial setup (`simulation.on('end', () => {})`). + this._simulation.alpha(this._settings.alpha.alpha).alphaTarget(this._settings.alpha.alphaTarget).restart(); + } + + setupData(data: ISimulationGraph) { + this.clearData(); + + this._initializeNewData(data); + + if (this._settings.isSimulatingOnDataUpdate) { + this._updateSimulationData(); + this._runSimulation(); } } - private fixDefinedNodes(data: ID3SimulatorGraph) { - // Treat nodes that have existing coordinates as "fixed". - for (let i = 0; i < data.nodes.length; i++) { - if (data.nodes[i].x !== null && data.nodes[i].x !== undefined) { - data.nodes[i].fx = data.nodes[i].x; + mergeData(data: Partial) { + this._initializeNewData(data); + + if (this._settings.isSimulatingOnDataUpdate) { + this._updateSimulationData(); + this.activateSimulation(); + } + } + + patchData(data: Partial) { + if (data.nodes) { + data.nodes = this._fixAndStickDefinedNodes(data.nodes); + const nodeIds: { [id: number]: number } = {}; + + for (let i = 0; i < this._nodes.length; i++) { + nodeIds[this._nodes[i].id] = i; } - if (data.nodes[i].y !== null && data.nodes[i].y !== undefined) { - data.nodes[i].fy = data.nodes[i].y; + + for (let i = 0; i < data.nodes.length; i += 1) { + const nodeId: any = data.nodes[i].id; + + if (nodeId in nodeIds) { + const index = nodeIds[nodeId]; + this._nodeIndexByNodeId[nodeId] = index; + this._nodes[index] = data.nodes[i]; + } else { + this._nodes.push(data.nodes[i]); + } } } - return data; - } - addData(data: ID3SimulatorGraph) { - data = this.fixDefinedNodes(data); - this._nodes.concat(data.nodes); - this._edges.concat(data.edges); - this.setNodeIndexByNodeId(); + if (data.edges) { + this._edges = this._edges.concat(data.edges); + } } - clearData() { - this._nodes = []; - this._edges = []; - this.setNodeIndexByNodeId(); + private _initializeNewData(data: Partial) { + if (data.nodes) { + data.nodes = this._fixAndStickDefinedNodes(data.nodes); + for (let i = 0; i < data.nodes.length; i += 1) { + const nodeId = data.nodes[i].id; + + if (this._nodeIndexByNodeId[nodeId]) { + this._nodeIndexByNodeId[nodeId] = i; + } else { + this._nodes.push(data.nodes[i]); + } + } + } else { + this._nodes = []; + } + if (data.edges) { + this._edges = this._edges.concat(data.edges); + } else { + this._edges = []; + } + this._setNodeIndexByNodeId(); } - setData(data: ID3SimulatorGraph) { - data = this.fixDefinedNodes(data); - this.clearData(); - this.addData(data); - } + updateData(data: ISimulationGraph) { + data.nodes = this._fixAndStickDefinedNodes(data.nodes); - updateData(data: ID3SimulatorGraph) { - data = this.fixDefinedNodes(data); // Keep existing nodes along with their (x, y, fx, fy) coordinates to avoid // rearranging the graph layout. // These nodes should not be reloaded into the array because the D3 simulation // will assign to them completely new coordinates, effectively restarting the animation. const newNodeIds = new Set(data.nodes.map((node) => node.id)); - // Remove old nodes that aren't present in the new data. + // Keep old nodes that are present in the new data instead of reassigning them. const oldNodes = this._nodes.filter((node) => newNodeIds.has(node.id)); const newNodes = data.nodes.filter((node) => this._nodeIndexByNodeId[node.id] === undefined); this._nodes = [...oldNodes, ...newNodes]; - this.setNodeIndexByNodeId(); + this._setNodeIndexByNodeId(); // Only keep new links and discard all old links. // Old links won't work as some discrepancies arise between the D3 index property // and Memgraph's `id` property which affects the source->target mapping. this._edges = data.edges; - // Update simulation with new data. - this.simulation.nodes(this._nodes); - this.linkForce.links(this._edges); + if (this._settings.isSimulatingOnSettingsUpdate) { + this._updateSimulationData(); + this.activateSimulation(); + } + } + + /** + * Removes specified data from the simulation. + * + * @param {ISimulationGraph} data Nodes and edges that will be deleted + */ + deleteData(data: Partial<{ nodeIds: number[] | undefined; edgeIds: number[] | undefined }>) { + const nodeIds = new Set(data.nodeIds); + this._nodes = this._nodes.filter((node) => !nodeIds.has(node.id)); + const edgeIds = new Set(data.edgeIds); + this._edges = this._edges.filter((edge) => !edgeIds.has(edge.id)); + this._setNodeIndexByNodeId(); + this._updateSimulationData(); } - simulate() { + /** + * Removes all internal and D3 simulation node and relationship data. + */ + clearData() { + const nodes = this._nodes; + const edges = this._edges; + this._nodes = []; + this._edges = []; + this._setNodeIndexByNodeId(); + this.resetSimulation(); + this.emit(D3SimulatorEngineEventType.DATA_CLEARED, { nodes: nodes, edges: edges }); + } + + /** + * Updates the internal D3 simulation data with the current data. + */ + private _updateSimulationData() { // Update simulation with new data. - this.simulation.nodes(this._nodes); - this.linkForce.links(this._edges); + this._simulation.nodes(this._nodes); + this._linkForce.links(this._edges); + } - // Run simulation "physics". - this.runSimulation(); + /** + * Resets the simulator engine by discarding all existing simulator data (nodes and edges), + * and keeping the current simulator engine settings. + */ + // TODO(Alex): Listeners memory leak (D3 force research) + resetSimulation() { + this._linkForce = forceLink>(this._edges).id( + (node) => node.id, + ); + this._simulation = forceSimulation(this._nodes).force('link', this._linkForce).stop(); - if (!this.settings.isPhysicsEnabled) { - this.fixNodes(); - } + this._applySettingsToSimulation(this._settings); + + this._simulation.on('tick', () => { + this.emit(D3SimulatorEngineEventType.SIMULATION_TICK, { nodes: this._nodes, edges: this._edges }); + }); + + this._simulation.on('end', () => { + this._isDragging = false; + this._isStabilizing = false; + this.emit(D3SimulatorEngineEventType.SIMULATION_END, { nodes: this._nodes, edges: this._edges }); + + if (!this._settings.isPhysicsEnabled) { + this.fixNodes(); + } + }); + + this.emit(D3SimulatorEngineEventType.SIMULATION_RESET, { nodes: this._nodes, edges: this._edges }); } - startSimulation(data: ID3SimulatorGraph) { - this.setData(data); + /** + * Fixes all nodes by setting their `fx` and `fy` properties to `x` and `y`. + * If no nodes are provided, this function fixes all nodes. + * + * @param {ISimulationNode[]} nodes Nodes that are going to be fixed. If undefined, all nodes get fixed. + */ + fixNodes(nodes?: ISimulationNode[]) { + if (!nodes) { + nodes = this._nodes; + } - // Update simulation with new data. - this.simulation.nodes(this._nodes); - this.linkForce.links(this._edges); + for (let i = 0; i < nodes.length; i++) { + this.fixNode(this._nodes[i]); + } + } + + /** + * Releases specified nodes. + * If no nodes are provided, this function releases all nodes. + * + * @param {ISimulationNode[]} nodes Nodes that are going to be released. If undefined, all nodes get released. + */ + unfixNodes(nodes?: ISimulationNode[]) { + if (!nodes) { + nodes = this._nodes; + } - // Run simulation "physics". - this.runSimulation(); + for (let i = 0; i < nodes.length; i++) { + this.unfixNode(this._nodes[i]); + } } - updateSimulation(data: ID3SimulatorGraph) { - // To avoid rearranging the graph layout during node expand/collapse/hide, - // it is necessary to keep existing nodes along with their (x, y) coordinates. - // These nodes should not be reloaded into the array because the D3 simulation - // will assign to them completely new coordinates, effectively restarting the animation. - const newNodeIds = new Set(data.nodes.map((node) => node.id)); + /** + * Fixes a node by setting its `fx` and `fy` properties to `x` and `y`. + * This function is called when disabling physics. + * + * @param {ISimulationNode} node Simulation node that is going to be fixed + */ + fixNode(node: ISimulationNode) { + if (node.sx === null || node.sx === undefined) { + node.fx = node.x; + } + if (node.sy === null || node.sy === undefined) { + node.fy = node.y; + } + } - // const newNodes = data.nodes.filter((node) => !this.nodeIdentities.has(node.id)); - const newNodes = data.nodes.filter((node) => this._nodeIndexByNodeId[node.id] === undefined); - const oldNodes = this._nodes.filter((node) => newNodeIds.has(node.id)); + /** + * Releases a node if it's not sticky by setting its `fx` and `fy` properties to `null`. + * This function is called when enabling physics but the sticky property overpowers physics. + * + * @param {ISimulationNode} node Simulation node that is going to be released + */ + unfixNode(node: ISimulationNode) { + if (node.sx === null || node.sx === undefined) { + node.fx = null; + } + if (node.sy === null || node.sy === undefined) { + node.fy = null; + } + } - if (!this.settings.isPhysicsEnabled) { - oldNodes.forEach((node) => fixNode(node)); + /** + * Sticks the specified nodes into place. + * This overpowers any physics state and also sticks the node to their current positions. + * If no nodes are provided, this function sticks all nodes. + * + * @param {ISimulationNode[]} nodes Nodes that are going to become sticky. If undefined, all nodes get sticked. + */ + stickNodes(nodes?: ISimulationNode[]) { + if (!nodes) { + nodes = this._nodes; } - // Remove old nodes that aren't present in the new data. - this._nodes = [...oldNodes, ...newNodes]; - this.setNodeIndexByNodeId(); + for (let i = 0; i < nodes.length; i++) { + this.stickNode(this._nodes[i]); + } + } - // Only keep new links and discard all old links. - // Old links won't work as some discrepancies arise between the D3 index property - // and Memgraph's `id` property which affects the source->target mapping. - this._edges = data.edges; + /** + * Removes the sticky properties from all specified nodes. + * If physics is enabled, the nodes get unfixed as well. + * If no nodes are provided, this function unsticks all nodes. + * + * @param {ISimulationNode[]} nodes Nodes that are going to be unsticked. If undefined, all nodes get unsticked. + */ + unstickNodes(nodes?: ISimulationNode[]) { + if (!nodes) { + nodes = this._nodes; + } - // Update simulation with new data. - this.simulation.nodes(this._nodes); - this.linkForce.links(this._edges); + for (let i = 0; i < nodes.length; i++) { + this.unstickNode(this._nodes[i]); + } - // If there are no new nodes, there is no need for the simulation - if (!this.settings.isPhysicsEnabled && !newNodes.length) { - this.emit(D3SimulatorEngineEventType.SIMULATION_END, { nodes: this._nodes, edges: this._edges }); - return; + if (this._settings.isSimulatingOnUnstick) { + this.activateSimulation(); } + } - // Run simulation "physics". - this.runSimulation({ isUpdatingSettings: true }); + /** + * Sticks a node into place. + * This function overpowers any physics state and also sticks the node to its current coordinates. + * + * @param {ISimulationNode} node Simulation node that is going to become sticky + */ + stickNode(node: ISimulationNode) { + node.sx = node.x; + node.fx = node.x; + node.sy = node.y; + node.fy = node.y; } - stopSimulation() { - this.simulation.stop(); - this._nodes = []; - this._edges = []; - this.setNodeIndexByNodeId(); - this.simulation.nodes(); - this.linkForce.links(); + /** + * Removes the sticky properties from the node. + * If physics is enabled, the node gets released as well. + * + * @param {ISimulationNode} node Simulation node that gets unstuck + */ + unstickNode(node: ISimulationNode) { + node.sx = null; + node.sy = null; + + if (this._settings.isPhysicsEnabled) { + node.fx = null; + node.fy = null; + } } - protected initSimulation(settings: ID3SimulatorEngineSettingsUpdate) { + /** + * Sticks all nodes thath have a defined position (x and y coordinates). + * This function should be called when the user initially sets up or merges some data. + * If the user provided nodes already have defined `x` **or** `y` properties, they are treated as _"sticky"_. + * Only the specified axis gets immobilized. + * + * @param {ISimulationNode[]} nodes Graph nodes. + * @return {ISimulationNodes[]} Graph nodes with attached `{fx, sx}`, and/or `{fy, sy}` coordinates. + */ + private _fixAndStickDefinedNodes(nodes: ISimulationNode[]): ISimulationNode[] { + for (let i = 0; i < nodes.length; i++) { + if (nodes[i].x !== null && nodes[i].x !== undefined) { + nodes[i].fx = nodes[i].x; + nodes[i].sx = nodes[i].x; + } + if (nodes[i].y !== null && nodes[i].y !== undefined) { + nodes[i].fy = nodes[i].y; + nodes[i].sy = nodes[i].y; + } + } + return nodes; + } + + /** + * Applies the provided settings to the D3 simulation. + * + * @param {ID3SimulatorEngineSettingsUpdate} settings Simulator engine settings + */ + private _applySettingsToSimulation(settings: ID3SimulatorEngineSettingsUpdate) { if (settings.alpha) { - this.simulation + this._simulation .alpha(settings.alpha.alpha) .alphaMin(settings.alpha.alphaMin) .alphaDecay(settings.alpha.alphaDecay) .alphaTarget(settings.alpha.alphaTarget); } if (settings.links) { - this.linkForce.distance(settings.links.distance).iterations(settings.links.iterations); + this._linkForce.distance(settings.links.distance).iterations(settings.links.iterations); } if (settings.collision) { const collision = forceCollide() .radius(settings.collision.radius) .strength(settings.collision.strength) .iterations(settings.collision.iterations); - this.simulation.force('collide', collision); + this._simulation.force('collide', collision); } if (settings.collision === null) { - this.simulation.force('collide', null); + this._simulation.force('collide', null); } if (settings.manyBody) { const manyBody = forceManyBody() @@ -420,51 +633,51 @@ export class D3SimulatorEngine extends Emitter { .theta(settings.manyBody.theta) .distanceMin(settings.manyBody.distanceMin) .distanceMax(settings.manyBody.distanceMax); - this.simulation.force('charge', manyBody); + this._simulation.force('charge', manyBody); } if (settings.manyBody === null) { - this.simulation.force('charge', null); + this._simulation.force('charge', null); } if (settings.positioning?.forceY) { const positioningForceX = forceX(settings.positioning.forceX.x).strength(settings.positioning.forceX.strength); - this.simulation.force('x', positioningForceX); + this._simulation.force('x', positioningForceX); } if (settings.positioning?.forceX === null) { - this.simulation.force('x', null); + this._simulation.force('x', null); } if (settings.positioning?.forceY) { const positioningForceY = forceY(settings.positioning.forceY.y).strength(settings.positioning.forceY.strength); - this.simulation.force('y', positioningForceY); + this._simulation.force('y', positioningForceY); } if (settings.positioning?.forceY === null) { - this.simulation.force('y', null); + this._simulation.force('y', null); } if (settings.centering) { const centering = forceCenter(settings.centering.x, settings.centering.y).strength(settings.centering.strength); - this.simulation.force('center', centering); + this._simulation.force('center', centering); } if (settings.centering === null) { - this.simulation.force('center', null); + this._simulation.force('center', null); } } // This is a blocking action - the user will not be able to interact with the graph // during the simulation process. - protected runSimulation(options?: IRunSimulationOptions) { + private _runSimulation(options?: IRunSimulationOptions) { if (this._isStabilizing) { return; } - if (this.settings.isPhysicsEnabled || options?.isUpdatingSettings) { - this.releaseNodes(); + if (this._settings.isPhysicsEnabled || options?.isUpdatingSettings) { + this.unfixNodes(); } this.emit(D3SimulatorEngineEventType.SIMULATION_START, undefined); this._isStabilizing = true; - this.simulation.alpha(this.settings.alpha.alpha).alphaTarget(this.settings.alpha.alphaTarget).stop(); + this._simulation.alpha(this._settings.alpha.alpha).alphaTarget(this._settings.alpha.alphaTarget).stop(); const totalSimulationSteps = Math.ceil( - Math.log(this.settings.alpha.alphaMin) / Math.log(1 - this.settings.alpha.alphaDecay), + Math.log(this._settings.alpha.alphaMin) / Math.log(1 - this._settings.alpha.alphaDecay), ); let lastProgress = -1; @@ -479,10 +692,10 @@ export class D3SimulatorEngine extends Emitter { progress: currentProgress / 100, }); } - this.simulation.tick(); + this._simulation.tick(); } - if (!this.settings.isPhysicsEnabled) { + if (!this._settings.isPhysicsEnabled) { this.fixNodes(); } @@ -490,41 +703,10 @@ export class D3SimulatorEngine extends Emitter { this.emit(D3SimulatorEngineEventType.SIMULATION_END, { nodes: this._nodes, edges: this._edges }); } - protected setNodeIndexByNodeId() { + private _setNodeIndexByNodeId() { this._nodeIndexByNodeId = {}; for (let i = 0; i < this._nodes.length; i++) { this._nodeIndexByNodeId[this._nodes[i].id] = i; } } - - fixNodes(nodes?: ISimulationNode[]) { - if (!nodes) { - nodes = this._nodes; - } - - for (let i = 0; i < nodes.length; i++) { - fixNode(this._nodes[i]); - } - } - - releaseNodes(nodes?: ISimulationNode[]) { - if (!nodes) { - nodes = this._nodes; - } - - for (let i = 0; i < nodes.length; i++) { - releaseNode(this._nodes[i]); - } - } } - -const fixNode = (node: ISimulationNode) => { - // fx and fy fix the node position in the D3 simulation. - node.fx = node.x; - node.fy = node.y; -}; - -const releaseNode = (node: ISimulationNode) => { - node.fx = null; - node.fy = null; -}; diff --git a/src/simulator/factory.ts b/src/simulator/factory.ts index 8ef2466..e902e6f 100644 --- a/src/simulator/factory.ts +++ b/src/simulator/factory.ts @@ -1,7 +1,8 @@ import { ISimulator } from './shared'; import { MainThreadSimulator } from './types/main-thread-simulator'; -import { WebWorkerSimulator } from './types/web-worker-simulator/simulator'; +import { WebWorkerSimulator } from './types/web-worker-simulator/web-worker-simulator'; +// TODO(dlozic & Alex): CORS handling export class SimulatorFactory { static getSimulator(): ISimulator { try { diff --git a/src/simulator/layout/layout.ts b/src/simulator/layout/layout.ts new file mode 100644 index 0000000..defe2bc --- /dev/null +++ b/src/simulator/layout/layout.ts @@ -0,0 +1,29 @@ +import { IEdgeBase } from '../../models/edge'; +import { INode, INodeBase, INodePosition } from '../../models/node'; +import { CircleLayout } from './layouts/circle'; + +export enum layouts { + DEFAULT = 'default', + CIRCLE = 'circle', +} + +export interface ILayout { + getPositions(nodes: INode[], width: number, height: number): INodePosition[]; +} + +export class Layout implements ILayout { + private readonly _layout: ILayout | null; + + private layoutByLayoutName: Record | null> = { + [layouts.DEFAULT]: null, + [layouts.CIRCLE]: new CircleLayout(), + }; + + constructor(layoutName: string) { + this._layout = this.layoutByLayoutName[layoutName]; + } + + getPositions(nodes: INode[], width: number, height: number): INodePosition[] { + return this._layout === null ? [] : this._layout.getPositions(nodes, width, height); + } +} diff --git a/src/simulator/layout/layouts/circle.ts b/src/simulator/layout/layouts/circle.ts new file mode 100644 index 0000000..b601d78 --- /dev/null +++ b/src/simulator/layout/layouts/circle.ts @@ -0,0 +1,11 @@ +import { IEdgeBase } from '../../../models/edge'; +import { INode, INodeBase, INodePosition } from '../../../models/node'; +import { ILayout } from '../layout'; + +export class CircleLayout implements ILayout { + getPositions(nodes: INode[], width: number, height: number): INodePosition[] { + return nodes.map((node, index) => { + return { id: node.id, x: width / 2, y: height - index * 10 }; + }); + } +} diff --git a/src/simulator/shared.ts b/src/simulator/shared.ts index f3d9d11..7501367 100644 --- a/src/simulator/shared.ts +++ b/src/simulator/shared.ts @@ -3,11 +3,39 @@ import { SimulationLinkDatum, SimulationNodeDatum } from 'd3-force'; import { ID3SimulatorEngineSettings, ID3SimulatorEngineSettingsUpdate } from './engine/d3-simulator-engine'; import { IEmitter } from '../utils/emitter.utils'; -export type ISimulationNode = SimulationNodeDatum & { id: number; mass?: number }; +/** + * Node with sticky coordinates. + * A sticky node is immovable and represents a positioned node with user defined coordinates. + * This node isn't affected by physics. + * This enables a combination of sticky and free nodes where the free nodes are positioned + * by the simulator engine to adjust to the immobilized sticky nodes. + * Not to be confused with fixed coordinates `{ fx, fy }` which are used for physics. + */ +export interface IStickyNode { + sx?: number | null; + sy?: number | null; +} + +export type ISimulationNode = SimulationNodeDatum & + IStickyNode & { + id: number; + mass?: number; + }; export type ISimulationEdge = SimulationLinkDatum & { id: number }; +export interface ISimulationGraph { + nodes: ISimulationNode[]; + edges: ISimulationEdge[]; +} + +export interface ISimulationIds { + nodeIds: number[]; + edgeIds: number[]; +} + export enum SimulatorEventType { SIMULATION_START = 'simulation-start', + SIMULATION_STEP = 'simulation-step', SIMULATION_PROGRESS = 'simulation-progress', SIMULATION_END = 'simulation-end', NODE_DRAG = 'node-drag', @@ -17,6 +45,7 @@ export enum SimulatorEventType { export type SimulatorEvents = { [SimulatorEventType.SIMULATION_START]: undefined; + [SimulatorEventType.SIMULATION_STEP]: ISimulatorEventGraph; [SimulatorEventType.SIMULATION_PROGRESS]: ISimulatorEventGraph & ISimulatorEventProgress; [SimulatorEventType.SIMULATION_END]: ISimulatorEventGraph; [SimulatorEventType.NODE_DRAG]: ISimulatorEventGraph; @@ -25,18 +54,16 @@ export type SimulatorEvents = { }; export interface ISimulator extends IEmitter { - // Sets nodes and edges without running simulation - setData(nodes: ISimulationNode[], edges: ISimulationEdge[]): void; - addData(nodes: ISimulationNode[], edges: ISimulationEdge[]): void; - updateData(nodes: ISimulationNode[], edges: ISimulationEdge[]): void; + setupData(data: ISimulationGraph): void; + mergeData(data: ISimulationGraph): void; + updateData(data: ISimulationGraph): void; + deleteData(data: Partial): void; + patchData(data: Partial): void; clearData(): void; // Simulation handlers simulate(): void; activateSimulation(): void; - startSimulation(nodes: ISimulationNode[], edges: ISimulationEdge[]): void; - updateSimulation(nodes: ISimulationNode[], edges: ISimulationEdge[]): void; - stopSimulation(): void; // Node handlers startDragNode(): void; @@ -68,6 +95,7 @@ export interface ISimulatorEvents { onNodeDrag: (data: ISimulatorEventGraph) => void; onNodeDragEnd: (data: ISimulatorEventGraph) => void; onSimulationStart: () => void; + onSimulationStep: (data: ISimulatorEventGraph) => void; onSimulationProgress: (data: ISimulatorEventGraph & ISimulatorEventProgress) => void; onSimulationEnd: (data: ISimulatorEventGraph) => void; onSettingsUpdate: (data: ISimulatorEventSettings) => void; diff --git a/src/simulator/types/main-thread-simulator.ts b/src/simulator/types/main-thread-simulator.ts index de62998..1bbc36c 100644 --- a/src/simulator/types/main-thread-simulator.ts +++ b/src/simulator/types/main-thread-simulator.ts @@ -1,4 +1,11 @@ -import { ISimulationEdge, ISimulationNode, ISimulator, SimulatorEvents, SimulatorEventType } from '../shared'; +import { + ISimulationNode, + ISimulator, + SimulatorEvents, + SimulatorEventType, + ISimulationGraph, + ISimulationIds, +} from '../shared'; import { IPosition } from '../../common'; import { Emitter } from '../../utils/emitter.utils'; import { @@ -8,97 +15,90 @@ import { } from '../engine/d3-simulator-engine'; export class MainThreadSimulator extends Emitter implements ISimulator { - protected readonly simulator: D3SimulatorEngine; + protected readonly _simulator: D3SimulatorEngine; constructor() { super(); - this.simulator = new D3SimulatorEngine(); - this.simulator.on(D3SimulatorEngineEventType.SIMULATION_START, () => { + this._simulator = new D3SimulatorEngine(); + this._simulator.on(D3SimulatorEngineEventType.SIMULATION_START, () => { this.emit(SimulatorEventType.SIMULATION_START, undefined); }); - this.simulator.on(D3SimulatorEngineEventType.SIMULATION_PROGRESS, (data) => { + this._simulator.on(D3SimulatorEngineEventType.SIMULATION_PROGRESS, (data) => { this.emit(SimulatorEventType.SIMULATION_PROGRESS, data); }); - this.simulator.on(D3SimulatorEngineEventType.SIMULATION_END, (data) => { + this._simulator.on(D3SimulatorEngineEventType.SIMULATION_END, (data) => { this.emit(SimulatorEventType.SIMULATION_END, data); }); - this.simulator.on(D3SimulatorEngineEventType.NODE_DRAG, (data) => { - this.emit(SimulatorEventType.NODE_DRAG_END, data); - }); - this.simulator.on(D3SimulatorEngineEventType.TICK, (data) => { + this._simulator.on(D3SimulatorEngineEventType.NODE_DRAG, (data) => { this.emit(SimulatorEventType.NODE_DRAG, data); }); - this.simulator.on(D3SimulatorEngineEventType.END, (data) => { - this.emit(SimulatorEventType.NODE_DRAG_END, data); + this._simulator.on(D3SimulatorEngineEventType.SIMULATION_TICK, (data) => { + this.emit(SimulatorEventType.SIMULATION_STEP, data); }); - this.simulator.on(D3SimulatorEngineEventType.SETTINGS_UPDATE, (data) => { + this._simulator.on(D3SimulatorEngineEventType.SETTINGS_UPDATE, (data) => { this.emit(SimulatorEventType.SETTINGS_UPDATE, data); }); } - setData(nodes: ISimulationNode[], edges: ISimulationEdge[]) { - this.simulator.setData({ nodes, edges }); + setupData(data: ISimulationGraph) { + this._simulator.setupData(data); } - addData(nodes: ISimulationNode[], edges: ISimulationEdge[]) { - this.simulator.addData({ nodes, edges }); + mergeData(data: ISimulationGraph) { + this._simulator.mergeData(data); } - updateData(nodes: ISimulationNode[], edges: ISimulationEdge[]) { - this.simulator.updateData({ nodes, edges }); - } - - clearData() { - this.simulator.clearData(); + updateData(data: ISimulationGraph) { + this._simulator.updateData(data); } - simulate() { - this.simulator.simulate(); + deleteData(data: ISimulationIds) { + this._simulator.deleteData(data); } - activateSimulation() { - this.simulator.activateSimulation(); + patchData(data: Partial): void { + this._simulator.patchData(data); } - startSimulation(nodes: ISimulationNode[], edges: ISimulationEdge[]) { - this.simulator.startSimulation({ nodes, edges }); + clearData() { + this._simulator.clearData(); } - updateSimulation(nodes: ISimulationNode[], edges: ISimulationEdge[]) { - this.simulator.updateSimulation({ nodes, edges }); + simulate() { + console.log('not implemented'); + // this.simulator.runSimulation(); } - stopSimulation() { - this.simulator.stopSimulation(); + activateSimulation() { + this._simulator.activateSimulation(); } startDragNode() { - this.simulator.startDragNode(); + this._simulator.startDragNode(); } dragNode(nodeId: number, position: IPosition) { - this.simulator.dragNode({ id: nodeId, ...position }); + this._simulator.dragNode({ id: nodeId, ...position }); } endDragNode(nodeId: number) { - this.simulator.endDragNode({ id: nodeId }); + this._simulator.endDragNode({ id: nodeId }); } fixNodes(nodes: ISimulationNode[]) { - this.simulator.fixNodes(nodes); + this._simulator.stickNodes(nodes); } releaseNodes(nodes?: ISimulationNode[] | undefined): void { - this.simulator.releaseNodes(nodes); + this._simulator.unstickNodes(nodes); } setSettings(settings: ID3SimulatorEngineSettingsUpdate) { - this.simulator.setSettings(settings); + this._simulator.setSettings(settings); } terminate() { - this.simulator.removeAllListeners(); + this._simulator.removeAllListeners(); this.removeAllListeners(); - // Do nothing } } diff --git a/src/simulator/types/web-worker-simulator/index.ts b/src/simulator/types/web-worker-simulator/index.ts index 97f396e..92dfcad 100644 --- a/src/simulator/types/web-worker-simulator/index.ts +++ b/src/simulator/types/web-worker-simulator/index.ts @@ -1 +1 @@ -export { WebWorkerSimulator } from './simulator'; +export { WebWorkerSimulator } from './web-worker-simulator'; diff --git a/src/simulator/types/web-worker-simulator/message/worker-input.ts b/src/simulator/types/web-worker-simulator/message/worker-input.ts index a57b8ed..5d28a74 100644 --- a/src/simulator/types/web-worker-simulator/message/worker-input.ts +++ b/src/simulator/types/web-worker-simulator/message/worker-input.ts @@ -8,18 +8,17 @@ import { IWorkerPayload } from './worker-payload'; // (not quite as there is no immediate response to a request) export enum WorkerInputType { - // Set node and edge data without simulating - SetData = 'Set Data', - AddData = 'Add Data', + SetupData = 'Set Data', + MergeData = 'Add Data', UpdateData = 'Update Data', + DeleteData = 'Delete Data', + PatchData = 'Patch Data', ClearData = 'Clear Data', // Simulation message types Simulate = 'Simulate', ActivateSimulation = 'Activate Simulation', - StartSimulation = 'Start Simulation', UpdateSimulation = 'Update Simulation', - StopSimulation = 'Stop Simulation', // Node dragging message types StartDragNode = 'Start Drag Node', @@ -32,16 +31,16 @@ export enum WorkerInputType { SetSettings = 'Set Settings', } -type IWorkerInputSetDataPayload = IWorkerPayload< - WorkerInputType.SetData, +type IWorkerInputSetupDataPayload = IWorkerPayload< + WorkerInputType.SetupData, { nodes: ISimulationNode[]; edges: ISimulationEdge[]; } >; -type IWorkerInputAddDataPayload = IWorkerPayload< - WorkerInputType.AddData, +type IWorkerInputMergeDataPayload = IWorkerPayload< + WorkerInputType.MergeData, { nodes: ISimulationNode[]; edges: ISimulationEdge[]; @@ -56,20 +55,28 @@ type IWorkerInputUpdateDataPayload = IWorkerPayload< } >; +type IWorkerInputDeleteDataPayload = IWorkerPayload< + WorkerInputType.DeleteData, + { + nodeIds: number[] | undefined; + edgeIds: number[] | undefined; + } +>; + +type IWorkerInputPatchDataPayload = IWorkerPayload< + WorkerInputType.PatchData, + { + nodes?: ISimulationNode[]; + edges?: ISimulationEdge[]; + } +>; + type IWorkerInputClearDataPayload = IWorkerPayload; type IWorkerInputSimulatePayload = IWorkerPayload; type IWorkerInputActivateSimulationPayload = IWorkerPayload; -type IWorkerInputStartSimulationPayload = IWorkerPayload< - WorkerInputType.StartSimulation, - { - nodes: ISimulationNode[]; - edges: ISimulationEdge[]; - } ->; - type IWorkerInputUpdateSimulationPayload = IWorkerPayload< WorkerInputType.UpdateSimulation, { @@ -78,8 +85,6 @@ type IWorkerInputUpdateSimulationPayload = IWorkerPayload< } >; -type IWorkerInputStopSimulationPayload = IWorkerPayload; - type IWorkerInputStartDragNodePayload = IWorkerPayload; type IWorkerInputDragNodePayload = IWorkerPayload; @@ -108,15 +113,15 @@ type IWorkerInputReleaseNodesPayload = IWorkerPayload< type IWorkerInputSetSettingsPayload = IWorkerPayload; export type IWorkerInputPayload = - | IWorkerInputSetDataPayload - | IWorkerInputAddDataPayload + | IWorkerInputSetupDataPayload + | IWorkerInputMergeDataPayload | IWorkerInputUpdateDataPayload + | IWorkerInputDeleteDataPayload + | IWorkerInputPatchDataPayload | IWorkerInputClearDataPayload | IWorkerInputSimulatePayload | IWorkerInputActivateSimulationPayload - | IWorkerInputStartSimulationPayload | IWorkerInputUpdateSimulationPayload - | IWorkerInputStopSimulationPayload | IWorkerInputStartDragNodePayload | IWorkerInputDragNodePayload | IWorkerInputFixNodesPayload diff --git a/src/simulator/types/web-worker-simulator/message/worker-output.ts b/src/simulator/types/web-worker-simulator/message/worker-output.ts index a8fdf95..d271bcf 100644 --- a/src/simulator/types/web-worker-simulator/message/worker-output.ts +++ b/src/simulator/types/web-worker-simulator/message/worker-output.ts @@ -4,8 +4,10 @@ import { ID3SimulatorEngineSettings } from '../../../engine/d3-simulator-engine' export enum WorkerOutputType { SIMULATION_START = 'simulation-start', + SIMULATION_STEP = 'simulation-step', SIMULATION_PROGRESS = 'simulation-progress', SIMULATION_END = 'simulation-end', + SIMULATION_TICK = 'simulation-tick', NODE_DRAG = 'node-drag', NODE_DRAG_END = 'node-drag-end', SETTINGS_UPDATE = 'settings-update', @@ -13,6 +15,14 @@ export enum WorkerOutputType { type IWorkerOutputSimulationStartPayload = IWorkerPayload; +type IWorkerOutputSimulationStepPayload = IWorkerPayload< + WorkerOutputType.SIMULATION_STEP, + { + nodes: ISimulationNode[]; + edges: ISimulationEdge[]; + } +>; + type IWorkerOutputSimulationProgressPayload = IWorkerPayload< WorkerOutputType.SIMULATION_PROGRESS, { @@ -55,6 +65,7 @@ type IWorkerOutputSettingsUpdatePayload = IWorkerPayload< export type IWorkerOutputPayload = | IWorkerOutputSimulationStartPayload + | IWorkerOutputSimulationStepPayload | IWorkerOutputSimulationProgressPayload | IWorkerOutputSimulationEndPayload | IWorkerOutputNodeDragPayload diff --git a/src/simulator/types/web-worker-simulator/process.worker.ts b/src/simulator/types/web-worker-simulator/simulator.worker.ts similarity index 68% rename from src/simulator/types/web-worker-simulator/process.worker.ts rename to src/simulator/types/web-worker-simulator/simulator.worker.ts index 6e93b4d..d0d76a2 100644 --- a/src/simulator/types/web-worker-simulator/process.worker.ts +++ b/src/simulator/types/web-worker-simulator/simulator.worker.ts @@ -10,14 +10,6 @@ const emitToMain = (message: IWorkerOutputPayload) => { postMessage(message); }; -simulator.on(D3SimulatorEngineEventType.TICK, (data) => { - emitToMain({ type: WorkerOutputType.NODE_DRAG, data }); -}); - -simulator.on(D3SimulatorEngineEventType.END, (data) => { - emitToMain({ type: WorkerOutputType.NODE_DRAG_END, data }); -}); - simulator.on(D3SimulatorEngineEventType.SIMULATION_START, () => { emitToMain({ type: WorkerOutputType.SIMULATION_START }); }); @@ -31,11 +23,13 @@ simulator.on(D3SimulatorEngineEventType.SIMULATION_END, (data) => { }); simulator.on(D3SimulatorEngineEventType.NODE_DRAG, (data) => { - // Notify the client that the node position changed. - // This is otherwise handled by the simulation tick if physics is enabled. emitToMain({ type: WorkerOutputType.NODE_DRAG, data }); }); +simulator.on(D3SimulatorEngineEventType.SIMULATION_TICK, (data) => { + emitToMain({ type: WorkerOutputType.SIMULATION_STEP, data }); +}); + simulator.on(D3SimulatorEngineEventType.SETTINGS_UPDATE, (data) => { emitToMain({ type: WorkerOutputType.SETTINGS_UPDATE, data }); }); @@ -47,13 +41,13 @@ addEventListener('message', ({ data }: MessageEvent) => { break; } - case WorkerInputType.SetData: { - simulator.setData(data.data); + case WorkerInputType.SetupData: { + simulator.setupData(data.data); break; } - case WorkerInputType.AddData: { - simulator.addData(data.data); + case WorkerInputType.MergeData: { + simulator.mergeData(data.data); break; } @@ -62,28 +56,18 @@ addEventListener('message', ({ data }: MessageEvent) => { break; } - case WorkerInputType.ClearData: { - simulator.clearData(); + case WorkerInputType.DeleteData: { + simulator.deleteData(data.data); break; } - case WorkerInputType.Simulate: { - simulator.simulate(); + case WorkerInputType.PatchData: { + simulator.patchData(data.data); break; } - case WorkerInputType.StartSimulation: { - simulator.startSimulation(data.data); - break; - } - - case WorkerInputType.UpdateSimulation: { - simulator.updateSimulation(data.data); - break; - } - - case WorkerInputType.StopSimulation: { - simulator.stopSimulation(); + case WorkerInputType.ClearData: { + simulator.clearData(); break; } @@ -98,12 +82,12 @@ addEventListener('message', ({ data }: MessageEvent) => { } case WorkerInputType.FixNodes: { - simulator.fixNodes(data.data.nodes); + simulator.stickNodes(data.data.nodes); break; } case WorkerInputType.ReleaseNodes: { - simulator.releaseNodes(data.data.nodes); + simulator.unstickNodes(data.data.nodes); break; } diff --git a/src/simulator/types/web-worker-simulator/simulator.ts b/src/simulator/types/web-worker-simulator/web-worker-simulator.ts similarity index 63% rename from src/simulator/types/web-worker-simulator/simulator.ts rename to src/simulator/types/web-worker-simulator/web-worker-simulator.ts index 01acb46..02f35ea 100644 --- a/src/simulator/types/web-worker-simulator/simulator.ts +++ b/src/simulator/types/web-worker-simulator/web-worker-simulator.ts @@ -1,25 +1,33 @@ import { IPosition } from '../../../common'; -import { ISimulator, ISimulationNode, ISimulationEdge, SimulatorEventType, SimulatorEvents } from '../../shared'; +import { + ISimulator, + ISimulationNode, + ISimulationEdge, + SimulatorEventType, + SimulatorEvents, + ISimulationGraph, + ISimulationIds, +} from '../../shared'; import { ID3SimulatorEngineSettingsUpdate } from '../../engine/d3-simulator-engine'; import { IWorkerInputPayload, WorkerInputType } from './message/worker-input'; import { IWorkerOutputPayload, WorkerOutputType } from './message/worker-output'; import { Emitter } from '../../../utils/emitter.utils'; export class WebWorkerSimulator extends Emitter implements ISimulator { - protected readonly worker: Worker; + protected readonly _worker: Worker; constructor() { super(); - this.worker = new Worker( + this._worker = new Worker( new URL( - /* webpackChunkName: 'process.worker' */ - './process.worker', + /* webpackChunkName: 'simulator.worker' */ + './simulator.worker', import.meta.url, ), { type: 'module' }, ); - this.worker.onmessage = ({ data }: MessageEvent) => { + this._worker.onmessage = ({ data }: MessageEvent) => { switch (data.type) { case WorkerOutputType.SIMULATION_START: { this.emit(SimulatorEventType.SIMULATION_START, undefined); @@ -33,6 +41,10 @@ export class WebWorkerSimulator extends Emitter implements ISim this.emit(SimulatorEventType.SIMULATION_END, data.data); break; } + case WorkerOutputType.SIMULATION_STEP: { + this.emit(SimulatorEventType.SIMULATION_STEP, data.data); + break; + } case WorkerOutputType.NODE_DRAG: { this.emit(SimulatorEventType.NODE_DRAG, data.data); break; @@ -49,16 +61,35 @@ export class WebWorkerSimulator extends Emitter implements ISim }; } - setData(nodes: ISimulationNode[], edges: ISimulationEdge[]) { - this.emitToWorker({ type: WorkerInputType.SetData, data: { nodes, edges } }); + /** + * Creates a new graph with the specified data. Any existing data gets discarded. + * This action creates a new simulation object but keeps the existing simulation settings. + * + * @param {ISimulationGraph} data New graph (nodes and edges). + */ + setupData(data: ISimulationGraph) { + this.emitToWorker({ type: WorkerInputType.SetupData, data }); + } + + /** + * Inserts or updates data to an existing graph. (Also known as upsert) + * + * @param {ISimulationGraph} data Added graph data (nodes and edges). + */ + mergeData(data: ISimulationGraph) { + this.emitToWorker({ type: WorkerInputType.MergeData, data }); + } + + updateData(data: ISimulationGraph) { + this.emitToWorker({ type: WorkerInputType.UpdateData, data }); } - addData(nodes: ISimulationNode[], edges: ISimulationEdge[]) { - this.emitToWorker({ type: WorkerInputType.AddData, data: { nodes, edges } }); + deleteData(data: ISimulationIds) { + this.emitToWorker({ type: WorkerInputType.DeleteData, data }); } - updateData(nodes: ISimulationNode[], edges: ISimulationEdge[]) { - this.emitToWorker({ type: WorkerInputType.UpdateData, data: { nodes, edges } }); + patchData(data: Partial): void { + this.emitToWorker({ type: WorkerInputType.PatchData, data }); } clearData() { @@ -73,18 +104,10 @@ export class WebWorkerSimulator extends Emitter implements ISim this.emitToWorker({ type: WorkerInputType.ActivateSimulation }); } - startSimulation(nodes: ISimulationNode[], edges: ISimulationEdge[]) { - this.emitToWorker({ type: WorkerInputType.StartSimulation, data: { nodes, edges } }); - } - updateSimulation(nodes: ISimulationNode[], edges: ISimulationEdge[]) { this.emitToWorker({ type: WorkerInputType.UpdateSimulation, data: { nodes, edges } }); } - stopSimulation() { - this.emitToWorker({ type: WorkerInputType.StopSimulation }); - } - startDragNode() { this.emitToWorker({ type: WorkerInputType.StartDragNode }); } @@ -110,11 +133,11 @@ export class WebWorkerSimulator extends Emitter implements ISim } terminate() { - this.worker.terminate(); + this._worker.terminate(); this.removeAllListeners(); } protected emitToWorker(message: IWorkerInputPayload) { - this.worker.postMessage(message); + this._worker.postMessage(message); } } diff --git a/src/utils/array.utils.ts b/src/utils/array.utils.ts index 376012a..a9db93b 100644 --- a/src/utils/array.utils.ts +++ b/src/utils/array.utils.ts @@ -15,3 +15,8 @@ export const copyArray = (array: Array): Array => { } return newArray; }; + +export const dedupArrays = (...arrays: T[][]): T[] => { + const combinedArray = arrays.reduce((acc, curr) => acc.concat(curr), []); + return Array.from(new Set(combinedArray)); +}; diff --git a/src/utils/object.utils.ts b/src/utils/object.utils.ts index 08a6426..d6dfcf9 100644 --- a/src/utils/object.utils.ts +++ b/src/utils/object.utils.ts @@ -120,3 +120,11 @@ const copyPlainObject = (obj: Record): Record => { }); return newObject; }; + +export const patchProperties = (target: T, source: T): void => { + const keys = Object.keys(source as Object) as (keyof T)[]; + + for (let i = 0; i < keys.length; i++) { + target[keys[i]] = source[keys[i]]; + } +}; diff --git a/src/utils/observer.utils.ts b/src/utils/observer.utils.ts new file mode 100644 index 0000000..4b9ce60 --- /dev/null +++ b/src/utils/observer.utils.ts @@ -0,0 +1,50 @@ +import { INodeCoordinates, INodePosition } from '../models/node'; +import { ISetStateDataPayload } from '../models/state'; + +export type GraphObject = 'node' | 'edge'; + +export type IObserverDataPayload = INodePosition | INodeCoordinates | ISetStateDataPayload; + +// Using callbacks here to ensure that the Observer update is abstracted from the user +export type IObserver = (data?: IObserverDataPayload) => void; + +export interface ISubject { + listeners: IObserver[]; + + addListener(observer: IObserver): void; + + getListeners(): IObserver[]; + + removeListener(observer: IObserver): void; + + notifyListeners(data?: IObserverDataPayload): void; +} + +export class Subject implements ISubject { + listeners: IObserver[]; + + constructor() { + this.listeners = []; + } + + addListener(observer: IObserver): void { + this.listeners.push(observer); + } + + getListeners(): IObserver[] { + return [...this.listeners]; + } + + removeListener(observer: IObserver): void { + const index = this.listeners.indexOf(observer); + if (index !== -1) { + this.listeners.splice(index, 1); + } + } + + notifyListeners(data?: IObserverDataPayload): void { + for (let i = 0; i < this.listeners.length; i++) { + this.listeners[i](data); + } + } +} diff --git a/src/views/orb-map-view.ts b/src/views/orb-map-view.ts index 01211ab..fc5f811 100644 --- a/src/views/orb-map-view.ts +++ b/src/views/orb-map-view.ts @@ -11,6 +11,7 @@ import { IRenderer, RendererType, RenderEventType, IRendererSettingsInit, IRende import { RendererFactory } from '../renderer/factory'; import { getDefaultGraphStyle } from '../models/style'; import { isBoolean } from '../utils/type.utils'; +import { IObserver } from '../utils/observer.utils'; export interface ILeafletMapTile { instance: L.TileLayer; @@ -85,6 +86,7 @@ export class OrbMapView implements IOr this.render(); } }, + listeners: [this._update], }); this._graph.setDefaultStyle(getDefaultGraphStyle()); this._events = new OrbEmitter(); @@ -201,6 +203,11 @@ export class OrbMapView implements IOr onRendered?.(); } + zoomIn(onRendered?: () => void) { + this._leaflet.zoomIn(); + onRendered?.(); + } + recenter(onRendered?: () => void) { const view = this._graph.getBoundingBox(); const topRightCoordinate = this._leaflet.layerPointToLatLng([view.x, view.y]); @@ -209,6 +216,11 @@ export class OrbMapView implements IOr onRendered?.(); } + zoomOut(onRendered?: () => void) { + this._leaflet.zoomOut(); + onRendered?.(); + } + destroy() { this._renderer.destroy(); this._leaflet.off(); @@ -216,6 +228,10 @@ export class OrbMapView implements IOr this._leaflet.getContainer().outerHTML = ''; } + private _update: IObserver = (): void => { + this.render(); + }; + private _initMap() { const map = document.createElement('div'); map.style.position = 'absolute'; @@ -231,6 +247,7 @@ export class OrbMapView implements IOr private _initLeaflet() { const leaflet = L.map(this._map, { doubleClickZoom: false, + zoomControl: false, }).setView([0, 0], this._settings.map.zoomLevel); leaflet.on('zoomstart', () => { @@ -426,8 +443,7 @@ export class OrbMapView implements IOr } const layerPoint = this._leaflet.latLngToLayerPoint([coordinates.lat, coordinates.lng]); - nodes[i].position.x = layerPoint.x; - nodes[i].position.y = layerPoint.y; + nodes[i].setPosition(layerPoint, { isNotifySkipped: true }); } } diff --git a/src/views/orb-view.ts b/src/views/orb-view.ts index d4832b6..427cc29 100644 --- a/src/views/orb-view.ts +++ b/src/views/orb-view.ts @@ -8,9 +8,9 @@ import { D3ZoomEvent, zoom, ZoomBehavior } from 'd3-zoom'; import { select } from 'd3-selection'; import { IPosition, isEqualPosition } from '../common'; import { ISimulator, SimulatorFactory } from '../simulator'; -import { Graph, IGraph } from '../models/graph'; +import { Graph, IGraph, INodeFilter, IEdgeFilter } from '../models/graph'; import { INode, INodeBase, isNode } from '../models/node'; -import { IEdgeBase, isEdge } from '../models/edge'; +import { IEdge, IEdgeBase, isEdge } from '../models/edge'; import { IOrbView } from './shared'; import { DefaultEventStrategy, IEventStrategy, IEventStrategySettings } from '../models/strategy'; import { ID3SimulatorEngineSettings } from '../simulator/engine/d3-simulator-engine'; @@ -21,6 +21,7 @@ import { RendererFactory } from '../renderer/factory'; import { SimulatorEventType } from '../simulator/shared'; import { getDefaultGraphStyle } from '../models/style'; import { isBoolean } from '../utils/type.utils'; +import { IObserver, IObserverDataPayload } from '../utils/observer.utils'; export interface IGraphInteractionSettings { isDragEnabled: boolean; @@ -36,7 +37,6 @@ export interface IOrbViewSettings { zoomFitTransitionMs: number; isOutOfBoundsDragEnabled: boolean; areCoordinatesRounded: boolean; - isSimulationAnimated: boolean; } export type IOrbViewSettingsInit = Omit< @@ -54,7 +54,7 @@ export class OrbView implements IOrbVi private readonly _renderer: IRenderer; private readonly _simulator: ISimulator; - private _isSimulating = false; + // private _isSimulating = false; private _onSimulationEnd: (() => void) | undefined; private _simulationStartedAt = Date.now(); private _d3Zoom: ZoomBehavior; @@ -62,23 +62,11 @@ export class OrbView implements IOrbVi constructor(container: HTMLElement, settings?: Partial>) { this._container = container; - this._graph = new Graph(undefined, { - onLoadedImages: () => { - // Not to call render() before user's .render() - if (this._renderer.isInitiallyRendered) { - this.render(); - } - }, - }); - this._graph.setDefaultStyle(getDefaultGraphStyle()); - this._events = new OrbEmitter(); - this._settings = { getPosition: settings?.getPosition, zoomFitTransitionMs: 200, isOutOfBoundsDragEnabled: false, areCoordinatesRounded: true, - isSimulationAnimated: true, ...settings, simulation: { isPhysicsEnabled: false, @@ -99,6 +87,18 @@ export class OrbView implements IOrbVi }, }; + this._graph = new Graph(undefined, { + onLoadedImages: () => { + // Not to call render() before user's .render() + if (this._renderer.isInitiallyRendered) { + this.render(); + } + }, + listeners: [this._update], + }); + this._graph.setDefaultStyle(getDefaultGraphStyle()); + this._events = new OrbEmitter(); + this._strategy = new DefaultEventStrategy({ isDefaultSelectEnabled: this._settings.strategy.isDefaultSelectEnabled ?? false, isDefaultHoverEnabled: this._settings.strategy.isDefaultHoverEnabled ?? false, @@ -150,34 +150,68 @@ export class OrbView implements IOrbVi this._simulator = SimulatorFactory.getSimulator(); this._simulator.on(SimulatorEventType.SIMULATION_START, () => { - this._isSimulating = true; + // this._isSimulating = true; this._simulationStartedAt = Date.now(); this._events.emit(OrbEventType.SIMULATION_START, undefined); }); this._simulator.on(SimulatorEventType.SIMULATION_PROGRESS, (data) => { this._graph.setNodePositions(data.nodes); this._events.emit(OrbEventType.SIMULATION_STEP, { progress: data.progress }); - if (this._settings.isSimulationAnimated) { - this._renderer.render(this._graph); - } + this.render(); }); this._simulator.on(SimulatorEventType.SIMULATION_END, (data) => { this._graph.setNodePositions(data.nodes); - this._renderer.render(this._graph); - this._isSimulating = false; + this.render(); + // this._isSimulating = false; this._onSimulationEnd?.(); this._onSimulationEnd = undefined; this._events.emit(OrbEventType.SIMULATION_END, { durationMs: Date.now() - this._simulationStartedAt }); }); + this._simulator.on(SimulatorEventType.SIMULATION_STEP, (data) => { + this._graph.setNodePositions(data.nodes); + this.render(); + }); this._simulator.on(SimulatorEventType.NODE_DRAG, (data) => { this._graph.setNodePositions(data.nodes); - this._renderer.render(this._graph); + this.render(); }); this._simulator.on(SimulatorEventType.SETTINGS_UPDATE, (data) => { this._settings.simulation = data.settings; }); this._simulator.setSettings(this._settings.simulation); + + // TODO(dlozic): Optimize crud operations here. + this._graph.setSettings({ + onSetupData: () => { + // if (this._isSimulating) { + // console.warn('Already running a simulation. Discarding the setup data call.'); + // return; + // } + // this._isSimulating = true; + this._assignPositions(this._graph.getNodes()); + const nodePositions = this._graph.getNodePositions(); + const edgePositions = this._graph.getEdgePositions(); + // this._onSimulationEnd = onRendered; + this._simulator.setupData({ nodes: nodePositions, edges: edgePositions }); + }, + onMergeData: (data) => { + const nodeIds = new Set(data.nodes?.map((node) => node.id)); + const nodeFilter: INodeFilter = (node: INode) => nodeIds.has(node.getId()); + const edgeIds = new Set(data.edges?.map((edge) => edge.id)); + const edgeFilter: IEdgeFilter = (edge: IEdge) => edgeIds.has(edge.getId()); + + this._assignPositions(this._graph.getNodes(nodeFilter)); + + const nodePositions = this._graph.getNodePositions(nodeFilter); + const edgePositions = this._graph.getEdgePositions(edgeFilter); + + this._simulator.mergeData({ nodes: nodePositions, edges: edgePositions }); + }, + onRemoveData: (data) => { + this._simulator.deleteData(data); + }, + }); } get data(): IGraph { @@ -238,26 +272,20 @@ export class OrbView implements IOrbVi } } - render(onRendered?: () => void) { - if (this._isSimulating) { - this._renderer.render(this._graph); - onRendered?.(); - return; - } - + private _assignPositions = (nodes: INode[]) => { if (this._settings.getPosition) { - const nodes = this._graph.getNodes(); for (let i = 0; i < nodes.length; i++) { const position = this._settings.getPosition(nodes[i]); if (position) { - nodes[i].position = { id: nodes[i].id, ...position }; + nodes[i].setPosition({ id: nodes[i].getId(), ...position }, { isNotifySkipped: true }); } } } + }; - this._isSimulating = true; - this._onSimulationEnd = onRendered; - this._startSimulation(); + render(onRendered?: () => void) { + this._renderer.render(this._graph); + onRendered?.(); } recenter(onRendered?: () => void) { @@ -269,8 +297,7 @@ export class OrbView implements IOrbVi .ease(easeLinear) .call(this._d3Zoom.transform, fitZoomTransform) .call(() => { - this._renderer.render(this._graph); - onRendered?.(); + this.render(onRendered); }); } @@ -319,7 +346,7 @@ export class OrbView implements IOrbVi this._dragStartPosition = undefined; } - this._simulator.dragNode(event.subject.id, simulationPoint); + this._simulator.dragNode(event.subject.getId(), simulationPoint); this._events.emit(OrbEventType.NODE_DRAG, { node: event.subject, event: event.sourceEvent, @@ -338,7 +365,7 @@ export class OrbView implements IOrbVi const simulationPoint = this._renderer.getSimulationPosition(mousePoint); if (!isEqualPosition(this._dragStartPosition, mousePoint)) { - this._simulator.endDragNode(event.subject.id); + this._simulator.endDragNode(event.subject.getId()); } this._events.emit(OrbEventType.NODE_DRAG_END, { @@ -356,7 +383,7 @@ export class OrbView implements IOrbVi } this._renderer.transform = event.transform; setTimeout(() => { - this._renderer.render(this._graph); + this.render(); this._events.emit(OrbEventType.TRANSFORM, { transform: event.transform }); }, 1); }; @@ -419,7 +446,7 @@ export class OrbView implements IOrbVi }); if (response.isStateChanged) { - this._renderer.render(this._graph); + this.render(); } }; @@ -457,7 +484,7 @@ export class OrbView implements IOrbVi }); if (response.isStateChanged || response.changedSubject) { - this._renderer.render(this._graph); + this.render(); } }; @@ -495,7 +522,7 @@ export class OrbView implements IOrbVi }); if (response.isStateChanged || response.changedSubject) { - this._renderer.render(this._graph); + this.render(); } }; @@ -533,17 +560,29 @@ export class OrbView implements IOrbVi }); if (response.isStateChanged || response.changedSubject) { - this._renderer.render(this._graph); + this.render(); } }; - private _startSimulation() { - const nodePositions = this._graph.getNodePositions(); - const edgePositions = this._graph.getEdgePositions(); - - this._simulator.updateData(nodePositions, edgePositions); - this._simulator.simulate(); - } + private _update: IObserver = (data?: IObserverDataPayload): void => { + if (data && 'x' in data && 'y' in data && 'id' in data) { + this._simulator.patchData({ + nodes: [ + { + x: data.x, + y: data.y, + sx: data.x, + sy: data.y, + fx: data.x, + fy: data.y, + id: data.id, + }, + ], + edges: [], + }); + } + this.render(); + }; // TODO: Do we keep these fixNodes() { diff --git a/test/models/graph.spec.ts b/test/models/graph.spec.ts index a8f9698..da440f5 100644 --- a/test/models/graph.spec.ts +++ b/test/models/graph.spec.ts @@ -46,9 +46,9 @@ const expectEqualNode = ( } const actualNode: IExpectedNode = { - id: node.id, - data: node.data, - style: node.style, + id: node.getId(), + data: node.getData(), + style: node.getStyle(), inEdges: node .getInEdges() .map((edge) => edge.id) @@ -57,8 +57,8 @@ const expectEqualNode = ( .getOutEdges() .map((edge) => edge.id) .sort(), - state: node.state, - position: node.position, + state: node.getState(), + position: node.getPosition(), }; expect(actualNode).toEqual(expectedNode); }; @@ -77,13 +77,13 @@ const expectEqualEdge = ( id: edge.id, start: edge.start, end: edge.end, - startNodeId: edge.startNode?.id, - endNodeId: edge.endNode?.id, - data: edge.data, - style: edge.style, + startNodeId: edge.startNode?.getId(), + endNodeId: edge.endNode?.getId(), + data: edge.getData(), + style: edge.getStyle(), type: edge.type, offset: edge.offset, - state: edge.state, + state: edge.getState(), }; expect(actualEdge).toEqual(expectedEdge); }; @@ -271,6 +271,113 @@ describe('Graph', () => { }, ]; + const updatedNodes: ITestNode[] = [ + { id: 0, name: 'Mia' }, + { id: 1, name: 'Lana' }, + { id: 2, name: 'Charlie' }, + ]; + + const updatedEdges: ITestEdge[] = [ + { id: 0, start: 1, end: 2, count: 1 }, + { id: 1, start: 2, end: 0, count: 0 }, + { id: 2, start: 0, end: 1, count: 7 }, + { id: 3, start: 1, end: 0, count: 7 }, + { id: 4, start: 2, end: 2, count: 5 }, + ]; + + const updatedExpectedNodes: IExpectedNode[] = [ + { + id: 0, + data: updatedNodes[0], + style: {}, + inEdges: [1, 3], + outEdges: [2], + state: GraphObjectState.NONE, + position: { id: 0 }, + }, + { + id: 1, + data: updatedNodes[1], + style: {}, + inEdges: [2], + outEdges: [0, 3], + state: GraphObjectState.NONE, + position: { id: 1 }, + }, + { + id: 2, + data: updatedNodes[2], + style: {}, + inEdges: [0, 4], + outEdges: [1, 4], + state: GraphObjectState.NONE, + position: { id: 2 }, + }, + ]; + + const updatedExpectedEdges: IExpectedEdge[] = [ + { + id: 0, + start: 1, + end: 2, + startNodeId: 1, + endNodeId: 2, + data: updatedEdges[0], + type: EdgeType.STRAIGHT, + offset: 0, + style: {}, + state: GraphObjectState.NONE, + }, + { + id: 1, + start: 2, + end: 0, + startNodeId: 2, + endNodeId: 0, + data: updatedEdges[1], + type: EdgeType.STRAIGHT, + offset: 0, + style: {}, + state: GraphObjectState.NONE, + }, + { + id: 2, + start: 0, + end: 1, + startNodeId: 0, + endNodeId: 1, + data: updatedEdges[2], + type: EdgeType.CURVED, + offset: 1, + style: {}, + state: GraphObjectState.NONE, + }, + { + id: 3, + start: 1, + end: 0, + startNodeId: 1, + endNodeId: 0, + data: updatedEdges[3], + type: EdgeType.CURVED, + offset: 1, + style: {}, + state: GraphObjectState.NONE, + }, + { + id: 4, + start: 2, + end: 2, + startNodeId: 2, + endNodeId: 2, + data: updatedEdges[4], + type: EdgeType.LOOPBACK, + offset: 1, + style: {}, + state: GraphObjectState.NONE, + }, + ]; + test('should merge new nodes', () => { const graph = new Graph({ nodes, edges }); graph.merge({ nodes: newNodes }); @@ -348,8 +455,26 @@ describe('Graph', () => { }); }); - // TODO @toni: Add tests for updating `data` with the same id, and edge `start` and `end` change - // test('should update existing nodes and edges', () => {}); + test('should update existing nodes and edges', () => { + const graph = new Graph({ nodes, edges }); + graph.merge({ nodes: updatedNodes, edges: updatedEdges }); + + const currentNodes: ITestNode[] = [...updatedNodes]; + const currentExpectedNodes: IExpectedNode[] = [...updatedExpectedNodes]; + + const currentEdges: ITestEdge[] = [...updatedEdges]; + const currentExpectedEdges: IExpectedEdge[] = [...updatedExpectedEdges]; + + expect(graph.getNodeCount()).toEqual(currentNodes.length); + expect(graph.getEdgeCount()).toEqual(currentEdges.length); + + currentNodes.forEach((node, i) => { + expectEqualNode(graph, node, currentExpectedNodes[i]); + }); + currentEdges.forEach((edge, i) => { + expectEqualEdge(graph, edge, currentExpectedEdges[i]); + }); + }); }); describe('remove', () => { @@ -443,7 +568,7 @@ describe('Graph', () => { const style: IGraphStyle = { getNodeStyle(node: INode): INodeStyle | undefined { // Simulate a special case (will be DEFAULT) - if (node.id === 0) { + if (node.getId() === 0) { return undefined; } return nodeStyle; @@ -457,6 +582,19 @@ describe('Graph', () => { }, }; + const styleByInOutEdges: IGraphStyle = { + getNodeStyle(node: INode): INodeStyle | undefined { + // Simulate a special case (will be DEFAULT) + if (node.getInEdges().length > 0 || node.getOutEdges().length > 0) { + return undefined; + } + return nodeStyle; + }, + getEdgeStyle(): IEdgeStyle | undefined { + return edgeStyle; + }, + }; + const newNodes: ITestNode[] = [ { id: 3, name: 'Mia' }, { id: 4, name: 'Lana' }, @@ -471,14 +609,14 @@ describe('Graph', () => { const graph = new Graph({ nodes, edges }); graph.setDefaultStyle(style); - expect(graph.getNodeById(0)?.style).toEqual({}); - expect(graph.getEdgeById(0)?.style).toEqual({}); + expect(graph.getNodeById(0)?.getStyle()).toEqual({}); + expect(graph.getEdgeById(0)?.getStyle()).toEqual({}); nodes.slice(1).forEach((node) => { - expect(graph.getNodeById(node.id)?.style).toEqual(nodeStyle); + expect(graph.getNodeById(node.id)?.getStyle()).toEqual(nodeStyle); }); edges.slice(1).forEach((edge) => { - expect(graph.getEdgeById(edge.id)?.style).toEqual(edgeStyle); + expect(graph.getEdgeById(edge.id)?.getStyle()).toEqual(edgeStyle); }); }); @@ -487,14 +625,14 @@ describe('Graph', () => { graph.setDefaultStyle(style); graph.setup({ nodes, edges }); - expect(graph.getNodeById(0)?.style).toEqual({}); - expect(graph.getEdgeById(0)?.style).toEqual({}); + expect(graph.getNodeById(0)?.getStyle()).toEqual({}); + expect(graph.getEdgeById(0)?.getStyle()).toEqual({}); nodes.slice(1).forEach((node) => { - expect(graph.getNodeById(node.id)?.style).toEqual(nodeStyle); + expect(graph.getNodeById(node.id)?.getStyle()).toEqual(nodeStyle); }); edges.slice(1).forEach((edge) => { - expect(graph.getEdgeById(edge.id)?.style).toEqual(edgeStyle); + expect(graph.getEdgeById(edge.id)?.getStyle()).toEqual(edgeStyle); }); }); @@ -506,14 +644,14 @@ describe('Graph', () => { const currentNodes: ITestNode[] = [...nodes, ...newNodes]; const currentEdges: ITestEdge[] = [...edges, ...newEdges]; - expect(graph.getNodeById(0)?.style).toEqual({}); - expect(graph.getEdgeById(0)?.style).toEqual({}); + expect(graph.getNodeById(0)?.getStyle()).toEqual({}); + expect(graph.getEdgeById(0)?.getStyle()).toEqual({}); currentNodes.slice(1).forEach((node) => { - expect(graph.getNodeById(node.id)?.style).toEqual(nodeStyle); + expect(graph.getNodeById(node.id)?.getStyle()).toEqual(nodeStyle); }); currentEdges.slice(1).forEach((edge) => { - expect(graph.getEdgeById(edge.id)?.style).toEqual(edgeStyle); + expect(graph.getEdgeById(edge.id)?.getStyle()).toEqual(edgeStyle); }); }); @@ -525,14 +663,14 @@ describe('Graph', () => { const currentNodes: ITestNode[] = [...nodes, ...newNodes]; const currentEdges: ITestEdge[] = [...edges, ...newEdges]; - expect(graph.getNodeById(0)?.style).toEqual({}); - expect(graph.getEdgeById(0)?.style).toEqual({}); + expect(graph.getNodeById(0)?.getStyle()).toEqual({}); + expect(graph.getEdgeById(0)?.getStyle()).toEqual({}); currentNodes.slice(1).forEach((node) => { - expect(graph.getNodeById(node.id)?.style).toEqual(nodeStyle); + expect(graph.getNodeById(node.id)?.getStyle()).toEqual(nodeStyle); }); currentEdges.slice(1).forEach((edge) => { - expect(graph.getEdgeById(edge.id)?.style).toEqual(edgeStyle); + expect(graph.getEdgeById(edge.id)?.getStyle()).toEqual(edgeStyle); }); }); @@ -546,14 +684,14 @@ describe('Graph', () => { const currentNodes: ITestNode[] = [...nodes, ...newNodes]; const currentEdges: ITestEdge[] = [...edges, ...newEdges]; - expect(graph.getNodeById(0)?.style).toEqual({ ...DEFAULT_NODE_STYLE, label: nodes[0].name }); - expect(graph.getEdgeById(0)?.style).toEqual(DEFAULT_EDGE_STYLE); + expect(graph.getNodeById(0)?.getStyle()).toEqual({ ...DEFAULT_NODE_STYLE, label: nodes[0].name }); + expect(graph.getEdgeById(0)?.getStyle()).toEqual(DEFAULT_EDGE_STYLE); currentNodes.slice(1).forEach((node) => { - expect(graph.getNodeById(node.id)?.style).toEqual(nodeStyle); + expect(graph.getNodeById(node.id)?.getStyle()).toEqual(nodeStyle); }); currentEdges.slice(1).forEach((edge) => { - expect(graph.getEdgeById(edge.id)?.style).toEqual(edgeStyle); + expect(graph.getEdgeById(edge.id)?.getStyle()).toEqual(edgeStyle); }); }); @@ -564,24 +702,42 @@ describe('Graph', () => { graph.setDefaultStyle(getDefaultGraphStyle()); graph.merge({ nodes: newNodes, edges: newEdges }); - expect(graph.getNodeById(0)?.style).toEqual({ ...DEFAULT_NODE_STYLE, label: nodes[0].name }); - expect(graph.getEdgeById(0)?.style).toEqual(DEFAULT_EDGE_STYLE); + expect(graph.getNodeById(0)?.getStyle()).toEqual({ ...DEFAULT_NODE_STYLE, label: nodes[0].name }); + expect(graph.getEdgeById(0)?.getStyle()).toEqual(DEFAULT_EDGE_STYLE); nodes.slice(1).forEach((node) => { - expect(graph.getNodeById(node.id)?.style).toEqual(nodeStyle); + expect(graph.getNodeById(node.id)?.getStyle()).toEqual(nodeStyle); }); newNodes.forEach((node) => { - expect(graph.getNodeById(node.id)?.style).toEqual({ ...DEFAULT_NODE_STYLE, label: node.name }); + expect(graph.getNodeById(node.id)?.getStyle()).toEqual({ ...DEFAULT_NODE_STYLE, label: node.name }); }); edges.slice(1).forEach((edge) => { - expect(graph.getEdgeById(edge.id)?.style).toEqual(edgeStyle); + expect(graph.getEdgeById(edge.id)?.getStyle()).toEqual(edgeStyle); }); newEdges.forEach((edge) => { - expect(graph.getEdgeById(edge.id)?.style).toEqual(DEFAULT_EDGE_STYLE); + expect(graph.getEdgeById(edge.id)?.getStyle()).toEqual(DEFAULT_EDGE_STYLE); }); }); - // TODO @toni: Add tests where style depends on in/outEdges and then hide an edge -> style should be updated + test('should apply style on edges removed', () => { + const graph = new Graph(); + graph.setDefaultStyle(styleByInOutEdges); + graph.setup({ nodes, edges }); + + graph.getNodes().forEach((node) => { + expect(node.getStyle()).toEqual({}); + }); + + graph.getEdges().forEach((edge) => { + expect(edge.getStyle()).toEqual(edgeStyle); + }); + + graph.remove({ edgeIds: graph.getEdges().map((edge) => edge.id) }); + + graph.getNodes().forEach((node) => { + expect(node.getStyle()).toEqual(nodeStyle); + }); + }); }); }); diff --git a/webpack.config.js b/webpack.config.js index 456fd06..c09811a 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -18,7 +18,7 @@ const commonConfiguration = { }, output: { chunkFilename(pathData) { - return pathData.chunk.name === 'process.worker' ? `${name}.worker.js` : `${name}.worker.vendor.js`; + return pathData.chunk.name === 'simulator.worker' ? `${name}.worker.js` : `${name}.worker.vendor.js`; }, filename: `${name}.js`, path: path.resolve(__dirname, 'dist/browser'), @@ -62,7 +62,7 @@ const productionConfiguration = { output: { ...commonConfiguration.output, chunkFilename(pathData) { - return pathData.chunk.name === 'process.worker' ? `${name}.worker.min.js` : `${name}.worker.vendor.min.js`; + return pathData.chunk.name === 'simulator.worker' ? `${name}.worker.min.js` : `${name}.worker.vendor.min.js`; }, filename: `${name}.min.js`, }, From 7cd077ba0cc6d145d0708d3b3a542deb0034c472 Mon Sep 17 00:00:00 2001 From: Oleksandr Ichenskyi <55350107+AlexIchenskiy@users.noreply.github.com> Date: Thu, 28 Mar 2024 07:15:35 +0100 Subject: [PATCH 13/22] New: Add zoom in and out functions (#100) --- src/views/orb-view.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/views/orb-view.ts b/src/views/orb-view.ts index 427cc29..3b5711a 100644 --- a/src/views/orb-view.ts +++ b/src/views/orb-view.ts @@ -564,6 +564,26 @@ export class OrbView implements IOrbVi } }; + zoomIn = (onRendered?: () => void) => { + select(this._renderer.canvas) + .transition() + .duration(this._settings.zoomFitTransitionMs) + .ease(easeLinear) + .call(this._d3Zoom.scaleBy, 1.2) + .call(() => { + this.render(onRendered); + }); + }; + + zoomOut = (onRendered?: () => void) => { + select(this._renderer.canvas) + .transition() + .duration(this._settings.zoomFitTransitionMs) + .ease(easeLinear) + .call(this._d3Zoom.scaleBy, 0.8) + .call(() => this.render(onRendered)); + }; + private _update: IObserver = (data?: IObserverDataPayload): void => { if (data && 'x' in data && 'y' in data && 'id' in data) { this._simulator.patchData({ From 88c300662879f0a4c60455afbf7b3a25fb2c6c6f Mon Sep 17 00:00:00 2001 From: AlexIchenskiy Date: Wed, 15 May 2024 14:48:39 +0200 Subject: [PATCH 14/22] Fix: Skip unnecessary listener notify on set style --- src/models/edge.ts | 32 ++++++++++++++++++++------------ src/models/graph.ts | 6 +++--- src/models/node.ts | 32 ++++++++++++++++++++------------ 3 files changed, 43 insertions(+), 27 deletions(-) diff --git a/src/models/edge.ts b/src/models/edge.ts index 4b36145..26eb5a5 100644 --- a/src/models/edge.ts +++ b/src/models/edge.ts @@ -30,6 +30,10 @@ export interface IEdgePosition { target: any; } +export interface IEdgeSetStyleOptions { + isNotifySkipped: boolean; +} + export enum EdgeLineStyleType { SOLID = 'solid', DASHED = 'dashed', @@ -115,10 +119,10 @@ export interface IEdge extends ISubjec setData(callback: (edge: IEdge) => E): void; patchData(data: Partial): void; patchData(callback: (edge: IEdge) => Partial): void; - setStyle(style: IEdgeStyle): void; - setStyle(callback: (edge: IEdge) => IEdgeStyle): void; - patchStyle(style: IEdgeStyle): void; - patchStyle(callback: (edge: IEdge) => IEdgeStyle): void; + setStyle(style: IEdgeStyle, options?: IEdgeSetStyleOptions): void; + setStyle(callback: (edge: IEdge) => IEdgeStyle, options?: IEdgeSetStyleOptions): void; + patchStyle(style: IEdgeStyle, options?: IEdgeSetStyleOptions): void; + patchStyle(callback: (edge: IEdge) => IEdgeStyle, options?: IEdgeSetStyleOptions): void; setState(state: number): void; setState(state: IGraphObjectStateParameters): void; setState(callback: (edge: IEdge) => number): void; @@ -374,20 +378,22 @@ abstract class Edge extends Subject im this.notifyListeners(); } - setStyle(style: IEdgeStyle): void; - setStyle(callback: (edge: IEdge) => IEdgeStyle): void; - setStyle(arg: IEdgeStyle | ((edge: IEdge) => IEdgeStyle)): void { + setStyle(style: IEdgeStyle, options?: IEdgeSetStyleOptions): void; + setStyle(callback: (edge: IEdge) => IEdgeStyle, options?: IEdgeSetStyleOptions): void; + setStyle(arg: IEdgeStyle | ((edge: IEdge) => IEdgeStyle), options?: IEdgeSetStyleOptions): void { if (isFunction(arg)) { this._style = (arg as (edge: IEdge) => IEdgeStyle)(this); } else { this._style = arg as IEdgeStyle; } - this.notifyListeners(); + if (!options?.isNotifySkipped) { + this.notifyListeners(); + } } - patchStyle(style: IEdgeStyle): void; - patchStyle(callback: (edge: IEdge) => IEdgeStyle): void; - patchStyle(arg: IEdgeStyle | ((edge: IEdge) => IEdgeStyle)) { + patchStyle(style: IEdgeStyle, options?: IEdgeSetStyleOptions): void; + patchStyle(callback: (edge: IEdge) => IEdgeStyle, options?: IEdgeSetStyleOptions): void; + patchStyle(arg: IEdgeStyle | ((edge: IEdge) => IEdgeStyle), options?: IEdgeSetStyleOptions) { let style: IEdgeStyle; if (isFunction(arg)) { @@ -398,7 +404,9 @@ abstract class Edge extends Subject im patchProperties(this._style, style); - this.notifyListeners(); + if (!options?.isNotifySkipped) { + this.notifyListeners(); + } } setState(state: number): void; diff --git a/src/models/graph.ts b/src/models/graph.ts index 071612f..f90555b 100644 --- a/src/models/graph.ts +++ b/src/models/graph.ts @@ -551,7 +551,7 @@ export class Graph extends Subject imp }, ); edge.setState(existingEdge.getState()); - edge.setStyle(existingEdge.getStyle()); + edge.setStyle(existingEdge.getStyle(), { isNotifySkipped: true }); newEdges.push(edge); } @@ -628,7 +628,7 @@ export class Graph extends Subject imp const style = this._defaultStyle.getNodeStyle(newNodes[i]); if (style) { - newNodes[i].setStyle(style); + newNodes[i].setStyle(style, { isNotifySkipped: true }); // TODO Add these checks to node property setup if (style.imageUrl) { styleImageUrls.add(style.imageUrl); @@ -649,7 +649,7 @@ export class Graph extends Subject imp const style = this._defaultStyle.getEdgeStyle(newEdges[i]); if (style) { - newEdges[i].setStyle(style); + newEdges[i].setStyle(style, { isNotifySkipped: true }); } } } diff --git a/src/models/node.ts b/src/models/node.ts index 78afeaa..ae31177 100644 --- a/src/models/node.ts +++ b/src/models/node.ts @@ -33,6 +33,10 @@ export interface INodeSetPositionOptions { isNotifySkipped: boolean; } +export interface INodeSetStyleOptions { + isNotifySkipped: boolean; +} + export enum NodeShapeType { CIRCLE = 'circle', DOT = 'dot', @@ -117,10 +121,10 @@ export interface INode extends ISubjec callback: (node: INode) => INodeCoordinates | INodePosition, options?: INodeSetPositionOptions, ): void; - setStyle(style: INodeStyle): void; - setStyle(callback: (node: INode) => INodeStyle): void; - patchStyle(style: INodeStyle): void; - patchStyle(callback: (node: INode) => INodeStyle): void; + setStyle(style: INodeStyle, options?: INodeSetPositionOptions): void; + setStyle(callback: (node: INode) => INodeStyle, options?: INodeSetPositionOptions): void; + patchStyle(style: INodeStyle, options?: INodeSetPositionOptions): void; + patchStyle(callback: (node: INode) => INodeStyle, options?: INodeSetPositionOptions): void; setState(state: number): void; setState(state: IGraphObjectStateParameters): void; setState(callback: (node: INode) => number): void; @@ -478,20 +482,22 @@ export class Node extends Subject impl } } - setStyle(style: INodeStyle): void; - setStyle(callback: (node: INode) => INodeStyle): void; - setStyle(arg: INodeStyle | ((node: INode) => INodeStyle)): void { + setStyle(style: INodeStyle, options?: INodeSetPositionOptions): void; + setStyle(callback: (node: INode) => INodeStyle, options?: INodeSetPositionOptions): void; + setStyle(arg: INodeStyle | ((node: INode) => INodeStyle), options?: INodeSetPositionOptions): void { if (isFunction(arg)) { this._style = (arg as (node: INode) => INodeStyle)(this); } else { this._style = arg as INodeStyle; } - this.notifyListeners(); + if (!options?.isNotifySkipped) { + this.notifyListeners(); + } } - patchStyle(style: INodeStyle): void; - patchStyle(callback: (node: INode) => INodeStyle): void; - patchStyle(arg: INodeStyle | ((node: INode) => INodeStyle)) { + patchStyle(style: INodeStyle, options?: INodeSetPositionOptions): void; + patchStyle(callback: (node: INode) => INodeStyle, options?: INodeSetPositionOptions): void; + patchStyle(arg: INodeStyle | ((node: INode) => INodeStyle), options?: INodeSetPositionOptions) { let style: INodeStyle; if (isFunction(arg)) { @@ -502,7 +508,9 @@ export class Node extends Subject impl patchProperties(this._style, style); - this.notifyListeners(); + if (!options?.isNotifySkipped) { + this.notifyListeners(); + } } setState(state: number): void; From f273ad8ee0681dd9d048c5c7c3c36f7b92225784 Mon Sep 17 00:00:00 2001 From: AlexIchenskiy Date: Wed, 3 Jul 2024 12:01:16 +0200 Subject: [PATCH 15/22] Fix: remove unnecessary rerender on state change --- src/models/edge.ts | 25 ++++++++++++++++--------- src/models/graph.ts | 2 +- src/models/node.ts | 29 +++++++++++++++++------------ src/models/strategy.ts | 16 ++++++++-------- 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/models/edge.ts b/src/models/edge.ts index 26eb5a5..d36c8af 100644 --- a/src/models/edge.ts +++ b/src/models/edge.ts @@ -34,6 +34,10 @@ export interface IEdgeSetStyleOptions { isNotifySkipped: boolean; } +export interface IEdgeSetStateOptions { + isNotifySkipped: boolean; +} + export enum EdgeLineStyleType { SOLID = 'solid', DASHED = 'dashed', @@ -123,10 +127,10 @@ export interface IEdge extends ISubjec setStyle(callback: (edge: IEdge) => IEdgeStyle, options?: IEdgeSetStyleOptions): void; patchStyle(style: IEdgeStyle, options?: IEdgeSetStyleOptions): void; patchStyle(callback: (edge: IEdge) => IEdgeStyle, options?: IEdgeSetStyleOptions): void; - setState(state: number): void; - setState(state: IGraphObjectStateParameters): void; - setState(callback: (edge: IEdge) => number): void; - setState(callback: (edge: IEdge) => IGraphObjectStateParameters): void; + setState(state: number, options?: IEdgeSetStateOptions): void; + setState(state: IGraphObjectStateParameters, options?: IEdgeSetStateOptions): void; + setState(callback: (edge: IEdge) => number, options?: IEdgeSetStateOptions): void; + setState(callback: (edge: IEdge) => IGraphObjectStateParameters, options?: IEdgeSetStateOptions): void; } export interface IEdgeSettings { @@ -409,16 +413,17 @@ abstract class Edge extends Subject im } } - setState(state: number): void; - setState(state: IGraphObjectStateParameters): void; - setState(callback: (edge: IEdge) => number): void; - setState(callback: (edge: IEdge) => IGraphObjectStateParameters): void; + setState(state: number, options?: IEdgeSetStateOptions): void; + setState(state: IGraphObjectStateParameters, options?: IEdgeSetStateOptions): void; + setState(callback: (edge: IEdge) => number, options?: IEdgeSetStateOptions): void; + setState(callback: (edge: IEdge) => IGraphObjectStateParameters, options?: IEdgeSetStateOptions): void; setState( arg: | number | IGraphObjectStateParameters | ((edge: IEdge) => number) | ((edge: IEdge) => IGraphObjectStateParameters), + options?: IEdgeSetStateOptions, ): void { let result: number | IGraphObjectStateParameters; @@ -446,7 +451,9 @@ abstract class Edge extends Subject im } } - this.notifyListeners(); + if (!options?.isNotifySkipped) { + this.notifyListeners(); + } } private _handleState(state: number, options?: Partial): number { diff --git a/src/models/graph.ts b/src/models/graph.ts index f90555b..8b7801e 100644 --- a/src/models/graph.ts +++ b/src/models/graph.ts @@ -550,7 +550,7 @@ export class Graph extends Subject imp listeners: [this._update], }, ); - edge.setState(existingEdge.getState()); + edge.setState(existingEdge.getState(), { isNotifySkipped: true }); edge.setStyle(existingEdge.getStyle(), { isNotifySkipped: true }); newEdges.push(edge); } diff --git a/src/models/node.ts b/src/models/node.ts index ae31177..af6b1f4 100644 --- a/src/models/node.ts +++ b/src/models/node.ts @@ -37,6 +37,10 @@ export interface INodeSetStyleOptions { isNotifySkipped: boolean; } +export interface INodeSetStateOptions { + isNotifySkipped: boolean; +} + export enum NodeShapeType { CIRCLE = 'circle', DOT = 'dot', @@ -125,10 +129,10 @@ export interface INode extends ISubjec setStyle(callback: (node: INode) => INodeStyle, options?: INodeSetPositionOptions): void; patchStyle(style: INodeStyle, options?: INodeSetPositionOptions): void; patchStyle(callback: (node: INode) => INodeStyle, options?: INodeSetPositionOptions): void; - setState(state: number): void; - setState(state: IGraphObjectStateParameters): void; - setState(callback: (node: INode) => number): void; - setState(callback: (node: INode) => IGraphObjectStateParameters): void; + setState(state: number, options?: INodeSetStateOptions): void; + setState(state: IGraphObjectStateParameters, options?: INodeSetStateOptions): void; + setState(callback: (node: INode) => number, options?: INodeSetStateOptions): void; + setState(callback: (node: INode) => IGraphObjectStateParameters, options?: INodeSetStateOptions): void; } // TODO: Dirty solution: Find another way to listen for global images, maybe through @@ -303,9 +307,7 @@ export class Node extends Subject impl } clearState(): void { - this.setState(GraphObjectState.NONE); - - this.notifyListeners(); + this.setState(GraphObjectState.NONE, { isNotifySkipped: true }); } getDistanceToBorder(): number { @@ -513,16 +515,17 @@ export class Node extends Subject impl } } - setState(state: number): void; - setState(state: IGraphObjectStateParameters): void; - setState(callback: (node: INode) => number): void; - setState(callback: (node: INode) => IGraphObjectStateParameters): void; + setState(state: number, options?: INodeSetStateOptions): void; + setState(state: IGraphObjectStateParameters, options?: INodeSetStateOptions): void; + setState(callback: (node: INode) => number, options?: INodeSetStateOptions): void; + setState(callback: (node: INode) => IGraphObjectStateParameters, options?: INodeSetStateOptions): void; setState( arg: | number | IGraphObjectStateParameters | ((node: INode) => number) | ((node: INode) => IGraphObjectStateParameters), + options?: INodeSetStateOptions, ): void { let result: number | IGraphObjectStateParameters; @@ -550,7 +553,9 @@ export class Node extends Subject impl } } - this.notifyListeners(); + if (!options?.isNotifySkipped) { + this.notifyListeners(); + } } protected _isPointInBoundingBox(point: IPosition): boolean { diff --git a/src/models/strategy.ts b/src/models/strategy.ts index d1fe4a6..9604963 100644 --- a/src/models/strategy.ts +++ b/src/models/strategy.ts @@ -229,24 +229,24 @@ const setNodeState = ( options?: ISetShapeStateOptions, ): void => { if (isStateChangeable(node, options)) { - node.setState(state); + node.setState(state, { isNotifySkipped: true }); } node.getInEdges().forEach((edge) => { if (edge && isStateChangeable(edge, options)) { - edge.setState(state); + edge.setState(state, { isNotifySkipped: true }); } if (edge.startNode && isStateChangeable(edge.startNode, options)) { - edge.startNode.setState(state); + edge.startNode.setState(state, { isNotifySkipped: true }); } }); node.getOutEdges().forEach((edge) => { if (edge && isStateChangeable(edge, options)) { - edge.setState(state); + edge.setState(state, { isNotifySkipped: true }); } if (edge.endNode && isStateChangeable(edge.endNode, options)) { - edge.endNode.setState(state); + edge.endNode.setState(state, { isNotifySkipped: true }); } }); }; @@ -257,15 +257,15 @@ const setEdgeState = ( options?: ISetShapeStateOptions, ): void => { if (isStateChangeable(edge, options)) { - edge.setState(state); + edge.setState(state, { isNotifySkipped: true }); } if (edge.startNode && isStateChangeable(edge.startNode, options)) { - edge.startNode.setState(state); + edge.startNode.setState(state, { isNotifySkipped: true }); } if (edge.endNode && isStateChangeable(edge.endNode, options)) { - edge.endNode.setState(state); + edge.endNode.setState(state, { isNotifySkipped: true }); } }; From e9133e5ad7651dbb81df699c8207462637bfe015 Mon Sep 17 00:00:00 2001 From: AlexIchenskiy Date: Fri, 12 Jul 2024 12:50:36 +0200 Subject: [PATCH 16/22] Chore: Update documentation --- docs/data.md | 195 ++++++++++++++++++++++++++++--------------- docs/styles.md | 187 +++++++++++++++++++++-------------------- docs/view-default.md | 6 +- docs/view-map.md | 34 +++++--- 4 files changed, 243 insertions(+), 179 deletions(-) diff --git a/docs/data.md b/docs/data.md index f694692..f07f26d 100644 --- a/docs/data.md +++ b/docs/data.md @@ -1,5 +1,4 @@ -Handling graph data in Orb -=== +# Handling graph data in Orb Graph data structure (nodes and edges) is the main part of Orb. Without the graph data structure, there wouldn't be anything to render. Read the following guide to get to know @@ -11,6 +10,31 @@ how to handle graph data in Orb. ## Setup nodes and edges +To set up `nodes` and `edges`, there are a few requirements that Orb expects: + +- Node data object should be a JSON plain object with a defined unique `id`. The value of `id` can + be `any`. All other properties are up to you (e.g. `text` and `myField` in the above example). +- Edge data object should be a JSON plain object with defined unique `id`, `start` (id of + the source node), `end` (id of the target node). The value of `id` can be `any`. All other + properties are up to you. (e.g. `connects` in the above example). + +You can have your own `node` and `edge` types that satisfy those requirements: + +```typescript +export interface MyNode { + id: number; + text: string; + myField: number; +} + +export interface MyEdge { + id: number; + start: number; + end: number; + connects: string; +} +``` + To initialize graph data structure use `orb.data.setup` function that receives `nodes` and `edges`. Here is a simple example of it: @@ -25,44 +49,58 @@ const nodes: MyNode[] = [ ]; const edges: MyEdge[] = [ - { id: 0, start: 0, end: 1, connects: 'A -> B' }, - { id: 1, start: 0, end: 0, connects: 'A -> A' }, + { id: 0, start: 0, end: 1, connects: "A -> B" }, + { id: 1, start: 0, end: 0, connects: "A -> A" }, ]; orb.data.setup({ nodes, edges }); ``` -To set up `nodes` and `edges`, there are a few requirements that Orb expects: - -* Node data object should be a JSON plain object with a defined unique `id`. The value of `id` can - be `any`. All other properties are up to you (e.g. `text` and `myField` in the above example). -* Edge data object should be a JSON plain object with defined unique `id`, `start` (id of - the source node), `end` (id of the target node). The value of `id` can be `any`. All other - properties are up to you. (e.g. `connects` in the above example). - Whenever `orb.data.setup` is called, any previous graph structure will be removed. ### Node Node object (interface `INode`) is created on top of the node data that is provided via -`orb.data.setup` or `orb.data.merge` functions. The Node object contains the information: +`orb.data.setup` or `orb.data.merge` functions. -* `id` - Readonly unique `id` provided on init (same as `.data.id`) -* `data` - User provided information on `orb.data.setup` or `orb.data.merge` -* `style` - Style properties like color, border, size (check more on [Styling guide](./styles.md)). -* `position` - Node `x` and `y` coordinate generated before first render -* `state` - Node state which can be selected (`GraphObjectState.SELECTED`), hovered +#### Node information + +- `id` - Readonly unique `id` provided on init (same as `.getData().id`) +- `data` - User provided information on `orb.data.setup` or `orb.data.merge` +- `style` - Style properties like color, border, size (check more on [Styling guide](./styles.md)). +- `position` - Node `x` and `y` coordinate generated before first render +- `state` - Node state which can be selected (`GraphObjectState.SELECTED`), hovered (`GraphObjectState.HOVERED`), or none (`GraphObjectState.NONE` - default) -There are some useful node functions that you can use such as: +#### Node getters functions + +- `getId()` - Alias for `.id` +- `getData()` - Returns the node data +- `getPosition()` - Returns the node position +- `getStyle()` - Returns the node style +- `getState()` - Returns the node state +- `getCenter()` - Alias for `.position` +- `getRadius()` - Alias for `.getStyle().size` +- `getBorderedRadius()` - Alias for `.getStyle().size + .getStyle().borderWidth` +- `getInEdges()` - Returns a list of inbound edges connected to the node +- `getOutEdges()` - Returns a list of outbound edges connected to the node +- `getEdges()` - Returns a list of all edges connected to the node, inbound and outbound +- `getAdjacentNodes()` - Returns a list of adjacent nodes +- `getLabel()` - Returns the node label +- `getColor()` - Returns the node color + +#### Node setter/patch functions -* `getCenter()` - Alias for `.position` -* `getRadius()` - Alias for `.style.size` -* `getBorderedRadius()` - Alias for `.style.size + .style.borderWidth` -* `getInEdges()` - Returns a list of inbound edges connected to the node -* `getOutEdges()` - Returns a list of outbound edges connected to the node -* `getEdges()` - Returns a list of all edges connected to the node, inbound and outbound -* `getAdjacentNodes()` - Returns a list of adjacent nodes +All of the setter/patch functions for nodes are able to accept the raw data of the corresponding type or the callback that returns this data. + +- `setData()` - Replaces the node data with the provided data +- `patchData()` - Replaces the node data entries with the provided ones +- `setPosition()` - Sets the node current position +- `setStyle()` - Sets the node current style +- `patchStyle()` - Replaces the node style entries with the provided ones +- `setState()` - Sets the node current state + +`position`, `style` and `state` setters can accept optional `options` argument. It can be used to skip the rerender on data change which can be useful for performance while changing the data of many nodes. Check the example to get to know node handling better: @@ -79,43 +117,62 @@ const nodes: MyNode[] = [ orb.data.setup({ nodes }); const node = orb.data.getNodeById(0); -console.log(node.id); // Output: 0 -console.log(node.data); // Output: { id: 0, text: "Node A", myField: 12 } +console.log(node.getId()); // Output: 0 +console.log(node.getData()); // Output: { id: 0, text: "Node A", myField: 12 } // Set node color to red -node.style.color = '#FF0000'; -console.log(node.style); // Output: { ..., color: '#FF0000' } +node.patchStyle({ color: "#FF0000" }); +console.log(node.getStyle()); // Output: { ..., color: '#FF0000' } ``` ### Edge Edge object (interface `IEdge`) is created on top of the edge data that is provided via -`orb.data.setup` or `orb.data.merge` functions. The Edge object contains the information: - -* `id` - Readonly unique `id` provided on init (same as `.data.id`) -* `data` - User provided information on `orb.data.setup` or `orb.data.merge` -* `start` - Readonly `start` provided on init (same as `.data.start`) -* `end` - Readonly `end` provided on init (same as `.data.end`) -* `startNode` - Reference to the start node (`INode`) that edge connects -* `endNode` - Reference to the end node (`INode`) that edge connects -* `style` - Style properties like color, border, size (check more on [Styling guide](./styles.md)). -* `state` - Edge state which can be selected (`GraphObjectState.SELECTED`), hovered +`orb.data.setup` or `orb.data.merge` functions. + +#### Edge information + +- `id` - Readonly unique `id` provided on init (same as `.getData().id`) +- `data` - User provided information on `orb.data.setup` or `orb.data.merge` +- `start` - Readonly `start` provided on init (same as `.getData().start`) +- `end` - Readonly `end` provided on init (same as `.getData().end`) +- `startNode` - Reference to the start node (`INode`) that edge connects +- `endNode` - Reference to the end node (`INode`) that edge connects +- `style` - Style properties like color, border, size (check more on [Styling guide](./styles.md)). +- `state` - Edge state which can be selected (`GraphObjectState.SELECTED`), hovered (`GraphObjectState.HOVERED`), or none (`GraphObjectState.NONE` - default) -* `type` - Edge line type which can be: - * straight (`EdgeType.STRAIGHT`) - if there are 1x, 3x, 5x, ... edges connecting nodes A and B, +- `type` - Edge line type which can be: + - straight (`EdgeType.STRAIGHT`) - if there are 1x, 3x, 5x, ... edges connecting nodes A and B, one edge will be a straight line edge. If there are multiple edges, other edges will be curved not to overlap with each other - * curved (`EdgeType.CURVED`) - if there is more than one edge connecting nodes A and B, some + - curved (`EdgeType.CURVED`) - if there is more than one edge connecting nodes A and B, some of those edges will be curved, so they do not overlap with each other - * loopback (`EdgeType.LOOPBACK) - connects a node to itself + - loopback (`EdgeType.LOOPBACK) - connects a node to itself + +#### Edge getters function + +- `getId()` - Alias for `.id` +- `getData()` - Getter for edge data +- `getPosition()` - Getter for edge position +- `getStyle()` - Getter for edge style +- `getState()` - Getter for edge state +- `getCenter()` - Gets the center edge position calculated by edge type and connected node positions +- `getWidth()` - Alias for `.style.width` +- `isLoopback()` - Checks if edge is a loopback type: connects a node to itself. +- `isStraight()` - Checks if edge is a straight line edge +- `isCurved()` - Checks if edge is a curved line edge. + +#### Edge setters/patch functions + +All of the setter/patch functions for edges are able to accept the raw data of the corresponding type or the callback that returns this data. -There are some useful node functions that you can use such as: +- `setData()` - Replaces the edge data with the provided data +- `patchData()` - Replaces the edge data entries with the provided ones +- `setStyle()` - Sets the edge current style +- `patchStyle()` - Replaces the edge style entries with the provided ones +- `setState()` - Sets the edge current state -* `getCenter()` - Gets the center edge position calculated by edge type and connected node positions -* `getWidth()` - Alias for `.style.width` -* `isLoopback()` - Checks if edge is a loopback type: connects a node to itself. -* `isStraight()` - Checks if edge is a straight line edge -* `isCurved()` - Checks if edge is a curved line edge. +`style` and `state` setters can accept optional `options` argument. It can be used to skip the rerender on data change which can be useful for performance while changing the data of many edges. Check the example to get to know edge handling better: @@ -130,21 +187,21 @@ const nodes: MyNode[] = [ ]; const edges: MyEdge[] = [ - { id: 0, start: 0, end: 1, connects: 'A -> B' }, - { id: 1, start: 0, end: 0, connects: 'A -> A' }, + { id: 0, start: 0, end: 1, connects: "A -> B" }, + { id: 1, start: 0, end: 0, connects: "A -> A" }, ]; orb.data.setup({ nodes, edges }); const edge = orb.data.geEdgeById(0); -console.log(edge.id); // Output: 0 -console.log(edge.data); // Output: { id: 0, start: 0, end: 1, connects: 'A -> B' } -console.log(edge.startNode.data); // Output: { id: 0, text: "Node A", myField: 12 } -console.log(edge.endNode.data); // Output: { id: 1, text: "Node B", myField: 77 } +console.log(edge.getId()); // Output: 0 +console.log(edge.getData()); // Output: { id: 0, start: 0, end: 1, connects: 'A -> B' } +console.log(edge.startNode.getData()); // Output: { id: 0, text: "Node A", myField: 12 } +console.log(edge.endNode.getData()); // Output: { id: 1, text: "Node B", myField: 77 } // Set edge line color to red -edge.style.color = '#FF0000'; -console.log(edge.style); // Output: { ..., color: '#FF0000' } +edge.patchStyle({ color: "#FF0000" }); +console.log(edge.getStyle()); // Output: { ..., color: '#FF0000' } ``` ## Merge nodes and edges @@ -164,8 +221,8 @@ const nodes: MyNode[] = [ ]; const edges: MyEdge[] = [ - { id: 0, start: 0, end: 1, connects: 'A -> B' }, - { id: 1, start: 0, end: 0, connects: 'A -> A' }, + { id: 0, start: 0, end: 1, connects: "A -> B" }, + { id: 1, start: 0, end: 0, connects: "A -> A" }, ]; orb.data.setup({ nodes, edges }); @@ -181,12 +238,12 @@ orb.data.merge({ ], edges: [ // This will update the edge with id = 1 because it already exists. `edge.data` will be updated, - // but also, edge will disconnect from previous nodes and connect to the new ones (0 -> 2). - { id: 1, start: 0, end: 2, connects: 'A -> C' }, + // but also, edge will disconnect from previous nodes and connect to the new ones (0 -> 2). + { id: 1, start: 0, end: 2, connects: "A -> C" }, // This will be a new edge in the graph because edge with id = 2 doesn't exist - { id: 2, start: 2, end: 1, connects: 'C -> B' }, + { id: 2, start: 2, end: 1, connects: "C -> B" }, // This edge will be dismissed because node with id = 7 doesn't exist - { id: 3, start: 2, end: 8, connects: 'C -> ?' }, + { id: 3, start: 2, end: 8, connects: "C -> ?" }, ], }); console.log(orb.data.getNodeCount()); // Output: 3 @@ -209,8 +266,8 @@ const nodes: MyNode[] = [ ]; const edges: MyEdge[] = [ - { id: 0, start: 0, end: 1, text: 'A -> B' }, - { id: 1, start: 0, end: 0, text: 'A -> A' }, + { id: 0, start: 0, end: 1, text: "A -> B" }, + { id: 1, start: 0, end: 0, text: "A -> A" }, ]; orb.data.setup({ nodes, edges }); @@ -230,13 +287,13 @@ orb.data.remove({ nodeIds: [0] }); orb.data.remove({ nodeIds: [0, 1, 2], edgeIds: [0] }); // Remove just edges -orb.data.remove({ edgeIds: [0, 1, 2 ] }); +orb.data.remove({ edgeIds: [0, 1, 2] }); ``` If you need to remove everything, you can do it with `remove` or even with `setup`: ```typescript -const nodeIds = orb.data.getNodes().map(node => node.id); +const nodeIds = orb.data.getNodes().map((node) => node.getId()); // No need to get edges because if we remove all the nodes, all the edges will be removed too orb.data.remove({ nodeIds: nodeIds }); @@ -258,7 +315,7 @@ const edges = orb.data.getEdges(); const nodeCount = orb.data.getNodeCount(); const edgeCount = orb.data.getEdgeCount(); -// Returns specific node or edge by id. If node or edge doesn't exist, it will return undefined +// Returns specific node or edge by id. If node or edge doesn't exist, it will return undefined const node = orb.data.getNodeById(0); const edge = orb.data.getEdgeById(0); diff --git a/docs/styles.md b/docs/styles.md index b44e4e9..d5ad90f 100644 --- a/docs/styles.md +++ b/docs/styles.md @@ -1,5 +1,4 @@ -Styling nodes and edges in Orb -=== +# Styling nodes and edges in Orb Styling nodes and edges in Orb refers to the configuration of colors, size, width, and other visual properties. In the following section, you can find all the details and available style properties to @@ -14,7 +13,7 @@ through which you can get and set style properties. ```typescript const node = orb.data.getNodeById(0); // Set node size to 10 -node.style.size = 10; +node.patchStyle({ size: 10 }); ``` ## Properties @@ -22,31 +21,31 @@ node.style.size = 10; The interface that defines all the node style properties is `INodeStyle`. It contains the following properties: -| Property name | Type | Description | -| --------------------- | ------------------- | ----------------------------------------------- | -| `borderColor` | Color | string | Node border color. | -| `borderColorHover` | Color | string | Node border color on mouse hover event. If not defined, `borderColor` is used. | -| `borderColorSelected` | Color | string | Node border color on mouse click event. If not defined, `borderColor` is used. | -| `borderWidth` | number | Node border width. | -| `borderWidthSelected` | number | Node border width on mouse click event. If not defined, `borderWidth` is used. | -| `color` | Color | string | Node background color. The default is `#1d87c9`. | -| `colorHover` | Color | string | Node background color on mouse hover event. If not defined `color` is used. | -| `colorSelected` | Color | string | Node background color on mouse click event. If not defined `color` is used. | -| `fontBackgroundColor` | Color | string | Node text (label) background color. | -| `fontColor` | Color | string | Node text (label) font color. The default is `#000000`. | -| `fontFamily` | string | Node text (label) font family. The default is `"Roboto, sans-serif"`. | -| `fontSize` | number | Node text (label) font size. The default is `4`. | -| `imageUrl` | string | Image used for a node background. If image is defined, `color` won't be used. | -| `imageUrlSelected` | string | Image used for a node background on mouse click event. If image is defined, `colorSelected` and `color` won't be used. | -| `label` | string | Node text content. Text content will be shown below the node if `fontSize` is greater than zero. | -| `shadowColor` | Color | string | Node background shadow color. | -| `shadowSize` | number | Node shadow blur size. If set to `0` the shadow will be a solid color defined by `shadowColor`. | -| `shadowOffsetX` | number | Node shadow horizontal offset. A positive value puts the shadow on the right side of the element, a negative value puts the shadow on the left side of the element. | -| `shadowOffsetY` | number | Node shadow vertical offset. A positive value puts the shadow below the element, a negative value puts the shadow above the element. | +| Property name | Type | Description | +| --------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `borderColor` | Color | string | Node border color. | +| `borderColorHover` | Color | string | Node border color on mouse hover event. If not defined, `borderColor` is used. | +| `borderColorSelected` | Color | string | Node border color on mouse click event. If not defined, `borderColor` is used. | +| `borderWidth` | number | Node border width. | +| `borderWidthSelected` | number | Node border width on mouse click event. If not defined, `borderWidth` is used. | +| `color` | Color | string | Node background color. The default is `#1d87c9`. | +| `colorHover` | Color | string | Node background color on mouse hover event. If not defined `color` is used. | +| `colorSelected` | Color | string | Node background color on mouse click event. If not defined `color` is used. | +| `fontBackgroundColor` | Color | string | Node text (label) background color. | +| `fontColor` | Color | string | Node text (label) font color. The default is `#000000`. | +| `fontFamily` | string | Node text (label) font family. The default is `"Roboto, sans-serif"`. | +| `fontSize` | number | Node text (label) font size. The default is `4`. | +| `imageUrl` | string | Image used for a node background. If image is defined, `color` won't be used. | +| `imageUrlSelected` | string | Image used for a node background on mouse click event. If image is defined, `colorSelected` and `color` won't be used. | +| `label` | string | Node text content. Text content will be shown below the node if `fontSize` is greater than zero. | +| `shadowColor` | Color | string | Node background shadow color. | +| `shadowSize` | number | Node shadow blur size. If set to `0` the shadow will be a solid color defined by `shadowColor`. | +| `shadowOffsetX` | number | Node shadow horizontal offset. A positive value puts the shadow on the right side of the element, a negative value puts the shadow on the left side of the element. | +| `shadowOffsetY` | number | Node shadow vertical offset. A positive value puts the shadow below the element, a negative value puts the shadow above the element. | | `shape` | NodeShapeType | Node shape enum. Possible values are: `CIRCLE`, `DOT` (same as circle), `SQUARE`, `DIAMOND`, `TRIANGLE`, `TRIANGLE_DOWN`, `STAR`, `HEXAGON`. Default is `NodeShapeEnum.CIRCLE`. | -| `size` | number | Node size (usually the radius). The default is `5`. | -| `mass` | number | Node mass. _(Currently not used)_ | -| `zIndex` | number | Specifies the stack order of an element during rendering. The default is `0`. | +| `size` | number | Node size (usually the radius). The default is `5`. | +| `mass` | number | Node mass. _(Currently not used)_ | +| `zIndex` | number | Specifies the stack order of an element during rendering. The default is `0`. | ## Shape enumeration @@ -54,14 +53,14 @@ The enum `NodeShapeType` which is used for the node `shape` property is defined ```typescript export enum NodeShapeType { - CIRCLE = 'circle', - DOT = 'dot', - SQUARE = 'square', - DIAMOND = 'diamond', - TRIANGLE = 'triangle', - TRIANGLE_DOWN = 'triangleDown', - STAR = 'star', - HEXAGON = 'hexagon', + CIRCLE = "circle", + DOT = "dot", + SQUARE = "square", + DIAMOND = "diamond", + TRIANGLE = "triangle", + TRIANGLE_DOWN = "triangleDown", + STAR = "star", + HEXAGON = "hexagon", } ``` @@ -72,10 +71,10 @@ Default node style values are defined as follows: ```typescript const DEFAULT_NODE_STYLE: INodeStyle = { size: 5, - color: new Color('#1d87c9'), + color: new Color("#1d87c9"), fontSize: 4, - fontColor: '#000000', - fontFamily: 'Roboto, sans-serif', + fontColor: "#000000", + fontFamily: "Roboto, sans-serif", shape: NodeShapeType.CIRCLE, }; ``` @@ -115,7 +114,7 @@ through which you can get and set style properties. ```typescript const edge = orb.data.getEdgebyId(0); // Set edge width to 1 -edge.style.width = 1; +edge.patchStyle({ width: 1 }); ``` ## Properties @@ -123,26 +122,26 @@ edge.style.width = 1; The interface that defines all the node properties is `IEdgeStyle`. It contains the following style properties: -| Property name | Type | Description | -| --------------------- | ------------------- | --------------------------------------------------- | +| Property name | Type | Description | +| --------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `arrowSize` | number | The scale of the edge arrow compared to the `width` of the edge. If set to `0`, an arrow will be dismissed. The default is `1` (follows the size of the edge `width`). | -| `color` | Color | string | Edge line color. The default is `#ababab`. | -| `colorHover` | Color | string | Edge line color on mouse hover event. If not defined `color` is used. | -| `colorSelected` | Color | string | Edge line color on mouse click event. If not defined `color` is used. | -| `fontBackgroundColor` | Color | string | Edge text (label) background color. -| `fontColor` | Color | string | Edge text (label) font color. The default is `#000000`. | -| `fontFamily` | string | Edge text (label) font family. The default is `"Roboto, sans-serif"`. | -| `fontSize` | number | Edge text (label) font size. The default is `4`. | -| `label` | string | Edge text content. Text content will be shown at the middle of the edge line if `fontSize` is greater than zero. | -| `shadowColor` | Color | string | Edge line background shadow color. | -| `shadowSize` | number | Edge line shadow blur size. If set to `0` the shadow will be a solid color defined by `shadowColor`. | -| `shadowOffsetX` | number | Edge shadow horizontal offset. A positive value puts the shadow on the right side of the line, a negative value puts the shadow on the left side of the line. | -| `shadowOffsetY` | number | Edge shadow vertical offset. A positive value puts the shadow below the line, a negative value puts the shadow above the line. | -| `width` | number | Edge line width. If the width is `0`, the edge won't be drawn. The default is `0.3`. | -| `widthHover` | number | Edge line width on mouse hover event. If not defined `width` is used. | -| `widthSelected` | number | Edge line width on mouse click event. If not defined `width` is used. | -| `zIndex` | number | Specifies the stack order of an element during rendering. The default is `0`. | -| `lineStyle` | object | Allows to customize the style of edges in the graph visualization. The default is `{type: 'solid'}` | +| `color` | Color | string | Edge line color. The default is `#ababab`. | +| `colorHover` | Color | string | Edge line color on mouse hover event. If not defined `color` is used. | +| `colorSelected` | Color | string | Edge line color on mouse click event. If not defined `color` is used. | +| `fontBackgroundColor` | Color | string | Edge text (label) background color. | +| `fontColor` | Color | string | Edge text (label) font color. The default is `#000000`. | +| `fontFamily` | string | Edge text (label) font family. The default is `"Roboto, sans-serif"`. | +| `fontSize` | number | Edge text (label) font size. The default is `4`. | +| `label` | string | Edge text content. Text content will be shown at the middle of the edge line if `fontSize` is greater than zero. | +| `shadowColor` | Color | string | Edge line background shadow color. | +| `shadowSize` | number | Edge line shadow blur size. If set to `0` the shadow will be a solid color defined by `shadowColor`. | +| `shadowOffsetX` | number | Edge shadow horizontal offset. A positive value puts the shadow on the right side of the line, a negative value puts the shadow on the left side of the line. | +| `shadowOffsetY` | number | Edge shadow vertical offset. A positive value puts the shadow below the line, a negative value puts the shadow above the line. | +| `width` | number | Edge line width. If the width is `0`, the edge won't be drawn. The default is `0.3`. | +| `widthHover` | number | Edge line width on mouse hover event. If not defined `width` is used. | +| `widthSelected` | number | Edge line width on mouse click event. If not defined `width` is used. | +| `zIndex` | number | Specifies the stack order of an element during rendering. The default is `0`. | +| `lineStyle` | object | Allows to customize the style of edges in the graph visualization. The default is `{type: 'solid'}` | ## Default style values @@ -150,12 +149,12 @@ Default edge style values are defined as follows: ```typescript const DEFAULT_EDGE_STYLE: IEdgeStyle = { - color: new Color('#ababab'), + color: new Color("#ababab"), width: 0.3, fontSize: 4, arrowSize: 1, - fontColor: '#000000', - fontFamily: 'Roboto, sans-serif', + fontColor: "#000000", + fontFamily: "Roboto, sans-serif", }; ``` @@ -168,17 +167,17 @@ Orb exports a utility class `Color` which you can use to define colors too. It c functions for easier color handling: ```typescript -import { Color } from '@memgraph/orb'; +import { Color } from "@memgraph/orb"; // Constructor always receives a color HEX code -const red = new Color('#FF0000'); +const red = new Color("#FF0000"); // Returns darker or lighter color by input factor (default is 0.3) const darkerRed = red.getDarkerColor(); const lighterRed = red.getLighterColor(); // Mix two colors (RGB values are joined and divided by 2) -const mixedColor = red.getMixedColor(new Color('#ffffff')); +const mixedColor = red.getMixedColor(new Color("#ffffff")); // Get a color object by RGB values, not HEX code const redByRGB = Color.getColorFromRGB({ r: 255, g: 0, b: 0 }); @@ -191,26 +190,27 @@ If you would like to have a lighter/darker tone of a node on node select/hover, that with `getLighterColor` or `getDarkerColor` functions: ```typescript -const nodeBaseColor = new Color('#FF0000'); +const nodeBaseColor = new Color("#FF0000"); -node.style.color = nodeBaseColor; -node.style.colorSelected = nodeBaseColor.getDarkerColor(); -node.style.colorHover = nodeBaseColor.getLighterColor(); +node.patchStyle({ color: nodeBaseColor }); +node.patchStyle({ colorSelected: nodeBaseColor.getDarkerColor() }); +node.patchStyle({ colorHover: nodeBaseColor.getLighterColor() }); ``` # Setting up styles There are two ways to set up a style: -* Setting up default style which is an initial style applied to new nodes and new edges -* Changing the style properties of particular nodes and edges + +- Setting up default style which is an initial style applied to new nodes and new edges +- Changing the style properties of particular nodes and edges ## Setting default style Orb comes with a default style which you can override with the function `orb.data.setDefaultStyle`. The function expects an object where you can define one or both style callback functions: -* `getNodeStyle(node)` - expects an object containing node style properties. -* `getEdgeStyle(edge)` - expects an object containing edge style properties. +- `getNodeStyle(node)` - expects an object containing node style properties. +- `getEdgeStyle(edge)` - expects an object containing edge style properties. The default style is an easy way to set up a style that will be applied to all newly created nodes or edges. With it, you don't need to worry about setting up style properties for each @@ -220,7 +220,7 @@ node or edge. orb.data.setDefaultStyle({ getNodeStyle(node) { return { - color: '#FF0000', + color: "#FF0000", fontSize: 10, size: 10, label: `Node: ${node.data.title}`, @@ -228,7 +228,7 @@ orb.data.setDefaultStyle({ }, getEdgeStyle() { return { - color: '#000000', + color: "#000000", width: 3, }; }, @@ -240,7 +240,6 @@ orb.data.setDefaultStyle({ // For all the `newNodes` and `newEdges` that have a new unique ID, a default // style defined above will be automatically applied orb.data.merge({ nodes: newNodes, edges: newEdges }); - ``` Without a default style, you would need to do the following after each call of `orb.data.setup` @@ -250,22 +249,22 @@ or `orb.data.merge` where new nodes/edges are created: // Without default style, after each call of `orb.data.setup` or `orb.data.merge` // you need to call the following code orb.data.getNodes().forEach((node) => { - node.style = { - color: '#FF0000', + node.setStyle({ + color: "#FF0000", fontSize: 10, size: 10, label: `Node: ${node.data.title}`, - }; + }); }); orb.data.getEdges().forEach((edge) => { - edge.style = { - color: '#000000', + edge.setStyle({ + color: "#000000", width: 3, - }; + }); }); // For all the `newNodes` and `newEdges` that have a new unique ID, Orb's default -// style will be applied, not the style properties above +// style will be applied, not the style properties above orb.data.merge({ nodes: newNodes, edges: newEdges }); ``` @@ -276,28 +275,28 @@ node (`INode`) or edge (`IEdge`) object. Using those objects, you can change the any time: ```typescript -import { OrbView, OrbEventType } from '@memgraph/orb'; +import { OrbView, OrbEventType } from "@memgraph/orb"; const orb = new OrbView(container); orb.data.setup({ nodes, edges }); const node = orb.data.getNodeById(0); // Override existing node style properties with the new ones -node.style = { - color: '#FF0000', +node.setStyle({ + color: "#FF0000", fontSize: 10, size: 10, label: `Node: ${node.data.title}`, -}; +}); // Change the width of all the edges to 1, but keep other style properties orb.data.getEdges().forEach((edge) => { - edge.style.width = 1; + edge.patchStyle({ width: 1 }); }); orb.events.on(OrbEventType.NODE_CLICK, ({ node }) => { // If a node is clicked, set its size to be 10 - node.style.size = 10; + node.patchStyle({ size: 10 }); }); ``` @@ -315,7 +314,7 @@ without setting `(node|edge).style.label = ""` or `(node|edge).style.fontSize = each node/edge, you can use the view settings to enable/disable labels globally: ```typescript -import { OrbView } from '@memgraph/orb'; +import { OrbView } from "@memgraph/orb"; // Change on view init const orb = new OrbView(container, { @@ -345,7 +344,7 @@ for the large number of nodes/edges. To simplify the way to disable/enable shado whole graph you can use the view settings to enable/disable shadows globally: ```typescript -import { OrbView } from '@memgraph/orb'; +import { OrbView } from "@memgraph/orb"; // Change on view init const orb = new OrbView(container, { @@ -372,17 +371,17 @@ properties are `true`. Additional performance affected property is the transparency of nodes/edges that are not selected nor hovered. Default Orb behavior on node/edge select (click) and hover to make all other nodes 30% -transparent, so the selection/hover is easily visible. +transparent, so the selection/hover is easily visible. You can configure the transparency with the following two properties: -* `contextAlphaOnEvent` - Transparency factor between 0 (hidden) and 1 (opaque). The default +- `contextAlphaOnEvent` - Transparency factor between 0 (hidden) and 1 (opaque). The default is `0.3`. -* `contextAlphaOnEventIsEnabled` - Enable or disable transparency regardless of the factor. +- `contextAlphaOnEventIsEnabled` - Enable or disable transparency regardless of the factor. The default is `true`. ```typescript -import { OrbView } from '@memgraph/orb'; +import { OrbView } from "@memgraph/orb"; // Change on view init const orb = new OrbView(container, { diff --git a/docs/view-default.md b/docs/view-default.md index 217e9bc..6d2fb78 100644 --- a/docs/view-default.md +++ b/docs/view-default.md @@ -244,7 +244,7 @@ const edges: MyEdge[] = [ ]; const orb = new OrbView(container, { - getPosition: (node) => ({ x: node.data.posX, y: node.data.posY }), + getPosition: (node) => ({ x: node.getData().posX, y: node.getData().posY }), }); // Initialize nodes and edges @@ -398,7 +398,7 @@ after the initialization with a view function `setSettings`: import { OrbView } from "@memgraph/orb"; const orb = new OrbView(container, { - getPosition: (node) => ({ x: node.data.posY, y: node.data.posX }), + getPosition: (node) => ({ x: node.getData().posY, y: node.getData().posX }), zoomFitTransformMs: 1000, render: { shadowIsEnabled: false, @@ -413,7 +413,7 @@ const settings = orb.getSettings(); // Change the x and y axis orb.setSettings({ - getPosition: (node) => ({ x: node.data.posY, y: node.data.posX }), + getPosition: (node) => ({ x: node.getData().posY, y: node.getData().posX }), }); // Change the zoom fit and transform time while recentering and disable shadows diff --git a/docs/view-map.md b/docs/view-map.md index 26c1cb8..4daa32b 100644 --- a/docs/view-map.md +++ b/docs/view-map.md @@ -32,7 +32,10 @@ const edges: MyEdge[] = [ ]; const orb = new OrbMapView(container, { - getGeoPosition: (node) => ({ lat: node.data.lat, lng: node.data.lng }), + getGeoPosition: (node) => ({ + lat: node.getData().lat, + lng: node.getData().lng, + }), }); // Assign a default style @@ -43,7 +46,7 @@ orb.data.setDefaultStyle({ borderWidth: 1, color: "#DD2222", fontSize: 10, - label: node.data.label, + label: node.getData().label, size: 10, }; }, @@ -81,14 +84,14 @@ const mapAttribution = const orb = new OrbMapView(container, { getGeoPosition: (node) => ({ - lat: node.data.latitude, - lng: node.data.longitude, + lat: node.getData().latitude, + lng: node.getData().longitude, }), map: { zoomLevel: 5, tile: { instance: new L.TileLayer( - "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" + "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" ), attribution: mapAttribution, }, @@ -217,14 +220,14 @@ Disabled by default (`false`). The optional property `strategy` has two properties that you can enable/disable: -* `isDefaultSelectEnabled` - when `true`, the default selection strategy is used on mouse click: - * If there is a node at the mouse click point, the node, its edges, and adjacent nodes will change +- `isDefaultSelectEnabled` - when `true`, the default selection strategy is used on mouse click: + - If there is a node at the mouse click point, the node, its edges, and adjacent nodes will change its state to `GraphObjectState.SELECTED`. Style properties that end with `...Selected` will be applied to all the selected objects (e.g. `borderColorSelected`). - * If there is an edge at the mouse click point, the edge and its starting and ending nodes will change + - If there is an edge at the mouse click point, the edge and its starting and ending nodes will change its state to `GraphObjectState.SELECTED`. -* `isDefaultHoverEnabled` - when `true`, the default hover strategy is used on mouse move: - * If there is a node at the mouse pointer, the node, its edges, and adjacent nodes will change its state to +- `isDefaultHoverEnabled` - when `true`, the default hover strategy is used on mouse move: + - If there is a node at the mouse pointer, the node, its edges, and adjacent nodes will change its state to `GraphObjectState.HOVERED`. Style properties that end with `...Hovered` will be applied to all the hovered objects (e.g. `borderColorHovered`). @@ -232,7 +235,7 @@ With property `strategy` you can disable the above behavior and implement your s top of events `OrbEventType.MOUSE_CLICK` and `OrbEventType.MOUSE_MOVE`, e.g: ```typescript -import { isNode, OrbEventType, GraphObjectState } from '@memgraph/orb'; +import { isNode, OrbEventType, GraphObjectState } from "@memgraph/orb"; // Disable default select and hover strategy orb.setSettings({ @@ -257,7 +260,9 @@ orb.events.on(OrbEventType.MOUSE_CLICK, (event) => { // Clicked on unselected node if (event.subject && isNode(event.subject) && !event.subject.isSelected()) { // Deselect the previously selected nodes - orb.data.getNodes((node) => node.isSelected()).forEach((node) => node.clearState()); + orb.data + .getNodes((node) => node.isSelected()) + .forEach((node) => node.clearState()); // Select the new node event.subject.state = GraphObjectState.SELECTED; orb.render(); @@ -276,7 +281,10 @@ const settings = orb.getSettings(); // Change the way how geo coordinates are defined on nodes orb.setSettings({ - getGeoPosition: (node) => ({ lat: node.data.lat, lng: node.data.lng }), + getGeoPosition: (node) => ({ + lat: node.getData().lat, + lng: node.getData().lng, + }), }); // Change the zoom level and disable shadows From aad6a2ef2077860cc69c7a2ee7c690befc40219e Mon Sep 17 00:00:00 2001 From: AlexIchenskiy Date: Fri, 12 Jul 2024 13:44:27 +0200 Subject: [PATCH 17/22] Fix: Node/edge getter performance issue --- src/models/edge.ts | 9 ++++++--- src/models/node.ts | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/models/edge.ts b/src/models/edge.ts index d36c8af..0a3374b 100644 --- a/src/models/edge.ts +++ b/src/models/edge.ts @@ -218,15 +218,18 @@ abstract class Edge extends Subject im } getData(): E { - return structuredClone(this._data); + // no shallow/deep copy here due to the performance issues + return this._data; } getPosition(): IEdgePosition { - return structuredClone(this._position); + // no shallow/deep copy here due to the performance issues + return this._position; } getStyle(): IEdgeStyle { - return structuredClone(this._style); + // no shallow/deep copy here due to the performance issues + return this._style; } getState(): number { diff --git a/src/models/node.ts b/src/models/node.ts index af6b1f4..262c4a9 100644 --- a/src/models/node.ts +++ b/src/models/node.ts @@ -182,15 +182,18 @@ export class Node extends Subject impl } getData(): N { - return structuredClone(this._data); + // no shallow/deep copy here due to the performance issues + return this._data; } getPosition(): INodePosition { - return structuredClone(this._position); + // no shallow/deep copy here due to the performance issues + return this._position; } getStyle(): INodeStyle { - return structuredClone(this._style); + // no shallow/deep copy here due to the performance issues + return this._style; } getState(): number { From 2570888801a0d38525c5f9b3980dbd88b0ec9ab5 Mon Sep 17 00:00:00 2001 From: AlexIchenskiy Date: Mon, 15 Jul 2024 08:08:59 +0200 Subject: [PATCH 18/22] Chore: Add data change docs example --- examples/example-dynamic-change.html | 110 +++++++++++++++++++++++++++ examples/index.html | 9 +++ 2 files changed, 119 insertions(+) create mode 100644 examples/example-dynamic-change.html diff --git a/examples/example-dynamic-change.html b/examples/example-dynamic-change.html new file mode 100644 index 0000000..bedbe39 --- /dev/null +++ b/examples/example-dynamic-change.html @@ -0,0 +1,110 @@ + + + + + + Orb | Data dynamics: Update nodes and edges data + + + + +
+

Example 7 - Data dynamics

+

+ Renders a simple graph to show graph data dynamics: updating nodes and edges data. + In intervals of 3 seconds, 1 node gets new size and 1 node gets new color + (green or red) and a new border color (white or black). Node will change its + unselected color to blue on node click event. +

+ + +
+
+ + + diff --git a/examples/index.html b/examples/index.html index 78b0c65..98f29f1 100644 --- a/examples/index.html +++ b/examples/index.html @@ -62,5 +62,14 @@

Orb Examples

longitude values.

+
+

  • Example 7 - Data dynamics
  • +

    + Renders a simple graph to show graph data dynamics: updating nodes and edges data. + In intervals of 3 seconds, 1 node gets new size and 1 node gets new color + (green or red) and a new border color (white or black). Node will change its + unselected color to blue on node click event. +

    +
    From 0825293f4f73d30a8d6f7cacb89cc34f50c6e891 Mon Sep 17 00:00:00 2001 From: AlexIchenskiy Date: Mon, 15 Jul 2024 08:14:35 +0200 Subject: [PATCH 19/22] Fix: Docs typos --- docs/styles.md | 10 +++++----- docs/view-default.md | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/styles.md b/docs/styles.md index 7553997..8a3ef9c 100644 --- a/docs/styles.md +++ b/docs/styles.md @@ -96,8 +96,8 @@ const orb = new OrbView(container); orb.data.setDefaultStyle({ getNodeStyle: (node) => { return { - ...node.style, - label: node.data.name, + ...node.getStyle(), + label: node.getData().name, }; }, }); @@ -223,7 +223,7 @@ orb.data.setDefaultStyle({ color: "#FF0000", fontSize: 10, size: 10, - label: `Node: ${node.data.title}`, + label: `Node: ${node.getData().title}`, }; }, getEdgeStyle() { @@ -253,7 +253,7 @@ orb.data.getNodes().forEach((node) => { color: "#FF0000", fontSize: 10, size: 10, - label: `Node: ${node.data.title}`, + label: `Node: ${node.getData().title}`, }); }); orb.data.getEdges().forEach((edge) => { @@ -286,7 +286,7 @@ node.setStyle({ color: "#FF0000", fontSize: 10, size: 10, - label: `Node: ${node.data.title}`, + label: `Node: ${node.getData().title}`, }); // Change the width of all the edges to 1, but keep other style properties diff --git a/docs/view-default.md b/docs/view-default.md index 6d2fb78..849796a 100644 --- a/docs/view-default.md +++ b/docs/view-default.md @@ -263,8 +263,8 @@ access your original properties through `.data` property. There you can find all your nodes that you assigned in the `orb.data.setup()` function. Here you can use your original properties to indicate which ones represent your node coordinates -(`node.data.posX`, `node.data.posY`). All you have to do is return a `IPosition` that requires -2 basic properties: `x` and `y` (`{ x: node.data.posX, y: node.data.posY }`). +(`node.getData().posX`, `node.getData().posY`). All you have to do is return a `IPosition` that requires +2 basic properties: `x` and `y` (`{ x: node.getData().posX, y: node.getData().posY }`). ### Property `render` From 5771996197dec521ed44ec1290a6430bfd013962 Mon Sep 17 00:00:00 2001 From: Oleksandr Ichenskyi <55350107+AlexIchenskiy@users.noreply.github.com> Date: Mon, 15 Jul 2024 09:39:14 +0200 Subject: [PATCH 20/22] Fix: Disable source map generation (#105) --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index bb28c93..828dd58 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ "module": "esnext", "lib": ["DOM", "ES6"], "declaration": true, - "sourceMap": true, + "sourceMap": false, "outDir": "./dist", "moduleResolution": "node", "esModuleInterop": true, From f538efe0ae86d4c78e4e82596c77ed87ff02098e Mon Sep 17 00:00:00 2001 From: Oleksandr Ichenskyi <55350107+AlexIchenskiy@users.noreply.github.com> Date: Tue, 3 Jun 2025 17:09:32 +0200 Subject: [PATCH 21/22] New: Add tree layout (#107) * New: Add new layouts * New: Add layout options * Chore: Make layout dynamically changeable * Chore: Update docs * Fix: Naming typo * Chore: Refactor layouts * New: Enable layout node add/remove * Chore: Improve behavior for recurrent nodes * Chore: Move some simulator settings to layout * Chore: Refactor code quality and performance * Fix: Layout behavior on change * Chore: Add recenter on layout change * Fix: Layout change behavior * Fix: Simulation behavior on data deletion * Chore: Add recenter on layout change --- docs/view-default.md | 38 ++++ examples/example-hierarchical-layout.html | 94 ++++++++++ examples/index.html | 6 + src/models/graph.ts | 21 +++ src/simulator/engine/d3-simulator-engine.ts | 20 +- src/simulator/layout/layout.ts | 52 ++++-- src/simulator/layout/layouts/circle.ts | 11 -- src/simulator/layout/layouts/circular.ts | 37 ++++ src/simulator/layout/layouts/force.ts | 11 ++ src/simulator/layout/layouts/grid.ts | 38 ++++ src/simulator/layout/layouts/hierarchical.ts | 163 ++++++++++++++++ src/simulator/shared.ts | 1 + src/simulator/types/main-thread-simulator.ts | 4 + .../message/worker-input.ts | 4 + .../web-worker-simulator/simulator.worker.ts | 5 + .../web-worker-simulator.ts | 4 + src/views/orb-view.ts | 176 ++++++++++++++---- 17 files changed, 620 insertions(+), 65 deletions(-) create mode 100644 examples/example-hierarchical-layout.html delete mode 100644 src/simulator/layout/layouts/circle.ts create mode 100644 src/simulator/layout/layouts/circular.ts create mode 100644 src/simulator/layout/layouts/force.ts create mode 100644 src/simulator/layout/layouts/grid.ts create mode 100644 src/simulator/layout/layouts/hierarchical.ts diff --git a/docs/view-default.md b/docs/view-default.md index 849796a..56e14d1 100644 --- a/docs/view-default.md +++ b/docs/view-default.md @@ -61,6 +61,16 @@ interface IOrbViewSettings { }; }; }; + // For graph layouting (if present, physics is disabled) + layout: { + type: 'hierarchical' | 'grid' | 'circular'; + options: null | { + orientation: 'vertical' | 'horizontal'; + reversed: boolean; + } | { + radius: number; + } + }; // For canvas rendering and events render: { devicePixelRatio: number | null; @@ -266,6 +276,34 @@ Here you can use your original properties to indicate which ones represent your (`node.getData().posX`, `node.getData().posY`). All you have to do is return a `IPosition` that requires 2 basic properties: `x` and `y` (`{ x: node.getData().posX, y: node.getData().posY }`). +### Property `layout` + +If you want to use one of the predefined layouts (hierarchical (tree), grid, circular...) you can specify +the optional property `layout`. Simulation physics are ignored when a layout is applied. There is no layout +applied by default. + +#### Property `type` + +You can specify the desired layout using the `type` property that can have one of the following values: + +- `hierarchical` - a tree-like layout style that tries to portrait graph nodes in a hierarchy + +- `circular` - arranges the nodes of the graph in a circle + +- `grid` - a layout where nodes are aligned in rows and columns + +#### Property `options` + +Each layout type has its own option list you can tweak in order to change the layout behaviour. + +- `hierarchical` + - `orientation` - The tree orientation that could be whether `vertical` (by default) or `horizontal` + - `reversed` - Whether the orientation is reversed. Default orientation is top-bottom for vertical and + left-right for horizontal which is reversed when this property is set to `true`. Disabled by default `false` + +- `circular` + - `radius` - Radius of the circle in relativa units. + ### Property `render` Optional property `render` has several rendering options that you can tweak. Read more about them diff --git a/examples/example-hierarchical-layout.html b/examples/example-hierarchical-layout.html new file mode 100644 index 0000000..0a03d09 --- /dev/null +++ b/examples/example-hierarchical-layout.html @@ -0,0 +1,94 @@ + + + + + + Orb | Simple hierarchical graph + + + + +
    +

    Example 8 - Hierarchical layout

    +

    Renders a simple graph with hierarchical layout.

    + + +
    +
    + + + diff --git a/examples/index.html b/examples/index.html index 98f29f1..73edf37 100644 --- a/examples/index.html +++ b/examples/index.html @@ -71,5 +71,11 @@

    Orb Examples

    unselected color to blue on node click event.

    +
    +

  • Example 8 - Hierarchical layout
  • +

    + Renders a simple graph with hierarchical layout (tree-like). +

    +
    diff --git a/src/models/graph.ts b/src/models/graph.ts index 8b7801e..7bcf0e0 100644 --- a/src/models/graph.ts +++ b/src/models/graph.ts @@ -8,6 +8,7 @@ import { IEntityState, EntityState } from '../utils/entity.utils'; import { IObserver, IObserverDataPayload, ISubject, Subject } from '../utils/observer.utils'; import { patchProperties } from '../utils/object.utils'; import { dedupArrays } from '../utils/array.utils'; +import { ILayout } from '../simulator/layout/layout'; export interface IGraphData { nodes: N[]; @@ -50,6 +51,7 @@ export interface IGraph extends ISubje getNearestNode(point: IPosition): INode | undefined; getNearestEdge(point: IPosition, minDistance?: number): IEdge | undefined; setSettings(settings: Partial>): void; + setLayout(layout: ILayout | undefined): void; } export interface IGraphSettings { @@ -73,6 +75,7 @@ export class Graph extends Subject imp }); private _defaultStyle?: Partial>; private _settings: IGraphSettings; + private _layout: ILayout | undefined; constructor(data?: Partial>, settings?: Partial>) { // TODO(dlozic): How to use object assign here? If I add add and export a default const here, it needs N, E. @@ -92,6 +95,11 @@ export class Graph extends Subject imp this.notifyListeners(); } + setLayout(layout: ILayout | undefined): void { + this._layout = layout; + this._resetLayout(); + } + /** * Returns a list of nodes. * @@ -274,6 +282,7 @@ export class Graph extends Subject imp this._applyEdgeOffsets(); this._applyStyle(); + this._resetLayout(); this._settings?.onMergeData?.(data); } @@ -287,6 +296,7 @@ export class Graph extends Subject imp this._applyEdgeOffsets(); this._applyStyle(); + this._resetLayout(); if (this._settings && this._settings.onRemoveData) { const removedData: IGraphObjectsIds = { @@ -603,6 +613,17 @@ export class Graph extends Subject imp return { nodeIds: [], edgeIds: removedEdgeIds }; } + private _resetLayout(): void { + if (!this._layout) { + this.clearPositions(); + return; + } + + const positions = this._layout.getPositions(this.getNodes()); + this.setNodePositions(positions); + this.notifyListeners(); + } + private _applyEdgeOffsets() { const graphEdges = this.getEdges(); const edgeOffsets = getEdgeOffsets(graphEdges); diff --git a/src/simulator/engine/d3-simulator-engine.ts b/src/simulator/engine/d3-simulator-engine.ts index 225fd67..f20346f 100644 --- a/src/simulator/engine/d3-simulator-engine.ts +++ b/src/simulator/engine/d3-simulator-engine.ts @@ -20,6 +20,7 @@ const DEFAULT_LINK_DISTANCE = 50; export enum D3SimulatorEngineEventType { SIMULATION_START = 'simulation-start', + SIMULATION_STOP = 'simulation-stop', SIMULATION_PROGRESS = 'simulation-progress', SIMULATION_END = 'simulation-end', SIMULATION_TICK = 'simulation-tick', @@ -282,10 +283,18 @@ export class D3SimulatorEngine extends Emitter { * This does not count as "stabilization" and won't emit any progress. */ activateSimulation() { - this.unfixNodes(); // If physics is disabled, the nodes get fixed in the callback from the initial setup (`simulation.on('end', () => {})`). + if (this._settings.isPhysicsEnabled) { + this.unfixNodes(); // If physics is disabled, the nodes get fixed in the callback from the initial setup (`simulation.on('end', () => {})`). + } else { + this.fixNodes(); + } this._simulation.alpha(this._settings.alpha.alpha).alphaTarget(this._settings.alpha.alphaTarget).restart(); } + stopSimulation() { + this._simulation.stop(); + } + setupData(data: ISimulationGraph) { this.clearData(); @@ -300,6 +309,10 @@ export class D3SimulatorEngine extends Emitter { mergeData(data: Partial) { this._initializeNewData(data); + if (!this._settings.isPhysicsEnabled) { + this.fixNodes(); + } + if (this._settings.isSimulatingOnDataUpdate) { this._updateSimulationData(); this.activateSimulation(); @@ -394,7 +407,10 @@ export class D3SimulatorEngine extends Emitter { const edgeIds = new Set(data.edgeIds); this._edges = this._edges.filter((edge) => !edgeIds.has(edge.id)); this._setNodeIndexByNodeId(); - this._updateSimulationData(); + if (this._settings.isSimulatingOnDataUpdate) { + this._updateSimulationData(); + this.activateSimulation(); + } } /** diff --git a/src/simulator/layout/layout.ts b/src/simulator/layout/layout.ts index defe2bc..e666e4f 100644 --- a/src/simulator/layout/layout.ts +++ b/src/simulator/layout/layout.ts @@ -1,29 +1,43 @@ import { IEdgeBase } from '../../models/edge'; import { INode, INodeBase, INodePosition } from '../../models/node'; -import { CircleLayout } from './layouts/circle'; +import { CircularLayout, ICircularLayoutOptions } from './layouts/circular'; +import { IForceLayoutOptions } from './layouts/force'; +import { GridLayout, IGridLayoutOptions } from './layouts/grid'; +import { HierarchicalLayout, IHierarchicalLayoutOptions } from './layouts/hierarchical'; -export enum layouts { - DEFAULT = 'default', - CIRCLE = 'circle', +export type LayoutType = 'circular' | 'force' | 'grid' | 'hierarchical'; + +export type LayoutSettingsMap = { + circular: ICircularLayoutOptions; + force: IForceLayoutOptions; + grid: IGridLayoutOptions; + hierarchical: IHierarchicalLayoutOptions; +}; + +export interface ILayoutSettings { + type: LayoutType; + options?: LayoutSettingsMap[LayoutType]; } export interface ILayout { - getPositions(nodes: INode[], width: number, height: number): INodePosition[]; + getPositions(nodes: INode[]): INodePosition[]; } -export class Layout implements ILayout { - private readonly _layout: ILayout | null; - - private layoutByLayoutName: Record | null> = { - [layouts.DEFAULT]: null, - [layouts.CIRCLE]: new CircleLayout(), - }; - - constructor(layoutName: string) { - this._layout = this.layoutByLayoutName[layoutName]; - } - - getPositions(nodes: INode[], width: number, height: number): INodePosition[] { - return this._layout === null ? [] : this._layout.getPositions(nodes, width, height); +export class LayoutFactory { + static create( + settings?: Partial, + ): ILayout | undefined { + switch (settings?.type) { + case 'circular': + return new CircularLayout(settings.options as ICircularLayoutOptions); + case 'force': + return undefined; + case 'grid': + return new GridLayout(settings.options as IGridLayoutOptions); + case 'hierarchical': + return new HierarchicalLayout(settings.options as IHierarchicalLayoutOptions); + default: + throw new Error('Incorrect layout type.'); + } } } diff --git a/src/simulator/layout/layouts/circle.ts b/src/simulator/layout/layouts/circle.ts deleted file mode 100644 index b601d78..0000000 --- a/src/simulator/layout/layouts/circle.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { IEdgeBase } from '../../../models/edge'; -import { INode, INodeBase, INodePosition } from '../../../models/node'; -import { ILayout } from '../layout'; - -export class CircleLayout implements ILayout { - getPositions(nodes: INode[], width: number, height: number): INodePosition[] { - return nodes.map((node, index) => { - return { id: node.id, x: width / 2, y: height - index * 10 }; - }); - } -} diff --git a/src/simulator/layout/layouts/circular.ts b/src/simulator/layout/layouts/circular.ts new file mode 100644 index 0000000..693d9a0 --- /dev/null +++ b/src/simulator/layout/layouts/circular.ts @@ -0,0 +1,37 @@ +import { IEdgeBase } from '../../../models/edge'; +import { INode, INodeBase, INodePosition } from '../../../models/node'; +import { ILayout } from '../layout'; + +export interface ICircularLayoutOptions { + radius?: number; + centerX?: number; + centerY?: number; +} + +export const DEFAULT_CIRCULAR_LAYOUT_OPTIONS: Required = { + radius: 100, + centerX: 0, + centerY: 0, +}; + +export class CircularLayout implements ILayout { + private _config: Required; + + constructor(options?: ICircularLayoutOptions) { + this._config = { ...DEFAULT_CIRCULAR_LAYOUT_OPTIONS, ...options }; + } + + getPositions(nodes: INode[]): INodePosition[] { + const angleStep = (2 * Math.PI) / nodes.length; + + const positions = nodes.map((node, index) => { + return { + id: node.id, + x: this._config.centerX + this._config.radius * Math.cos(angleStep * index), + y: this._config.centerY + this._config.radius * Math.sin(angleStep * index), + }; + }); + + return positions; + } +} diff --git a/src/simulator/layout/layouts/force.ts b/src/simulator/layout/layouts/force.ts new file mode 100644 index 0000000..29edc22 --- /dev/null +++ b/src/simulator/layout/layouts/force.ts @@ -0,0 +1,11 @@ +export interface IForceLayoutOptions { + centerX?: number; + centerY?: number; + nodeDistance?: number; +} + +export const DEFAULT_FORCE_LAYOUT_OPTIONS: Required = { + centerX: 0, + centerY: 0, + nodeDistance: 50, +}; diff --git a/src/simulator/layout/layouts/grid.ts b/src/simulator/layout/layouts/grid.ts new file mode 100644 index 0000000..e48470b --- /dev/null +++ b/src/simulator/layout/layouts/grid.ts @@ -0,0 +1,38 @@ +import { IEdgeBase } from '../../../models/edge'; +import { INode, INodeBase, INodePosition } from '../../../models/node'; +import { ILayout } from '../layout'; + +export interface IGridLayoutOptions { + rowGap?: number; + colGap?: number; +} + +export const DEFAULT_GRID_LAYOUT_OPTIONS: Required = { + rowGap: 50, + colGap: 50, +}; + +export class GridLayout implements ILayout { + private _config: Required; + + constructor(options?: IGridLayoutOptions) { + this._config = { ...DEFAULT_GRID_LAYOUT_OPTIONS, ...options }; + } + + getPositions(nodes: INode[]): INodePosition[] { + const rows = Math.ceil(Math.sqrt(nodes.length)); + const cols = Math.ceil(nodes.length / rows); + + const positions: INodePosition[] = []; + + for (let i = 0; i < nodes.length; i++) { + const row = Math.floor(i / cols); + const col = i % cols; + const x = col * this._config.colGap; + const y = row * this._config.rowGap; + positions.push({ id: nodes[i].getId(), x, y }); + } + + return positions; + } +} diff --git a/src/simulator/layout/layouts/hierarchical.ts b/src/simulator/layout/layouts/hierarchical.ts new file mode 100644 index 0000000..777c1f1 --- /dev/null +++ b/src/simulator/layout/layouts/hierarchical.ts @@ -0,0 +1,163 @@ +import { IEdge, IEdgeBase } from '../../../models/edge'; +import { INode, INodeBase, INodePosition } from '../../../models/node'; +import { ILayout } from '../layout'; + +export type HierarchicalLayoutOrientation = 'horizontal' | 'vertical'; + +export interface IHierarchicalLayoutOptions { + nodeGap?: number; + levelGap?: number; + treeGap?: number; + orientation?: HierarchicalLayoutOrientation; + reversed?: boolean; +} + +export const DEFAULT_HIERARCHICAL_LAYOUT_OPTIONS: Required = { + nodeGap: 50, + levelGap: 50, + treeGap: 100, + orientation: 'vertical', + reversed: false, +}; + +export class HierarchicalLayout implements ILayout { + private _config: Required; + + constructor(options?: IHierarchicalLayoutOptions) { + this._config = { ...DEFAULT_HIERARCHICAL_LAYOUT_OPTIONS, ...options }; + } + + getPositions(nodes: INode[]): INodePosition[] { + const components = this.getConnectedComponents(nodes); + const positions: INodePosition[] = new Array(nodes.length); + let maxX = 0; + let maxHeight = 0; + let counter = 0; + + for (let i = 0; i < components.length; i++) { + const levels: Map[]> = this.assignLevels(components[i]); + const maxLevelSize = Math.max(...Array.from(levels.values()).map((levelNodes) => levelNodes.length)); + + if (levels.size * this._config.levelGap > maxHeight) { + maxHeight = levels.size * this._config.levelGap; + } + + let offsetX = i === 0 ? 0 : this._config.treeGap + maxX; + + if (i > 0) { + offsetX += ((maxLevelSize - 1) * this._config.nodeGap) / 2; + } + + for (let j = 0; j < levels.size; j++) { + const y = j * this._config.levelGap; + const level = levels.get(j); + if (!level) { + continue; + } + + const width = level.length * this._config.nodeGap; + + for (let k = 0; k < level.length; k++) { + const node = level[k]; + const x = width / 2 - k * this._config.nodeGap + offsetX; + if (x > maxX) { + maxX = x; + } + + positions[counter++] = { + id: node.getId(), + x: this._config.orientation === 'horizontal' ? y : x, + y: this._config.orientation === 'horizontal' ? x : y, + }; + } + } + } + + if (this._config.reversed === true) { + positions.forEach((position) => { + if (this._config.orientation === 'horizontal' && position.x !== undefined) { + position.x = maxX - position.x; + } + if (this._config.orientation === 'vertical' && position.y !== undefined) { + position.y = maxHeight - position.y; + } + }); + } + + return positions; + } + + getConnectedComponents = (nodes: INode[]): INode[][] => { + const visited = new Set>(); + const components: INode[][] = []; + + for (let i = 0; i < nodes.length; i++) { + if (visited.has(nodes[i])) { + continue; + } + + const component: INode[] = []; + const queue: INode[] = [nodes[i]]; + visited.add(nodes[i]); + + while (queue.length > 0) { + const current = queue.pop(); + + if (current) { + component.push(current); + const neighbors = current.getAdjacentNodes(); + for (let j = 0; j < neighbors.length; j++) { + if (visited.has(neighbors[j])) { + continue; + } + + visited.add(neighbors[j]); + queue.push(neighbors[j]); + } + } + } + + components.push(component); + } + + return components; + }; + + assignLevels = (nodes: INode[]): Map[]> => { + const levels = new Map[]>(); + const visited = new Set>(); + + let root = nodes.filter((node) => this.getExternalInEdges(node).length === 0)[0]; + + if (!root) { + root = nodes.sort((a, b) => this.getExternalInEdges(a).length - this.getExternalInEdges(b).length)[0]; + } + + const queue: [INode, number][] = [[root, 0]]; + + for (const [node, level] of queue) { + if (visited.has(node)) { + continue; + } + + visited.add(node); + if (levels.has(level)) { + levels.get(level)?.push(node); + } else { + levels.set(level, [node]); + } + + const neighbors = node.getAdjacentNodes(); + + for (let i = 0; i < neighbors.length; i++) { + queue.push([neighbors[i], level + 1]); + } + } + + return levels; + }; + + getExternalInEdges = (node: INode): IEdge[] => { + return node.getInEdges().filter((edge) => edge.startNode.id !== edge.endNode.id); + }; +} diff --git a/src/simulator/shared.ts b/src/simulator/shared.ts index 7501367..b1190de 100644 --- a/src/simulator/shared.ts +++ b/src/simulator/shared.ts @@ -64,6 +64,7 @@ export interface ISimulator extends IEmitter { // Simulation handlers simulate(): void; activateSimulation(): void; + stopSimulation(): void; // Node handlers startDragNode(): void; diff --git a/src/simulator/types/main-thread-simulator.ts b/src/simulator/types/main-thread-simulator.ts index 1bbc36c..b560b33 100644 --- a/src/simulator/types/main-thread-simulator.ts +++ b/src/simulator/types/main-thread-simulator.ts @@ -73,6 +73,10 @@ export class MainThreadSimulator extends Emitter implements ISi this._simulator.activateSimulation(); } + stopSimulation() { + this._simulator.stopSimulation(); + } + startDragNode() { this._simulator.startDragNode(); } diff --git a/src/simulator/types/web-worker-simulator/message/worker-input.ts b/src/simulator/types/web-worker-simulator/message/worker-input.ts index 5d28a74..c252d4a 100644 --- a/src/simulator/types/web-worker-simulator/message/worker-input.ts +++ b/src/simulator/types/web-worker-simulator/message/worker-input.ts @@ -19,6 +19,7 @@ export enum WorkerInputType { Simulate = 'Simulate', ActivateSimulation = 'Activate Simulation', UpdateSimulation = 'Update Simulation', + StopSimulation = 'Stop Simulation', // Node dragging message types StartDragNode = 'Start Drag Node', @@ -77,6 +78,8 @@ type IWorkerInputSimulatePayload = IWorkerPayload; type IWorkerInputActivateSimulationPayload = IWorkerPayload; +type IWorkerInputStopSimulationPayload = IWorkerPayload; + type IWorkerInputUpdateSimulationPayload = IWorkerPayload< WorkerInputType.UpdateSimulation, { @@ -121,6 +124,7 @@ export type IWorkerInputPayload = | IWorkerInputClearDataPayload | IWorkerInputSimulatePayload | IWorkerInputActivateSimulationPayload + | IWorkerInputStopSimulationPayload | IWorkerInputUpdateSimulationPayload | IWorkerInputStartDragNodePayload | IWorkerInputDragNodePayload diff --git a/src/simulator/types/web-worker-simulator/simulator.worker.ts b/src/simulator/types/web-worker-simulator/simulator.worker.ts index d0d76a2..f07da1d 100644 --- a/src/simulator/types/web-worker-simulator/simulator.worker.ts +++ b/src/simulator/types/web-worker-simulator/simulator.worker.ts @@ -41,6 +41,11 @@ addEventListener('message', ({ data }: MessageEvent) => { break; } + case WorkerInputType.StopSimulation: { + simulator.stopSimulation(); + break; + } + case WorkerInputType.SetupData: { simulator.setupData(data.data); break; diff --git a/src/simulator/types/web-worker-simulator/web-worker-simulator.ts b/src/simulator/types/web-worker-simulator/web-worker-simulator.ts index 02f35ea..005d043 100644 --- a/src/simulator/types/web-worker-simulator/web-worker-simulator.ts +++ b/src/simulator/types/web-worker-simulator/web-worker-simulator.ts @@ -104,6 +104,10 @@ export class WebWorkerSimulator extends Emitter implements ISim this.emitToWorker({ type: WorkerInputType.ActivateSimulation }); } + stopSimulation() { + this.emitToWorker({ type: WorkerInputType.StopSimulation }); + } + updateSimulation(nodes: ISimulationNode[], edges: ISimulationEdge[]) { this.emitToWorker({ type: WorkerInputType.UpdateSimulation, data: { nodes, edges } }); } diff --git a/src/views/orb-view.ts b/src/views/orb-view.ts index 3b5711a..16ea79d 100644 --- a/src/views/orb-view.ts +++ b/src/views/orb-view.ts @@ -13,7 +13,12 @@ import { INode, INodeBase, isNode } from '../models/node'; import { IEdge, IEdgeBase, isEdge } from '../models/edge'; import { IOrbView } from './shared'; import { DefaultEventStrategy, IEventStrategy, IEventStrategySettings } from '../models/strategy'; -import { ID3SimulatorEngineSettings } from '../simulator/engine/d3-simulator-engine'; +import { + DEFAULT_SETTINGS, + ID3SimulatorEngineSettings, + ID3SimulatorEngineSettingsCentering, + ID3SimulatorEngineSettingsLinks, +} from '../simulator/engine/d3-simulator-engine'; import { copyObject } from '../utils/object.utils'; import { OrbEmitter, OrbEventType } from '../events'; import { IRenderer, RenderEventType, IRendererSettingsInit, IRendererSettings } from '../renderer/shared'; @@ -22,6 +27,8 @@ import { SimulatorEventType } from '../simulator/shared'; import { getDefaultGraphStyle } from '../models/style'; import { isBoolean } from '../utils/type.utils'; import { IObserver, IObserverDataPayload } from '../utils/observer.utils'; +import { ILayoutSettings, LayoutFactory } from '../simulator/layout/layout'; +import { DEFAULT_FORCE_LAYOUT_OPTIONS } from '../simulator/layout/layouts/force'; export interface IGraphInteractionSettings { isDragEnabled: boolean; @@ -34,6 +41,7 @@ export interface IOrbViewSettings { render: Partial; strategy: Partial; interaction: Partial; + layout: Partial; zoomFitTransitionMs: number; isOutOfBoundsDragEnabled: boolean; areCoordinatesRounded: boolean; @@ -72,6 +80,10 @@ export class OrbView implements IOrbVi isPhysicsEnabled: false, ...settings?.simulation, }, + layout: { + type: 'force', + ...settings?.layout, + }, render: { ...settings?.render, }, @@ -149,36 +161,30 @@ export class OrbView implements IOrbVi .on('dblclick.zoom', this.mouseDoubleClicked); this._simulator = SimulatorFactory.getSimulator(); - this._simulator.on(SimulatorEventType.SIMULATION_START, () => { - // this._isSimulating = true; - this._simulationStartedAt = Date.now(); - this._events.emit(OrbEventType.SIMULATION_START, undefined); - }); - this._simulator.on(SimulatorEventType.SIMULATION_PROGRESS, (data) => { - this._graph.setNodePositions(data.nodes); - this._events.emit(OrbEventType.SIMULATION_STEP, { progress: data.progress }); - this.render(); - }); - this._simulator.on(SimulatorEventType.SIMULATION_END, (data) => { - this._graph.setNodePositions(data.nodes); - this.render(); - // this._isSimulating = false; - this._onSimulationEnd?.(); - this._onSimulationEnd = undefined; - this._events.emit(OrbEventType.SIMULATION_END, { durationMs: Date.now() - this._simulationStartedAt }); - }); - this._simulator.on(SimulatorEventType.SIMULATION_STEP, (data) => { - this._graph.setNodePositions(data.nodes); - this.render(); - }); - this._simulator.on(SimulatorEventType.NODE_DRAG, (data) => { - this._graph.setNodePositions(data.nodes); - this.render(); - }); - this._simulator.on(SimulatorEventType.SETTINGS_UPDATE, (data) => { - this._settings.simulation = data.settings; - }); + if (this._settings.layout.type === 'force') { + this._enableSimulation(); + } + + if (this._settings.layout.options) { + const _options = { + ...DEFAULT_FORCE_LAYOUT_OPTIONS, + ...this._settings.layout.options, + }; + + this._settings.simulation.centering = { + ...(DEFAULT_SETTINGS.centering as Required), + ...this._settings.simulation.centering, + x: _options.centerX, + y: _options.centerY, + }; + + this._settings.simulation.links = { + ...(DEFAULT_SETTINGS.links as Required), + ...this._settings.simulation.links, + distance: _options.nodeDistance, + }; + } this._simulator.setSettings(this._settings.simulation); // TODO(dlozic): Optimize crud operations here. @@ -193,6 +199,9 @@ export class OrbView implements IOrbVi const nodePositions = this._graph.getNodePositions(); const edgePositions = this._graph.getEdgePositions(); // this._onSimulationEnd = onRendered; + if (this._settings.layout) { + this._graph.setLayout(LayoutFactory.create(this._settings.layout)); + } this._simulator.setupData({ nodes: nodePositions, edges: edgePositions }); }, onMergeData: (data) => { @@ -203,10 +212,12 @@ export class OrbView implements IOrbVi this._assignPositions(this._graph.getNodes(nodeFilter)); - const nodePositions = this._graph.getNodePositions(nodeFilter); - const edgePositions = this._graph.getEdgePositions(edgeFilter); + if (this._settings.layout.type === 'force') { + const nodePositions = this._graph.getNodePositions(nodeFilter); + const edgePositions = this._graph.getEdgePositions(edgeFilter); - this._simulator.mergeData({ nodes: nodePositions, edges: edgePositions }); + this._simulator.mergeData({ nodes: nodePositions, edges: edgePositions }); + } }, onRemoveData: (data) => { this._simulator.deleteData(data); @@ -244,6 +255,37 @@ export class OrbView implements IOrbVi this._settings.render = this._renderer.getSettings(); } + if (settings.layout) { + const shouldRecenter = this._settings.layout.type !== settings.layout.type; + this._settings.layout = { + ...this._settings.layout, + ...settings.layout, + }; + + this._graph.setLayout(LayoutFactory.create(this._settings.layout)); + + const nodePositions = this._graph.getNodePositions(); + const edgePositions = this._graph.getEdgePositions(); + + this._simulator.setupData({ nodes: nodePositions, edges: edgePositions }); + + if (this._settings.layout.type === 'force') { + this._enableSimulation(); + this._simulator.releaseNodes(); + } else { + this._disableSimulation(); + this._simulator.clearData(); + } + + if (shouldRecenter) { + this._simulator.once(SimulatorEventType.SIMULATION_END, () => { + this.recenter(); + }); + } + + this.render(); + } + if (settings.strategy) { if (isBoolean(settings.strategy.isDefaultHoverEnabled)) { this._settings.strategy.isDefaultHoverEnabled = settings.strategy.isDefaultHoverEnabled; @@ -604,6 +646,74 @@ export class OrbView implements IOrbVi this.render(); }; + private _enableSimulation = () => { + this._simulator.on(SimulatorEventType.SIMULATION_START, () => { + // this._isSimulating = true; + this._simulationStartedAt = Date.now(); + this._events.emit(OrbEventType.SIMULATION_START, undefined); + }); + this._simulator.on(SimulatorEventType.SIMULATION_PROGRESS, (data) => { + this._graph.setNodePositions(data.nodes); + this._events.emit(OrbEventType.SIMULATION_STEP, { progress: data.progress }); + this.render(); + }); + this._simulator.on(SimulatorEventType.SIMULATION_END, (data) => { + this._graph.setNodePositions(data.nodes); + this.render(); + // this._isSimulating = false; + this._onSimulationEnd?.(); + this._onSimulationEnd = undefined; + this._events.emit(OrbEventType.SIMULATION_END, { durationMs: Date.now() - this._simulationStartedAt }); + }); + this._simulator.on(SimulatorEventType.SIMULATION_STEP, (data) => { + this._graph.setNodePositions(data.nodes); + this.render(); + }); + this._simulator.on(SimulatorEventType.NODE_DRAG, (data) => { + this._graph.setNodePositions(data.nodes); + this.render(); + }); + this._simulator.on(SimulatorEventType.SETTINGS_UPDATE, (data) => { + this._settings.simulation = data.settings; + }); + + this._simulator.activateSimulation(); + }; + + private _disableSimulation = () => { + this._simulator.off(SimulatorEventType.SIMULATION_START, () => { + // this._isSimulating = true; + this._simulationStartedAt = Date.now(); + this._events.emit(OrbEventType.SIMULATION_START, undefined); + }); + this._simulator.off(SimulatorEventType.SIMULATION_PROGRESS, (data) => { + this._graph.setNodePositions(data.nodes); + this._events.emit(OrbEventType.SIMULATION_STEP, { progress: data.progress }); + this.render(); + }); + this._simulator.off(SimulatorEventType.SIMULATION_END, (data) => { + this._graph.setNodePositions(data.nodes); + this.render(); + // this._isSimulating = false; + this._onSimulationEnd?.(); + this._onSimulationEnd = undefined; + this._events.emit(OrbEventType.SIMULATION_END, { durationMs: Date.now() - this._simulationStartedAt }); + }); + this._simulator.off(SimulatorEventType.SIMULATION_STEP, (data) => { + this._graph.setNodePositions(data.nodes); + this.render(); + }); + this._simulator.off(SimulatorEventType.NODE_DRAG, (data) => { + this._graph.setNodePositions(data.nodes); + this.render(); + }); + this._simulator.off(SimulatorEventType.SETTINGS_UPDATE, (data) => { + this._settings.simulation = data.settings; + }); + + this._simulator.stopSimulation(); + }; + // TODO: Do we keep these fixNodes() { this._simulator.fixNodes(); From 572be3fdcc5ede50d37f5f540ff0d6f2fef42a75 Mon Sep 17 00:00:00 2001 From: Oleksandr Ichenskyi <55350107+AlexIchenskiy@users.noreply.github.com> Date: Thu, 5 Mar 2026 10:47:35 +0100 Subject: [PATCH 22/22] Fix: Change layout engine logic (#108) * Fix: Change layout engine logic * New: Add simulation cancellation logic * Chore: Remove leftover code * Fix: Hierarchical layout recenter logic * Chore: Refactor package versions and code logic * Fix: Refactor function types --- .eslintrc | 4 +- docs/view-default.md | 145 +- package-lock.json | 3906 +++++++++++------ package.json | 18 +- src/models/graph.ts | 21 - src/models/interaction.ts | 67 + src/models/strategy.ts | 122 +- src/renderer/canvas/canvas-renderer.ts | 18 +- src/renderer/shared.ts | 7 +- src/simulator/engine/d3-simulator-engine.ts | 728 --- .../engine/engines/base-layout-engine.ts | 61 + .../engines/dynamic/force-layout-engine.ts | 506 +++ .../engines/static/circular-layout-engine.ts | 49 + .../engines/static/grid-layout-engine.ts | 53 + .../static/hierarchical-layout-engine.ts | 220 + .../engines/static/static-layout-engine.ts | 233 + src/simulator/engine/factory.ts | 29 + src/simulator/engine/shared.ts | 203 + src/simulator/factory.ts | 9 +- src/simulator/index.ts | 2 + src/simulator/layout/layout.ts | 43 - src/simulator/layout/layouts/circular.ts | 37 - src/simulator/layout/layouts/force.ts | 11 - src/simulator/layout/layouts/grid.ts | 38 - src/simulator/layout/layouts/hierarchical.ts | 163 - src/simulator/shared.ts | 9 +- src/simulator/types/main-thread-simulator.ts | 107 +- .../message/worker-input.ts | 9 +- .../message/worker-output.ts | 4 +- .../web-worker-simulator/simulator.worker.ts | 150 +- .../web-worker-simulator.ts | 25 +- src/utils/function.utils.ts | 32 +- src/utils/graph.utils.ts | 145 + src/utils/object.utils.ts | 2 +- src/views/orb-map-view.ts | 12 +- src/views/orb-view.ts | 190 +- src/views/shared.ts | 2 + 37 files changed, 4404 insertions(+), 2976 deletions(-) create mode 100644 src/models/interaction.ts delete mode 100644 src/simulator/engine/d3-simulator-engine.ts create mode 100644 src/simulator/engine/engines/base-layout-engine.ts create mode 100644 src/simulator/engine/engines/dynamic/force-layout-engine.ts create mode 100644 src/simulator/engine/engines/static/circular-layout-engine.ts create mode 100644 src/simulator/engine/engines/static/grid-layout-engine.ts create mode 100644 src/simulator/engine/engines/static/hierarchical-layout-engine.ts create mode 100644 src/simulator/engine/engines/static/static-layout-engine.ts create mode 100644 src/simulator/engine/factory.ts create mode 100644 src/simulator/engine/shared.ts delete mode 100644 src/simulator/layout/layout.ts delete mode 100644 src/simulator/layout/layouts/circular.ts delete mode 100644 src/simulator/layout/layouts/force.ts delete mode 100644 src/simulator/layout/layouts/grid.ts delete mode 100644 src/simulator/layout/layouts/hierarchical.ts create mode 100644 src/utils/graph.utils.ts diff --git a/.eslintrc b/.eslintrc index a2f3666..0f31eb6 100644 --- a/.eslintrc +++ b/.eslintrc @@ -33,7 +33,8 @@ { "singleQuote": true, "trailingComma": "all", - "printWidth": 120 + "printWidth": 120, + "endOfLine": "auto" } ], "brace-style": ["error", "1tbs"], @@ -52,6 +53,7 @@ ], "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/no-unsafe-function-type": "off", "@typescript-eslint/ban-ts-comment": "off", "@typescript-eslint/ban-types": "off", "jest/no-standalone-expect": "off", diff --git a/docs/view-default.md b/docs/view-default.md index 56e14d1..34b7659 100644 --- a/docs/view-default.md +++ b/docs/view-default.md @@ -109,42 +109,49 @@ The default settings that `OrbView` uses is: ```typescript const defaultSettings = { - simulation: { - isPhysicsEnabled: false; - alpha: { - alpha: 1, - alphaMin: 0.001, - alphaDecay: 0.0228, - alphaTarget: 0.1, - }, - centering: { - x: 0, - y: 0, - strength: 1, - }, - collision: { - radius: 15, - strength: 1, - iterations: 1, - }, - links: { - distance: 30, - iterations: 1, - }, - manyBody: { - strength: -100, - theta: 0.9, - distanceMin: 0, - distanceMax: 3000, - }, - positioning: { - forceX: { - x: 0, - strength: 0.1, + layout: { + type: 'force', + options: { + isPhysicsEnabled: false, + isSimulatingOnDataUpdate: true, + isSimulatingOnSettingsUpdate: true, + isSimulatingOnUnstick: true, + alpha: { + alpha: 1, + alphaMin: 0.001, + alphaDecay: 0.0228, + alphaTarget: 0, }, - forceY: { + centering: { + x: 0, y: 0, - strength: 0.1, + strength: 1, + }, + collision: { + radius: 15, + strength: 1, + iterations: 1, + }, + links: { + distance: DEFAULT_LINK_DISTANCE, + strength: 1, + iterations: 1, + }, + manyBody: { + strength: -100, + theta: 0.9, + distanceMin: 0, + distanceMax: getManyBodyMaxDistance(DEFAULT_LINK_DISTANCE), + }, + positioning: { + forceX: { + x: 0, + strength: 0.1, + }, + forceY: { + y: 0, + strength: 0.1, + }, }, }, }, @@ -168,13 +175,13 @@ const defaultSettings = { isDefaultHoverEnabled: true, }, interaction: { - isDragEnabled: true; - isZoomEnabled: true; + isDragEnabled: true, + isZoomEnabled: true, }, zoomFitTransitionMs: 200, isOutOfBoundsDragEnabled: false, areCoordinatesRounded: true, - areCollapsedContainerDimensionsAllowed: false; + areCollapsedContainerDimensionsAllowed: false, } ``` @@ -189,13 +196,6 @@ There are two basic ways to use the `OrbView` API based on the node positions: - **Fixed coordinates** - You provide node coordinates through the `getPosition()` callback function. -#### Simulated node positions - -In this mode, the `OrbView` arranges node positions by internally calculating their -coordinates using the [D3.js](https://d3js.org/) library, or more specifically, -[`d3-force`](https://github.com/d3/d3-force). This method is applied by default - you don't -need to initialize Orb with any additional configuration. - ![](./assets/view-default-simulated.png) ```typescript @@ -278,14 +278,20 @@ Here you can use your original properties to indicate which ones represent your ### Property `layout` -If you want to use one of the predefined layouts (hierarchical (tree), grid, circular...) you can specify -the optional property `layout`. Simulation physics are ignored when a layout is applied. There is no layout -applied by default. +The optional property `layout` controls how graph nodes are positioned. You can choose between +a physics-based force layout or one of the predefined static layouts (hierarchical (tree), grid, +circular). The default layout is `force`. #### Property `type` You can specify the desired layout using the `type` property that can have one of the following values: +- `force` - fine-grained [D3.js](https://d3js.org/) simulation engine settings. They include `isPhysicsEnabled`, `alpha`, +`centering`, `collision`, `links`, `manyBody`, and `positioning`. You can use `isPhysicsEnabled` +to enable or disable physics. You can read more about the other settings on the official +[`d3-force docs`](https://github.com/d3/d3-force). This may be condensed into fewer, more abstract +settings in the future + - `hierarchical` - a tree-like layout style that tries to portrait graph nodes in a hierarchy - `circular` - arranges the nodes of the graph in a circle @@ -304,6 +310,43 @@ Each layout type has its own option list you can tweak in order to change the la - `circular` - `radius` - Radius of the circle in relativa units. +- `grid` + - `rowGap` - The gap between rows of nodes. Default `50`. + - `colGap` - The gap between columns of nodes. Default `50`. + +- `force` + - `isPhysicsEnabled` - Enables or disables continuous physics simulation. Disabled by default (`false`). + - `isSimulatingOnDataUpdate` - Whether to run simulation when graph data is updated. Enabled by default (`true`). + - `isSimulatingOnSettingsUpdate` - Whether to re-run simulation when settings are updated. Enabled by default (`true`). + - `isSimulatingOnUnstick` - Whether to re-run simulation when a node is unstuck. Enabled by default (`true`). + - `alpha` - Fine-grained control over the simulation's annealing process. + - `alpha` - Current alpha value. Default `1`. + - `alphaMin` - Minimum alpha threshold below which simulation stops. Default `0.001`. + - `alphaDecay` - Rate at which alpha decreases over time. Default `0.0228`. + - `alphaTarget` - Target alpha the simulation converges toward. Default `0`. + - `centering` - Centers the graph around a point. + - `x` - X coordinate of the center. Default `0`. + - `y` - Y coordinate of the center. Default `0`. + - `strength` - Strength of the centering force. Default `1`. + - `collision` - Prevents nodes from overlapping. + - `radius` - Collision radius per node. Default `15`. + - `strength` - Strength of the collision force. Default `1`. + - `iterations` - Number of iterations per tick. Default `1`. + - `links` - Controls the length and rigidity of edges. + - `distance` - Desired distance between linked nodes. + - `strength` - Strength of the link force. Default `1`. + - `iterations` - Number of iterations per tick. Default `1`. + - `manyBody` - Simulates attraction or repulsion between all nodes. + - `strength` - Negative values repel, positive attract. Default `-100`. + - `theta` - Barnes-Hut approximation parameter. Default `0.9`. + - `distanceMin` - Minimum distance between nodes. Default `0`. + - `distanceMax` - Maximum distance over which force applies. + - `positioning` - Applies independent forces along each axis. + - `forceX.x` - Target X position. Default `0`. + - `forceX.strength` - Strength of the X positioning force. Default `0.1`. + - `forceY.y` - Target Y position. Default `0`. + - `forceY.strength` - Strength of the Y positioning force. Default `0.1`. + ### Property `render` Optional property `render` has several rendering options that you can tweak. Read more about them @@ -398,14 +441,6 @@ These properties provide a straightforward way to enable or disable dragging and orb.setSettings({ interaction: { isDragEnabled: false, isZoomEnabled: true } }); ``` -### Property `simulation` - -Fine-grained D3 simulation engine settings. They include `isPhysicsEnabled`, `alpha`, -`centering`, `collision`, `links`, `manyBody`, and `positioning`. You can use `isPhysicsEnabled` -to enable or disable physics. You can read more about the other settings on the official -[`d3-force docs`](https://github.com/d3/d3-force). This may be condensed into fewer, more abstract -settings in the future. - ### Property `zoomFitTransitionMs` Use this property to adjust the transition time when re-centering the graph. Defaults to `200ms`. diff --git a/package-lock.json b/package-lock.json index aacbcc3..ac11942 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,27 +31,27 @@ "@types/jest": "29.5.12", "@types/leaflet": "1.7.9", "@types/resize-observer-browser": "^0.1.7", - "@typescript-eslint/eslint-plugin": "5.24.0", - "@typescript-eslint/parser": "5.24.0", + "@typescript-eslint/eslint-plugin": "8.56.1", + "@typescript-eslint/parser": "8.56.1", "conventional-changelog-eslint": "3.0.9", "copy-webpack-plugin": "^11.0.0", - "eslint": "8.15.0", + "eslint": "8.57.0", "eslint-config-google": "0.14.0", "eslint-config-prettier": "8.5.0", - "eslint-plugin-jest": "26.2.2", - "eslint-plugin-prettier": "4.0.0", + "eslint-plugin-jest": "29.15.0", + "eslint-plugin-prettier": "5.5.5", "http-server": "^14.1.1", "husky": "^8.0.1", "jest": "29.7.0", - "prettier": "^2.7.1", + "prettier": "3.8.1", "semantic-release": "19.0.3", "ts-jest": "29.1.2", "ts-loader": "^9.3.1", - "ts-node": "10.8.0", - "typescript": "4.6.3", + "ts-node": "10.9.2", + "typescript": "5.9.3", "webpack": "^5.73.0", "webpack-cli": "^4.10.0", - "webpack-dev-server": "^4.9.3" + "webpack-dev-server": "5.2.0" }, "engines": { "node": ">=18.0.0" @@ -71,89 +71,20 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/compat-data": { "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", @@ -356,19 +287,21 @@ } }, "node_modules/@babel/helper-string-parser": { - "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==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "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==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -383,109 +316,28 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", - "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", - "dev": true, - "dependencies": { - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@babel/types": "^7.29.0" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", - "dev": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -671,14 +523,15 @@ } }, "node_modules/@babel/template": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", - "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -715,14 +568,14 @@ } }, "node_modules/@babel/types": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -880,15 +733,6 @@ "node": ">=v14" } }, - "node_modules/@commitlint/load/node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/@commitlint/load/node_modules/cosmiconfig": { "version": "8.1.3", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz", @@ -907,62 +751,6 @@ "url": "https://github.com/sponsors/d-fischer" } }, - "node_modules/@commitlint/load/node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/@commitlint/load/node_modules/typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, "node_modules/@commitlint/message": { "version": "17.0.0", "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-17.0.0.tgz", @@ -1098,16 +886,46 @@ "node": ">=10.0.0" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -1116,13 +934,17 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1138,36 +960,65 @@ "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==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" @@ -1199,10 +1050,11 @@ } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -1553,17 +1405,14 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", - "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, "node_modules/@jridgewell/resolve-uri": { @@ -1575,46 +1424,471 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=6.0.0" + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" } }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", - "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", + "node_modules/@jsonjoy.com/buffers": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz", + "integrity": "sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/codegen": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz", + "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==", "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-core": { + "version": "4.56.11", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.56.11.tgz", + "integrity": "sha512-wThHjzUp01ImIjfCwhs+UnFkeGPFAymwLEkOtenHewaKe2pTP12p6r1UuwikA9NEvNf9Vlck92r8fb8n/MWM5w==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jsonjoy.com/fs-node-builtins": "4.56.11", + "@jsonjoy.com/fs-node-utils": "4.56.11", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "node_modules/@jsonjoy.com/fs-fsa": { + "version": "4.56.11", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.56.11.tgz", + "integrity": "sha512-ZYlF3XbMayyp97xEN8ZvYutU99PCHjM64mMZvnCseXkCJXJDVLAwlF8Q/7q/xiWQRsv3pQBj1WXHd9eEyYcaCQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.56.11", + "@jsonjoy.com/fs-node-builtins": "4.56.11", + "@jsonjoy.com/fs-node-utils": "4.56.11", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "node_modules/@jsonjoy.com/fs-node": { + "version": "4.56.11", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.56.11.tgz", + "integrity": "sha512-D65YrnP6wRuZyEWoSFnBJSr5zARVpVBGctnhie4rCsMuGXNzX7IHKaOt85/Aj7SSoG1N2+/xlNjWmkLvZ2H3Tg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.56.11", + "@jsonjoy.com/fs-node-builtins": "4.56.11", + "@jsonjoy.com/fs-node-utils": "4.56.11", + "@jsonjoy.com/fs-print": "4.56.11", + "@jsonjoy.com/fs-snapshot": "4.56.11", + "glob-to-regex.js": "^1.0.0", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-builtins": { + "version": "4.56.11", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.56.11.tgz", + "integrity": "sha512-CNmt3a0zMCIhniFLXtzPWuUxXFU+U+2VyQiIrgt/rRVeEJNrMQUABaRbVxR0Ouw1LyR9RjaEkPM6nYpED+y43A==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-to-fsa": { + "version": "4.56.11", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.56.11.tgz", + "integrity": "sha512-5OzGdvJDgZVo+xXWEYo72u81zpOWlxlbG4d4nL+hSiW+LKlua/dldNgPrpWxtvhgyntmdFQad2UTxFyGjJAGhA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jsonjoy.com/fs-fsa": "4.56.11", + "@jsonjoy.com/fs-node-builtins": "4.56.11", + "@jsonjoy.com/fs-node-utils": "4.56.11" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-utils": { + "version": "4.56.11", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.56.11.tgz", + "integrity": "sha512-JADOZFDA3wRfsuxkT0+MYc4F9hJO2PYDaY66kRTG6NqGX3+bqmKu66YFYAbII/tEmQWPZeHoClUB23rtQM9UPg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.56.11" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-print": { + "version": "4.56.11", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.56.11.tgz", + "integrity": "sha512-rnaKRgCRIn8JGTjxhS0JPE38YM3Pj/H7SW4/tglhIPbfKEkky7dpPayNKV2qy25SZSL15oFVgH/62dMZ/z7cyA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-utils": "4.56.11", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot": { + "version": "4.56.11", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.56.11.tgz", + "integrity": "sha512-IIldPX+cIRQuUol9fQzSS3hqyECxVpYMJQMqdU3dCKZFRzEl1rkIkw4P6y7Oh493sI7YdxZlKr/yWdzEWZ1wGQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^17.65.0", + "@jsonjoy.com/fs-node-utils": "4.56.11", + "@jsonjoy.com/json-pack": "^17.65.0", + "@jsonjoy.com/util": "^17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.67.0.tgz", + "integrity": "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/codegen": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.67.0.tgz", + "integrity": "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-17.67.0.tgz", + "integrity": "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "17.67.0", + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0", + "@jsonjoy.com/json-pointer": "17.67.0", + "@jsonjoy.com/util": "17.67.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pointer": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-17.67.0.tgz", + "integrity": "sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/util": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.67.0.tgz", + "integrity": "sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", + "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "^1.1.2", + "@jsonjoy.com/buffers": "^1.2.0", + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/json-pointer": "^1.0.2", + "@jsonjoy.com/util": "^1.9.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pointer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", + "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/util": "^1.9.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", + "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^1.0.0", + "@jsonjoy.com/codegen": "^1.0.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" } }, "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", - "dev": true + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true, + "license": "MIT" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", @@ -1652,28 +1926,27 @@ } }, "node_modules/@octokit/auth-token": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.0.tgz", - "integrity": "sha512-MDNFUBcJIptB9At7HiV7VCvU3NcL4GnfCQaP8C5lrxWrRPMJBnemYtehaKSOlaM7AYxeRyj9etenu8LVpSpVaQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz", + "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==", "dev": true, - "dependencies": { - "@octokit/types": "^6.0.3" - }, + "license": "MIT", "engines": { "node": ">= 14" } }, "node_modules/@octokit/core": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.0.4.tgz", - "integrity": "sha512-sUpR/hc4Gc7K34o60bWC7WUH6Q7T6ftZ2dUmepSyJr9PRF76/qqkWjE2SOEzCqLA5W83SaISymwKtxks+96hPQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", + "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/auth-token": "^3.0.0", "@octokit/graphql": "^5.0.0", "@octokit/request": "^6.0.0", "@octokit/request-error": "^3.0.0", - "@octokit/types": "^6.0.3", + "@octokit/types": "^9.0.0", "before-after-hook": "^2.2.0", "universal-user-agent": "^6.0.0" }, @@ -1682,12 +1955,13 @@ } }, "node_modules/@octokit/endpoint": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.0.tgz", - "integrity": "sha512-Kz/mIkOTjs9rV50hf/JK9pIDl4aGwAtT8pry6Rpy+hVXkAPhXanNQRxMoq6AeRgDCZR6t/A1zKniY2V1YhrzlQ==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz", + "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==", "dev": true, + "license": "MIT", "dependencies": { - "@octokit/types": "^6.0.3", + "@octokit/types": "^9.0.0", "is-plain-object": "^5.0.0", "universal-user-agent": "^6.0.0" }, @@ -1696,13 +1970,14 @@ } }, "node_modules/@octokit/graphql": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.0.tgz", - "integrity": "sha512-1ZZ8tX4lUEcLPvHagfIVu5S2xpHYXAmgN0+95eAOPoaVPzCfUXJtA5vASafcpWcO86ze0Pzn30TAx72aB2aguQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", + "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/request": "^6.0.0", - "@octokit/types": "^6.0.3", + "@octokit/types": "^9.0.0", "universal-user-agent": "^6.0.0" }, "engines": { @@ -1710,18 +1985,21 @@ } }, "node_modules/@octokit/openapi-types": { - "version": "12.10.1", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.10.1.tgz", - "integrity": "sha512-P+SukKanjFY0ZhsK6wSVnQmxTP2eVPPE8OPSNuxaMYtgVzwJZgfGdwlYjf4RlRU4vLEw4ts2fsE2icG4nZ5ddQ==", - "dev": true + "version": "18.1.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz", + "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==", + "dev": true, + "license": "MIT" }, "node_modules/@octokit/plugin-paginate-rest": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-3.0.0.tgz", - "integrity": "sha512-fvw0Q5IXnn60D32sKeLIxgXCEZ7BTSAjJd8cFAE6QU5qUp0xo7LjFUjjX1J5D7HgN355CN4EXE4+Q1/96JaNUA==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz", + "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==", "dev": true, + "license": "MIT", "dependencies": { - "@octokit/types": "^6.39.0" + "@octokit/tsconfig": "^1.0.2", + "@octokit/types": "^9.2.3" }, "engines": { "node": ">= 14" @@ -1730,40 +2008,50 @@ "@octokit/core": ">=4" } }, - "node_modules/@octokit/plugin-request-log": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", - "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "node_modules/@octokit/plugin-retry": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-4.1.6.tgz", + "integrity": "sha512-obkYzIgEC75r8+9Pnfiiqy3y/x1bc3QLE5B7qvv9wi9Kj0R5tGQFC6QMBg1154WQ9lAVypuQDGyp3hNpp15gQQ==", "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^9.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 14" + }, "peerDependencies": { "@octokit/core": ">=3" } }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.1.2.tgz", - "integrity": "sha512-sAfSKtLHNq0UQ2iFuI41I6m5SK6bnKFRJ5kUjDRVbmQXiRVi4aQiIcgG4cM7bt+bhSiWL4HwnTxDkWFlKeKClA==", + "node_modules/@octokit/plugin-throttling": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-5.2.3.tgz", + "integrity": "sha512-C9CFg9mrf6cugneKiaI841iG8DOv6P5XXkjmiNNut+swePxQ7RWEdAZRp5rJoE1hjsIqiYcKa/ZkOQ+ujPI39Q==", "dev": true, + "license": "MIT", "dependencies": { - "@octokit/types": "^6.40.0", - "deprecation": "^2.3.1" + "@octokit/types": "^9.0.0", + "bottleneck": "^2.15.3" }, "engines": { "node": ">= 14" }, "peerDependencies": { - "@octokit/core": ">=3" + "@octokit/core": "^4.0.0" } }, "node_modules/@octokit/request": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.0.tgz", - "integrity": "sha512-7IAmHnaezZrgUqtRShMlByJK33MT9ZDnMRgZjnRrRV9a/jzzFwKGz0vxhFU6i7VMLraYcQ1qmcAOin37Kryq+Q==", + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz", + "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/endpoint": "^7.0.0", "@octokit/request-error": "^3.0.0", - "@octokit/types": "^6.16.1", + "@octokit/types": "^9.0.0", "is-plain-object": "^5.0.0", "node-fetch": "^2.6.7", "universal-user-agent": "^6.0.0" @@ -1773,12 +2061,13 @@ } }, "node_modules/@octokit/request-error": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.0.tgz", - "integrity": "sha512-WBtpzm9lR8z4IHIMtOqr6XwfkGvMOOILNLxsWvDwtzm/n7f5AWuqJTXQXdDtOvPfTDrH4TPhEvW2qMlR4JFA2w==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz", + "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", "dev": true, + "license": "MIT", "dependencies": { - "@octokit/types": "^6.0.3", + "@octokit/types": "^9.0.0", "deprecation": "^2.0.0", "once": "^1.4.0" }, @@ -1786,28 +2075,34 @@ "node": ">= 14" } }, - "node_modules/@octokit/rest": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.3.tgz", - "integrity": "sha512-5arkTsnnRT7/sbI4fqgSJ35KiFaN7zQm0uQiQtivNQLI8RQx8EHwJCajcTUwmaCMNDg7tdCvqAnc7uvHHPxrtQ==", + "node_modules/@octokit/tsconfig": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz", + "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==", "dev": true, - "dependencies": { - "@octokit/core": "^4.0.0", - "@octokit/plugin-paginate-rest": "^3.0.0", - "@octokit/plugin-request-log": "^1.0.4", - "@octokit/plugin-rest-endpoint-methods": "^6.0.0" - }, - "engines": { - "node": ">= 14" - } + "license": "MIT" }, "node_modules/@octokit/types": { - "version": "6.40.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.40.0.tgz", - "integrity": "sha512-MFZOU5r8SwgJWDMhrLUSvyJPtVsqA6VnbVI3TNbsmw+Jnvrktzvq2fYES/6RiJA/5Ykdwq4mJmtlYUfW7CGjmw==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", + "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==", "dev": true, + "license": "MIT", "dependencies": { - "@octokit/openapi-types": "^12.10.0" + "@octokit/openapi-types": "^18.0.0" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" } }, "node_modules/@pnpm/config.env-replace": { @@ -1931,62 +2226,50 @@ } }, "node_modules/@semantic-release/github": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-8.0.5.tgz", - "integrity": "sha512-9pGxRM3gv1hgoZ/muyd4pWnykdIUVfCiev6MXE9lOyGQof4FQy95GFE26nDcifs9ZG7bBzV8ue87bo/y1zVf0g==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-8.1.0.tgz", + "integrity": "sha512-erR9E5rpdsz0dW1I7785JtndQuMWN/iDcemcptf67tBNOmBUN0b2YNOgcjYUnBpgRpZ5ozfBHrK7Bz+2ets/Dg==", "dev": true, + "license": "MIT", "dependencies": { - "@octokit/rest": "^19.0.0", - "@semantic-release/error": "^2.2.0", + "@octokit/core": "^4.2.1", + "@octokit/plugin-paginate-rest": "^6.1.2", + "@octokit/plugin-retry": "^4.1.3", + "@octokit/plugin-throttling": "^5.2.3", + "@semantic-release/error": "^3.0.0", "aggregate-error": "^3.0.0", - "bottleneck": "^2.18.1", "debug": "^4.0.0", "dir-glob": "^3.0.0", - "fs-extra": "^10.0.0", + "fs-extra": "^11.0.0", "globby": "^11.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", "issue-parser": "^6.0.0", "lodash": "^4.17.4", "mime": "^3.0.0", "p-filter": "^2.0.0", - "p-retry": "^4.0.0", "url-join": "^4.0.0" }, "engines": { - "node": ">=14.17" - }, - "peerDependencies": { - "semantic-release": ">=18.0.0-beta.1" - } - }, - "node_modules/@semantic-release/github/node_modules/@semantic-release/error": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", - "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", - "dev": true - }, - "node_modules/@semantic-release/github/node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true, - "engines": { - "node": ">= 10" + "node": ">=14.17" + }, + "peerDependencies": { + "semantic-release": ">=18.0.0-beta.1" } }, - "node_modules/@semantic-release/github/node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "node_modules/@semantic-release/github/node_modules/fs-extra": { + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", "dev": true, + "license": "MIT", "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">= 6" + "node": ">=14.14" } }, "node_modules/@semantic-release/github/node_modules/mime": { @@ -2166,10 +2449,11 @@ } }, "node_modules/@types/bonjour": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", - "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -2184,10 +2468,11 @@ } }, "node_modules/@types/connect-history-api-fallback": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", - "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", "dev": true, + "license": "MIT", "dependencies": { "@types/express-serve-static-core": "*", "@types/node": "*" @@ -2255,52 +2540,58 @@ } }, "node_modules/@types/eslint": { - "version": "8.4.5", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.5.tgz", - "integrity": "sha512-dhsC09y1gpJWnK+Ff4SGvCuSnk9DaU0BJZSzOwa6GVSg65XtTugLBITDAAzRU5duGBoXBHpdR/9jHGxJjNflJQ==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, + "license": "MIT", "dependencies": { "@types/eslint": "*", "@types/estree": "*" } }, "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" }, "node_modules/@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "version": "4.17.25", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", + "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", "dev": true, + "license": "MIT", "dependencies": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", + "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", - "@types/serve-static": "*" + "@types/serve-static": "^1" } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.29", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz", - "integrity": "sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q==", + "version": "4.19.8", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz", + "integrity": "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", - "@types/range-parser": "*" + "@types/range-parser": "*", + "@types/send": "*" } }, "node_modules/@types/geojson": { @@ -2318,6 +2609,13 @@ "@types/node": "*" } }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/http-proxy": { "version": "1.17.9", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", @@ -2362,10 +2660,11 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/leaflet": { "version": "1.7.9", @@ -2377,10 +2676,11 @@ } }, "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", - "dev": true + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true, + "license": "MIT" }, "node_modules/@types/minimist": { "version": "1.2.2", @@ -2394,6 +2694,16 @@ "integrity": "sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw==", "dev": true }, + "node_modules/@types/node-forge": { + "version": "1.3.14", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.14.tgz", + "integrity": "sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", @@ -2425,35 +2735,61 @@ "dev": true }, "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "dev": true + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", + "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", "dev": true, + "license": "MIT", "dependencies": { "@types/express": "*" } }, "node_modules/@types/serve-static": { - "version": "1.13.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", - "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "version": "1.15.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz", + "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "<1" + } + }, + "node_modules/@types/serve-static/node_modules/@types/send": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz", + "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", "dev": true, + "license": "MIT", "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "node_modules/@types/sockjs": { - "version": "0.3.33", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", - "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -2465,10 +2801,11 @@ "dev": true }, "node_modules/@types/ws": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", - "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -2489,115 +2826,159 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.24.0.tgz", - "integrity": "sha512-6bqFGk6wa9+6RrU++eLknKyDqXU1Oc8nyoLu5a1fU17PNRJd9UBr56rMF7c4DRaRtnarlkQ4jwxUbvBo8cNlpw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.1.tgz", + "integrity": "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "5.24.0", - "@typescript-eslint/type-utils": "5.24.0", - "@typescript-eslint/utils": "5.24.0", - "debug": "^4.3.4", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.2.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/type-utils": "8.56.1", + "@typescript-eslint/utils": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.4.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@typescript-eslint/parser": "^8.56.1", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" } }, "node_modules/@typescript-eslint/parser": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.24.0.tgz", - "integrity": "sha512-4q29C6xFYZ5B2CXqSBBdcS0lPyfM9M09DoQLtHS5kf+WbpV8pBBhHDLNhXfgyVwFnhrhYzOu7xmg02DzxeF2Uw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.1.tgz", + "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "5.24.0", - "@typescript-eslint/types": "5.24.0", - "@typescript-eslint/typescript-estree": "5.24.0", - "debug": "^4.3.4" + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", + "debug": "^4.4.3" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz", + "integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.56.1", + "@typescript-eslint/types": "^8.56.1", + "debug": "^4.4.3" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.24.0.tgz", - "integrity": "sha512-WpMWipcDzGmMzdT7NtTjRXFabx10WleLUGrJpuJLGaxSqpcyq5ACpKSD5VE40h2nz3melQ91aP4Du7lh9FliCA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", + "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.24.0", - "@typescript-eslint/visitor-keys": "5.24.0" + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz", + "integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.24.0.tgz", - "integrity": "sha512-uGi+sQiM6E5CeCZYBXiaIvIChBXru4LZ1tMoeKbh1Lze+8BO9syUG07594C4lvN2YPT4KVeIupOJkVI+9/DAmQ==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.1.tgz", + "integrity": "sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "5.24.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/utils": "8.56.1", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.24.0.tgz", - "integrity": "sha512-Tpg1c3shTDgTmZd3qdUyd+16r/pGmVaVEbLs+ufuWP0EruVbUiEOmpBBQxBb9a8iPRxi8Rb2oiwOxuZJzSq11A==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", + "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -2605,216 +2986,305 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.24.0.tgz", - "integrity": "sha512-zcor6vQkQmZAQfebSPVwUk/FD+CvnsnlfKXYeQDsWXRF+t7SBPmIfNia/wQxCSeu1h1JIjwV2i9f5/DdSp/uDw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz", + "integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.24.0", - "@typescript-eslint/visitor-keys": "5.24.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "@typescript-eslint/project-service": "8.56.1", + "@typescript-eslint/tsconfig-utils": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/@typescript-eslint/utils": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.24.0.tgz", - "integrity": "sha512-K05sbWoeCBJH8KXu6hetBJ+ukG0k2u2KlgD3bN+v+oBKm8adJqVHpSSLHNzqyuv0Lh4GVSAUgZ5lB4icmPmWLw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz", + "integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==", "dev": true, + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.24.0", - "@typescript-eslint/types": "5.24.0", - "@typescript-eslint/typescript-estree": "5.24.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.24.0.tgz", - "integrity": "sha512-qzGwSXMyMnogcAo+/2fU+jhlPPVMXlIH2PeAonIKjJSoDKl1+lJVvG5Z5Oud36yU0TWK2cs1p/FaSN5J2OUFYA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz", + "integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.24.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "8.56.1", + "eslint-visitor-keys": "^5.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.5.tgz", - "integrity": "sha512-LHY/GSAZZRpsNQH+/oHqhRQ5FT7eoULcBqgfyTB5nQHogFnK3/7QoN7dLnwSE/JkUAF0SrRuclT7ODqMFtWxxQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.5.tgz", - "integrity": "sha512-1j1zTIC5EZOtCplMBG/IEwLtUojtwFVwdyVMbL/hwWqbzlQoJsWCOavrdnLkemwNoC/EOwtUFch3fuo+cbcXYQ==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.5.tgz", - "integrity": "sha512-L65bDPmfpY0+yFrsgz8b6LhXmbbs38OnwDCf6NpnMUYqa+ENfE5Dq9E42ny0qz/PdR0LJyq/T5YijPnU8AXEpA==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.5.tgz", - "integrity": "sha512-fDKo1gstwFFSfacIeH5KfwzjykIE6ldh1iH9Y/8YkAZrhmu4TctqYjSh7t0K2VyDSXOZJ1MLhht/k9IvYGcIxg==", - "dev": true + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.5.tgz", - "integrity": "sha512-DhykHXM0ZABqfIGYNv93A5KKDw/+ywBFnuWybZZWcuzWHfbp21wUfRkbtz7dMGwGgT4iXjWuhRMA2Mzod6W4WA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.5", - "@webassemblyjs/helper-api-error": "1.11.5", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.5.tgz", - "integrity": "sha512-oC4Qa0bNcqnjAowFn7MPCETQgDYytpsfvz4ujZz63Zu/a/v71HeCAAmZsgZ3YVKec3zSPYytG3/PrRCqbtcAvA==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.5.tgz", - "integrity": "sha512-uEoThA1LN2NA+K3B9wDo3yKlBfVtC6rh0i4/6hvbz071E8gTNZD/pT0MsBf7MeD6KbApMSkaAK0XeKyOZC7CIA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-buffer": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5", - "@webassemblyjs/wasm-gen": "1.11.5" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.5.tgz", - "integrity": "sha512-37aGq6qVL8A8oPbPrSGMBcp38YZFXcHfiROflJn9jxSdSMMM5dS5P/9e2/TpaJuhE+wFrbukN2WI6Hw9MH5acg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dev": true, + "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.5.tgz", - "integrity": "sha512-ajqrRSXaTJoPW+xmkfYN6l8VIeNnR4vBOTQO9HzR7IygoCcKWkICbKFbVTNMjMgMREqXEr0+2M6zukzM47ZUfQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.5.tgz", - "integrity": "sha512-WiOhulHKTZU5UPlRl53gHR8OxdGsSOxqfpqWeA2FmcwBMaoEdz6b2x2si3IwC9/fSPLfe8pBMRTHVMk5nlwnFQ==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.5.tgz", - "integrity": "sha512-C0p9D2fAu3Twwqvygvf42iGCQ4av8MFBLiTb+08SZ4cEdwzWx9QeAHDo1E2k+9s/0w1DM40oflJOpkZ8jW4HCQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-buffer": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5", - "@webassemblyjs/helper-wasm-section": "1.11.5", - "@webassemblyjs/wasm-gen": "1.11.5", - "@webassemblyjs/wasm-opt": "1.11.5", - "@webassemblyjs/wasm-parser": "1.11.5", - "@webassemblyjs/wast-printer": "1.11.5" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.5.tgz", - "integrity": "sha512-14vteRlRjxLK9eSyYFvw1K8Vv+iPdZU0Aebk3j6oB8TQiQYuO6hj9s4d7qf6f2HJr2khzvNldAFG13CgdkAIfA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5", - "@webassemblyjs/ieee754": "1.11.5", - "@webassemblyjs/leb128": "1.11.5", - "@webassemblyjs/utf8": "1.11.5" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.5.tgz", - "integrity": "sha512-tcKwlIXstBQgbKy1MlbDMlXaxpucn42eb17H29rawYLxm5+MsEmgPzeCP8B1Cl69hCice8LeKgZpRUAPtqYPgw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-buffer": "1.11.5", - "@webassemblyjs/wasm-gen": "1.11.5", - "@webassemblyjs/wasm-parser": "1.11.5" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.5.tgz", - "integrity": "sha512-SVXUIwsLQlc8srSD7jejsfTU83g7pIGr2YYNb9oHdtldSxaOhvA5xwvIiWIfcX8PlSakgqMXsLpLfbbJ4cBYew==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-api-error": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5", - "@webassemblyjs/ieee754": "1.11.5", - "@webassemblyjs/leb128": "1.11.5", - "@webassemblyjs/utf8": "1.11.5" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.5.tgz", - "integrity": "sha512-f7Pq3wvg3GSPUPzR0F6bmI89Hdb+u9WXrSKc4v+N0aV0q6r42WoF92Jp2jEorBEBRoRNXgjp53nBniDXcqZYPA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.5", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, @@ -2858,13 +3328,15 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/accepts": { "version": "1.3.8", @@ -2880,10 +3352,11 @@ } }, "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -2891,13 +3364,17 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, "peerDependencies": { - "acorn": "^8" + "acorn": "^8.14.0" } }, "node_modules/acorn-jsx": { @@ -2905,20 +3382,19 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "dev": true, - "dependencies": { - "debug": "4" - }, + "license": "MIT", "engines": { - "node": ">= 6.0.0" + "node": ">= 14" } }, "node_modules/aggregate-error": { @@ -2935,15 +3411,16 @@ } }, "node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -3079,12 +3556,6 @@ "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", "dev": true }, - "node_modules/array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true - }, "node_modules/array-ify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", @@ -3243,12 +3714,25 @@ "@babel/core": "^7.0.0" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", + "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", @@ -3268,58 +3752,56 @@ "dev": true }, "node_modules/before-after-hook": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", - "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==", - "dev": true + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true, + "license": "Apache-2.0" }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", "dev": true, + "license": "MIT", "dependencies": { - "bytes": "3.1.2", + "bytes": "~3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", "type-is": "~1.6.18", - "unpipe": "1.0.0" + "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -3328,16 +3810,16 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/bonjour-service": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.13.tgz", - "integrity": "sha512-LWKRU/7EqDUC9CTAQtuZl5HzBALoCYwtLhffW3et7vZMwv3bWLpJf8bRYlMD5OCcDpTfnPgNCV4yo9ZIaJGMiA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", "dev": true, + "license": "MIT", "dependencies": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } @@ -3346,34 +3828,37 @@ "version": "2.19.5", "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "funding": [ { @@ -3389,11 +3874,13 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" @@ -3429,23 +3916,58 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/call-bind": { + "node_modules/call-bind-apply-helpers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, + "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3487,9 +4009,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001591", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz", - "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==", + "version": "1.0.30001776", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001776.tgz", + "integrity": "sha512-sg01JDPzZ9jGshqKSckOQthXnYwOEP50jeVFhaSFbZcOy05TiuuaffDOfcwtCisJ9kNQuLBFibYywv2Bgm9osw==", "dev": true, "funding": [ { @@ -3504,7 +4026,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/cardinal": { "version": "2.1.1", @@ -3545,16 +4068,11 @@ } }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -3567,6 +4085,9 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } @@ -3576,6 +4097,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -3718,7 +4240,8 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/compare-func": { "version": "2.0.0", @@ -3743,17 +4266,18 @@ } }, "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", "dev": true, + "license": "MIT", "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", + "bytes": "3.1.2", + "compressible": "~2.0.18", "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", "vary": "~1.1.2" }, "engines": { @@ -3775,6 +4299,37 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3837,6 +4392,7 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -3952,10 +4508,11 @@ "dev": true }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -4096,10 +4653,11 @@ "dev": true }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4254,12 +4812,13 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -4328,7 +4887,8 @@ "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==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", @@ -4339,25 +4899,47 @@ "node": ">=0.10.0" } }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "node_modules/default-browser": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", + "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", "dev": true, + "license": "MIT", "dependencies": { - "execa": "^5.0.0" + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" }, "engines": { - "node": ">= 10" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/del": { @@ -4402,6 +4984,7 @@ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -4410,13 +4993,15 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -4438,10 +5023,11 @@ "dev": true }, "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -4467,17 +5053,12 @@ "node": ">=8" } }, - "node_modules/dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==", - "dev": true - }, "node_modules/dns-packet": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz", - "integrity": "sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", "dev": true, + "license": "MIT", "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" }, @@ -4509,6 +5090,21 @@ "node": ">=8" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", @@ -4522,13 +5118,15 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.685", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.685.tgz", - "integrity": "sha512-yDYeobbTEe4TNooEzOQO6xFqg9XnAkVy2Lod1C1B2it8u47JNLYvl9nLDWBamqUakWB8Jc1hhS1uHUNYTNQdfw==", - "dev": true + "version": "1.5.307", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.307.tgz", + "integrity": "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg==", + "dev": true, + "license": "ISC" }, "node_modules/emittery": { "version": "0.13.1", @@ -4549,22 +5147,24 @@ "dev": true }, "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/enhanced-resolve": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.13.0.tgz", - "integrity": "sha512-eyV8f0y1+bzyfh8xAwW/WTSZpLbjhqc4ne9eGSH4Zo2ejdyiNG9pU6mf9DG8a7+Auk6MFTlNOT4Y2y/9k8GKVg==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz", + "integrity": "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "tapable": "^2.3.0" }, "engines": { "node": ">=10.13.0" @@ -4605,17 +5205,52 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.1.tgz", - "integrity": "sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4639,46 +5274,51 @@ } }, "node_modules/eslint": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz", - "integrity": "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, + "license": "MIT", "dependencies": { - "@eslint/eslintrc": "^1.2.3", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@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.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "esquery": "^1.4.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", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.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.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -4715,19 +5355,22 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.2.2.tgz", - "integrity": "sha512-etSFZ8VIFX470aA6kTqDPhIq7YWe0tjBcboFNV3WeiC18PJ/AVonGhuTwlmuz2fBkH8FJHA7JQ4k7GsQIj1Gew==", + "version": "29.15.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.0.tgz", + "integrity": "sha512-ZCGr7vTH2WSo2hrK5oM2RULFmMruQ7W3cX7YfwoTiPfzTGTFBMmrVIz45jZHd++cGKj/kWf02li/RhTGcANJSA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "^5.10.0" + "@typescript-eslint/utils": "^8.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.12.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "@typescript-eslint/eslint-plugin": "^8.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "jest": "*", + "typescript": ">=4.8.4 <6.0.0" }, "peerDependenciesMeta": { "@typescript-eslint/eslint-plugin": { @@ -4735,84 +5378,75 @@ }, "jest": { "optional": true + }, + "typescript": { + "optional": true } } }, "node_modules/eslint-plugin-prettier": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", - "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", + "version": "5.5.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.5.tgz", + "integrity": "sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==", "dev": true, + "license": "MIT", "dependencies": { - "prettier-linter-helpers": "^1.0.0" + "prettier-linter-helpers": "^1.0.1", + "synckit": "^0.11.12" }, "engines": { - "node": ">=6.0.0" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" }, "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", + "prettier": ">=3.0.0" }, "peerDependenciesMeta": { - "eslint-config-prettier": { + "@types/eslint": { "optional": true - } - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" + }, + "eslint-config-prettier": { + "optional": true + } } }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, "engines": { - "node": ">=10" + "node": ">=8.0.0" } }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "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==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4825,16 +5459,20 @@ } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/estraverse": { @@ -4842,6 +5480,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -4853,17 +5492,21 @@ "dev": true }, "node_modules/espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.7.1", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -4880,10 +5523,11 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -4896,6 +5540,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -4944,6 +5589,7 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -5012,45 +5658,50 @@ } }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", "dev": true, + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", - "on-finished": "2.4.1", + "on-finished": "~2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "~6.14.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "~0.19.0", + "serve-static": "~1.16.2", "setprototypeof": "1.2.0", - "statuses": "2.0.1", + "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/array-flatten": { @@ -5101,10 +5752,11 @@ "dev": true }, "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true, + "license": "Apache-2.0" }, "node_modules/fast-glob": { "version": "3.2.11", @@ -5144,7 +5796,25 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" }, "node_modules/fastest-levenshtein": { "version": "1.0.14", @@ -5222,10 +5892,11 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -5234,17 +5905,18 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", "dev": true, + "license": "MIT", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", - "on-finished": "2.4.1", + "on-finished": "~2.4.1", "parseurl": "~1.3.3", - "statuses": "2.0.1", + "statuses": "~2.0.2", "unpipe": "~1.0.0" }, "engines": { @@ -5256,6 +5928,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -5264,7 +5937,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/find-up": { "version": "5.0.0", @@ -5350,6 +6024,7 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -5398,12 +6073,6 @@ "node": ">=12" } }, - "node_modules/fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", - "dev": true - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -5425,16 +6094,14 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/gensync": { "version": "1.0.0-beta.2", @@ -5455,14 +6122,25 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, + "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5477,6 +6155,20 @@ "node": ">=8.0.0" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -5573,11 +6265,29 @@ "node": ">=10.13.0" } }, + "node_modules/glob-to-regex.js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz", + "integrity": "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" }, "node_modules/global-dirs": { "version": "0.1.1", @@ -5592,10 +6302,11 @@ } }, "node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -5626,12 +6337,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", @@ -5690,10 +6421,11 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5701,6 +6433,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -5743,12 +6488,6 @@ "wbuf": "^1.1.0" } }, - "node_modules/html-entities": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", - "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==", - "dev": true - }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -5762,19 +6501,24 @@ "dev": true }, "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "dev": true, + "license": "MIT", "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" }, "engines": { "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/http-parser-js": { @@ -5797,11 +6541,26 @@ "node": ">=8.0.0" } }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", + "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", @@ -5897,16 +6656,17 @@ } }, "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, + "license": "MIT", "dependencies": { - "agent-base": "6", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/human-signals": { @@ -5933,11 +6693,22 @@ "url": "https://github.com/sponsors/typicode" } }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.18" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -6125,10 +6896,11 @@ } }, "node_modules/ipaddr.js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", - "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz", + "integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10" } @@ -6144,6 +6916,7 @@ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -6164,15 +6937,16 @@ } }, "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", "dev": true, + "license": "MIT", "bin": { "is-docker": "cli.js" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6217,11 +6991,44 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-network-error": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.1.tgz", + "integrity": "sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -6267,6 +7074,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6296,15 +7104,19 @@ } }, "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", "dev": true, + "license": "MIT", "dependencies": { - "is-docker": "^2.0.0" + "is-inside-container": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/isarray": { @@ -7094,6 +7906,7 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -7108,6 +7921,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -7122,13 +7936,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -7245,6 +8061,17 @@ "node": ">=6" } }, + "node_modules/launch-editor": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.13.1.tgz", + "integrity": "sha512-lPSddlAAluRKJ7/cjRFoXUFzaX7q/YKI7yPHuEvSJVqoXvFnJov1/Ud87Aa4zULIbA9Nja4mSPK8l0z/7eV2wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.1", + "shell-quote": "^1.8.3" + } + }, "node_modules/leaflet": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.8.0.tgz", @@ -7264,6 +8091,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -7325,12 +8153,17 @@ } }, "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/locate-path": { @@ -7349,10 +8182,11 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "dev": true, + "license": "MIT" }, "node_modules/lodash.capitalize": { "version": "4.2.1", @@ -7554,25 +8388,54 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/memfs": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.7.tgz", - "integrity": "sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw==", + "version": "4.56.11", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.56.11.tgz", + "integrity": "sha512-/GodtwVeKVIHZKLUSr2ZdOxKBC5hHki4JNCU22DoCGPEHr5o2PD5U721zvESKyWwCfTfavFl9WZYgA13OAYK0g==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "fs-monkey": "^1.0.3" + "@jsonjoy.com/fs-core": "4.56.11", + "@jsonjoy.com/fs-fsa": "4.56.11", + "@jsonjoy.com/fs-node": "4.56.11", + "@jsonjoy.com/fs-node-builtins": "4.56.11", + "@jsonjoy.com/fs-node-to-fsa": "4.56.11", + "@jsonjoy.com/fs-node-utils": "4.56.11", + "@jsonjoy.com/fs-print": "4.56.11", + "@jsonjoy.com/fs-snapshot": "4.56.11", + "@jsonjoy.com/json-pack": "^1.11.0", + "@jsonjoy.com/util": "^1.9.0", + "glob-to-regex.js": "^1.0.1", + "thingies": "^2.5.0", + "tree-dump": "^1.0.3", + "tslib": "^2.0.0" }, - "engines": { - "node": ">= 4.0.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" } }, "node_modules/meow": { @@ -7612,12 +8475,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true - }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -7643,12 +8510,13 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -7713,10 +8581,11 @@ "dev": true }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -7766,16 +8635,18 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "node_modules/multicast-dns": { "version": "7.2.5", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", "dev": true, + "license": "MIT", "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" @@ -7821,10 +8692,11 @@ } }, "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -7840,33 +8712,12 @@ } } }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz", + "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==", "dev": true, + "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" } @@ -7878,10 +8729,11 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", + "dev": true, + "license": "MIT" }, "node_modules/normalize-package-data": { "version": "3.0.3", @@ -10498,10 +11350,14 @@ "license": "ISC" }, "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -10517,6 +11373,7 @@ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -10525,10 +11382,11 @@ } }, "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -10558,17 +11416,19 @@ } }, "node_modules/open": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", "dev": true, + "license": "MIT", "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -10584,17 +11444,18 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -10697,16 +11558,21 @@ } }, "node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", "dev": true, + "license": "MIT", "dependencies": { - "@types/retry": "0.12.0", + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", "retry": "^0.13.1" }, "engines": { - "node": ">=8" + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-try": { @@ -10791,10 +11657,11 @@ "dev": true }, "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true, + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", @@ -10806,10 +11673,11 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", @@ -10940,30 +11808,33 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", "dev": true, + "license": "MIT", "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=10.13.0" + "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz", + "integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==", "dev": true, + "license": "MIT", "dependencies": { "fast-diff": "^1.1.2" }, @@ -11080,12 +11951,13 @@ } }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", + "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.1.0" }, "engines": { "node": ">=0.6" @@ -11142,29 +12014,21 @@ } }, "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", "dev": true, + "license": "MIT", "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -11329,6 +12193,7 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -11370,18 +12235,6 @@ "esprima": "~4.0.0" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, "node_modules/registry-auth-token": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", @@ -11482,6 +12335,7 @@ "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -11511,6 +12365,19 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -11547,18 +12414,19 @@ "dev": true }, "node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", + "ajv": "^8.9.0", "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" + "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 10.13.0" }, "funding": { "type": "opencollective", @@ -11578,11 +12446,13 @@ "dev": true }, "node_modules/selfsigned": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.0.1.tgz", - "integrity": "sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", "dev": true, + "license": "MIT", "dependencies": { + "@types/node-forge": "^1.3.0", "node-forge": "^1" }, "engines": { @@ -11707,24 +12577,25 @@ } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", "dev": true, + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "2.4.1", + "on-finished": "~2.4.1", "range-parser": "~1.2.1", - "statuses": "2.0.1" + "statuses": "~2.0.2" }, "engines": { "node": ">= 0.8.0" @@ -11735,6 +12606,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -11743,19 +12615,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } @@ -11839,15 +12707,16 @@ } }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", "dev": true, + "license": "MIT", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "~0.19.1" }, "engines": { "node": ">= 0.8.0" @@ -11857,7 +12726,8 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/shallow-clone": { "version": "3.0.1", @@ -11892,15 +12762,90 @@ "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -12049,6 +12994,7 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -12199,10 +13145,11 @@ } }, "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -12344,13 +13291,34 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/synckit": { + "version": "0.11.12", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", + "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.9" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/temp-dir": { @@ -12394,13 +13362,14 @@ } }, "node_modules/terser": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz", - "integrity": "sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -12411,80 +13380,17 @@ "node": ">=10" } }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz", - "integrity": "sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.17", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.16.5" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "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" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", - "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", + "node_modules/terser-webpack-plugin": { + "version": "5.3.17", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.17.tgz", + "integrity": "sha512-YR7PtUp6GMU91BgSJmlaX/rS2lGDbAF7D+Wtq7hRO+MiljNmodYvqslzCFiYVAgW+Qoaaia/QUIP4lGXufjdZw==", "dev": true, + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "terser": "^5.31.1" }, "engines": { "node": ">= 10.13.0" @@ -12492,6 +13398,20 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } } }, "node_modules/test-exclude": { @@ -12523,6 +13443,23 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/thingies": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.5.0.tgz", + "integrity": "sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "^2" + } + }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -12556,7 +13493,56 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, "node_modules/tmpl": { "version": "1.0.5", @@ -12564,20 +13550,12 @@ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, - "node_modules/to-fast-properties": { - "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==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "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==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -12590,16 +13568,41 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.6" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, "node_modules/traverse": { "version": "0.6.6", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", "integrity": "sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw==", "dev": true }, + "node_modules/tree-dump": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", + "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, "node_modules/trim-newlines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", @@ -12609,6 +13612,19 @@ "node": ">=8" } }, + "node_modules/ts-api-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/ts-jest": { "version": "29.1.2", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.2.tgz", @@ -12696,10 +13712,11 @@ } }, "node_modules/ts-node": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.0.tgz", - "integrity": "sha512-/fNd5Qh+zTt8Vt1KbYZjRHCE9sI5i7nqfD/dzBBRDeVXZXS6kToW6R7tTU6Nd4XavFs0mAVCg29Q//ML7WsZYA==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, + "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -12747,32 +13764,19 @@ "node": ">=0.4.0" } }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -12794,6 +13798,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -12806,6 +13811,7 @@ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -12815,16 +13821,17 @@ } }, "node_modules/typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/uglify-js": { @@ -12865,10 +13872,11 @@ } }, "node_modules/universal-user-agent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", - "dev": true + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", + "dev": true, + "license": "ISC" }, "node_modules/universalify": { "version": "2.0.0", @@ -12884,14 +13892,15 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -12907,9 +13916,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -12957,12 +13967,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -13012,10 +14016,11 @@ } }, "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", "dev": true, + "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -13033,36 +14038,45 @@ "minimalistic-assert": "^1.0.0" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/webpack": { - "version": "5.80.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.80.0.tgz", - "integrity": "sha512-OIMiq37XK1rWO8mH9ssfFKZsXg4n6klTEDL7S8/HqbAOBBaiy8ABvXvz0dDCXeEF9gqwxSvVk611zFPjS8hJxA==", - "dev": true, - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", + "version": "5.105.4", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.4.tgz", + "integrity": "sha512-jTywjboN9aHxFlToqb0K0Zs9SbBoW4zRUlGzI2tYNxVYcEi/IPpn+Xi4ye5jTLvX2YeLuic/IvxNot+Q1jMoOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.16.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.13.0", - "es-module-lexer": "^1.2.1", + "enhanced-resolve": "^5.20.0", + "es-module-lexer": "^2.0.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", + "loader-runner": "^4.3.1", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.2", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.17", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.4" }, "bin": { "webpack": "bin/webpack.js" @@ -13137,100 +14151,115 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.5.tgz", + "integrity": "sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==", "dev": true, + "license": "MIT", "dependencies": { "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", + "memfs": "^4.43.1", + "mime-types": "^3.0.1", + "on-finished": "^2.4.1", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/webpack-dev-server": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.9.3.tgz", - "integrity": "sha512-3qp/eoboZG5/6QgiZ3llN8TUzkSpYg1Ko9khWX1h40MIEUNS2mDoIa8aXsPfskER+GbTvs/IJZ1QTBBhhuetSw==", - "dev": true, - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.1", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.0.tgz", + "integrity": "sha512-90SqqYXA2SK36KcT6o1bvwvZfJFcmoamqeJY7+boioffX9g9C0wjjJRGUrQIuh43pb0ttX7+ssavmj/WN2RHtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", "colorette": "^2.0.10", "compression": "^1.7.4", "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", + "express": "^4.21.2", "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.0.1", + "http-proxy-middleware": "^2.0.7", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.4.2" + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" }, "bin": { "webpack-dev-server": "bin/webpack-dev-server.js" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", - "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "webpack": "^5.0.0" }, "peerDependenciesMeta": { - "bufferutil": { + "webpack": { "optional": true }, - "utf-8-validate": { + "webpack-cli": { "optional": true } } @@ -13249,62 +14278,21 @@ } }, "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.4.tgz", + "integrity": "sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.13.0" } }, - "node_modules/webpack/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "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" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/webpack/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", - "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", + "node_modules/webpack/node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } + "license": "ISC" }, "node_modules/websocket-driver": { "version": "0.7.4", @@ -13329,6 +14317,17 @@ "node": ">=0.8.0" } }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -13355,6 +14354,7 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -13401,6 +14401,44 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index 9e2f4ed..bfb4610 100644 --- a/package.json +++ b/package.json @@ -67,27 +67,27 @@ "@types/jest": "29.5.12", "@types/leaflet": "1.7.9", "@types/resize-observer-browser": "^0.1.7", - "@typescript-eslint/eslint-plugin": "5.24.0", - "@typescript-eslint/parser": "5.24.0", + "@typescript-eslint/eslint-plugin": "8.56.1", + "@typescript-eslint/parser": "8.56.1", "conventional-changelog-eslint": "3.0.9", "copy-webpack-plugin": "^11.0.0", - "eslint": "8.15.0", + "eslint": "8.57.0", "eslint-config-google": "0.14.0", "eslint-config-prettier": "8.5.0", - "eslint-plugin-jest": "26.2.2", - "eslint-plugin-prettier": "4.0.0", + "eslint-plugin-jest": "29.15.0", + "eslint-plugin-prettier": "5.5.5", "http-server": "^14.1.1", "husky": "^8.0.1", "jest": "29.7.0", - "prettier": "^2.7.1", + "prettier": "3.8.1", "semantic-release": "19.0.3", "ts-jest": "29.1.2", "ts-loader": "^9.3.1", - "ts-node": "10.8.0", - "typescript": "4.6.3", + "ts-node": "10.9.2", + "typescript": "5.9.3", "webpack": "^5.73.0", "webpack-cli": "^4.10.0", - "webpack-dev-server": "^4.9.3" + "webpack-dev-server": "5.2.0" }, "jest": { "moduleFileExtensions": [ diff --git a/src/models/graph.ts b/src/models/graph.ts index 7bcf0e0..8b7801e 100644 --- a/src/models/graph.ts +++ b/src/models/graph.ts @@ -8,7 +8,6 @@ import { IEntityState, EntityState } from '../utils/entity.utils'; import { IObserver, IObserverDataPayload, ISubject, Subject } from '../utils/observer.utils'; import { patchProperties } from '../utils/object.utils'; import { dedupArrays } from '../utils/array.utils'; -import { ILayout } from '../simulator/layout/layout'; export interface IGraphData { nodes: N[]; @@ -51,7 +50,6 @@ export interface IGraph extends ISubje getNearestNode(point: IPosition): INode | undefined; getNearestEdge(point: IPosition, minDistance?: number): IEdge | undefined; setSettings(settings: Partial>): void; - setLayout(layout: ILayout | undefined): void; } export interface IGraphSettings { @@ -75,7 +73,6 @@ export class Graph extends Subject imp }); private _defaultStyle?: Partial>; private _settings: IGraphSettings; - private _layout: ILayout | undefined; constructor(data?: Partial>, settings?: Partial>) { // TODO(dlozic): How to use object assign here? If I add add and export a default const here, it needs N, E. @@ -95,11 +92,6 @@ export class Graph extends Subject imp this.notifyListeners(); } - setLayout(layout: ILayout | undefined): void { - this._layout = layout; - this._resetLayout(); - } - /** * Returns a list of nodes. * @@ -282,7 +274,6 @@ export class Graph extends Subject imp this._applyEdgeOffsets(); this._applyStyle(); - this._resetLayout(); this._settings?.onMergeData?.(data); } @@ -296,7 +287,6 @@ export class Graph extends Subject imp this._applyEdgeOffsets(); this._applyStyle(); - this._resetLayout(); if (this._settings && this._settings.onRemoveData) { const removedData: IGraphObjectsIds = { @@ -613,17 +603,6 @@ export class Graph extends Subject imp return { nodeIds: [], edgeIds: removedEdgeIds }; } - private _resetLayout(): void { - if (!this._layout) { - this.clearPositions(); - return; - } - - const positions = this._layout.getPositions(this.getNodes()); - this.setNodePositions(positions); - this.notifyListeners(); - } - private _applyEdgeOffsets() { const graphEdges = this.getEdges(); const edgeOffsets = getEdgeOffsets(graphEdges); diff --git a/src/models/interaction.ts b/src/models/interaction.ts new file mode 100644 index 0000000..5e6c6c5 --- /dev/null +++ b/src/models/interaction.ts @@ -0,0 +1,67 @@ +import { hoverEdge, hoverNode, selectEdge, selectNode, unhoverAll, unselectAll } from '../utils/graph.utils'; +import { IEdgeBase } from './edge'; +import { IGraph } from './graph'; +import { INodeBase } from './node'; + +export interface IGraphInteraction { + selectNodeById(id: any): boolean; + selectEdgeById(id: any): boolean; + unselectAll(): number; + hoverNodeById(id: any): boolean; + hoverEdgeById(id: any): boolean; + unhoverAll(): number; +} + +export class GraphInteraction implements IGraphInteraction { + private _graph: IGraph; + + constructor(graph: IGraph) { + this._graph = graph; + } + + selectNodeById(id: any): boolean { + const node = this._graph.getNodeById(id); + if (!node) { + return false; + } + selectNode(node); + return true; + } + + selectEdgeById(id: any): boolean { + const edge = this._graph.getEdgeById(id); + if (!edge) { + return false; + } + selectEdge(edge); + return true; + } + + unselectAll(): number { + const { changedCount } = unselectAll(this._graph); + return changedCount; + } + + hoverNodeById(id: any): boolean { + const node = this._graph.getNodeById(id); + if (!node) { + return false; + } + hoverNode(node); + return true; + } + + hoverEdgeById(id: any): boolean { + const edge = this._graph.getEdgeById(id); + if (!edge) { + return false; + } + hoverEdge(edge); + return true; + } + + unhoverAll(): number { + const { changedCount } = unhoverAll(this._graph); + return changedCount; + } +} diff --git a/src/models/strategy.ts b/src/models/strategy.ts index 9604963..a3580b6 100644 --- a/src/models/strategy.ts +++ b/src/models/strategy.ts @@ -2,7 +2,7 @@ import { INode, INodeBase } from './node'; import { IEdge, IEdgeBase } from './edge'; import { IGraph } from './graph'; import { IPosition } from '../common'; -import { GraphObjectState } from './state'; +import { hoverOnlyNode, selectOnlyEdge, selectOnlyNode, unhoverAll, unselectAll } from '../utils/graph.utils'; export interface IEventStrategySettings { isDefaultSelectEnabled: boolean; @@ -37,7 +37,7 @@ export class DefaultEventStrategy impl const node = graph.getNearestNode(point); if (node) { if (this.isSelectEnabled) { - selectNode(graph, node); + selectOnlyNode(graph, node); } return { @@ -49,7 +49,7 @@ export class DefaultEventStrategy impl const edge = graph.getNearestEdge(point); if (edge) { if (this.isSelectEnabled) { - selectEdge(graph, edge); + selectOnlyEdge(graph, edge); } return { @@ -79,7 +79,7 @@ export class DefaultEventStrategy impl } if (this.isHoverEnabled) { - hoverNode(graph, node); + hoverOnlyNode(graph, node); } this._lastHoveredNode = node; @@ -104,7 +104,7 @@ export class DefaultEventStrategy impl const node = graph.getNearestNode(point); if (node) { if (this.isSelectEnabled) { - selectNode(graph, node); + selectOnlyNode(graph, node); } return { @@ -116,7 +116,7 @@ export class DefaultEventStrategy impl const edge = graph.getNearestEdge(point); if (edge) { if (this.isSelectEnabled) { - selectEdge(graph, edge); + selectOnlyEdge(graph, edge); } return { @@ -139,7 +139,7 @@ export class DefaultEventStrategy impl const node = graph.getNearestNode(point); if (node) { if (this.isSelectEnabled) { - selectNode(graph, node); + selectOnlyNode(graph, node); } return { @@ -151,7 +151,7 @@ export class DefaultEventStrategy impl const edge = graph.getNearestEdge(point); if (edge) { if (this.isSelectEnabled) { - selectEdge(graph, edge); + selectOnlyEdge(graph, edge); } return { @@ -170,109 +170,3 @@ export class DefaultEventStrategy impl }; } } - -const selectNode = (graph: IGraph, node: INode) => { - unselectAll(graph); - setNodeState(node, GraphObjectState.SELECTED, { isStateOverride: true }); -}; - -const selectEdge = (graph: IGraph, edge: IEdge) => { - unselectAll(graph); - setEdgeState(edge, GraphObjectState.SELECTED, { isStateOverride: true }); -}; - -const unselectAll = (graph: IGraph): { changedCount: number } => { - const selectedNodes = graph.getNodes((node) => node.isSelected()); - for (let i = 0; i < selectedNodes.length; i++) { - selectedNodes[i].clearState(); - } - - const selectedEdges = graph.getEdges((edge) => edge.isSelected()); - for (let i = 0; i < selectedEdges.length; i++) { - selectedEdges[i].clearState(); - } - - return { changedCount: selectedNodes.length + selectedEdges.length }; -}; - -const hoverNode = (graph: IGraph, node: INode) => { - unhoverAll(graph); - setNodeState(node, GraphObjectState.HOVERED); -}; - -// const hoverEdge = (graph: Graph, edge: Edge) => { -// unhoverAll(graph); -// setEdgeState(edge, GraphObjectState.HOVERED); -// }; - -const unhoverAll = (graph: IGraph): { changedCount: number } => { - const hoveredNodes = graph.getNodes((node) => node.isHovered()); - for (let i = 0; i < hoveredNodes.length; i++) { - hoveredNodes[i].clearState(); - } - - const hoveredEdges = graph.getEdges((edge) => edge.isHovered()); - for (let i = 0; i < hoveredEdges.length; i++) { - hoveredEdges[i].clearState(); - } - - return { changedCount: hoveredNodes.length + hoveredEdges.length }; -}; - -interface ISetShapeStateOptions { - isStateOverride: boolean; -} - -const setNodeState = ( - node: INode, - state: number, - options?: ISetShapeStateOptions, -): void => { - if (isStateChangeable(node, options)) { - node.setState(state, { isNotifySkipped: true }); - } - - node.getInEdges().forEach((edge) => { - if (edge && isStateChangeable(edge, options)) { - edge.setState(state, { isNotifySkipped: true }); - } - if (edge.startNode && isStateChangeable(edge.startNode, options)) { - edge.startNode.setState(state, { isNotifySkipped: true }); - } - }); - - node.getOutEdges().forEach((edge) => { - if (edge && isStateChangeable(edge, options)) { - edge.setState(state, { isNotifySkipped: true }); - } - if (edge.endNode && isStateChangeable(edge.endNode, options)) { - edge.endNode.setState(state, { isNotifySkipped: true }); - } - }); -}; - -const setEdgeState = ( - edge: IEdge, - state: number, - options?: ISetShapeStateOptions, -): void => { - if (isStateChangeable(edge, options)) { - edge.setState(state, { isNotifySkipped: true }); - } - - if (edge.startNode && isStateChangeable(edge.startNode, options)) { - edge.startNode.setState(state, { isNotifySkipped: true }); - } - - if (edge.endNode && isStateChangeable(edge.endNode, options)) { - edge.endNode.setState(state, { isNotifySkipped: true }); - } -}; - -const isStateChangeable = ( - graphObject: INode | IEdge, - options?: ISetShapeStateOptions, -): boolean => { - const isOverride = options?.isStateOverride; - return isOverride || (!isOverride && !graphObject.getState()); -}; diff --git a/src/renderer/canvas/canvas-renderer.ts b/src/renderer/canvas/canvas-renderer.ts index 3e1eed8..7b99861 100644 --- a/src/renderer/canvas/canvas-renderer.ts +++ b/src/renderer/canvas/canvas-renderer.ts @@ -10,6 +10,7 @@ import { DEFAULT_RENDERER_HEIGHT, DEFAULT_RENDERER_SETTINGS, DEFAULT_RENDERER_WIDTH, + IFitZoomTransformOptions, IRenderer, IRendererSettings, RendererEvents as RE, @@ -285,12 +286,23 @@ export class CanvasRenderer extends Em this._context.save(); } - getFitZoomTransform(graph: IGraph): ZoomTransform { + getFitZoomTransform(graph: IGraph, options?: IFitZoomTransformOptions): ZoomTransform { // Graph view is a bounding box of the graph nodes that takes into // account node positions (x, y) and node sizes (style: size + border width) const graphView = graph.getBoundingBox(); - const graphMiddleX = graphView.x + graphView.width / 2; - const graphMiddleY = graphView.y + graphView.height / 2; + const graphMiddleX = + options?.anchorX === 'center' + ? graphView.x + graphView.width / 2 + : options?.anchorX === 'end' + ? graphView.x + graphView.width + : 0; + + const graphMiddleY = + options?.anchorY === 'center' + ? graphView.y + graphView.height / 2 + : options?.anchorY === 'end' + ? graphView.y + graphView.height + : 0; // Simulation view is actually a renderer view (canvas) but in the coordinate system of // the simulator: node position (x, y). We want to fit a graph view into a simulation view. diff --git a/src/renderer/shared.ts b/src/renderer/shared.ts index a5719bc..7ad965e 100644 --- a/src/renderer/shared.ts +++ b/src/renderer/shared.ts @@ -36,6 +36,11 @@ export interface IRendererSettingsInit extends IRendererSettings { type: RendererType; } +export interface IFitZoomTransformOptions { + anchorX?: 'start' | 'center' | 'end'; + anchorY?: 'start' | 'center' | 'end'; +} + export type RendererEvents = { [RenderEventType.RESIZE]: undefined; [RenderEventType.RENDER_START]: undefined; @@ -60,7 +65,7 @@ export interface IRenderer extends IEm render(graph: IGraph): void; reset(): void; - getFitZoomTransform(graph: IGraph): ZoomTransform; + getFitZoomTransform(graph: IGraph, options?: IFitZoomTransformOptions): ZoomTransform; getSimulationPosition(canvasPoint: IPosition): IPosition; /** diff --git a/src/simulator/engine/d3-simulator-engine.ts b/src/simulator/engine/d3-simulator-engine.ts deleted file mode 100644 index f20346f..0000000 --- a/src/simulator/engine/d3-simulator-engine.ts +++ /dev/null @@ -1,728 +0,0 @@ -import { - forceCenter, - forceCollide, - forceLink, - ForceLink, - forceManyBody, - forceSimulation, - forceX, - forceY, - Simulation, - SimulationLinkDatum, -} from 'd3-force'; -import { IPosition } from '../../common'; -import { ISimulationNode, ISimulationEdge, ISimulationGraph } from '../shared'; -import { Emitter } from '../../utils/emitter.utils'; -import { isObjectEqual, copyObject } from '../../utils/object.utils'; - -const MANY_BODY_MAX_DISTANCE_TO_LINK_DISTANCE_RATIO = 100; -const DEFAULT_LINK_DISTANCE = 50; - -export enum D3SimulatorEngineEventType { - SIMULATION_START = 'simulation-start', - SIMULATION_STOP = 'simulation-stop', - SIMULATION_PROGRESS = 'simulation-progress', - SIMULATION_END = 'simulation-end', - SIMULATION_TICK = 'simulation-tick', - SIMULATION_RESET = 'simulation-reset', - NODE_DRAG = 'node-drag', - SETTINGS_UPDATE = 'settings-update', - DATA_CLEARED = 'data-cleared', -} - -export interface ID3SimulatorEngineSettingsAlpha { - alpha: number; - alphaMin: number; - alphaDecay: number; - alphaTarget: number; -} - -export interface ID3SimulatorEngineSettingsCentering { - x: number; - y: number; - strength: number; -} - -export interface ID3SimulatorEngineSettingsCollision { - radius: number; - strength: number; - iterations: number; -} - -export interface ID3SimulatorEngineSettingsLinks { - distance: number; - strength?: number; - iterations: number; -} - -export interface ID3SimulatorEngineSettingsManyBody { - strength: number; - theta: number; - distanceMin: number; - distanceMax: number; -} - -export interface ID3SimulatorEngineSettingsPositioning { - forceX: { - x: number; - strength: number; - }; - forceY: { - y: number; - strength: number; - }; -} - -export interface ID3SimulatorEngineSettings { - isSimulatingOnDataUpdate: boolean; - isSimulatingOnSettingsUpdate: boolean; - isSimulatingOnUnstick: boolean; - isPhysicsEnabled: boolean; - alpha: ID3SimulatorEngineSettingsAlpha; - centering: ID3SimulatorEngineSettingsCentering | null; - collision: ID3SimulatorEngineSettingsCollision | null; - links: ID3SimulatorEngineSettingsLinks; - manyBody: ID3SimulatorEngineSettingsManyBody | null; - positioning: ID3SimulatorEngineSettingsPositioning | null; -} - -export type ID3SimulatorEngineSettingsUpdate = Partial; - -export const getManyBodyMaxDistance = (linkDistance: number) => { - const distance = linkDistance > 0 ? linkDistance : 1; - return distance * MANY_BODY_MAX_DISTANCE_TO_LINK_DISTANCE_RATIO; -}; - -export const DEFAULT_SETTINGS: ID3SimulatorEngineSettings = { - isSimulatingOnDataUpdate: true, - isSimulatingOnSettingsUpdate: true, - isSimulatingOnUnstick: true, - isPhysicsEnabled: false, - alpha: { - alpha: 1, - alphaMin: 0.001, - alphaDecay: 0.0228, - alphaTarget: 0, - }, - centering: { - x: 0, - y: 0, - strength: 1, - }, - collision: { - radius: 15, - strength: 1, - iterations: 1, - }, - links: { - distance: DEFAULT_LINK_DISTANCE, - strength: 1, - iterations: 1, - }, - manyBody: { - strength: -100, - theta: 0.9, - distanceMin: 0, - distanceMax: getManyBodyMaxDistance(DEFAULT_LINK_DISTANCE), - }, - positioning: { - forceX: { - x: 0, - strength: 0.1, - }, - forceY: { - y: 0, - strength: 0.1, - }, - }, -}; - -export interface ID3SimulatorProgress { - progress: number; -} - -export interface ID3SimulatorNodeId { - id: number; -} - -export interface ID3SimulatorSettings { - settings: ID3SimulatorEngineSettings; -} - -interface IRunSimulationOptions { - isUpdatingSettings: boolean; -} - -export type D3SimulatorEvents = { - [D3SimulatorEngineEventType.SIMULATION_START]: undefined; - [D3SimulatorEngineEventType.SIMULATION_PROGRESS]: ISimulationGraph & ID3SimulatorProgress; - [D3SimulatorEngineEventType.SIMULATION_END]: ISimulationGraph; - [D3SimulatorEngineEventType.SIMULATION_TICK]: ISimulationGraph; - [D3SimulatorEngineEventType.SIMULATION_RESET]: ISimulationGraph; - [D3SimulatorEngineEventType.NODE_DRAG]: ISimulationGraph; - [D3SimulatorEngineEventType.SETTINGS_UPDATE]: ID3SimulatorSettings; - [D3SimulatorEngineEventType.DATA_CLEARED]: ISimulationGraph; -}; - -export class D3SimulatorEngine extends Emitter { - protected _linkForce!: ForceLink>; - protected _simulation!: Simulation; - protected _settings: ID3SimulatorEngineSettings; - - protected _edges: ISimulationEdge[] = []; - protected _nodes: ISimulationNode[] = []; - protected _nodeIndexByNodeId: Record = {}; - - protected _isDragging = false; - protected _isStabilizing = false; - - // These are settings provided during construction if they are specified, - // or during the first call of setSettings if unspecified during construction. - protected _initialSettings: ID3SimulatorEngineSettings | undefined; - - constructor(settings?: ID3SimulatorEngineSettings) { - super(); - - if (settings !== undefined) { - this._initialSettings = Object.assign(copyObject(DEFAULT_SETTINGS), settings); - } - - this._settings = this.resetSettings(); - this.clearData(); - } - - getSettings(): ID3SimulatorEngineSettings { - return copyObject(this._settings); - } - - /** - * Applies the specified settings to the D3 simulator engine. - * - * @param {ID3SimulatorEngineSettingsUpdate} settings Partial D3 simulator engine settings (any property of settings) - */ - setSettings(settings: ID3SimulatorEngineSettingsUpdate) { - if (!this._initialSettings) { - this._initialSettings = Object.assign(copyObject(DEFAULT_SETTINGS), settings); - } - - const previousSettings = this.getSettings(); - Object.assign(this._settings, settings); - - if (isObjectEqual(this._settings, previousSettings)) { - return; - } - - this._applySettingsToSimulation(settings); - this.emit(D3SimulatorEngineEventType.SETTINGS_UPDATE, { settings: this._settings }); - - const hasPhysicsBeenDisabled = previousSettings.isPhysicsEnabled && !settings.isPhysicsEnabled; - - if (hasPhysicsBeenDisabled) { - this._simulation.stop(); - } else if (this._settings.isSimulatingOnSettingsUpdate) { - // this.runSimulation({ isUpdatingSettings: true }); - this.activateSimulation(); - } - } - - /** - * Restores simulator engine settings to the initial settings provided during construction. - * - * @return {ID3SimulatorEngineSettings} The default settings patched with the specified parameters in the - * initial settings provided in the constructor or during the first settings update. - */ - resetSettings(): ID3SimulatorEngineSettings { - return Object.assign(copyObject(DEFAULT_SETTINGS), this._initialSettings); - } - - startDragNode() { - this._isDragging = true; - - if (!this._isStabilizing && this._settings.isPhysicsEnabled) { - this.activateSimulation(); - } - } - - dragNode(data: ID3SimulatorNodeId & IPosition) { - const node = this._nodes[this._nodeIndexByNodeId[data.id]]; - if (!node) { - return; - } - - if (!this._isDragging) { - this.startDragNode(); - } - - node.fx = data.x; - node.fy = data.y; - - if (!this._settings.isPhysicsEnabled) { - node.x = data.x; - node.y = data.y; - } - - // Notify the client that the node position changed. - this.emit(D3SimulatorEngineEventType.NODE_DRAG, { nodes: this._nodes, edges: this._edges }); - } - - endDragNode(data: ID3SimulatorNodeId) { - this._isDragging = false; - - if (this._settings.isPhysicsEnabled) { - this._simulation.alphaTarget(0); - } - const node = this._nodes[this._nodeIndexByNodeId[data.id]]; - // TODO(dlozic): Add special behavior for sticky nodes that have been dragged - if (node && this._settings.isPhysicsEnabled) { - this.unfixNode(node); - } - } - - /** - * Activates the simulation and "re-heats" the nodes so that they converge to a new layout. - * This does not count as "stabilization" and won't emit any progress. - */ - activateSimulation() { - if (this._settings.isPhysicsEnabled) { - this.unfixNodes(); // If physics is disabled, the nodes get fixed in the callback from the initial setup (`simulation.on('end', () => {})`). - } else { - this.fixNodes(); - } - this._simulation.alpha(this._settings.alpha.alpha).alphaTarget(this._settings.alpha.alphaTarget).restart(); - } - - stopSimulation() { - this._simulation.stop(); - } - - setupData(data: ISimulationGraph) { - this.clearData(); - - this._initializeNewData(data); - - if (this._settings.isSimulatingOnDataUpdate) { - this._updateSimulationData(); - this._runSimulation(); - } - } - - mergeData(data: Partial) { - this._initializeNewData(data); - - if (!this._settings.isPhysicsEnabled) { - this.fixNodes(); - } - - if (this._settings.isSimulatingOnDataUpdate) { - this._updateSimulationData(); - this.activateSimulation(); - } - } - - patchData(data: Partial) { - if (data.nodes) { - data.nodes = this._fixAndStickDefinedNodes(data.nodes); - const nodeIds: { [id: number]: number } = {}; - - for (let i = 0; i < this._nodes.length; i++) { - nodeIds[this._nodes[i].id] = i; - } - - for (let i = 0; i < data.nodes.length; i += 1) { - const nodeId: any = data.nodes[i].id; - - if (nodeId in nodeIds) { - const index = nodeIds[nodeId]; - this._nodeIndexByNodeId[nodeId] = index; - this._nodes[index] = data.nodes[i]; - } else { - this._nodes.push(data.nodes[i]); - } - } - } - - if (data.edges) { - this._edges = this._edges.concat(data.edges); - } - } - - private _initializeNewData(data: Partial) { - if (data.nodes) { - data.nodes = this._fixAndStickDefinedNodes(data.nodes); - for (let i = 0; i < data.nodes.length; i += 1) { - const nodeId = data.nodes[i].id; - - if (this._nodeIndexByNodeId[nodeId]) { - this._nodeIndexByNodeId[nodeId] = i; - } else { - this._nodes.push(data.nodes[i]); - } - } - } else { - this._nodes = []; - } - if (data.edges) { - this._edges = this._edges.concat(data.edges); - } else { - this._edges = []; - } - this._setNodeIndexByNodeId(); - } - - updateData(data: ISimulationGraph) { - data.nodes = this._fixAndStickDefinedNodes(data.nodes); - - // Keep existing nodes along with their (x, y, fx, fy) coordinates to avoid - // rearranging the graph layout. - // These nodes should not be reloaded into the array because the D3 simulation - // will assign to them completely new coordinates, effectively restarting the animation. - const newNodeIds = new Set(data.nodes.map((node) => node.id)); - - // Keep old nodes that are present in the new data instead of reassigning them. - const oldNodes = this._nodes.filter((node) => newNodeIds.has(node.id)); - const newNodes = data.nodes.filter((node) => this._nodeIndexByNodeId[node.id] === undefined); - - this._nodes = [...oldNodes, ...newNodes]; - this._setNodeIndexByNodeId(); - - // Only keep new links and discard all old links. - // Old links won't work as some discrepancies arise between the D3 index property - // and Memgraph's `id` property which affects the source->target mapping. - this._edges = data.edges; - - if (this._settings.isSimulatingOnSettingsUpdate) { - this._updateSimulationData(); - this.activateSimulation(); - } - } - - /** - * Removes specified data from the simulation. - * - * @param {ISimulationGraph} data Nodes and edges that will be deleted - */ - deleteData(data: Partial<{ nodeIds: number[] | undefined; edgeIds: number[] | undefined }>) { - const nodeIds = new Set(data.nodeIds); - this._nodes = this._nodes.filter((node) => !nodeIds.has(node.id)); - const edgeIds = new Set(data.edgeIds); - this._edges = this._edges.filter((edge) => !edgeIds.has(edge.id)); - this._setNodeIndexByNodeId(); - if (this._settings.isSimulatingOnDataUpdate) { - this._updateSimulationData(); - this.activateSimulation(); - } - } - - /** - * Removes all internal and D3 simulation node and relationship data. - */ - clearData() { - const nodes = this._nodes; - const edges = this._edges; - this._nodes = []; - this._edges = []; - this._setNodeIndexByNodeId(); - this.resetSimulation(); - this.emit(D3SimulatorEngineEventType.DATA_CLEARED, { nodes: nodes, edges: edges }); - } - - /** - * Updates the internal D3 simulation data with the current data. - */ - private _updateSimulationData() { - // Update simulation with new data. - this._simulation.nodes(this._nodes); - this._linkForce.links(this._edges); - } - - /** - * Resets the simulator engine by discarding all existing simulator data (nodes and edges), - * and keeping the current simulator engine settings. - */ - // TODO(Alex): Listeners memory leak (D3 force research) - resetSimulation() { - this._linkForce = forceLink>(this._edges).id( - (node) => node.id, - ); - this._simulation = forceSimulation(this._nodes).force('link', this._linkForce).stop(); - - this._applySettingsToSimulation(this._settings); - - this._simulation.on('tick', () => { - this.emit(D3SimulatorEngineEventType.SIMULATION_TICK, { nodes: this._nodes, edges: this._edges }); - }); - - this._simulation.on('end', () => { - this._isDragging = false; - this._isStabilizing = false; - this.emit(D3SimulatorEngineEventType.SIMULATION_END, { nodes: this._nodes, edges: this._edges }); - - if (!this._settings.isPhysicsEnabled) { - this.fixNodes(); - } - }); - - this.emit(D3SimulatorEngineEventType.SIMULATION_RESET, { nodes: this._nodes, edges: this._edges }); - } - - /** - * Fixes all nodes by setting their `fx` and `fy` properties to `x` and `y`. - * If no nodes are provided, this function fixes all nodes. - * - * @param {ISimulationNode[]} nodes Nodes that are going to be fixed. If undefined, all nodes get fixed. - */ - fixNodes(nodes?: ISimulationNode[]) { - if (!nodes) { - nodes = this._nodes; - } - - for (let i = 0; i < nodes.length; i++) { - this.fixNode(this._nodes[i]); - } - } - - /** - * Releases specified nodes. - * If no nodes are provided, this function releases all nodes. - * - * @param {ISimulationNode[]} nodes Nodes that are going to be released. If undefined, all nodes get released. - */ - unfixNodes(nodes?: ISimulationNode[]) { - if (!nodes) { - nodes = this._nodes; - } - - for (let i = 0; i < nodes.length; i++) { - this.unfixNode(this._nodes[i]); - } - } - - /** - * Fixes a node by setting its `fx` and `fy` properties to `x` and `y`. - * This function is called when disabling physics. - * - * @param {ISimulationNode} node Simulation node that is going to be fixed - */ - fixNode(node: ISimulationNode) { - if (node.sx === null || node.sx === undefined) { - node.fx = node.x; - } - if (node.sy === null || node.sy === undefined) { - node.fy = node.y; - } - } - - /** - * Releases a node if it's not sticky by setting its `fx` and `fy` properties to `null`. - * This function is called when enabling physics but the sticky property overpowers physics. - * - * @param {ISimulationNode} node Simulation node that is going to be released - */ - unfixNode(node: ISimulationNode) { - if (node.sx === null || node.sx === undefined) { - node.fx = null; - } - if (node.sy === null || node.sy === undefined) { - node.fy = null; - } - } - - /** - * Sticks the specified nodes into place. - * This overpowers any physics state and also sticks the node to their current positions. - * If no nodes are provided, this function sticks all nodes. - * - * @param {ISimulationNode[]} nodes Nodes that are going to become sticky. If undefined, all nodes get sticked. - */ - stickNodes(nodes?: ISimulationNode[]) { - if (!nodes) { - nodes = this._nodes; - } - - for (let i = 0; i < nodes.length; i++) { - this.stickNode(this._nodes[i]); - } - } - - /** - * Removes the sticky properties from all specified nodes. - * If physics is enabled, the nodes get unfixed as well. - * If no nodes are provided, this function unsticks all nodes. - * - * @param {ISimulationNode[]} nodes Nodes that are going to be unsticked. If undefined, all nodes get unsticked. - */ - unstickNodes(nodes?: ISimulationNode[]) { - if (!nodes) { - nodes = this._nodes; - } - - for (let i = 0; i < nodes.length; i++) { - this.unstickNode(this._nodes[i]); - } - - if (this._settings.isSimulatingOnUnstick) { - this.activateSimulation(); - } - } - - /** - * Sticks a node into place. - * This function overpowers any physics state and also sticks the node to its current coordinates. - * - * @param {ISimulationNode} node Simulation node that is going to become sticky - */ - stickNode(node: ISimulationNode) { - node.sx = node.x; - node.fx = node.x; - node.sy = node.y; - node.fy = node.y; - } - - /** - * Removes the sticky properties from the node. - * If physics is enabled, the node gets released as well. - * - * @param {ISimulationNode} node Simulation node that gets unstuck - */ - unstickNode(node: ISimulationNode) { - node.sx = null; - node.sy = null; - - if (this._settings.isPhysicsEnabled) { - node.fx = null; - node.fy = null; - } - } - - /** - * Sticks all nodes thath have a defined position (x and y coordinates). - * This function should be called when the user initially sets up or merges some data. - * If the user provided nodes already have defined `x` **or** `y` properties, they are treated as _"sticky"_. - * Only the specified axis gets immobilized. - * - * @param {ISimulationNode[]} nodes Graph nodes. - * @return {ISimulationNodes[]} Graph nodes with attached `{fx, sx}`, and/or `{fy, sy}` coordinates. - */ - private _fixAndStickDefinedNodes(nodes: ISimulationNode[]): ISimulationNode[] { - for (let i = 0; i < nodes.length; i++) { - if (nodes[i].x !== null && nodes[i].x !== undefined) { - nodes[i].fx = nodes[i].x; - nodes[i].sx = nodes[i].x; - } - if (nodes[i].y !== null && nodes[i].y !== undefined) { - nodes[i].fy = nodes[i].y; - nodes[i].sy = nodes[i].y; - } - } - return nodes; - } - - /** - * Applies the provided settings to the D3 simulation. - * - * @param {ID3SimulatorEngineSettingsUpdate} settings Simulator engine settings - */ - private _applySettingsToSimulation(settings: ID3SimulatorEngineSettingsUpdate) { - if (settings.alpha) { - this._simulation - .alpha(settings.alpha.alpha) - .alphaMin(settings.alpha.alphaMin) - .alphaDecay(settings.alpha.alphaDecay) - .alphaTarget(settings.alpha.alphaTarget); - } - if (settings.links) { - this._linkForce.distance(settings.links.distance).iterations(settings.links.iterations); - } - if (settings.collision) { - const collision = forceCollide() - .radius(settings.collision.radius) - .strength(settings.collision.strength) - .iterations(settings.collision.iterations); - this._simulation.force('collide', collision); - } - if (settings.collision === null) { - this._simulation.force('collide', null); - } - if (settings.manyBody) { - const manyBody = forceManyBody() - .strength(settings.manyBody.strength) - .theta(settings.manyBody.theta) - .distanceMin(settings.manyBody.distanceMin) - .distanceMax(settings.manyBody.distanceMax); - this._simulation.force('charge', manyBody); - } - if (settings.manyBody === null) { - this._simulation.force('charge', null); - } - if (settings.positioning?.forceY) { - const positioningForceX = forceX(settings.positioning.forceX.x).strength(settings.positioning.forceX.strength); - this._simulation.force('x', positioningForceX); - } - if (settings.positioning?.forceX === null) { - this._simulation.force('x', null); - } - if (settings.positioning?.forceY) { - const positioningForceY = forceY(settings.positioning.forceY.y).strength(settings.positioning.forceY.strength); - this._simulation.force('y', positioningForceY); - } - if (settings.positioning?.forceY === null) { - this._simulation.force('y', null); - } - if (settings.centering) { - const centering = forceCenter(settings.centering.x, settings.centering.y).strength(settings.centering.strength); - this._simulation.force('center', centering); - } - if (settings.centering === null) { - this._simulation.force('center', null); - } - } - - // This is a blocking action - the user will not be able to interact with the graph - // during the simulation process. - private _runSimulation(options?: IRunSimulationOptions) { - if (this._isStabilizing) { - return; - } - if (this._settings.isPhysicsEnabled || options?.isUpdatingSettings) { - this.unfixNodes(); - } - - this.emit(D3SimulatorEngineEventType.SIMULATION_START, undefined); - - this._isStabilizing = true; - this._simulation.alpha(this._settings.alpha.alpha).alphaTarget(this._settings.alpha.alphaTarget).stop(); - - const totalSimulationSteps = Math.ceil( - Math.log(this._settings.alpha.alphaMin) / Math.log(1 - this._settings.alpha.alphaDecay), - ); - - let lastProgress = -1; - for (let i = 0; i < totalSimulationSteps; i++) { - const currentProgress = Math.round((i * 100) / totalSimulationSteps); - // Emit progress maximum of 100 times (every percent) - if (currentProgress > lastProgress) { - lastProgress = currentProgress; - this.emit(D3SimulatorEngineEventType.SIMULATION_PROGRESS, { - nodes: this._nodes, - edges: this._edges, - progress: currentProgress / 100, - }); - } - this._simulation.tick(); - } - - if (!this._settings.isPhysicsEnabled) { - this.fixNodes(); - } - - this._isStabilizing = false; - this.emit(D3SimulatorEngineEventType.SIMULATION_END, { nodes: this._nodes, edges: this._edges }); - } - - private _setNodeIndexByNodeId() { - this._nodeIndexByNodeId = {}; - for (let i = 0; i < this._nodes.length; i++) { - this._nodeIndexByNodeId[this._nodes[i].id] = i; - } - } -} diff --git a/src/simulator/engine/engines/base-layout-engine.ts b/src/simulator/engine/engines/base-layout-engine.ts new file mode 100644 index 0000000..1df8506 --- /dev/null +++ b/src/simulator/engine/engines/base-layout-engine.ts @@ -0,0 +1,61 @@ +import { IPosition } from '../../../common'; +import { Emitter } from '../../../utils/emitter.utils'; +import { ISimulationNode, ISimulationEdge, ISimulationGraph, ISimulationIds, SimulatorEvents } from '../../shared'; +import { ILayoutEngine, IEngineSettingsUpdate, LayoutType } from '../shared'; + +export abstract class BaseLayoutEngine extends Emitter implements ILayoutEngine { + protected _nodes: ISimulationNode[] = []; + protected _edges: ISimulationEdge[] = []; + protected _nodeIndexByNodeId: Record = {}; + protected _cancelSimulation = false; + private _schedulerPort: MessagePort | null = null; + + abstract readonly type: LayoutType; + + abstract setupData(data: ISimulationGraph): void; + abstract mergeData(data: ISimulationGraph): void; + abstract updateData(data: ISimulationGraph): void; + abstract deleteData(data: Partial): void; + abstract patchData(data: Partial): void; + abstract clearData(): void; + + abstract activateSimulation(): void; + abstract stopSimulation(): void; + + abstract startDragNode(): void; + abstract dragNode(nodeId: number, position: IPosition): void; + abstract endDragNode(nodeId: number): void; + abstract fixNodes(nodes?: ISimulationNode[]): void; + abstract releaseNodes(nodes?: ISimulationNode[]): void; + + abstract setSettings(settings: IEngineSettingsUpdate): void; + + terminate(): void { + this._cancelSimulation = true; + this._schedulerPort?.close(); + this._schedulerPort = null; + this.removeAllListeners(); + } + + // use MessageChannel for microtask-like scheduling that avoids setTimeout's ~4ms minimum delay + protected _scheduleNext(callback: () => void): void { + if (typeof MessageChannel !== 'undefined') { + const channel = new MessageChannel(); + this._schedulerPort = channel.port2; + channel.port1.onmessage = () => { + this._schedulerPort = null; + callback(); + }; + channel.port2.postMessage(null); + } else { + setTimeout(callback, 0); + } + } + + protected _rebuildNodeIndex(): void { + this._nodeIndexByNodeId = {}; + for (let i = 0; i < this._nodes.length; i++) { + this._nodeIndexByNodeId[this._nodes[i].id] = i; + } + } +} diff --git a/src/simulator/engine/engines/dynamic/force-layout-engine.ts b/src/simulator/engine/engines/dynamic/force-layout-engine.ts new file mode 100644 index 0000000..40dd4f8 --- /dev/null +++ b/src/simulator/engine/engines/dynamic/force-layout-engine.ts @@ -0,0 +1,506 @@ +import { + forceCenter, + forceCollide, + forceLink, + ForceLink, + forceManyBody, + forceSimulation, + forceX, + forceY, + Simulation, + SimulationLinkDatum, +} from 'd3-force'; +import { IPosition } from '../../../../common'; +import { ISimulationNode, ISimulationGraph, ISimulationIds, SimulatorEventType } from '../../../shared'; +import { isObjectEqual, copyObject } from '../../../../utils/object.utils'; +import { IEngineSettingsUpdate, IForceLayoutOptions, DEFAULT_FORCE_LAYOUT_OPTIONS, LayoutType } from '../../shared'; +import { BaseLayoutEngine } from '../base-layout-engine'; + +const MAX_SIMULATION_STEPS = 500; +const CHUNK_SIZE = 100; + +interface IRunSimulationOptions { + isUpdatingSettings: boolean; +} + +export class ForceLayoutEngine extends BaseLayoutEngine { + private _linkForce!: ForceLink>; + private _simulation!: Simulation; + private _settings: IForceLayoutOptions; + + private _isDragging = false; + private _isStabilizing = false; + + private _initialSettings: IForceLayoutOptions | undefined; + + readonly type: LayoutType = 'force'; + + constructor(options?: IForceLayoutOptions) { + super(); + this._settings = { + ...DEFAULT_FORCE_LAYOUT_OPTIONS, + ...options, + }; + this.clearData(); + } + + setSettings(settings: IEngineSettingsUpdate) { + const forceSettings = settings as Partial; + + if (!this._initialSettings) { + this._initialSettings = Object.assign(copyObject(DEFAULT_FORCE_LAYOUT_OPTIONS), forceSettings); + } + + const previousSettings = copyObject(this._settings); + Object.assign(this._settings, forceSettings); + + if (isObjectEqual(this._settings, previousSettings)) { + return; + } + + this._applySettingsToSimulation(forceSettings); + this.emit(SimulatorEventType.SETTINGS_UPDATE, { + settings: { type: 'force', options: this._settings }, + }); + + const hasPhysicsBeenDisabled = previousSettings.isPhysicsEnabled && !forceSettings.isPhysicsEnabled; + + if (hasPhysicsBeenDisabled) { + this._simulation.stop(); + } else if (this._settings.isSimulatingOnSettingsUpdate && this._nodes.length > 0) { + this.activateSimulation(); + } + } + + setupData(data: ISimulationGraph) { + this.clearData(); + this._initializeNewData(data); + + if (this._settings.isSimulatingOnDataUpdate) { + this._updateSimulationData(); + this._runSimulation(); + } + } + + mergeData(data: ISimulationGraph) { + this._initializeNewData(data); + + if (!this._settings.isPhysicsEnabled) { + this._pinNodes(); + } + + if (this._settings.isSimulatingOnDataUpdate) { + this._updateSimulationData(); + this.activateSimulation(); + } + } + + updateData(data: ISimulationGraph) { + const newNodeIds = new Set(data.nodes.map((node) => node.id)); + const oldNodes = this._nodes.filter((node) => newNodeIds.has(node.id)); + const newNodes = data.nodes.filter((node) => this._nodeIndexByNodeId[node.id] === undefined); + + this._nodes = [...oldNodes, ...newNodes]; + this._rebuildNodeIndex(); + this._edges = data.edges; + + if (this._settings.isSimulatingOnSettingsUpdate) { + this._updateSimulationData(); + this.activateSimulation(); + } + } + + deleteData(data: Partial) { + if (data.nodeIds) { + const nodeIds = new Set(data.nodeIds); + this._nodes = this._nodes.filter((node) => !nodeIds.has(node.id)); + } + if (data.edgeIds) { + const edgeIds = new Set(data.edgeIds); + this._edges = this._edges.filter((edge) => !edgeIds.has(edge.id)); + } + this._rebuildNodeIndex(); + + if (this._settings.isSimulatingOnDataUpdate) { + this._updateSimulationData(); + this.activateSimulation(); + } + } + + patchData(data: Partial) { + if (data.nodes) { + const nodeIds: { [id: number]: number } = {}; + + for (let i = 0; i < this._nodes.length; i++) { + nodeIds[this._nodes[i].id] = i; + } + + for (let i = 0; i < data.nodes.length; i += 1) { + const nodeId: number = data.nodes[i].id; + + if (nodeId in nodeIds) { + const index = nodeIds[nodeId]; + this._nodeIndexByNodeId[nodeId] = index; + this._nodes[index] = data.nodes[i]; + } else { + this._nodes.push(data.nodes[i]); + } + } + } + + if (data.edges) { + const edgeIds: { [id: number]: number } = {}; + for (let i = 0; i < this._edges.length; i++) { + edgeIds[this._edges[i].id] = i; + } + for (let i = 0; i < data.edges.length; i++) { + const edgeId = data.edges[i].id; + if (edgeId in edgeIds) { + this._edges[edgeIds[edgeId]] = data.edges[i]; + } else { + this._edges.push(data.edges[i]); + } + } + } + } + + clearData() { + this._nodes = []; + this._edges = []; + this._rebuildNodeIndex(); + this._resetSimulation(); + } + + activateSimulation() { + if (this._settings.isPhysicsEnabled) { + this._unpinNodes(); + } else { + this._pinNodes(); + } + this._simulation.alpha(this._settings.alpha.alpha).alphaTarget(this._settings.alpha.alphaTarget).restart(); + } + + stopSimulation() { + this._simulation.stop(); + } + + startDragNode() { + this._isDragging = true; + + if (!this._isStabilizing && this._settings.isPhysicsEnabled) { + this.activateSimulation(); + } + } + + dragNode(nodeId: number, position: IPosition) { + const node = this._nodes[this._nodeIndexByNodeId[nodeId]]; + if (!node) { + return; + } + + if (!this._isDragging) { + this.startDragNode(); + } + + node.fx = position.x; + node.fy = position.y; + + if (!this._settings.isPhysicsEnabled) { + node.x = position.x; + node.y = position.y; + } + + this.emit(SimulatorEventType.NODE_DRAG, { nodes: this._nodes, edges: this._edges }); + } + + endDragNode(nodeId: number) { + this._isDragging = false; + + if (this._settings.isPhysicsEnabled) { + this._simulation.alphaTarget(0); + } + const node = this._nodes[this._nodeIndexByNodeId[nodeId]]; + if (node && this._settings.isPhysicsEnabled) { + this._unpinNode(node); + } + } + + fixNodes(nodes?: ISimulationNode[]) { + if (!nodes) { + nodes = this._nodes; + } + for (let i = 0; i < nodes.length; i++) { + this._stickNode(nodes[i]); + } + } + + releaseNodes(nodes?: ISimulationNode[]) { + if (!nodes) { + nodes = this._nodes; + } + for (let i = 0; i < nodes.length; i++) { + this._unstickNode(nodes[i]); + } + + if (this._settings.isSimulatingOnUnstick && this._nodes.length > 0) { + this.activateSimulation(); + } + } + + terminate() { + super.terminate(); + this._simulation?.stop(); + } + + // TODO(Alex): Listeners memory leak (D3 force research) + private _resetSimulation() { + if (this._simulation) { + this._simulation.stop(); + this._simulation.on('tick', null).on('end', null); + } + + this._linkForce = forceLink>(this._edges).id( + (node) => node.id, + ); + this._simulation = forceSimulation(this._nodes).force('link', this._linkForce).stop(); + + this._applySettingsToSimulation(this._settings); + + this._simulation.on('tick', () => { + this.emit(SimulatorEventType.SIMULATION_STEP, { nodes: this._nodes, edges: this._edges }); + }); + + this._simulation.on('end', () => { + this._isDragging = false; + this._isStabilizing = false; + this.emit(SimulatorEventType.SIMULATION_END, { nodes: this._nodes, edges: this._edges }); + + if (!this._settings.isPhysicsEnabled) { + this._pinNodes(); + } + }); + } + + private _runSimulation(options?: IRunSimulationOptions) { + if (this._isStabilizing || this._cancelSimulation) { + return; + } + + if (this._settings.isPhysicsEnabled || options?.isUpdatingSettings) { + this._unpinNodes(); + } + + this.emit(SimulatorEventType.SIMULATION_START, undefined); + + this._isStabilizing = true; + this._simulation.alpha(this._settings.alpha.alpha).alphaTarget(this._settings.alpha.alphaTarget).stop(); + + const totalSimulationSteps = Math.min( + MAX_SIMULATION_STEPS, + Math.ceil(Math.log(this._settings.alpha.alphaMin) / Math.log(1 - this._settings.alpha.alphaDecay)), + ); + + let lastProgress = -1; + let step = 0; + + const runChunk = () => { + if (this._cancelSimulation) { + this._isStabilizing = false; + this._cancelSimulation = false; + return; + } + + const end = Math.min(step + CHUNK_SIZE, totalSimulationSteps); + + for (; step < end; step++) { + this._simulation.tick(); + + const currentProgress = Math.round((step * 100) / totalSimulationSteps); + if (currentProgress > lastProgress) { + lastProgress = currentProgress; + this.emit(SimulatorEventType.SIMULATION_PROGRESS, { + nodes: this._nodes, + edges: this._edges, + progress: currentProgress / 100, + }); + } + } + + if (step < totalSimulationSteps && !this._cancelSimulation) { + this._scheduleNext(runChunk); + } else { + if (!this._settings.isPhysicsEnabled) { + this._pinNodes(); + } + + this._isStabilizing = false; + this._cancelSimulation = false; + this.emit(SimulatorEventType.SIMULATION_END, { nodes: this._nodes, edges: this._edges }); + } + }; + + runChunk(); + } + + private _updateSimulationData() { + this._simulation.nodes(this._nodes); + this._linkForce.links(this._edges); + } + + private _initializeNewData(data: Partial) { + if (data.nodes) { + for (let i = 0; i < data.nodes.length; i += 1) { + const nodeId = data.nodes[i].id; + + if (this._nodeIndexByNodeId[nodeId] !== undefined) { + this._nodeIndexByNodeId[nodeId] = i; + } else { + this._nodes.push(data.nodes[i]); + } + } + } else { + this._nodes = []; + } + + if (data.edges) { + const edgeIds: { [id: number]: number } = {}; + for (let i = 0; i < this._edges.length; i++) { + edgeIds[this._edges[i].id] = i; + } + for (let i = 0; i < data.edges.length; i++) { + const edgeId = data.edges[i].id; + if (edgeId in edgeIds) { + this._edges[edgeIds[edgeId]] = data.edges[i]; + } else { + this._edges.push(data.edges[i]); + } + } + } else { + this._edges = []; + } + + this._rebuildNodeIndex(); + } + + private _pinNodes(nodes?: ISimulationNode[]) { + if (!nodes) { + nodes = this._nodes; + } + for (let i = 0; i < nodes.length; i++) { + this._pinNode(this._nodes[i]); + } + } + + private _unpinNodes(nodes?: ISimulationNode[]) { + if (!nodes) { + nodes = this._nodes; + } + + for (let i = 0; i < nodes.length; i++) { + this._unpinNode(this._nodes[i]); + } + } + + private _pinNode(node: ISimulationNode) { + if (node.sx === null || node.sx === undefined) { + node.fx = node.x; + } + + if (node.sy === null || node.sy === undefined) { + node.fy = node.y; + } + } + + private _unpinNode(node: ISimulationNode) { + if (node.sx === null || node.sx === undefined) { + node.fx = null; + } + + if (node.sy === null || node.sy === undefined) { + node.fy = null; + } + } + + private _stickNode(node: ISimulationNode) { + node.sx = node.x; + node.fx = node.x; + node.sy = node.y; + node.fy = node.y; + } + + private _unstickNode(node: ISimulationNode) { + node.sx = null; + node.sy = null; + + if (this._settings.isPhysicsEnabled) { + node.fx = null; + node.fy = null; + } + } + + private _applySettingsToSimulation(settings: Partial) { + if (settings.alpha) { + this._simulation + .alpha(settings.alpha.alpha) + .alphaMin(settings.alpha.alphaMin) + .alphaDecay(settings.alpha.alphaDecay) + .alphaTarget(settings.alpha.alphaTarget); + } + + if (settings.links) { + this._linkForce.distance(settings.links.distance).iterations(settings.links.iterations); + } + + if (settings.collision) { + const collision = forceCollide() + .radius(settings.collision.radius) + .strength(settings.collision.strength) + .iterations(settings.collision.iterations); + this._simulation.force('collide', collision); + } + + if (settings.collision === null) { + this._simulation.force('collide', null); + } + + if (settings.manyBody) { + const manyBody = forceManyBody() + .strength(settings.manyBody.strength) + .theta(settings.manyBody.theta) + .distanceMin(settings.manyBody.distanceMin) + .distanceMax(settings.manyBody.distanceMax); + this._simulation.force('charge', manyBody); + } + + if (settings.manyBody === null) { + this._simulation.force('charge', null); + } + + if (settings.positioning?.forceX) { + const positioningForceX = forceX(settings.positioning.forceX.x).strength(settings.positioning.forceX.strength); + this._simulation.force('x', positioningForceX); + } + + if (settings.positioning?.forceX === null) { + this._simulation.force('x', null); + } + + if (settings.positioning?.forceY) { + const positioningForceY = forceY(settings.positioning.forceY.y).strength(settings.positioning.forceY.strength); + this._simulation.force('y', positioningForceY); + } + + if (settings.positioning?.forceY === null) { + this._simulation.force('y', null); + } + + if (settings.centering) { + const centering = forceCenter(settings.centering.x, settings.centering.y).strength(settings.centering.strength); + this._simulation.force('center', centering); + } + + if (settings.centering === null) { + this._simulation.force('center', null); + } + } +} diff --git a/src/simulator/engine/engines/static/circular-layout-engine.ts b/src/simulator/engine/engines/static/circular-layout-engine.ts new file mode 100644 index 0000000..24b3903 --- /dev/null +++ b/src/simulator/engine/engines/static/circular-layout-engine.ts @@ -0,0 +1,49 @@ +import { ISimulationNode, ISimulationEdge } from '../../../shared'; +import { ICircularLayoutOptions, DEFAULT_CIRCULAR_LAYOUT_OPTIONS, LayoutType } from '../../shared'; +import { CHUNK_SIZE, StaticLayoutEngine } from './static-layout-engine'; + +export class CircularLayoutEngine extends StaticLayoutEngine { + protected _config: ICircularLayoutOptions; + + readonly type: LayoutType = 'circular'; + + constructor(options?: ICircularLayoutOptions) { + super(); + this._config = { ...DEFAULT_CIRCULAR_LAYOUT_OPTIONS, ...options }; + } + + protected calculatePositions( + nodes: ISimulationNode[], + _edges: ISimulationEdge[], + onProgress: (progress: number) => void, + isCancelled: () => boolean, + onComplete: () => void, + ) { + const angleStep = (2 * Math.PI) / nodes.length; + let lastProgress = -1; + let step = 0; + + const runChunk = () => { + if (isCancelled()) { + onComplete(); + return; + } + + const end = Math.min(step + CHUNK_SIZE, nodes.length); + + for (; step < end; step++) { + nodes[step].x = this._config.centerX + this._config.radius * Math.cos(angleStep * step); + nodes[step].y = this._config.centerY + this._config.radius * Math.sin(angleStep * step); + } + + if (step < nodes.length && !this._cancelSimulation) { + lastProgress = this._emitProgress(step + 1, nodes.length, lastProgress, onProgress); + this._scheduleNext(runChunk); + } else { + onComplete(); + } + }; + + runChunk(); + } +} diff --git a/src/simulator/engine/engines/static/grid-layout-engine.ts b/src/simulator/engine/engines/static/grid-layout-engine.ts new file mode 100644 index 0000000..d4b51de --- /dev/null +++ b/src/simulator/engine/engines/static/grid-layout-engine.ts @@ -0,0 +1,53 @@ +import { ISimulationNode, ISimulationEdge } from '../../../shared'; +import { IGridLayoutOptions, DEFAULT_GRID_LAYOUT_OPTIONS, LayoutType } from '../../shared'; +import { CHUNK_SIZE, StaticLayoutEngine } from './static-layout-engine'; + +export class GridLayoutEngine extends StaticLayoutEngine { + protected _config: IGridLayoutOptions; + + readonly type: LayoutType = 'grid'; + + constructor(options?: IGridLayoutOptions) { + super(); + this._config = { ...DEFAULT_GRID_LAYOUT_OPTIONS, ...options }; + } + + protected calculatePositions( + nodes: ISimulationNode[], + _edges: ISimulationEdge[], + onProgress: (progress: number) => void, + isCancelled: () => boolean, + onComplete: () => void, + ) { + const rows = Math.ceil(Math.sqrt(nodes.length)); + const cols = Math.ceil(nodes.length / rows); + let lastProgress = -1; + let step = 0; + + const runChunk = () => { + if (isCancelled()) { + onComplete(); + return; + } + + const end = Math.min(step + CHUNK_SIZE, nodes.length); + + for (; step < end; step++) { + const row = Math.floor(step / cols); + const col = step % cols; + nodes[step].x = col * this._config.colGap; + nodes[step].y = row * this._config.rowGap; + } + + if (step < nodes.length && !this._cancelSimulation) { + console.log(step); + lastProgress = this._emitProgress(step + 1, nodes.length, lastProgress, onProgress); + this._scheduleNext(runChunk); + } else { + onComplete(); + } + }; + + runChunk(); + } +} diff --git a/src/simulator/engine/engines/static/hierarchical-layout-engine.ts b/src/simulator/engine/engines/static/hierarchical-layout-engine.ts new file mode 100644 index 0000000..4c1fdae --- /dev/null +++ b/src/simulator/engine/engines/static/hierarchical-layout-engine.ts @@ -0,0 +1,220 @@ +import { ISimulationNode, ISimulationEdge } from '../../../shared'; +import { IHierarchicalLayoutOptions, DEFAULT_HIERARCHICAL_LAYOUT_OPTIONS, LayoutType } from '../../shared'; +import { StaticLayoutEngine } from './static-layout-engine'; + +export class HierarchicalLayoutEngine extends StaticLayoutEngine { + protected _config: IHierarchicalLayoutOptions; + + readonly type: LayoutType = 'hierarchical'; + + constructor(options?: IHierarchicalLayoutOptions) { + super(); + this._config = { ...DEFAULT_HIERARCHICAL_LAYOUT_OPTIONS, ...options }; + } + + protected calculatePositions( + nodes: ISimulationNode[], + edges: ISimulationEdge[], + onProgress: (progress: number) => void, + isCancelled: () => boolean, + onComplete: () => void, + ) { + const { adjacency, inDegree } = this._buildAdjacency(nodes, edges); + const components = this._getConnectedComponents(nodes, adjacency); + + let maxX = 0; + let maxHeight = 0; + let counter = 0; + let lastProgress = -1; + let componentIndex = 0; + + const processComponent = () => { + if (isCancelled() || componentIndex >= components.length) { + if (!isCancelled() && this._config.reversed) { + this._applyReversal(nodes, maxX, maxHeight); + } + onComplete(); + return; + } + + const levels = this._assignLevels(components[componentIndex], adjacency, inDegree); + const maxLevelSize = Math.max(...Array.from(levels.values()).map((level) => level.length)); + + if (levels.size * this._config.levelGap > maxHeight) { + maxHeight = levels.size * this._config.levelGap; + } + + let offsetX = componentIndex === 0 ? 0 : this._config.treeGap + maxX; + + if (componentIndex > 0) { + offsetX += ((maxLevelSize - 1) * this._config.nodeGap) / 2; + } + + for (let j = 0; j < levels.size; j++) { + const y = j * this._config.levelGap; + const level = levels.get(j); + if (!level) { + continue; + } + + const width = level.length * this._config.nodeGap; + + for (let k = 0; k < level.length; k++) { + const nodeId = level[k]; + const nodeIndex = this._nodeIndexByNodeId[nodeId]; + const x = width / 2 - k * this._config.nodeGap + offsetX; + + if (x > maxX) { + maxX = x; + } + + if (nodeIndex !== undefined) { + nodes[nodeIndex].x = this._config.orientation === 'horizontal' ? y : x; + nodes[nodeIndex].y = this._config.orientation === 'horizontal' ? x : y; + } + + counter++; + } + } + + componentIndex++; + + if (componentIndex < components.length && !this._cancelSimulation) { + lastProgress = this._emitProgress(counter, nodes.length, lastProgress, onProgress); + this._scheduleNext(processComponent); + } else { + if (!isCancelled() && this._config.reversed) { + this._applyReversal(nodes, maxX, maxHeight); + } + onComplete(); + } + }; + + processComponent(); + } + + private _applyReversal(nodes: ISimulationNode[], maxX: number, maxHeight: number) { + for (let i = 0; i < nodes.length; i++) { + if (this._config.orientation === 'horizontal' && nodes[i].x !== undefined) { + nodes[i].x = maxX - (nodes[i].x ?? 0); + } + if (this._config.orientation === 'vertical' && nodes[i].y !== undefined) { + nodes[i].y = maxHeight - (nodes[i].y ?? 0); + } + } + } + + private _buildAdjacency( + _nodes: ISimulationNode[], + edges: ISimulationEdge[], + ): { adjacency: Map; inDegree: Map } { + const adjacency = new Map(); + const inDegree = new Map(); + + for (let i = 0; i < edges.length; i++) { + const sourceId = this._getEdgeEndpointId(edges[i].source); + const targetId = this._getEdgeEndpointId(edges[i].target); + + if (sourceId === targetId) { + continue; + } + + if (!adjacency.has(sourceId)) { + adjacency.set(sourceId, []); + } + if (!adjacency.has(targetId)) { + adjacency.set(targetId, []); + } + + adjacency.get(sourceId)?.push(targetId); + adjacency.get(targetId)?.push(sourceId); + + inDegree.set(targetId, (inDegree.get(targetId) ?? 0) + 1); + } + + return { adjacency, inDegree }; + } + + private _getConnectedComponents(nodes: ISimulationNode[], adjacency: Map): number[][] { + const visited = new Set(); + const components: number[][] = []; + + for (let i = 0; i < nodes.length; i++) { + const nodeId = nodes[i].id; + if (visited.has(nodeId)) { + continue; + } + + const component: number[] = []; + const queue: number[] = [nodeId]; + visited.add(nodeId); + + while (queue.length > 0) { + const current = queue.pop(); + if (current === undefined) { + continue; + } + + component.push(current); + + const neighbors = adjacency.get(current) ?? []; + for (let j = 0; j < neighbors.length; j++) { + if (!visited.has(neighbors[j])) { + visited.add(neighbors[j]); + queue.push(neighbors[j]); + } + } + } + + components.push(component); + } + + return components; + } + + private _assignLevels( + componentNodeIds: number[], + adjacency: Map, + inDegree: Map, + ): Map { + const levels = new Map(); + const visited = new Set(); + + let root = componentNodeIds.find((id) => (inDegree.get(id) ?? 0) === 0); + if (root === undefined) { + root = componentNodeIds.reduce((minId, id) => + (inDegree.get(id) ?? 0) < (inDegree.get(minId) ?? 0) ? id : minId, + ); + } + + const queue: [number, number][] = [[root, 0]]; + + for (const [nodeId, level] of queue) { + if (visited.has(nodeId)) { + continue; + } + + visited.add(nodeId); + + if (levels.has(level)) { + levels.get(level)?.push(nodeId); + } else { + levels.set(level, [nodeId]); + } + + const neighbors = adjacency.get(nodeId) ?? []; + for (let i = 0; i < neighbors.length; i++) { + queue.push([neighbors[i], level + 1]); + } + } + + return levels; + } + + private _getEdgeEndpointId(endpoint: number | string | ISimulationNode): number { + if (typeof endpoint === 'object') { + return endpoint.id; + } + return endpoint as number; + } +} diff --git a/src/simulator/engine/engines/static/static-layout-engine.ts b/src/simulator/engine/engines/static/static-layout-engine.ts new file mode 100644 index 0000000..08f9869 --- /dev/null +++ b/src/simulator/engine/engines/static/static-layout-engine.ts @@ -0,0 +1,233 @@ +import { IPosition } from '../../../../common'; +import { copyObject, isObjectEqual } from '../../../../utils/object.utils'; +import { + ISimulationNode, + ISimulationEdge, + ISimulationGraph, + ISimulationIds, + SimulatorEventType, +} from '../../../shared'; +import { IEngineSettingsUpdate, ILayoutOptionsBase, LayoutType } from '../../shared'; +import { BaseLayoutEngine } from '../base-layout-engine'; + +export const CHUNK_SIZE = 5000; + +export abstract class StaticLayoutEngine extends BaseLayoutEngine { + protected abstract _config: T; + + private _isCalculating = false; + private _pendingRecalculation = false; + + abstract readonly type: LayoutType; + + setupData(data: ISimulationGraph) { + this._nodes = [...data.nodes]; + this._edges = [...data.edges]; + this._rebuildNodeIndex(); + this._calculateAndEmit(); + } + + mergeData(data: ISimulationGraph) { + if (data.nodes) { + for (let i = 0; i < data.nodes.length; i++) { + const existingIndex = this._nodeIndexByNodeId[data.nodes[i].id]; + if (existingIndex !== undefined) { + this._nodes[existingIndex] = data.nodes[i]; + } else { + this._nodes.push(data.nodes[i]); + } + } + } + + if (data.edges) { + const edgeIds: { [id: number]: number } = {}; + for (let i = 0; i < this._edges.length; i++) { + edgeIds[this._edges[i].id] = i; + } + for (let i = 0; i < data.edges.length; i++) { + const edgeId = data.edges[i].id; + if (edgeId in edgeIds) { + this._edges[edgeIds[edgeId]] = data.edges[i]; + } else { + this._edges.push(data.edges[i]); + } + } + } + + this._rebuildNodeIndex(); + this._calculateAndEmit(); + } + + updateData(data: ISimulationGraph) { + const newNodeIds = new Set(data.nodes.map((node) => node.id)); + const oldNodes = this._nodes.filter((node) => newNodeIds.has(node.id)); + const newNodes = data.nodes.filter((node) => this._nodeIndexByNodeId[node.id] === undefined); + + this._nodes = [...oldNodes, ...newNodes]; + this._edges = data.edges; + this._rebuildNodeIndex(); + this._calculateAndEmit(); + } + + deleteData(data: Partial) { + if (data.nodeIds) { + const nodeIds = new Set(data.nodeIds); + this._nodes = this._nodes.filter((node) => !nodeIds.has(node.id)); + } + + if (data.edgeIds) { + const edgeIds = new Set(data.edgeIds); + this._edges = this._edges.filter((edge) => !edgeIds.has(edge.id)); + } + + this._rebuildNodeIndex(); + this._calculateAndEmit(); + } + + patchData(data: Partial) { + if (data.nodes) { + for (let i = 0; i < data.nodes.length; i++) { + const id: number = data.nodes[i].id; + const index = this._nodeIndexByNodeId[id]; + if (index !== undefined) { + this._nodes[index] = data.nodes[i]; + } else { + this._nodes.push(data.nodes[i]); + this._nodeIndexByNodeId[id] = this._nodes.length - 1; + } + } + } + + if (data.edges) { + const edgeIds: { [id: number]: number } = {}; + for (let i = 0; i < this._edges.length; i++) { + edgeIds[this._edges[i].id] = i; + } + for (let i = 0; i < data.edges.length; i++) { + const edgeId = data.edges[i].id; + if (edgeId in edgeIds) { + this._edges[edgeIds[edgeId]] = data.edges[i]; + } else { + this._edges.push(data.edges[i]); + } + } + } + } + + clearData() { + this._nodes = []; + this._edges = []; + this._nodeIndexByNodeId = {}; + } + + activateSimulation() { + // No-op for static layouts + } + + stopSimulation() { + // No-op for static layouts + } + + startDragNode() { + // No-op for static layouts + } + + dragNode(nodeId: number, position: IPosition) { + const index = this._nodeIndexByNodeId[nodeId]; + if (index !== undefined) { + const node = this._nodes[index]; + node.x = position.x; + node.y = position.y; + node.fx = position.x; + node.fy = position.y; + this.emit(SimulatorEventType.NODE_DRAG, { nodes: this._nodes, edges: this._edges }); + } + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + endDragNode(_nodeId: number) { + // No-op for static layouts + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + fixNodes(_nodes?: ISimulationNode[]) { + // No-op for static layouts + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + releaseNodes(_nodes?: ISimulationNode[]) { + // No-op for static layouts + } + + setSettings(settings: IEngineSettingsUpdate) { + const previous = copyObject(this._config); + Object.assign(this._config, settings); + + if (!isObjectEqual(this._config, previous) && this._nodes.length > 0) { + this._calculateAndEmit(); + } + } + + terminate() { + this._pendingRecalculation = false; + super.terminate(); + } + + protected _calculateAndEmit() { + if (this._nodes.length === 0 || this._cancelSimulation) { + return; + } + + if (this._isCalculating) { + this._pendingRecalculation = true; + return; + } + + this._isCalculating = true; + this.emit(SimulatorEventType.SIMULATION_START, undefined); + + this.calculatePositions( + this._nodes, + this._edges, + (progress) => { + this.emit(SimulatorEventType.SIMULATION_PROGRESS, { + nodes: this._nodes, + edges: this._edges, + progress, + }); + }, + () => this._cancelSimulation, + () => { + this._isCalculating = false; + + if (!this._cancelSimulation) { + this.emit(SimulatorEventType.SIMULATION_END, { nodes: this._nodes, edges: this._edges }); + } + + this._cancelSimulation = false; + + if (this._pendingRecalculation) { + this._pendingRecalculation = false; + this._calculateAndEmit(); + } + }, + ); + } + + protected abstract calculatePositions( + nodes: ISimulationNode[], + edges: ISimulationEdge[], + onProgress: (progress: number) => void, + isCancelled: () => boolean, + onComplete: () => void, + ): void; + + protected _emitProgress(index: number, total: number, lastProgress: number, onProgress: (p: number) => void): number { + const currentProgress = Math.round((index * 100) / total); + if (currentProgress > lastProgress) { + onProgress(currentProgress / 100); + return currentProgress; + } + return lastProgress; + } +} diff --git a/src/simulator/engine/factory.ts b/src/simulator/engine/factory.ts new file mode 100644 index 0000000..aa1e058 --- /dev/null +++ b/src/simulator/engine/factory.ts @@ -0,0 +1,29 @@ +import { + ILayoutEngine, + ILayoutSettings, + ICircularLayoutOptions, + IGridLayoutOptions, + IHierarchicalLayoutOptions, + IForceLayoutOptions, +} from './shared'; +import { ForceLayoutEngine } from './engines/dynamic/force-layout-engine'; +import { CircularLayoutEngine } from './engines/static/circular-layout-engine'; +import { GridLayoutEngine } from './engines/static/grid-layout-engine'; +import { HierarchicalLayoutEngine } from './engines/static/hierarchical-layout-engine'; +import { DeepPartial } from '../../utils/type.utils'; + +export class LayoutEngineFactory { + static create(settings?: DeepPartial): ILayoutEngine { + switch (settings?.type) { + case 'circular': + return new CircularLayoutEngine(settings.options as ICircularLayoutOptions); + case 'grid': + return new GridLayoutEngine(settings.options as IGridLayoutOptions); + case 'hierarchical': + return new HierarchicalLayoutEngine(settings.options as IHierarchicalLayoutOptions); + case 'force': + default: + return new ForceLayoutEngine(settings?.options as IForceLayoutOptions); + } + } +} diff --git a/src/simulator/engine/shared.ts b/src/simulator/engine/shared.ts new file mode 100644 index 0000000..4bf5ac1 --- /dev/null +++ b/src/simulator/engine/shared.ts @@ -0,0 +1,203 @@ +import { IPosition } from '../../common'; +import { IEmitter } from '../../utils/emitter.utils'; +import { DeepPartial } from '../../utils/type.utils'; +import { ISimulationNode, ISimulationGraph, ISimulationIds, SimulatorEvents } from '../shared'; + +export type LayoutType = 'circular' | 'force' | 'grid' | 'hierarchical'; + +export interface ILayoutOptionsBase { + anchorX?: 'start' | 'center' | 'end'; + anchorY?: 'start' | 'center' | 'end'; +} + +export interface ICircularLayoutOptions extends ILayoutOptionsBase { + radius: number; + centerX: number; + centerY: number; +} + +export const DEFAULT_CIRCULAR_LAYOUT_OPTIONS: ICircularLayoutOptions = { + radius: 100, + centerX: 0, + centerY: 0, +}; + +export interface IForceLayoutOptions extends ILayoutOptionsBase { + isSimulatingOnDataUpdate: boolean; + isSimulatingOnSettingsUpdate: boolean; + isSimulatingOnUnstick: boolean; + isPhysicsEnabled: boolean; + alpha: IForceLayoutAlpha; + centering: IForceLayoutCentering | null; + collision: IForceLayoutCollision | null; + links: IForceLayoutLinks; + manyBody: IForceLayoutManyBody | null; + positioning: IForceLayoutPositioning | null; +} + +const MANY_BODY_MAX_DISTANCE_TO_LINK_DISTANCE_RATIO = 100; +const DEFAULT_LINK_DISTANCE = 50; + +export const getManyBodyMaxDistance = (linkDistance: number) => { + const distance = linkDistance > 0 ? linkDistance : 1; + return distance * MANY_BODY_MAX_DISTANCE_TO_LINK_DISTANCE_RATIO; +}; + +export const DEFAULT_FORCE_LAYOUT_OPTIONS: IForceLayoutOptions = { + isSimulatingOnDataUpdate: true, + isSimulatingOnSettingsUpdate: true, + isSimulatingOnUnstick: true, + isPhysicsEnabled: false, + alpha: { + alpha: 1, + alphaMin: 0.05, // default alphaMin is 0.001, which results in 285 ticks to converge. Using 0.05 converges to similar stable results in 106 ticks + alphaDecay: 0.028, + alphaTarget: 0, + }, + centering: { + x: 0, + y: 0, + strength: 1, + }, + collision: { + radius: 15, + strength: 1, + iterations: 1, + }, + links: { + distance: DEFAULT_LINK_DISTANCE, + strength: 1, + iterations: 1, + }, + manyBody: { + strength: -100, + theta: 0.9, + distanceMin: 0, + distanceMax: getManyBodyMaxDistance(DEFAULT_LINK_DISTANCE), + }, + positioning: { + forceX: { + x: 0, + strength: 0.1, + }, + forceY: { + y: 0, + strength: 0.1, + }, + }, + anchorX: 'center', + anchorY: 'center', +}; + +export interface IGridLayoutOptions extends ILayoutOptionsBase { + rowGap: number; + colGap: number; +} + +export const DEFAULT_GRID_LAYOUT_OPTIONS: IGridLayoutOptions = { + rowGap: 50, + colGap: 50, +}; + +export type HierarchicalLayoutOrientation = 'horizontal' | 'vertical'; + +export interface IHierarchicalLayoutOptions extends ILayoutOptionsBase { + nodeGap: number; + levelGap: number; + treeGap: number; + orientation: HierarchicalLayoutOrientation; + reversed: boolean; +} + +export const DEFAULT_HIERARCHICAL_LAYOUT_OPTIONS: IHierarchicalLayoutOptions = { + nodeGap: 50, + levelGap: 50, + treeGap: 100, + orientation: 'vertical', + reversed: false, +}; + +export type LayoutSettingsMap = { + circular: ICircularLayoutOptions; + force: IForceLayoutOptions; + grid: IGridLayoutOptions; + hierarchical: IHierarchicalLayoutOptions; +}; + +export interface ILayoutSettings { + type: LayoutType; + options?: DeepPartial; +} + +export interface IForceLayoutAlpha { + alpha: number; + alphaMin: number; + alphaDecay: number; + alphaTarget: number; +} + +export interface IForceLayoutCentering { + x: number; + y: number; + strength: number; +} + +export interface IForceLayoutCollision { + radius: number; + strength: number; + iterations: number; +} + +export interface IForceLayoutLinks { + distance: number; + strength?: number; + iterations: number; +} + +export interface IForceLayoutManyBody { + strength: number; + theta: number; + distanceMin: number; + distanceMax: number; +} + +export interface IForceLayoutPositioning { + forceX: { + x: number; + strength: number; + }; + forceY: { + y: number; + strength: number; + }; +} + +export type IEngineSettingsUpdate = + | Partial + | Partial + | Partial + | Partial; + +export interface ILayoutEngine extends IEmitter { + readonly type: LayoutType; + + setupData(data: ISimulationGraph): void; + mergeData(data: ISimulationGraph): void; + updateData(data: ISimulationGraph): void; + deleteData(data: Partial): void; + patchData(data: Partial): void; + clearData(): void; + + activateSimulation(): void; + stopSimulation(): void; + + startDragNode(): void; + dragNode(nodeId: number, position: IPosition): void; + endDragNode(nodeId: number): void; + fixNodes(nodes?: ISimulationNode[]): void; + releaseNodes(nodes?: ISimulationNode[]): void; + + setSettings(settings: IEngineSettingsUpdate): void; + + terminate(): void; +} diff --git a/src/simulator/factory.ts b/src/simulator/factory.ts index e902e6f..4470442 100644 --- a/src/simulator/factory.ts +++ b/src/simulator/factory.ts @@ -1,13 +1,16 @@ +import { DeepPartial } from '../utils/type.utils'; +import { ILayoutSettings } from './engine/shared'; import { ISimulator } from './shared'; import { MainThreadSimulator } from './types/main-thread-simulator'; import { WebWorkerSimulator } from './types/web-worker-simulator/web-worker-simulator'; // TODO(dlozic & Alex): CORS handling export class SimulatorFactory { - static getSimulator(): ISimulator { + static getSimulator(settings?: DeepPartial): ISimulator { + const layoutSettings: DeepPartial = { type: 'force', ...settings }; try { if (typeof Worker !== 'undefined') { - return new WebWorkerSimulator(); + return new WebWorkerSimulator(layoutSettings); } throw new Error('WebWorkers are unavailable in your environment.'); } catch (err) { @@ -15,7 +18,7 @@ export class SimulatorFactory { 'Could not create simulator in a WebWorker context. All calculations will be done in the main thread.', err, ); - return new MainThreadSimulator(); + return new MainThreadSimulator(layoutSettings); } } } diff --git a/src/simulator/index.ts b/src/simulator/index.ts index 2c02f6d..52154cd 100644 --- a/src/simulator/index.ts +++ b/src/simulator/index.ts @@ -1,2 +1,4 @@ export { SimulatorFactory } from './factory'; export { ISimulator, ISimulationNode, ISimulationEdge } from './shared'; +export { ILayoutEngine, ILayoutSettings, LayoutType, IEngineSettingsUpdate } from './engine/shared'; +export { LayoutEngineFactory } from './engine/factory'; diff --git a/src/simulator/layout/layout.ts b/src/simulator/layout/layout.ts deleted file mode 100644 index e666e4f..0000000 --- a/src/simulator/layout/layout.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { IEdgeBase } from '../../models/edge'; -import { INode, INodeBase, INodePosition } from '../../models/node'; -import { CircularLayout, ICircularLayoutOptions } from './layouts/circular'; -import { IForceLayoutOptions } from './layouts/force'; -import { GridLayout, IGridLayoutOptions } from './layouts/grid'; -import { HierarchicalLayout, IHierarchicalLayoutOptions } from './layouts/hierarchical'; - -export type LayoutType = 'circular' | 'force' | 'grid' | 'hierarchical'; - -export type LayoutSettingsMap = { - circular: ICircularLayoutOptions; - force: IForceLayoutOptions; - grid: IGridLayoutOptions; - hierarchical: IHierarchicalLayoutOptions; -}; - -export interface ILayoutSettings { - type: LayoutType; - options?: LayoutSettingsMap[LayoutType]; -} - -export interface ILayout { - getPositions(nodes: INode[]): INodePosition[]; -} - -export class LayoutFactory { - static create( - settings?: Partial, - ): ILayout | undefined { - switch (settings?.type) { - case 'circular': - return new CircularLayout(settings.options as ICircularLayoutOptions); - case 'force': - return undefined; - case 'grid': - return new GridLayout(settings.options as IGridLayoutOptions); - case 'hierarchical': - return new HierarchicalLayout(settings.options as IHierarchicalLayoutOptions); - default: - throw new Error('Incorrect layout type.'); - } - } -} diff --git a/src/simulator/layout/layouts/circular.ts b/src/simulator/layout/layouts/circular.ts deleted file mode 100644 index 693d9a0..0000000 --- a/src/simulator/layout/layouts/circular.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { IEdgeBase } from '../../../models/edge'; -import { INode, INodeBase, INodePosition } from '../../../models/node'; -import { ILayout } from '../layout'; - -export interface ICircularLayoutOptions { - radius?: number; - centerX?: number; - centerY?: number; -} - -export const DEFAULT_CIRCULAR_LAYOUT_OPTIONS: Required = { - radius: 100, - centerX: 0, - centerY: 0, -}; - -export class CircularLayout implements ILayout { - private _config: Required; - - constructor(options?: ICircularLayoutOptions) { - this._config = { ...DEFAULT_CIRCULAR_LAYOUT_OPTIONS, ...options }; - } - - getPositions(nodes: INode[]): INodePosition[] { - const angleStep = (2 * Math.PI) / nodes.length; - - const positions = nodes.map((node, index) => { - return { - id: node.id, - x: this._config.centerX + this._config.radius * Math.cos(angleStep * index), - y: this._config.centerY + this._config.radius * Math.sin(angleStep * index), - }; - }); - - return positions; - } -} diff --git a/src/simulator/layout/layouts/force.ts b/src/simulator/layout/layouts/force.ts deleted file mode 100644 index 29edc22..0000000 --- a/src/simulator/layout/layouts/force.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface IForceLayoutOptions { - centerX?: number; - centerY?: number; - nodeDistance?: number; -} - -export const DEFAULT_FORCE_LAYOUT_OPTIONS: Required = { - centerX: 0, - centerY: 0, - nodeDistance: 50, -}; diff --git a/src/simulator/layout/layouts/grid.ts b/src/simulator/layout/layouts/grid.ts deleted file mode 100644 index e48470b..0000000 --- a/src/simulator/layout/layouts/grid.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { IEdgeBase } from '../../../models/edge'; -import { INode, INodeBase, INodePosition } from '../../../models/node'; -import { ILayout } from '../layout'; - -export interface IGridLayoutOptions { - rowGap?: number; - colGap?: number; -} - -export const DEFAULT_GRID_LAYOUT_OPTIONS: Required = { - rowGap: 50, - colGap: 50, -}; - -export class GridLayout implements ILayout { - private _config: Required; - - constructor(options?: IGridLayoutOptions) { - this._config = { ...DEFAULT_GRID_LAYOUT_OPTIONS, ...options }; - } - - getPositions(nodes: INode[]): INodePosition[] { - const rows = Math.ceil(Math.sqrt(nodes.length)); - const cols = Math.ceil(nodes.length / rows); - - const positions: INodePosition[] = []; - - for (let i = 0; i < nodes.length; i++) { - const row = Math.floor(i / cols); - const col = i % cols; - const x = col * this._config.colGap; - const y = row * this._config.rowGap; - positions.push({ id: nodes[i].getId(), x, y }); - } - - return positions; - } -} diff --git a/src/simulator/layout/layouts/hierarchical.ts b/src/simulator/layout/layouts/hierarchical.ts deleted file mode 100644 index 777c1f1..0000000 --- a/src/simulator/layout/layouts/hierarchical.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { IEdge, IEdgeBase } from '../../../models/edge'; -import { INode, INodeBase, INodePosition } from '../../../models/node'; -import { ILayout } from '../layout'; - -export type HierarchicalLayoutOrientation = 'horizontal' | 'vertical'; - -export interface IHierarchicalLayoutOptions { - nodeGap?: number; - levelGap?: number; - treeGap?: number; - orientation?: HierarchicalLayoutOrientation; - reversed?: boolean; -} - -export const DEFAULT_HIERARCHICAL_LAYOUT_OPTIONS: Required = { - nodeGap: 50, - levelGap: 50, - treeGap: 100, - orientation: 'vertical', - reversed: false, -}; - -export class HierarchicalLayout implements ILayout { - private _config: Required; - - constructor(options?: IHierarchicalLayoutOptions) { - this._config = { ...DEFAULT_HIERARCHICAL_LAYOUT_OPTIONS, ...options }; - } - - getPositions(nodes: INode[]): INodePosition[] { - const components = this.getConnectedComponents(nodes); - const positions: INodePosition[] = new Array(nodes.length); - let maxX = 0; - let maxHeight = 0; - let counter = 0; - - for (let i = 0; i < components.length; i++) { - const levels: Map[]> = this.assignLevels(components[i]); - const maxLevelSize = Math.max(...Array.from(levels.values()).map((levelNodes) => levelNodes.length)); - - if (levels.size * this._config.levelGap > maxHeight) { - maxHeight = levels.size * this._config.levelGap; - } - - let offsetX = i === 0 ? 0 : this._config.treeGap + maxX; - - if (i > 0) { - offsetX += ((maxLevelSize - 1) * this._config.nodeGap) / 2; - } - - for (let j = 0; j < levels.size; j++) { - const y = j * this._config.levelGap; - const level = levels.get(j); - if (!level) { - continue; - } - - const width = level.length * this._config.nodeGap; - - for (let k = 0; k < level.length; k++) { - const node = level[k]; - const x = width / 2 - k * this._config.nodeGap + offsetX; - if (x > maxX) { - maxX = x; - } - - positions[counter++] = { - id: node.getId(), - x: this._config.orientation === 'horizontal' ? y : x, - y: this._config.orientation === 'horizontal' ? x : y, - }; - } - } - } - - if (this._config.reversed === true) { - positions.forEach((position) => { - if (this._config.orientation === 'horizontal' && position.x !== undefined) { - position.x = maxX - position.x; - } - if (this._config.orientation === 'vertical' && position.y !== undefined) { - position.y = maxHeight - position.y; - } - }); - } - - return positions; - } - - getConnectedComponents = (nodes: INode[]): INode[][] => { - const visited = new Set>(); - const components: INode[][] = []; - - for (let i = 0; i < nodes.length; i++) { - if (visited.has(nodes[i])) { - continue; - } - - const component: INode[] = []; - const queue: INode[] = [nodes[i]]; - visited.add(nodes[i]); - - while (queue.length > 0) { - const current = queue.pop(); - - if (current) { - component.push(current); - const neighbors = current.getAdjacentNodes(); - for (let j = 0; j < neighbors.length; j++) { - if (visited.has(neighbors[j])) { - continue; - } - - visited.add(neighbors[j]); - queue.push(neighbors[j]); - } - } - } - - components.push(component); - } - - return components; - }; - - assignLevels = (nodes: INode[]): Map[]> => { - const levels = new Map[]>(); - const visited = new Set>(); - - let root = nodes.filter((node) => this.getExternalInEdges(node).length === 0)[0]; - - if (!root) { - root = nodes.sort((a, b) => this.getExternalInEdges(a).length - this.getExternalInEdges(b).length)[0]; - } - - const queue: [INode, number][] = [[root, 0]]; - - for (const [node, level] of queue) { - if (visited.has(node)) { - continue; - } - - visited.add(node); - if (levels.has(level)) { - levels.get(level)?.push(node); - } else { - levels.set(level, [node]); - } - - const neighbors = node.getAdjacentNodes(); - - for (let i = 0; i < neighbors.length; i++) { - queue.push([neighbors[i], level + 1]); - } - } - - return levels; - }; - - getExternalInEdges = (node: INode): IEdge[] => { - return node.getInEdges().filter((edge) => edge.startNode.id !== edge.endNode.id); - }; -} diff --git a/src/simulator/shared.ts b/src/simulator/shared.ts index b1190de..683e444 100644 --- a/src/simulator/shared.ts +++ b/src/simulator/shared.ts @@ -1,7 +1,8 @@ import { IPosition } from '../common'; import { SimulationLinkDatum, SimulationNodeDatum } from 'd3-force'; -import { ID3SimulatorEngineSettings, ID3SimulatorEngineSettingsUpdate } from './engine/d3-simulator-engine'; import { IEmitter } from '../utils/emitter.utils'; +import { ILayoutSettings } from './engine/shared'; +import { DeepPartial } from '../utils/type.utils'; /** * Node with sticky coordinates. @@ -62,7 +63,6 @@ export interface ISimulator extends IEmitter { clearData(): void; // Simulation handlers - simulate(): void; activateSimulation(): void; stopSimulation(): void; @@ -74,8 +74,9 @@ export interface ISimulator extends IEmitter { releaseNodes(nodes?: ISimulationNode[]): void; // Settings handlers - setSettings(settings: ID3SimulatorEngineSettingsUpdate): void; + setSettings(settings: DeepPartial): void; + isSimulationRunning(): boolean; terminate(): void; } @@ -89,7 +90,7 @@ export interface ISimulatorEventProgress { } export interface ISimulatorEventSettings { - settings: ID3SimulatorEngineSettings; + settings: ILayoutSettings; } export interface ISimulatorEvents { diff --git a/src/simulator/types/main-thread-simulator.ts b/src/simulator/types/main-thread-simulator.ts index b560b33..9a930d5 100644 --- a/src/simulator/types/main-thread-simulator.ts +++ b/src/simulator/types/main-thread-simulator.ts @@ -8,101 +8,114 @@ import { } from '../shared'; import { IPosition } from '../../common'; import { Emitter } from '../../utils/emitter.utils'; -import { - D3SimulatorEngine, - D3SimulatorEngineEventType, - ID3SimulatorEngineSettingsUpdate, -} from '../engine/d3-simulator-engine'; +import { ILayoutEngine, ILayoutSettings } from '../engine/shared'; +import { LayoutEngineFactory } from '../engine/factory'; +import { DeepPartial } from '../../utils/type.utils'; export class MainThreadSimulator extends Emitter implements ISimulator { - protected readonly _simulator: D3SimulatorEngine; + private _engine: ILayoutEngine; + private _isSimulationRunning = false; - constructor() { + constructor(settings: DeepPartial) { super(); - this._simulator = new D3SimulatorEngine(); - this._simulator.on(D3SimulatorEngineEventType.SIMULATION_START, () => { - this.emit(SimulatorEventType.SIMULATION_START, undefined); - }); - this._simulator.on(D3SimulatorEngineEventType.SIMULATION_PROGRESS, (data) => { - this.emit(SimulatorEventType.SIMULATION_PROGRESS, data); - }); - this._simulator.on(D3SimulatorEngineEventType.SIMULATION_END, (data) => { - this.emit(SimulatorEventType.SIMULATION_END, data); - }); - this._simulator.on(D3SimulatorEngineEventType.NODE_DRAG, (data) => { - this.emit(SimulatorEventType.NODE_DRAG, data); - }); - this._simulator.on(D3SimulatorEngineEventType.SIMULATION_TICK, (data) => { - this.emit(SimulatorEventType.SIMULATION_STEP, data); - }); - this._simulator.on(D3SimulatorEngineEventType.SETTINGS_UPDATE, (data) => { - this.emit(SimulatorEventType.SETTINGS_UPDATE, data); - }); + this._engine = LayoutEngineFactory.create(settings); + this._wireEngineEvents(); } setupData(data: ISimulationGraph) { - this._simulator.setupData(data); + this._engine.setupData(data); } mergeData(data: ISimulationGraph) { - this._simulator.mergeData(data); + this._engine.mergeData(data); } updateData(data: ISimulationGraph) { - this._simulator.updateData(data); + this._engine.updateData(data); } deleteData(data: ISimulationIds) { - this._simulator.deleteData(data); + this._engine.deleteData(data); } patchData(data: Partial): void { - this._simulator.patchData(data); + this._engine.patchData(data); } clearData() { - this._simulator.clearData(); - } - - simulate() { - console.log('not implemented'); - // this.simulator.runSimulation(); + this._engine.clearData(); } activateSimulation() { - this._simulator.activateSimulation(); + this._engine.activateSimulation(); } stopSimulation() { - this._simulator.stopSimulation(); + this._engine.stopSimulation(); } startDragNode() { - this._simulator.startDragNode(); + this._engine.startDragNode(); } dragNode(nodeId: number, position: IPosition) { - this._simulator.dragNode({ id: nodeId, ...position }); + this._engine.dragNode(nodeId, position); } endDragNode(nodeId: number) { - this._simulator.endDragNode({ id: nodeId }); + this._engine.endDragNode(nodeId); } fixNodes(nodes: ISimulationNode[]) { - this._simulator.stickNodes(nodes); + this._engine.fixNodes(nodes); } releaseNodes(nodes?: ISimulationNode[] | undefined): void { - this._simulator.unstickNodes(nodes); + this._engine.releaseNodes(nodes); + } + + setSettings(settings: ILayoutSettings) { + if (settings.type === this._engine.type && settings.options) { + this._engine.setSettings(settings.options); + return; + } + + this._engine.removeAllListeners(); + this._engine.terminate(); + this._engine = LayoutEngineFactory.create(settings); + this._wireEngineEvents(); } - setSettings(settings: ID3SimulatorEngineSettingsUpdate) { - this._simulator.setSettings(settings); + isSimulationRunning(): boolean { + return this._isSimulationRunning; } terminate() { - this._simulator.removeAllListeners(); + this._engine.removeAllListeners(); + this._engine.terminate(); this.removeAllListeners(); } + + private _wireEngineEvents() { + this._engine.on(SimulatorEventType.SIMULATION_START, () => { + this.emit(SimulatorEventType.SIMULATION_START, undefined); + this._isSimulationRunning = true; + }); + this._engine.on(SimulatorEventType.SIMULATION_PROGRESS, (data) => { + this.emit(SimulatorEventType.SIMULATION_PROGRESS, data); + }); + this._engine.on(SimulatorEventType.SIMULATION_END, (data) => { + this.emit(SimulatorEventType.SIMULATION_END, data); + this._isSimulationRunning = false; + }); + this._engine.on(SimulatorEventType.SIMULATION_STEP, (data) => { + this.emit(SimulatorEventType.SIMULATION_STEP, data); + }); + this._engine.on(SimulatorEventType.NODE_DRAG, (data) => { + this.emit(SimulatorEventType.NODE_DRAG, data); + }); + this._engine.on(SimulatorEventType.SETTINGS_UPDATE, (data) => { + this.emit(SimulatorEventType.SETTINGS_UPDATE, data); + }); + } } diff --git a/src/simulator/types/web-worker-simulator/message/worker-input.ts b/src/simulator/types/web-worker-simulator/message/worker-input.ts index c252d4a..45e830d 100644 --- a/src/simulator/types/web-worker-simulator/message/worker-input.ts +++ b/src/simulator/types/web-worker-simulator/message/worker-input.ts @@ -1,7 +1,8 @@ import { IPosition } from '../../../../common'; import { ISimulationNode, ISimulationEdge } from '../../../shared'; -import { ID3SimulatorEngineSettingsUpdate } from '../../../engine/d3-simulator-engine'; import { IWorkerPayload } from './worker-payload'; +import { ILayoutSettings } from '../../../engine/shared'; +import { DeepPartial } from '../../../../utils/type.utils'; // Messages are objects going into the simulation worker. // They can be thought of similar to requests. @@ -16,7 +17,6 @@ export enum WorkerInputType { ClearData = 'Clear Data', // Simulation message types - Simulate = 'Simulate', ActivateSimulation = 'Activate Simulation', UpdateSimulation = 'Update Simulation', StopSimulation = 'Stop Simulation', @@ -74,8 +74,6 @@ type IWorkerInputPatchDataPayload = IWorkerPayload< type IWorkerInputClearDataPayload = IWorkerPayload; -type IWorkerInputSimulatePayload = IWorkerPayload; - type IWorkerInputActivateSimulationPayload = IWorkerPayload; type IWorkerInputStopSimulationPayload = IWorkerPayload; @@ -113,7 +111,7 @@ type IWorkerInputReleaseNodesPayload = IWorkerPayload< } >; -type IWorkerInputSetSettingsPayload = IWorkerPayload; +type IWorkerInputSetSettingsPayload = IWorkerPayload>; export type IWorkerInputPayload = | IWorkerInputSetupDataPayload @@ -122,7 +120,6 @@ export type IWorkerInputPayload = | IWorkerInputDeleteDataPayload | IWorkerInputPatchDataPayload | IWorkerInputClearDataPayload - | IWorkerInputSimulatePayload | IWorkerInputActivateSimulationPayload | IWorkerInputStopSimulationPayload | IWorkerInputUpdateSimulationPayload diff --git a/src/simulator/types/web-worker-simulator/message/worker-output.ts b/src/simulator/types/web-worker-simulator/message/worker-output.ts index d271bcf..7325e60 100644 --- a/src/simulator/types/web-worker-simulator/message/worker-output.ts +++ b/src/simulator/types/web-worker-simulator/message/worker-output.ts @@ -1,6 +1,6 @@ import { ISimulationNode, ISimulationEdge } from '../../../shared'; import { IWorkerPayload } from './worker-payload'; -import { ID3SimulatorEngineSettings } from '../../../engine/d3-simulator-engine'; +import { ILayoutSettings } from '../../../engine/shared'; export enum WorkerOutputType { SIMULATION_START = 'simulation-start', @@ -59,7 +59,7 @@ type IWorkerOutputNodeDragEndPayload = IWorkerPayload< type IWorkerOutputSettingsUpdatePayload = IWorkerPayload< WorkerOutputType.SETTINGS_UPDATE, { - settings: ID3SimulatorEngineSettings; + settings: ILayoutSettings; } >; diff --git a/src/simulator/types/web-worker-simulator/simulator.worker.ts b/src/simulator/types/web-worker-simulator/simulator.worker.ts index f07da1d..e922c5c 100644 --- a/src/simulator/types/web-worker-simulator/simulator.worker.ts +++ b/src/simulator/types/web-worker-simulator/simulator.worker.ts @@ -1,109 +1,61 @@ // / -import { D3SimulatorEngine, D3SimulatorEngineEventType } from '../../engine/d3-simulator-engine'; +import { LayoutEngineFactory } from '../../engine/factory'; +import { ILayoutEngine, ILayoutSettings } from '../../engine/shared'; +import { SimulatorEventType } from '../../shared'; import { IWorkerInputPayload, WorkerInputType } from './message/worker-input'; import { IWorkerOutputPayload, WorkerOutputType } from './message/worker-output'; -const simulator = new D3SimulatorEngine(); - -const emitToMain = (message: IWorkerOutputPayload) => { - // @ts-ignore Web worker postMessage is a global function - postMessage(message); +let engine: ILayoutEngine | null = null; + +const emitToMain = (message: IWorkerOutputPayload) => postMessage(message); + +function wireEngineEvents(target: ILayoutEngine) { + target.on(SimulatorEventType.SIMULATION_START, () => emitToMain({ type: WorkerOutputType.SIMULATION_START })); + target.on(SimulatorEventType.SIMULATION_PROGRESS, (data) => + emitToMain({ type: WorkerOutputType.SIMULATION_PROGRESS, data }), + ); + target.on(SimulatorEventType.SIMULATION_END, (data) => emitToMain({ type: WorkerOutputType.SIMULATION_END, data })); + target.on(SimulatorEventType.SIMULATION_STEP, (data) => emitToMain({ type: WorkerOutputType.SIMULATION_STEP, data })); + target.on(SimulatorEventType.NODE_DRAG, (data) => emitToMain({ type: WorkerOutputType.NODE_DRAG, data })); + target.on(SimulatorEventType.SETTINGS_UPDATE, (data) => emitToMain({ type: WorkerOutputType.SETTINGS_UPDATE, data })); +} + +type ExtractPayload = Extract; +type EngineHandler = (engine: ILayoutEngine, payload: ExtractPayload) => void; + +const handlers: { [T in WorkerInputType]?: EngineHandler } = { + [WorkerInputType.SetupData]: (e, { data }) => e.setupData(data), + [WorkerInputType.MergeData]: (e, { data }) => e.mergeData(data), + [WorkerInputType.UpdateData]: (e, { data }) => e.updateData(data), + [WorkerInputType.DeleteData]: (e, { data }) => e.deleteData(data), + [WorkerInputType.PatchData]: (e, { data }) => e.patchData(data), + [WorkerInputType.ClearData]: (e) => e.clearData(), + [WorkerInputType.ActivateSimulation]: (e) => e.activateSimulation(), + [WorkerInputType.StopSimulation]: (e) => e.stopSimulation(), + [WorkerInputType.StartDragNode]: (e) => e.startDragNode(), + [WorkerInputType.DragNode]: (e, { data }) => e.dragNode(data.id, { x: data.x, y: data.y }), + [WorkerInputType.EndDragNode]: (e, { data }) => e.endDragNode(data.id), + [WorkerInputType.FixNodes]: (e, { data }) => e.fixNodes(data.nodes), + [WorkerInputType.ReleaseNodes]: (e, { data }) => e.releaseNodes(data.nodes), }; -simulator.on(D3SimulatorEngineEventType.SIMULATION_START, () => { - emitToMain({ type: WorkerOutputType.SIMULATION_START }); -}); - -simulator.on(D3SimulatorEngineEventType.SIMULATION_PROGRESS, (data) => { - emitToMain({ type: WorkerOutputType.SIMULATION_PROGRESS, data }); -}); - -simulator.on(D3SimulatorEngineEventType.SIMULATION_END, (data) => { - emitToMain({ type: WorkerOutputType.SIMULATION_END, data }); -}); - -simulator.on(D3SimulatorEngineEventType.NODE_DRAG, (data) => { - emitToMain({ type: WorkerOutputType.NODE_DRAG, data }); -}); - -simulator.on(D3SimulatorEngineEventType.SIMULATION_TICK, (data) => { - emitToMain({ type: WorkerOutputType.SIMULATION_STEP, data }); -}); - -simulator.on(D3SimulatorEngineEventType.SETTINGS_UPDATE, (data) => { - emitToMain({ type: WorkerOutputType.SETTINGS_UPDATE, data }); -}); - addEventListener('message', ({ data }: MessageEvent) => { - switch (data.type) { - case WorkerInputType.ActivateSimulation: { - simulator.activateSimulation(); - break; - } - - case WorkerInputType.StopSimulation: { - simulator.stopSimulation(); - break; - } - - case WorkerInputType.SetupData: { - simulator.setupData(data.data); - break; - } - - case WorkerInputType.MergeData: { - simulator.mergeData(data.data); - break; - } - - case WorkerInputType.UpdateData: { - simulator.updateData(data.data); - break; - } - - case WorkerInputType.DeleteData: { - simulator.deleteData(data.data); - break; - } - - case WorkerInputType.PatchData: { - simulator.patchData(data.data); - break; - } - - case WorkerInputType.ClearData: { - simulator.clearData(); - break; - } - - case WorkerInputType.StartDragNode: { - simulator.startDragNode(); - break; - } - - case WorkerInputType.DragNode: { - simulator.dragNode(data.data); - break; - } - - case WorkerInputType.FixNodes: { - simulator.stickNodes(data.data.nodes); - break; - } - - case WorkerInputType.ReleaseNodes: { - simulator.unstickNodes(data.data.nodes); - break; - } - - case WorkerInputType.EndDragNode: { - simulator.endDragNode(data.data); - break; - } + if (data.type === WorkerInputType.SetSettings) { + const settings = data.data as ILayoutSettings; + if (settings.type === engine?.type && settings.options) { + engine?.setSettings(settings.options); + return; + } + + engine?.removeAllListeners(); + engine?.terminate(); + engine = LayoutEngineFactory.create(settings); + wireEngineEvents(engine); + return; + } - case WorkerInputType.SetSettings: { - simulator.setSettings(data.data); - break; - } + if (engine) { + const handler = handlers[data.type] as EngineHandler | undefined; + handler?.(engine, data); } }); diff --git a/src/simulator/types/web-worker-simulator/web-worker-simulator.ts b/src/simulator/types/web-worker-simulator/web-worker-simulator.ts index 005d043..ce5cf3e 100644 --- a/src/simulator/types/web-worker-simulator/web-worker-simulator.ts +++ b/src/simulator/types/web-worker-simulator/web-worker-simulator.ts @@ -8,15 +8,17 @@ import { ISimulationGraph, ISimulationIds, } from '../../shared'; -import { ID3SimulatorEngineSettingsUpdate } from '../../engine/d3-simulator-engine'; import { IWorkerInputPayload, WorkerInputType } from './message/worker-input'; import { IWorkerOutputPayload, WorkerOutputType } from './message/worker-output'; import { Emitter } from '../../../utils/emitter.utils'; +import { ILayoutSettings } from '../../engine/shared'; +import { DeepPartial } from '../../../utils/type.utils'; export class WebWorkerSimulator extends Emitter implements ISimulator { protected readonly _worker: Worker; + private _isSimulationRunning = false; - constructor() { + constructor(settings: DeepPartial) { super(); this._worker = new Worker( new URL( @@ -27,10 +29,13 @@ export class WebWorkerSimulator extends Emitter implements ISim { type: 'module' }, ); + this.emitToWorker({ type: WorkerInputType.SetSettings, data: settings }); + this._worker.onmessage = ({ data }: MessageEvent) => { switch (data.type) { case WorkerOutputType.SIMULATION_START: { this.emit(SimulatorEventType.SIMULATION_START, undefined); + this._isSimulationRunning = true; break; } case WorkerOutputType.SIMULATION_PROGRESS: { @@ -39,6 +44,7 @@ export class WebWorkerSimulator extends Emitter implements ISim } case WorkerOutputType.SIMULATION_END: { this.emit(SimulatorEventType.SIMULATION_END, data.data); + this._isSimulationRunning = false; break; } case WorkerOutputType.SIMULATION_STEP: { @@ -96,10 +102,6 @@ export class WebWorkerSimulator extends Emitter implements ISim this.emitToWorker({ type: WorkerInputType.ClearData }); } - simulate() { - this.emitToWorker({ type: WorkerInputType.Simulate }); - } - activateSimulation() { this.emitToWorker({ type: WorkerInputType.ActivateSimulation }); } @@ -132,8 +134,15 @@ export class WebWorkerSimulator extends Emitter implements ISim this.emitToWorker({ type: WorkerInputType.ReleaseNodes, data: { nodes } }); } - setSettings(settings: ID3SimulatorEngineSettingsUpdate) { - this.emitToWorker({ type: WorkerInputType.SetSettings, data: settings }); + setSettings(settings: ILayoutSettings) { + this.emitToWorker({ + type: WorkerInputType.SetSettings, + data: settings, + } satisfies IWorkerInputPayload); + } + + isSimulationRunning(): boolean { + return this._isSimulationRunning; } terminate() { diff --git a/src/utils/function.utils.ts b/src/utils/function.utils.ts index dcfd73e..7c6dc3f 100644 --- a/src/utils/function.utils.ts +++ b/src/utils/function.utils.ts @@ -1,28 +1,26 @@ export const throttle = (fn: Function, waitMs = 300) => { - let isInThrottle = false; - let lastTimer: ReturnType; - let lastTimestamp: number = Date.now(); + let lastTime = 0; + let timer: ReturnType | null = null; return function () { // eslint-disable-next-line prefer-rest-params const args = arguments; const now = Date.now(); + const remaining = waitMs - (now - lastTime); - if (!isInThrottle) { + if (remaining <= 0) { + if (timer) { + clearTimeout(timer); + timer = null; + } + lastTime = now; fn(...args); - lastTimestamp = now; - isInThrottle = true; - return; - } - - clearTimeout(lastTimer); - const timerWaitMs = Math.max(waitMs - (now - lastTimestamp), 0); - - lastTimer = setTimeout(() => { - if (now - lastTimestamp >= waitMs) { + } else if (!timer) { + timer = setTimeout(() => { + lastTime = Date.now(); + timer = null; fn(...args); - lastTimestamp = now; - } - }, timerWaitMs); + }, remaining); + } }; }; diff --git a/src/utils/graph.utils.ts b/src/utils/graph.utils.ts new file mode 100644 index 0000000..b969614 --- /dev/null +++ b/src/utils/graph.utils.ts @@ -0,0 +1,145 @@ +import { IEdge, IEdgeBase } from '../models/edge'; +import { IGraph } from '../models/graph'; +import { INode, INodeBase } from '../models/node'; +import { GraphObjectState } from '../models/state'; +import { IFitZoomTransformOptions } from '../renderer/shared'; +import { ILayoutSettings } from '../simulator'; +import { IHierarchicalLayoutOptions } from '../simulator/engine/shared'; + +export const selectNode = (node: INode) => { + setNodeState(node, GraphObjectState.SELECTED, { isStateOverride: true }); +}; + +export const selectEdge = (edge: IEdge) => { + setEdgeState(edge, GraphObjectState.SELECTED, { isStateOverride: true }); +}; + +export const selectOnlyNode = (graph: IGraph, node: INode) => { + unselectAll(graph); + selectNode(node); +}; + +export const selectOnlyEdge = (graph: IGraph, edge: IEdge) => { + unselectAll(graph); + selectEdge(edge); +}; + +export const unselectAll = ( + graph: IGraph, +): { changedCount: number } => { + const selectedNodes = graph.getNodes((node) => node.isSelected()); + for (let i = 0; i < selectedNodes.length; i++) { + selectedNodes[i].clearState(); + } + + const selectedEdges = graph.getEdges((edge) => edge.isSelected()); + for (let i = 0; i < selectedEdges.length; i++) { + selectedEdges[i].clearState(); + } + + return { changedCount: selectedNodes.length + selectedEdges.length }; +}; + +export const hoverNode = (node: INode) => { + setNodeState(node, GraphObjectState.HOVERED); +}; + +export const hoverOnlyNode = (graph: IGraph, node: INode) => { + unhoverAll(graph); + hoverNode(node); +}; + +export const hoverEdge = (edge: IEdge) => { + setEdgeState(edge, GraphObjectState.HOVERED); +}; + +export const hoverOnlyEdge = (graph: IGraph, edge: IEdge) => { + unhoverAll(graph); + hoverEdge(edge); +}; + +export const unhoverAll = (graph: IGraph): { changedCount: number } => { + const hoveredNodes = graph.getNodes((node) => node.isHovered()); + for (let i = 0; i < hoveredNodes.length; i++) { + hoveredNodes[i].clearState(); + } + + const hoveredEdges = graph.getEdges((edge) => edge.isHovered()); + for (let i = 0; i < hoveredEdges.length; i++) { + hoveredEdges[i].clearState(); + } + + return { changedCount: hoveredNodes.length + hoveredEdges.length }; +}; + +export interface ISetShapeStateOptions { + isStateOverride: boolean; +} + +export const setNodeState = ( + node: INode, + state: number, + options?: ISetShapeStateOptions, +): void => { + if (isStateChangeable(node, options)) { + node.setState(state, { isNotifySkipped: true }); + } + + node.getInEdges().forEach((edge) => { + if (edge && isStateChangeable(edge, options)) { + edge.setState(state, { isNotifySkipped: true }); + } + if (edge.startNode && isStateChangeable(edge.startNode, options)) { + edge.startNode.setState(state, { isNotifySkipped: true }); + } + }); + + node.getOutEdges().forEach((edge) => { + if (edge && isStateChangeable(edge, options)) { + edge.setState(state, { isNotifySkipped: true }); + } + if (edge.endNode && isStateChangeable(edge.endNode, options)) { + edge.endNode.setState(state, { isNotifySkipped: true }); + } + }); +}; + +export const setEdgeState = ( + edge: IEdge, + state: number, + options?: ISetShapeStateOptions, +): void => { + if (isStateChangeable(edge, options)) { + edge.setState(state, { isNotifySkipped: true }); + } + + if (edge.startNode && isStateChangeable(edge.startNode, options)) { + edge.startNode.setState(state, { isNotifySkipped: true }); + } + + if (edge.endNode && isStateChangeable(edge.endNode, options)) { + edge.endNode.setState(state, { isNotifySkipped: true }); + } +}; + +export const isStateChangeable = ( + graphObject: INode | IEdge, + options?: ISetShapeStateOptions, +): boolean => { + const isOverride = options?.isStateOverride; + return isOverride || (!isOverride && !graphObject.getState()); +}; + +export const getLayoutAnchors = (layout: ILayoutSettings): IFitZoomTransformOptions => { + if (layout.type === 'hierarchical') { + const opts = layout.options as IHierarchicalLayoutOptions; + return { + anchorX: opts.anchorX ?? (opts.orientation === 'horizontal' ? (opts.reversed ? 'end' : 'start') : 'center'), + anchorY: opts.anchorY ?? (opts.orientation === 'vertical' ? (opts.reversed ? 'end' : 'start') : 'center'), + }; + } + return { + anchorX: layout.options?.anchorX ?? 'center', + anchorY: layout.options?.anchorY ?? 'center', + }; +}; diff --git a/src/utils/object.utils.ts b/src/utils/object.utils.ts index d6dfcf9..debcc7d 100644 --- a/src/utils/object.utils.ts +++ b/src/utils/object.utils.ts @@ -122,7 +122,7 @@ const copyPlainObject = (obj: Record): Record => { }; export const patchProperties = (target: T, source: T): void => { - const keys = Object.keys(source as Object) as (keyof T)[]; + const keys = Object.keys(source as object) as (keyof T)[]; for (let i = 0; i < keys.length; i++) { target[keys[i]] = source[keys[i]]; diff --git a/src/views/orb-map-view.ts b/src/views/orb-map-view.ts index fc5f811..91b0f4f 100644 --- a/src/views/orb-map-view.ts +++ b/src/views/orb-map-view.ts @@ -12,6 +12,7 @@ import { RendererFactory } from '../renderer/factory'; import { getDefaultGraphStyle } from '../models/style'; import { isBoolean } from '../utils/type.utils'; import { IObserver } from '../utils/observer.utils'; +import { GraphInteraction, IGraphInteraction } from '../models/interaction'; export interface ILeafletMapTile { instance: L.TileLayer; @@ -70,6 +71,7 @@ export class OrbMapView implements IOr private _graph: IGraph; private _events: OrbEmitter; private _strategy: IEventStrategy; + private _interaction: IGraphInteraction; private _settings: IOrbMapViewSettings; private _map: HTMLDivElement; @@ -90,6 +92,7 @@ export class OrbMapView implements IOr }); this._graph.setDefaultStyle(getDefaultGraphStyle()); this._events = new OrbEmitter(); + this._interaction = new GraphInteraction(this._graph); this._settings = { areCollapsedContainerDimensionsAllowed: false, @@ -153,6 +156,10 @@ export class OrbMapView implements IOr return this._events; } + get interaction(): IGraphInteraction { + return this._interaction; + } + get leaflet(): L.Map { return this._leaflet; } @@ -198,9 +205,12 @@ export class OrbMapView implements IOr } render(onRendered?: () => void) { + if (onRendered) { + this._renderer.once(RenderEventType.RENDER_END, () => onRendered()); + } + this._updateGraphPositions(); this._renderer.render(this._graph); - onRendered?.(); } zoomIn(onRendered?: () => void) { diff --git a/src/views/orb-view.ts b/src/views/orb-view.ts index 16ea79d..532d38e 100644 --- a/src/views/orb-view.ts +++ b/src/views/orb-view.ts @@ -13,22 +13,23 @@ import { INode, INodeBase, isNode } from '../models/node'; import { IEdge, IEdgeBase, isEdge } from '../models/edge'; import { IOrbView } from './shared'; import { DefaultEventStrategy, IEventStrategy, IEventStrategySettings } from '../models/strategy'; -import { - DEFAULT_SETTINGS, - ID3SimulatorEngineSettings, - ID3SimulatorEngineSettingsCentering, - ID3SimulatorEngineSettingsLinks, -} from '../simulator/engine/d3-simulator-engine'; +import { DEFAULT_FORCE_LAYOUT_OPTIONS, ILayoutSettings } from '../simulator/engine/shared'; import { copyObject } from '../utils/object.utils'; import { OrbEmitter, OrbEventType } from '../events'; -import { IRenderer, RenderEventType, IRendererSettingsInit, IRendererSettings } from '../renderer/shared'; +import { + IRenderer, + RenderEventType, + IRendererSettingsInit, + IRendererSettings, + IFitZoomTransformOptions, +} from '../renderer/shared'; import { RendererFactory } from '../renderer/factory'; import { SimulatorEventType } from '../simulator/shared'; import { getDefaultGraphStyle } from '../models/style'; import { isBoolean } from '../utils/type.utils'; import { IObserver, IObserverDataPayload } from '../utils/observer.utils'; -import { ILayoutSettings, LayoutFactory } from '../simulator/layout/layout'; -import { DEFAULT_FORCE_LAYOUT_OPTIONS } from '../simulator/layout/layouts/force'; +import { GraphInteraction, IGraphInteraction } from '../models/interaction'; +import { getLayoutAnchors } from '../utils/graph.utils'; export interface IGraphInteractionSettings { isDragEnabled: boolean; @@ -37,7 +38,6 @@ export interface IGraphInteractionSettings { export interface IOrbViewSettings { getPosition?(node: INode): IPosition | undefined; - simulation: Partial; render: Partial; strategy: Partial; interaction: Partial; @@ -58,12 +58,11 @@ export class OrbView implements IOrbVi private _events: OrbEmitter; private _strategy: IEventStrategy; private _settings: IOrbViewSettings; + private _interaction: IGraphInteraction; private readonly _renderer: IRenderer; private readonly _simulator: ISimulator; - // private _isSimulating = false; - private _onSimulationEnd: (() => void) | undefined; private _simulationStartedAt = Date.now(); private _d3Zoom: ZoomBehavior; private _dragStartPosition: IPosition | undefined; @@ -76,13 +75,9 @@ export class OrbView implements IOrbVi isOutOfBoundsDragEnabled: false, areCoordinatesRounded: true, ...settings, - simulation: { - isPhysicsEnabled: false, - ...settings?.simulation, - }, layout: { type: 'force', - ...settings?.layout, + ...(settings?.layout ?? DEFAULT_FORCE_LAYOUT_OPTIONS), }, render: { ...settings?.render, @@ -110,6 +105,7 @@ export class OrbView implements IOrbVi }); this._graph.setDefaultStyle(getDefaultGraphStyle()); this._events = new OrbEmitter(); + this._interaction = new GraphInteraction(this._graph); this._strategy = new DefaultEventStrategy({ isDefaultSelectEnabled: this._settings.strategy.isDefaultSelectEnabled ?? false, @@ -160,48 +156,14 @@ export class OrbView implements IOrbVi .on('contextmenu', this.mouseRightClicked) .on('dblclick.zoom', this.mouseDoubleClicked); - this._simulator = SimulatorFactory.getSimulator(); - - if (this._settings.layout.type === 'force') { - this._enableSimulation(); - } - - if (this._settings.layout.options) { - const _options = { - ...DEFAULT_FORCE_LAYOUT_OPTIONS, - ...this._settings.layout.options, - }; - - this._settings.simulation.centering = { - ...(DEFAULT_SETTINGS.centering as Required), - ...this._settings.simulation.centering, - x: _options.centerX, - y: _options.centerY, - }; - - this._settings.simulation.links = { - ...(DEFAULT_SETTINGS.links as Required), - ...this._settings.simulation.links, - distance: _options.nodeDistance, - }; - } - this._simulator.setSettings(this._settings.simulation); + this._simulator = SimulatorFactory.getSimulator(this._settings.layout); + this._initializeSimulationEvents(); - // TODO(dlozic): Optimize crud operations here. this._graph.setSettings({ onSetupData: () => { - // if (this._isSimulating) { - // console.warn('Already running a simulation. Discarding the setup data call.'); - // return; - // } - // this._isSimulating = true; this._assignPositions(this._graph.getNodes()); const nodePositions = this._graph.getNodePositions(); const edgePositions = this._graph.getEdgePositions(); - // this._onSimulationEnd = onRendered; - if (this._settings.layout) { - this._graph.setLayout(LayoutFactory.create(this._settings.layout)); - } this._simulator.setupData({ nodes: nodePositions, edges: edgePositions }); }, onMergeData: (data) => { @@ -212,12 +174,9 @@ export class OrbView implements IOrbVi this._assignPositions(this._graph.getNodes(nodeFilter)); - if (this._settings.layout.type === 'force') { - const nodePositions = this._graph.getNodePositions(nodeFilter); - const edgePositions = this._graph.getEdgePositions(edgeFilter); - - this._simulator.mergeData({ nodes: nodePositions, edges: edgePositions }); - } + const nodePositions = this._graph.getNodePositions(nodeFilter); + const edgePositions = this._graph.getEdgePositions(edgeFilter); + this._simulator.mergeData({ nodes: nodePositions, edges: edgePositions }); }, onRemoveData: (data) => { this._simulator.deleteData(data); @@ -233,6 +192,10 @@ export class OrbView implements IOrbVi return this._events; } + get interaction(): IGraphInteraction { + return this._interaction; + } + getSettings(): IOrbViewSettings { return copyObject(this._settings); } @@ -242,14 +205,6 @@ export class OrbView implements IOrbVi this._settings.getPosition = settings.getPosition; } - if (settings.simulation) { - this._settings.simulation = { - ...this._settings.simulation, - ...settings.simulation, - }; - this._simulator.setSettings(this._settings.simulation); - } - if (settings.render) { this._renderer.setSettings(settings.render); this._settings.render = this._renderer.getSettings(); @@ -262,28 +217,26 @@ export class OrbView implements IOrbVi ...settings.layout, }; - this._graph.setLayout(LayoutFactory.create(this._settings.layout)); - const nodePositions = this._graph.getNodePositions(); const edgePositions = this._graph.getEdgePositions(); - this._simulator.setupData({ nodes: nodePositions, edges: edgePositions }); - - if (this._settings.layout.type === 'force') { - this._enableSimulation(); - this._simulator.releaseNodes(); - } else { - this._disableSimulation(); - this._simulator.clearData(); + if (shouldRecenter) { + for (let i = 0; i < nodePositions.length; i++) { + delete (nodePositions[i] as any).x; + delete (nodePositions[i] as any).y; + } } + this._simulator.setSettings(this._settings.layout); + this._simulator.releaseNodes(); + if (shouldRecenter) { this._simulator.once(SimulatorEventType.SIMULATION_END, () => { this.recenter(); }); } - this.render(); + this._simulator.setupData({ nodes: nodePositions, edges: edgePositions }); } if (settings.strategy) { @@ -326,21 +279,40 @@ export class OrbView implements IOrbVi }; render(onRendered?: () => void) { + if (onRendered) { + if (this._simulator.isSimulationRunning()) { + this._simulator.once(SimulatorEventType.SIMULATION_END, () => { + this._renderer.once(RenderEventType.RENDER_END, () => onRendered()); + }); + } else { + this._renderer.once(RenderEventType.RENDER_END, () => onRendered()); + } + } + this._renderer.render(this._graph); - onRendered?.(); } - recenter(onRendered?: () => void) { - const fitZoomTransform = this._renderer.getFitZoomTransform(this._graph); + recenter(options?: Partial, onRendered?: () => void): void; + recenter(onRendered?: () => void): void; + recenter(optionsOrCallback?: Partial | (() => void), onRendered?: () => void) { + if (typeof optionsOrCallback === 'function') { + onRendered = optionsOrCallback; + optionsOrCallback = undefined; + } + + const layoutAnchors = getLayoutAnchors(this._settings.layout as ILayoutSettings); + const recenterOptions: IFitZoomTransformOptions = { + ...layoutAnchors, + ...optionsOrCallback, + }; + const fitZoomTransform = this._renderer.getFitZoomTransform(this._graph, recenterOptions); select(this._renderer.canvas) .transition() .duration(this._settings.zoomFitTransitionMs) .ease(easeLinear) .call(this._d3Zoom.transform, fitZoomTransform) - .call(() => { - this.render(onRendered); - }); + .on('end', () => this.render(onRendered)); } destroy() { @@ -612,9 +584,7 @@ export class OrbView implements IOrbVi .duration(this._settings.zoomFitTransitionMs) .ease(easeLinear) .call(this._d3Zoom.scaleBy, 1.2) - .call(() => { - this.render(onRendered); - }); + .on('end', () => this.render(onRendered)); }; zoomOut = (onRendered?: () => void) => { @@ -623,7 +593,7 @@ export class OrbView implements IOrbVi .duration(this._settings.zoomFitTransitionMs) .ease(easeLinear) .call(this._d3Zoom.scaleBy, 0.8) - .call(() => this.render(onRendered)); + .on('end', () => this.render(onRendered)); }; private _update: IObserver = (data?: IObserverDataPayload): void => { @@ -646,9 +616,8 @@ export class OrbView implements IOrbVi this.render(); }; - private _enableSimulation = () => { + private _initializeSimulationEvents = () => { this._simulator.on(SimulatorEventType.SIMULATION_START, () => { - // this._isSimulating = true; this._simulationStartedAt = Date.now(); this._events.emit(OrbEventType.SIMULATION_START, undefined); }); @@ -660,9 +629,6 @@ export class OrbView implements IOrbVi this._simulator.on(SimulatorEventType.SIMULATION_END, (data) => { this._graph.setNodePositions(data.nodes); this.render(); - // this._isSimulating = false; - this._onSimulationEnd?.(); - this._onSimulationEnd = undefined; this._events.emit(OrbEventType.SIMULATION_END, { durationMs: Date.now() - this._simulationStartedAt }); }); this._simulator.on(SimulatorEventType.SIMULATION_STEP, (data) => { @@ -674,44 +640,8 @@ export class OrbView implements IOrbVi this.render(); }); this._simulator.on(SimulatorEventType.SETTINGS_UPDATE, (data) => { - this._settings.simulation = data.settings; - }); - - this._simulator.activateSimulation(); - }; - - private _disableSimulation = () => { - this._simulator.off(SimulatorEventType.SIMULATION_START, () => { - // this._isSimulating = true; - this._simulationStartedAt = Date.now(); - this._events.emit(OrbEventType.SIMULATION_START, undefined); + this._settings.layout.options = data.settings?.options; }); - this._simulator.off(SimulatorEventType.SIMULATION_PROGRESS, (data) => { - this._graph.setNodePositions(data.nodes); - this._events.emit(OrbEventType.SIMULATION_STEP, { progress: data.progress }); - this.render(); - }); - this._simulator.off(SimulatorEventType.SIMULATION_END, (data) => { - this._graph.setNodePositions(data.nodes); - this.render(); - // this._isSimulating = false; - this._onSimulationEnd?.(); - this._onSimulationEnd = undefined; - this._events.emit(OrbEventType.SIMULATION_END, { durationMs: Date.now() - this._simulationStartedAt }); - }); - this._simulator.off(SimulatorEventType.SIMULATION_STEP, (data) => { - this._graph.setNodePositions(data.nodes); - this.render(); - }); - this._simulator.off(SimulatorEventType.NODE_DRAG, (data) => { - this._graph.setNodePositions(data.nodes); - this.render(); - }); - this._simulator.off(SimulatorEventType.SETTINGS_UPDATE, (data) => { - this._settings.simulation = data.settings; - }); - - this._simulator.stopSimulation(); }; // TODO: Do we keep these diff --git a/src/views/shared.ts b/src/views/shared.ts index 98c28aa..4578dde 100644 --- a/src/views/shared.ts +++ b/src/views/shared.ts @@ -2,10 +2,12 @@ import { INodeBase } from '../models/node'; import { IEdgeBase } from '../models/edge'; import { IGraph } from '../models/graph'; import { OrbEmitter } from '../events'; +import { IGraphInteraction } from '../models/interaction'; export interface IOrbView { data: IGraph; events: OrbEmitter; + interaction: IGraphInteraction; getSettings(): S; setSettings(settings: Partial): void; render(onRendered?: () => void): void;