├── .gitignore
├── .npmignore
├── README.md
├── dist
├── d3.d.ts
├── example
│ └── index.html
├── index.d.ts
├── initializeSVG.d.ts
├── links
│ ├── draw-links.d.ts
│ ├── link-enter.d.ts
│ ├── link-exit.d.ts
│ └── link-update.d.ts
├── nodes
│ ├── node-enter.d.ts
│ ├── node-exit.d.ts
│ └── node-update.d.ts
├── prepare-data.d.ts
├── treeviz.js
├── typings.d.ts
└── utils.d.ts
├── example
├── example.ts
└── index.html
├── package.json
├── src
├── d3.ts
├── index.ts
├── initializeSVG.ts
├── links
│ ├── draw-links.ts
│ ├── link-enter.ts
│ ├── link-exit.ts
│ └── link-update.ts
├── nodes
│ ├── node-enter.ts
│ ├── node-exit.ts
│ └── node-update.ts
├── prepare-data.ts
├── typings.ts
├── utils.ts
└── vite-env.d.ts
├── tsconfig.json
├── vite.config.ts
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist-ssr
12 | *.local
13 |
14 | # Editor directories and files
15 | .vscode/*
16 | !.vscode/extensions.json
17 | .idea
18 | .DS_Store
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | src/
2 | example/
3 | vite.config.ts
4 | tsconfig.json
5 | dist/example/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Treeviz
2 |
3 | [](https://snyk.io/test/github/dwyl/hapi-auth-jwt2?targetFile=package.json)
4 | [](./LICENSE)
5 |
6 | This javascript module aims at providing an easy interface in order to represent tree diagrams on screen with the ability to handle dynamic data flows. The data format must be JSON.
7 |
8 | 
9 |
10 | ## Installation
11 |
12 | With npm :
13 |
14 | ```Bash
15 | npm install treeviz
16 | ```
17 |
18 | and then you can use it with :
19 |
20 | ```JavaScript
21 | import {Treeviz} from 'treeviz';
22 | ```
23 |
24 | Or download this zip repository in the Github Release section and link the dist/treeviz.js file in your page directly : `
55 | ```
56 |
57 | To update the tree visually you will just have to pass new data to the `refresh` method like this :
58 |
59 | ```JS
60 | myTree.refresh(data);
61 | myTree.refresh(data_update1);
62 | myTree.refresh(data_update2);
63 | ```
64 |
65 | The tree will be clever enough to updates only the part of the trees that have been added or removed in the dataset, and so it won't redraw the entire tree.
66 |
67 | [Treeviz Example](https://codepen.io/pierrecapo/pen/MPbBdv)
68 |
69 | #### Hierarchical data case :
70 |
71 | ```js
72 | var hierarchical_data_example = {
73 | name: "Mom",
74 | qty: 10,
75 | children: [
76 | { name: "Son A", qty: 3 },
77 | { name: "Son B", qty: 7 },
78 | ],
79 | };
80 |
81 | var myTree = Treeviz.create({
82 | htmlId: "tree",
83 | idKey: "name",
84 | hasFlatData: false,
85 | relationnalField: "children",
86 | });
87 |
88 | myTree.refresh(hierarchical_data_example);
89 | ```
90 |
91 | ## API
92 |
93 | The big part of the API is configuring the tree before passing data to it :
94 |
95 | ```JS
96 | Treeviz.create(config);
97 | ```
98 |
99 | The table below lists all the avalaible key that the config object can have
100 |
101 | | Key | Type | Default | Definition |
102 | | -------------------------- | --------------------------------------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
103 | | `htmlId` | string (Required) | | The HTML id tag on the page where the tree should be drawn. It must have a width and an height specified |
104 | | `idKey` | string | "id" | The key in a data item representing the unique identifier of a node |
105 | | `relationnalField` | string | "father" | In case of flat dataset, usually the relationnal field between each node is the field representing the father of the node, linking it to the id of the field. (See example below). |
106 | | `hasFlatData` | boolean | true | Specify whether the data passed to the tree is flat or already hierarchical |
107 | | `hasPan` | boolean | false | Toggle the ability to pan the tree |
108 | | `hasZoom` | boolean | false | Toggle the ability to zoom the tree |
109 | | `nodeWidth` | number | 160 | Width of a node in px |
110 | | `nodeHeight` | number | 100 | Height of a node in px |
111 | | `linkColor` | function | (node: NodeData) => "#ffcc80" | Color of the link |
112 | | `linkWidth` | function | (node: NodeData) => 10 | Width of the link |
113 | | `linkShape` | "quadraticBeziers" \| "orthogonal" \| "curve" | "quadraticBeziers" | Shape of the link |
114 | | `renderNode` | function | (node: NodeData) => null | HTML template for every node |
115 | | `isHorizontal` | boolean | true | Direction of the tree. If true, the tree expands from left to right. If false, it goes from top to bottom |
116 | | `onNodeClick` | function | (node: NodeData) => null | Function handling the event when someone click on it |
117 | | `onNodeMouseEnter` | function | (node: NodeData) => null | Function handling the event when someone hover a node |
118 | | `onNodeMouseLeave` | function | (node: NodeData) => null | Function handling the event when the mouse pointer leaves a node |
119 | | `mainAxisNodeSpacing` | number or "auto" | 300 | Set the distance in pixels between two depths in the tree. If the value is `auto` it will automatically display the tree to fit the size of the container. |
120 | | `secondaryAxisNodeSpacing` | number | 1.25 | Set the distance between nodes in the same level as a coefficient of node dimensions. Recommended to have the value superior to 1 |
121 | | `marginTop` | number | 1.25 | Set the margin between the SVG element and the tree |
122 | | `marginBottom` | number | 1.25 | Set the margin between the SVG element and the tree |
123 | | `marginLeft` | number | 1.25 | Set the margin between the SVG element and the tree |
124 | | `marginRight` | number | 1.25 | Set the margin between the SVG element and the tree |
125 | | `duration` | number | 600 | The duration of the animation transition between layouts |
126 | | `data` | any | | Needed for Typescript projects only to type the `NodeData` argument |
127 |
128 | And then, we have the `NodeData` type that is passed as callback of some functions:
129 | `
130 | type NodeData {
131 | data: // the data of each item
132 | settings: // the settings object
133 | }
134 | `
135 |
136 | ## Contributing
137 |
138 | - Clone the repo.
139 | - Run `npm install`.
140 | - Run `npm run dev`, then you can edit the files in the `./src` folder and the `./example/index.html` file.
141 | - To publish (admin rights), run `npm run build && npm publish`.
142 |
143 | ## Credits
144 |
145 | This module is based on d3 library, credit to all the contributors of this project.
146 |
147 | ## License
148 |
149 | MIT
150 |
--------------------------------------------------------------------------------
/dist/d3.d.ts:
--------------------------------------------------------------------------------
1 | import { hierarchy, stratify, tree, treemap } from "d3-hierarchy";
2 | import { select, selectAll } from "d3-selection";
3 | import { zoom } from "d3-zoom";
4 | declare const _default: {
5 | hierarchy: typeof hierarchy;
6 | stratify: typeof stratify;
7 | tree: typeof tree;
8 | treemap: typeof treemap;
9 | select: typeof select;
10 | selectAll: typeof selectAll;
11 | zoom: typeof zoom;
12 | };
13 | export default _default;
14 |
--------------------------------------------------------------------------------
/dist/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
25 |
26 |
--------------------------------------------------------------------------------
/dist/index.d.ts:
--------------------------------------------------------------------------------
1 | import { ITreeConfig } from "./typings";
2 | export declare const Treeviz: {
3 | create: typeof create;
4 | };
5 | declare function create(userSettings: Partial): {
6 | refresh: (data: any, newSettings?: Partial) => void;
7 | clean: (keepConfig: boolean) => void;
8 | };
9 | export {};
10 |
--------------------------------------------------------------------------------
/dist/initializeSVG.d.ts:
--------------------------------------------------------------------------------
1 | import { ITreeConfig } from "./typings";
2 | export declare const initiliazeSVG: (treeConfig: ITreeConfig) => import("d3-selection").Selection;
3 |
--------------------------------------------------------------------------------
/dist/links/draw-links.d.ts:
--------------------------------------------------------------------------------
1 | import { ITreeConfig } from "../typings";
2 | interface ICoordinates {
3 | x: number;
4 | y: number;
5 | }
6 | export declare const generateLinkLayout: (s: ICoordinates, d: ICoordinates, treeConfig: ITreeConfig) => string;
7 | export {};
8 |
--------------------------------------------------------------------------------
/dist/links/link-enter.d.ts:
--------------------------------------------------------------------------------
1 | import { HierarchyPointNode } from "d3-hierarchy";
2 | import { BaseType, Selection } from "d3-selection";
3 | import { ExtendedHierarchyPointNode, ITreeConfig } from "../typings";
4 | export declare const drawLinkEnter: (link: Selection, SVGGElement, {}>, settings: ITreeConfig, nodes: ExtendedHierarchyPointNode[], oldNodes: ExtendedHierarchyPointNode[]) => Selection, SVGGElement, {}>;
5 |
--------------------------------------------------------------------------------
/dist/links/link-exit.d.ts:
--------------------------------------------------------------------------------
1 | import { HierarchyPointNode } from "d3-hierarchy";
2 | import { BaseType, Selection } from "d3-selection";
3 | import { ExtendedHierarchyPointNode, ITreeConfig } from "../typings";
4 | export declare const drawLinkExit: (link: Selection, SVGGElement, {}>, settings: ITreeConfig, nodes: ExtendedHierarchyPointNode[], oldNodes: ExtendedHierarchyPointNode[]) => void;
5 |
--------------------------------------------------------------------------------
/dist/links/link-update.d.ts:
--------------------------------------------------------------------------------
1 | import { HierarchyPointNode } from "d3-hierarchy";
2 | import { Selection } from "d3-selection";
3 | import { ITreeConfig } from "../typings";
4 | export declare const drawLinkUpdate: (linkEnter: Selection, SVGGElement, {}>, link: Selection, SVGGElement, {}>, settings: ITreeConfig) => void;
5 |
--------------------------------------------------------------------------------
/dist/nodes/node-enter.d.ts:
--------------------------------------------------------------------------------
1 | import { BaseType, Selection } from "d3-selection";
2 | import { ExtendedHierarchyPointNode, ITreeConfig } from "../typings";
3 | export declare const drawNodeEnter: (node: Selection, settings: ITreeConfig, nodes: ExtendedHierarchyPointNode[], oldNodes: ExtendedHierarchyPointNode[]) => string & Selection;
4 |
--------------------------------------------------------------------------------
/dist/nodes/node-exit.d.ts:
--------------------------------------------------------------------------------
1 | import { BaseType, Selection } from "d3-selection";
2 | import { ExtendedHierarchyPointNode, ITreeConfig } from "../typings";
3 | export declare const drawNodeExit: (node: Selection, settings: ITreeConfig, nodes: ExtendedHierarchyPointNode[], oldNodes: ExtendedHierarchyPointNode[]) => void;
4 |
--------------------------------------------------------------------------------
/dist/nodes/node-update.d.ts:
--------------------------------------------------------------------------------
1 | import { Selection } from "d3-selection";
2 | import { ExtendedHierarchyPointNode, ITreeConfig } from "../typings";
3 | export declare const drawNodeUpdate: (nodeEnter: Selection, node: Selection, settings: ITreeConfig) => void;
4 |
--------------------------------------------------------------------------------
/dist/prepare-data.d.ts:
--------------------------------------------------------------------------------
1 | import { HierarchyNode } from "d3-hierarchy";
2 | import { ITreeConfig } from "./typings";
3 | export declare const generateNestedData: (data: any, treeConfig: ITreeConfig) => HierarchyNode;
4 | export declare const generateBasicTreemap: (treeConfig: ITreeConfig) => import("d3-hierarchy").TreeLayout;
5 |
--------------------------------------------------------------------------------
/dist/treeviz.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | const e = document.createElement("link").relList;
3 | if (e && e.supports && e.supports("modulepreload"))
4 | return;
5 | for (const r of document.querySelectorAll('link[rel="modulepreload"]'))
6 | d(r);
7 | new MutationObserver((r) => {
8 | for (const i of r)
9 | if (i.type === "childList")
10 | for (const l of i.addedNodes)
11 | l.tagName === "LINK" && l.rel === "modulepreload" && d(l);
12 | }).observe(document, { childList: !0, subtree: !0 });
13 | function a(r) {
14 | const i = {};
15 | return r.integrity && (i.integrity = r.integrity), r.referrerPolicy && (i.referrerPolicy = r.referrerPolicy), r.crossOrigin === "use-credentials" ? i.credentials = "include" : r.crossOrigin === "anonymous" ? i.credentials = "omit" : i.credentials = "same-origin", i;
16 | }
17 | function d(r) {
18 | if (r.ep)
19 | return;
20 | r.ep = !0;
21 | const i = a(r);
22 | fetch(r.href, i);
23 | }
24 | })();
25 | function s(t, e, a) {
26 | this.k = t, this.x = e, this.y = a;
27 | }
28 | s.prototype = {
29 | constructor: s,
30 | scale: function(t) {
31 | return t === 1 ? this : new s(this.k * t, this.x, this.y);
32 | },
33 | translate: function(t, e) {
34 | return t === 0 & e === 0 ? this : new s(this.k, this.x + this.k * t, this.y + this.k * e);
35 | },
36 | apply: function(t) {
37 | return [t[0] * this.k + this.x, t[1] * this.k + this.y];
38 | },
39 | applyX: function(t) {
40 | return t * this.k + this.x;
41 | },
42 | applyY: function(t) {
43 | return t * this.k + this.y;
44 | },
45 | invert: function(t) {
46 | return [(t[0] - this.x) / this.k, (t[1] - this.y) / this.k];
47 | },
48 | invertX: function(t) {
49 | return (t - this.x) / this.k;
50 | },
51 | invertY: function(t) {
52 | return (t - this.y) / this.k;
53 | },
54 | rescaleX: function(t) {
55 | return t.copy().domain(t.range().map(this.invertX, this).map(t.invert, t));
56 | },
57 | rescaleY: function(t) {
58 | return t.copy().domain(t.range().map(this.invertY, this).map(t.invert, t));
59 | },
60 | toString: function() {
61 | return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")";
62 | }
63 | };
64 | s.prototype;
65 | var h = [{
66 | id: 1,
67 | text_1: "Chaos",
68 | text_2: "Void",
69 | father: null,
70 | color: "#FF5722"
71 | }, {
72 | id: 2,
73 | text_1: "Tartarus",
74 | text_2: "Abyss",
75 | father: 1,
76 | color: "#FFC107"
77 | }, {
78 | id: 3,
79 | text_1: "Gaia",
80 | text_2: "Earth",
81 | father: 1,
82 | color: "#8BC34A"
83 | }, {
84 | id: 4,
85 | text_1: "Eros",
86 | text_2: "Desire",
87 | father: 1,
88 | color: "#00BCD4"
89 | }], f = [{
90 | id: 1,
91 | text_1: "Chaos",
92 | text_2: " Void",
93 | father: null,
94 | color: "#2196F3"
95 | }, {
96 | id: 2,
97 | text_1: "Tartarus",
98 | text_2: "Abyss",
99 | father: 1,
100 | color: "#F44336"
101 | }, {
102 | id: 3,
103 | text_1: "Gaia",
104 | text_2: "Earth",
105 | father: 1,
106 | color: "#673AB7"
107 | }, {
108 | id: 4,
109 | text_1: "Eros",
110 | text_2: "Desire",
111 | father: 1,
112 | color: "#009688"
113 | }, {
114 | id: 5,
115 | text_1: "Uranus",
116 | text_2: "Sky",
117 | father: 3,
118 | color: "#4CAF50"
119 | }, {
120 | id: 6,
121 | text_1: "Ourea",
122 | text_2: "Mountains",
123 | father: 3,
124 | color: "#FF9800"
125 | }], x = [{
126 | id: 1,
127 | text_1: "Chaos",
128 | text_2: "Void",
129 | father: null,
130 | color: "#2196F3"
131 | }, {
132 | id: 2,
133 | text_1: "Tartarus",
134 | text_2: "Abyss",
135 | father: 1,
136 | color: "#F44336"
137 | }, {
138 | id: 3,
139 | text_1: "Gaia",
140 | text_2: "Earth",
141 | father: 1,
142 | color: "#673AB7"
143 | }, {
144 | id: 4,
145 | text_1: "Eros",
146 | text_2: "Desire",
147 | father: 1,
148 | color: "#009688"
149 | }, {
150 | id: 5,
151 | text_1: "Uranus",
152 | text_2: "Sky",
153 | father: 3,
154 | color: "#4CAF50"
155 | }, {
156 | id: 6,
157 | text_1: "Ourea",
158 | text_2: "Mountains",
159 | father: 3,
160 | color: "#FF9800"
161 | }, {
162 | id: 7,
163 | text_1: "Hermes",
164 | text_2: " Sky",
165 | father: 4,
166 | color: "#2196F3"
167 | }, {
168 | id: 8,
169 | text_1: "Aphrodite",
170 | text_2: "Love",
171 | father: 4,
172 | color: "#8BC34A"
173 | }, {
174 | id: 3.3,
175 | text_1: "Love",
176 | text_2: "Peace",
177 | father: 8,
178 | color: "#c72e99"
179 | }, {
180 | id: 4.1,
181 | text_1: "Hope",
182 | text_2: "Life",
183 | father: 8,
184 | color: "#2eecc7"
185 | }], c = (void 0)({
186 | htmlId: "tree",
187 | idKey: "id",
188 | hasFlatData: !0,
189 | relationnalField: "father",
190 | nodeWidth: 120,
191 | hasPan: !0,
192 | hasZoom: !0,
193 | nodeHeight: 80,
194 | mainAxisNodeSpacing: 2,
195 | isHorizontal: !1,
196 | renderNode: function(e) {
197 | return "" + e.data.text_1 + "
is
" + e.data.text_2 + "
";
198 | },
199 | linkWidth: function(e) {
200 | return 5;
201 | },
202 | linkShape: "curve",
203 | linkColor: function(e) {
204 | return e.linkColor || "#B0BEC5";
205 | },
206 | onNodeClick: function(e) {
207 | return console.log(e);
208 | }
209 | });
210 | c.refresh(h);
211 | var u = !0, n = document.querySelector("#add"), o = document.querySelector("#remove"), _ = document.querySelector("#doTasks");
212 | n.addEventListener("click", function() {
213 | console.log("addButton clicked"), u ? c.refresh(f) : c.refresh(x), u = !1;
214 | });
215 | o.addEventListener("click", function() {
216 | console.log("removeButton clicked"), c.refresh(h);
217 | });
218 | _.addEventListener("click", function() {
219 | n.click(), o.click(), n.click(), o.click(), o.click(), n.click(), o.click(), n.click(), n.click(), o.click(), o.click();
220 | });
221 |
--------------------------------------------------------------------------------
/dist/typings.d.ts:
--------------------------------------------------------------------------------
1 | import { HierarchyPointNode } from "d3-hierarchy";
2 | export interface ITreeConfig {
3 | htmlId: string;
4 | idKey: string;
5 | relationnalField: string;
6 | hasFlatData: boolean;
7 | nodeWidth: number;
8 | nodeHeight: number;
9 | mainAxisNodeSpacing: number | "auto";
10 | renderNode: (node: any) => string | null;
11 | linkShape?: "quadraticBeziers" | "curve" | "orthogonal" | "";
12 | linkColor: (node: any) => string;
13 | linkWidth: (node: any) => number;
14 | onNodeClick: (node: any) => void;
15 | onNodeMouseEnter: (node: any) => void;
16 | onNodeMouseLeave: (node: any) => void;
17 | isHorizontal: boolean;
18 | hasPan: boolean;
19 | hasZoom: boolean;
20 | duration: number;
21 | marginTop: number;
22 | marginBottom: number;
23 | marginLeft: number;
24 | marginRight: number;
25 | secondaryAxisNodeSpacing: number;
26 | }
27 | export interface ExtendedHierarchyPointNode extends HierarchyPointNode<{}> {
28 | x0?: number;
29 | y0?: number;
30 | }
31 |
--------------------------------------------------------------------------------
/dist/utils.d.ts:
--------------------------------------------------------------------------------
1 | import { ExtendedHierarchyPointNode, ITreeConfig } from "./typings";
2 | export declare const getAreaSize: (htmlId: string) => {
3 | areaWidth: number;
4 | areaHeight: number;
5 | };
6 | type Result = ExtendedHierarchyPointNode & {
7 | x0: number;
8 | y0: number;
9 | };
10 | export declare const getFirstDisplayedAncestor: (ghostNodes: ExtendedHierarchyPointNode[], viewableNodes: ExtendedHierarchyPointNode[], id: string) => Result;
11 | export declare const setNodeLocation: (xPosition: number, yPosition: number, settings: ITreeConfig) => string;
12 | export declare class RefreshQueue {
13 | private static queue;
14 | private static runner;
15 | private static runnerSpeed;
16 | private static readonly extraDelayBetweenCallbacks;
17 | private static showQueueLog;
18 | static add(duration: number, callback: () => any): void;
19 | private static runnerFunction;
20 | private static log;
21 | }
22 | export {};
23 |
--------------------------------------------------------------------------------
/example/example.ts:
--------------------------------------------------------------------------------
1 | import { Treeviz } from "../src";
2 |
3 | var data_1 = [
4 | {
5 | id: 1,
6 | text_1: "Chaos",
7 | text_2: "Void",
8 | father: null,
9 | color: "#FF5722",
10 | },
11 | {
12 | id: 2,
13 | text_1: "Tartarus",
14 | text_2: "Abyss",
15 | father: 1,
16 | color: "#FFC107",
17 | },
18 | {
19 | id: 3,
20 | text_1: "Gaia",
21 | text_2: "Earth",
22 | father: 1,
23 | color: "#8BC34A",
24 | },
25 | {
26 | id: 4,
27 | text_1: "Eros",
28 | text_2: "Desire",
29 | father: 1,
30 | color: "#00BCD4",
31 | },
32 | ];
33 | var data_2 = [
34 | {
35 | id: 1,
36 | text_1: "Chaos",
37 | text_2: " Void",
38 | father: null,
39 | color: "#2196F3",
40 | },
41 | {
42 | id: 2,
43 | text_1: "Tartarus",
44 | text_2: "Abyss",
45 | father: 1,
46 | color: "#F44336",
47 | },
48 | {
49 | id: 3,
50 | text_1: "Gaia",
51 | text_2: "Earth",
52 | father: 1,
53 | color: "#673AB7",
54 | },
55 | {
56 | id: 4,
57 | text_1: "Eros",
58 | text_2: "Desire",
59 | father: 1,
60 | color: "#009688",
61 | },
62 | {
63 | id: 5,
64 | text_1: "Uranus",
65 | text_2: "Sky",
66 | father: 3,
67 | color: "#4CAF50",
68 | },
69 | {
70 | id: 6,
71 | text_1: "Ourea",
72 | text_2: "Mountains",
73 | father: 3,
74 | color: "#FF9800",
75 | },
76 | ];
77 | var data_3 = [
78 | {
79 | id: 1,
80 | text_1: "Chaos",
81 | text_2: "Void",
82 | father: null,
83 | color: "#2196F3",
84 | },
85 | {
86 | id: 2,
87 | text_1: "Tartarus",
88 | text_2: "Abyss",
89 | father: 1,
90 | color: "#F44336",
91 | },
92 | {
93 | id: 3,
94 | text_1: "Gaia",
95 | text_2: "Earth",
96 | father: 1,
97 | color: "#673AB7",
98 | },
99 | {
100 | id: 4,
101 | text_1: "Eros",
102 | text_2: "Desire",
103 | father: 1,
104 | color: "#009688",
105 | },
106 | {
107 | id: 5,
108 | text_1: "Uranus",
109 | text_2: "Sky",
110 | father: 3,
111 | color: "#4CAF50",
112 | },
113 | {
114 | id: 6,
115 | text_1: "Ourea",
116 | text_2: "Mountains",
117 | father: 3,
118 | color: "#FF9800",
119 | },
120 | {
121 | id: 7,
122 | text_1: "Hermes",
123 | text_2: " Sky",
124 | father: 4,
125 | color: "#2196F3",
126 | },
127 | {
128 | id: 8,
129 | text_1: "Aphrodite",
130 | text_2: "Love",
131 | father: 4,
132 | color: "#8BC34A",
133 | },
134 | {
135 | id: 3.3,
136 | text_1: "Love",
137 | text_2: "Peace",
138 | father: 8,
139 | color: "#c72e99",
140 | },
141 | {
142 | id: 4.1,
143 | text_1: "Hope",
144 | text_2: "Life",
145 | father: 8,
146 | color: "#2eecc7",
147 | },
148 | ];
149 |
150 | var myTree = Treeviz.create({
151 | data: data_1, // for Typescript projects only.
152 | htmlId: "tree",
153 | idKey: "id",
154 | hasFlatData: true,
155 | relationnalField: "father",
156 | nodeWidth: 120,
157 | hasPan: true,
158 | hasZoom: true,
159 | nodeHeight: 80,
160 | mainAxisNodeSpacing: 2,
161 | isHorizontal: false,
162 | renderNode: function renderNode(node) {
163 | return (
164 | "" +
171 | node.data.text_1 +
172 | "
is
" +
173 | node.data.text_2 +
174 | "
"
175 | );
176 | },
177 | linkWidth: (node) => {
178 | return node.data.id * 2;
179 | },
180 | linkShape: "curve",
181 | linkColor: () => `#B0BEC5`,
182 | onNodeClick: (node) => {
183 | console.log(node.data);
184 | },
185 | onNodeMouseEnter: (node) => {
186 | console.log(node.data);
187 | },
188 | });
189 | myTree.refresh(data_1);
190 |
191 | var toggle = true;
192 | var addButton = document.querySelector("#add");
193 | var removeButton = document.querySelector("#remove");
194 | var doTasksButton = document.querySelector("#doTasks");
195 | addButton?.addEventListener("click", function () {
196 | console.log("addButton clicked");
197 | toggle ? myTree.refresh(data_2) : myTree.refresh(data_3);
198 | toggle = false;
199 | });
200 | removeButton?.addEventListener("click", function () {
201 | console.log("removeButton clicked");
202 | myTree.refresh(data_1);
203 | });
204 | doTasksButton?.addEventListener("click", function () {
205 | addButton?.click();
206 | removeButton?.click();
207 | addButton?.click();
208 | removeButton?.click();
209 | removeButton?.click();
210 | addButton?.click();
211 | removeButton?.click();
212 | addButton?.click();
213 | addButton?.click();
214 | removeButton?.click();
215 | removeButton?.click();
216 | });
217 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
11 |
17 |
23 |
24 |
25 |
26 |
34 |
35 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "treeviz",
3 | "version": "3.0.1",
4 | "type": "module",
5 | "description": "Library which aims to represent trees for data visualization",
6 | "license": "MIT",
7 | "main": "./dist/treeviz.js",
8 | "types": "./dist/index.d.ts",
9 | "keywords": [
10 | "d3",
11 | "data",
12 | "visualization",
13 | "tree",
14 | "decision",
15 | "hierarchy",
16 | "dynamic"
17 | ],
18 | "repository": {
19 | "type": "git",
20 | "url": "https://github.com/PierreCapo/treeviz"
21 | },
22 | "scripts": {
23 | "dev": "vite",
24 | "build": "tsc && vite build",
25 | "preview": "vite preview"
26 | },
27 | "devDependencies": {
28 | "@types/node": "^20.10.3",
29 | "typescript": "^5.3.2",
30 | "vite": "^5.0.6",
31 | "vite-plugin-dts": "^3.6.4"
32 | },
33 | "dependencies": {
34 | "@types/d3-hierarchy": "^3.1.6",
35 | "@types/d3-selection": "^3.0.10",
36 | "@types/d3-transition": "^3.0.8",
37 | "@types/d3-zoom": "^3.0.8",
38 | "d3-hierarchy": "^3.1.2",
39 | "d3-selection": "^3.0.0",
40 | "d3-transition": "^3.0.1",
41 | "d3-zoom": "^3.0.0"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/d3.ts:
--------------------------------------------------------------------------------
1 | import { hierarchy, stratify, tree, treemap } from "d3-hierarchy";
2 | import { select, selectAll } from "d3-selection";
3 | import { zoom } from "d3-zoom";
4 |
5 | export default {
6 | hierarchy,
7 | stratify,
8 | tree,
9 | treemap,
10 | select,
11 | selectAll,
12 | zoom,
13 | };
14 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { HierarchyPointNode } from "d3-hierarchy";
2 | import { BaseType, Selection } from "d3-selection";
3 | import { initiliazeSVG } from "./initializeSVG";
4 | import { drawLinkEnter } from "./links/link-enter";
5 | import { drawLinkExit } from "./links/link-exit";
6 | import { drawLinkUpdate } from "./links/link-update";
7 | import { drawNodeEnter } from "./nodes/node-enter";
8 | import { drawNodeExit } from "./nodes/node-exit";
9 | import { drawNodeUpdate } from "./nodes/node-update";
10 | import { generateBasicTreemap, generateNestedData } from "./prepare-data";
11 | import { ExtendedHierarchyPointNode, ITreeConfig } from "./typings";
12 | import { RefreshQueue } from "./utils";
13 |
14 | export const Treeviz = {
15 | create,
16 | };
17 |
18 | function create(userSettings: Partial>) {
19 | const defaultSettings: ITreeConfig = {
20 | data: [],
21 | htmlId: "",
22 | idKey: "id",
23 | relationnalField: "father",
24 | hasFlatData: true,
25 | nodeWidth: 160,
26 | nodeHeight: 100,
27 | mainAxisNodeSpacing: 300,
28 | renderNode: () => "Node",
29 | linkColor: () => "#ffcc80",
30 | linkWidth: () => 10,
31 | linkShape: "quadraticBeziers",
32 | isHorizontal: true,
33 | hasPan: false,
34 | hasZoom: false,
35 | duration: 600,
36 | onNodeClick: () => undefined,
37 | onNodeMouseEnter: () => undefined,
38 | onNodeMouseLeave: () => undefined,
39 | marginBottom: 0,
40 | marginLeft: 0,
41 | marginRight: 0,
42 | marginTop: 0,
43 | secondaryAxisNodeSpacing: 1.25,
44 | };
45 |
46 | // @ts-ignore
47 | let settings: ITreeConfig = {
48 | ...defaultSettings,
49 | ...userSettings,
50 | };
51 |
52 | let oldNodes: ExtendedHierarchyPointNode[] = [];
53 |
54 | function draw(
55 | svg: Selection,
56 | computedTree: HierarchyPointNode<{}>
57 | ) {
58 | const nodes = computedTree.descendants() as ExtendedHierarchyPointNode[];
59 |
60 | const links = computedTree.descendants().slice(1);
61 |
62 | const { mainAxisNodeSpacing: mainAxisNodeSpacing } = settings;
63 | if (mainAxisNodeSpacing !== "auto") {
64 | // Normalize for fixed-depth.
65 | nodes.forEach((d) => {
66 | d.y = d.depth * settings.nodeWidth * mainAxisNodeSpacing;
67 | });
68 | }
69 |
70 | nodes.forEach((currentNode: ExtendedHierarchyPointNode) => {
71 | const currentNodeOldPosition = oldNodes.find(
72 | (node) => node.id === currentNode.id
73 | );
74 | currentNode.x0 = currentNodeOldPosition
75 | ? currentNodeOldPosition.x0
76 | : currentNode.x;
77 | currentNode.y0 = currentNodeOldPosition
78 | ? currentNodeOldPosition.y0
79 | : currentNode.y;
80 | });
81 |
82 | // ****************** Nodes section ***************************
83 | const node: Selection<
84 | BaseType,
85 | ExtendedHierarchyPointNode,
86 | SVGGElement,
87 | {}
88 | > = svg.selectAll("g.node").data(nodes, (d: any) => {
89 | return d[settings.idKey];
90 | });
91 |
92 | const nodeEnter = drawNodeEnter(node, settings, nodes, oldNodes);
93 | //@ts-ignore
94 | drawNodeUpdate(nodeEnter, node, settings);
95 | drawNodeExit(node, settings, nodes, oldNodes);
96 |
97 | // ****************** links section ***************************
98 |
99 | const link = svg.selectAll("path.link").data(links, (d: any) => {
100 | return d.id;
101 | });
102 |
103 | const linkEnter = drawLinkEnter(link, settings, nodes, oldNodes);
104 | // @ts-ignore
105 | drawLinkUpdate(linkEnter, link, settings);
106 | drawLinkExit(link, settings, nodes, oldNodes);
107 |
108 | oldNodes = [...nodes];
109 | }
110 |
111 | function refresh(data: any, newSettings?: Partial) {
112 | RefreshQueue.add(settings.duration, () => {
113 | if (newSettings) {
114 | settings = { ...settings, ...newSettings };
115 | }
116 | const nestedData = generateNestedData(data, settings);
117 | const treemap = generateBasicTreemap(settings);
118 | const computedTree = treemap(nestedData); // mutation
119 |
120 | // @ts-ignore
121 | draw(svg, computedTree);
122 | });
123 | }
124 |
125 | function clean(keepConfig: boolean) {
126 | const myNode = keepConfig
127 | ? document.querySelector(`#${settings.htmlId} svg g`)
128 | : document.querySelector(`#${settings.htmlId}`);
129 | if (myNode) {
130 | while (myNode.firstChild) {
131 | myNode.removeChild(myNode.firstChild);
132 | }
133 | }
134 | oldNodes = [];
135 | }
136 |
137 | const treeObject = { refresh, clean };
138 |
139 | const svg = initiliazeSVG(settings);
140 | return treeObject;
141 | }
142 |
--------------------------------------------------------------------------------
/src/initializeSVG.ts:
--------------------------------------------------------------------------------
1 | import d3 from "./d3";
2 | import { ITreeConfig } from "./typings";
3 | import { getAreaSize } from "./utils";
4 |
5 | export const initiliazeSVG = (treeConfig: ITreeConfig) => {
6 | const {
7 | htmlId,
8 | isHorizontal,
9 | hasPan,
10 | hasZoom,
11 | mainAxisNodeSpacing,
12 | nodeHeight,
13 | nodeWidth,
14 | marginBottom,
15 | marginLeft,
16 | marginRight,
17 | marginTop,
18 | } = treeConfig;
19 | const margin = {
20 | top: marginTop,
21 | right: marginRight,
22 | bottom: marginBottom,
23 | left: marginLeft,
24 | };
25 | const { areaHeight, areaWidth } = getAreaSize(treeConfig.htmlId);
26 | const width = areaWidth - margin.left - margin.right;
27 | const height = areaHeight - margin.top - margin.bottom;
28 |
29 | const svg = d3
30 | .select("#" + htmlId)
31 | .append("svg")
32 | .attr("width", areaWidth)
33 | .attr("height", areaHeight);
34 |
35 | // Create a G container and move it according to the Zoom Behavior attached to the main element
36 | const ZoomContainer = svg.append("g");
37 | const zoom = d3.zoom().on("zoom", (e) => {
38 | ZoomContainer.attr("transform", () => e.transform);
39 | });
40 | // @ts-ignore
41 | svg.call(zoom);
42 |
43 | if (!hasPan) {
44 | svg
45 | .on("mousedown.zoom", null)
46 | .on("touchstart.zoom", null)
47 | .on("touchmove.zoom", null)
48 | .on("touchend.zoom", null);
49 | }
50 |
51 | if (!hasZoom) {
52 | svg
53 | .on("wheel.zoom", null)
54 | .on("mousewheel.zoom", null)
55 | .on("mousemove.zoom", null)
56 | .on("DOMMouseScroll.zoom", null)
57 | .on("dblclick.zoom", null);
58 | }
59 |
60 | const MainG = ZoomContainer.append("g").attr(
61 | "transform",
62 | mainAxisNodeSpacing === "auto"
63 | ? "translate(0,0)"
64 | : isHorizontal
65 | ? "translate(" +
66 | margin.left +
67 | "," +
68 | (margin.top + height / 2 - nodeHeight / 2) +
69 | ")"
70 | : "translate(" +
71 | (margin.left + width / 2 - nodeWidth / 2) +
72 | "," +
73 | margin.top +
74 | ")"
75 | );
76 | return MainG;
77 | };
78 |
--------------------------------------------------------------------------------
/src/links/draw-links.ts:
--------------------------------------------------------------------------------
1 | import { ITreeConfig } from "../typings";
2 |
3 | interface ICoordinates {
4 | x: number;
5 | y: number;
6 | }
7 |
8 | export const generateLinkLayout = (
9 | s: ICoordinates, // source
10 | d: ICoordinates, // destination
11 | treeConfig: ITreeConfig
12 | ): string => {
13 | const { isHorizontal, nodeHeight, nodeWidth, linkShape } = treeConfig;
14 | if (linkShape === "orthogonal") {
15 | if (isHorizontal) {
16 | return `M ${s.y} ${s.x + nodeHeight / 2}
17 | L ${(s.y + d.y + nodeWidth) / 2} ${s.x + nodeHeight / 2}
18 | L ${(s.y + d.y + nodeWidth) / 2} ${d.x + nodeHeight / 2}
19 | ${d.y + nodeWidth} ${d.x + nodeHeight / 2}`;
20 | } else {
21 | return `M ${s.x + nodeWidth / 2} ${s.y}
22 | L ${s.x + nodeWidth / 2} ${(s.y + d.y + nodeHeight) / 2}
23 | L ${d.x + nodeWidth / 2} ${(s.y + d.y + nodeHeight) / 2}
24 | ${d.x + nodeWidth / 2} ${d.y + nodeHeight} `;
25 | }
26 | } else if (linkShape === "curve") {
27 | if (isHorizontal) {
28 | return `M ${s.y} ${s.x + nodeHeight / 2}
29 | L ${s.y - (s.y - d.y - nodeWidth) / 2 + 15} ${s.x + nodeHeight / 2}
30 | Q${s.y - (s.y - d.y - nodeWidth) / 2} ${s.x + nodeHeight / 2}
31 | ${s.y - (s.y - d.y - nodeWidth) / 2} ${s.x +
32 | nodeHeight / 2 -
33 | offsetPosOrNeg(s.x, d.x, 15)}
34 | L ${s.y - (s.y - d.y - nodeWidth) / 2} ${d.x + nodeHeight / 2}
35 | L ${d.y + nodeWidth} ${d.x + nodeHeight / 2}`;
36 | } else {
37 | return `M ${s.x + nodeWidth / 2} ${s.y}
38 | L ${s.x + nodeWidth / 2} ${s.y - (s.y - d.y - nodeHeight) / 2 + 15}
39 | Q${s.x + nodeWidth / 2} ${s.y - (s.y - d.y - nodeHeight) / 2}
40 | ${s.x + nodeWidth / 2 - offsetPosOrNeg(s.x, d.x, 15)} ${s.y -
41 | (s.y - d.y - nodeHeight) / 2}
42 | L ${d.x + nodeWidth / 2} ${s.y - (s.y - d.y - nodeHeight) / 2}
43 | L ${d.x + nodeWidth / 2} ${d.y + nodeHeight} `;
44 | }
45 | } else {
46 | if (isHorizontal) {
47 | return `M ${s.y} ${s.x + nodeHeight / 2}
48 | C ${(s.y + d.y + nodeWidth) / 2} ${s.x + nodeHeight / 2}
49 | ${(s.y + d.y + nodeWidth) / 2} ${d.x + nodeHeight / 2}
50 | ${d.y + nodeWidth} ${d.x + nodeHeight / 2}`;
51 | } else {
52 | return `M ${s.x + nodeWidth / 2} ${s.y}
53 | C ${s.x + nodeWidth / 2} ${(s.y + d.y + nodeHeight) / 2}
54 | ${d.x + nodeWidth / 2} ${(s.y + d.y + nodeHeight) / 2}
55 | ${d.x + nodeWidth / 2} ${d.y + nodeHeight} `;
56 | }
57 | }
58 | };
59 |
60 | const offsetPosOrNeg = (val1: number, val2: number, offset: number) =>
61 | val1 > val2 ? offset : val1 < val2 ? -offset : 0;
62 |
--------------------------------------------------------------------------------
/src/links/link-enter.ts:
--------------------------------------------------------------------------------
1 | import { HierarchyPointNode } from "d3-hierarchy";
2 | import { BaseType, Selection } from "d3-selection";
3 | import { ExtendedHierarchyPointNode, ITreeConfig } from "../typings";
4 | import { getFirstDisplayedAncestor } from "../utils";
5 | import { generateLinkLayout } from "./draw-links";
6 |
7 | export const drawLinkEnter = (
8 | link: Selection, SVGGElement, {}>,
9 | settings: ITreeConfig,
10 | nodes: ExtendedHierarchyPointNode[],
11 | oldNodes: ExtendedHierarchyPointNode[]
12 | ) =>
13 | link
14 | .enter()
15 | .insert("path", "g")
16 | .attr("class", "link")
17 | .attr("d", (d: any) => {
18 | const firstDisplayedParentNode = getFirstDisplayedAncestor(
19 | nodes,
20 | oldNodes,
21 | d.id
22 | );
23 | const o = {
24 | x: firstDisplayedParentNode.x0,
25 | y: firstDisplayedParentNode.y0,
26 | };
27 | return generateLinkLayout(o, o, settings);
28 | })
29 | .attr("fill", "none")
30 | .attr("stroke-width", ({ data }: { data: any }) =>
31 | settings.linkWidth({ data, settings })
32 | )
33 | .attr("stroke", ({ data }: { data: any }) =>
34 | settings.linkColor({ data, settings })
35 | );
36 |
--------------------------------------------------------------------------------
/src/links/link-exit.ts:
--------------------------------------------------------------------------------
1 | import { HierarchyPointNode } from "d3-hierarchy";
2 | import { BaseType, Selection } from "d3-selection";
3 | import { ExtendedHierarchyPointNode, ITreeConfig } from "../typings";
4 | import { getFirstDisplayedAncestor } from "../utils";
5 | import { generateLinkLayout } from "./draw-links";
6 |
7 | export const drawLinkExit = (
8 | link: Selection, SVGGElement, {}>,
9 | settings: ITreeConfig,
10 | nodes: ExtendedHierarchyPointNode[],
11 | oldNodes: ExtendedHierarchyPointNode[]
12 | ) => {
13 | link
14 | .exit()
15 | //@ts-ignore
16 | .transition()
17 | .duration(settings.duration)
18 | .style("opacity", 0)
19 | .attr("d", (d: any) => {
20 | const firstDisplayedParentNode = getFirstDisplayedAncestor(
21 | oldNodes,
22 | nodes,
23 | d.id
24 | );
25 | const o = {
26 | x: firstDisplayedParentNode.x0,
27 | y: firstDisplayedParentNode.y0,
28 | };
29 | return generateLinkLayout(o, o, settings);
30 | })
31 | .remove();
32 | };
33 |
--------------------------------------------------------------------------------
/src/links/link-update.ts:
--------------------------------------------------------------------------------
1 | import { HierarchyPointNode } from "d3-hierarchy";
2 | import { Selection } from "d3-selection";
3 | import { ITreeConfig } from "../typings";
4 | import { generateLinkLayout } from "./draw-links";
5 |
6 | export const drawLinkUpdate = (
7 | linkEnter: Selection, SVGGElement, {}>,
8 | link: Selection, SVGGElement, {}>,
9 | settings: ITreeConfig
10 | ) => {
11 | const linkUpdate = linkEnter.merge(link);
12 |
13 | linkUpdate
14 | //@ts-ignore
15 | .transition()
16 | .duration(settings.duration)
17 | .attr("d", (d: any) => {
18 | return generateLinkLayout(d, d.parent, settings);
19 | })
20 | .attr("fill", "none")
21 | .attr("stroke-width", ({ data }: { data: any }) =>
22 | settings.linkWidth({ data, settings })
23 | )
24 | .attr("stroke", ({ data }: { data: any }) =>
25 | settings.linkColor({ data, settings })
26 | );
27 | };
28 |
--------------------------------------------------------------------------------
/src/nodes/node-enter.ts:
--------------------------------------------------------------------------------
1 | import { BaseType, Selection } from "d3-selection";
2 | import { ExtendedHierarchyPointNode, ITreeConfig } from "../typings";
3 | import { getFirstDisplayedAncestor, setNodeLocation } from "../utils";
4 |
5 | export const drawNodeEnter = (
6 | node: Selection,
7 | settings: ITreeConfig,
8 | nodes: ExtendedHierarchyPointNode[],
9 | oldNodes: ExtendedHierarchyPointNode[]
10 | ) => {
11 | const nodeEnter = node
12 | .enter()
13 | .append("g")
14 | .attr("class", "node")
15 | // @ts-ignore
16 | .attr("id", (d) => d?.id)
17 | .attr("transform", (d: any) => {
18 | const firstDisplayedParentNode = getFirstDisplayedAncestor(
19 | nodes,
20 | oldNodes,
21 | d.id
22 | );
23 | return setNodeLocation(
24 | firstDisplayedParentNode.x0,
25 | firstDisplayedParentNode.y0,
26 | settings
27 | );
28 | });
29 |
30 | nodeEnter
31 | .append("foreignObject")
32 | .attr("width", settings.nodeWidth)
33 | .attr("height", settings.nodeHeight);
34 |
35 | return nodeEnter;
36 | };
37 |
--------------------------------------------------------------------------------
/src/nodes/node-exit.ts:
--------------------------------------------------------------------------------
1 | import { BaseType, Selection } from "d3-selection";
2 | import { ExtendedHierarchyPointNode, ITreeConfig } from "../typings";
3 | import { getFirstDisplayedAncestor, setNodeLocation } from "../utils";
4 |
5 | export const drawNodeExit = (
6 | node: Selection,
7 | settings: ITreeConfig,
8 | nodes: ExtendedHierarchyPointNode[],
9 | oldNodes: ExtendedHierarchyPointNode[]
10 | ) => {
11 | const nodeExit = node
12 | .exit()
13 | //@ts-ignore
14 | .transition()
15 | .duration(settings.duration)
16 | .style("opacity", 0)
17 | .attr("transform", (d: any) => {
18 | const firstDisplayedParentNode = getFirstDisplayedAncestor(
19 | oldNodes,
20 | nodes,
21 | d.id
22 | );
23 | return setNodeLocation(
24 | firstDisplayedParentNode.x0,
25 | firstDisplayedParentNode.y0,
26 | settings
27 | );
28 | })
29 | .remove();
30 |
31 | nodeExit.select("rect").style("fill-opacity", 1e-6);
32 | nodeExit.select("circle").attr("r", 1e-6);
33 | nodeExit.select("text").style("fill-opacity", 1e-6);
34 | };
35 |
--------------------------------------------------------------------------------
/src/nodes/node-update.ts:
--------------------------------------------------------------------------------
1 | import { Selection } from "d3-selection";
2 | import { ExtendedHierarchyPointNode, ITreeConfig } from "../typings";
3 |
4 | export const drawNodeUpdate = (
5 | nodeEnter: Selection<
6 | SVGGElement,
7 | ExtendedHierarchyPointNode,
8 | SVGGElement,
9 | {}
10 | >,
11 | node: Selection,
12 | settings: ITreeConfig
13 | ) => {
14 | const nodeUpdate = nodeEnter.merge(node);
15 | nodeUpdate
16 | //@ts-ignore
17 | .transition()
18 | .duration(settings.duration)
19 | //@ts-ignore
20 | .attr("transform", (d) => {
21 | return settings.isHorizontal
22 | ? "translate(" + d.y + "," + d.x + ")"
23 | : "translate(" + d.x + "," + d.y + ")";
24 | });
25 |
26 | nodeUpdate
27 | .select("foreignObject")
28 | .attr("width", settings.nodeWidth)
29 | .attr("height", settings.nodeHeight)
30 | .style("overflow", "visible")
31 | .on("click", (_, d) => settings.onNodeClick({ ...d, settings }))
32 | .on("mouseenter", (_, d) => settings.onNodeMouseEnter({ ...d, settings }))
33 | .on("mouseleave", (_, d) => settings.onNodeMouseLeave({ ...d, settings }))
34 | .html((d) => settings.renderNode({ ...d, settings }));
35 | };
36 |
--------------------------------------------------------------------------------
/src/prepare-data.ts:
--------------------------------------------------------------------------------
1 | import { HierarchyNode } from "d3-hierarchy";
2 | import d3 from "./d3";
3 | import { ITreeConfig } from "./typings";
4 | import { getAreaSize } from "./utils";
5 |
6 | export const generateNestedData = (
7 | data: any,
8 | treeConfig: ITreeConfig
9 | ): HierarchyNode => {
10 | const { idKey, relationnalField, hasFlatData } = treeConfig;
11 | return hasFlatData
12 | ? d3
13 | .stratify()
14 | .id((d: any) => d[idKey])
15 | .parentId((d: any) => d[relationnalField])(data)
16 | : d3.hierarchy(data, d => d[relationnalField]);
17 | };
18 |
19 | export const generateBasicTreemap = (treeConfig: ITreeConfig) => {
20 | const { areaHeight, areaWidth } = getAreaSize(treeConfig.htmlId);
21 | return treeConfig.mainAxisNodeSpacing === "auto" && treeConfig.isHorizontal
22 | ? d3
23 | .tree()
24 | .size([
25 | areaHeight - treeConfig.nodeHeight,
26 | areaWidth - treeConfig.nodeWidth,
27 | ])
28 | : treeConfig.mainAxisNodeSpacing === "auto" && !treeConfig.isHorizontal
29 | ? d3
30 | .tree()
31 | .size([
32 | areaWidth - treeConfig.nodeWidth,
33 | areaHeight - treeConfig.nodeHeight,
34 | ])
35 | : treeConfig.isHorizontal === true
36 | ? d3
37 | .tree()
38 | .nodeSize([
39 | treeConfig.nodeHeight * treeConfig.secondaryAxisNodeSpacing,
40 | treeConfig.nodeWidth,
41 | ])
42 | : d3
43 | .tree()
44 | .nodeSize([
45 | treeConfig.nodeWidth * treeConfig.secondaryAxisNodeSpacing,
46 | treeConfig.nodeHeight,
47 | ]);
48 | };
49 |
--------------------------------------------------------------------------------
/src/typings.ts:
--------------------------------------------------------------------------------
1 | import { HierarchyPointNode } from "d3-hierarchy";
2 |
3 | type NodeData = {
4 | data: T;
5 | settings: ITreeConfig;
6 | } & ExtendedHierarchyPointNode;
7 |
8 | export interface ITreeConfig {
9 | data: T[];
10 | htmlId: string;
11 | idKey: string;
12 | relationnalField: string;
13 | hasFlatData: boolean;
14 | nodeWidth: number;
15 | nodeHeight: number;
16 | mainAxisNodeSpacing: number | "auto";
17 | linkShape?: "quadraticBeziers" | "curve" | "orthogonal" | "";
18 | renderNode: (node: NodeData) => string | null;
19 | linkColor: (node: NodeData) => string;
20 | linkWidth: (node: NodeData) => number;
21 | onNodeClick: (node: NodeData) => void;
22 | onNodeMouseEnter: (node: NodeData) => void;
23 | onNodeMouseLeave: (node: NodeData) => void;
24 | isHorizontal: boolean;
25 | hasPan: boolean;
26 | hasZoom: boolean;
27 | duration: number;
28 | marginTop: number;
29 | marginBottom: number;
30 | marginLeft: number;
31 | marginRight: number;
32 | secondaryAxisNodeSpacing: number;
33 | }
34 |
35 | export interface ExtendedHierarchyPointNode extends HierarchyPointNode<{}> {
36 | x0?: number;
37 | y0?: number;
38 | }
39 |
40 | // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/16176#issuecomment-348095843
41 | import { select as d3Select } from "d3-selection";
42 | import { transition as d3Transition } from "d3-transition";
43 | d3Select.prototype.transition = d3Transition;
44 |
--------------------------------------------------------------------------------
/src/utils.ts:
--------------------------------------------------------------------------------
1 | import { ExtendedHierarchyPointNode, ITreeConfig } from "./typings";
2 |
3 | export const getAreaSize = (htmlId: string) => {
4 | const SVGContainer = document.querySelector(`#${htmlId}`);
5 | if (SVGContainer === null) {
6 | throw new Error(`Cannot find dom element with id:${htmlId}`);
7 | }
8 | const areaWidth = SVGContainer.clientWidth;
9 | const areaHeight = SVGContainer.clientHeight;
10 | if (areaHeight === 0 || areaWidth === 0) {
11 | throw new Error(
12 | "The tree can't be display because the svg height or width of the container is null"
13 | );
14 | }
15 | return { areaWidth, areaHeight };
16 | };
17 |
18 | type Result = ExtendedHierarchyPointNode & { x0: number; y0: number };
19 |
20 | export const getFirstDisplayedAncestor = (
21 | ghostNodes: ExtendedHierarchyPointNode[],
22 | viewableNodes: ExtendedHierarchyPointNode[],
23 | id: string
24 | ): Result => {
25 | try {
26 | // @ts-ignore
27 | const parentNode: Result = ghostNodes.find((node) => node.id === id);
28 |
29 | // @ts-ignore
30 | const parentNodeId: string = parentNode.ancestors()[1].id;
31 | const isPresentInOldNodes = viewableNodes.some(
32 | (oldNode) => oldNode.id === parentNodeId
33 | );
34 |
35 | if (isPresentInOldNodes) {
36 | return parentNode.ancestors()[1];
37 | } else {
38 | return getFirstDisplayedAncestor(ghostNodes, viewableNodes, parentNodeId);
39 | }
40 | } catch (e) {
41 | // @ts-ignore
42 | return ghostNodes.find((node) => node.id === id);
43 | }
44 | };
45 |
46 | export const setNodeLocation = (
47 | xPosition: number,
48 | yPosition: number,
49 | settings: ITreeConfig
50 | ) => {
51 | if (settings.isHorizontal) {
52 | return "translate(" + yPosition + "," + xPosition + ")";
53 | } else {
54 | return "translate(" + xPosition + "," + yPosition + ")";
55 | }
56 | };
57 |
58 | // RefreshQueue ensures that don't run a refresh while another refresh
59 | // is in transition.
60 | export class RefreshQueue {
61 | // The queue is an array that contains objects. Each object represents an
62 | // refresh action and only they have 2 properties:
63 | // {
64 | // callback: triggers when it's the first of queue and then it
65 | // becomes null to prevent that callback executes more
66 | // than once.
67 | // delayNextCallback: when callback is executed, queue will subtracts
68 | // milliseconds from it. When it becomes 0, the entire
69 | // object is destroyed (shifted) from the array and then
70 | // the next item (if exists) will be executed similary
71 | // to this.
72 | // }
73 | private static queue: Array<{
74 | delayNextCallback: number;
75 | callback: any;
76 | }> = [];
77 |
78 | // Contains setInterval ID
79 | private static runner: number;
80 |
81 | // Milliseconds of each iteration
82 | private static runnerSpeed: number = 100;
83 |
84 | // Developer internal magic number. Time added at end of refresh transition to
85 | // let DOM and d3 rest before another refresh.
86 | // 0 creates console and visual errors because getFirstDisplayedAncestor never
87 | // found the needed id and setNodeLocation receives undefined parameters.
88 | // Between 50 and 100 milliseconds seems enough for 10 nodes (demo example)
89 | private static readonly extraDelayBetweenCallbacks: number = 100;
90 |
91 | // Developer internal for debugging RefreshQueue class. Set true to see
92 | // console "real time" queue of tasks.
93 | // If there is a cleaner method, remove it!
94 | private static showQueueLog: boolean = false;
95 |
96 | // Adds one refresh action to the queue. When safe callback will be
97 | // triggered
98 | public static add(duration: number, callback: () => any) {
99 | this.queue.push({
100 | delayNextCallback: duration + this.extraDelayBetweenCallbacks,
101 | callback: callback,
102 | });
103 | this.log(
104 | this.queue.map((_) => _.delayNextCallback),
105 | "<-- New task !!!"
106 | );
107 | if (!this.runner) {
108 | this.runnerFunction();
109 | //@ts-ignore
110 | this.runner = setInterval(() => this.runnerFunction(), this.runnerSpeed);
111 | }
112 | }
113 |
114 | // Each this.runnerSpeed milliseconds it's executed. It stops when finish.
115 | private static runnerFunction() {
116 | if (this.queue[0]) {
117 | // ************************ Callback section ************************
118 | if (this.queue[0].callback) {
119 | this.log("Executing task, delaying next task...");
120 | try {
121 | this.queue[0].callback();
122 | } catch (e) {
123 | console.error(e);
124 | } finally {
125 | // To prevent trigger callback more than once
126 | this.queue[0].callback = null;
127 | }
128 | }
129 | // ******************** Delay until next callback ********************
130 | this.queue[0].delayNextCallback -= this.runnerSpeed;
131 | this.log(this.queue.map((_) => _.delayNextCallback));
132 | if (this.queue[0].delayNextCallback <= 0) {
133 | this.queue.shift();
134 | }
135 | } else {
136 | this.log("No task found");
137 | clearInterval(this.runner);
138 | this.runner = 0;
139 | }
140 | }
141 |
142 | // Print to console debug data if this.showQueueLog = true
143 | private static log(...msg: any) {
144 | if (this.showQueueLog) console.log(...msg);
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "useDefineForClassFields": true,
5 | "module": "ESNext",
6 | "lib": ["ES2020", "DOM", "DOM.Iterable"],
7 | "skipLibCheck": true,
8 |
9 | /* Bundler mode */
10 | "moduleResolution": "bundler",
11 | "allowImportingTsExtensions": true,
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "noEmit": true,
15 |
16 | /* Linting */
17 | "strict": true,
18 | "noUnusedLocals": true,
19 | "noUnusedParameters": true,
20 | "noFallthroughCasesInSwitch": true,
21 | "sourceMap": true,
22 | },
23 | "include": ["src", "example/example.ts"]
24 | }
25 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import { resolve } from "path";
3 | import dts from "vite-plugin-dts";
4 |
5 | export default defineConfig({
6 | plugins: [dts({ include: ["src"] })],
7 | build: {
8 | lib: {
9 | entry: resolve(__dirname, "src/index.ts"),
10 | formats: ["es"],
11 | },
12 | rollupOptions: {
13 | input: {
14 | app: "./example/index.html",
15 | },
16 | },
17 | copyPublicDir: false,
18 | },
19 | server: {
20 | open: "/example/index.html",
21 | },
22 | });
23 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@babel/parser@^7.23.5":
6 | version "7.23.5"
7 | resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.5.tgz#37dee97c4752af148e1d38c34b856b2507660563"
8 | integrity sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==
9 |
10 | "@esbuild/android-arm64@0.19.8":
11 | version "0.19.8"
12 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.8.tgz#fb7130103835b6d43ea499c3f30cfb2b2ed58456"
13 | integrity sha512-B8JbS61bEunhfx8kasogFENgQfr/dIp+ggYXwTqdbMAgGDhRa3AaPpQMuQU0rNxDLECj6FhDzk1cF9WHMVwrtA==
14 |
15 | "@esbuild/android-arm@0.19.8":
16 | version "0.19.8"
17 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.8.tgz#b46e4d9e984e6d6db6c4224d72c86b7757e35bcb"
18 | integrity sha512-31E2lxlGM1KEfivQl8Yf5aYU/mflz9g06H6S15ITUFQueMFtFjESRMoDSkvMo8thYvLBax+VKTPlpnx+sPicOA==
19 |
20 | "@esbuild/android-x64@0.19.8":
21 | version "0.19.8"
22 | resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.8.tgz#a13db9441b5a4f4e4fec4a6f8ffacfea07888db7"
23 | integrity sha512-rdqqYfRIn4jWOp+lzQttYMa2Xar3OK9Yt2fhOhzFXqg0rVWEfSclJvZq5fZslnz6ypHvVf3CT7qyf0A5pM682A==
24 |
25 | "@esbuild/darwin-arm64@0.19.8":
26 | version "0.19.8"
27 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.8.tgz#49f5718d36541f40dd62bfdf84da9c65168a0fc2"
28 | integrity sha512-RQw9DemMbIq35Bprbboyf8SmOr4UXsRVxJ97LgB55VKKeJOOdvsIPy0nFyF2l8U+h4PtBx/1kRf0BelOYCiQcw==
29 |
30 | "@esbuild/darwin-x64@0.19.8":
31 | version "0.19.8"
32 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.8.tgz#75c5c88371eea4bfc1f9ecfd0e75104c74a481ac"
33 | integrity sha512-3sur80OT9YdeZwIVgERAysAbwncom7b4bCI2XKLjMfPymTud7e/oY4y+ci1XVp5TfQp/bppn7xLw1n/oSQY3/Q==
34 |
35 | "@esbuild/freebsd-arm64@0.19.8":
36 | version "0.19.8"
37 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.8.tgz#9d7259fea4fd2b5f7437b52b542816e89d7c8575"
38 | integrity sha512-WAnPJSDattvS/XtPCTj1tPoTxERjcTpH6HsMr6ujTT+X6rylVe8ggxk8pVxzf5U1wh5sPODpawNicF5ta/9Tmw==
39 |
40 | "@esbuild/freebsd-x64@0.19.8":
41 | version "0.19.8"
42 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.8.tgz#abac03e1c4c7c75ee8add6d76ec592f46dbb39e3"
43 | integrity sha512-ICvZyOplIjmmhjd6mxi+zxSdpPTKFfyPPQMQTK/w+8eNK6WV01AjIztJALDtwNNfFhfZLux0tZLC+U9nSyA5Zg==
44 |
45 | "@esbuild/linux-arm64@0.19.8":
46 | version "0.19.8"
47 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.8.tgz#c577932cf4feeaa43cb9cec27b89cbe0df7d9098"
48 | integrity sha512-z1zMZivxDLHWnyGOctT9JP70h0beY54xDDDJt4VpTX+iwA77IFsE1vCXWmprajJGa+ZYSqkSbRQ4eyLCpCmiCQ==
49 |
50 | "@esbuild/linux-arm@0.19.8":
51 | version "0.19.8"
52 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.8.tgz#d6014d8b98b5cbc96b95dad3d14d75bb364fdc0f"
53 | integrity sha512-H4vmI5PYqSvosPaTJuEppU9oz1dq2A7Mr2vyg5TF9Ga+3+MGgBdGzcyBP7qK9MrwFQZlvNyJrvz6GuCaj3OukQ==
54 |
55 | "@esbuild/linux-ia32@0.19.8":
56 | version "0.19.8"
57 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.8.tgz#2379a0554307d19ac4a6cdc15b08f0ea28e7a40d"
58 | integrity sha512-1a8suQiFJmZz1khm/rDglOc8lavtzEMRo0v6WhPgxkrjcU0LkHj+TwBrALwoz/OtMExvsqbbMI0ChyelKabSvQ==
59 |
60 | "@esbuild/linux-loong64@0.19.8":
61 | version "0.19.8"
62 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.8.tgz#e2a5bbffe15748b49356a6cd7b2d5bf60c5a7123"
63 | integrity sha512-fHZWS2JJxnXt1uYJsDv9+b60WCc2RlvVAy1F76qOLtXRO+H4mjt3Tr6MJ5l7Q78X8KgCFudnTuiQRBhULUyBKQ==
64 |
65 | "@esbuild/linux-mips64el@0.19.8":
66 | version "0.19.8"
67 | resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.8.tgz#1359331e6f6214f26f4b08db9b9df661c57cfa24"
68 | integrity sha512-Wy/z0EL5qZYLX66dVnEg9riiwls5IYnziwuju2oUiuxVc+/edvqXa04qNtbrs0Ukatg5HEzqT94Zs7J207dN5Q==
69 |
70 | "@esbuild/linux-ppc64@0.19.8":
71 | version "0.19.8"
72 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.8.tgz#9ba436addc1646dc89dae48c62d3e951ffe70951"
73 | integrity sha512-ETaW6245wK23YIEufhMQ3HSeHO7NgsLx8gygBVldRHKhOlD1oNeNy/P67mIh1zPn2Hr2HLieQrt6tWrVwuqrxg==
74 |
75 | "@esbuild/linux-riscv64@0.19.8":
76 | version "0.19.8"
77 | resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.8.tgz#fbcf0c3a0b20f40b5fc31c3b7695f0769f9de66b"
78 | integrity sha512-T2DRQk55SgoleTP+DtPlMrxi/5r9AeFgkhkZ/B0ap99zmxtxdOixOMI570VjdRCs9pE4Wdkz7JYrsPvsl7eESg==
79 |
80 | "@esbuild/linux-s390x@0.19.8":
81 | version "0.19.8"
82 | resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.8.tgz#989e8a05f7792d139d5564ffa7ff898ac6f20a4a"
83 | integrity sha512-NPxbdmmo3Bk7mbNeHmcCd7R7fptJaczPYBaELk6NcXxy7HLNyWwCyDJ/Xx+/YcNH7Im5dHdx9gZ5xIwyliQCbg==
84 |
85 | "@esbuild/linux-x64@0.19.8":
86 | version "0.19.8"
87 | resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.8.tgz#b187295393a59323397fe5ff51e769ec4e72212b"
88 | integrity sha512-lytMAVOM3b1gPypL2TRmZ5rnXl7+6IIk8uB3eLsV1JwcizuolblXRrc5ShPrO9ls/b+RTp+E6gbsuLWHWi2zGg==
89 |
90 | "@esbuild/netbsd-x64@0.19.8":
91 | version "0.19.8"
92 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.8.tgz#c1ec0e24ea82313cb1c7bae176bd5acd5bde7137"
93 | integrity sha512-hvWVo2VsXz/8NVt1UhLzxwAfo5sioj92uo0bCfLibB0xlOmimU/DeAEsQILlBQvkhrGjamP0/el5HU76HAitGw==
94 |
95 | "@esbuild/openbsd-x64@0.19.8":
96 | version "0.19.8"
97 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.8.tgz#0c5b696ac66c6d70cf9ee17073a581a28af9e18d"
98 | integrity sha512-/7Y7u77rdvmGTxR83PgaSvSBJCC2L3Kb1M/+dmSIvRvQPXXCuC97QAwMugBNG0yGcbEGfFBH7ojPzAOxfGNkwQ==
99 |
100 | "@esbuild/sunos-x64@0.19.8":
101 | version "0.19.8"
102 | resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.8.tgz#2a697e1f77926ff09fcc457d8f29916d6cd48fb1"
103 | integrity sha512-9Lc4s7Oi98GqFA4HzA/W2JHIYfnXbUYgekUP/Sm4BG9sfLjyv6GKKHKKVs83SMicBF2JwAX6A1PuOLMqpD001w==
104 |
105 | "@esbuild/win32-arm64@0.19.8":
106 | version "0.19.8"
107 | resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.8.tgz#ec029e62a2fca8c071842ecb1bc5c2dd20b066f1"
108 | integrity sha512-rq6WzBGjSzihI9deW3fC2Gqiak68+b7qo5/3kmB6Gvbh/NYPA0sJhrnp7wgV4bNwjqM+R2AApXGxMO7ZoGhIJg==
109 |
110 | "@esbuild/win32-ia32@0.19.8":
111 | version "0.19.8"
112 | resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.8.tgz#cbb9a3146bde64dc15543e48afe418c7a3214851"
113 | integrity sha512-AIAbverbg5jMvJznYiGhrd3sumfwWs8572mIJL5NQjJa06P8KfCPWZQ0NwZbPQnbQi9OWSZhFVSUWjjIrn4hSw==
114 |
115 | "@esbuild/win32-x64@0.19.8":
116 | version "0.19.8"
117 | resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.8.tgz#c8285183dbdb17008578dbacb6e22748709b4822"
118 | integrity sha512-bfZ0cQ1uZs2PqpulNL5j/3w+GDhP36k1K5c38QdQg+Swy51jFZWWeIkteNsufkQxp986wnqRRsb/bHbY1WQ7TA==
119 |
120 | "@microsoft/api-extractor-model@7.28.2":
121 | version "7.28.2"
122 | resolved "https://registry.yarnpkg.com/@microsoft/api-extractor-model/-/api-extractor-model-7.28.2.tgz#91c66dd820ccc70e0c163e06b392d8363f1b9269"
123 | integrity sha512-vkojrM2fo3q4n4oPh4uUZdjJ2DxQ2+RnDQL/xhTWSRUNPF6P4QyrvY357HBxbnltKcYu+nNNolVqc6TIGQ73Ig==
124 | dependencies:
125 | "@microsoft/tsdoc" "0.14.2"
126 | "@microsoft/tsdoc-config" "~0.16.1"
127 | "@rushstack/node-core-library" "3.61.0"
128 |
129 | "@microsoft/api-extractor@^7.38.0":
130 | version "7.38.4"
131 | resolved "https://registry.yarnpkg.com/@microsoft/api-extractor/-/api-extractor-7.38.4.tgz#bb7847cbec6af4f762762a0897c312d434e12ae5"
132 | integrity sha512-0SW3Of6os4bAYlHdiD1hJx/ygXr7vRZi92E1pREufNERH87aZ0B9Vhku/4Mj2Oxp58gyV5d18t7uZold6HCSEw==
133 | dependencies:
134 | "@microsoft/api-extractor-model" "7.28.2"
135 | "@microsoft/tsdoc" "0.14.2"
136 | "@microsoft/tsdoc-config" "~0.16.1"
137 | "@rushstack/node-core-library" "3.61.0"
138 | "@rushstack/rig-package" "0.5.1"
139 | "@rushstack/ts-command-line" "4.17.1"
140 | colors "~1.2.1"
141 | lodash "~4.17.15"
142 | resolve "~1.22.1"
143 | semver "~7.5.4"
144 | source-map "~0.6.1"
145 | typescript "~5.0.4"
146 |
147 | "@microsoft/tsdoc-config@~0.16.1":
148 | version "0.16.2"
149 | resolved "https://registry.yarnpkg.com/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz#b786bb4ead00d54f53839a458ce626c8548d3adf"
150 | integrity sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==
151 | dependencies:
152 | "@microsoft/tsdoc" "0.14.2"
153 | ajv "~6.12.6"
154 | jju "~1.4.0"
155 | resolve "~1.19.0"
156 |
157 | "@microsoft/tsdoc@0.14.2":
158 | version "0.14.2"
159 | resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz#c3ec604a0b54b9a9b87e9735dfc59e1a5da6a5fb"
160 | integrity sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==
161 |
162 | "@rollup/pluginutils@^5.0.5":
163 | version "5.1.0"
164 | resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz#7e53eddc8c7f483a4ad0b94afb1f7f5fd3c771e0"
165 | integrity sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==
166 | dependencies:
167 | "@types/estree" "^1.0.0"
168 | estree-walker "^2.0.2"
169 | picomatch "^2.3.1"
170 |
171 | "@rollup/rollup-android-arm-eabi@4.6.1":
172 | version "4.6.1"
173 | resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.6.1.tgz#0ea289f68ff248b50fea5716ca9f65f7d4dba3ae"
174 | integrity sha512-0WQ0ouLejaUCRsL93GD4uft3rOmB8qoQMU05Kb8CmMtMBe7XUDLAltxVZI1q6byNqEtU7N1ZX1Vw5lIpgulLQA==
175 |
176 | "@rollup/rollup-android-arm64@4.6.1":
177 | version "4.6.1"
178 | resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.6.1.tgz#27c8c67fc5de574874085a1b480ac65b3e18378e"
179 | integrity sha512-1TKm25Rn20vr5aTGGZqo6E4mzPicCUD79k17EgTLAsXc1zysyi4xXKACfUbwyANEPAEIxkzwue6JZ+stYzWUTA==
180 |
181 | "@rollup/rollup-darwin-arm64@4.6.1":
182 | version "4.6.1"
183 | resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.6.1.tgz#c5735c042980c85495411af7183dd20294763bd8"
184 | integrity sha512-cEXJQY/ZqMACb+nxzDeX9IPLAg7S94xouJJCNVE5BJM8JUEP4HeTF+ti3cmxWeSJo+5D+o8Tc0UAWUkfENdeyw==
185 |
186 | "@rollup/rollup-darwin-x64@4.6.1":
187 | version "4.6.1"
188 | resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.6.1.tgz#af844bd54abb73ca3c9cf89a31eec17861d1375d"
189 | integrity sha512-LoSU9Xu56isrkV2jLldcKspJ7sSXmZWkAxg7sW/RfF7GS4F5/v4EiqKSMCFbZtDu2Nc1gxxFdQdKwkKS4rwxNg==
190 |
191 | "@rollup/rollup-linux-arm-gnueabihf@4.6.1":
192 | version "4.6.1"
193 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.6.1.tgz#5e972f63c441eaf859551039b3f18db9b035977d"
194 | integrity sha512-EfI3hzYAy5vFNDqpXsNxXcgRDcFHUWSx5nnRSCKwXuQlI5J9dD84g2Usw81n3FLBNsGCegKGwwTVsSKK9cooSQ==
195 |
196 | "@rollup/rollup-linux-arm64-gnu@4.6.1":
197 | version "4.6.1"
198 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.6.1.tgz#f4cfbc71e3b6fdb395b28b1472414e181515c72d"
199 | integrity sha512-9lhc4UZstsegbNLhH0Zu6TqvDfmhGzuCWtcTFXY10VjLLUe4Mr0Ye2L3rrtHaDd/J5+tFMEuo5LTCSCMXWfUKw==
200 |
201 | "@rollup/rollup-linux-arm64-musl@4.6.1":
202 | version "4.6.1"
203 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.6.1.tgz#6a94c691830dc29bf708de7c640f494996130893"
204 | integrity sha512-FfoOK1yP5ksX3wwZ4Zk1NgyGHZyuRhf99j64I5oEmirV8EFT7+OhUZEnP+x17lcP/QHJNWGsoJwrz4PJ9fBEXw==
205 |
206 | "@rollup/rollup-linux-x64-gnu@4.6.1":
207 | version "4.6.1"
208 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.6.1.tgz#f07bae3f7dc532d9ea5ab36c9071db329f9a1efb"
209 | integrity sha512-DNGZvZDO5YF7jN5fX8ZqmGLjZEXIJRdJEdTFMhiyXqyXubBa0WVLDWSNlQ5JR2PNgDbEV1VQowhVRUh+74D+RA==
210 |
211 | "@rollup/rollup-linux-x64-musl@4.6.1":
212 | version "4.6.1"
213 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.6.1.tgz#357a34fdbf410af88ce48bd802bea6462bb9a8bc"
214 | integrity sha512-RkJVNVRM+piYy87HrKmhbexCHg3A6Z6MU0W9GHnJwBQNBeyhCJG9KDce4SAMdicQnpURggSvtbGo9xAWOfSvIQ==
215 |
216 | "@rollup/rollup-win32-arm64-msvc@4.6.1":
217 | version "4.6.1"
218 | resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.6.1.tgz#b6e97fd38281667e35297033393cd1101f4a31be"
219 | integrity sha512-v2FVT6xfnnmTe3W9bJXl6r5KwJglMK/iRlkKiIFfO6ysKs0rDgz7Cwwf3tjldxQUrHL9INT/1r4VA0n9L/F1vQ==
220 |
221 | "@rollup/rollup-win32-ia32-msvc@4.6.1":
222 | version "4.6.1"
223 | resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.6.1.tgz#a95db026c640c8128bfd38546d85342f2329beaf"
224 | integrity sha512-YEeOjxRyEjqcWphH9dyLbzgkF8wZSKAKUkldRY6dgNR5oKs2LZazqGB41cWJ4Iqqcy9/zqYgmzBkRoVz3Q9MLw==
225 |
226 | "@rollup/rollup-win32-x64-msvc@4.6.1":
227 | version "4.6.1"
228 | resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.6.1.tgz#45785b5caf83200a34a9867ba50d69560880c120"
229 | integrity sha512-0zfTlFAIhgz8V2G8STq8toAjsYYA6eci1hnXuyOTUFnymrtJwnS6uGKiv3v5UrPZkBlamLvrLV2iiaeqCKzb0A==
230 |
231 | "@rushstack/node-core-library@3.61.0":
232 | version "3.61.0"
233 | resolved "https://registry.yarnpkg.com/@rushstack/node-core-library/-/node-core-library-3.61.0.tgz#7441a0d2ae5268b758a7a49588a78cd55af57e66"
234 | integrity sha512-tdOjdErme+/YOu4gPed3sFS72GhtWCgNV9oDsHDnoLY5oDfwjKUc9Z+JOZZ37uAxcm/OCahDHfuu2ugqrfWAVQ==
235 | dependencies:
236 | colors "~1.2.1"
237 | fs-extra "~7.0.1"
238 | import-lazy "~4.0.0"
239 | jju "~1.4.0"
240 | resolve "~1.22.1"
241 | semver "~7.5.4"
242 | z-schema "~5.0.2"
243 |
244 | "@rushstack/rig-package@0.5.1":
245 | version "0.5.1"
246 | resolved "https://registry.yarnpkg.com/@rushstack/rig-package/-/rig-package-0.5.1.tgz#6c9c283cc96b5bb1eae9875946d974ac5429bb21"
247 | integrity sha512-pXRYSe29TjRw7rqxD4WS3HN/sRSbfr+tJs4a9uuaSIBAITbUggygdhuG0VrO0EO+QqH91GhYMN4S6KRtOEmGVA==
248 | dependencies:
249 | resolve "~1.22.1"
250 | strip-json-comments "~3.1.1"
251 |
252 | "@rushstack/ts-command-line@4.17.1":
253 | version "4.17.1"
254 | resolved "https://registry.yarnpkg.com/@rushstack/ts-command-line/-/ts-command-line-4.17.1.tgz#c78db928ce5b93f2e98fd9e14c24f3f3876e57f1"
255 | integrity sha512-2jweO1O57BYP5qdBGl6apJLB+aRIn5ccIRTPDyULh0KMwVzFqWtw6IZWt1qtUoZD/pD2RNkIOosH6Cq45rIYeg==
256 | dependencies:
257 | "@types/argparse" "1.0.38"
258 | argparse "~1.0.9"
259 | colors "~1.2.1"
260 | string-argv "~0.3.1"
261 |
262 | "@types/argparse@1.0.38":
263 | version "1.0.38"
264 | resolved "https://registry.yarnpkg.com/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9"
265 | integrity sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==
266 |
267 | "@types/d3-color@*":
268 | version "3.1.2"
269 | resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.2.tgz#7939eed011a908287cd1bcfd11580c17b2ac7f8a"
270 | integrity sha512-At+Ski7dL8Bs58E8g8vPcFJc8tGcaC12Z4m07+p41+DRqnZQcAlp3NfYjLrhNYv+zEyQitU1CUxXNjqUyf+c0g==
271 |
272 | "@types/d3-hierarchy@^3.1.6":
273 | version "3.1.6"
274 | resolved "https://registry.yarnpkg.com/@types/d3-hierarchy/-/d3-hierarchy-3.1.6.tgz#8d3638df273ec90da34b3ac89d8784c59708cb0d"
275 | integrity sha512-qlmD/8aMk5xGorUvTUWHCiumvgaUXYldYjNVOWtYoTYY/L+WwIEAmJxUmTgr9LoGNG0PPAOmqMDJVDPc7DOpPw==
276 |
277 | "@types/d3-interpolate@*":
278 | version "3.0.3"
279 | resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.3.tgz#e10c06c4bf11bd770ed56184a0d76cd516ff4ded"
280 | integrity sha512-6OZ2EIB4lLj+8cUY7I/Cgn9Q+hLdA4DjJHYOQDiHL0SzqS1K9DL5xIOVBSIHgF+tiuO9MU1D36qvdIvRDRPh+Q==
281 | dependencies:
282 | "@types/d3-color" "*"
283 |
284 | "@types/d3-selection@*":
285 | version "3.0.8"
286 | resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-3.0.8.tgz#9423511db3ed00a55aad4217ac8d546db5d8e5f5"
287 | integrity sha512-pxCZUfQyedq/DIlPXIR5wE1mIH37omOdx1yxRudL3KZ4AC+156jMjOv1z5RVlGq62f8WX2kyO0hTVgEx627QFg==
288 |
289 | "@types/d3-selection@^3.0.10":
290 | version "3.0.10"
291 | resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-3.0.10.tgz#98cdcf986d0986de6912b5892e7c015a95ca27fe"
292 | integrity sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==
293 |
294 | "@types/d3-transition@^3.0.8":
295 | version "3.0.8"
296 | resolved "https://registry.yarnpkg.com/@types/d3-transition/-/d3-transition-3.0.8.tgz#677707f5eed5b24c66a1918cde05963021351a8f"
297 | integrity sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ==
298 | dependencies:
299 | "@types/d3-selection" "*"
300 |
301 | "@types/d3-zoom@^3.0.8":
302 | version "3.0.8"
303 | resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-3.0.8.tgz#dccb32d1c56b1e1c6e0f1180d994896f038bc40b"
304 | integrity sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==
305 | dependencies:
306 | "@types/d3-interpolate" "*"
307 | "@types/d3-selection" "*"
308 |
309 | "@types/estree@^1.0.0":
310 | version "1.0.5"
311 | resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
312 | integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
313 |
314 | "@types/node@^20.10.3":
315 | version "20.10.3"
316 | resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.3.tgz#4900adcc7fc189d5af5bb41da8f543cea6962030"
317 | integrity sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==
318 | dependencies:
319 | undici-types "~5.26.4"
320 |
321 | "@volar/language-core@1.11.1", "@volar/language-core@~1.11.1":
322 | version "1.11.1"
323 | resolved "https://registry.yarnpkg.com/@volar/language-core/-/language-core-1.11.1.tgz#ecdf12ea8dc35fb8549e517991abcbf449a5ad4f"
324 | integrity sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==
325 | dependencies:
326 | "@volar/source-map" "1.11.1"
327 |
328 | "@volar/source-map@1.11.1", "@volar/source-map@~1.11.1":
329 | version "1.11.1"
330 | resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-1.11.1.tgz#535b0328d9e2b7a91dff846cab4058e191f4452f"
331 | integrity sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==
332 | dependencies:
333 | muggle-string "^0.3.1"
334 |
335 | "@volar/typescript@~1.11.1":
336 | version "1.11.1"
337 | resolved "https://registry.yarnpkg.com/@volar/typescript/-/typescript-1.11.1.tgz#ba86c6f326d88e249c7f5cfe4b765be3946fd627"
338 | integrity sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==
339 | dependencies:
340 | "@volar/language-core" "1.11.1"
341 | path-browserify "^1.0.1"
342 |
343 | "@vue/compiler-core@3.3.10":
344 | version "3.3.10"
345 | resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.3.10.tgz#9ca4123a1458df43db641aaa8b7d1e636aa22545"
346 | integrity sha512-doe0hODR1+i1menPkRzJ5MNR6G+9uiZHIknK3Zn5OcIztu6GGw7u0XUzf3AgB8h/dfsZC9eouzoLo3c3+N/cVA==
347 | dependencies:
348 | "@babel/parser" "^7.23.5"
349 | "@vue/shared" "3.3.10"
350 | estree-walker "^2.0.2"
351 | source-map-js "^1.0.2"
352 |
353 | "@vue/compiler-dom@^3.3.0":
354 | version "3.3.10"
355 | resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.3.10.tgz#183811252be6aff4ac923f783124bb1590301907"
356 | integrity sha512-NCrqF5fm10GXZIK0GrEAauBqdy+F2LZRt3yNHzrYjpYBuRssQbuPLtSnSNjyR9luHKkWSH8we5LMB3g+4z2HvA==
357 | dependencies:
358 | "@vue/compiler-core" "3.3.10"
359 | "@vue/shared" "3.3.10"
360 |
361 | "@vue/language-core@1.8.25", "@vue/language-core@^1.8.20":
362 | version "1.8.25"
363 | resolved "https://registry.yarnpkg.com/@vue/language-core/-/language-core-1.8.25.tgz#b44b4e3c244ba9b1b79cccf9eb7b046535a4676f"
364 | integrity sha512-NJk/5DnAZlpvXX8BdWmHI45bWGLViUaS3R/RMrmFSvFMSbJKuEODpM4kR0F0Ofv5SFzCWuNiMhxameWpVdQsnA==
365 | dependencies:
366 | "@volar/language-core" "~1.11.1"
367 | "@volar/source-map" "~1.11.1"
368 | "@vue/compiler-dom" "^3.3.0"
369 | "@vue/shared" "^3.3.0"
370 | computeds "^0.0.1"
371 | minimatch "^9.0.3"
372 | muggle-string "^0.3.1"
373 | path-browserify "^1.0.1"
374 | vue-template-compiler "^2.7.14"
375 |
376 | "@vue/shared@3.3.10", "@vue/shared@^3.3.0":
377 | version "3.3.10"
378 | resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.3.10.tgz#1583a8d85a957d8b819078c465d2a11db7914b2f"
379 | integrity sha512-2y3Y2J1a3RhFa0WisHvACJR2ncvWiVHcP8t0Inxo+NKz+8RKO4ZV8eZgCxRgQoA6ITfV12L4E6POOL9HOU5nqw==
380 |
381 | ajv@~6.12.6:
382 | version "6.12.6"
383 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
384 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
385 | dependencies:
386 | fast-deep-equal "^3.1.1"
387 | fast-json-stable-stringify "^2.0.0"
388 | json-schema-traverse "^0.4.1"
389 | uri-js "^4.2.2"
390 |
391 | argparse@~1.0.9:
392 | version "1.0.10"
393 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
394 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
395 | dependencies:
396 | sprintf-js "~1.0.2"
397 |
398 | balanced-match@^1.0.0:
399 | version "1.0.2"
400 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
401 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
402 |
403 | brace-expansion@^2.0.1:
404 | version "2.0.1"
405 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
406 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
407 | dependencies:
408 | balanced-match "^1.0.0"
409 |
410 | colors@~1.2.1:
411 | version "1.2.5"
412 | resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.5.tgz#89c7ad9a374bc030df8013241f68136ed8835afc"
413 | integrity sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==
414 |
415 | commander@^10.0.0:
416 | version "10.0.1"
417 | resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06"
418 | integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==
419 |
420 | computeds@^0.0.1:
421 | version "0.0.1"
422 | resolved "https://registry.yarnpkg.com/computeds/-/computeds-0.0.1.tgz#215b08a4ba3e08a11ff6eee5d6d8d7166a97ce2e"
423 | integrity sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==
424 |
425 | "d3-color@1 - 3":
426 | version "3.1.0"
427 | resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2"
428 | integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==
429 |
430 | "d3-dispatch@1 - 3":
431 | version "3.0.1"
432 | resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz#5fc75284e9c2375c36c839411a0cf550cbfc4d5e"
433 | integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==
434 |
435 | "d3-drag@2 - 3":
436 | version "3.0.0"
437 | resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-3.0.0.tgz#994aae9cd23c719f53b5e10e3a0a6108c69607ba"
438 | integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==
439 | dependencies:
440 | d3-dispatch "1 - 3"
441 | d3-selection "3"
442 |
443 | "d3-ease@1 - 3":
444 | version "3.0.1"
445 | resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4"
446 | integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==
447 |
448 | d3-hierarchy@^3.1.2:
449 | version "3.1.2"
450 | resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz#b01cd42c1eed3d46db77a5966cf726f8c09160c6"
451 | integrity sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==
452 |
453 | "d3-interpolate@1 - 3":
454 | version "3.0.1"
455 | resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d"
456 | integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==
457 | dependencies:
458 | d3-color "1 - 3"
459 |
460 | "d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0:
461 | version "3.0.0"
462 | resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-3.0.0.tgz#c25338207efa72cc5b9bd1458a1a41901f1e1b31"
463 | integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==
464 |
465 | "d3-timer@1 - 3":
466 | version "3.0.1"
467 | resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0"
468 | integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==
469 |
470 | "d3-transition@2 - 3", d3-transition@^3.0.1:
471 | version "3.0.1"
472 | resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-3.0.1.tgz#6869fdde1448868077fdd5989200cb61b2a1645f"
473 | integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==
474 | dependencies:
475 | d3-color "1 - 3"
476 | d3-dispatch "1 - 3"
477 | d3-ease "1 - 3"
478 | d3-interpolate "1 - 3"
479 | d3-timer "1 - 3"
480 |
481 | d3-zoom@^3.0.0:
482 | version "3.0.0"
483 | resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-3.0.0.tgz#d13f4165c73217ffeaa54295cd6969b3e7aee8f3"
484 | integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==
485 | dependencies:
486 | d3-dispatch "1 - 3"
487 | d3-drag "2 - 3"
488 | d3-interpolate "1 - 3"
489 | d3-selection "2 - 3"
490 | d3-transition "2 - 3"
491 |
492 | de-indent@^1.0.2:
493 | version "1.0.2"
494 | resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
495 | integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==
496 |
497 | debug@^4.3.4:
498 | version "4.3.4"
499 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
500 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
501 | dependencies:
502 | ms "2.1.2"
503 |
504 | esbuild@^0.19.3:
505 | version "0.19.8"
506 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.8.tgz#ad05b72281d84483fa6b5345bd246c27a207b8f1"
507 | integrity sha512-l7iffQpT2OrZfH2rXIp7/FkmaeZM0vxbxN9KfiCwGYuZqzMg/JdvX26R31Zxn/Pxvsrg3Y9N6XTcnknqDyyv4w==
508 | optionalDependencies:
509 | "@esbuild/android-arm" "0.19.8"
510 | "@esbuild/android-arm64" "0.19.8"
511 | "@esbuild/android-x64" "0.19.8"
512 | "@esbuild/darwin-arm64" "0.19.8"
513 | "@esbuild/darwin-x64" "0.19.8"
514 | "@esbuild/freebsd-arm64" "0.19.8"
515 | "@esbuild/freebsd-x64" "0.19.8"
516 | "@esbuild/linux-arm" "0.19.8"
517 | "@esbuild/linux-arm64" "0.19.8"
518 | "@esbuild/linux-ia32" "0.19.8"
519 | "@esbuild/linux-loong64" "0.19.8"
520 | "@esbuild/linux-mips64el" "0.19.8"
521 | "@esbuild/linux-ppc64" "0.19.8"
522 | "@esbuild/linux-riscv64" "0.19.8"
523 | "@esbuild/linux-s390x" "0.19.8"
524 | "@esbuild/linux-x64" "0.19.8"
525 | "@esbuild/netbsd-x64" "0.19.8"
526 | "@esbuild/openbsd-x64" "0.19.8"
527 | "@esbuild/sunos-x64" "0.19.8"
528 | "@esbuild/win32-arm64" "0.19.8"
529 | "@esbuild/win32-ia32" "0.19.8"
530 | "@esbuild/win32-x64" "0.19.8"
531 |
532 | estree-walker@^2.0.2:
533 | version "2.0.2"
534 | resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
535 | integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
536 |
537 | fast-deep-equal@^3.1.1:
538 | version "3.1.3"
539 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
540 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
541 |
542 | fast-json-stable-stringify@^2.0.0:
543 | version "2.1.0"
544 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
545 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
546 |
547 | fs-extra@~7.0.1:
548 | version "7.0.1"
549 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
550 | integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==
551 | dependencies:
552 | graceful-fs "^4.1.2"
553 | jsonfile "^4.0.0"
554 | universalify "^0.1.0"
555 |
556 | fsevents@~2.3.2, fsevents@~2.3.3:
557 | version "2.3.3"
558 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
559 | integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
560 |
561 | function-bind@^1.1.2:
562 | version "1.1.2"
563 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
564 | integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
565 |
566 | graceful-fs@^4.1.2, graceful-fs@^4.1.6:
567 | version "4.2.11"
568 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
569 | integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
570 |
571 | hasown@^2.0.0:
572 | version "2.0.0"
573 | resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c"
574 | integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==
575 | dependencies:
576 | function-bind "^1.1.2"
577 |
578 | he@^1.2.0:
579 | version "1.2.0"
580 | resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
581 | integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
582 |
583 | import-lazy@~4.0.0:
584 | version "4.0.0"
585 | resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153"
586 | integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==
587 |
588 | is-core-module@^2.1.0, is-core-module@^2.13.0:
589 | version "2.13.1"
590 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384"
591 | integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==
592 | dependencies:
593 | hasown "^2.0.0"
594 |
595 | jju@~1.4.0:
596 | version "1.4.0"
597 | resolved "https://registry.yarnpkg.com/jju/-/jju-1.4.0.tgz#a3abe2718af241a2b2904f84a625970f389ae32a"
598 | integrity sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==
599 |
600 | json-schema-traverse@^0.4.1:
601 | version "0.4.1"
602 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
603 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
604 |
605 | jsonfile@^4.0.0:
606 | version "4.0.0"
607 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
608 | integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==
609 | optionalDependencies:
610 | graceful-fs "^4.1.6"
611 |
612 | kolorist@^1.8.0:
613 | version "1.8.0"
614 | resolved "https://registry.yarnpkg.com/kolorist/-/kolorist-1.8.0.tgz#edddbbbc7894bc13302cdf740af6374d4a04743c"
615 | integrity sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==
616 |
617 | lodash.get@^4.4.2:
618 | version "4.4.2"
619 | resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
620 | integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==
621 |
622 | lodash.isequal@^4.5.0:
623 | version "4.5.0"
624 | resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
625 | integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==
626 |
627 | lodash@~4.17.15:
628 | version "4.17.21"
629 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
630 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
631 |
632 | lru-cache@^6.0.0:
633 | version "6.0.0"
634 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
635 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
636 | dependencies:
637 | yallist "^4.0.0"
638 |
639 | minimatch@^9.0.3:
640 | version "9.0.3"
641 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825"
642 | integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==
643 | dependencies:
644 | brace-expansion "^2.0.1"
645 |
646 | ms@2.1.2:
647 | version "2.1.2"
648 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
649 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
650 |
651 | muggle-string@^0.3.1:
652 | version "0.3.1"
653 | resolved "https://registry.yarnpkg.com/muggle-string/-/muggle-string-0.3.1.tgz#e524312eb1728c63dd0b2ac49e3282e6ed85963a"
654 | integrity sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==
655 |
656 | nanoid@^3.3.7:
657 | version "3.3.7"
658 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
659 | integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
660 |
661 | path-browserify@^1.0.1:
662 | version "1.0.1"
663 | resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
664 | integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==
665 |
666 | path-parse@^1.0.6, path-parse@^1.0.7:
667 | version "1.0.7"
668 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
669 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
670 |
671 | picocolors@^1.0.0:
672 | version "1.0.0"
673 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
674 | integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
675 |
676 | picomatch@^2.3.1:
677 | version "2.3.1"
678 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
679 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
680 |
681 | postcss@^8.4.32:
682 | version "8.4.32"
683 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.32.tgz#1dac6ac51ab19adb21b8b34fd2d93a86440ef6c9"
684 | integrity sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==
685 | dependencies:
686 | nanoid "^3.3.7"
687 | picocolors "^1.0.0"
688 | source-map-js "^1.0.2"
689 |
690 | punycode@^2.1.0:
691 | version "2.3.1"
692 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
693 | integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
694 |
695 | resolve@~1.19.0:
696 | version "1.19.0"
697 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c"
698 | integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==
699 | dependencies:
700 | is-core-module "^2.1.0"
701 | path-parse "^1.0.6"
702 |
703 | resolve@~1.22.1:
704 | version "1.22.8"
705 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
706 | integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
707 | dependencies:
708 | is-core-module "^2.13.0"
709 | path-parse "^1.0.7"
710 | supports-preserve-symlinks-flag "^1.0.0"
711 |
712 | rollup@^4.2.0:
713 | version "4.6.1"
714 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.6.1.tgz#351501c86b5b4f976dde8c5837516452b59921f8"
715 | integrity sha512-jZHaZotEHQaHLgKr8JnQiDT1rmatjgKlMekyksz+yk9jt/8z9quNjnKNRoaM0wd9DC2QKXjmWWuDYtM3jfF8pQ==
716 | optionalDependencies:
717 | "@rollup/rollup-android-arm-eabi" "4.6.1"
718 | "@rollup/rollup-android-arm64" "4.6.1"
719 | "@rollup/rollup-darwin-arm64" "4.6.1"
720 | "@rollup/rollup-darwin-x64" "4.6.1"
721 | "@rollup/rollup-linux-arm-gnueabihf" "4.6.1"
722 | "@rollup/rollup-linux-arm64-gnu" "4.6.1"
723 | "@rollup/rollup-linux-arm64-musl" "4.6.1"
724 | "@rollup/rollup-linux-x64-gnu" "4.6.1"
725 | "@rollup/rollup-linux-x64-musl" "4.6.1"
726 | "@rollup/rollup-win32-arm64-msvc" "4.6.1"
727 | "@rollup/rollup-win32-ia32-msvc" "4.6.1"
728 | "@rollup/rollup-win32-x64-msvc" "4.6.1"
729 | fsevents "~2.3.2"
730 |
731 | semver@^7.5.4, semver@~7.5.4:
732 | version "7.5.4"
733 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
734 | integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
735 | dependencies:
736 | lru-cache "^6.0.0"
737 |
738 | source-map-js@^1.0.2:
739 | version "1.0.2"
740 | resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
741 | integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
742 |
743 | source-map@~0.6.1:
744 | version "0.6.1"
745 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
746 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
747 |
748 | sprintf-js@~1.0.2:
749 | version "1.0.3"
750 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
751 | integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
752 |
753 | string-argv@~0.3.1:
754 | version "0.3.2"
755 | resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6"
756 | integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==
757 |
758 | strip-json-comments@~3.1.1:
759 | version "3.1.1"
760 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
761 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
762 |
763 | supports-preserve-symlinks-flag@^1.0.0:
764 | version "1.0.0"
765 | resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
766 | integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
767 |
768 | typescript@^5.3.2:
769 | version "5.3.2"
770 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.2.tgz#00d1c7c1c46928c5845c1ee8d0cc2791031d4c43"
771 | integrity sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==
772 |
773 | typescript@~5.0.4:
774 | version "5.0.4"
775 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b"
776 | integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==
777 |
778 | undici-types@~5.26.4:
779 | version "5.26.5"
780 | resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
781 | integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
782 |
783 | universalify@^0.1.0:
784 | version "0.1.2"
785 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
786 | integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
787 |
788 | uri-js@^4.2.2:
789 | version "4.4.1"
790 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
791 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
792 | dependencies:
793 | punycode "^2.1.0"
794 |
795 | validator@^13.7.0:
796 | version "13.11.0"
797 | resolved "https://registry.yarnpkg.com/validator/-/validator-13.11.0.tgz#23ab3fd59290c61248364eabf4067f04955fbb1b"
798 | integrity sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==
799 |
800 | vite-plugin-dts@^3.6.4:
801 | version "3.6.4"
802 | resolved "https://registry.yarnpkg.com/vite-plugin-dts/-/vite-plugin-dts-3.6.4.tgz#4ac51f6a5ca081ed18bc331cebc967545dac31fd"
803 | integrity sha512-yOVhUI/kQhtS6lCXRYYLv2UUf9bftcwQK9ROxCX2ul17poLQs02ctWX7+vXB8GPRzH8VCK3jebEFtPqqijXx6w==
804 | dependencies:
805 | "@microsoft/api-extractor" "^7.38.0"
806 | "@rollup/pluginutils" "^5.0.5"
807 | "@vue/language-core" "^1.8.20"
808 | debug "^4.3.4"
809 | kolorist "^1.8.0"
810 | vue-tsc "^1.8.20"
811 |
812 | vite@^5.0.6:
813 | version "5.0.6"
814 | resolved "https://registry.yarnpkg.com/vite/-/vite-5.0.6.tgz#f9e13503a4c5ccd67312c67803dec921f3bdea7c"
815 | integrity sha512-MD3joyAEBtV7QZPl2JVVUai6zHms3YOmLR+BpMzLlX2Yzjfcc4gTgNi09d/Rua3F4EtC8zdwPU8eQYyib4vVMQ==
816 | dependencies:
817 | esbuild "^0.19.3"
818 | postcss "^8.4.32"
819 | rollup "^4.2.0"
820 | optionalDependencies:
821 | fsevents "~2.3.3"
822 |
823 | vue-template-compiler@^2.7.14:
824 | version "2.7.15"
825 | resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.7.15.tgz#ec88ba8ceafe0f17a528b89c57e01e02da92b0de"
826 | integrity sha512-yQxjxMptBL7UAog00O8sANud99C6wJF+7kgbcwqkvA38vCGF7HWE66w0ZFnS/kX5gSoJr/PQ4/oS3Ne2pW37Og==
827 | dependencies:
828 | de-indent "^1.0.2"
829 | he "^1.2.0"
830 |
831 | vue-tsc@^1.8.20:
832 | version "1.8.25"
833 | resolved "https://registry.yarnpkg.com/vue-tsc/-/vue-tsc-1.8.25.tgz#90cd03e71d28c5c4a8068167b232eb97cc96b77f"
834 | integrity sha512-lHsRhDc/Y7LINvYhZ3pv4elflFADoEOo67vfClAfF2heVHpHmVquLSjojgCSIwzA4F0Pc4vowT/psXCYcfk+iQ==
835 | dependencies:
836 | "@volar/typescript" "~1.11.1"
837 | "@vue/language-core" "1.8.25"
838 | semver "^7.5.4"
839 |
840 | yallist@^4.0.0:
841 | version "4.0.0"
842 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
843 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
844 |
845 | z-schema@~5.0.2:
846 | version "5.0.6"
847 | resolved "https://registry.yarnpkg.com/z-schema/-/z-schema-5.0.6.tgz#46d6a687b15e4a4369e18d6cb1c7b8618fc256c5"
848 | integrity sha512-+XR1GhnWklYdfr8YaZv/iu+vY+ux7V5DS5zH1DQf6bO5ufrt/5cgNhVO5qyhsjFXvsqQb/f08DWE9b6uPscyAg==
849 | dependencies:
850 | lodash.get "^4.4.2"
851 | lodash.isequal "^4.5.0"
852 | validator "^13.7.0"
853 | optionalDependencies:
854 | commander "^10.0.0"
855 |
--------------------------------------------------------------------------------