- Go backend (server/)
- Frontend (web/, server/static/)
- Database and deployment files
- Scripts and docs
Co-Authored-By: 狸花猫/Claude-Qwen3.6-Plus 🐾
668 lines
20 KiB
JavaScript
668 lines
20 KiB
JavaScript
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
||
|
||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
||
|
||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||
|
||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
||
|
||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
||
|
||
import { edgeArgsToId, isFunction } from '../util';
|
||
import { GraphEnum } from './enum';
|
||
import { decrementOrRemoveEntry, edgeArgsToObj, edgeObjToId, incrementOrInitEntry } from '../util';
|
||
import { read, write } from './toJSON';
|
||
var defaultOption = {
|
||
compound: false,
|
||
multigraph: false,
|
||
directed: true
|
||
};
|
||
|
||
var Graph = /*#__PURE__*/function () {
|
||
// Graph option or basic props
|
||
|
||
/**
|
||
* @description Label for this graph itself
|
||
* @description.zh-CN 图本身的标签(label)
|
||
* @default undefined
|
||
*/
|
||
|
||
/**
|
||
* @description Number of nodes in the graph
|
||
* @description.zh-CN 节点的数量
|
||
* @default 0
|
||
*/
|
||
|
||
/**
|
||
* @description Number of edges in the graph
|
||
* @description.zh-CN 节点的数量
|
||
* @default 0
|
||
*/
|
||
|
||
/**
|
||
* @description return node label with its id
|
||
* @description.zh-CN 返回节点的默认的标签
|
||
*/
|
||
|
||
/**
|
||
* @description return edge label with its id
|
||
* @description.zh-CN 返回边的默认的标签
|
||
*/
|
||
function Graph() {
|
||
var _this = this;
|
||
|
||
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
||
|
||
_classCallCheck(this, Graph);
|
||
|
||
this.directed = true;
|
||
this.multigraph = false;
|
||
this.compound = false;
|
||
this.GRAPH_NODE = GraphEnum.GRAPH_NODE;
|
||
this.label = void 0;
|
||
this.nodeCountNum = 0;
|
||
this.edgeCountNum = 0;
|
||
|
||
this.defaultNodeLabelFn = function () {
|
||
return undefined;
|
||
};
|
||
|
||
this.defaultEdgeLabelFn = function () {
|
||
return undefined;
|
||
};
|
||
|
||
this.parentMap = void 0;
|
||
this.childrenMap = void 0;
|
||
this.nodesLabelMap = new Map();
|
||
this.inEdgesMap = new Map();
|
||
this.outEdgesMap = new Map();
|
||
this.predecessorsMap = new Map();
|
||
this.successorsMap = new Map();
|
||
this.edgesMap = new Map();
|
||
this.edgesLabelsMap = new Map();
|
||
|
||
this.isDirected = function () {
|
||
return _this.directed;
|
||
};
|
||
|
||
this.isMultigraph = function () {
|
||
return _this.multigraph;
|
||
};
|
||
|
||
this.isCompound = function () {
|
||
return _this.compound;
|
||
};
|
||
|
||
this.setGraph = function (label) {
|
||
_this.label = label;
|
||
return _this;
|
||
};
|
||
|
||
this.graph = function () {
|
||
return _this.label;
|
||
};
|
||
|
||
this.setDefaultNodeLabel = function (newDefault) {
|
||
if (isFunction(newDefault)) {
|
||
_this.defaultNodeLabelFn = newDefault;
|
||
} else {
|
||
_this.defaultNodeLabelFn = function () {
|
||
return newDefault;
|
||
};
|
||
}
|
||
|
||
return _this;
|
||
};
|
||
|
||
this.nodeCount = function () {
|
||
return _this.nodeCountNum;
|
||
};
|
||
|
||
this.node = function (n) {
|
||
return _this.nodesLabelMap.get(n);
|
||
};
|
||
|
||
this.nodes = function () {
|
||
return Array.from(_this.nodesLabelMap.keys());
|
||
};
|
||
|
||
this.sources = function () {
|
||
return _this.nodes().filter(function (n) {
|
||
var _this$inEdgesMap$get;
|
||
|
||
return !((_this$inEdgesMap$get = _this.inEdgesMap.get(n)) === null || _this$inEdgesMap$get === void 0 ? void 0 : _this$inEdgesMap$get.size);
|
||
});
|
||
};
|
||
|
||
this.sinks = function () {
|
||
return _this.nodes().filter(function (n) {
|
||
var _this$outEdgesMap$get;
|
||
|
||
return !((_this$outEdgesMap$get = _this.outEdgesMap.get(n)) === null || _this$outEdgesMap$get === void 0 ? void 0 : _this$outEdgesMap$get.size);
|
||
});
|
||
};
|
||
|
||
this.setNodes = function (nodes, value) {
|
||
nodes.map(function (node) {
|
||
return _this.setNode(node, value);
|
||
});
|
||
return _this;
|
||
};
|
||
|
||
this.hasNode = function (node) {
|
||
return _this.nodesLabelMap.has(node);
|
||
};
|
||
|
||
this.checkCompound = function () {
|
||
if (!_this.isCompound()) {
|
||
throw new Error('Cannot construct parent-children relations in a non-compound graph');
|
||
}
|
||
};
|
||
|
||
this.parent = function (node) {
|
||
if (_this.isCompound()) {
|
||
var _this$parentMap;
|
||
|
||
var parent = (_this$parentMap = _this.parentMap) === null || _this$parentMap === void 0 ? void 0 : _this$parentMap.get(node);
|
||
|
||
if (parent !== _this.GRAPH_NODE) {
|
||
return parent;
|
||
}
|
||
}
|
||
};
|
||
|
||
this.removeFromParentsChildList = function (node) {
|
||
var targetParent = _this.parentMap.get(node);
|
||
|
||
_this.childrenMap.get(targetParent).delete(node);
|
||
};
|
||
|
||
this.setParent = function (node, parent) {
|
||
var _this$parentMap2, _this$childrenMap;
|
||
|
||
_this.checkCompound();
|
||
|
||
var realParent = parent === undefined ? _this.GRAPH_NODE : parent;
|
||
|
||
var checkNode = _this.parent(realParent);
|
||
|
||
while (checkNode) {
|
||
if (node === checkNode) {
|
||
throw new Error('Setting ' + parent + ' as parent of ' + node + ' would create a cycle');
|
||
}
|
||
|
||
checkNode = _this.parent(checkNode);
|
||
}
|
||
|
||
if (parent) {
|
||
_this.setNode(parent);
|
||
}
|
||
|
||
_this.setNode(node);
|
||
|
||
_this.removeFromParentsChildList(node);
|
||
|
||
(_this$parentMap2 = _this.parentMap) === null || _this$parentMap2 === void 0 ? void 0 : _this$parentMap2.set(node, realParent);
|
||
|
||
var realParentChilren = _this.childrenMap.get(realParent);
|
||
|
||
realParentChilren.set(node, true);
|
||
(_this$childrenMap = _this.childrenMap) === null || _this$childrenMap === void 0 ? void 0 : _this$childrenMap.set(realParent, realParentChilren);
|
||
return _this;
|
||
};
|
||
|
||
this.children = function (node) {
|
||
var targetNode = node === undefined ? _this.GRAPH_NODE : node;
|
||
|
||
if (_this.isCompound()) {
|
||
var _this$childrenMap2;
|
||
|
||
var target = (_this$childrenMap2 = _this.childrenMap) === null || _this$childrenMap2 === void 0 ? void 0 : _this$childrenMap2.get(targetNode);
|
||
|
||
if (target) {
|
||
return Array.from(target.keys());
|
||
}
|
||
|
||
return undefined;
|
||
}
|
||
|
||
if (targetNode === _this.GRAPH_NODE) {
|
||
return _this.nodes();
|
||
}
|
||
|
||
if (node && _this.hasNode(node)) {
|
||
return [];
|
||
}
|
||
};
|
||
|
||
this.predecessors = function (node) {
|
||
var preds = _this.predecessorsMap.get(node);
|
||
|
||
return preds ? Array.from(preds.keys()) : undefined;
|
||
};
|
||
|
||
this.successors = function (node) {
|
||
var succs = _this.successorsMap.get(node);
|
||
|
||
return succs ? Array.from(succs.keys()) : undefined;
|
||
};
|
||
|
||
this.neighbors = function (node) {
|
||
var _this$predecessors;
|
||
|
||
if (!_this.hasNode(node)) {
|
||
return undefined;
|
||
}
|
||
|
||
return Array.from(new Set((_this$predecessors = _this.predecessors(node)) === null || _this$predecessors === void 0 ? void 0 : _this$predecessors.concat(_this.successors(node))));
|
||
};
|
||
|
||
this.isLeaf = function (node) {
|
||
var _this$neighbors;
|
||
|
||
if (_this.isDirected()) {
|
||
var _this$successors;
|
||
|
||
return !((_this$successors = _this.successors(node)) === null || _this$successors === void 0 ? void 0 : _this$successors.length);
|
||
}
|
||
|
||
return !((_this$neighbors = _this.neighbors(node)) === null || _this$neighbors === void 0 ? void 0 : _this$neighbors.length);
|
||
};
|
||
|
||
this.filterNodes = function (filter) {
|
||
var directed = _this.directed,
|
||
multigraph = _this.multigraph,
|
||
compound = _this.compound;
|
||
var copyGraph = new Graph({
|
||
directed: directed,
|
||
multigraph: multigraph,
|
||
compound: compound
|
||
});
|
||
copyGraph.setGraph(_this.graph());
|
||
|
||
_this.nodes().forEach(function (n) {
|
||
if (filter(n)) {
|
||
copyGraph.setNode(n, _this.node(n));
|
||
}
|
||
});
|
||
|
||
_this.edges().forEach(function (edgeObj) {
|
||
if (copyGraph.hasNode(edgeObj.v) && copyGraph.hasNode(edgeObj.w)) {
|
||
copyGraph.setEdgeObj(edgeObj, _this.edge(edgeObj));
|
||
}
|
||
});
|
||
|
||
if (compound) {
|
||
var findParent = function findParent(node) {
|
||
var parent = _this.parent(node);
|
||
|
||
while (parent !== undefined && !copyGraph.hasNode(parent)) {
|
||
parent = _this.parent(parent);
|
||
}
|
||
|
||
return parent;
|
||
};
|
||
|
||
copyGraph.nodes().forEach(function (node) {
|
||
copyGraph.setParent(node, findParent(node));
|
||
});
|
||
}
|
||
|
||
return copyGraph;
|
||
};
|
||
|
||
this.setDefaultEdgeLabel = function (newDefault) {
|
||
if (isFunction(newDefault)) {
|
||
_this.defaultEdgeLabelFn = newDefault;
|
||
} else {
|
||
_this.defaultEdgeLabelFn = function () {
|
||
return newDefault;
|
||
};
|
||
}
|
||
|
||
return _this;
|
||
};
|
||
|
||
this.edgeCount = function () {
|
||
return _this.edgeCountNum;
|
||
};
|
||
|
||
this.setEdgeObj = function (edgeObj, value) {
|
||
return _this.setEdge(edgeObj.v, edgeObj.w, value, edgeObj.name);
|
||
};
|
||
|
||
this.setPath = function (edges, value) {
|
||
edges.reduce(function (v, w) {
|
||
_this.setEdge(v, w, value);
|
||
|
||
return w;
|
||
});
|
||
return _this;
|
||
};
|
||
|
||
this.edgeFromArgs = function (v, w, name) {
|
||
return _this.edge({
|
||
v: v,
|
||
w: w,
|
||
name: name
|
||
});
|
||
};
|
||
|
||
this.edge = function (edgeObj) {
|
||
return _this.edgesLabelsMap.get(edgeObjToId(_this.isDirected(), edgeObj));
|
||
};
|
||
|
||
this.hasEdge = function (v, w, name) {
|
||
return _this.edgesLabelsMap.has(edgeObjToId(_this.isDirected(), {
|
||
v: v,
|
||
w: w,
|
||
name: name
|
||
}));
|
||
};
|
||
|
||
this.removeEdgeObj = function (_ref) {
|
||
var v = _ref.v,
|
||
w = _ref.w,
|
||
name = _ref.name;
|
||
return _this.removeEdge(v, w, name);
|
||
};
|
||
|
||
this.edges = function () {
|
||
return Array.from(_this.edgesMap.values());
|
||
};
|
||
|
||
this.inEdges = function (v, u) {
|
||
var inV = _this.inEdgesMap.get(v);
|
||
|
||
if (inV) {
|
||
return Array.from(inV.values()).filter(function (e) {
|
||
return !u || e.v === u;
|
||
});
|
||
}
|
||
|
||
return undefined;
|
||
};
|
||
|
||
this.outEdges = function (w, u) {
|
||
var outW = _this.outEdgesMap.get(w);
|
||
|
||
if (outW) {
|
||
return Array.from(outW.values()).filter(function (e) {
|
||
return !u || e.w === u;
|
||
});
|
||
}
|
||
|
||
return undefined;
|
||
};
|
||
|
||
this.nodeEdges = function (v, w) {
|
||
var _this$inEdges;
|
||
|
||
if (!_this.hasNode(v)) {
|
||
return undefined;
|
||
}
|
||
|
||
return (_this$inEdges = _this.inEdges(v, w)) === null || _this$inEdges === void 0 ? void 0 : _this$inEdges.concat(_this.outEdges(v, w));
|
||
};
|
||
|
||
this.toJSON = function () {
|
||
return write(_this);
|
||
};
|
||
|
||
this.nodeInDegree = function (node) {
|
||
var inEdges = _this.inEdgesMap.get(node);
|
||
|
||
if (inEdges) {
|
||
return inEdges.size;
|
||
}
|
||
|
||
return 0;
|
||
};
|
||
|
||
this.nodeOutDegree = function (node) {
|
||
var outEdges = _this.outEdgesMap.get(node);
|
||
|
||
if (outEdges) {
|
||
return outEdges.size;
|
||
}
|
||
|
||
return 0;
|
||
};
|
||
|
||
this.nodeDegree = function (node) {
|
||
return _this.nodeInDegree(node) + _this.nodeOutDegree(node);
|
||
};
|
||
|
||
this.source = function (edge) {
|
||
return edge.v;
|
||
};
|
||
|
||
this.target = function (edge) {
|
||
return edge.w;
|
||
};
|
||
|
||
var resultOptions = _objectSpread(_objectSpread({}, defaultOption), options);
|
||
|
||
this.compound = resultOptions.compound;
|
||
this.directed = resultOptions.directed;
|
||
this.multigraph = resultOptions.multigraph;
|
||
|
||
if (this.compound) {
|
||
this.parentMap = new Map();
|
||
this.childrenMap = new Map();
|
||
}
|
||
} // Map for graph
|
||
|
||
/**
|
||
* @description Map for parent relationship
|
||
* @description.zh-CN 父子关系的映射
|
||
*/
|
||
|
||
|
||
_createClass(Graph, [{
|
||
key: "setNode",
|
||
value:
|
||
/**
|
||
* @description Set Node label in graph if node not in graph then create it
|
||
* @description.zh-CN 设置节点的label,如果这个节点不在图中,则在图中创建这个节点
|
||
* @param node
|
||
* @param value
|
||
* @returns
|
||
*/
|
||
function setNode(node, value) {
|
||
var nodesLabelMap = this.nodesLabelMap,
|
||
defaultNodeLabelFn = this.defaultNodeLabelFn,
|
||
isCompound = this.isCompound,
|
||
parentMap = this.parentMap,
|
||
childrenMap = this.childrenMap,
|
||
inEdgesMap = this.inEdgesMap,
|
||
outEdgesMap = this.outEdgesMap,
|
||
predecessorsMap = this.predecessorsMap,
|
||
successorsMap = this.successorsMap; // 如果节点不在图中,则创建节点
|
||
|
||
if (nodesLabelMap.has(node)) {
|
||
if (value !== undefined) {
|
||
nodesLabelMap.set(node, value);
|
||
}
|
||
|
||
return this;
|
||
}
|
||
|
||
nodesLabelMap.set(node, value || defaultNodeLabelFn(node)); // 如果是复合图,则创建节点的子节点
|
||
|
||
if (isCompound()) {
|
||
var _childrenMap$get;
|
||
|
||
parentMap === null || parentMap === void 0 ? void 0 : parentMap.set(node, this.GRAPH_NODE);
|
||
childrenMap === null || childrenMap === void 0 ? void 0 : childrenMap.set(node, new Map());
|
||
|
||
if (!(childrenMap === null || childrenMap === void 0 ? void 0 : childrenMap.has(this.GRAPH_NODE))) {
|
||
childrenMap === null || childrenMap === void 0 ? void 0 : childrenMap.set(this.GRAPH_NODE, new Map());
|
||
}
|
||
|
||
childrenMap === null || childrenMap === void 0 ? void 0 : (_childrenMap$get = childrenMap.get(this.GRAPH_NODE)) === null || _childrenMap$get === void 0 ? void 0 : _childrenMap$get.set(node, true);
|
||
}
|
||
|
||
[inEdgesMap, outEdgesMap, predecessorsMap, successorsMap].forEach(function (map) {
|
||
return map.set(node, new Map());
|
||
});
|
||
this.nodeCountNum += 1;
|
||
return this;
|
||
}
|
||
/**
|
||
* @description Set nodes or add nodes in batch
|
||
* @description.zh-CN 批量设置或者创建节点
|
||
* @param nodes
|
||
* @param value
|
||
* @returns
|
||
*/
|
||
|
||
}, {
|
||
key: "removeNode",
|
||
value:
|
||
/**
|
||
* @description Remove node from graph
|
||
* @description.zh-CN 将节点从图中移除
|
||
* @param node
|
||
* @returns
|
||
*/
|
||
function removeNode(node) {
|
||
var _this2 = this;
|
||
|
||
if (this.hasNode(node)) {
|
||
var cleanEdge = function cleanEdge(edgeObj) {
|
||
_this2.removeEdge(edgeObj.v, edgeObj.w, edgeObj.name);
|
||
};
|
||
|
||
var inEdgesMap = this.inEdgesMap,
|
||
outEdgesMap = this.outEdgesMap,
|
||
predecessorsMap = this.predecessorsMap,
|
||
successorsMap = this.successorsMap,
|
||
nodesLabelMap = this.nodesLabelMap;
|
||
|
||
if (this.isCompound()) {
|
||
var _this$parentMap3, _this$children, _this$childrenMap3;
|
||
|
||
this.removeFromParentsChildList(node);
|
||
(_this$parentMap3 = this.parentMap) === null || _this$parentMap3 === void 0 ? void 0 : _this$parentMap3.delete(node);
|
||
(_this$children = this.children(node)) === null || _this$children === void 0 ? void 0 : _this$children.forEach(function (n) {
|
||
return _this2.setParent(n);
|
||
});
|
||
(_this$childrenMap3 = this.childrenMap) === null || _this$childrenMap3 === void 0 ? void 0 : _this$childrenMap3.delete(node);
|
||
}
|
||
|
||
var inE = inEdgesMap.get(node);
|
||
var outE = outEdgesMap.get(node);
|
||
Array.from(inE.values()).forEach(function (edge) {
|
||
return cleanEdge(edge);
|
||
});
|
||
Array.from(outE.values()).forEach(function (edge) {
|
||
return cleanEdge(edge);
|
||
});
|
||
nodesLabelMap.delete(node);
|
||
inEdgesMap.delete(node);
|
||
outEdgesMap.delete(node);
|
||
predecessorsMap.delete(node);
|
||
successorsMap.delete(node);
|
||
this.nodeCountNum -= 1;
|
||
}
|
||
|
||
return this;
|
||
}
|
||
/**
|
||
* @description Set function that generate default label for edge, if param is non-function value then default label will always be this value;
|
||
* @description.zh-CN 设置默认获取边Label的方法,如果传入不是函数的,那么默认label 的值只会是传入值
|
||
* @param newDefault
|
||
* @returns
|
||
*/
|
||
|
||
}, {
|
||
key: "setEdge",
|
||
value:
|
||
/**
|
||
* @description set edge value, if nodes or edges not exsit then add to graph
|
||
* @description.zh-CN 设置边的属性,如果边或节点不存在,那么将他们加入这个图
|
||
* @param v
|
||
* @param w
|
||
* @param value
|
||
* @param name
|
||
* @returns
|
||
*/
|
||
function setEdge(v_, w_, value, name) {
|
||
var _this$inEdgesMap$get2, _this$outEdgesMap$get2;
|
||
|
||
var edgeObj = edgeArgsToObj(this.isDirected(), v_, w_, name);
|
||
var edgeId = edgeObjToId(this.isDirected(), edgeObj);
|
||
var v = edgeObj.v,
|
||
w = edgeObj.w;
|
||
|
||
if (this.edgesLabelsMap.has(edgeId)) {
|
||
this.edgesLabelsMap.set(edgeId, value);
|
||
return this;
|
||
}
|
||
|
||
if (name !== undefined && !this.isMultigraph()) {
|
||
throw new Error('Cannot set a named edge when isMultigraph = false');
|
||
}
|
||
|
||
this.setNode(v);
|
||
this.setNode(w);
|
||
this.edgesLabelsMap.set(edgeId, value || this.defaultEdgeLabelFn(v, w, name));
|
||
Object.freeze(edgeObj);
|
||
this.edgesMap.set(edgeId, edgeObj);
|
||
var preds = this.predecessorsMap.get(w);
|
||
var succs = this.successorsMap.get(v);
|
||
incrementOrInitEntry(preds, v);
|
||
incrementOrInitEntry(succs, w);
|
||
(_this$inEdgesMap$get2 = this.inEdgesMap.get(w)) === null || _this$inEdgesMap$get2 === void 0 ? void 0 : _this$inEdgesMap$get2.set(edgeId, edgeObj);
|
||
(_this$outEdgesMap$get2 = this.outEdgesMap.get(v)) === null || _this$outEdgesMap$get2 === void 0 ? void 0 : _this$outEdgesMap$get2.set(edgeId, edgeObj);
|
||
this.edgeCountNum += 1;
|
||
return this;
|
||
}
|
||
}, {
|
||
key: "removeEdge",
|
||
value:
|
||
/**
|
||
* @description remove a specific edge
|
||
* @description.zh-CN 删除一条边
|
||
* @param v
|
||
* @param w
|
||
* @param name
|
||
* @returns
|
||
*/
|
||
function removeEdge(v_, w_, name) {
|
||
var edgeId = edgeArgsToId(this.isDirected(), v_, w_, name);
|
||
var edgeObj = this.edgesMap.get(edgeId);
|
||
|
||
if (edgeObj) {
|
||
var _edgeArgsToObj = edgeArgsToObj(this.isDirected(), v_, w_, name),
|
||
v = _edgeArgsToObj.v,
|
||
w = _edgeArgsToObj.w;
|
||
|
||
this.edgesLabelsMap.delete(edgeId);
|
||
this.edgesMap.delete(edgeId);
|
||
var preds = this.predecessorsMap.get(w);
|
||
var succs = this.successorsMap.get(v);
|
||
decrementOrRemoveEntry(preds, v);
|
||
decrementOrRemoveEntry(succs, w);
|
||
this.inEdgesMap.get(w).delete(edgeId);
|
||
this.outEdgesMap.get(v).delete(edgeId);
|
||
this.edgeCountNum -= 1;
|
||
}
|
||
|
||
return this;
|
||
}
|
||
/**
|
||
* @description remove a specific edge by edge object
|
||
* @description.zh-CN 删除一条边
|
||
*/
|
||
|
||
}]);
|
||
|
||
return Graph;
|
||
}();
|
||
|
||
Graph.fromJSON = read;
|
||
export { Graph as default }; |