完成世界书、骰子、apiconfig页面处理
This commit is contained in:
82
frontend/node_modules/dagre-d3-es/src/dagre-js/arrows.js
generated
vendored
Normal file
82
frontend/node_modules/dagre-d3-es/src/dagre-js/arrows.js
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
import * as util from './util.js';
|
||||
|
||||
export { arrows, setArrows };
|
||||
|
||||
var arrows = {
|
||||
normal,
|
||||
vee,
|
||||
undirected,
|
||||
};
|
||||
|
||||
function setArrows(value) {
|
||||
arrows = value;
|
||||
}
|
||||
|
||||
function normal(parent, id, edge, type) {
|
||||
var marker = parent
|
||||
.append('marker')
|
||||
.attr('id', id)
|
||||
.attr('viewBox', '0 0 10 10')
|
||||
.attr('refX', 9)
|
||||
.attr('refY', 5)
|
||||
.attr('markerUnits', 'strokeWidth')
|
||||
.attr('markerWidth', 8)
|
||||
.attr('markerHeight', 6)
|
||||
.attr('orient', 'auto');
|
||||
|
||||
var path = marker
|
||||
.append('path')
|
||||
.attr('d', 'M 0 0 L 10 5 L 0 10 z')
|
||||
.style('stroke-width', 1)
|
||||
.style('stroke-dasharray', '1,0');
|
||||
util.applyStyle(path, edge[type + 'Style']);
|
||||
if (edge[type + 'Class']) {
|
||||
path.attr('class', edge[type + 'Class']);
|
||||
}
|
||||
}
|
||||
|
||||
function vee(parent, id, edge, type) {
|
||||
var marker = parent
|
||||
.append('marker')
|
||||
.attr('id', id)
|
||||
.attr('viewBox', '0 0 10 10')
|
||||
.attr('refX', 9)
|
||||
.attr('refY', 5)
|
||||
.attr('markerUnits', 'strokeWidth')
|
||||
.attr('markerWidth', 8)
|
||||
.attr('markerHeight', 6)
|
||||
.attr('orient', 'auto');
|
||||
|
||||
var path = marker
|
||||
.append('path')
|
||||
.attr('d', 'M 0 0 L 10 5 L 0 10 L 4 5 z')
|
||||
.style('stroke-width', 1)
|
||||
.style('stroke-dasharray', '1,0');
|
||||
util.applyStyle(path, edge[type + 'Style']);
|
||||
if (edge[type + 'Class']) {
|
||||
path.attr('class', edge[type + 'Class']);
|
||||
}
|
||||
}
|
||||
|
||||
function undirected(parent, id, edge, type) {
|
||||
var marker = parent
|
||||
.append('marker')
|
||||
.attr('id', id)
|
||||
.attr('viewBox', '0 0 10 10')
|
||||
.attr('refX', 9)
|
||||
.attr('refY', 5)
|
||||
.attr('markerUnits', 'strokeWidth')
|
||||
.attr('markerWidth', 8)
|
||||
.attr('markerHeight', 6)
|
||||
.attr('orient', 'auto');
|
||||
|
||||
var path = marker
|
||||
.append('path')
|
||||
.attr('d', 'M 0 5 L 10 5')
|
||||
.style('stroke-width', 1)
|
||||
.style('stroke-dasharray', '1,0');
|
||||
util.applyStyle(path, edge[type + 'Style']);
|
||||
if (edge[type + 'Class']) {
|
||||
path.attr('class', edge[type + 'Class']);
|
||||
}
|
||||
}
|
||||
49
frontend/node_modules/dagre-d3-es/src/dagre-js/create-clusters.js
generated
vendored
Normal file
49
frontend/node_modules/dagre-d3-es/src/dagre-js/create-clusters.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
import * as d3 from 'd3';
|
||||
import { addLabel } from './label/add-label.js';
|
||||
import * as util from './util.js';
|
||||
|
||||
export { createClusters, setCreateClusters };
|
||||
|
||||
var createClusters = function (selection, g) {
|
||||
var clusters = g.nodes().filter(function (v) {
|
||||
return util.isSubgraph(g, v);
|
||||
});
|
||||
var svgClusters = selection.selectAll('g.cluster').data(clusters, function (v) {
|
||||
return v;
|
||||
});
|
||||
|
||||
util.applyTransition(svgClusters.exit(), g).style('opacity', 0).remove();
|
||||
|
||||
var enterSelection = svgClusters
|
||||
.enter()
|
||||
.append('g')
|
||||
.attr('class', 'cluster')
|
||||
.attr('id', function (v) {
|
||||
var node = g.node(v);
|
||||
return node.id;
|
||||
})
|
||||
.style('opacity', 0)
|
||||
.each(function (v) {
|
||||
var node = g.node(v);
|
||||
var thisGroup = d3.select(this);
|
||||
d3.select(this).append('rect');
|
||||
var labelGroup = thisGroup.append('g').attr('class', 'label');
|
||||
addLabel(labelGroup, node, node.clusterLabelPos);
|
||||
});
|
||||
|
||||
svgClusters = svgClusters.merge(enterSelection);
|
||||
|
||||
svgClusters = util.applyTransition(svgClusters, g).style('opacity', 1);
|
||||
|
||||
svgClusters.selectAll('rect').each(function (c) {
|
||||
var node = g.node(c);
|
||||
var domCluster = d3.select(this);
|
||||
util.applyStyle(domCluster, node.style);
|
||||
});
|
||||
|
||||
return svgClusters;
|
||||
};
|
||||
|
||||
function setCreateClusters(value) {
|
||||
createClusters = value;
|
||||
}
|
||||
2
frontend/node_modules/dagre-d3-es/src/dagre-js/create-edge-labels.d.ts
generated
vendored
Normal file
2
frontend/node_modules/dagre-d3-es/src/dagre-js/create-edge-labels.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export function createEdgeLabels(selection: any, g: any): any;
|
||||
export function setCreateEdgeLabels(value: any): void;
|
||||
53
frontend/node_modules/dagre-d3-es/src/dagre-js/create-edge-labels.js
generated
vendored
Normal file
53
frontend/node_modules/dagre-d3-es/src/dagre-js/create-edge-labels.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
import * as d3 from 'd3';
|
||||
import { addLabel } from './label/add-label.js';
|
||||
import * as util from './util.js';
|
||||
|
||||
export { createEdgeLabels, setCreateEdgeLabels };
|
||||
|
||||
let createEdgeLabels = function (selection, g) {
|
||||
var svgEdgeLabels = selection
|
||||
.selectAll('g.edgeLabel')
|
||||
.data(g.edges(), function (e) {
|
||||
return util.edgeToId(e);
|
||||
})
|
||||
.classed('update', true);
|
||||
|
||||
svgEdgeLabels.exit().remove();
|
||||
svgEdgeLabels.enter().append('g').classed('edgeLabel', true).style('opacity', 0);
|
||||
|
||||
svgEdgeLabels = selection.selectAll('g.edgeLabel');
|
||||
|
||||
svgEdgeLabels.each(function (e) {
|
||||
var root = d3.select(this);
|
||||
root.select('.label').remove();
|
||||
var edge = g.edge(e);
|
||||
var label = addLabel(root, g.edge(e), 0).classed('label', true);
|
||||
var bbox = label.node().getBBox();
|
||||
|
||||
if (edge.labelId) {
|
||||
label.attr('id', edge.labelId);
|
||||
}
|
||||
if (!Object.prototype.hasOwnProperty.call(edge, 'width')) {
|
||||
edge.width = bbox.width;
|
||||
}
|
||||
if (!Object.prototype.hasOwnProperty.call(edge, 'height')) {
|
||||
edge.height = bbox.height;
|
||||
}
|
||||
});
|
||||
|
||||
var exitSelection;
|
||||
|
||||
if (svgEdgeLabels.exit) {
|
||||
exitSelection = svgEdgeLabels.exit();
|
||||
} else {
|
||||
exitSelection = svgEdgeLabels.selectAll(null); // empty selection
|
||||
}
|
||||
|
||||
util.applyTransition(exitSelection, g).style('opacity', 0).remove();
|
||||
|
||||
return svgEdgeLabels;
|
||||
};
|
||||
|
||||
function setCreateEdgeLabels(value) {
|
||||
createEdgeLabels = value;
|
||||
}
|
||||
132
frontend/node_modules/dagre-d3-es/src/dagre-js/create-edge-paths.js
generated
vendored
Normal file
132
frontend/node_modules/dagre-d3-es/src/dagre-js/create-edge-paths.js
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
import * as d3 from 'd3';
|
||||
import * as _ from 'lodash-es';
|
||||
import { intersectNode } from './intersect/intersect-node.js';
|
||||
import * as util from './util.js';
|
||||
|
||||
export { createEdgePaths, setCreateEdgePaths };
|
||||
|
||||
var createEdgePaths = function (selection, g, arrows) {
|
||||
var previousPaths = selection
|
||||
.selectAll('g.edgePath')
|
||||
.data(g.edges(), function (e) {
|
||||
return util.edgeToId(e);
|
||||
})
|
||||
.classed('update', true);
|
||||
|
||||
var newPaths = enter(previousPaths, g);
|
||||
exit(previousPaths, g);
|
||||
|
||||
var svgPaths = previousPaths.merge !== undefined ? previousPaths.merge(newPaths) : previousPaths;
|
||||
util.applyTransition(svgPaths, g).style('opacity', 1);
|
||||
|
||||
// Save DOM element in the path group, and set ID and class
|
||||
svgPaths.each(function (e) {
|
||||
var domEdge = d3.select(this);
|
||||
var edge = g.edge(e);
|
||||
edge.elem = this;
|
||||
|
||||
if (edge.id) {
|
||||
domEdge.attr('id', edge.id);
|
||||
}
|
||||
|
||||
util.applyClass(
|
||||
domEdge,
|
||||
edge['class'],
|
||||
(domEdge.classed('update') ? 'update ' : '') + 'edgePath',
|
||||
);
|
||||
});
|
||||
|
||||
svgPaths.selectAll('path.path').each(function (e) {
|
||||
var edge = g.edge(e);
|
||||
edge.arrowheadId = _.uniqueId('arrowhead');
|
||||
|
||||
var domEdge = d3
|
||||
.select(this)
|
||||
.attr('marker-end', function () {
|
||||
return 'url(' + makeFragmentRef(location.href, edge.arrowheadId) + ')';
|
||||
})
|
||||
.style('fill', 'none');
|
||||
|
||||
util.applyTransition(domEdge, g).attr('d', function (e) {
|
||||
return calcPoints(g, e);
|
||||
});
|
||||
|
||||
util.applyStyle(domEdge, edge.style);
|
||||
});
|
||||
|
||||
svgPaths.selectAll('defs *').remove();
|
||||
svgPaths.selectAll('defs').each(function (e) {
|
||||
var edge = g.edge(e);
|
||||
var arrowhead = arrows[edge.arrowhead];
|
||||
arrowhead(d3.select(this), edge.arrowheadId, edge, 'arrowhead');
|
||||
});
|
||||
|
||||
return svgPaths;
|
||||
};
|
||||
|
||||
function setCreateEdgePaths(value) {
|
||||
createEdgePaths = value;
|
||||
}
|
||||
|
||||
function makeFragmentRef(url, fragmentId) {
|
||||
var baseUrl = url.split('#')[0];
|
||||
return baseUrl + '#' + fragmentId;
|
||||
}
|
||||
|
||||
function calcPoints(g, e) {
|
||||
var edge = g.edge(e);
|
||||
var tail = g.node(e.v);
|
||||
var head = g.node(e.w);
|
||||
var points = edge.points.slice(1, edge.points.length - 1);
|
||||
points.unshift(intersectNode(tail, points[0]));
|
||||
points.push(intersectNode(head, points[points.length - 1]));
|
||||
|
||||
return createLine(edge, points);
|
||||
}
|
||||
|
||||
function createLine(edge, points) {
|
||||
// @ts-expect-error
|
||||
var line = (d3.line || d3.svg.line)()
|
||||
.x(function (d) {
|
||||
return d.x;
|
||||
})
|
||||
.y(function (d) {
|
||||
return d.y;
|
||||
});
|
||||
|
||||
(line.curve || line.interpolate)(edge.curve);
|
||||
|
||||
return line(points);
|
||||
}
|
||||
|
||||
function getCoords(elem) {
|
||||
var bbox = elem.getBBox();
|
||||
var matrix = elem.ownerSVGElement
|
||||
.getScreenCTM()
|
||||
.inverse()
|
||||
.multiply(elem.getScreenCTM())
|
||||
.translate(bbox.width / 2, bbox.height / 2);
|
||||
return { x: matrix.e, y: matrix.f };
|
||||
}
|
||||
|
||||
function enter(svgPaths, g) {
|
||||
var svgPathsEnter = svgPaths.enter().append('g').attr('class', 'edgePath').style('opacity', 0);
|
||||
svgPathsEnter
|
||||
.append('path')
|
||||
.attr('class', 'path')
|
||||
.attr('d', function (e) {
|
||||
var edge = g.edge(e);
|
||||
var sourceElem = g.node(e.v).elem;
|
||||
var points = _.range(edge.points.length).map(function () {
|
||||
return getCoords(sourceElem);
|
||||
});
|
||||
return createLine(edge, points);
|
||||
});
|
||||
svgPathsEnter.append('defs');
|
||||
return svgPathsEnter;
|
||||
}
|
||||
|
||||
function exit(svgPaths, g) {
|
||||
var svgPathExit = svgPaths.exit();
|
||||
util.applyTransition(svgPathExit, g).style('opacity', 0).remove();
|
||||
}
|
||||
4
frontend/node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-circle.d.ts
generated
vendored
Normal file
4
frontend/node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-circle.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
export function intersectCircle(node: any, rx: any, point: any): {
|
||||
x: any;
|
||||
y: any;
|
||||
};
|
||||
7
frontend/node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-circle.js
generated
vendored
Normal file
7
frontend/node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-circle.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import { intersectEllipse } from './intersect-ellipse.js';
|
||||
|
||||
export { intersectCircle };
|
||||
|
||||
function intersectCircle(node, rx, point) {
|
||||
return intersectEllipse(node, rx, rx, point);
|
||||
}
|
||||
4
frontend/node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-ellipse.d.ts
generated
vendored
Normal file
4
frontend/node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-ellipse.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
export function intersectEllipse(node: any, rx: any, ry: any, point: any): {
|
||||
x: any;
|
||||
y: any;
|
||||
};
|
||||
5
frontend/node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-node.js
generated
vendored
Normal file
5
frontend/node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-node.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
export { intersectNode };
|
||||
|
||||
function intersectNode(node, point) {
|
||||
return node.intersect(point);
|
||||
}
|
||||
13
frontend/node_modules/dagre-d3-es/src/dagre-js/label/add-svg-label.js
generated
vendored
Normal file
13
frontend/node_modules/dagre-d3-es/src/dagre-js/label/add-svg-label.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import * as util from '../util.js';
|
||||
|
||||
export { addSVGLabel };
|
||||
|
||||
function addSVGLabel(root, node) {
|
||||
var domNode = root;
|
||||
|
||||
domNode.node().appendChild(node.label);
|
||||
|
||||
util.applyStyle(domNode, node.labelStyle);
|
||||
|
||||
return domNode;
|
||||
}
|
||||
48
frontend/node_modules/dagre-d3-es/src/dagre-js/label/add-text-label.js
generated
vendored
Normal file
48
frontend/node_modules/dagre-d3-es/src/dagre-js/label/add-text-label.js
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
import * as util from '../util.js';
|
||||
|
||||
export { addTextLabel };
|
||||
|
||||
/*
|
||||
* Attaches a text label to the specified root. Handles escape sequences.
|
||||
*/
|
||||
function addTextLabel(root, node) {
|
||||
var domNode = root.append('text');
|
||||
|
||||
var lines = processEscapeSequences(node.label).split('\n');
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
domNode
|
||||
.append('tspan')
|
||||
.attr('xml:space', 'preserve')
|
||||
.attr('dy', '1em')
|
||||
.attr('x', '1')
|
||||
.text(lines[i]);
|
||||
}
|
||||
|
||||
util.applyStyle(domNode, node.labelStyle);
|
||||
|
||||
return domNode;
|
||||
}
|
||||
|
||||
function processEscapeSequences(text) {
|
||||
var newText = '';
|
||||
var escaped = false;
|
||||
var ch;
|
||||
for (var i = 0; i < text.length; ++i) {
|
||||
ch = text[i];
|
||||
if (escaped) {
|
||||
switch (ch) {
|
||||
case 'n':
|
||||
newText += '\n';
|
||||
break;
|
||||
default:
|
||||
newText += ch;
|
||||
}
|
||||
escaped = false;
|
||||
} else if (ch === '\\') {
|
||||
escaped = true;
|
||||
} else {
|
||||
newText += ch;
|
||||
}
|
||||
}
|
||||
return newText;
|
||||
}
|
||||
1
frontend/node_modules/dagre-d3-es/src/dagre-js/position-edge-labels.d.ts
generated
vendored
Normal file
1
frontend/node_modules/dagre-d3-es/src/dagre-js/position-edge-labels.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export function positionEdgeLabels(selection: any, g: any): void;
|
||||
48
frontend/node_modules/dagre-d3-es/src/dagre-js/render.d.ts
generated
vendored
Normal file
48
frontend/node_modules/dagre-d3-es/src/dagre-js/render.d.ts
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
export type Node = {
|
||||
/**
|
||||
* - The label of the node.
|
||||
*/
|
||||
label: string;
|
||||
/**
|
||||
* - The horizontal padding of the node.
|
||||
*/
|
||||
paddingX?: number;
|
||||
/**
|
||||
* - The vertical padding of the node.
|
||||
*/
|
||||
paddingY?: number;
|
||||
/**
|
||||
* - The padding of the node for all directions. Overrides `paddingX` and `paddingY`.
|
||||
*/
|
||||
padding?: number;
|
||||
/**
|
||||
* - The left padding of the node.
|
||||
*/
|
||||
paddingLeft?: number;
|
||||
/**
|
||||
* - The right padding of the node.
|
||||
*/
|
||||
paddingRight?: number;
|
||||
_prevWidth?: number;
|
||||
width?: number;
|
||||
_prevHeight?: number;
|
||||
height?: number;
|
||||
};
|
||||
export function render(): {
|
||||
(svg: any, g: any): void;
|
||||
createNodes(value: any, ...args: any[]): (selection: any, g: any, shapes: any) => any;
|
||||
createClusters(value: any, ...args: any[]): (selection: any, g: any) => any;
|
||||
createEdgeLabels(value: any, ...args: any[]): (selection: any, g: any) => any;
|
||||
createEdgePaths(value: any, ...args: any[]): (selection: any, g: any, arrows: any) => any;
|
||||
shapes(value: any, ...args: any[]): {
|
||||
rect: (parent: any, bbox: any, node: any) => any;
|
||||
ellipse: (parent: any, bbox: any, node: any) => any;
|
||||
circle: (parent: any, bbox: any, node: any) => any;
|
||||
diamond: (parent: any, bbox: any, node: any) => any;
|
||||
} | /*elided*/ any;
|
||||
arrows(value: any, ...args: any[]): {
|
||||
normal: (parent: any, id: any, edge: any, type: any) => void;
|
||||
vee: (parent: any, id: any, edge: any, type: any) => void;
|
||||
undirected: (parent: any, id: any, edge: any, type: any) => void;
|
||||
} | /*elided*/ any;
|
||||
};
|
||||
5
frontend/node_modules/dagre-d3-es/src/dagre-js/util.d.ts
generated
vendored
Normal file
5
frontend/node_modules/dagre-d3-es/src/dagre-js/util.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
export function isSubgraph(g: any, v: any): boolean;
|
||||
export function edgeToId(e: any): string;
|
||||
export function applyStyle(dom: any, styleFn: any): void;
|
||||
export function applyClass(dom: any, classFn: any, otherClasses: any): void;
|
||||
export function applyTransition(selection: any, g: any): any;
|
||||
60
frontend/node_modules/dagre-d3-es/src/dagre/acyclic.js
generated
vendored
Normal file
60
frontend/node_modules/dagre-d3-es/src/dagre/acyclic.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
import * as _ from 'lodash-es';
|
||||
import { greedyFAS } from './greedy-fas.js';
|
||||
|
||||
export { run, undo };
|
||||
|
||||
function run(g) {
|
||||
var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g);
|
||||
_.forEach(fas, function (e) {
|
||||
var label = g.edge(e);
|
||||
g.removeEdge(e);
|
||||
label.forwardName = e.name;
|
||||
label.reversed = true;
|
||||
g.setEdge(e.w, e.v, label, _.uniqueId('rev'));
|
||||
});
|
||||
|
||||
function weightFn(g) {
|
||||
return function (e) {
|
||||
return g.edge(e).weight;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function dfsFAS(g) {
|
||||
var fas = [];
|
||||
var stack = {};
|
||||
var visited = {};
|
||||
|
||||
function dfs(v) {
|
||||
if (Object.prototype.hasOwnProperty.call(visited, v)) {
|
||||
return;
|
||||
}
|
||||
visited[v] = true;
|
||||
stack[v] = true;
|
||||
_.forEach(g.outEdges(v), function (e) {
|
||||
if (Object.prototype.hasOwnProperty.call(stack, e.w)) {
|
||||
fas.push(e);
|
||||
} else {
|
||||
dfs(e.w);
|
||||
}
|
||||
});
|
||||
delete stack[v];
|
||||
}
|
||||
|
||||
_.forEach(g.nodes(), dfs);
|
||||
return fas;
|
||||
}
|
||||
|
||||
function undo(g) {
|
||||
_.forEach(g.edges(), function (e) {
|
||||
var label = g.edge(e);
|
||||
if (label.reversed) {
|
||||
g.removeEdge(e);
|
||||
|
||||
var forwardName = label.forwardName;
|
||||
delete label.reversed;
|
||||
delete label.forwardName;
|
||||
g.setEdge(e.w, e.v, label, forwardName);
|
||||
}
|
||||
});
|
||||
}
|
||||
2
frontend/node_modules/dagre-d3-es/src/dagre/debug.d.ts
generated
vendored
Normal file
2
frontend/node_modules/dagre-d3-es/src/dagre/debug.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export function debugOrdering(g: any): Graph<any, any, any>;
|
||||
import { Graph } from '../graphlib/index.js';
|
||||
126
frontend/node_modules/dagre-d3-es/src/dagre/greedy-fas.js
generated
vendored
Normal file
126
frontend/node_modules/dagre-d3-es/src/dagre/greedy-fas.js
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
import * as _ from 'lodash-es';
|
||||
import { Graph } from '../graphlib/index.js';
|
||||
import { List } from './data/list.js';
|
||||
|
||||
/*
|
||||
* A greedy heuristic for finding a feedback arc set for a graph. A feedback
|
||||
* arc set is a set of edges that can be removed to make a graph acyclic.
|
||||
* The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and
|
||||
* effective heuristic for the feedback arc set problem." This implementation
|
||||
* adjusts that from the paper to allow for weighted edges.
|
||||
*/
|
||||
export { greedyFAS };
|
||||
|
||||
var DEFAULT_WEIGHT_FN = _.constant(1);
|
||||
|
||||
function greedyFAS(g, weightFn) {
|
||||
if (g.nodeCount() <= 1) {
|
||||
return [];
|
||||
}
|
||||
var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN);
|
||||
var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx);
|
||||
|
||||
// Expand multi-edges
|
||||
return _.flatten(
|
||||
_.map(results, function (e) {
|
||||
return g.outEdges(e.v, e.w);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
function doGreedyFAS(g, buckets, zeroIdx) {
|
||||
var results = [];
|
||||
var sources = buckets[buckets.length - 1];
|
||||
var sinks = buckets[0];
|
||||
|
||||
var entry;
|
||||
while (g.nodeCount()) {
|
||||
while ((entry = sinks.dequeue())) {
|
||||
removeNode(g, buckets, zeroIdx, entry);
|
||||
}
|
||||
while ((entry = sources.dequeue())) {
|
||||
removeNode(g, buckets, zeroIdx, entry);
|
||||
}
|
||||
if (g.nodeCount()) {
|
||||
for (var i = buckets.length - 2; i > 0; --i) {
|
||||
entry = buckets[i].dequeue();
|
||||
if (entry) {
|
||||
results = results.concat(removeNode(g, buckets, zeroIdx, entry, true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) {
|
||||
var results = collectPredecessors ? [] : undefined;
|
||||
|
||||
_.forEach(g.inEdges(entry.v), function (edge) {
|
||||
var weight = g.edge(edge);
|
||||
var uEntry = g.node(edge.v);
|
||||
|
||||
if (collectPredecessors) {
|
||||
results.push({ v: edge.v, w: edge.w });
|
||||
}
|
||||
|
||||
uEntry.out -= weight;
|
||||
assignBucket(buckets, zeroIdx, uEntry);
|
||||
});
|
||||
|
||||
_.forEach(g.outEdges(entry.v), function (edge) {
|
||||
var weight = g.edge(edge);
|
||||
var w = edge.w;
|
||||
var wEntry = g.node(w);
|
||||
wEntry['in'] -= weight;
|
||||
assignBucket(buckets, zeroIdx, wEntry);
|
||||
});
|
||||
|
||||
g.removeNode(entry.v);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
function buildState(g, weightFn) {
|
||||
var fasGraph = new Graph();
|
||||
var maxIn = 0;
|
||||
var maxOut = 0;
|
||||
|
||||
_.forEach(g.nodes(), function (v) {
|
||||
fasGraph.setNode(v, { v: v, in: 0, out: 0 });
|
||||
});
|
||||
|
||||
// Aggregate weights on nodes, but also sum the weights across multi-edges
|
||||
// into a single edge for the fasGraph.
|
||||
_.forEach(g.edges(), function (e) {
|
||||
var prevWeight = fasGraph.edge(e.v, e.w) || 0;
|
||||
var weight = weightFn(e);
|
||||
var edgeWeight = prevWeight + weight;
|
||||
fasGraph.setEdge(e.v, e.w, edgeWeight);
|
||||
maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight));
|
||||
maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight));
|
||||
});
|
||||
|
||||
var buckets = _.range(maxOut + maxIn + 3).map(function () {
|
||||
return new List();
|
||||
});
|
||||
var zeroIdx = maxIn + 1;
|
||||
|
||||
_.forEach(fasGraph.nodes(), function (v) {
|
||||
assignBucket(buckets, zeroIdx, fasGraph.node(v));
|
||||
});
|
||||
|
||||
return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx };
|
||||
}
|
||||
|
||||
function assignBucket(buckets, zeroIdx, entry) {
|
||||
if (!entry.out) {
|
||||
buckets[0].enqueue(entry);
|
||||
} else if (!entry['in']) {
|
||||
buckets[buckets.length - 1].enqueue(entry);
|
||||
} else {
|
||||
buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry);
|
||||
}
|
||||
}
|
||||
6
frontend/node_modules/dagre-d3-es/src/dagre/index.js
generated
vendored
Normal file
6
frontend/node_modules/dagre-d3-es/src/dagre/index.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import * as acyclic from './acyclic.js';
|
||||
import { layout } from './layout.js';
|
||||
import * as normalize from './normalize.js';
|
||||
import { rank } from './rank/index.js';
|
||||
|
||||
export { acyclic, normalize, rank, layout };
|
||||
2
frontend/node_modules/dagre-d3-es/src/dagre/nesting-graph.d.ts
generated
vendored
Normal file
2
frontend/node_modules/dagre-d3-es/src/dagre/nesting-graph.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export function run(g: any): void;
|
||||
export function cleanup(g: any): void;
|
||||
137
frontend/node_modules/dagre-d3-es/src/dagre/nesting-graph.js
generated
vendored
Normal file
137
frontend/node_modules/dagre-d3-es/src/dagre/nesting-graph.js
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
import * as _ from 'lodash-es';
|
||||
import * as util from './util.js';
|
||||
|
||||
export { run, cleanup };
|
||||
|
||||
/*
|
||||
* A nesting graph creates dummy nodes for the tops and bottoms of subgraphs,
|
||||
* adds appropriate edges to ensure that all cluster nodes are placed between
|
||||
* these boundries, and ensures that the graph is connected.
|
||||
*
|
||||
* In addition we ensure, through the use of the minlen property, that nodes
|
||||
* and subgraph border nodes to not end up on the same rank.
|
||||
*
|
||||
* Preconditions:
|
||||
*
|
||||
* 1. Input graph is a DAG
|
||||
* 2. Nodes in the input graph has a minlen attribute
|
||||
*
|
||||
* Postconditions:
|
||||
*
|
||||
* 1. Input graph is connected.
|
||||
* 2. Dummy nodes are added for the tops and bottoms of subgraphs.
|
||||
* 3. The minlen attribute for nodes is adjusted to ensure nodes do not
|
||||
* get placed on the same rank as subgraph border nodes.
|
||||
*
|
||||
* The nesting graph idea comes from Sander, "Layout of Compound Directed
|
||||
* Graphs."
|
||||
*/
|
||||
function run(g) {
|
||||
var root = util.addDummyNode(g, 'root', {}, '_root');
|
||||
var depths = treeDepths(g);
|
||||
var height = _.max(_.values(depths)) - 1; // Note: depths is an Object not an array
|
||||
var nodeSep = 2 * height + 1;
|
||||
|
||||
g.graph().nestingRoot = root;
|
||||
|
||||
// Multiply minlen by nodeSep to align nodes on non-border ranks.
|
||||
_.forEach(g.edges(), function (e) {
|
||||
g.edge(e).minlen *= nodeSep;
|
||||
});
|
||||
|
||||
// Calculate a weight that is sufficient to keep subgraphs vertically compact
|
||||
var weight = sumWeights(g) + 1;
|
||||
|
||||
// Create border nodes and link them up
|
||||
_.forEach(g.children(), function (child) {
|
||||
dfs(g, root, nodeSep, weight, height, depths, child);
|
||||
});
|
||||
|
||||
// Save the multiplier for node layers for later removal of empty border
|
||||
// layers.
|
||||
g.graph().nodeRankFactor = nodeSep;
|
||||
}
|
||||
|
||||
function dfs(g, root, nodeSep, weight, height, depths, v) {
|
||||
var children = g.children(v);
|
||||
if (!children.length) {
|
||||
if (v !== root) {
|
||||
g.setEdge(root, v, { weight: 0, minlen: nodeSep });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var top = util.addBorderNode(g, '_bt');
|
||||
var bottom = util.addBorderNode(g, '_bb');
|
||||
var label = g.node(v);
|
||||
|
||||
g.setParent(top, v);
|
||||
label.borderTop = top;
|
||||
g.setParent(bottom, v);
|
||||
label.borderBottom = bottom;
|
||||
|
||||
_.forEach(children, function (child) {
|
||||
dfs(g, root, nodeSep, weight, height, depths, child);
|
||||
|
||||
var childNode = g.node(child);
|
||||
var childTop = childNode.borderTop ? childNode.borderTop : child;
|
||||
var childBottom = childNode.borderBottom ? childNode.borderBottom : child;
|
||||
var thisWeight = childNode.borderTop ? weight : 2 * weight;
|
||||
var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1;
|
||||
|
||||
g.setEdge(top, childTop, {
|
||||
weight: thisWeight,
|
||||
minlen: minlen,
|
||||
nestingEdge: true,
|
||||
});
|
||||
|
||||
g.setEdge(childBottom, bottom, {
|
||||
weight: thisWeight,
|
||||
minlen: minlen,
|
||||
nestingEdge: true,
|
||||
});
|
||||
});
|
||||
|
||||
if (!g.parent(v)) {
|
||||
g.setEdge(root, top, { weight: 0, minlen: height + depths[v] });
|
||||
}
|
||||
}
|
||||
|
||||
function treeDepths(g) {
|
||||
var depths = {};
|
||||
function dfs(v, depth) {
|
||||
var children = g.children(v);
|
||||
if (children && children.length) {
|
||||
_.forEach(children, function (child) {
|
||||
dfs(child, depth + 1);
|
||||
});
|
||||
}
|
||||
depths[v] = depth;
|
||||
}
|
||||
_.forEach(g.children(), function (v) {
|
||||
dfs(v, 1);
|
||||
});
|
||||
return depths;
|
||||
}
|
||||
|
||||
function sumWeights(g) {
|
||||
return _.reduce(
|
||||
g.edges(),
|
||||
function (acc, e) {
|
||||
return acc + g.edge(e).weight;
|
||||
},
|
||||
0,
|
||||
);
|
||||
}
|
||||
|
||||
function cleanup(g) {
|
||||
var graphLabel = g.graph();
|
||||
g.removeNode(graphLabel.nestingRoot);
|
||||
delete graphLabel.nestingRoot;
|
||||
_.forEach(g.edges(), function (e) {
|
||||
var edge = g.edge(e);
|
||||
if (edge.nestingEdge) {
|
||||
g.removeEdge(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
2
frontend/node_modules/dagre-d3-es/src/dagre/normalize.d.ts
generated
vendored
Normal file
2
frontend/node_modules/dagre-d3-es/src/dagre/normalize.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export function run(g: any): void;
|
||||
export function undo(g: any): void;
|
||||
1
frontend/node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.d.ts
generated
vendored
Normal file
1
frontend/node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export function addSubgraphConstraints(g: any, cg: any, vs: any): void;
|
||||
76
frontend/node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js
generated
vendored
Normal file
76
frontend/node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
import * as _ from 'lodash-es';
|
||||
import { Graph } from '../../graphlib/index.js';
|
||||
|
||||
export { buildLayerGraph };
|
||||
|
||||
/*
|
||||
* Constructs a graph that can be used to sort a layer of nodes. The graph will
|
||||
* contain all base and subgraph nodes from the request layer in their original
|
||||
* hierarchy and any edges that are incident on these nodes and are of the type
|
||||
* requested by the "relationship" parameter.
|
||||
*
|
||||
* Nodes from the requested rank that do not have parents are assigned a root
|
||||
* node in the output graph, which is set in the root graph attribute. This
|
||||
* makes it easy to walk the hierarchy of movable nodes during ordering.
|
||||
*
|
||||
* Pre-conditions:
|
||||
*
|
||||
* 1. Input graph is a DAG
|
||||
* 2. Base nodes in the input graph have a rank attribute
|
||||
* 3. Subgraph nodes in the input graph has minRank and maxRank attributes
|
||||
* 4. Edges have an assigned weight
|
||||
*
|
||||
* Post-conditions:
|
||||
*
|
||||
* 1. Output graph has all nodes in the movable rank with preserved
|
||||
* hierarchy.
|
||||
* 2. Root nodes in the movable layer are made children of the node
|
||||
* indicated by the root attribute of the graph.
|
||||
* 3. Non-movable nodes incident on movable nodes, selected by the
|
||||
* relationship parameter, are included in the graph (without hierarchy).
|
||||
* 4. Edges incident on movable nodes, selected by the relationship
|
||||
* parameter, are added to the output graph.
|
||||
* 5. The weights for copied edges are aggregated as need, since the output
|
||||
* graph is not a multi-graph.
|
||||
*/
|
||||
function buildLayerGraph(g, rank, relationship) {
|
||||
var root = createRootNode(g),
|
||||
result = new Graph({ compound: true })
|
||||
.setGraph({ root: root })
|
||||
.setDefaultNodeLabel(function (v) {
|
||||
return g.node(v);
|
||||
});
|
||||
|
||||
_.forEach(g.nodes(), function (v) {
|
||||
var node = g.node(v),
|
||||
parent = g.parent(v);
|
||||
|
||||
if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) {
|
||||
result.setNode(v);
|
||||
result.setParent(v, parent || root);
|
||||
|
||||
// This assumes we have only short edges!
|
||||
_.forEach(g[relationship](v), function (e) {
|
||||
var u = e.v === v ? e.w : e.v,
|
||||
edge = result.edge(u, v),
|
||||
weight = !_.isUndefined(edge) ? edge.weight : 0;
|
||||
result.setEdge(u, v, { weight: g.edge(e).weight + weight });
|
||||
});
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(node, 'minRank')) {
|
||||
result.setNode(v, {
|
||||
borderLeft: node.borderLeft[rank],
|
||||
borderRight: node.borderRight[rank],
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function createRootNode(g) {
|
||||
var v;
|
||||
while (g.hasNode((v = _.uniqueId('_root'))));
|
||||
return v;
|
||||
}
|
||||
3
frontend/node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.d.ts
generated
vendored
Normal file
3
frontend/node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export function sortSubgraph(g: any, v: any, cg: any, biasRight: any): {
|
||||
vs: any[];
|
||||
};
|
||||
46
frontend/node_modules/dagre-d3-es/src/dagre/position/bk.d.ts
generated
vendored
Normal file
46
frontend/node_modules/dagre-d3-es/src/dagre/position/bk.d.ts
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
export function positionX(g: any): {
|
||||
[x: string]: any;
|
||||
};
|
||||
export function findType1Conflicts(g: any, layering: any): {
|
||||
[nodeId: string]: {
|
||||
[nodeId: string]: true;
|
||||
[nodeId: number]: true;
|
||||
};
|
||||
[nodeId: number]: {
|
||||
[nodeId: string]: true;
|
||||
[nodeId: number]: true;
|
||||
};
|
||||
};
|
||||
export function findType2Conflicts(g: any, layering: any): {
|
||||
[nodeId: string]: {
|
||||
[nodeId: string]: true;
|
||||
[nodeId: number]: true;
|
||||
};
|
||||
[nodeId: number]: {
|
||||
[nodeId: string]: true;
|
||||
[nodeId: number]: true;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Sets `conflicts[v][w] = true`, creating objects if needed.
|
||||
*
|
||||
* @param {{[nodeId: string | number]: {[nodeId: string | number]: true}}} conflicts - Object to set.
|
||||
* @param {string | number} v - First Node ID
|
||||
* @param {string | number} w - Second Node ID
|
||||
*/
|
||||
export function addConflict(conflicts: {
|
||||
[nodeId: string | number]: {
|
||||
[nodeId: string | number]: true;
|
||||
};
|
||||
}, v: string | number, w: string | number): void;
|
||||
export function hasConflict(conflicts: any, v: any, w: any): any;
|
||||
export function verticalAlignment(g: any, layering: any, conflicts: any, neighborFn: any): {
|
||||
root: {};
|
||||
align: {};
|
||||
};
|
||||
export function horizontalCompaction(g: any, layering: any, root: any, align: any, reverseSep: any): Record<string, number>;
|
||||
export function alignCoordinates(xss: any, alignTo: any): void;
|
||||
export function findSmallestWidthAlignment(g: any, xss: any): any;
|
||||
export function balance(xss: any, align: any): {
|
||||
[x: string]: any;
|
||||
};
|
||||
1
frontend/node_modules/dagre-d3-es/src/dagre/position/index.d.ts
generated
vendored
Normal file
1
frontend/node_modules/dagre-d3-es/src/dagre/position/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export function position(g: any): void;
|
||||
31
frontend/node_modules/dagre-d3-es/src/dagre/position/index.js
generated
vendored
Normal file
31
frontend/node_modules/dagre-d3-es/src/dagre/position/index.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
import * as _ from 'lodash-es';
|
||||
import * as util from '../util.js';
|
||||
import { positionX } from './bk.js';
|
||||
|
||||
export { position };
|
||||
|
||||
function position(g) {
|
||||
g = util.asNonCompoundGraph(g);
|
||||
|
||||
positionY(g);
|
||||
_.forOwn(positionX(g), function (x, v) {
|
||||
g.node(v).x = x;
|
||||
});
|
||||
}
|
||||
|
||||
function positionY(g) {
|
||||
var layering = util.buildLayerMatrix(g);
|
||||
var rankSep = g.graph().ranksep;
|
||||
var prevY = 0;
|
||||
_.forEach(layering, function (layer) {
|
||||
var maxHeight = _.max(
|
||||
_.map(layer, function (v) {
|
||||
return g.node(v).height;
|
||||
}),
|
||||
);
|
||||
_.forEach(layer, function (v) {
|
||||
g.node(v).y = prevY + maxHeight / 2;
|
||||
});
|
||||
prevY += maxHeight + rankSep;
|
||||
});
|
||||
}
|
||||
87
frontend/node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js
generated
vendored
Normal file
87
frontend/node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
import * as _ from 'lodash-es';
|
||||
import { Graph } from '../../graphlib/index.js';
|
||||
import { slack } from './util.js';
|
||||
|
||||
export { feasibleTree };
|
||||
|
||||
/*
|
||||
* Constructs a spanning tree with tight edges and adjusted the input node's
|
||||
* ranks to achieve this. A tight edge is one that is has a length that matches
|
||||
* its "minlen" attribute.
|
||||
*
|
||||
* The basic structure for this function is derived from Gansner, et al., "A
|
||||
* Technique for Drawing Directed Graphs."
|
||||
*
|
||||
* Pre-conditions:
|
||||
*
|
||||
* 1. Graph must be a DAG.
|
||||
* 2. Graph must be connected.
|
||||
* 3. Graph must have at least one node.
|
||||
* 5. Graph nodes must have been previously assigned a "rank" property that
|
||||
* respects the "minlen" property of incident edges.
|
||||
* 6. Graph edges must have a "minlen" property.
|
||||
*
|
||||
* Post-conditions:
|
||||
*
|
||||
* - Graph nodes will have their rank adjusted to ensure that all edges are
|
||||
* tight.
|
||||
*
|
||||
* Returns a tree (undirected graph) that is constructed using only "tight"
|
||||
* edges.
|
||||
*/
|
||||
function feasibleTree(g) {
|
||||
var t = new Graph({ directed: false });
|
||||
|
||||
// Choose arbitrary node from which to start our tree
|
||||
var start = g.nodes()[0];
|
||||
var size = g.nodeCount();
|
||||
t.setNode(start, {});
|
||||
|
||||
var edge, delta;
|
||||
while (tightTree(t, g) < size) {
|
||||
edge = findMinSlackEdge(t, g);
|
||||
delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge);
|
||||
shiftRanks(t, g, delta);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds a maximal tree of tight edges and returns the number of nodes in the
|
||||
* tree.
|
||||
*/
|
||||
function tightTree(t, g) {
|
||||
function dfs(v) {
|
||||
_.forEach(g.nodeEdges(v), function (e) {
|
||||
var edgeV = e.v,
|
||||
w = v === edgeV ? e.w : edgeV;
|
||||
if (!t.hasNode(w) && !slack(g, e)) {
|
||||
t.setNode(w, {});
|
||||
t.setEdge(v, w, {});
|
||||
dfs(w);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_.forEach(t.nodes(), dfs);
|
||||
return t.nodeCount();
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds the edge with the smallest slack that is incident on tree and returns
|
||||
* it.
|
||||
*/
|
||||
function findMinSlackEdge(t, g) {
|
||||
return _.minBy(g.edges(), function (e) {
|
||||
if (t.hasNode(e.v) !== t.hasNode(e.w)) {
|
||||
return slack(g, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function shiftRanks(t, g, delta) {
|
||||
_.forEach(t.nodes(), function (v) {
|
||||
g.node(v).rank += delta;
|
||||
});
|
||||
}
|
||||
52
frontend/node_modules/dagre-d3-es/src/dagre/rank/index.js
generated
vendored
Normal file
52
frontend/node_modules/dagre-d3-es/src/dagre/rank/index.js
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
import { feasibleTree } from './feasible-tree.js';
|
||||
import { networkSimplex } from './network-simplex.js';
|
||||
import { longestPath } from './util.js';
|
||||
|
||||
export { rank };
|
||||
|
||||
/*
|
||||
* Assigns a rank to each node in the input graph that respects the "minlen"
|
||||
* constraint specified on edges between nodes.
|
||||
*
|
||||
* This basic structure is derived from Gansner, et al., "A Technique for
|
||||
* Drawing Directed Graphs."
|
||||
*
|
||||
* Pre-conditions:
|
||||
*
|
||||
* 1. Graph must be a connected DAG
|
||||
* 2. Graph nodes must be objects
|
||||
* 3. Graph edges must have "weight" and "minlen" attributes
|
||||
*
|
||||
* Post-conditions:
|
||||
*
|
||||
* 1. Graph nodes will have a "rank" attribute based on the results of the
|
||||
* algorithm. Ranks can start at any index (including negative), we'll
|
||||
* fix them up later.
|
||||
*/
|
||||
function rank(g) {
|
||||
switch (g.graph().ranker) {
|
||||
case 'network-simplex':
|
||||
networkSimplexRanker(g);
|
||||
break;
|
||||
case 'tight-tree':
|
||||
tightTreeRanker(g);
|
||||
break;
|
||||
case 'longest-path':
|
||||
longestPathRanker(g);
|
||||
break;
|
||||
default:
|
||||
networkSimplexRanker(g);
|
||||
}
|
||||
}
|
||||
|
||||
// A fast and simple ranker, but results are far from optimal.
|
||||
var longestPathRanker = longestPath;
|
||||
|
||||
function tightTreeRanker(g) {
|
||||
longestPath(g);
|
||||
feasibleTree(g);
|
||||
}
|
||||
|
||||
function networkSimplexRanker(g) {
|
||||
networkSimplex(g);
|
||||
}
|
||||
2
frontend/node_modules/dagre-d3-es/src/dagre/rank/util.d.ts
generated
vendored
Normal file
2
frontend/node_modules/dagre-d3-es/src/dagre/rank/util.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export function longestPath(g: any): void;
|
||||
export function slack(g: any, e: any): number;
|
||||
63
frontend/node_modules/dagre-d3-es/src/dagre/rank/util.js
generated
vendored
Normal file
63
frontend/node_modules/dagre-d3-es/src/dagre/rank/util.js
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
import * as _ from 'lodash-es';
|
||||
|
||||
export { longestPath, slack };
|
||||
|
||||
/*
|
||||
* Initializes ranks for the input graph using the longest path algorithm. This
|
||||
* algorithm scales well and is fast in practice, it yields rather poor
|
||||
* solutions. Nodes are pushed to the lowest layer possible, leaving the bottom
|
||||
* ranks wide and leaving edges longer than necessary. However, due to its
|
||||
* speed, this algorithm is good for getting an initial ranking that can be fed
|
||||
* into other algorithms.
|
||||
*
|
||||
* This algorithm does not normalize layers because it will be used by other
|
||||
* algorithms in most cases. If using this algorithm directly, be sure to
|
||||
* run normalize at the end.
|
||||
*
|
||||
* Pre-conditions:
|
||||
*
|
||||
* 1. Input graph is a DAG.
|
||||
* 2. Input graph node labels can be assigned properties.
|
||||
*
|
||||
* Post-conditions:
|
||||
*
|
||||
* 1. Each node will be assign an (unnormalized) "rank" property.
|
||||
*/
|
||||
function longestPath(g) {
|
||||
var visited = {};
|
||||
|
||||
function dfs(v) {
|
||||
var label = g.node(v);
|
||||
if (Object.prototype.hasOwnProperty.call(visited, v)) {
|
||||
return label.rank;
|
||||
}
|
||||
visited[v] = true;
|
||||
|
||||
var rank = _.min(
|
||||
_.map(g.outEdges(v), function (e) {
|
||||
return dfs(e.w) - g.edge(e).minlen;
|
||||
}),
|
||||
);
|
||||
|
||||
if (
|
||||
rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3
|
||||
rank === undefined || // return value of _.map([]) for Lodash 4
|
||||
rank === null
|
||||
) {
|
||||
// return value of _.map([null])
|
||||
rank = 0;
|
||||
}
|
||||
|
||||
return (label.rank = rank);
|
||||
}
|
||||
|
||||
_.forEach(g.sources(), dfs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the amount of slack for the given edge. The slack is defined as the
|
||||
* difference between the length of the edge and its minimum length.
|
||||
*/
|
||||
function slack(g, e) {
|
||||
return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen;
|
||||
}
|
||||
21
frontend/node_modules/dagre-d3-es/src/dagre/util.d.ts
generated
vendored
Normal file
21
frontend/node_modules/dagre-d3-es/src/dagre/util.d.ts
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
export function addDummyNode(g: any, type: any, attrs: any, name: any): string;
|
||||
export function simplify(g: any): Graph<any, any, any>;
|
||||
export function asNonCompoundGraph(g: any): Graph<any, any, any>;
|
||||
export function successorWeights(g: any): import("lodash").Dictionary<{}>;
|
||||
export function predecessorWeights(g: any): import("lodash").Dictionary<{}>;
|
||||
export function intersectRect(rect: any, point: any): {
|
||||
x: any;
|
||||
y: any;
|
||||
};
|
||||
export function buildLayerMatrix(g: any): any[][];
|
||||
export function normalizeRanks(g: any): void;
|
||||
export function removeEmptyRanks(g: any): void;
|
||||
export function addBorderNode(g: any, prefix: any, rank: any, order: any, ...args: any[]): string;
|
||||
export function maxRank(g: any): any;
|
||||
export function partition(collection: any, fn: any): {
|
||||
lhs: any[];
|
||||
rhs: any[];
|
||||
};
|
||||
export function time(name: any, fn: any): any;
|
||||
export function notime(name: any, fn: any): any;
|
||||
import { Graph } from '../graphlib/index.js';
|
||||
66
frontend/node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.d.ts
generated
vendored
Normal file
66
frontend/node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.d.ts
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
export type PathEntry = {
|
||||
/**
|
||||
* The sum of the weights from `source` to `v`
|
||||
* along the shortest path or `Number.POSITIVE_INFINITY` if there is no path
|
||||
* from `source`.
|
||||
*/
|
||||
distance: number;
|
||||
/**
|
||||
* Can be used to walk the individual
|
||||
* elements of the path from `source` to `v` in reverse order.
|
||||
*/
|
||||
predecessor?: NodeID;
|
||||
};
|
||||
/**
|
||||
* @typedef {Object} PathEntry
|
||||
* @property {number} distance The sum of the weights from `source` to `v`
|
||||
* along the shortest path or `Number.POSITIVE_INFINITY` if there is no path
|
||||
* from `source`.
|
||||
* @property {NodeID} [predecessor] Can be used to walk the individual
|
||||
* elements of the path from `source` to `v` in reverse order.
|
||||
*/
|
||||
/**
|
||||
* This function is an implementation of [Dijkstra's algorithm][] which finds
|
||||
* the shortest path from `source` to all other nodes in `g`. This
|
||||
* function returns
|
||||
*
|
||||
* [Dijkstra's algorithm]: http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* 
|
||||
* <!-- SOURCE:
|
||||
* http://dagrejs.github.io/project/dagre-d3/latest/demo/interactive-demo.html?graph=digraph%20%7B%0Anode%20%5Bshape%3Dcircle%2C%20style%3D%22fill%3Awhite%3Bstroke%3A%23333%3Bstroke-width%3A1.5px%22%5D%0Aedge%20%5Blabeloffset%3D2%20labelpos%3Dr%5D%0Arankdir%3Dlr%0A%20%20A%20-%3E%20B%5Blabel%3D10%5D%0A%20%20A%20-%3E%20C%5Blabel%3D4%5D%0A%20%20A%20-%3E%20D%5Blabel%3D2%5D%0A%20%20C%20-%3E%20B%5Blabel%3D2%5D%0A%20%20C%20-%3E%20D%5Blabel%3D8%5D%0A%20%20B%20-%3E%20E%5Blabel%3D6%5D%0A%20%20D%20-%3E%20F%5Blabel%3D2%5D%0A%20%20F%20-%3E%20E%5Blabel%3D4%5D%0A%7D
|
||||
* -->
|
||||
*
|
||||
* ```js
|
||||
* function weight(e) { return g.edge(e); }
|
||||
*
|
||||
* graphlib.alg.dijkstra(g, "A", weight);
|
||||
* // => { A: { distance: 0 },
|
||||
* // B: { distance: 6, predecessor: 'C' },
|
||||
* // C: { distance: 4, predecessor: 'A' },
|
||||
* // D: { distance: 2, predecessor: 'A' },
|
||||
* // E: { distance: 8, predecessor: 'F' },
|
||||
* // F: { distance: 4, predecessor: 'D' } }
|
||||
* ```
|
||||
*
|
||||
* @remarks It takes `O((|E| + |V|) * log |V|)` time.
|
||||
*
|
||||
* @param {Graph} g - Input graph.
|
||||
* @param {NodeID | number} source - The source node id. Converted to a string.
|
||||
* @param {(e: EdgeObj) => number} [weightFn] - Optional function that returns
|
||||
* the weight for edge `e`. If no `weightFn` is supplied then each edge is
|
||||
* assumed to have a weight of 1.
|
||||
* @param {(v: NodeID) => EdgeObj[]} [edgeFn] - Optional function that returns
|
||||
* the ids of all edges incident to the node `v` for the purposes of shortest
|
||||
* path traversal.
|
||||
* By default this function uses the {@link Graph.outEdges} function on the
|
||||
* supplied graph.
|
||||
* @returns {Record<NodeID, PathEntry>} a map of `v -> { distance, predecessor }`.
|
||||
* @throws {Error} If any of the traversed edges has a negative edge weight.
|
||||
*/
|
||||
export function dijkstra(g: Graph, source: NodeID | number, weightFn?: (e: EdgeObj) => number, edgeFn?: (v: NodeID) => EdgeObj[]): Record<NodeID, PathEntry>;
|
||||
import type { NodeID } from '../graph.js';
|
||||
import type { Graph } from '../graph.js';
|
||||
import type { EdgeObj } from '../graph.js';
|
||||
43
frontend/node_modules/dagre-d3-es/src/graphlib/alg/find-cycles.d.ts
generated
vendored
Normal file
43
frontend/node_modules/dagre-d3-es/src/graphlib/alg/find-cycles.d.ts
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Given a Graph, `g`, this function returns all nodes that
|
||||
* are part of a cycle. As there may be more than one cycle in a graph this
|
||||
* function return an array of these cycles, where each cycle is itself
|
||||
* represented by an array of ids for each node involved in that cycle.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* {@link isAcyclic} is more efficient if you only need to
|
||||
* determine whether a graph has a cycle or not.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```js
|
||||
* var g = new graphlib.Graph();
|
||||
* g.setNode(1);
|
||||
* g.setNode(2);
|
||||
* g.setNode(3);
|
||||
* g.setEdge(1, 2);
|
||||
* g.setEdge(2, 3);
|
||||
*
|
||||
* graphlib.alg.findCycles(g);
|
||||
* // => []
|
||||
*
|
||||
* g.setEdge(3, 1);
|
||||
* graphlib.alg.findCycles(g);
|
||||
* // => [ [ '3', '2', '1' ] ]
|
||||
*
|
||||
* g.setNode(4);
|
||||
* g.setNode(5);
|
||||
* g.setEdge(4, 5);
|
||||
* g.setEdge(5, 4);
|
||||
* graphlib.alg.findCycles(g);
|
||||
* // => [ [ '3', '2', '1' ], [ '5', '4' ] ]
|
||||
* ```
|
||||
*
|
||||
* @param {Graph} g - The graph to analyze.
|
||||
* @returns {NodeID[][]} An array of cycles. Each cycle is itself an array
|
||||
* that contains the ids of all nodes in the cycle.
|
||||
*/
|
||||
export function findCycles(g: Graph): NodeID[][];
|
||||
import type { Graph } from '../graph.js';
|
||||
import type { NodeID } from '../graph.js';
|
||||
57
frontend/node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.d.ts
generated
vendored
Normal file
57
frontend/node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.d.ts
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* This function is an implementation of the [Floyd-Warshall algorithm][],
|
||||
* which finds the shortest path from each node to every other reachable node
|
||||
* in the graph. It is similar to {@link dijkstraAll}, but
|
||||
* it handles negative edge weights and is more efficient for some types of
|
||||
* graphs.
|
||||
*
|
||||
* [Floyd-Warshall algorithm]: https://en.wikipedia.org/wiki/Floyd-Warshall_algorithm
|
||||
*
|
||||
* @remarks This algorithm takes `O(|V|^3)` time.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* 
|
||||
*
|
||||
* ```js
|
||||
* function weight(e) { return g.edge(e); }
|
||||
*
|
||||
* graphlib.alg.floydWarshall(g, function(e) { return g.edge(e); });
|
||||
*
|
||||
* // => { A:
|
||||
* // { A: { distance: 0 },
|
||||
* // B: { distance: 6, predecessor: 'C' },
|
||||
* // C: { distance: 4, predecessor: 'A' },
|
||||
* // D: { distance: 2, predecessor: 'A' },
|
||||
* // E: { distance: 8, predecessor: 'F' },
|
||||
* // F: { distance: 4, predecessor: 'D' } },
|
||||
* // B:
|
||||
* // { A: { distance: Infinity },
|
||||
* // B: { distance: 0 },
|
||||
* // C: { distance: Infinity },
|
||||
* // D: { distance: Infinity },
|
||||
* // E: { distance: 6, predecessor: 'B' },
|
||||
* // F: { distance: Infinity } },
|
||||
* // C: { ... },
|
||||
* // D: { ... },
|
||||
* // E: { ... },
|
||||
* // F: { ... } }
|
||||
* ```
|
||||
*
|
||||
* @param {Graph} g - The graph to analyze.
|
||||
* @param {(e: EdgeObj) => number} [weightFn] - Optional function that returns
|
||||
* the weight for edge `e`. If no `weightFn` is supplied then each edge is
|
||||
* assumed to have a weight of 1.
|
||||
* @param {(v: NodeID) => EdgeObj[]} [edgeFn] - Optional function that returns
|
||||
* the ids of all edges incident to the node `v` for the purposes of shortest
|
||||
* path traversal.
|
||||
* By default this function uses the {@link Graph.outEdges} function on the
|
||||
* supplied graph.
|
||||
* @returns {Record<NodeID, Record<NodeID, PathEntry>>} a map of
|
||||
* `source -> { target -> { distance, predecessor }`.
|
||||
*/
|
||||
export function floydWarshall(g: Graph, weightFn?: (e: EdgeObj) => number, edgeFn?: (v: NodeID) => EdgeObj[]): Record<NodeID, Record<NodeID, PathEntry>>;
|
||||
import type { Graph } from '../graph.js';
|
||||
import type { EdgeObj } from '../graph.js';
|
||||
import type { NodeID } from '../graph.js';
|
||||
import type { PathEntry } from './dijkstra.js';
|
||||
31
frontend/node_modules/dagre-d3-es/src/graphlib/alg/postorder.js
generated
vendored
Normal file
31
frontend/node_modules/dagre-d3-es/src/graphlib/alg/postorder.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
import { dfs } from './dfs.js';
|
||||
|
||||
export { postorder };
|
||||
|
||||
/**
|
||||
* This function performs a [postorder traversal][] of the graph `g` starting
|
||||
* at the nodes `vs`. For each node visited, `v`, the function `callback(v)`
|
||||
* is called.
|
||||
*
|
||||
* [postorder traversal]: https://en.wikipedia.org/wiki/Tree_traversal#Depth-first
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* 
|
||||
*
|
||||
* ```js
|
||||
* graphlib.alg.postorder(g, "A");
|
||||
* // => One of:
|
||||
* // [ "B", "D", "E", C", "A" ]
|
||||
* // [ "B", "E", "D", C", "A" ]
|
||||
* // [ "D", "E", "C", B", "A" ]
|
||||
* // [ "E", "D", "C", B", "A" ]
|
||||
* ```
|
||||
*
|
||||
* @param {Parameters<typeof dfs>[0]} g - The graph to traverse.
|
||||
* @param {Parameters<typeof dfs>[1]} vs - Nodes to start the traversal from.
|
||||
* @returns {ReturnType<typeof dfs>} The nodes in the order they were visited.
|
||||
*/
|
||||
function postorder(g, vs) {
|
||||
return dfs(g, vs, 'post');
|
||||
}
|
||||
118
frontend/node_modules/dagre-d3-es/src/graphlib/alg/prim.js
generated
vendored
Normal file
118
frontend/node_modules/dagre-d3-es/src/graphlib/alg/prim.js
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
import * as _ from 'lodash-es';
|
||||
import { PriorityQueue } from '../data/priority-queue.js';
|
||||
import { Graph } from '../graph.js';
|
||||
|
||||
/**
|
||||
* @import { EdgeObj, NodeID } from '../graph.js';
|
||||
*/
|
||||
|
||||
export { prim };
|
||||
|
||||
/**
|
||||
* [Prim's algorithm][] takes a connected undirected graph and generates a
|
||||
* [minimum spanning tree][]. This function returns the minimum spanning
|
||||
* tree as an undirected graph. This algorithm is derived from the description
|
||||
* in "Introduction to Algorithms", Third Edition, Cormen, et al., Pg 634.
|
||||
*
|
||||
* [Prim's algorithm]: https://en.wikipedia.org/wiki/Prim's_algorithm
|
||||
* [minimum spanning tree]: https://en.wikipedia.org/wiki/Minimum_spanning_tree
|
||||
*
|
||||
* @remarks This function takes `O(|E| log |V|)` time.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* 
|
||||
* <!-- SOURCE:
|
||||
* digraph {
|
||||
* node [shape=circle, style="fill:white;stroke:#333;stroke-width:1.5px"]
|
||||
* edge [labeloffset=2 labelpos=r arrowhead="none"]
|
||||
* rankdir=lr
|
||||
* A -> B [label=3]
|
||||
* A -> D [label=12]
|
||||
* B -> C [label=6]
|
||||
* B -> D [label=1]
|
||||
* C -> D [label=1]
|
||||
* D -> E [label=2]
|
||||
* C -> E [label=9]
|
||||
* }
|
||||
* -->
|
||||
*
|
||||
* ```js
|
||||
* function weight(e) { return g(e); }
|
||||
* graphlib.alg.prim(g, weight);
|
||||
* ```
|
||||
*
|
||||
* Returns a tree (represented as a Graph) of the following form:
|
||||
*
|
||||
* 
|
||||
* <!-- SOURCE:
|
||||
* digraph {
|
||||
* node [shape=circle, style="fill:white;stroke:#333;stroke-width:1.5px"]
|
||||
* edge [labeloffset=2 labelpos=r arrowhead="none"]
|
||||
* rankdir=lr
|
||||
* A -> B
|
||||
* B -> D
|
||||
* C -> D
|
||||
* D -> E
|
||||
* }
|
||||
* -->
|
||||
*
|
||||
* @param {Graph} g - The input undirected connected graph.
|
||||
* @param {(e: EdgeObj) => number} weightFunc - Function that returns
|
||||
* the weight for edge `e`.
|
||||
* @returns {Graph<undefined, undefined, undefined>} The minimum spanning tree
|
||||
* as an undirected graph.
|
||||
* @throws {Error} If the input graph is not connected.
|
||||
*/
|
||||
function prim(g, weightFunc) {
|
||||
var result = new Graph();
|
||||
/** @type {Record<NodeID, NodeID>} */
|
||||
var parents = {};
|
||||
var pq = new PriorityQueue();
|
||||
/** @type {NodeID} */
|
||||
var v;
|
||||
|
||||
/**
|
||||
* @param {EdgeObj} edge - Edge to examine for possible inclusion in the
|
||||
* minimum spanning tree.
|
||||
*/
|
||||
function updateNeighbors(edge) {
|
||||
var w = edge.v === v ? edge.w : edge.v;
|
||||
var pri = pq.priority(w);
|
||||
if (pri !== undefined) {
|
||||
var edgeWeight = weightFunc(edge);
|
||||
if (edgeWeight < pri) {
|
||||
parents[w] = v;
|
||||
pq.decrease(w, edgeWeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g.nodeCount() === 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
_.each(g.nodes(), function (v) {
|
||||
pq.add(v, Number.POSITIVE_INFINITY);
|
||||
result.setNode(v);
|
||||
});
|
||||
|
||||
// Start from an arbitrary node
|
||||
pq.decrease(g.nodes()[0], 0);
|
||||
|
||||
var init = false;
|
||||
while (pq.size() > 0) {
|
||||
v = pq.removeMin();
|
||||
if (Object.prototype.hasOwnProperty.call(parents, v)) {
|
||||
result.setEdge(v, parents[v]);
|
||||
} else if (init) {
|
||||
throw new Error('Input graph is not connected: ' + g);
|
||||
} else {
|
||||
init = true;
|
||||
}
|
||||
|
||||
g.nodeEdges(v).forEach(updateNeighbors);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
44
frontend/node_modules/dagre-d3-es/src/graphlib/alg/tarjan.d.ts
generated
vendored
Normal file
44
frontend/node_modules/dagre-d3-es/src/graphlib/alg/tarjan.d.ts
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* This function is an implementation of [Tarjan's algorithm][] which finds
|
||||
* all [strongly connected components][] in the directed graph `g`. Each
|
||||
* strongly connected component is composed of nodes that can reach all other
|
||||
* nodes in the component via directed edges. A strongly connected component
|
||||
* can consist of a single node if that node cannot both reach and be reached
|
||||
* by any other specific node in the graph. Components of more than one node
|
||||
* are guaranteed to have at least one cycle.
|
||||
*
|
||||
* [Tarjan's algorithm]: http://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm
|
||||
* [strongly connected components]: http://en.wikipedia.org/wiki/Strongly_connected_component
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* 
|
||||
* <!-- SOURCE:
|
||||
* digraph {
|
||||
* node [shape=circle, style="fill:white;stroke:#333;stroke-width:1.5px"]
|
||||
* edge [lineInterpolate=bundle]
|
||||
* rankdir=lr
|
||||
*
|
||||
* A -> B -> C -> D -> H -> G -> F
|
||||
* F -> G
|
||||
* D -> C
|
||||
* H -> D
|
||||
* B -> E -> G
|
||||
* E -> A
|
||||
* }
|
||||
* -->
|
||||
*
|
||||
* ```js
|
||||
* graphlib.alg.tarjan(g);
|
||||
* // => [ [ 'F', 'G' ],
|
||||
* // [ 'H', 'D', 'C' ],
|
||||
* // [ 'E', 'B', 'A' ] ]
|
||||
* ```
|
||||
*
|
||||
* @param {Graph} g - The directed graph to analyze.
|
||||
* @returns {NodeID[][]} an array of components. Each component is itself an
|
||||
* array that contains the ids of all nodes in the component.
|
||||
*/
|
||||
export function tarjan(g: Graph): NodeID[][];
|
||||
import type { Graph } from '../graph.js';
|
||||
import type { NodeID } from '../graph.js';
|
||||
100
frontend/node_modules/dagre-d3-es/src/graphlib/alg/tarjan.js
generated
vendored
Normal file
100
frontend/node_modules/dagre-d3-es/src/graphlib/alg/tarjan.js
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* @import { Graph, NodeID } from '../graph.js';
|
||||
*/
|
||||
|
||||
export { tarjan };
|
||||
|
||||
/**
|
||||
* This function is an implementation of [Tarjan's algorithm][] which finds
|
||||
* all [strongly connected components][] in the directed graph `g`. Each
|
||||
* strongly connected component is composed of nodes that can reach all other
|
||||
* nodes in the component via directed edges. A strongly connected component
|
||||
* can consist of a single node if that node cannot both reach and be reached
|
||||
* by any other specific node in the graph. Components of more than one node
|
||||
* are guaranteed to have at least one cycle.
|
||||
*
|
||||
* [Tarjan's algorithm]: http://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm
|
||||
* [strongly connected components]: http://en.wikipedia.org/wiki/Strongly_connected_component
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* 
|
||||
* <!-- SOURCE:
|
||||
* digraph {
|
||||
* node [shape=circle, style="fill:white;stroke:#333;stroke-width:1.5px"]
|
||||
* edge [lineInterpolate=bundle]
|
||||
* rankdir=lr
|
||||
*
|
||||
* A -> B -> C -> D -> H -> G -> F
|
||||
* F -> G
|
||||
* D -> C
|
||||
* H -> D
|
||||
* B -> E -> G
|
||||
* E -> A
|
||||
* }
|
||||
* -->
|
||||
*
|
||||
* ```js
|
||||
* graphlib.alg.tarjan(g);
|
||||
* // => [ [ 'F', 'G' ],
|
||||
* // [ 'H', 'D', 'C' ],
|
||||
* // [ 'E', 'B', 'A' ] ]
|
||||
* ```
|
||||
*
|
||||
* @param {Graph} g - The directed graph to analyze.
|
||||
* @returns {NodeID[][]} an array of components. Each component is itself an
|
||||
* array that contains the ids of all nodes in the component.
|
||||
*/
|
||||
function tarjan(g) {
|
||||
var index = 0;
|
||||
/** @type {NodeID[]} */
|
||||
var stack = [];
|
||||
/**
|
||||
* @type {Record<NodeID, { onStack: boolean, lowlink: number, index: number }>}
|
||||
*/
|
||||
var visited = {};
|
||||
/** @type {NodeID[][]} */
|
||||
var results = [];
|
||||
|
||||
/**
|
||||
* @param {NodeID} v - Node to recursively visit
|
||||
*/
|
||||
function dfs(v) {
|
||||
var entry = (visited[v] = {
|
||||
onStack: true,
|
||||
lowlink: index,
|
||||
index: index++,
|
||||
});
|
||||
stack.push(v);
|
||||
|
||||
g.successors(v).forEach(function (w) {
|
||||
if (!Object.prototype.hasOwnProperty.call(visited, w)) {
|
||||
dfs(w);
|
||||
entry.lowlink = Math.min(entry.lowlink, visited[w].lowlink);
|
||||
} else if (visited[w].onStack) {
|
||||
entry.lowlink = Math.min(entry.lowlink, visited[w].index);
|
||||
}
|
||||
});
|
||||
|
||||
if (entry.lowlink === entry.index) {
|
||||
/** @type {NodeID[]} */
|
||||
var cmpt = [];
|
||||
/** @type {NodeID} */
|
||||
var w;
|
||||
do {
|
||||
w = stack.pop();
|
||||
visited[w].onStack = false;
|
||||
cmpt.push(w);
|
||||
} while (v !== w);
|
||||
results.push(cmpt);
|
||||
}
|
||||
}
|
||||
|
||||
g.nodes().forEach(function (v) {
|
||||
if (!Object.prototype.hasOwnProperty.call(visited, v)) {
|
||||
dfs(v);
|
||||
}
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
179
frontend/node_modules/dagre-d3-es/src/graphlib/data/priority-queue.js
generated
vendored
Normal file
179
frontend/node_modules/dagre-d3-es/src/graphlib/data/priority-queue.js
generated
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
export { PriorityQueue };
|
||||
|
||||
/**
|
||||
* A min-priority queue data structure. This algorithm is derived from Cormen,
|
||||
* et al., "Introduction to Algorithms". The basic idea of a min-priority
|
||||
* queue is that you can efficiently (in O(1) time) get the smallest key in
|
||||
* the queue. Adding and removing elements takes O(log n) time. A key can
|
||||
* have its priority decreased in O(log n) time.
|
||||
*/
|
||||
class PriorityQueue {
|
||||
constructor() {
|
||||
/**
|
||||
* @private
|
||||
* @type {Array<{key: string, priority: number}>}
|
||||
*/
|
||||
this._arr = [];
|
||||
/**
|
||||
* @private
|
||||
* @type {Record<string, number>}
|
||||
*/
|
||||
this._keyIndices = {};
|
||||
}
|
||||
/**
|
||||
* @returns {number} the number of elements in the queue.
|
||||
* @remarks Takes `O(1)` time.
|
||||
*/
|
||||
size() {
|
||||
return this._arr.length;
|
||||
}
|
||||
/**
|
||||
* @returns {string[]} the keys that are in the queue.
|
||||
* @remarks Takes `O(n)` time.
|
||||
*/
|
||||
keys() {
|
||||
return this._arr.map(function (x) {
|
||||
return x.key;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @param {Object} key - The key to check for presence in the queue.
|
||||
* @returns {boolean} `true` if **key** is in the queue and `false` if not.
|
||||
*/
|
||||
has(key) {
|
||||
return Object.prototype.hasOwnProperty.call(this._keyIndices, key);
|
||||
}
|
||||
/**
|
||||
* @param {Object} key - The key to get the priority for.
|
||||
* @returns {number | undefined} the priority for **key**.
|
||||
* If **key** is not present in the queue then this function returns `undefined`.
|
||||
* @remarks Takes `O(1)` time.
|
||||
*/
|
||||
priority(key) {
|
||||
var index = this._keyIndices[key];
|
||||
if (index !== undefined) {
|
||||
return this._arr[index].priority;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @returns {string} the key for the minimum element in this queue.
|
||||
* @throws {Error} if the queue is empty.
|
||||
* @remarks Takes `O(1)` time.
|
||||
*/
|
||||
min() {
|
||||
if (this.size() === 0) {
|
||||
throw new Error('Queue underflow');
|
||||
}
|
||||
return this._arr[0].key;
|
||||
}
|
||||
/**
|
||||
* Inserts a new key into the priority queue.
|
||||
*
|
||||
* @remarks Takes `O(n)` time.
|
||||
*
|
||||
* @param {Object} key the key to add. This will be coerced to a `string`.
|
||||
* @param {Number} priority the initial priority for the key
|
||||
* @returns {boolean} `true` if the key was added and `false` if it was already
|
||||
* present in the queue.
|
||||
*/
|
||||
add(key, priority) {
|
||||
var keyIndices = this._keyIndices;
|
||||
key = String(key);
|
||||
if (!Object.prototype.hasOwnProperty.call(keyIndices, key)) {
|
||||
var arr = this._arr;
|
||||
var index = arr.length;
|
||||
keyIndices[key] = index;
|
||||
arr.push({ key: key, priority: priority });
|
||||
this._decrease(index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Removes and returns the smallest key in the queue.
|
||||
* @returns {string} the key with the smallest priority
|
||||
* @remarks Takes `O(log n)` time.
|
||||
*/
|
||||
removeMin() {
|
||||
this._swap(0, this._arr.length - 1);
|
||||
var min = this._arr.pop();
|
||||
delete this._keyIndices[min.key];
|
||||
this._heapify(0);
|
||||
return min.key;
|
||||
}
|
||||
/**
|
||||
* Decreases the priority for **key** to **priority**.
|
||||
*
|
||||
* @param {Object} key the key for which to raise priority
|
||||
* @param {Number} priority the new priority for the key
|
||||
* @throws {Error} if the new priority is greater than the previous priority.
|
||||
*/
|
||||
decrease(key, priority) {
|
||||
var index = this._keyIndices[key];
|
||||
if (priority > this._arr[index].priority) {
|
||||
throw new Error(
|
||||
'New priority is greater than current priority. ' +
|
||||
'Key: ' +
|
||||
key +
|
||||
' Old: ' +
|
||||
this._arr[index].priority +
|
||||
' New: ' +
|
||||
priority,
|
||||
);
|
||||
}
|
||||
this._arr[index].priority = priority;
|
||||
this._decrease(index);
|
||||
}
|
||||
/**
|
||||
* @param {number} i - Lower index.
|
||||
* @private
|
||||
*/
|
||||
_heapify(i) {
|
||||
var arr = this._arr;
|
||||
var l = 2 * i;
|
||||
var r = l + 1;
|
||||
var largest = i;
|
||||
if (l < arr.length) {
|
||||
largest = arr[l].priority < arr[largest].priority ? l : largest;
|
||||
if (r < arr.length) {
|
||||
largest = arr[r].priority < arr[largest].priority ? r : largest;
|
||||
}
|
||||
if (largest !== i) {
|
||||
this._swap(i, largest);
|
||||
this._heapify(largest);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {number} index - Index to decrease.
|
||||
* @private
|
||||
*/
|
||||
_decrease(index) {
|
||||
var arr = this._arr;
|
||||
var priority = arr[index].priority;
|
||||
var parent;
|
||||
while (index !== 0) {
|
||||
parent = index >> 1;
|
||||
if (arr[parent].priority < priority) {
|
||||
break;
|
||||
}
|
||||
this._swap(index, parent);
|
||||
index = parent;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {number} i - First index
|
||||
* @param {number} j - Second index
|
||||
* @private
|
||||
*/
|
||||
_swap(i, j) {
|
||||
var arr = this._arr;
|
||||
var keyIndices = this._keyIndices;
|
||||
var origArrI = arr[i];
|
||||
var origArrJ = arr[j];
|
||||
arr[i] = origArrJ;
|
||||
arr[j] = origArrI;
|
||||
keyIndices[origArrJ.key] = i;
|
||||
keyIndices[origArrI.key] = j;
|
||||
}
|
||||
}
|
||||
717
frontend/node_modules/dagre-d3-es/src/graphlib/graph.d.ts
generated
vendored
Normal file
717
frontend/node_modules/dagre-d3-es/src/graphlib/graph.d.ts
generated
vendored
Normal file
@@ -0,0 +1,717 @@
|
||||
/**
|
||||
* @typedef {string} NodeID ID of a node.
|
||||
*/
|
||||
/**
|
||||
* @typedef {`${string}${typeof EDGE_KEY_DELIM}${string}${typeof EDGE_KEY_DELIM}${string}`} EdgeID ID of an edge.
|
||||
* @internal - All public APIs use {@link EdgeObj} instead to refer to edges.
|
||||
*/
|
||||
/**
|
||||
* @typedef {object} EdgeObj
|
||||
* @property {NodeID} v the id of the source or tail node of an edge
|
||||
* @property {NodeID} w the id of the target or head node of an edge
|
||||
* @property {string | number} [name] Name of the edge. Needed to uniquely identify
|
||||
* multiple edges between the same pair of nodes in a multigraph.
|
||||
*/
|
||||
/**
|
||||
* @template {unknown} T
|
||||
* @typedef {T[] | Record<any, T>} Collection
|
||||
* Lodash object that can be iterated over with `_.each`.
|
||||
*
|
||||
* Beware, objects with `.length` are treated as arrays, see
|
||||
* https://lodash.com/docs/4.17.15#forEach
|
||||
*/
|
||||
/**
|
||||
* @typedef {object} GraphOptions
|
||||
* @property {boolean | undefined} [directed] - set to `true` to get a
|
||||
* directed graph and `false` to get an undirected graph.
|
||||
* An undirected graph does not treat the order of nodes in an edge as
|
||||
* significant.
|
||||
* In other words, `g.edge("a", "b") === g.edge("b", "a")` for
|
||||
* an undirected graph.
|
||||
* Default: `true`
|
||||
* @property {boolean | undefined} [multigraph] - set to `true` to allow a
|
||||
* graph to have multiple edges between the same pair of nodes.
|
||||
* Default: `false`.
|
||||
* @property {boolean | undefined} [compound] - set to `true` to allow a
|
||||
* graph to have compound nodes - nodes which can be the parent of other
|
||||
* nodes.
|
||||
* Default: `false`.
|
||||
*/
|
||||
/**
|
||||
* Graphlib has a single graph type: {@link Graph}. To create a new instance:
|
||||
*
|
||||
* ```js
|
||||
* var g = new Graph();
|
||||
* ```
|
||||
*
|
||||
* By default this will create a directed graph that does not allow multi-edges
|
||||
* or compound nodes.
|
||||
* The following options can be used when constructing a new graph:
|
||||
*
|
||||
* * {@link GraphOptions#directed}: set to `true` to get a directed graph and `false` to get an
|
||||
* undirected graph.
|
||||
* An undirected graph does not treat the order of nodes in an edge as
|
||||
* significant. In other words,
|
||||
* `g.edge("a", "b") === g.edge("b", "a")` for an undirected graph.
|
||||
* Default: `true`.
|
||||
* * {@link GraphOptions#multigraph}: set to `true` to allow a graph to have multiple edges
|
||||
* between the same pair of nodes. Default: `false`.
|
||||
* * {@link GraphOptions#compound}: set to `true` to allow a graph to have compound nodes -
|
||||
* nodes which can be the parent of other nodes. Default: `false`.
|
||||
*
|
||||
* To set the options, pass in an options object to the `Graph` constructor.
|
||||
* For example, to create a directed compound multigraph:
|
||||
*
|
||||
* ```js
|
||||
* var g = new Graph({ directed: true, compound: true, multigraph: true });
|
||||
* ```
|
||||
*
|
||||
* ### Node and Edge Representation
|
||||
*
|
||||
* In graphlib, a node is represented by a user-supplied String id.
|
||||
* All node related functions use this String id as a way to uniquely identify
|
||||
* the node. Here is an example of interacting with nodes:
|
||||
*
|
||||
* ```js
|
||||
* var g = new Graph();
|
||||
* g.setNode("my-id", "my-label");
|
||||
* g.node("my-id"); // returns "my-label"
|
||||
* ```
|
||||
*
|
||||
* Edges in graphlib are identified by the nodes they connect. For example:
|
||||
*
|
||||
* ```js
|
||||
* var g = new Graph();
|
||||
* g.setEdge("source", "target", "my-label");
|
||||
* g.edge("source", "target"); // returns "my-label"
|
||||
* ```
|
||||
*
|
||||
* However, we need a way to uniquely identify an edge in a single object for
|
||||
* various edge queries (e.g. {@link Graph#outEdges}).
|
||||
* We use {@link EdgeObj}s for this purpose.
|
||||
* They consist of the following properties:
|
||||
*
|
||||
* * {@link EdgeObj#v}: the id of the source or tail node of an edge
|
||||
* * {@link EdgeObj#w}: the id of the target or head node of an edge
|
||||
* * {@link EdgeObj#name} (optional): the name that uniquely identifies a multiedge.
|
||||
*
|
||||
* Any edge function that takes an edge id will also work with an {@link EdgeObj}. For example:
|
||||
*
|
||||
* ```js
|
||||
* var g = new Graph();
|
||||
* g.setEdge("source", "target", "my-label");
|
||||
* g.edge({ v: "source", w: "target" }); // returns "my-label"
|
||||
* ```
|
||||
*
|
||||
* ### Multigraphs
|
||||
*
|
||||
* A [multigraph](https://en.wikipedia.org/wiki/Multigraph) is a graph that can
|
||||
* have more than one edge between the same pair of nodes.
|
||||
* By default graphlib graphs are not multigraphs, but a multigraph can be
|
||||
* constructed by setting the {@link GraphOptions#multigraph} property to true:
|
||||
*
|
||||
* ```js
|
||||
* var g = new Graph({ multigraph: true });
|
||||
* ```
|
||||
*
|
||||
* With multiple edges between two nodes we need some way to uniquely identify
|
||||
* each edge. We call this the {@link EdgeObj#name} property.
|
||||
* Here's an example of creating a couple of edges between the same nodes:
|
||||
*
|
||||
* ```js
|
||||
* var g = new Graph({ multigraph: true });
|
||||
* g.setEdge("a", "b", "edge1-label", "edge1");
|
||||
* g.setEdge("a", "b", "edge2-label", "edge2");
|
||||
* g.edge("a", "b", "edge1"); // returns "edge1-label"
|
||||
* g.edge("a", "b", "edge2"); // returns "edge2-label"
|
||||
* g.edges(); // returns [{ v: "a", w: "b", name: "edge1" },
|
||||
* // { v: "a", w: "b", name: "edge2" }]
|
||||
* ```
|
||||
*
|
||||
* A multigraph still allows an edge with no name to be created:
|
||||
*
|
||||
* ```js
|
||||
* var g = new Graph({ multigraph: true });
|
||||
* g.setEdge("a", "b", "my-label");
|
||||
* g.edge({ v: "a", w: "b" }); // returns "my-label"
|
||||
* ```
|
||||
*
|
||||
* ### Compound Graphs
|
||||
*
|
||||
* A compound graph is one where a node can be the parent of other nodes.
|
||||
* The child nodes form a "subgraph".
|
||||
* Here's an example of constructing and interacting with a compound graph:
|
||||
*
|
||||
* ```js
|
||||
* var g = new Graph({ compound: true });
|
||||
* g.setParent("a", "parent");
|
||||
* g.setParent("b", "parent");
|
||||
* g.parent("a"); // returns "parent"
|
||||
* g.parent("b"); // returns "parent"
|
||||
* g.parent("parent"); // returns undefined
|
||||
* ```
|
||||
*
|
||||
* ### Default Labels
|
||||
*
|
||||
* When a node or edge is created without a label, a default label can be assigned.
|
||||
* See {@link setDefaultNodeLabel} and {@link setDefaultEdgeLabel}.
|
||||
*
|
||||
* @template [GraphLabel=any] - Label of the graph.
|
||||
* @template [NodeLabel=any] - Label of a node.
|
||||
* Even though this is a "label", this could be any type that the user requires
|
||||
* (and may need to be an object for some layout/ranking algorithms in dagre).
|
||||
* @template [EdgeLabel=any] - Label of an edge.
|
||||
* Even though this is a "label", this could be any type that the user requires,
|
||||
* (and may need to be a object for ranking in dagre).
|
||||
*/
|
||||
export class Graph<GraphLabel = any, NodeLabel = any, EdgeLabel = any> {
|
||||
/**
|
||||
* @param {GraphOptions} [opts] - Graph options.
|
||||
*/
|
||||
constructor(opts?: GraphOptions);
|
||||
/**
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
private _isDirected;
|
||||
/**
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
private _isMultigraph;
|
||||
/**
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
private _isCompound;
|
||||
/**
|
||||
* @type {GraphLabel | undefined}
|
||||
* Label for the graph itself
|
||||
*/
|
||||
_label: GraphLabel | undefined;
|
||||
/**
|
||||
* Default label to be set when creating a new node.
|
||||
*
|
||||
* @private
|
||||
* @type {(v: NodeID | number) => NodeLabel}
|
||||
*/
|
||||
private _defaultNodeLabelFn;
|
||||
/**
|
||||
* Default label to be set when creating a new edge
|
||||
*
|
||||
* @private
|
||||
* @type {(v: NodeID, w: NodeID, name: string | undefined) => EdgeLabel}
|
||||
*/
|
||||
private _defaultEdgeLabelFn;
|
||||
/**
|
||||
* @type {Record<NodeID, NodeLabel>}
|
||||
* @private
|
||||
*
|
||||
* v -> label
|
||||
*/
|
||||
private _nodes;
|
||||
/**
|
||||
* @type {Record<NodeID, NodeID>}
|
||||
* @private
|
||||
* v -> parent
|
||||
*/
|
||||
private _parent;
|
||||
/**
|
||||
* @type {Record<NodeID, Record<NodeID, true>>}
|
||||
* @private
|
||||
* v -> children
|
||||
*/
|
||||
private _children;
|
||||
/**
|
||||
* @type {Record<NodeID, Record<EdgeID, EdgeObj>>}
|
||||
* @private
|
||||
* v -> edgeObj
|
||||
*/
|
||||
private _in;
|
||||
/**
|
||||
* @type {Record<NodeID, Record<NodeID, number>>}
|
||||
* @private
|
||||
* u -> v -> Number
|
||||
*/
|
||||
private _preds;
|
||||
/**
|
||||
* @type {Record<NodeID, Record<EdgeID, EdgeObj>>}
|
||||
* @private
|
||||
* v -> edgeObj
|
||||
*/
|
||||
private _out;
|
||||
/**
|
||||
* @type {Record<NodeID, Record<NodeID, number>>}
|
||||
* @private
|
||||
* v -> w -> Number
|
||||
*/
|
||||
private _sucs;
|
||||
/**
|
||||
* @type {Record<EdgeID, EdgeObj>}
|
||||
* @private
|
||||
* e -> edgeObj
|
||||
*/
|
||||
private _edgeObjs;
|
||||
/**
|
||||
* @type {Record<EdgeID, EdgeLabel>}
|
||||
* @private
|
||||
* e -> label
|
||||
*/
|
||||
private _edgeLabels;
|
||||
/**
|
||||
*
|
||||
* @returns {boolean} `true` if the graph is [directed](https://en.wikipedia.org/wiki/Directed_graph).
|
||||
* A directed graph treats the order of nodes in an edge as significant whereas an
|
||||
* [undirected](https://en.wikipedia.org/wiki/Graph_(mathematics)#Undirected_graph)
|
||||
* graph does not.
|
||||
* This example demonstrates the difference:
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```js
|
||||
* var directed = new Graph({ directed: true });
|
||||
* directed.setEdge("a", "b", "my-label");
|
||||
* directed.edge("a", "b"); // returns "my-label"
|
||||
* directed.edge("b", "a"); // returns undefined
|
||||
*
|
||||
* var undirected = new Graph({ directed: false });
|
||||
* undirected.setEdge("a", "b", "my-label");
|
||||
* undirected.edge("a", "b"); // returns "my-label"
|
||||
* undirected.edge("b", "a"); // returns "my-label"
|
||||
* ```
|
||||
*/
|
||||
isDirected(): boolean;
|
||||
/**
|
||||
* @returns {boolean} `true` if the graph is a multigraph.
|
||||
*/
|
||||
isMultigraph(): boolean;
|
||||
/**
|
||||
* @returns {boolean} `true` if the graph is compound.
|
||||
*/
|
||||
isCompound(): boolean;
|
||||
/**
|
||||
* Sets the label for the graph to `label`.
|
||||
*
|
||||
* @param {GraphLabel} label - Label for the graph.
|
||||
* @returns {this}
|
||||
*/
|
||||
setGraph(label: GraphLabel): this;
|
||||
/**
|
||||
* @returns {GraphLabel | undefined} the currently assigned label for the graph.
|
||||
* If no label has been assigned, returns `undefined`.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```js
|
||||
* var g = new Graph();
|
||||
* g.graph(); // returns undefined
|
||||
* g.setGraph("graph-label");
|
||||
* g.graph(); // returns "graph-label"
|
||||
* ```
|
||||
*/
|
||||
graph(): GraphLabel | undefined;
|
||||
/**
|
||||
* Sets a new default value that is assigned to nodes that are created without
|
||||
* a label.
|
||||
*
|
||||
* @param {typeof this._defaultNodeLabelFn | NodeLabel} newDefault - If a function,
|
||||
* it is called with the id of the node being created.
|
||||
* Otherwise, it is assigned as the label directly.
|
||||
* @returns {this}
|
||||
*/
|
||||
setDefaultNodeLabel(newDefault: typeof this._defaultNodeLabelFn | NodeLabel): this;
|
||||
/**
|
||||
* @returns {number} the number of nodes in the graph.
|
||||
*/
|
||||
nodeCount(): number;
|
||||
/**
|
||||
* @returns {NodeID[]} the ids of the nodes in the graph.
|
||||
*
|
||||
* @remarks
|
||||
* Use {@link node()} to get the label for each node.
|
||||
* Takes `O(|V|)` time.
|
||||
*/
|
||||
nodes(): NodeID[];
|
||||
/**
|
||||
* @returns {NodeID[]} those nodes in the graph that have no in-edges.
|
||||
* @remarks Takes `O(|V|)` time.
|
||||
*/
|
||||
sources(): NodeID[];
|
||||
/**
|
||||
* @returns {NodeID[]} those nodes in the graph that have no out-edges.
|
||||
* @remarks Takes `O(|V|)` time.
|
||||
*/
|
||||
sinks(): NodeID[];
|
||||
/**
|
||||
* Invokes setNode method for each node in `vs` list.
|
||||
*
|
||||
* @param {Collection<NodeID | number>} vs - List of node IDs to create/set.
|
||||
* @param {NodeLabel} [value] - If set, update all nodes with this value.
|
||||
* @returns {this}
|
||||
* @remarks Complexity: O(|names|).
|
||||
*/
|
||||
setNodes(vs: Collection<NodeID | number>, value?: NodeLabel, ...args: any[]): this;
|
||||
/**
|
||||
* Creates or updates the value for the node `v` in the graph.
|
||||
*
|
||||
* @param {NodeID | number} v - ID of the node to create/set.
|
||||
* @param {NodeLabel} [value] - If supplied, it is set as the value for the node.
|
||||
* If not supplied and the node was created by this call then
|
||||
* {@link setDefaultNodeLabel} will be used to set the node's value.
|
||||
* @returns {this} the graph, allowing this to be chained with other functions.
|
||||
* @remarks Takes `O(1)` time.
|
||||
*/
|
||||
setNode(v: NodeID | number, value?: NodeLabel, ...args: any[]): this;
|
||||
/**
|
||||
* Gets the label of node with specified name.
|
||||
*
|
||||
* @param {NodeID | number} v - Node ID.
|
||||
* @returns {NodeLabel | undefined} the label assigned to the node with the id `v`
|
||||
* if it is in the graph.
|
||||
* Otherwise returns `undefined`.
|
||||
* @remarks Takes `O(1)` time.
|
||||
*/
|
||||
node(v: NodeID | number): NodeLabel | undefined;
|
||||
/**
|
||||
* Detects whether graph has a node with specified name or not.
|
||||
*
|
||||
* @param {NodeID | number} v - Node ID.
|
||||
* @returns {boolean} Returns `true` the graph has a node with the id.
|
||||
* @remarks Takes `O(1)` time.
|
||||
*/
|
||||
hasNode(v: NodeID | number): boolean;
|
||||
/**
|
||||
* Remove the node with the id `v` in the graph or do nothing if the node is
|
||||
* not in the graph.
|
||||
*
|
||||
* If the node was removed this function also removes any incident edges.
|
||||
*
|
||||
* @param {NodeID | number} v - Node ID to remove.
|
||||
* @returns {this} the graph, allowing this to be chained with other functions.
|
||||
* @remarks Takes `O(|E|)` time.
|
||||
*/
|
||||
removeNode(v: NodeID | number): this;
|
||||
/**
|
||||
* Sets the parent for `v` to `parent` if it is defined or removes the parent
|
||||
* for `v` if `parent` is undefined.
|
||||
*
|
||||
* @param {NodeID | number} v - Node ID to set the parent for.
|
||||
* @param {NodeID | number} [parent] - Parent node ID. If not defined, removes the parent.
|
||||
* @returns {this} the graph, allowing this to be chained with other functions.
|
||||
* @throws if the graph is not compound.
|
||||
* @throws if setting the parent would create a cycle.
|
||||
* @remarks Takes `O(1)` time.
|
||||
*/
|
||||
setParent(v: NodeID | number, parent?: NodeID | number): this;
|
||||
/**
|
||||
* @private
|
||||
* @param {NodeID | number} v - Node ID.
|
||||
*/
|
||||
private _removeFromParentsChildList;
|
||||
/**
|
||||
* Get parent node for node `v`.
|
||||
*
|
||||
* @param {NodeID | number} v - Node ID.
|
||||
* @returns {NodeID | undefined} the node that is a parent of node `v`
|
||||
* or `undefined` if node `v` does not have a parent or is not a member of
|
||||
* the graph.
|
||||
* Always returns `undefined` for graphs that are not compound.
|
||||
* @remarks Takes `O(1)` time.
|
||||
*/
|
||||
parent(v: NodeID | number): NodeID | undefined;
|
||||
/**
|
||||
* Gets list of direct children of node v.
|
||||
*
|
||||
* @param {NodeID | number} [v] - Node ID. If not specified, gets nodes
|
||||
* with no parent (top-level nodes).
|
||||
* @returns {NodeID[] | undefined} all nodes that are children of node `v` or
|
||||
* `undefined` if node `v` is not in the graph.
|
||||
* Always returns `[]` for graphs that are not compound.
|
||||
* @remarks Takes `O(|V|)` time.
|
||||
*/
|
||||
children(v?: NodeID | number): NodeID[] | undefined;
|
||||
/**
|
||||
* @param {NodeID | number} v - Node ID.
|
||||
* @returns {NodeID[] | undefined} all nodes that are predecessors of the
|
||||
* specified node or `undefined` if node `v` is not in the graph.
|
||||
* @remarks
|
||||
* Behavior is undefined for undirected graphs - use {@link neighbors} instead.
|
||||
* Takes `O(|V|)` time.
|
||||
*/
|
||||
predecessors(v: NodeID | number): NodeID[] | undefined;
|
||||
/**
|
||||
* @param {NodeID | number} v - Node ID.
|
||||
* @returns {NodeID[] | undefined} all nodes that are successors of the
|
||||
* specified node or `undefined` if node `v` is not in the graph.
|
||||
* @remarks
|
||||
* Behavior is undefined for undirected graphs - use {@link neighbors} instead.
|
||||
* Takes `O(|V|)` time.
|
||||
*/
|
||||
successors(v: NodeID | number): NodeID[] | undefined;
|
||||
/**
|
||||
* @param {NodeID | number} v - Node ID.
|
||||
* @returns {NodeID[] | undefined} all nodes that are predecessors or
|
||||
* successors of the specified node
|
||||
* or `undefined` if node `v` is not in the graph.
|
||||
* @remarks Takes `O(|V|)` time.
|
||||
*/
|
||||
neighbors(v: NodeID | number): NodeID[] | undefined;
|
||||
/**
|
||||
* @param {NodeID | number} v - Node ID.
|
||||
* @returns {boolean} True if the node is a leaf (has no successors), false otherwise.
|
||||
*/
|
||||
isLeaf(v: NodeID | number): boolean;
|
||||
/**
|
||||
* Creates new graph with nodes filtered via `filter`.
|
||||
* Edges incident to rejected node
|
||||
* are also removed.
|
||||
*
|
||||
* In case of compound graph, if parent is rejected by `filter`,
|
||||
* than all its children are rejected too.
|
||||
|
||||
* @param {(v: NodeID) => boolean} filter - Function that returns `true` for nodes to keep.
|
||||
* @returns {Graph<GraphLabel, NodeLabel, EdgeLabel>} A new graph containing only the nodes for which `filter` returns `true`.
|
||||
* @remarks Average-case complexity: O(|E|+|V|).
|
||||
*/
|
||||
filterNodes(filter: (v: NodeID) => boolean): Graph<GraphLabel, NodeLabel, EdgeLabel>;
|
||||
/**
|
||||
* Sets a new default value that is assigned to edges that are created without
|
||||
* a label.
|
||||
*
|
||||
* @param {typeof this._defaultEdgeLabelFn | EdgeLabel} newDefault - If a function,
|
||||
* it is called with the parameters `(v, w, name)`.
|
||||
* Otherwise, it is assigned as the label directly.
|
||||
* @returns {this}
|
||||
*/
|
||||
setDefaultEdgeLabel(newDefault: typeof this._defaultEdgeLabelFn | EdgeLabel): this;
|
||||
/**
|
||||
* @returns {number} the number of edges in the graph.
|
||||
* @remarks Complexity: O(1).
|
||||
*/
|
||||
edgeCount(): number;
|
||||
/**
|
||||
* Gets edges of the graph.
|
||||
*
|
||||
* @returns {EdgeObj[]} the {@link EdgeObj} for each edge in the graph.
|
||||
*
|
||||
* @remarks
|
||||
* In case of compound graph subgraphs are not considered.
|
||||
* Use {@link edge()} to get the label for each edge.
|
||||
* Takes `O(|E|)` time.
|
||||
*/
|
||||
edges(): EdgeObj[];
|
||||
/**
|
||||
* Establish an edges path over the nodes in nodes list.
|
||||
*
|
||||
* If some edge is already exists, it will update its label, otherwise it will
|
||||
* create an edge between pair of nodes with label provided or default label
|
||||
* if no label provided.
|
||||
*
|
||||
* @param {Collection<NodeID>} vs - List of node IDs to create edges between.
|
||||
* @param {EdgeLabel} [value] - If set, update all edges with this value.
|
||||
* @returns {this}
|
||||
* @remarks Complexity: O(|nodes|).
|
||||
*/
|
||||
setPath(vs: Collection<NodeID>, value?: EdgeLabel, ...args: any[]): this;
|
||||
/**
|
||||
* Creates or updates the label for the edge (`v`, `w`) with the optionally
|
||||
* supplied `name`.
|
||||
*
|
||||
* @overload
|
||||
* @param {EdgeObj} arg0 - Edge object.
|
||||
* @param {EdgeLabel} [value] - If supplied, it is set as the label for the edge.
|
||||
* If not supplied and the edge was created by this call then
|
||||
* {@link setDefaultEdgeLabel} will be used to assign the edge's label.
|
||||
* @returns {this} the graph, allowing this to be chained with other functions.
|
||||
* @remarks Takes `O(1)` time.
|
||||
*/
|
||||
setEdge(arg0: EdgeObj, value?: EdgeLabel): this;
|
||||
/**
|
||||
* Creates or updates the label for the edge (`v`, `w`) with the optionally
|
||||
* supplied `name`.
|
||||
*
|
||||
* @overload
|
||||
* @param {NodeID | number} v - Source node ID. Number values will be coerced to strings.
|
||||
* @param {NodeID | number} w - Target node ID. Number values will be coerced to strings.
|
||||
* @param {EdgeLabel} [value] - If supplied, it is set as the label for the edge.
|
||||
* If not supplied and the edge was created by this call then
|
||||
* {@link setDefaultEdgeLabel} will be used to assign the edge's label.
|
||||
* @param {string | number} [name] - Edge name. Only useful with multigraphs.
|
||||
* @returns {this} the graph, allowing this to be chained with other functions.
|
||||
* @remarks Takes `O(1)` time.
|
||||
*/
|
||||
setEdge(v: NodeID | number, w: NodeID | number, value?: EdgeLabel, name?: string | number): this;
|
||||
/**
|
||||
* Gets the label for the specified edge.
|
||||
*
|
||||
* @overload
|
||||
* @param {EdgeObj} v - Edge object.
|
||||
* @returns {EdgeLabel | undefined} the label for the edge (`v`, `w`) if the
|
||||
* graph has an edge between `v` and `w` with the optional `name`.
|
||||
* Returned `undefined` if there is no such edge in the graph.
|
||||
* @remarks
|
||||
* `v` and `w` can be interchanged for undirected graphs.
|
||||
* Takes `O(1)` time.
|
||||
*/
|
||||
edge(v: EdgeObj): EdgeLabel | undefined;
|
||||
/**
|
||||
* Gets the label for the specified edge.
|
||||
*
|
||||
* @overload
|
||||
* @param {NodeID | number} v - Source node ID.
|
||||
* @param {NodeID | number} w - Target node ID.
|
||||
* @param {string | number} [name] - Edge name. Only useful with multigraphs.
|
||||
* @returns {EdgeLabel | undefined} the label for the edge (`v`, `w`) if the
|
||||
* graph has an edge between `v` and `w` with the optional `name`.
|
||||
* Returned `undefined` if there is no such edge in the graph.
|
||||
* @remarks
|
||||
* `v` and `w` can be interchanged for undirected graphs.
|
||||
* Takes `O(1)` time.
|
||||
*/
|
||||
edge(v: NodeID | number, w: NodeID | number, name?: string | number): EdgeLabel | undefined;
|
||||
/**
|
||||
* Detects whether the graph contains specified edge or not.
|
||||
*
|
||||
* @overload
|
||||
* @param {EdgeObj} v - Edge object.
|
||||
* @returns {boolean} `true` if the graph has an edge between `v` and `w`
|
||||
* with the optional `name`.
|
||||
* @remarks
|
||||
* `v` and `w` can be interchanged for undirected graphs.
|
||||
* No subgraphs are considered.
|
||||
* Takes `O(1)` time.
|
||||
*/
|
||||
hasEdge(v: EdgeObj): boolean;
|
||||
/**
|
||||
* Detects whether the graph contains specified edge or not.
|
||||
*
|
||||
* @overload
|
||||
* @param {NodeID | number} v - Source node ID.
|
||||
* @param {NodeID | number} w - Target node ID.
|
||||
* @param {string | number} [name] - Edge name. Only useful with multigraphs.
|
||||
* @returns {boolean} `true` if the graph has an edge between `v` and `w`
|
||||
* with the optional `name`.
|
||||
* @remarks
|
||||
* `v` and `w` can be interchanged for undirected graphs.
|
||||
* No subgraphs are considered.
|
||||
* Takes `O(1)` time.
|
||||
*/
|
||||
hasEdge(v: NodeID | number, w: NodeID | number, name?: string | number): boolean;
|
||||
/**
|
||||
* Removes the edge (`v`, `w`) if the graph has an edge between `v` and `w`
|
||||
* with the optional `name`. If not this function does nothing.
|
||||
*
|
||||
* @overload
|
||||
* @param {EdgeObj} v - Edge object.
|
||||
* @returns {this}
|
||||
* @remarks
|
||||
* `v` and `w` can be interchanged for undirected graphs.
|
||||
* No subgraphs are considered.
|
||||
* Takes `O(1)` time.
|
||||
*/
|
||||
removeEdge(v: EdgeObj): this;
|
||||
/**
|
||||
* Removes the edge (`v`, `w`) if the graph has an edge between `v` and `w`
|
||||
* with the optional `name`. If not this function does nothing.
|
||||
*
|
||||
* @overload
|
||||
* @param {NodeID | number} v - Source node ID.
|
||||
* @param {NodeID | number} w - Target node ID.
|
||||
* @param {string | number} [name] - Edge name. Only useful with multigraphs.
|
||||
* @returns {this}
|
||||
* @remarks
|
||||
* `v` and `w` can be interchanged for undirected graphs.
|
||||
* Takes `O(1)` time.
|
||||
*/
|
||||
removeEdge(v: NodeID | number, w: NodeID | number, name?: string | number): this;
|
||||
/**
|
||||
* @param {NodeID | number} v - Target node ID.
|
||||
* @param {NodeID | number} [u] - Optionally filters edges down to just those
|
||||
* coming from node `u`.
|
||||
* @returns {EdgeObj[] | undefined} all edges that point to the node `v`.
|
||||
* Returns `undefined` if node `v` is not in the graph.
|
||||
* @remarks
|
||||
* Behavior is undefined for undirected graphs - use {@link nodeEdges} instead.
|
||||
* Takes `O(|E|)` time.
|
||||
*/
|
||||
inEdges(v: NodeID | number, u?: NodeID | number): EdgeObj[] | undefined;
|
||||
/**
|
||||
* @param {NodeID | number} v - Target node ID.
|
||||
* @param {NodeID | number} [w] - Optionally filters edges down to just those
|
||||
* that point to `w`.
|
||||
* @returns {EdgeObj[] | undefined} all edges that point to the node `v`.
|
||||
* Returns `undefined` if node `v` is not in the graph.
|
||||
* @remarks
|
||||
* Behavior is undefined for undirected graphs - use {@link nodeEdges} instead.
|
||||
* Takes `O(|E|)` time.
|
||||
*/
|
||||
outEdges(v: NodeID | number, w?: NodeID | number): EdgeObj[] | undefined;
|
||||
/**
|
||||
* @param {NodeID | number} v - Target Node ID.
|
||||
* @param {NodeID | number} [w] - If set, filters those edges down to just
|
||||
* those between nodes `v` and `w` regardless of direction
|
||||
* @returns {EdgeObj[] | undefined} all edges to or from node `v` regardless
|
||||
* of direction. Returns `undefined` if node `v` is not in the graph.
|
||||
* @remarks Takes `O(|E|)` time.
|
||||
*/
|
||||
nodeEdges(v: NodeID | number, w?: NodeID | number): EdgeObj[] | undefined;
|
||||
_nodeCount: number;
|
||||
_edgeCount: number;
|
||||
}
|
||||
/**
|
||||
* ID of a node.
|
||||
*/
|
||||
export type NodeID = string;
|
||||
/**
|
||||
* ID of an edge.
|
||||
*/
|
||||
export type EdgeID = `${string}${typeof EDGE_KEY_DELIM}${string}${typeof EDGE_KEY_DELIM}${string}`;
|
||||
export type EdgeObj = {
|
||||
/**
|
||||
* the id of the source or tail node of an edge
|
||||
*/
|
||||
v: NodeID;
|
||||
/**
|
||||
* the id of the target or head node of an edge
|
||||
*/
|
||||
w: NodeID;
|
||||
/**
|
||||
* Name of the edge. Needed to uniquely identify
|
||||
* multiple edges between the same pair of nodes in a multigraph.
|
||||
*/
|
||||
name?: string | number;
|
||||
};
|
||||
/**
|
||||
* Lodash object that can be iterated over with `_.each`.
|
||||
*
|
||||
* Beware, objects with `.length` are treated as arrays, see
|
||||
* https://lodash.com/docs/4.17.15#forEach
|
||||
*/
|
||||
export type Collection<T extends unknown> = T[] | Record<any, T>;
|
||||
export type GraphOptions = {
|
||||
/**
|
||||
* - set to `true` to get a
|
||||
* directed graph and `false` to get an undirected graph.
|
||||
* An undirected graph does not treat the order of nodes in an edge as
|
||||
* significant.
|
||||
* In other words, `g.edge("a", "b") === g.edge("b", "a")` for
|
||||
* an undirected graph.
|
||||
* Default: `true`
|
||||
*/
|
||||
directed?: boolean | undefined;
|
||||
/**
|
||||
* - set to `true` to allow a
|
||||
* graph to have multiple edges between the same pair of nodes.
|
||||
* Default: `false`.
|
||||
*/
|
||||
multigraph?: boolean | undefined;
|
||||
/**
|
||||
* - set to `true` to allow a
|
||||
* graph to have compound nodes - nodes which can be the parent of other
|
||||
* nodes.
|
||||
* Default: `false`.
|
||||
*/
|
||||
compound?: boolean | undefined;
|
||||
};
|
||||
declare var EDGE_KEY_DELIM: string;
|
||||
export {};
|
||||
1165
frontend/node_modules/dagre-d3-es/src/graphlib/graph.js
generated
vendored
Normal file
1165
frontend/node_modules/dagre-d3-es/src/graphlib/graph.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
frontend/node_modules/dagre-d3-es/src/graphlib/index.js
generated
vendored
Normal file
7
frontend/node_modules/dagre-d3-es/src/graphlib/index.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// Includes only the "core" of graphlib
|
||||
|
||||
import { Graph } from './graph.js';
|
||||
|
||||
const version = '2.1.9-pre';
|
||||
|
||||
export { Graph, version };
|
||||
104
frontend/node_modules/dagre-d3-es/src/graphlib/json.d.ts
generated
vendored
Normal file
104
frontend/node_modules/dagre-d3-es/src/graphlib/json.d.ts
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
export type GraphJSON<GraphLabel = any, NodeLabel = any, EdgeLabel = any> = {
|
||||
/**
|
||||
* - The options used to create the graph.
|
||||
*/
|
||||
options: Required<GraphOptions>;
|
||||
/**
|
||||
* - The nodes in the graph.
|
||||
*/
|
||||
nodes: Array<{
|
||||
v: NodeID;
|
||||
value?: NodeLabel;
|
||||
parent?: NodeID;
|
||||
}>;
|
||||
/**
|
||||
* - The edges in the graph.
|
||||
*/
|
||||
edges: Array<EdgeObj & {
|
||||
value?: EdgeLabel;
|
||||
}>;
|
||||
/**
|
||||
* - The graph's value, if any.
|
||||
*/
|
||||
value?: GraphLabel;
|
||||
};
|
||||
/**
|
||||
* @template [GraphLabel=any] - Label of the graph.
|
||||
* @template [NodeLabel=any] - Label of a node.
|
||||
* @template [EdgeLabel=any] - Label of an edge.
|
||||
*
|
||||
* @typedef {object} GraphJSON
|
||||
* @property {Required<GraphOptions>} options - The options used to create the graph.
|
||||
* @property {Array<{ v: NodeID; value?: NodeLabel; parent?: NodeID }>} nodes - The nodes in the graph.
|
||||
* @property {Array<EdgeObj & { value?: EdgeLabel }>} edges - The edges in the graph.
|
||||
* @property {GraphLabel} [value] - The graph's value, if any.
|
||||
*/
|
||||
/**
|
||||
* Creates a JSON representation of the graph that can be serialized to a
|
||||
* string with
|
||||
* [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify).
|
||||
* The graph can later be restored using {@link read}.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```js
|
||||
* var g = new graphlib.Graph();
|
||||
* g.setNode("a", { label: "node a" });
|
||||
* g.setNode("b", { label: "node b" });
|
||||
* g.setEdge("a", "b", { label: "edge a->b" });
|
||||
* graphlib.json.write(g);
|
||||
* // Returns the object:
|
||||
* //
|
||||
* // {
|
||||
* // "options": {
|
||||
* // "directed": true,
|
||||
* // "multigraph": false,
|
||||
* // "compound": false
|
||||
* // },
|
||||
* // "nodes": [
|
||||
* // { "v": "a", "value": { "label": "node a" } },
|
||||
* // { "v": "b", "value": { "label": "node b" } }
|
||||
* // ],
|
||||
* // "edges": [
|
||||
* // { "v": "a", "w": "b", "value": { "label": "edge a->b" } }
|
||||
* // ]
|
||||
* // }
|
||||
* ```
|
||||
*
|
||||
* @template [GraphLabel=any] - Label of the graph.
|
||||
* @template [NodeLabel=any] - Label of a node.
|
||||
* @template [EdgeLabel=any] - Label of an edge.
|
||||
* @param {Graph<GraphLabel, NodeLabel, EdgeLabel>} g - The graph to serialize.
|
||||
* @returns {GraphJSON<GraphLabel, NodeLabel, EdgeLabel>} The JSON representation of the graph.
|
||||
*/
|
||||
export function write<GraphLabel = any, NodeLabel = any, EdgeLabel = any>(g: Graph<GraphLabel, NodeLabel, EdgeLabel>): GraphJSON<GraphLabel, NodeLabel, EdgeLabel>;
|
||||
/**
|
||||
* Takes JSON as input and returns the graph representation.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* For example, if we have serialized the graph in {@link write}
|
||||
* to a string named `str`, we can restore it to a graph as follows:
|
||||
*
|
||||
* ```js
|
||||
* var g2 = graphlib.json.read(JSON.parse(str));
|
||||
* // or, in order to copy the graph
|
||||
* var g3 = graphlib.json.read(graphlib.json.write(g))
|
||||
*
|
||||
* g2.nodes();
|
||||
* // ['a', 'b']
|
||||
* g2.edges()
|
||||
* // [ { v: 'a', w: 'b' } ]
|
||||
* ```
|
||||
*
|
||||
* @template [GraphLabel=any] - Label of the graph.
|
||||
* @template [NodeLabel=any] - Label of a node.
|
||||
* @template [EdgeLabel=any] - Label of an edge.
|
||||
* @param {GraphJSON<GraphLabel, NodeLabel, EdgeLabel>} json - The JSON representation of the graph.
|
||||
* @returns {Graph<GraphLabel, NodeLabel, EdgeLabel>} The restored graph.
|
||||
*/
|
||||
export function read<GraphLabel = any, NodeLabel = any, EdgeLabel = any>(json: GraphJSON<GraphLabel, NodeLabel, EdgeLabel>): Graph<GraphLabel, NodeLabel, EdgeLabel>;
|
||||
import type { GraphOptions } from './graph.js';
|
||||
import type { NodeID } from './graph.js';
|
||||
import type { EdgeObj } from './graph.js';
|
||||
import { Graph } from './graph.js';
|
||||
6
frontend/node_modules/dagre-d3-es/src/index.js
generated
vendored
Normal file
6
frontend/node_modules/dagre-d3-es/src/index.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import { render } from './dagre-js/render.js';
|
||||
import * as graphlib from './graphlib/index.js';
|
||||
|
||||
import * as intersect from './dagre-js/intersect/index.js';
|
||||
|
||||
export { graphlib, intersect, render };
|
||||
Reference in New Issue
Block a user