occam-directed-graphs 3.0.107 → 3.0.109

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -15,7 +15,10 @@
15
15
 
16
16
  ## Introduction
17
17
 
18
- This implementation extends an incremental algorithm for directed graphs, one that returns a topological ordering for the graph. If one or more cyclic edges are added then the extended algorithm handles it gracefully rather than throwing an error. In these cases a cycle can be returned rather than a topological ordering. If all cyclic edges are removed thereafter then the algorithm recovers and a topological ordering can be returned again.
18
+ This implementation extends an incremental algorithm for directed graphs, one that returns a topological ordering for the graph.
19
+ If one or more cyclic edges are added then the extended algorithm handles it gracefully rather than throwing an error.
20
+ In these cases a cycle can be returned rather than a topological ordering.
21
+ If all cyclic edges are removed thereafter then the algorithm recovers and a topological ordering can be returned again.
19
22
 
20
23
  ## Installation
21
24
 
@@ -31,24 +34,6 @@ You can also clone the repository with [Git](https://git-scm.com/)...
31
34
 
32
35
  npm install
33
36
 
34
- ## Example
35
-
36
- There is a small development server that can be run from within the project's directory with the following command:
37
-
38
- npm start
39
-
40
- The example will then be available at the following URL:
41
-
42
- http://localhost:8888
43
-
44
- The source for the example can be found in the `src/example.js` file. You are encouraged to try the example whilst reading what follows. You can rebuild it on the fly with the following command:
45
-
46
- npm run watch-debug
47
-
48
- The development server will reload the page whenever you make changes.
49
-
50
- One last thing to bear in mind is that this package is included by way of a relative rather than a package import. If you are importing it into your own application, however, you should use the standard package import.
51
-
52
37
  ## Usage
53
38
 
54
39
  An empty directed graph can be created by calling the `fromNothing()` factory method:
@@ -77,7 +62,8 @@ directedGraph.addEdge(edge);
77
62
 
78
63
  Note that there is no need to add vertices explicitly, they will be added whenever necessary when edges that reference them are added.
79
64
 
80
- You can also remove vertices and edges. Removing a vertex could result in removing edges. When you remove an edge, you can additionally specify that the any stranded vertices that result are also removed:
65
+ You can also remove vertices and edges. Removing a vertex could result in removing edges.
66
+ When you remove an edge, you can additionally specify that the any stranded vertices that result are also removed:
81
67
 
82
68
  ```
83
69
  import { Edge } from "occam-directed-graphs";
@@ -108,6 +94,7 @@ if (cyclePresent) {
108
94
  ...
109
95
  }
110
96
  ```
97
+
111
98
  You can get a topologically ordered list of vertices at any time.
112
99
  Bear in mind that this is useless information when cycles are present.
113
100
 
package/lib/cycle.js CHANGED
@@ -16,6 +16,21 @@ class Cycle {
16
16
  getVertexNames() {
17
17
  return this.vertexNames;
18
18
  }
19
+ static fromBackEdgeAndDirectedGraph(backEdge, directedGraph) {
20
+ let cycle;
21
+ const sourceVertexName = backEdge.getSourceVertexName(), targetVertexName = backEdge.getTargetVertexName(), sourceVertex = directedGraph.getVertexByVertexName(sourceVertexName), targetVertex = directedGraph.getVertexByVertexName(targetVertexName);
22
+ targetVertex.forwardsDepthFirstSearch((vertex, predecessorVertexes)=>{
23
+ if (vertex === sourceVertex) {
24
+ const vertexes = [
25
+ ...predecessorVertexes,
26
+ sourceVertex
27
+ ], vertexNames = (0, _vertex.vertexNamesFromVertexes)(vertexes);
28
+ cycle = new Cycle(vertexNames);
29
+ return true;
30
+ }
31
+ });
32
+ return cycle;
33
+ }
19
34
  static fromSourceVertexAndPredecessorVertexes(sourceVertex, predecessorVertexes) {
20
35
  const vertexes = [
21
36
  ...predecessorVertexes,
@@ -25,4 +40,4 @@ class Cycle {
25
40
  }
26
41
  }
27
42
 
28
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jeWNsZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IHsgdmVydGV4TmFtZXNGcm9tVmVydGV4ZXMgfSBmcm9tIFwiLi91dGlsaXRpZXMvdmVydGV4XCI7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEN5Y2xlIHtcbiAgY29uc3RydWN0b3IodmVydGV4TmFtZXMpIHtcbiAgICB0aGlzLnZlcnRleE5hbWVzID0gdmVydGV4TmFtZXM7XG4gIH1cblxuICBnZXRWZXJ0ZXhOYW1lcygpIHtcbiAgICByZXR1cm4gdGhpcy52ZXJ0ZXhOYW1lcztcbiAgfVxuXG4gIHN0YXRpYyBmcm9tU291cmNlVmVydGV4QW5kUHJlZGVjZXNzb3JWZXJ0ZXhlcyhzb3VyY2VWZXJ0ZXgsIHByZWRlY2Vzc29yVmVydGV4ZXMpIHtcbiAgICBjb25zdCB2ZXJ0ZXhlcyA9IFtcbiAgICAgICAgICAgIC4uLnByZWRlY2Vzc29yVmVydGV4ZXMsXG4gICAgICAgICAgICBzb3VyY2VWZXJ0ZXhcbiAgICAgICAgICBdLFxuICAgICAgICAgIHZlcnRleE5hbWVzID0gdmVydGV4TmFtZXNGcm9tVmVydGV4ZXModmVydGV4ZXMpLFxuICAgICAgICAgIGN5Y2xlID0gbmV3IEN5Y2xlKHZlcnRleE5hbWVzKTtcblxuICAgIHJldHVybiBjeWNsZTtcbiAgfVxufVxuIl0sIm5hbWVzIjpbIkN5Y2xlIiwidmVydGV4TmFtZXMiLCJnZXRWZXJ0ZXhOYW1lcyIsImZyb21Tb3VyY2VWZXJ0ZXhBbmRQcmVkZWNlc3NvclZlcnRleGVzIiwic291cmNlVmVydGV4IiwicHJlZGVjZXNzb3JWZXJ0ZXhlcyIsInZlcnRleGVzIiwidmVydGV4TmFtZXNGcm9tVmVydGV4ZXMiLCJjeWNsZSJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7K0JBSUE7OztlQUFxQkE7Ozt3QkFGbUI7QUFFekIsTUFBTUE7SUFDbkIsWUFBWUMsV0FBVyxDQUFFO1FBQ3ZCLElBQUksQ0FBQ0EsV0FBVyxHQUFHQTtJQUNyQjtJQUVBQyxpQkFBaUI7UUFDZixPQUFPLElBQUksQ0FBQ0QsV0FBVztJQUN6QjtJQUVBLE9BQU9FLHVDQUF1Q0MsWUFBWSxFQUFFQyxtQkFBbUIsRUFBRTtRQUMvRSxNQUFNQyxXQUFXO2VBQ05EO1lBQ0hEO1NBQ0QsRUFDREgsY0FBY00sSUFBQUEsK0JBQXVCLEVBQUNELFdBQ3RDRSxRQUFRLElBQUlSLE1BQU1DO1FBRXhCLE9BQU9PO0lBQ1Q7QUFDRiJ9
43
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jeWNsZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IHsgdmVydGV4TmFtZXNGcm9tVmVydGV4ZXMgfSBmcm9tIFwiLi91dGlsaXRpZXMvdmVydGV4XCI7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEN5Y2xlIHtcbiAgY29uc3RydWN0b3IodmVydGV4TmFtZXMpIHtcbiAgICB0aGlzLnZlcnRleE5hbWVzID0gdmVydGV4TmFtZXM7XG4gIH1cblxuICBnZXRWZXJ0ZXhOYW1lcygpIHtcbiAgICByZXR1cm4gdGhpcy52ZXJ0ZXhOYW1lcztcbiAgfVxuXG4gIHN0YXRpYyBmcm9tQmFja0VkZ2VBbmREaXJlY3RlZEdyYXBoKGJhY2tFZGdlLCBkaXJlY3RlZEdyYXBoKSB7XG4gICAgbGV0IGN5Y2xlO1xuXG4gICAgY29uc3Qgc291cmNlVmVydGV4TmFtZSA9IGJhY2tFZGdlLmdldFNvdXJjZVZlcnRleE5hbWUoKSwgLy8vXG4gICAgICAgICAgdGFyZ2V0VmVydGV4TmFtZSA9IGJhY2tFZGdlLmdldFRhcmdldFZlcnRleE5hbWUoKSwgLy8vXG4gICAgICAgICAgc291cmNlVmVydGV4ID0gZGlyZWN0ZWRHcmFwaC5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSksXG4gICAgICAgICAgdGFyZ2V0VmVydGV4ID0gZGlyZWN0ZWRHcmFwaC5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSk7XG5cbiAgICB0YXJnZXRWZXJ0ZXguZm9yd2FyZHNEZXB0aEZpcnN0U2VhcmNoKCh2ZXJ0ZXgsIHByZWRlY2Vzc29yVmVydGV4ZXMpID0+IHtcbiAgICAgIGlmICh2ZXJ0ZXggPT09IHNvdXJjZVZlcnRleCkge1xuICAgICAgICBjb25zdCB2ZXJ0ZXhlcyA9IFtcbiAgICAgICAgICAgICAgICAuLi5wcmVkZWNlc3NvclZlcnRleGVzLFxuICAgICAgICAgICAgICAgIHNvdXJjZVZlcnRleFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICB2ZXJ0ZXhOYW1lcyA9IHZlcnRleE5hbWVzRnJvbVZlcnRleGVzKHZlcnRleGVzKTtcblxuICAgICAgICBjeWNsZSA9IG5ldyBDeWNsZSh2ZXJ0ZXhOYW1lcyk7XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gY3ljbGU7XG4gIH1cblxuICBzdGF0aWMgZnJvbVNvdXJjZVZlcnRleEFuZFByZWRlY2Vzc29yVmVydGV4ZXMoc291cmNlVmVydGV4LCBwcmVkZWNlc3NvclZlcnRleGVzKSB7XG4gICAgY29uc3QgdmVydGV4ZXMgPSBbXG4gICAgICAgICAgICAuLi5wcmVkZWNlc3NvclZlcnRleGVzLFxuICAgICAgICAgICAgc291cmNlVmVydGV4XG4gICAgICAgICAgXSxcbiAgICAgICAgICB2ZXJ0ZXhOYW1lcyA9IHZlcnRleE5hbWVzRnJvbVZlcnRleGVzKHZlcnRleGVzKSxcbiAgICAgICAgICBjeWNsZSA9IG5ldyBDeWNsZSh2ZXJ0ZXhOYW1lcyk7XG5cbiAgICByZXR1cm4gY3ljbGU7XG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJDeWNsZSIsInZlcnRleE5hbWVzIiwiZ2V0VmVydGV4TmFtZXMiLCJmcm9tQmFja0VkZ2VBbmREaXJlY3RlZEdyYXBoIiwiYmFja0VkZ2UiLCJkaXJlY3RlZEdyYXBoIiwiY3ljbGUiLCJzb3VyY2VWZXJ0ZXhOYW1lIiwiZ2V0U291cmNlVmVydGV4TmFtZSIsInRhcmdldFZlcnRleE5hbWUiLCJnZXRUYXJnZXRWZXJ0ZXhOYW1lIiwic291cmNlVmVydGV4IiwiZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lIiwidGFyZ2V0VmVydGV4IiwiZm9yd2FyZHNEZXB0aEZpcnN0U2VhcmNoIiwidmVydGV4IiwicHJlZGVjZXNzb3JWZXJ0ZXhlcyIsInZlcnRleGVzIiwidmVydGV4TmFtZXNGcm9tVmVydGV4ZXMiLCJmcm9tU291cmNlVmVydGV4QW5kUHJlZGVjZXNzb3JWZXJ0ZXhlcyJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7K0JBSUE7OztlQUFxQkE7Ozt3QkFGbUI7QUFFekIsTUFBTUE7SUFDbkIsWUFBWUMsV0FBVyxDQUFFO1FBQ3ZCLElBQUksQ0FBQ0EsV0FBVyxHQUFHQTtJQUNyQjtJQUVBQyxpQkFBaUI7UUFDZixPQUFPLElBQUksQ0FBQ0QsV0FBVztJQUN6QjtJQUVBLE9BQU9FLDZCQUE2QkMsUUFBUSxFQUFFQyxhQUFhLEVBQUU7UUFDM0QsSUFBSUM7UUFFSixNQUFNQyxtQkFBbUJILFNBQVNJLG1CQUFtQixJQUMvQ0MsbUJBQW1CTCxTQUFTTSxtQkFBbUIsSUFDL0NDLGVBQWVOLGNBQWNPLHFCQUFxQixDQUFDTCxtQkFDbkRNLGVBQWVSLGNBQWNPLHFCQUFxQixDQUFDSDtRQUV6REksYUFBYUMsd0JBQXdCLENBQUMsQ0FBQ0MsUUFBUUM7WUFDN0MsSUFBSUQsV0FBV0osY0FBYztnQkFDM0IsTUFBTU0sV0FBVzt1QkFDTkQ7b0JBQ0hMO2lCQUNELEVBQ0RWLGNBQWNpQixJQUFBQSwrQkFBdUIsRUFBQ0Q7Z0JBRTVDWCxRQUFRLElBQUlOLE1BQU1DO2dCQUVsQixPQUFPO1lBQ1Q7UUFDRjtRQUVBLE9BQU9LO0lBQ1Q7SUFFQSxPQUFPYSx1Q0FBdUNSLFlBQVksRUFBRUssbUJBQW1CLEVBQUU7UUFDL0UsTUFBTUMsV0FBVztlQUNORDtZQUNITDtTQUNELEVBQ0RWLGNBQWNpQixJQUFBQSwrQkFBdUIsRUFBQ0QsV0FDdENYLFFBQVEsSUFBSU4sTUFBTUM7UUFFeEIsT0FBT0s7SUFDVDtBQUNGIn0=
@@ -24,7 +24,7 @@ class DirectedGraph {
24
24
  constructor(vertexMap){
25
25
  this.vertexMap = vertexMap;
26
26
  }
27
- getVertexNap() {
27
+ getVertexMap() {
28
28
  return this.vertexMap;
29
29
  }
30
30
  getVertexes() {
@@ -48,9 +48,9 @@ class DirectedGraph {
48
48
  getEdgesBySourceVertexName(sourceVertexName) {
49
49
  const edges = [], sourceVertex = this.getVertexByVertexName(sourceVertexName);
50
50
  if (sourceVertex !== null) {
51
- const immediateSuccessorVertexes = sourceVertex.getImmediateSuccessorVertexes(), immediateSuccessorVertexNames = (0, _vertex1.vertexNamesFromVertexes)(immediateSuccessorVertexes), targetVertexNames = immediateSuccessorVertexNames; ///
52
- targetVertexNames.forEach((targetVertexName)=>{
53
- const edge = _edge.default.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
51
+ const immediateSuccessorVertexes = sourceVertex.getImmediateSuccessorVertexes(), targetVertexes = immediateSuccessorVertexes; ///
52
+ targetVertexes.forEach((targetVertex)=>{
53
+ const edge = _edge.default.fromSourceVertexAndTargetVertex(sourceVertex, targetVertex);
54
54
  edges.push(edge);
55
55
  });
56
56
  }
@@ -59,68 +59,56 @@ class DirectedGraph {
59
59
  getEdgesByTargetVertexName(targetVertexName) {
60
60
  const edges = [], targetVertex = this.getVertexByVertexName(targetVertexName);
61
61
  if (targetVertex !== null) {
62
- const immediatePredecessorVertexes = targetVertex.getImmediatePredecessorVertexes(), immediatePredecessorVertexNames = (0, _vertex1.vertexNamesFromVertexes)(immediatePredecessorVertexes), sourceVertexNames = immediatePredecessorVertexNames; ///
63
- sourceVertexNames.forEach((sourceVertexName)=>{
64
- const edge = _edge.default.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
62
+ const immediatePredecessorVertexes = targetVertex.getImmediatePredecessorVertexes(), sourceVertexes = immediatePredecessorVertexes; ///
63
+ sourceVertexes.forEach((sourceVertex)=>{
64
+ const edge = _edge.default.fromSourceVertexAndTargetVertex(sourceVertex, targetVertex);
65
65
  edges.push(edge);
66
66
  });
67
67
  }
68
68
  return edges;
69
69
  }
70
+ areCyclesPresent() {
71
+ const vertexes = this.getVertexes(), cyclesPresent = vertexes.some((vertex)=>{
72
+ const sourceVertex = vertex, sourceVertexIndex = sourceVertex.getIndex(), cyclicEdgePresent = vertex.someImmediateSuccessorVertex((immediateSuccessorVertex)=>{
73
+ const targetVertex = immediateSuccessorVertex, targetVertexIndex = targetVertex.getIndex();
74
+ if (targetVertexIndex < sourceVertexIndex) {
75
+ return true;
76
+ }
77
+ });
78
+ if (cyclicEdgePresent) {
79
+ return true;
80
+ }
81
+ });
82
+ return cyclesPresent;
83
+ }
70
84
  getFirstCycle() {
71
85
  let firstCycle = null;
72
86
  const cyclesPresent = this.areCyclesPresent();
73
87
  if (cyclesPresent) {
74
- const cyclicEdges = this.getCyclicEdges(), firstCyclicEdge = first(cyclicEdges), sourceVertexName = firstCyclicEdge.getSourceVertexName(), targetVertexName = firstCyclicEdge.getTargetVertexName(), sourceVertex = this.getVertexByVertexName(sourceVertexName), targetVertex = this.getVertexByVertexName(targetVertexName);
75
- targetVertex.forwardsDepthFirstSearch((vertex, predecessorVertexes)=>{
76
- let terminate = false;
77
- if (vertex === sourceVertex) {
78
- terminate = true;
79
- const cycle = _cycle.default.fromSourceVertexAndPredecessorVertexes(sourceVertex, predecessorVertexes); ///
80
- firstCycle = cycle; ///
81
- }
82
- return terminate;
83
- });
88
+ const backEdges = this.getBackEdges(), firstBackEdge = first(backEdges), directedGraph = this, backEdge = firstBackEdge, cycle = _cycle.default.fromBackEdgeAndDirectedGraph(backEdge, directedGraph);
89
+ firstCycle = cycle; ///
84
90
  }
85
91
  return firstCycle;
86
92
  }
87
- getCyclicEdges() {
88
- const cyclicEdges = [], vertexes = this.getVertexes();
93
+ getBackEdges() {
94
+ const backEdges = [], vertexes = this.getVertexes();
89
95
  vertexes.forEach((vertex)=>{
90
96
  const sourceVertex = vertex, sourceVertexIndex = sourceVertex.getIndex();
91
97
  vertex.forEachImmediateSuccessorVertex((immediateSuccessorVertex)=>{
92
98
  const targetVertex = immediateSuccessorVertex, targetVertexIndex = targetVertex.getIndex();
93
99
  if (targetVertexIndex < sourceVertexIndex) {
94
- const sourceVertexName = sourceVertex.getName(), targetVertexName = targetVertex.getName(), edge = _edge.default.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName), cyclicEdge = edge; ///
95
- cyclicEdges.push(cyclicEdge);
96
- }
97
- });
98
- sourceVertex;
99
- });
100
- return cyclicEdges;
101
- }
102
- areCyclesPresent() {
103
- const vertexes = this.getVertexes(), cyclesPresent = vertexes.some((vertex)=>{
104
- const sourceVertex = vertex, sourceVertexIndex = sourceVertex.getIndex(), cyclicEdgePresent = vertex.someImmediateSuccessorVertex((immediateSuccessorVertex)=>{
105
- const targetVertex = immediateSuccessorVertex, targetVertexIndex = targetVertex.getIndex();
106
- if (targetVertexIndex < sourceVertexIndex) {
107
- return true;
100
+ const edge = _edge.default.fromSourceVertexAndTargetVertex(sourceVertex, targetVertex), backEdge = edge; ///
101
+ backEdges.push(backEdge);
108
102
  }
109
103
  });
110
- if (cyclicEdgePresent) {
111
- return true;
112
- }
113
104
  });
114
- return cyclesPresent;
105
+ return backEdges;
115
106
  }
116
107
  isEdgePresent(edge) {
117
108
  let edgePresent = false;
118
- const sourceVertexName = edge.getSourceVertexName(), sourceVertex = this.getVertexByVertexName(sourceVertexName);
119
- if (sourceVertex !== null) {
120
- const targetVertexName = edge.getTargetVertexName(), targetVertex = this.getVertexByVertexName(targetVertexName);
121
- if (targetVertex !== null) {
122
- edgePresent = sourceVertex.isEdgePresentByTargetVertex(targetVertex);
123
- }
109
+ const sourceVertexName = edge.getSourceVertexName(), targetVertexName = edge.getTargetVertexName(), sourceVertex = this.getVertexByVertexName(sourceVertexName), targetVertex = this.getVertexByVertexName(targetVertexName);
110
+ if (targetVertex !== null && sourceVertex !== null) {
111
+ edgePresent = sourceVertex.isEdgePresentByTargetVertex(targetVertex);
124
112
  }
125
113
  return edgePresent;
126
114
  }
@@ -149,7 +137,7 @@ class DirectedGraph {
149
137
  const vertex = this.getVertexByVertexName(vertexName);
150
138
  return vertex;
151
139
  }
152
- removeVertexByVertexName(vertexName) {
140
+ removeVertexByVertexName(vertexName, filterBackEdges = true) {
153
141
  const vertexPresent = this.isVertexPresentByVertexName(vertexName);
154
142
  if (!vertexPresent) {
155
143
  return;
@@ -171,17 +159,23 @@ class DirectedGraph {
171
159
  vertex.decrementIndex();
172
160
  }
173
161
  });
174
- this.filterCyclicEdges();
162
+ if (filterBackEdges) {
163
+ this.filterBackEdges();
164
+ }
175
165
  }
176
166
  addVertexesByVertexNames(vertexNames) {
177
167
  vertexNames.forEach((vertexName)=>{
178
168
  this.addVertexByVertexName(vertexName);
179
169
  });
180
170
  }
181
- removeVertexesByVertexNames(vertexNames) {
171
+ removeVertexesByVertexNames(vertexNames, filterBackEdges = true) {
182
172
  vertexNames.forEach((vertexName)=>{
183
- this.removeVertexByVertexName(vertexName);
173
+ const filterBackEdges = false;
174
+ this.removeVertexByVertexName(vertexName, filterBackEdges);
184
175
  });
176
+ if (filterBackEdges) {
177
+ this.filterBackEdges();
178
+ }
185
179
  }
186
180
  addEdge(edge) {
187
181
  const sourceVertexName = edge.getSourceVertexName(), targetVertexName = edge.getTargetVertexName();
@@ -205,23 +199,26 @@ class DirectedGraph {
205
199
  this.addEdge(edge);
206
200
  });
207
201
  }
208
- removeEdge(edge, removeStrandedVertexes) {
209
- const sourceVertexName = edge.getSourceVertexName(), targetVertexName = edge.getTargetVertexName(), sourceVertex = this.addVertexByVertexName(sourceVertexName), targetVertex = this.addVertexByVertexName(targetVertexName), edgePresent = sourceVertex.isEdgePresentByTargetVertex(targetVertex);
202
+ removeEdge(edge, removeStrandedVertexes = false) {
203
+ const edgePresent = this.isEdgePresent(edge);
210
204
  if (!edgePresent) {
211
205
  return;
212
206
  }
207
+ const edgeCyclic = this.isEdgeCyclic(edge), filterBackEdges = edgeCyclic, sourceVertexName = edge.getSourceVertexName(), targetVertexName = edge.getTargetVertexName(), sourceVertex = this.getVertexByVertexName(sourceVertexName), targetVertex = this.getVertexByVertexName(targetVertexName);
213
208
  sourceVertex.removeImmediateSuccessorVertex(targetVertex);
214
209
  targetVertex.removeImmediatePredecessorVertex(sourceVertex);
215
210
  if (removeStrandedVertexes) {
216
- const sourceVertexStranded = sourceVertex.isStranded(), targetVertexStranded = targetVertex.isStranded();
211
+ const filterBackEdges = false, sourceVertexStranded = sourceVertex.isStranded(), targetVertexStranded = targetVertex.isStranded();
217
212
  if (sourceVertexStranded) {
218
- this.removeVertexByVertexName(sourceVertexName);
213
+ this.removeVertexByVertexName(sourceVertexName, filterBackEdges);
219
214
  }
220
215
  if (targetVertexStranded) {
221
- this.removeVertexByVertexName(targetVertexName);
216
+ this.removeVertexByVertexName(targetVertexName, filterBackEdges);
222
217
  }
223
218
  }
224
- this.filterCyclicEdges();
219
+ if (filterBackEdges) {
220
+ this.filterBackEdges();
221
+ }
225
222
  }
226
223
  removeEdges(edges, removeStrandedVertexes = false) {
227
224
  edges.forEach((edge)=>{
@@ -254,8 +251,12 @@ class DirectedGraph {
254
251
  reachableVertex.setIndex(index);
255
252
  });
256
253
  }
257
- filterCyclicEdges() {
258
- const cyclicEdges = this.getCyclicEdges(), edges = cyclicEdges; ///
254
+ isEdgeCyclic(edge) {
255
+ const sourceVertexName = edge.getSourceVertexName(), targetVertexName = edge.getTargetVertexName(), sourceVertex = this.getVertexByVertexName(sourceVertexName), targetVertex = this.getVertexByVertexName(targetVertexName), sourceVertexReachable = targetVertex.isVertexReachable(sourceVertex), edgeCyclic = sourceVertexReachable; ///
256
+ return edgeCyclic;
257
+ }
258
+ filterBackEdges() {
259
+ const backEdges = this.getBackEdges(), edges = backEdges; ///
259
260
  edges.forEach((edge)=>{
260
261
  const sourceVertexName = edge.getSourceVertexName(), targetVertexName = edge.getTargetVertexName(), sourceVertex = this.getVertexByVertexName(sourceVertexName), targetVertex = this.getVertexByVertexName(targetVertexName), sourceVertexForwardsReachable = targetVertex.isVertexForwardsReachable(sourceVertex);
261
262
  if (!sourceVertexForwardsReachable) {
@@ -275,4 +276,4 @@ class DirectedGraph {
275
276
  }
276
277
  }
277
278
 
278
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kaXJlY3RlZEdyYXBoLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQgeyBhcnJheVV0aWxpdGllcyB9IGZyb20gXCJuZWNlc3NhcnlcIjtcblxuaW1wb3J0IEVkZ2UgZnJvbSBcIi4vZWRnZVwiO1xuaW1wb3J0IEN5Y2xlIGZyb20gXCIuL2N5Y2xlXCI7XG5pbXBvcnQgVmVydGV4IGZyb20gXCIuL3ZlcnRleFwiO1xuXG5pbXBvcnQgeyBvcmRlckluZGV4ZXMsIGluZGV4ZXNGcm9tVmVydGV4ZXMgfSBmcm9tIFwiLi91dGlsaXRpZXMvaW5kZXhcIjtcbmltcG9ydCB7IG9yZGVyVmVydGV4ZXMsIHZlcnRleE5hbWVzRnJvbVZlcnRleGVzIH0gZnJvbSBcIi4vdXRpbGl0aWVzL3ZlcnRleFwiO1xuXG5jb25zdCB7IGZpcnN0IH0gPSBhcnJheVV0aWxpdGllcztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRGlyZWN0ZWRHcmFwaCB7XG4gIGNvbnN0cnVjdG9yKHZlcnRleE1hcCkge1xuICAgIHRoaXMudmVydGV4TWFwID0gdmVydGV4TWFwO1xuICB9XG5cbiAgZ2V0VmVydGV4TmFwKCkge1xuICAgIHJldHVybiB0aGlzLnZlcnRleE1hcDtcbiAgfVxuXG4gIGdldFZlcnRleGVzKCkge1xuICAgIGNvbnN0IHZlcnRleE1hcFZhbHVlcyA9IE9iamVjdC52YWx1ZXModGhpcy52ZXJ0ZXhNYXApLFxuICAgICAgICAgIHZlcnRleGVzID0gdmVydGV4TWFwVmFsdWVzOyAvLy9cblxuICAgIHJldHVybiB2ZXJ0ZXhlcztcbiAgfVxuXG4gIGdldFZlcnRleE5hbWVzKCkge1xuICAgIGNvbnN0IHZlcnRleE1hcEtleXMgPSBPYmplY3Qua2V5cyh0aGlzLnZlcnRleE1hcCksXG4gICAgICAgICAgdmVydGV4TmFtZXMgPSB2ZXJ0ZXhNYXBLZXlzOyAgLy8vXG5cbiAgICByZXR1cm4gdmVydGV4TmFtZXM7XG4gIH1cblxuICBnZXRPcmRlcmVkVmVydGV4TmFtZXMoKSB7XG4gICAgY29uc3QgdmVydGV4ZXMgPSB0aGlzLmdldFZlcnRleGVzKCk7XG5cbiAgICBvcmRlclZlcnRleGVzKHZlcnRleGVzKTtcblxuICAgIGNvbnN0IG9yZGVyZWRWZXJ0ZXhlcyA9IHZlcnRleGVzLCAvLy9cbiAgICAgICAgICBvcmRlcmVkVmVydGV4TmFtZXMgPSB2ZXJ0ZXhOYW1lc0Zyb21WZXJ0ZXhlcyhvcmRlcmVkVmVydGV4ZXMpO1xuXG4gICAgcmV0dXJuIG9yZGVyZWRWZXJ0ZXhOYW1lcztcbiAgfVxuXG4gIGdldFZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKSB7XG4gICAgY29uc3QgdmVydGV4UHJlc2VudCA9IHRoaXMuaXNWZXJ0ZXhQcmVzZW50QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpLFxuICAgICAgICAgIHZlcnRleCA9IHZlcnRleFByZXNlbnQgP1xuICAgICAgICAgICAgICAgICAgICAgdGhpcy52ZXJ0ZXhNYXBbdmVydGV4TmFtZV0gOlxuICAgICAgICAgICAgICAgICAgICAgICBudWxsO1xuXG4gICAgcmV0dXJuIHZlcnRleDtcbiAgfVxuXG4gIGdldEVkZ2VzQnlTb3VyY2VWZXJ0ZXhOYW1lKHNvdXJjZVZlcnRleE5hbWUpIHtcbiAgICBjb25zdCBlZGdlcyA9IFtdLFxuICAgICAgICAgIHNvdXJjZVZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHNvdXJjZVZlcnRleE5hbWUpO1xuXG4gICAgaWYgKHNvdXJjZVZlcnRleCAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMgPSBzb3VyY2VWZXJ0ZXguZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMoKSxcbiAgICAgICAgICAgIGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleE5hbWVzID0gdmVydGV4TmFtZXNGcm9tVmVydGV4ZXMoaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMpLFxuICAgICAgICAgICAgdGFyZ2V0VmVydGV4TmFtZXMgPSBpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lczsgIC8vL1xuXG4gICAgICB0YXJnZXRWZXJ0ZXhOYW1lcy5mb3JFYWNoKCh0YXJnZXRWZXJ0ZXhOYW1lKSA9PiB7XG4gICAgICAgIGNvbnN0IGVkZ2UgPSBFZGdlLmZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKTtcblxuICAgICAgICBlZGdlcy5wdXNoKGVkZ2UpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVkZ2VzO1xuICB9XG5cbiAgZ2V0RWRnZXNCeVRhcmdldFZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSkge1xuICAgIGNvbnN0IGVkZ2VzID0gW10sXG4gICAgICAgICAgdGFyZ2V0VmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSk7XG5cbiAgICBpZiAodGFyZ2V0VmVydGV4ICE9PSBudWxsKSB7XG4gICAgICBjb25zdCBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzID0gdGFyZ2V0VmVydGV4LmdldEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMoKSxcbiAgICAgICAgICAgIGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXMgPSB2ZXJ0ZXhOYW1lc0Zyb21WZXJ0ZXhlcyhpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzKSxcbiAgICAgICAgICAgIHNvdXJjZVZlcnRleE5hbWVzID0gaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lczsgIC8vL1xuXG4gICAgICBzb3VyY2VWZXJ0ZXhOYW1lcy5mb3JFYWNoKChzb3VyY2VWZXJ0ZXhOYW1lKSA9PiB7XG4gICAgICAgIGNvbnN0IGVkZ2UgPSBFZGdlLmZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKTtcblxuICAgICAgICBlZGdlcy5wdXNoKGVkZ2UpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVkZ2VzO1xuICB9XG5cbiAgZ2V0Rmlyc3RDeWNsZSgpIHtcbiAgICBsZXQgZmlyc3RDeWNsZSA9IG51bGw7XG5cbiAgICBjb25zdCBjeWNsZXNQcmVzZW50ID0gdGhpcy5hcmVDeWNsZXNQcmVzZW50KCk7XG5cbiAgICBpZiAoY3ljbGVzUHJlc2VudCkge1xuICAgICAgY29uc3QgY3ljbGljRWRnZXMgPSB0aGlzLmdldEN5Y2xpY0VkZ2VzKCksXG4gICAgICAgICAgICBmaXJzdEN5Y2xpY0VkZ2UgPSBmaXJzdChjeWNsaWNFZGdlcyksXG4gICAgICAgICAgICBzb3VyY2VWZXJ0ZXhOYW1lID0gZmlyc3RDeWNsaWNFZGdlLmdldFNvdXJjZVZlcnRleE5hbWUoKSwgLy8vXG4gICAgICAgICAgICB0YXJnZXRWZXJ0ZXhOYW1lID0gZmlyc3RDeWNsaWNFZGdlLmdldFRhcmdldFZlcnRleE5hbWUoKSwgLy8vXG4gICAgICAgICAgICBzb3VyY2VWZXJ0ZXggPSB0aGlzLmdldFZlcnRleEJ5VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lKSxcbiAgICAgICAgICAgIHRhcmdldFZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHRhcmdldFZlcnRleE5hbWUpO1xuXG4gICAgICB0YXJnZXRWZXJ0ZXguZm9yd2FyZHNEZXB0aEZpcnN0U2VhcmNoKCh2ZXJ0ZXgsIHByZWRlY2Vzc29yVmVydGV4ZXMpID0+IHtcbiAgICAgICAgbGV0IHRlcm1pbmF0ZSA9IGZhbHNlO1xuXG4gICAgICAgIGlmICh2ZXJ0ZXggPT09IHNvdXJjZVZlcnRleCkge1xuICAgICAgICAgIHRlcm1pbmF0ZSA9IHRydWU7XG5cbiAgICAgICAgICBjb25zdCBjeWNsZSA9IEN5Y2xlLmZyb21Tb3VyY2VWZXJ0ZXhBbmRQcmVkZWNlc3NvclZlcnRleGVzKHNvdXJjZVZlcnRleCwgcHJlZGVjZXNzb3JWZXJ0ZXhlcyk7ICAvLy9cblxuICAgICAgICAgIGZpcnN0Q3ljbGUgPSBjeWNsZTsgLy8vXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGVybWluYXRlO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpcnN0Q3ljbGU7XG4gIH1cblxuICBnZXRDeWNsaWNFZGdlcygpIHtcbiAgICBjb25zdCBjeWNsaWNFZGdlcyA9IFtdLFxuICAgICAgICAgIHZlcnRleGVzID0gdGhpcy5nZXRWZXJ0ZXhlcygpO1xuXG4gICAgdmVydGV4ZXMuZm9yRWFjaCgodmVydGV4KSA9PiB7XG4gICAgICBjb25zdCBzb3VyY2VWZXJ0ZXggPSB2ZXJ0ZXgsICAvLy9cbiAgICAgICAgICAgIHNvdXJjZVZlcnRleEluZGV4ID0gc291cmNlVmVydGV4LmdldEluZGV4KCk7XG5cbiAgICAgIHZlcnRleC5mb3JFYWNoSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KChpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgpID0+IHtcbiAgICAgICAgY29uc3QgdGFyZ2V0VmVydGV4ID0gaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4LCAgLy8vXG4gICAgICAgICAgICAgIHRhcmdldFZlcnRleEluZGV4ID0gdGFyZ2V0VmVydGV4LmdldEluZGV4KCk7XG5cbiAgICAgICAgaWYgKHRhcmdldFZlcnRleEluZGV4IDwgc291cmNlVmVydGV4SW5kZXgpIHtcbiAgICAgICAgICBjb25zdCBzb3VyY2VWZXJ0ZXhOYW1lID0gc291cmNlVmVydGV4LmdldE5hbWUoKSxcbiAgICAgICAgICAgICAgICB0YXJnZXRWZXJ0ZXhOYW1lID0gdGFyZ2V0VmVydGV4LmdldE5hbWUoKSxcbiAgICAgICAgICAgICAgICBlZGdlID0gRWRnZS5mcm9tU291cmNlVmVydGV4TmFtZUFuZFRhcmdldFZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSwgdGFyZ2V0VmVydGV4TmFtZSksXG4gICAgICAgICAgICAgICAgY3ljbGljRWRnZSA9IGVkZ2U7ICAvLy9cblxuICAgICAgICAgIGN5Y2xpY0VkZ2VzLnB1c2goY3ljbGljRWRnZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBzb3VyY2VWZXJ0ZXhcbiAgICB9KTtcblxuICAgIHJldHVybiBjeWNsaWNFZGdlcztcbiAgfVxuXG4gIGFyZUN5Y2xlc1ByZXNlbnQoKSB7XG4gICAgY29uc3QgdmVydGV4ZXMgPSB0aGlzLmdldFZlcnRleGVzKCksXG4gICAgICAgICAgY3ljbGVzUHJlc2VudCA9IHZlcnRleGVzLnNvbWUoKHZlcnRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc291cmNlVmVydGV4ID0gdmVydGV4LCAgLy8vXG4gICAgICAgICAgICAgICAgICBzb3VyY2VWZXJ0ZXhJbmRleCA9IHNvdXJjZVZlcnRleC5nZXRJbmRleCgpLFxuICAgICAgICAgICAgICAgICAgY3ljbGljRWRnZVByZXNlbnQgPSB2ZXJ0ZXguc29tZUltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCgoaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldFZlcnRleCA9IGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCwgIC8vL1xuICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRWZXJ0ZXhJbmRleCA9IHRhcmdldFZlcnRleC5nZXRJbmRleCgpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXRWZXJ0ZXhJbmRleCA8IHNvdXJjZVZlcnRleEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAoY3ljbGljRWRnZVByZXNlbnQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG5cbiAgICByZXR1cm4gY3ljbGVzUHJlc2VudDtcbiAgfVxuXG4gIGlzRWRnZVByZXNlbnQoZWRnZSkge1xuICAgIGxldCBlZGdlUHJlc2VudCA9IGZhbHNlO1xuXG4gICAgY29uc3Qgc291cmNlVmVydGV4TmFtZSA9IGVkZ2UuZ2V0U291cmNlVmVydGV4TmFtZSgpLFxuICAgICAgICAgIHNvdXJjZVZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHNvdXJjZVZlcnRleE5hbWUpO1xuXG4gICAgaWYgKHNvdXJjZVZlcnRleCAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgdGFyZ2V0VmVydGV4TmFtZSA9IGVkZ2UuZ2V0VGFyZ2V0VmVydGV4TmFtZSgpLFxuICAgICAgICAgICAgdGFyZ2V0VmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSk7XG5cbiAgICAgIGlmICh0YXJnZXRWZXJ0ZXggIT09IG51bGwpIHtcbiAgICAgICAgZWRnZVByZXNlbnQgPSBzb3VyY2VWZXJ0ZXguaXNFZGdlUHJlc2VudEJ5VGFyZ2V0VmVydGV4KHRhcmdldFZlcnRleCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGVkZ2VQcmVzZW50O1xuICB9XG5cbiAgaXNWZXJ0ZXhQcmVzZW50QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpIHtcbiAgICBjb25zdCB2ZXJ0ZXhOYW1lcyA9IHRoaXMuZ2V0VmVydGV4TmFtZXMoKSxcbiAgICAgICAgICB2ZXJ0ZXhOYW1lc0luY2x1ZGVzVmVydGV4TmFtZSA9IHZlcnRleE5hbWVzLmluY2x1ZGVzKHZlcnRleE5hbWUpLFxuICAgICAgICAgIHZlcnRleFByZXNlbnQgPSB2ZXJ0ZXhOYW1lc0luY2x1ZGVzVmVydGV4TmFtZTsgIC8vL1xuXG4gICAgcmV0dXJuIHZlcnRleFByZXNlbnQ7XG4gIH1cblxuICBnZXRJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lc0J5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKSB7XG4gICAgY29uc3QgdmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUodmVydGV4TmFtZSksXG4gICAgICAgICAgaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4TmFtZXMgPSB2ZXJ0ZXguZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4TmFtZXMoKTtcblxuICAgIHJldHVybiBpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lcztcbiAgfVxuXG4gIGdldEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXNCeVZlcnRleE5hbWUodmVydGV4TmFtZSkge1xuICAgIGNvbnN0IHZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpLFxuICAgICAgICAgIGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXMgPSB2ZXJ0ZXguZ2V0SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcygpO1xuXG4gICAgcmV0dXJuIGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXM7XG4gIH1cblxuICBpc0VkZ2VQcmVzZW50QnlTb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKSB7XG4gICAgY29uc3QgZWRnZSA9IEVkZ2UuZnJvbVNvdXJjZVZlcnRleE5hbWVBbmRUYXJnZXRWZXJ0ZXhOYW1lKHNvdXJjZVZlcnRleE5hbWUsIHRhcmdldFZlcnRleE5hbWUpLFxuICAgICAgICAgIGVkZ2VQcmVzZW50ID0gdGhpcy5pc0VkZ2VQcmVzZW50KGVkZ2UpO1xuXG4gICAgcmV0dXJuIGVkZ2VQcmVzZW50O1xuICB9XG5cbiAgYWRkVmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpIHtcbiAgICBjb25zdCB2ZXJ0ZXhQcmVzZW50ID0gdGhpcy5pc1ZlcnRleFByZXNlbnRCeVZlcnRleE5hbWUodmVydGV4TmFtZSk7XG5cbiAgICBpZiAoIXZlcnRleFByZXNlbnQpIHtcbiAgICAgIGNvbnN0IHZlcnRleE5hbWVzID0gdGhpcy5nZXRWZXJ0ZXhOYW1lcygpLFxuICAgICAgICAgICAgdmVydGV4TmFtZXNMZW5ndGggPSB2ZXJ0ZXhOYW1lcy5sZW5ndGgsXG4gICAgICAgICAgICBuYW1lID0gdmVydGV4TmFtZSwgIC8vL1xuICAgICAgICAgICAgaW5kZXggPSB2ZXJ0ZXhOYW1lc0xlbmd0aCwgLy8vXG4gICAgICAgICAgICB2ZXJ0ZXggPSBWZXJ0ZXguZnJvbU5hbWVBbmRJbmRleChuYW1lLCBpbmRleCk7XG5cbiAgICAgIHRoaXMuc2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUsIHZlcnRleCk7XG4gICAgfVxuXG4gICAgY29uc3QgdmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUodmVydGV4TmFtZSk7XG5cbiAgICByZXR1cm4gdmVydGV4O1xuICB9XG5cbiAgcmVtb3ZlVmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpIHtcbiAgICBjb25zdCB2ZXJ0ZXhQcmVzZW50ID0gdGhpcy5pc1ZlcnRleFByZXNlbnRCeVZlcnRleE5hbWUodmVydGV4TmFtZSk7XG5cbiAgICBpZiAoIXZlcnRleFByZXNlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB2ZXJ0ZXggPSB0aGlzLmdldFZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKTtcblxuICAgIHZlcnRleC5mb3JFYWNoSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KChpbW1lZGlhdGVTdWNjZXNzVmVydGV4KSA9PiB7XG4gICAgICBjb25zdCBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCA9IHZlcnRleDsgIC8vL1xuXG4gICAgICBpbW1lZGlhdGVTdWNjZXNzVmVydGV4LnJlbW92ZUltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KTtcbiAgICB9KTtcblxuICAgIHZlcnRleC5mb3JFYWNoSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgoKGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KSA9PiB7XG4gICAgICBjb25zdCBpbW1lZGlhdGVTdWNjZXNzVmVydGV4ID0gdmVydGV4OyAgLy8vXG5cbiAgICAgIGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4LnJlbW92ZUltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleChpbW1lZGlhdGVTdWNjZXNzVmVydGV4KTtcbiAgICB9KTtcblxuICAgIHRoaXMuZGVsZXRlVmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpO1xuXG4gICAgY29uc3QgdmVydGV4ZXMgPSB0aGlzLmdldFZlcnRleGVzKCksXG4gICAgICAgICAgZGVsZXRlZFZlcnRleCA9IHZlcnRleCwgLy8vXG4gICAgICAgICAgZGVsZXRlZFZlcnRleEluZGV4ID0gZGVsZXRlZFZlcnRleC5nZXRJbmRleCgpO1xuXG4gICAgdmVydGV4ZXMuZm9yRWFjaCgodmVydGV4KSA9PiB7XG4gICAgICBjb25zdCB2ZXJ0ZXhJbmRleCA9IHZlcnRleC5nZXRJbmRleCgpO1xuXG4gICAgICBpZiAodmVydGV4SW5kZXggPiBkZWxldGVkVmVydGV4SW5kZXgpIHtcbiAgICAgICAgdmVydGV4LmRlY3JlbWVudEluZGV4KCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmZpbHRlckN5Y2xpY0VkZ2VzKCk7XG4gIH1cblxuICBhZGRWZXJ0ZXhlc0J5VmVydGV4TmFtZXModmVydGV4TmFtZXMpIHtcbiAgICB2ZXJ0ZXhOYW1lcy5mb3JFYWNoKCh2ZXJ0ZXhOYW1lKSA9PiB7XG4gICAgICB0aGlzLmFkZFZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJlbW92ZVZlcnRleGVzQnlWZXJ0ZXhOYW1lcyh2ZXJ0ZXhOYW1lcykge1xuICAgIHZlcnRleE5hbWVzLmZvckVhY2goKHZlcnRleE5hbWUpID0+IHtcbiAgICAgIHRoaXMucmVtb3ZlVmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpO1xuICAgIH0pO1xuICB9XG5cbiAgYWRkRWRnZShlZGdlKSB7XG4gICAgY29uc3Qgc291cmNlVmVydGV4TmFtZSA9IGVkZ2UuZ2V0U291cmNlVmVydGV4TmFtZSgpLFxuICAgICAgICAgIHRhcmdldFZlcnRleE5hbWUgPSBlZGdlLmdldFRhcmdldFZlcnRleE5hbWUoKTtcblxuICAgIGlmIChzb3VyY2VWZXJ0ZXhOYW1lID09PSB0YXJnZXRWZXJ0ZXhOYW1lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc291cmNlVmVydGV4ID0gdGhpcy5hZGRWZXJ0ZXhCeVZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSksXG4gICAgICAgICAgdGFyZ2V0VmVydGV4ID0gdGhpcy5hZGRWZXJ0ZXhCeVZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSksXG4gICAgICAgICAgZWRnZVByZXNlbnQgPSBzb3VyY2VWZXJ0ZXguaXNFZGdlUHJlc2VudEJ5VGFyZ2V0VmVydGV4KHRhcmdldFZlcnRleCk7XG5cbiAgICBpZiAoZWRnZVByZXNlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzb3VyY2VWZXJ0ZXhJbmRleCA9IHNvdXJjZVZlcnRleC5nZXRJbmRleCgpLFxuICAgICAgICAgIHRhcmdldFZlcnRleEluZGV4ID0gdGFyZ2V0VmVydGV4LmdldEluZGV4KCk7XG5cbiAgICBpZiAoc291cmNlVmVydGV4SW5kZXggPiB0YXJnZXRWZXJ0ZXhJbmRleCkge1xuICAgICAgdGhpcy5yZW9yZGVyVmVydGV4ZXNCeVNvdXJjZVZlcnRleEFuZFRhcmdldFZlcnRleChzb3VyY2VWZXJ0ZXgsIHRhcmdldFZlcnRleCk7XG4gICAgfVxuXG4gICAgY29uc3QgaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXggPSBzb3VyY2VWZXJ0ZXgsIC8vL1xuICAgICAgICAgIGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCA9IHRhcmdldFZlcnRleDsgLy8vXG5cbiAgICBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleC5hZGRJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgoaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KTtcblxuICAgIGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleC5hZGRJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleChpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCk7XG4gIH1cblxuICBhZGRFZGdlcyhlZGdlcykge1xuICAgIGVkZ2VzLmZvckVhY2goKGVkZ2UpID0+IHtcbiAgICAgIHRoaXMuYWRkRWRnZShlZGdlKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJlbW92ZUVkZ2UoZWRnZSwgcmVtb3ZlU3RyYW5kZWRWZXJ0ZXhlcykge1xuICAgIGNvbnN0IHNvdXJjZVZlcnRleE5hbWUgPSBlZGdlLmdldFNvdXJjZVZlcnRleE5hbWUoKSxcbiAgICAgICAgICB0YXJnZXRWZXJ0ZXhOYW1lID0gZWRnZS5nZXRUYXJnZXRWZXJ0ZXhOYW1lKCksXG4gICAgICAgICAgc291cmNlVmVydGV4ID0gdGhpcy5hZGRWZXJ0ZXhCeVZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSksXG4gICAgICAgICAgdGFyZ2V0VmVydGV4ID0gdGhpcy5hZGRWZXJ0ZXhCeVZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSksXG4gICAgICAgICAgZWRnZVByZXNlbnQgPSBzb3VyY2VWZXJ0ZXguaXNFZGdlUHJlc2VudEJ5VGFyZ2V0VmVydGV4KHRhcmdldFZlcnRleCk7XG5cbiAgICBpZiAoIWVkZ2VQcmVzZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc291cmNlVmVydGV4LnJlbW92ZUltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCh0YXJnZXRWZXJ0ZXgpO1xuXG4gICAgdGFyZ2V0VmVydGV4LnJlbW92ZUltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KHNvdXJjZVZlcnRleCk7XG5cbiAgICBpZiAocmVtb3ZlU3RyYW5kZWRWZXJ0ZXhlcykge1xuICAgICAgY29uc3Qgc291cmNlVmVydGV4U3RyYW5kZWQgPSBzb3VyY2VWZXJ0ZXguaXNTdHJhbmRlZCgpLFxuICAgICAgICAgICAgdGFyZ2V0VmVydGV4U3RyYW5kZWQgPSB0YXJnZXRWZXJ0ZXguaXNTdHJhbmRlZCgpO1xuXG4gICAgICBpZiAoc291cmNlVmVydGV4U3RyYW5kZWQpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVWZXJ0ZXhCeVZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0YXJnZXRWZXJ0ZXhTdHJhbmRlZCkge1xuICAgICAgICB0aGlzLnJlbW92ZVZlcnRleEJ5VmVydGV4TmFtZSh0YXJnZXRWZXJ0ZXhOYW1lKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmZpbHRlckN5Y2xpY0VkZ2VzKCk7XG4gIH1cblxuICByZW1vdmVFZGdlcyhlZGdlcywgcmVtb3ZlU3RyYW5kZWRWZXJ0ZXhlcyA9IGZhbHNlKSB7XG4gICAgZWRnZXMuZm9yRWFjaCgoZWRnZSkgPT4ge1xuICAgICAgdGhpcy5yZW1vdmVFZGdlKGVkZ2UsIHJlbW92ZVN0cmFuZGVkVmVydGV4ZXMpO1xuICAgIH0pO1xuICB9XG5cbiAgcmVtb3ZlQWxsRWRnZXNBbmRWZXJ0ZXhlcygpIHtcbiAgICB0aGlzLnZlcnRleE1hcCA9IHt9O1xuICB9XG5cbiAgYWRkRWRnZUJ5U291cmNlVmVydGV4TmFtZUFuZFRhcmdldFZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSwgdGFyZ2V0VmVydGV4TmFtZSkge1xuICAgIGNvbnN0IGVkZ2UgPSBFZGdlLmZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKTtcblxuICAgIHRoaXMuYWRkRWRnZShlZGdlKTtcbiAgfVxuXG4gIHJlb3JkZXJWZXJ0ZXhlc0J5U291cmNlVmVydGV4QW5kVGFyZ2V0VmVydGV4KHNvdXJjZVZlcnRleCwgdGFyZ2V0VmVydGV4KSB7XG4gICAgY29uc3Qgc291cmNlVmVydGV4Rm9yd2FyZHNSZWFjaGFibGUgPSB0YXJnZXRWZXJ0ZXguaXNWZXJ0ZXhGb3J3YXJkc1JlYWNoYWJsZShzb3VyY2VWZXJ0ZXgpO1xuXG4gICAgaWYgKHNvdXJjZVZlcnRleEZvcndhcmRzUmVhY2hhYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyA9IHRhcmdldFZlcnRleC5yZXRyaWV2ZUZvcndhcmRzUmVhY2hhYmxlVmVydGV4ZXMoKSxcbiAgICAgICAgICBiYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyA9IHNvdXJjZVZlcnRleC5yZXRyaWV2ZUJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzKCk7XG5cbiAgICBvcmRlclZlcnRleGVzKGJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzKTtcblxuICAgIG9yZGVyVmVydGV4ZXMoZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyk7XG5cbiAgICBjb25zdCByZWFjaGFibGVWZXJ0ZXhlcyA9IFtcbiAgICAgICAgICAgIC4uLmJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzLFxuICAgICAgICAgICAgLi4uZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlc1xuICAgICAgICAgIF0sXG4gICAgICAgICAgcmVhY2hhYmxlSW5kZXhlcyA9IGluZGV4ZXNGcm9tVmVydGV4ZXMocmVhY2hhYmxlVmVydGV4ZXMpO1xuXG4gICAgb3JkZXJJbmRleGVzKHJlYWNoYWJsZUluZGV4ZXMpO1xuXG4gICAgcmVhY2hhYmxlVmVydGV4ZXMuZm9yRWFjaCgocmVhY2hhYmxlVmVydGV4LCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgcmVhY2hhYmxlSW5kZXggPSByZWFjaGFibGVJbmRleGVzW2luZGV4XTtcblxuICAgICAgaW5kZXggPSByZWFjaGFibGVJbmRleDsgLy8vXG5cbiAgICAgIHJlYWNoYWJsZVZlcnRleC5zZXRJbmRleChpbmRleCk7XG4gICAgfSk7XG4gIH1cblxuICBmaWx0ZXJDeWNsaWNFZGdlcygpIHtcbiAgICBjb25zdCBjeWNsaWNFZGdlcyA9IHRoaXMuZ2V0Q3ljbGljRWRnZXMoKSxcbiAgICAgICAgICBlZGdlcyA9IGN5Y2xpY0VkZ2VzOyAgLy8vXG5cbiAgICBlZGdlcy5mb3JFYWNoKChlZGdlKSA9PiB7XG4gICAgICBjb25zdCBzb3VyY2VWZXJ0ZXhOYW1lID0gZWRnZS5nZXRTb3VyY2VWZXJ0ZXhOYW1lKCksXG4gICAgICAgICAgICB0YXJnZXRWZXJ0ZXhOYW1lID0gZWRnZS5nZXRUYXJnZXRWZXJ0ZXhOYW1lKCksXG4gICAgICAgICAgICBzb3VyY2VWZXJ0ZXggPSB0aGlzLmdldFZlcnRleEJ5VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lKSxcbiAgICAgICAgICAgIHRhcmdldFZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHRhcmdldFZlcnRleE5hbWUpLFxuICAgICAgICAgICAgc291cmNlVmVydGV4Rm9yd2FyZHNSZWFjaGFibGUgPSB0YXJnZXRWZXJ0ZXguaXNWZXJ0ZXhGb3J3YXJkc1JlYWNoYWJsZShzb3VyY2VWZXJ0ZXgpO1xuXG4gICAgICBpZiAoIXNvdXJjZVZlcnRleEZvcndhcmRzUmVhY2hhYmxlKSB7XG4gICAgICAgIHRoaXMucmVvcmRlclZlcnRleGVzQnlTb3VyY2VWZXJ0ZXhBbmRUYXJnZXRWZXJ0ZXgoc291cmNlVmVydGV4LCB0YXJnZXRWZXJ0ZXgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgc2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUsIHZlcnRleCkge1xuICAgIHRoaXMudmVydGV4TWFwW3ZlcnRleE5hbWVdID0gdmVydGV4O1xuICB9XG5cbiAgZGVsZXRlVmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpIHtcbiAgICBkZWxldGUgdGhpcy52ZXJ0ZXhNYXBbdmVydGV4TmFtZV07XG4gIH1cblxuICBzdGF0aWMgZnJvbU5vdGhpbmcoKSB7XG4gICAgY29uc3QgdmVydGV4TWFwID0ge30sXG4gICAgICAgICAgZGlyZWN0ZWRHcmFwaCA9IG5ldyBEaXJlY3RlZEdyYXBoKHZlcnRleE1hcCk7XG4gICAgXG4gICAgcmV0dXJuIGRpcmVjdGVkR3JhcGg7ICAgIFxuICB9XG59XG4iXSwibmFtZXMiOlsiRGlyZWN0ZWRHcmFwaCIsImZpcnN0IiwiYXJyYXlVdGlsaXRpZXMiLCJ2ZXJ0ZXhNYXAiLCJnZXRWZXJ0ZXhOYXAiLCJnZXRWZXJ0ZXhlcyIsInZlcnRleE1hcFZhbHVlcyIsIk9iamVjdCIsInZhbHVlcyIsInZlcnRleGVzIiwiZ2V0VmVydGV4TmFtZXMiLCJ2ZXJ0ZXhNYXBLZXlzIiwia2V5cyIsInZlcnRleE5hbWVzIiwiZ2V0T3JkZXJlZFZlcnRleE5hbWVzIiwib3JkZXJWZXJ0ZXhlcyIsIm9yZGVyZWRWZXJ0ZXhlcyIsIm9yZGVyZWRWZXJ0ZXhOYW1lcyIsInZlcnRleE5hbWVzRnJvbVZlcnRleGVzIiwiZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lIiwidmVydGV4TmFtZSIsInZlcnRleFByZXNlbnQiLCJpc1ZlcnRleFByZXNlbnRCeVZlcnRleE5hbWUiLCJ2ZXJ0ZXgiLCJnZXRFZGdlc0J5U291cmNlVmVydGV4TmFtZSIsInNvdXJjZVZlcnRleE5hbWUiLCJlZGdlcyIsInNvdXJjZVZlcnRleCIsImltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzIiwiZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMiLCJpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lcyIsInRhcmdldFZlcnRleE5hbWVzIiwiZm9yRWFjaCIsInRhcmdldFZlcnRleE5hbWUiLCJlZGdlIiwiRWRnZSIsImZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZSIsInB1c2giLCJnZXRFZGdlc0J5VGFyZ2V0VmVydGV4TmFtZSIsInRhcmdldFZlcnRleCIsImltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMiLCJnZXRJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzIiwiaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcyIsInNvdXJjZVZlcnRleE5hbWVzIiwiZ2V0Rmlyc3RDeWNsZSIsImZpcnN0Q3ljbGUiLCJjeWNsZXNQcmVzZW50IiwiYXJlQ3ljbGVzUHJlc2VudCIsImN5Y2xpY0VkZ2VzIiwiZ2V0Q3ljbGljRWRnZXMiLCJmaXJzdEN5Y2xpY0VkZ2UiLCJnZXRTb3VyY2VWZXJ0ZXhOYW1lIiwiZ2V0VGFyZ2V0VmVydGV4TmFtZSIsImZvcndhcmRzRGVwdGhGaXJzdFNlYXJjaCIsInByZWRlY2Vzc29yVmVydGV4ZXMiLCJ0ZXJtaW5hdGUiLCJjeWNsZSIsIkN5Y2xlIiwiZnJvbVNvdXJjZVZlcnRleEFuZFByZWRlY2Vzc29yVmVydGV4ZXMiLCJzb3VyY2VWZXJ0ZXhJbmRleCIsImdldEluZGV4IiwiZm9yRWFjaEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsImltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsInRhcmdldFZlcnRleEluZGV4IiwiZ2V0TmFtZSIsImN5Y2xpY0VkZ2UiLCJzb21lIiwiY3ljbGljRWRnZVByZXNlbnQiLCJzb21lSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4IiwiaXNFZGdlUHJlc2VudCIsImVkZ2VQcmVzZW50IiwiaXNFZGdlUHJlc2VudEJ5VGFyZ2V0VmVydGV4IiwidmVydGV4TmFtZXNJbmNsdWRlc1ZlcnRleE5hbWUiLCJpbmNsdWRlcyIsImdldEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleE5hbWVzQnlWZXJ0ZXhOYW1lIiwiZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4TmFtZXMiLCJnZXRJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleE5hbWVzQnlWZXJ0ZXhOYW1lIiwiZ2V0SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcyIsImlzRWRnZVByZXNlbnRCeVNvdXJjZVZlcnRleE5hbWVBbmRUYXJnZXRWZXJ0ZXhOYW1lIiwiYWRkVmVydGV4QnlWZXJ0ZXhOYW1lIiwidmVydGV4TmFtZXNMZW5ndGgiLCJsZW5ndGgiLCJuYW1lIiwiaW5kZXgiLCJWZXJ0ZXgiLCJmcm9tTmFtZUFuZEluZGV4Iiwic2V0VmVydGV4QnlWZXJ0ZXhOYW1lIiwicmVtb3ZlVmVydGV4QnlWZXJ0ZXhOYW1lIiwiaW1tZWRpYXRlU3VjY2Vzc1ZlcnRleCIsImltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4IiwicmVtb3ZlSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJmb3JFYWNoSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJyZW1vdmVJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgiLCJkZWxldGVWZXJ0ZXhCeVZlcnRleE5hbWUiLCJkZWxldGVkVmVydGV4IiwiZGVsZXRlZFZlcnRleEluZGV4IiwidmVydGV4SW5kZXgiLCJkZWNyZW1lbnRJbmRleCIsImZpbHRlckN5Y2xpY0VkZ2VzIiwiYWRkVmVydGV4ZXNCeVZlcnRleE5hbWVzIiwicmVtb3ZlVmVydGV4ZXNCeVZlcnRleE5hbWVzIiwiYWRkRWRnZSIsInJlb3JkZXJWZXJ0ZXhlc0J5U291cmNlVmVydGV4QW5kVGFyZ2V0VmVydGV4IiwiYWRkSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4IiwiYWRkSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJhZGRFZGdlcyIsInJlbW92ZUVkZ2UiLCJyZW1vdmVTdHJhbmRlZFZlcnRleGVzIiwic291cmNlVmVydGV4U3RyYW5kZWQiLCJpc1N0cmFuZGVkIiwidGFyZ2V0VmVydGV4U3RyYW5kZWQiLCJyZW1vdmVFZGdlcyIsInJlbW92ZUFsbEVkZ2VzQW5kVmVydGV4ZXMiLCJhZGRFZGdlQnlTb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZSIsInNvdXJjZVZlcnRleEZvcndhcmRzUmVhY2hhYmxlIiwiaXNWZXJ0ZXhGb3J3YXJkc1JlYWNoYWJsZSIsImZvcndhcmRzUmVhY2hhYmxlVmVydGV4ZXMiLCJyZXRyaWV2ZUZvcndhcmRzUmVhY2hhYmxlVmVydGV4ZXMiLCJiYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyIsInJldHJpZXZlQmFja3dhcmRzUmVhY2hhYmxlVmVydGV4ZXMiLCJyZWFjaGFibGVWZXJ0ZXhlcyIsInJlYWNoYWJsZUluZGV4ZXMiLCJpbmRleGVzRnJvbVZlcnRleGVzIiwib3JkZXJJbmRleGVzIiwicmVhY2hhYmxlVmVydGV4IiwicmVhY2hhYmxlSW5kZXgiLCJzZXRJbmRleCIsImZyb21Ob3RoaW5nIiwiZGlyZWN0ZWRHcmFwaCJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7K0JBYUE7OztlQUFxQkE7OzsyQkFYVTs2REFFZDs4REFDQzsrREFDQzt1QkFFK0I7eUJBQ0s7Ozs7OztBQUV2RCxNQUFNLEVBQUVDLEtBQUssRUFBRSxHQUFHQyx5QkFBYztBQUVqQixNQUFNRjtJQUNuQixZQUFZRyxTQUFTLENBQUU7UUFDckIsSUFBSSxDQUFDQSxTQUFTLEdBQUdBO0lBQ25CO0lBRUFDLGVBQWU7UUFDYixPQUFPLElBQUksQ0FBQ0QsU0FBUztJQUN2QjtJQUVBRSxjQUFjO1FBQ1osTUFBTUMsa0JBQWtCQyxPQUFPQyxNQUFNLENBQUMsSUFBSSxDQUFDTCxTQUFTLEdBQzlDTSxXQUFXSCxpQkFBaUIsR0FBRztRQUVyQyxPQUFPRztJQUNUO0lBRUFDLGlCQUFpQjtRQUNmLE1BQU1DLGdCQUFnQkosT0FBT0ssSUFBSSxDQUFDLElBQUksQ0FBQ1QsU0FBUyxHQUMxQ1UsY0FBY0YsZUFBZ0IsR0FBRztRQUV2QyxPQUFPRTtJQUNUO0lBRUFDLHdCQUF3QjtRQUN0QixNQUFNTCxXQUFXLElBQUksQ0FBQ0osV0FBVztRQUVqQ1UsSUFBQUEsc0JBQWEsRUFBQ047UUFFZCxNQUFNTyxrQkFBa0JQLFVBQ2xCUSxxQkFBcUJDLElBQUFBLGdDQUF1QixFQUFDRjtRQUVuRCxPQUFPQztJQUNUO0lBRUFFLHNCQUFzQkMsVUFBVSxFQUFFO1FBQ2hDLE1BQU1DLGdCQUFnQixJQUFJLENBQUNDLDJCQUEyQixDQUFDRixhQUNqREcsU0FBU0YsZ0JBQ0UsSUFBSSxDQUFDbEIsU0FBUyxDQUFDaUIsV0FBVyxHQUN4QjtRQUVuQixPQUFPRztJQUNUO0lBRUFDLDJCQUEyQkMsZ0JBQWdCLEVBQUU7UUFDM0MsTUFBTUMsUUFBUSxFQUFFLEVBQ1ZDLGVBQWUsSUFBSSxDQUFDUixxQkFBcUIsQ0FBQ007UUFFaEQsSUFBSUUsaUJBQWlCLE1BQU07WUFDekIsTUFBTUMsNkJB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
279
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kaXJlY3RlZEdyYXBoLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQgeyBhcnJheVV0aWxpdGllcyB9IGZyb20gXCJuZWNlc3NhcnlcIjtcblxuaW1wb3J0IEVkZ2UgZnJvbSBcIi4vZWRnZVwiO1xuaW1wb3J0IEN5Y2xlIGZyb20gXCIuL2N5Y2xlXCI7XG5pbXBvcnQgVmVydGV4IGZyb20gXCIuL3ZlcnRleFwiO1xuXG5pbXBvcnQgeyBvcmRlckluZGV4ZXMsIGluZGV4ZXNGcm9tVmVydGV4ZXMgfSBmcm9tIFwiLi91dGlsaXRpZXMvaW5kZXhcIjtcbmltcG9ydCB7IG9yZGVyVmVydGV4ZXMsIHZlcnRleE5hbWVzRnJvbVZlcnRleGVzIH0gZnJvbSBcIi4vdXRpbGl0aWVzL3ZlcnRleFwiO1xuXG5jb25zdCB7IGZpcnN0IH0gPSBhcnJheVV0aWxpdGllcztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRGlyZWN0ZWRHcmFwaCB7XG4gIGNvbnN0cnVjdG9yKHZlcnRleE1hcCkge1xuICAgIHRoaXMudmVydGV4TWFwID0gdmVydGV4TWFwO1xuICB9XG5cbiAgZ2V0VmVydGV4TWFwKCkge1xuICAgIHJldHVybiB0aGlzLnZlcnRleE1hcDtcbiAgfVxuXG4gIGdldFZlcnRleGVzKCkge1xuICAgIGNvbnN0IHZlcnRleE1hcFZhbHVlcyA9IE9iamVjdC52YWx1ZXModGhpcy52ZXJ0ZXhNYXApLFxuICAgICAgICAgIHZlcnRleGVzID0gdmVydGV4TWFwVmFsdWVzOyAvLy9cblxuICAgIHJldHVybiB2ZXJ0ZXhlcztcbiAgfVxuXG4gIGdldFZlcnRleE5hbWVzKCkge1xuICAgIGNvbnN0IHZlcnRleE1hcEtleXMgPSBPYmplY3Qua2V5cyh0aGlzLnZlcnRleE1hcCksXG4gICAgICAgICAgdmVydGV4TmFtZXMgPSB2ZXJ0ZXhNYXBLZXlzOyAgLy8vXG5cbiAgICByZXR1cm4gdmVydGV4TmFtZXM7XG4gIH1cblxuICBnZXRPcmRlcmVkVmVydGV4TmFtZXMoKSB7XG4gICAgY29uc3QgdmVydGV4ZXMgPSB0aGlzLmdldFZlcnRleGVzKCk7XG5cbiAgICBvcmRlclZlcnRleGVzKHZlcnRleGVzKTtcblxuICAgIGNvbnN0IG9yZGVyZWRWZXJ0ZXhlcyA9IHZlcnRleGVzLCAvLy9cbiAgICAgICAgICBvcmRlcmVkVmVydGV4TmFtZXMgPSB2ZXJ0ZXhOYW1lc0Zyb21WZXJ0ZXhlcyhvcmRlcmVkVmVydGV4ZXMpO1xuXG4gICAgcmV0dXJuIG9yZGVyZWRWZXJ0ZXhOYW1lcztcbiAgfVxuXG4gIGdldFZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKSB7XG4gICAgY29uc3QgdmVydGV4UHJlc2VudCA9IHRoaXMuaXNWZXJ0ZXhQcmVzZW50QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpLFxuICAgICAgICAgIHZlcnRleCA9IHZlcnRleFByZXNlbnQgP1xuICAgICAgICAgICAgICAgICAgICAgdGhpcy52ZXJ0ZXhNYXBbdmVydGV4TmFtZV0gOlxuICAgICAgICAgICAgICAgICAgICAgICBudWxsO1xuXG4gICAgcmV0dXJuIHZlcnRleDtcbiAgfVxuXG4gIGdldEVkZ2VzQnlTb3VyY2VWZXJ0ZXhOYW1lKHNvdXJjZVZlcnRleE5hbWUpIHtcbiAgICBjb25zdCBlZGdlcyA9IFtdLFxuICAgICAgICAgIHNvdXJjZVZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHNvdXJjZVZlcnRleE5hbWUpO1xuXG4gICAgaWYgKHNvdXJjZVZlcnRleCAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMgPSBzb3VyY2VWZXJ0ZXguZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMoKSxcbiAgICAgICAgICAgIHRhcmdldFZlcnRleGVzID0gaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXM7ICAvLy9cblxuICAgICAgdGFyZ2V0VmVydGV4ZXMuZm9yRWFjaCgodGFyZ2V0VmVydGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IGVkZ2UgPSBFZGdlLmZyb21Tb3VyY2VWZXJ0ZXhBbmRUYXJnZXRWZXJ0ZXgoc291cmNlVmVydGV4LCB0YXJnZXRWZXJ0ZXgpO1xuXG4gICAgICAgIGVkZ2VzLnB1c2goZWRnZSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZWRnZXM7XG4gIH1cblxuICBnZXRFZGdlc0J5VGFyZ2V0VmVydGV4TmFtZSh0YXJnZXRWZXJ0ZXhOYW1lKSB7XG4gICAgY29uc3QgZWRnZXMgPSBbXSxcbiAgICAgICAgICB0YXJnZXRWZXJ0ZXggPSB0aGlzLmdldFZlcnRleEJ5VmVydGV4TmFtZSh0YXJnZXRWZXJ0ZXhOYW1lKTtcblxuICAgIGlmICh0YXJnZXRWZXJ0ZXggIT09IG51bGwpIHtcbiAgICAgIGNvbnN0IGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMgPSB0YXJnZXRWZXJ0ZXguZ2V0SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhlcygpLFxuICAgICAgICAgICAgc291cmNlVmVydGV4ZXMgPSBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzOyAgLy8vXG5cbiAgICAgIHNvdXJjZVZlcnRleGVzLmZvckVhY2goKHNvdXJjZVZlcnRleCkgPT4ge1xuICAgICAgICBjb25zdCBlZGdlID0gRWRnZS5mcm9tU291cmNlVmVydGV4QW5kVGFyZ2V0VmVydGV4KHNvdXJjZVZlcnRleCwgdGFyZ2V0VmVydGV4KTtcblxuICAgICAgICBlZGdlcy5wdXNoKGVkZ2UpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVkZ2VzO1xuICB9XG5cbiAgYXJlQ3ljbGVzUHJlc2VudCgpIHtcbiAgICBjb25zdCB2ZXJ0ZXhlcyA9IHRoaXMuZ2V0VmVydGV4ZXMoKSxcbiAgICAgICAgICBjeWNsZXNQcmVzZW50ID0gdmVydGV4ZXMuc29tZSgodmVydGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzb3VyY2VWZXJ0ZXggPSB2ZXJ0ZXgsICAvLy9cbiAgICAgICAgICAgICAgICAgIHNvdXJjZVZlcnRleEluZGV4ID0gc291cmNlVmVydGV4LmdldEluZGV4KCksXG4gICAgICAgICAgICAgICAgICBjeWNsaWNFZGdlUHJlc2VudCA9IHZlcnRleC5zb21lSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KChpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0VmVydGV4ID0gaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4LCAgLy8vXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFZlcnRleEluZGV4ID0gdGFyZ2V0VmVydGV4LmdldEluZGV4KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRhcmdldFZlcnRleEluZGV4IDwgc291cmNlVmVydGV4SW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmIChjeWNsaWNFZGdlUHJlc2VudCkge1xuICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgIHJldHVybiBjeWNsZXNQcmVzZW50O1xuICB9XG5cbiAgZ2V0Rmlyc3RDeWNsZSgpIHtcbiAgICBsZXQgZmlyc3RDeWNsZSA9IG51bGw7XG5cbiAgICBjb25zdCBjeWNsZXNQcmVzZW50ID0gdGhpcy5hcmVDeWNsZXNQcmVzZW50KCk7XG5cbiAgICBpZiAoY3ljbGVzUHJlc2VudCkge1xuICAgICAgY29uc3QgYmFja0VkZ2VzID0gdGhpcy5nZXRCYWNrRWRnZXMoKSxcbiAgICAgICAgICAgIGZpcnN0QmFja0VkZ2UgPSBmaXJzdChiYWNrRWRnZXMpLFxuICAgICAgICAgICAgZGlyZWN0ZWRHcmFwaCA9IHRoaXMsIC8vL1xuICAgICAgICAgICAgYmFja0VkZ2UgPSBmaXJzdEJhY2tFZGdlLCAvLy9cbiAgICAgICAgICAgIGN5Y2xlID0gQ3ljbGUuZnJvbUJhY2tFZGdlQW5kRGlyZWN0ZWRHcmFwaChiYWNrRWRnZSwgZGlyZWN0ZWRHcmFwaCk7XG5cbiAgICAgIGZpcnN0Q3ljbGUgPSBjeWNsZTsgLy8vXG4gICAgfVxuXG4gICAgcmV0dXJuIGZpcnN0Q3ljbGU7XG4gIH1cblxuICBnZXRCYWNrRWRnZXMoKSB7XG4gICAgY29uc3QgYmFja0VkZ2VzID0gW10sXG4gICAgICAgICAgdmVydGV4ZXMgPSB0aGlzLmdldFZlcnRleGVzKCk7XG5cbiAgICB2ZXJ0ZXhlcy5mb3JFYWNoKCh2ZXJ0ZXgpID0+IHtcbiAgICAgIGNvbnN0IHNvdXJjZVZlcnRleCA9IHZlcnRleCwgIC8vL1xuICAgICAgICAgICAgc291cmNlVmVydGV4SW5kZXggPSBzb3VyY2VWZXJ0ZXguZ2V0SW5kZXgoKTtcblxuICAgICAgdmVydGV4LmZvckVhY2hJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgoKGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCkgPT4ge1xuICAgICAgICBjb25zdCB0YXJnZXRWZXJ0ZXggPSBpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgsICAvLy9cbiAgICAgICAgICAgICAgdGFyZ2V0VmVydGV4SW5kZXggPSB0YXJnZXRWZXJ0ZXguZ2V0SW5kZXgoKTtcblxuICAgICAgICBpZiAodGFyZ2V0VmVydGV4SW5kZXggPCBzb3VyY2VWZXJ0ZXhJbmRleCkge1xuICAgICAgICAgIGNvbnN0IGVkZ2UgPSBFZGdlLmZyb21Tb3VyY2VWZXJ0ZXhBbmRUYXJnZXRWZXJ0ZXgoc291cmNlVmVydGV4LCB0YXJnZXRWZXJ0ZXgpLFxuICAgICAgICAgICAgICAgIGJhY2tFZGdlID0gZWRnZTsgIC8vL1xuXG4gICAgICAgICAgYmFja0VkZ2VzLnB1c2goYmFja0VkZ2UpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiBiYWNrRWRnZXM7XG4gIH1cblxuICBpc0VkZ2VQcmVzZW50KGVkZ2UpIHtcbiAgICBsZXQgZWRnZVByZXNlbnQgPSBmYWxzZTtcblxuICAgIGNvbnN0IHNvdXJjZVZlcnRleE5hbWUgPSBlZGdlLmdldFNvdXJjZVZlcnRleE5hbWUoKSxcbiAgICAgICAgICB0YXJnZXRWZXJ0ZXhOYW1lID0gZWRnZS5nZXRUYXJnZXRWZXJ0ZXhOYW1lKCksXG4gICAgICAgICAgc291cmNlVmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSksXG4gICAgICAgICAgdGFyZ2V0VmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSk7XG5cbiAgICBpZiAoKHRhcmdldFZlcnRleCAhPT0gbnVsbCkgJiYgKHNvdXJjZVZlcnRleCAhPT0gbnVsbCkpIHtcbiAgICAgIGVkZ2VQcmVzZW50ID0gc291cmNlVmVydGV4LmlzRWRnZVByZXNlbnRCeVRhcmdldFZlcnRleCh0YXJnZXRWZXJ0ZXgpO1xuICAgIH1cblxuICAgIHJldHVybiBlZGdlUHJlc2VudDtcbiAgfVxuXG4gIGlzVmVydGV4UHJlc2VudEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKSB7XG4gICAgY29uc3QgdmVydGV4TmFtZXMgPSB0aGlzLmdldFZlcnRleE5hbWVzKCksXG4gICAgICAgICAgdmVydGV4TmFtZXNJbmNsdWRlc1ZlcnRleE5hbWUgPSB2ZXJ0ZXhOYW1lcy5pbmNsdWRlcyh2ZXJ0ZXhOYW1lKSxcbiAgICAgICAgICB2ZXJ0ZXhQcmVzZW50ID0gdmVydGV4TmFtZXNJbmNsdWRlc1ZlcnRleE5hbWU7ICAvLy9cblxuICAgIHJldHVybiB2ZXJ0ZXhQcmVzZW50O1xuICB9XG5cbiAgZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4TmFtZXNCeVZlcnRleE5hbWUodmVydGV4TmFtZSkge1xuICAgIGNvbnN0IHZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpLFxuICAgICAgICAgIGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleE5hbWVzID0gdmVydGV4LmdldEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleE5hbWVzKCk7XG5cbiAgICByZXR1cm4gaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4TmFtZXM7XG4gIH1cblxuICBnZXRJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleE5hbWVzQnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpIHtcbiAgICBjb25zdCB2ZXJ0ZXggPSB0aGlzLmdldFZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKSxcbiAgICAgICAgICBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleE5hbWVzID0gdmVydGV4LmdldEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXMoKTtcblxuICAgIHJldHVybiBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleE5hbWVzO1xuICB9XG5cbiAgaXNFZGdlUHJlc2VudEJ5U291cmNlVmVydGV4TmFtZUFuZFRhcmdldFZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSwgdGFyZ2V0VmVydGV4TmFtZSkge1xuICAgIGNvbnN0IGVkZ2UgPSBFZGdlLmZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKSxcbiAgICAgICAgICBlZGdlUHJlc2VudCA9IHRoaXMuaXNFZGdlUHJlc2VudChlZGdlKTtcblxuICAgIHJldHVybiBlZGdlUHJlc2VudDtcbiAgfVxuXG4gIGFkZFZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKSB7XG4gICAgY29uc3QgdmVydGV4UHJlc2VudCA9IHRoaXMuaXNWZXJ0ZXhQcmVzZW50QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpO1xuXG4gICAgaWYgKCF2ZXJ0ZXhQcmVzZW50KSB7XG4gICAgICBjb25zdCB2ZXJ0ZXhOYW1lcyA9IHRoaXMuZ2V0VmVydGV4TmFtZXMoKSxcbiAgICAgICAgICAgIHZlcnRleE5hbWVzTGVuZ3RoID0gdmVydGV4TmFtZXMubGVuZ3RoLFxuICAgICAgICAgICAgbmFtZSA9IHZlcnRleE5hbWUsICAvLy9cbiAgICAgICAgICAgIGluZGV4ID0gdmVydGV4TmFtZXNMZW5ndGgsIC8vL1xuICAgICAgICAgICAgdmVydGV4ID0gVmVydGV4LmZyb21OYW1lQW5kSW5kZXgobmFtZSwgaW5kZXgpO1xuXG4gICAgICB0aGlzLnNldFZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lLCB2ZXJ0ZXgpO1xuICAgIH1cblxuICAgIGNvbnN0IHZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpO1xuXG4gICAgcmV0dXJuIHZlcnRleDtcbiAgfVxuXG4gIHJlbW92ZVZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lLCBmaWx0ZXJCYWNrRWRnZXMgPSB0cnVlKSB7XG4gICAgY29uc3QgdmVydGV4UHJlc2VudCA9IHRoaXMuaXNWZXJ0ZXhQcmVzZW50QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpO1xuXG4gICAgaWYgKCF2ZXJ0ZXhQcmVzZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUodmVydGV4TmFtZSk7XG5cbiAgICB2ZXJ0ZXguZm9yRWFjaEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCgoaW1tZWRpYXRlU3VjY2Vzc1ZlcnRleCkgPT4ge1xuICAgICAgY29uc3QgaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXggPSB2ZXJ0ZXg7ICAvLy9cblxuICAgICAgaW1tZWRpYXRlU3VjY2Vzc1ZlcnRleC5yZW1vdmVJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleChpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCk7XG4gICAgfSk7XG5cbiAgICB2ZXJ0ZXguZm9yRWFjaEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KChpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCkgPT4ge1xuICAgICAgY29uc3QgaW1tZWRpYXRlU3VjY2Vzc1ZlcnRleCA9IHZlcnRleDsgIC8vL1xuXG4gICAgICBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleC5yZW1vdmVJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgoaW1tZWRpYXRlU3VjY2Vzc1ZlcnRleCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmRlbGV0ZVZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKTtcblxuICAgIGNvbnN0IHZlcnRleGVzID0gdGhpcy5nZXRWZXJ0ZXhlcygpLFxuICAgICAgICAgIGRlbGV0ZWRWZXJ0ZXggPSB2ZXJ0ZXgsIC8vL1xuICAgICAgICAgIGRlbGV0ZWRWZXJ0ZXhJbmRleCA9IGRlbGV0ZWRWZXJ0ZXguZ2V0SW5kZXgoKTtcblxuICAgIHZlcnRleGVzLmZvckVhY2goKHZlcnRleCkgPT4ge1xuICAgICAgY29uc3QgdmVydGV4SW5kZXggPSB2ZXJ0ZXguZ2V0SW5kZXgoKTtcblxuICAgICAgaWYgKHZlcnRleEluZGV4ID4gZGVsZXRlZFZlcnRleEluZGV4KSB7XG4gICAgICAgIHZlcnRleC5kZWNyZW1lbnRJbmRleCgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKGZpbHRlckJhY2tFZGdlcykge1xuICAgICAgdGhpcy5maWx0ZXJCYWNrRWRnZXMoKTtcbiAgICB9XG4gIH1cblxuICBhZGRWZXJ0ZXhlc0J5VmVydGV4TmFtZXModmVydGV4TmFtZXMpIHtcbiAgICB2ZXJ0ZXhOYW1lcy5mb3JFYWNoKCh2ZXJ0ZXhOYW1lKSA9PiB7XG4gICAgICB0aGlzLmFkZFZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJlbW92ZVZlcnRleGVzQnlWZXJ0ZXhOYW1lcyh2ZXJ0ZXhOYW1lcywgZmlsdGVyQmFja0VkZ2VzID0gdHJ1ZSkge1xuICAgIHZlcnRleE5hbWVzLmZvckVhY2goKHZlcnRleE5hbWUpID0+IHtcbiAgICAgIGNvbnN0IGZpbHRlckJhY2tFZGdlcyA9IGZhbHNlO1xuXG4gICAgICB0aGlzLnJlbW92ZVZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lLCBmaWx0ZXJCYWNrRWRnZXMpO1xuICAgIH0pO1xuXG4gICAgaWYgKGZpbHRlckJhY2tFZGdlcykge1xuICAgICAgdGhpcy5maWx0ZXJCYWNrRWRnZXMoKTtcbiAgICB9XG4gIH1cblxuICBhZGRFZGdlKGVkZ2UpIHtcbiAgICBjb25zdCBzb3VyY2VWZXJ0ZXhOYW1lID0gZWRnZS5nZXRTb3VyY2VWZXJ0ZXhOYW1lKCksXG4gICAgICAgICAgdGFyZ2V0VmVydGV4TmFtZSA9IGVkZ2UuZ2V0VGFyZ2V0VmVydGV4TmFtZSgpO1xuXG4gICAgaWYgKHNvdXJjZVZlcnRleE5hbWUgPT09IHRhcmdldFZlcnRleE5hbWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzb3VyY2VWZXJ0ZXggPSB0aGlzLmFkZFZlcnRleEJ5VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lKSxcbiAgICAgICAgICB0YXJnZXRWZXJ0ZXggPSB0aGlzLmFkZFZlcnRleEJ5VmVydGV4TmFtZSh0YXJnZXRWZXJ0ZXhOYW1lKSxcbiAgICAgICAgICBlZGdlUHJlc2VudCA9IHNvdXJjZVZlcnRleC5pc0VkZ2VQcmVzZW50QnlUYXJnZXRWZXJ0ZXgodGFyZ2V0VmVydGV4KTtcblxuICAgIGlmIChlZGdlUHJlc2VudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHNvdXJjZVZlcnRleEluZGV4ID0gc291cmNlVmVydGV4LmdldEluZGV4KCksXG4gICAgICAgICAgdGFyZ2V0VmVydGV4SW5kZXggPSB0YXJnZXRWZXJ0ZXguZ2V0SW5kZXgoKTtcblxuICAgIGlmIChzb3VyY2VWZXJ0ZXhJbmRleCA+IHRhcmdldFZlcnRleEluZGV4KSB7XG4gICAgICB0aGlzLnJlb3JkZXJWZXJ0ZXhlc0J5U291cmNlVmVydGV4QW5kVGFyZ2V0VmVydGV4KHNvdXJjZVZlcnRleCwgdGFyZ2V0VmVydGV4KTtcbiAgICB9XG5cbiAgICBjb25zdCBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCA9IHNvdXJjZVZlcnRleCwgLy8vXG4gICAgICAgICAgaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ID0gdGFyZ2V0VmVydGV4OyAvLy9cblxuICAgIGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4LmFkZEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleChpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgpO1xuXG4gICAgaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4LmFkZEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KTtcbiAgfVxuXG4gIGFkZEVkZ2VzKGVkZ2VzKSB7XG4gICAgZWRnZXMuZm9yRWFjaCgoZWRnZSkgPT4ge1xuICAgICAgdGhpcy5hZGRFZGdlKGVkZ2UpO1xuICAgIH0pO1xuICB9XG5cbiAgcmVtb3ZlRWRnZShlZGdlLCByZW1vdmVTdHJhbmRlZFZlcnRleGVzID0gZmFsc2UpIHtcbiAgICBjb25zdCBlZGdlUHJlc2VudCA9IHRoaXMuaXNFZGdlUHJlc2VudChlZGdlKTtcblxuICAgIGlmICghZWRnZVByZXNlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBlZGdlQ3ljbGljID0gdGhpcy5pc0VkZ2VDeWNsaWMoZWRnZSksXG4gICAgICAgICAgZmlsdGVyQmFja0VkZ2VzID0gZWRnZUN5Y2xpYywgLy8vXG4gICAgICAgICAgc291cmNlVmVydGV4TmFtZSA9IGVkZ2UuZ2V0U291cmNlVmVydGV4TmFtZSgpLFxuICAgICAgICAgIHRhcmdldFZlcnRleE5hbWUgPSBlZGdlLmdldFRhcmdldFZlcnRleE5hbWUoKSxcbiAgICAgICAgICBzb3VyY2VWZXJ0ZXggPSB0aGlzLmdldFZlcnRleEJ5VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lKSxcbiAgICAgICAgICB0YXJnZXRWZXJ0ZXggPSB0aGlzLmdldFZlcnRleEJ5VmVydGV4TmFtZSh0YXJnZXRWZXJ0ZXhOYW1lKTtcblxuICAgIHNvdXJjZVZlcnRleC5yZW1vdmVJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgodGFyZ2V0VmVydGV4KTtcblxuICAgIHRhcmdldFZlcnRleC5yZW1vdmVJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleChzb3VyY2VWZXJ0ZXgpO1xuXG4gICAgaWYgKHJlbW92ZVN0cmFuZGVkVmVydGV4ZXMpIHtcbiAgICAgIGNvbnN0IGZpbHRlckJhY2tFZGdlcyA9IGZhbHNlLFxuICAgICAgICAgICAgc291cmNlVmVydGV4U3RyYW5kZWQgPSBzb3VyY2VWZXJ0ZXguaXNTdHJhbmRlZCgpLFxuICAgICAgICAgICAgdGFyZ2V0VmVydGV4U3RyYW5kZWQgPSB0YXJnZXRWZXJ0ZXguaXNTdHJhbmRlZCgpO1xuXG4gICAgICBpZiAoc291cmNlVmVydGV4U3RyYW5kZWQpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVWZXJ0ZXhCeVZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSwgZmlsdGVyQmFja0VkZ2VzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRhcmdldFZlcnRleFN0cmFuZGVkKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlVmVydGV4QnlWZXJ0ZXhOYW1lKHRhcmdldFZlcnRleE5hbWUsIGZpbHRlckJhY2tFZGdlcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGZpbHRlckJhY2tFZGdlcykge1xuICAgICAgdGhpcy5maWx0ZXJCYWNrRWRnZXMoKTtcbiAgICB9XG4gIH1cblxuICByZW1vdmVFZGdlcyhlZGdlcywgcmVtb3ZlU3RyYW5kZWRWZXJ0ZXhlcyA9IGZhbHNlKSB7XG4gICAgZWRnZXMuZm9yRWFjaCgoZWRnZSkgPT4ge1xuICAgICAgdGhpcy5yZW1vdmVFZGdlKGVkZ2UsIHJlbW92ZVN0cmFuZGVkVmVydGV4ZXMpO1xuICAgIH0pO1xuICB9XG5cbiAgcmVtb3ZlQWxsRWRnZXNBbmRWZXJ0ZXhlcygpIHtcbiAgICB0aGlzLnZlcnRleE1hcCA9IHt9O1xuICB9XG5cbiAgYWRkRWRnZUJ5U291cmNlVmVydGV4TmFtZUFuZFRhcmdldFZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSwgdGFyZ2V0VmVydGV4TmFtZSkge1xuICAgIGNvbnN0IGVkZ2UgPSBFZGdlLmZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKTtcblxuICAgIHRoaXMuYWRkRWRnZShlZGdlKTtcbiAgfVxuXG4gIHJlb3JkZXJWZXJ0ZXhlc0J5U291cmNlVmVydGV4QW5kVGFyZ2V0VmVydGV4KHNvdXJjZVZlcnRleCwgdGFyZ2V0VmVydGV4KSB7XG4gICAgY29uc3Qgc291cmNlVmVydGV4Rm9yd2FyZHNSZWFjaGFibGUgPSB0YXJnZXRWZXJ0ZXguaXNWZXJ0ZXhGb3J3YXJkc1JlYWNoYWJsZShzb3VyY2VWZXJ0ZXgpO1xuXG4gICAgaWYgKHNvdXJjZVZlcnRleEZvcndhcmRzUmVhY2hhYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyA9IHRhcmdldFZlcnRleC5yZXRyaWV2ZUZvcndhcmRzUmVhY2hhYmxlVmVydGV4ZXMoKSxcbiAgICAgICAgICBiYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyA9IHNvdXJjZVZlcnRleC5yZXRyaWV2ZUJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzKCk7XG5cbiAgICBvcmRlclZlcnRleGVzKGJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzKTtcblxuICAgIG9yZGVyVmVydGV4ZXMoZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyk7XG5cbiAgICBjb25zdCByZWFjaGFibGVWZXJ0ZXhlcyA9IFtcbiAgICAgICAgICAgIC4uLmJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzLFxuICAgICAgICAgICAgLi4uZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlc1xuICAgICAgICAgIF0sXG4gICAgICAgICAgcmVhY2hhYmxlSW5kZXhlcyA9IGluZGV4ZXNGcm9tVmVydGV4ZXMocmVhY2hhYmxlVmVydGV4ZXMpO1xuXG4gICAgb3JkZXJJbmRleGVzKHJlYWNoYWJsZUluZGV4ZXMpO1xuXG4gICAgcmVhY2hhYmxlVmVydGV4ZXMuZm9yRWFjaCgocmVhY2hhYmxlVmVydGV4LCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgcmVhY2hhYmxlSW5kZXggPSByZWFjaGFibGVJbmRleGVzW2luZGV4XTtcblxuICAgICAgaW5kZXggPSByZWFjaGFibGVJbmRleDsgLy8vXG5cbiAgICAgIHJlYWNoYWJsZVZlcnRleC5zZXRJbmRleChpbmRleCk7XG4gICAgfSk7XG4gIH1cblxuICBpc0VkZ2VDeWNsaWMoZWRnZSkge1xuICAgIGNvbnN0IHNvdXJjZVZlcnRleE5hbWUgPSBlZGdlLmdldFNvdXJjZVZlcnRleE5hbWUoKSxcbiAgICAgICAgICB0YXJnZXRWZXJ0ZXhOYW1lID0gZWRnZS5nZXRUYXJnZXRWZXJ0ZXhOYW1lKCksXG4gICAgICAgICAgc291cmNlVmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSksXG4gICAgICAgICAgdGFyZ2V0VmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSksXG4gICAgICAgICAgc291cmNlVmVydGV4UmVhY2hhYmxlID0gdGFyZ2V0VmVydGV4LmlzVmVydGV4UmVhY2hhYmxlKHNvdXJjZVZlcnRleCksXG4gICAgICAgICAgZWRnZUN5Y2xpYyA9IHNvdXJjZVZlcnRleFJlYWNoYWJsZTsgLy8vXG5cbiAgICByZXR1cm4gZWRnZUN5Y2xpYztcbiAgfVxuXG4gIGZpbHRlckJhY2tFZGdlcygpIHtcbiAgICBjb25zdCBiYWNrRWRnZXMgPSB0aGlzLmdldEJhY2tFZGdlcygpLFxuICAgICAgICAgIGVkZ2VzID0gYmFja0VkZ2VzOyAgLy8vXG5cbiAgICBlZGdlcy5mb3JFYWNoKChlZGdlKSA9PiB7XG4gICAgICBjb25zdCBzb3VyY2VWZXJ0ZXhOYW1lID0gZWRnZS5nZXRTb3VyY2VWZXJ0ZXhOYW1lKCksXG4gICAgICAgICAgICB0YXJnZXRWZXJ0ZXhOYW1lID0gZWRnZS5nZXRUYXJnZXRWZXJ0ZXhOYW1lKCksXG4gICAgICAgICAgICBzb3VyY2VWZXJ0ZXggPSB0aGlzLmdldFZlcnRleEJ5VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lKSxcbiAgICAgICAgICAgIHRhcmdldFZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHRhcmdldFZlcnRleE5hbWUpLFxuICAgICAgICAgICAgc291cmNlVmVydGV4Rm9yd2FyZHNSZWFjaGFibGUgPSB0YXJnZXRWZXJ0ZXguaXNWZXJ0ZXhGb3J3YXJkc1JlYWNoYWJsZShzb3VyY2VWZXJ0ZXgpO1xuXG4gICAgICBpZiAoIXNvdXJjZVZlcnRleEZvcndhcmRzUmVhY2hhYmxlKSB7XG4gICAgICAgIHRoaXMucmVvcmRlclZlcnRleGVzQnlTb3VyY2VWZXJ0ZXhBbmRUYXJnZXRWZXJ0ZXgoc291cmNlVmVydGV4LCB0YXJnZXRWZXJ0ZXgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgc2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUsIHZlcnRleCkge1xuICAgIHRoaXMudmVydGV4TWFwW3ZlcnRleE5hbWVdID0gdmVydGV4O1xuICB9XG5cbiAgZGVsZXRlVmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpIHtcbiAgICBkZWxldGUgdGhpcy52ZXJ0ZXhNYXBbdmVydGV4TmFtZV07XG4gIH1cblxuICBzdGF0aWMgZnJvbU5vdGhpbmcoKSB7XG4gICAgY29uc3QgdmVydGV4TWFwID0ge30sXG4gICAgICAgICAgZGlyZWN0ZWRHcmFwaCA9IG5ldyBEaXJlY3RlZEdyYXBoKHZlcnRleE1hcCk7XG4gICAgXG4gICAgcmV0dXJuIGRpcmVjdGVkR3JhcGg7ICAgIFxuICB9XG59XG4iXSwibmFtZXMiOlsiRGlyZWN0ZWRHcmFwaCIsImZpcnN0IiwiYXJyYXlVdGlsaXRpZXMiLCJ2ZXJ0ZXhNYXAiLCJnZXRWZXJ0ZXhNYXAiLCJnZXRWZXJ0ZXhlcyIsInZlcnRleE1hcFZhbHVlcyIsIk9iamVjdCIsInZhbHVlcyIsInZlcnRleGVzIiwiZ2V0VmVydGV4TmFtZXMiLCJ2ZXJ0ZXhNYXBLZXlzIiwia2V5cyIsInZlcnRleE5hbWVzIiwiZ2V0T3JkZXJlZFZlcnRleE5hbWVzIiwib3JkZXJWZXJ0ZXhlcyIsIm9yZGVyZWRWZXJ0ZXhlcyIsIm9yZGVyZWRWZXJ0ZXhOYW1lcyIsInZlcnRleE5hbWVzRnJvbVZlcnRleGVzIiwiZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lIiwidmVydGV4TmFtZSIsInZlcnRleFByZXNlbnQiLCJpc1ZlcnRleFByZXNlbnRCeVZlcnRleE5hbWUiLCJ2ZXJ0ZXgiLCJnZXRFZGdlc0J5U291cmNlVmVydGV4TmFtZSIsInNvdXJjZVZlcnRleE5hbWUiLCJlZGdlcyIsInNvdXJjZVZlcnRleCIsImltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzIiwiZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMiLCJ0YXJnZXRWZXJ0ZXhlcyIsImZvckVhY2giLCJ0YXJnZXRWZXJ0ZXgiLCJlZGdlIiwiRWRnZSIsImZyb21Tb3VyY2VWZXJ0ZXhBbmRUYXJnZXRWZXJ0ZXgiLCJwdXNoIiwiZ2V0RWRnZXNCeVRhcmdldFZlcnRleE5hbWUiLCJ0YXJnZXRWZXJ0ZXhOYW1lIiwiaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhlcyIsImdldEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMiLCJzb3VyY2VWZXJ0ZXhlcyIsImFyZUN5Y2xlc1ByZXNlbnQiLCJjeWNsZXNQcmVzZW50Iiwic29tZSIsInNvdXJjZVZlcnRleEluZGV4IiwiZ2V0SW5kZXgiLCJjeWNsaWNFZGdlUHJlc2VudCIsInNvbWVJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgiLCJpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgiLCJ0YXJnZXRWZXJ0ZXhJbmRleCIsImdldEZpcnN0Q3ljbGUiLCJmaXJzdEN5Y2xlIiwiYmFja0VkZ2VzIiwiZ2V0QmFja0VkZ2VzIiwiZmlyc3RCYWNrRWRnZSIsImRpcmVjdGVkR3JhcGgiLCJiYWNrRWRnZSIsImN5Y2xlIiwiQ3ljbGUiLCJmcm9tQmFja0VkZ2VBbmREaXJlY3RlZEdyYXBoIiwiZm9yRWFjaEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsImlzRWRnZVByZXNlbnQiLCJlZGdlUHJlc2VudCIsImdldFNvdXJjZVZlcnRleE5hbWUiLCJnZXRUYXJnZXRWZXJ0ZXhOYW1lIiwiaXNFZGdlUHJlc2VudEJ5VGFyZ2V0VmVydGV4IiwidmVydGV4TmFtZXNJbmNsdWRlc1ZlcnRleE5hbWUiLCJpbmNsdWRlcyIsImdldEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleE5hbWVzQnlWZXJ0ZXhOYW1lIiwiaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4TmFtZXMiLCJnZXRJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lcyIsImdldEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXNCeVZlcnRleE5hbWUiLCJpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleE5hbWVzIiwiZ2V0SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcyIsImlzRWRnZVByZXNlbnRCeVNvdXJjZVZlcnRleE5hbWVBbmRUYXJnZXRWZXJ0ZXhOYW1lIiwiZnJvbVNvdXJjZVZlcnRleE5hbWVBbmRUYXJnZXRWZXJ0ZXhOYW1lIiwiYWRkVmVydGV4QnlWZXJ0ZXhOYW1lIiwidmVydGV4TmFtZXNMZW5ndGgiLCJsZW5ndGgiLCJuYW1lIiwiaW5kZXgiLCJWZXJ0ZXgiLCJmcm9tTmFtZUFuZEluZGV4Iiwic2V0VmVydGV4QnlWZXJ0ZXhOYW1lIiwicmVtb3ZlVmVydGV4QnlWZXJ0ZXhOYW1lIiwiZmlsdGVyQmFja0VkZ2VzIiwiaW1tZWRpYXRlU3VjY2Vzc1ZlcnRleCIsImltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4IiwicmVtb3ZlSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJmb3JFYWNoSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJyZW1vdmVJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgiLCJkZWxldGVWZXJ0ZXhCeVZlcnRleE5hbWUiLCJkZWxldGVkVmVydGV4IiwiZGVsZXRlZFZlcnRleEluZGV4IiwidmVydGV4SW5kZXgiLCJkZWNyZW1lbnRJbmRleCIsImFkZFZlcnRleGVzQnlWZXJ0ZXhOYW1lcyIsInJlbW92ZVZlcnRleGVzQnlWZXJ0ZXhOYW1lcyIsImFkZEVkZ2UiLCJyZW9yZGVyVmVydGV4ZXNCeVNvdXJjZVZlcnRleEFuZFRhcmdldFZlcnRleCIsImFkZEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsImFkZEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4IiwiYWRkRWRnZXMiLCJyZW1vdmVFZGdlIiwicmVtb3ZlU3RyYW5kZWRWZXJ0ZXhlcyIsImVkZ2VDeWNsaWMiLCJpc0VkZ2VDeWNsaWMiLCJzb3VyY2VWZXJ0ZXhTdHJhbmRlZCIsImlzU3RyYW5kZWQiLCJ0YXJnZXRWZXJ0ZXhTdHJhbmRlZCIsInJlbW92ZUVkZ2VzIiwicmVtb3ZlQWxsRWRnZXNBbmRWZXJ0ZXhlcyIsImFkZEVkZ2VCeVNvdXJjZVZlcnRleE5hbWVBbmRUYXJnZXRWZXJ0ZXhOYW1lIiwic291cmNlVmVydGV4Rm9yd2FyZHNSZWFjaGFibGUiLCJpc1ZlcnRleEZvcndhcmRzUmVhY2hhYmxlIiwiZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyIsInJldHJpZXZlRm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyIsImJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzIiwicmV0cmlldmVCYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyIsInJlYWNoYWJsZVZlcnRleGVzIiwicmVhY2hhYmxlSW5kZXhlcyIsImluZGV4ZXNGcm9tVmVydGV4ZXMiLCJvcmRlckluZGV4ZXMiLCJyZWFjaGFibGVWZXJ0ZXgiLCJyZWFjaGFibGVJbmRleCIsInNldEluZGV4Iiwic291cmNlVmVydGV4UmVhY2hhYmxlIiwiaXNWZXJ0ZXhSZWFjaGFibGUiLCJmcm9tTm90aGluZyJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7K0JBYUE7OztlQUFxQkE7OzsyQkFYVTs2REFF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
package/lib/edge.js CHANGED
@@ -27,6 +27,10 @@ class Edge {
27
27
  const matches = this.sourceVertexName === vertexName || this.targetVertexName === vertexName;
28
28
  return matches;
29
29
  }
30
+ matchVertexNames(sourceVertexName, targetVertexName) {
31
+ const matches = this.sourceVertexName === sourceVertexName && this.targetVertexName === targetVertexName;
32
+ return matches;
33
+ }
30
34
  matchSourceVertexName(sourceVertexName) {
31
35
  const matches = this.sourceVertexName === sourceVertexName;
32
36
  return matches;
@@ -35,9 +39,9 @@ class Edge {
35
39
  const matches = this.targetVertexName === targetVertexName;
36
40
  return matches;
37
41
  }
38
- matchVertexNames(sourceVertexName, targetVertexName) {
39
- const matches = this.sourceVertexName === sourceVertexName && this.targetVertexName === targetVertexName;
40
- return matches;
42
+ static fromSourceVertexAndTargetVertex(sourceVertex, targetVertex) {
43
+ const sourceVertexName = sourceVertex.getName(), targetVertexName = targetVertex.getName(), edge = new Edge(sourceVertexName, targetVertexName);
44
+ return edge;
41
45
  }
42
46
  static fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName) {
43
47
  const edge = new Edge(sourceVertexName, targetVertexName);
@@ -45,4 +49,4 @@ class Edge {
45
49
  }
46
50
  }
47
51
 
48
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9lZGdlLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFZGdlIHtcbiAgY29uc3RydWN0b3Ioc291cmNlVmVydGV4TmFtZSwgdGFyZ2V0VmVydGV4TmFtZSkge1xuICAgIHRoaXMuc291cmNlVmVydGV4TmFtZSA9IHNvdXJjZVZlcnRleE5hbWU7XG4gICAgdGhpcy50YXJnZXRWZXJ0ZXhOYW1lID0gdGFyZ2V0VmVydGV4TmFtZTtcbiAgfVxuICBcbiAgZ2V0U291cmNlVmVydGV4TmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5zb3VyY2VWZXJ0ZXhOYW1lO1xuICB9XG4gIFxuICBnZXRUYXJnZXRWZXJ0ZXhOYW1lKCkge1xuICAgIHJldHVybiB0aGlzLnRhcmdldFZlcnRleE5hbWU7XG4gIH1cbiAgXG4gIG1hdGNoKGVkZ2UpIHtcbiAgICBjb25zdCBzb3VyY2VWZXJ0ZXhOYW1lID0gZWRnZS5nZXRTb3VyY2VWZXJ0ZXhOYW1lKCksXG4gICAgICAgICAgdGFyZ2V0VmVydGV4TmFtZSA9IGVkZ2UuZ2V0VGFyZ2V0VmVydGV4TmFtZSgpLFxuICAgICAgICAgIG1hdGNoZXMgPSAoKHRoaXMuc291cmNlVmVydGV4TmFtZSA9PT0gc291cmNlVmVydGV4TmFtZSkgJiYgKHRoaXMudGFyZ2V0VmVydGV4TmFtZSA9PT0gdGFyZ2V0VmVydGV4TmFtZSkpO1xuICAgIFxuICAgIHJldHVybiBtYXRjaGVzO1xuICB9XG5cbiAgbWF0Y2hWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpIHtcbiAgICBjb25zdCBtYXRjaGVzID0gKCh0aGlzLnNvdXJjZVZlcnRleE5hbWUgPT09IHZlcnRleE5hbWUpIHx8ICh0aGlzLnRhcmdldFZlcnRleE5hbWUgPT09IHZlcnRleE5hbWUpKTtcblxuICAgIHJldHVybiBtYXRjaGVzO1xuICB9XG5cbiAgbWF0Y2hTb3VyY2VWZXJ0ZXhOYW1lKHNvdXJjZVZlcnRleE5hbWUpIHtcbiAgICBjb25zdCBtYXRjaGVzID0gKHRoaXMuc291cmNlVmVydGV4TmFtZSA9PT0gc291cmNlVmVydGV4TmFtZSk7XG5cbiAgICByZXR1cm4gbWF0Y2hlcztcbiAgfVxuXG4gIG1hdGNoVGFyZ2V0VmVydGV4TmFtZSh0YXJnZXRWZXJ0ZXhOYW1lKSB7XG4gICAgY29uc3QgbWF0Y2hlcyA9ICh0aGlzLnRhcmdldFZlcnRleE5hbWUgPT09IHRhcmdldFZlcnRleE5hbWUpO1xuXG4gICAgcmV0dXJuIG1hdGNoZXM7XG4gIH1cblxuICBtYXRjaFZlcnRleE5hbWVzKHNvdXJjZVZlcnRleE5hbWUsIHRhcmdldFZlcnRleE5hbWUpIHtcbiAgICBjb25zdCBtYXRjaGVzID0gKCh0aGlzLnNvdXJjZVZlcnRleE5hbWUgPT09IHNvdXJjZVZlcnRleE5hbWUpICYmICh0aGlzLnRhcmdldFZlcnRleE5hbWUgPT09IHRhcmdldFZlcnRleE5hbWUpKTtcbiAgICBcbiAgICByZXR1cm4gbWF0Y2hlcztcbiAgfVxuXG4gIHN0YXRpYyBmcm9tU291cmNlVmVydGV4TmFtZUFuZFRhcmdldFZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSwgdGFyZ2V0VmVydGV4TmFtZSkge1xuICAgIGNvbnN0IGVkZ2UgPSBuZXcgRWRnZShzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKTtcblxuICAgIHJldHVybiBlZGdlO1xuICB9XG59XG4iXSwibmFtZXMiOlsiRWRnZSIsInNvdXJjZVZlcnRleE5hbWUiLCJ0YXJnZXRWZXJ0ZXhOYW1lIiwiZ2V0U291cmNlVmVydGV4TmFtZSIsImdldFRhcmdldFZlcnRleE5hbWUiLCJtYXRjaCIsImVkZ2UiLCJtYXRjaGVzIiwibWF0Y2hWZXJ0ZXhOYW1lIiwidmVydGV4TmFtZSIsIm1hdGNoU291cmNlVmVydGV4TmFtZSIsIm1hdGNoVGFyZ2V0VmVydGV4TmFtZSIsIm1hdGNoVmVydGV4TmFtZXMiLCJmcm9tU291cmNlVmVydGV4TmFtZUFuZFRhcmdldFZlcnRleE5hbWUiXSwibWFwcGluZ3MiOiJBQUFBOzs7OytCQUVBOzs7ZUFBcUJBOzs7QUFBTixNQUFNQTtJQUNuQixZQUFZQyxnQkFBZ0IsRUFBRUMsZ0JBQWdCLENBQUU7UUFDOUMsSUFBSSxDQUFDRCxnQkFBZ0IsR0FBR0E7UUFDeEIsSUFBSSxDQUFDQyxnQkFBZ0IsR0FBR0E7SUFDMUI7SUFFQUMsc0JBQXNCO1FBQ3BCLE9BQU8sSUFBSSxDQUFDRixnQkFBZ0I7SUFDOUI7SUFFQUcsc0JBQXNCO1FBQ3BCLE9BQU8sSUFBSSxDQUFDRixnQkFBZ0I7SUFDOUI7SUFFQUcsTUFBTUMsSUFBSSxFQUFFO1FBQ1YsTUFBTUwsbUJBQW1CSyxLQUFLSCxtQkFBbUIsSUFDM0NELG1CQUFtQkksS0FBS0YsbUJBQW1CLElBQzNDRyxVQUFXLEFBQUMsSUFBSSxDQUFDTixnQkFBZ0IsS0FBS0Esb0JBQXNCLElBQUksQ0FBQ0MsZ0JBQWdCLEtBQUtBO1FBRTVGLE9BQU9LO0lBQ1Q7SUFFQUMsZ0JBQWdCQyxVQUFVLEVBQUU7UUFDMUIsTUFBTUYsVUFBVyxBQUFDLElBQUksQ0FBQ04sZ0JBQWdCLEtBQUtRLGNBQWdCLElBQUksQ0FBQ1AsZ0JBQWdCLEtBQUtPO1FBRXRGLE9BQU9GO0lBQ1Q7SUFFQUcsc0JBQXNCVCxnQkFBZ0IsRUFBRTtRQUN0QyxNQUFNTSxVQUFXLElBQUksQ0FBQ04sZ0JBQWdCLEtBQUtBO1FBRTNDLE9BQU9NO0lBQ1Q7SUFFQUksc0JBQXNCVCxnQkFBZ0IsRUFBRTtRQUN0QyxNQUFNSyxVQUFXLElBQUksQ0FBQ0wsZ0JBQWdCLEtBQUtBO1FBRTNDLE9BQU9LO0lBQ1Q7SUFFQUssaUJBQWlCWCxnQkFBZ0IsRUFBRUMsZ0JBQWdCLEVBQUU7UUFDbkQsTUFBTUssVUFBVyxBQUFDLElBQUksQ0FBQ04sZ0JBQWdCLEtBQUtBLG9CQUFzQixJQUFJLENBQUNDLGdCQUFnQixLQUFLQTtRQUU1RixPQUFPSztJQUNUO0lBRUEsT0FBT00sd0NBQXdDWixnQkFBZ0IsRUFBRUMsZ0JBQWdCLEVBQUU7UUFDakYsTUFBTUksT0FBTyxJQUFJTixLQUFLQyxrQkFBa0JDO1FBRXhDLE9BQU9JO0lBQ1Q7QUFDRiJ9
52
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9lZGdlLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFZGdlIHtcbiAgY29uc3RydWN0b3Ioc291cmNlVmVydGV4TmFtZSwgdGFyZ2V0VmVydGV4TmFtZSkge1xuICAgIHRoaXMuc291cmNlVmVydGV4TmFtZSA9IHNvdXJjZVZlcnRleE5hbWU7XG4gICAgdGhpcy50YXJnZXRWZXJ0ZXhOYW1lID0gdGFyZ2V0VmVydGV4TmFtZTtcbiAgfVxuICBcbiAgZ2V0U291cmNlVmVydGV4TmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5zb3VyY2VWZXJ0ZXhOYW1lO1xuICB9XG4gIFxuICBnZXRUYXJnZXRWZXJ0ZXhOYW1lKCkge1xuICAgIHJldHVybiB0aGlzLnRhcmdldFZlcnRleE5hbWU7XG4gIH1cbiAgXG4gIG1hdGNoKGVkZ2UpIHtcbiAgICBjb25zdCBzb3VyY2VWZXJ0ZXhOYW1lID0gZWRnZS5nZXRTb3VyY2VWZXJ0ZXhOYW1lKCksXG4gICAgICAgICAgdGFyZ2V0VmVydGV4TmFtZSA9IGVkZ2UuZ2V0VGFyZ2V0VmVydGV4TmFtZSgpLFxuICAgICAgICAgIG1hdGNoZXMgPSAoKHRoaXMuc291cmNlVmVydGV4TmFtZSA9PT0gc291cmNlVmVydGV4TmFtZSkgJiYgKHRoaXMudGFyZ2V0VmVydGV4TmFtZSA9PT0gdGFyZ2V0VmVydGV4TmFtZSkpO1xuICAgIFxuICAgIHJldHVybiBtYXRjaGVzO1xuICB9XG5cbiAgbWF0Y2hWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpIHtcbiAgICBjb25zdCBtYXRjaGVzID0gKCh0aGlzLnNvdXJjZVZlcnRleE5hbWUgPT09IHZlcnRleE5hbWUpIHx8ICh0aGlzLnRhcmdldFZlcnRleE5hbWUgPT09IHZlcnRleE5hbWUpKTtcblxuICAgIHJldHVybiBtYXRjaGVzO1xuICB9XG5cbiAgbWF0Y2hWZXJ0ZXhOYW1lcyhzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKSB7XG4gICAgY29uc3QgbWF0Y2hlcyA9ICgodGhpcy5zb3VyY2VWZXJ0ZXhOYW1lID09PSBzb3VyY2VWZXJ0ZXhOYW1lKSAmJiAodGhpcy50YXJnZXRWZXJ0ZXhOYW1lID09PSB0YXJnZXRWZXJ0ZXhOYW1lKSk7XG5cbiAgICByZXR1cm4gbWF0Y2hlcztcbiAgfVxuXG4gIG1hdGNoU291cmNlVmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lKSB7XG4gICAgY29uc3QgbWF0Y2hlcyA9ICh0aGlzLnNvdXJjZVZlcnRleE5hbWUgPT09IHNvdXJjZVZlcnRleE5hbWUpO1xuXG4gICAgcmV0dXJuIG1hdGNoZXM7XG4gIH1cblxuICBtYXRjaFRhcmdldFZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSkge1xuICAgIGNvbnN0IG1hdGNoZXMgPSAodGhpcy50YXJnZXRWZXJ0ZXhOYW1lID09PSB0YXJnZXRWZXJ0ZXhOYW1lKTtcblxuICAgIHJldHVybiBtYXRjaGVzO1xuICB9XG5cbiAgc3RhdGljIGZyb21Tb3VyY2VWZXJ0ZXhBbmRUYXJnZXRWZXJ0ZXgoc291cmNlVmVydGV4LCB0YXJnZXRWZXJ0ZXgpIHtcbiAgICBjb25zdCBzb3VyY2VWZXJ0ZXhOYW1lID0gc291cmNlVmVydGV4LmdldE5hbWUoKSxcbiAgICAgICAgICB0YXJnZXRWZXJ0ZXhOYW1lID0gdGFyZ2V0VmVydGV4LmdldE5hbWUoKSxcbiAgICAgICAgICBlZGdlID0gbmV3IEVkZ2Uoc291cmNlVmVydGV4TmFtZSwgdGFyZ2V0VmVydGV4TmFtZSk7XG5cbiAgICByZXR1cm4gZWRnZTtcbiAgfVxuXG4gIHN0YXRpYyBmcm9tU291cmNlVmVydGV4TmFtZUFuZFRhcmdldFZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSwgdGFyZ2V0VmVydGV4TmFtZSkge1xuICAgIGNvbnN0IGVkZ2UgPSBuZXcgRWRnZShzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKTtcblxuICAgIHJldHVybiBlZGdlO1xuICB9XG59XG4iXSwibmFtZXMiOlsiRWRnZSIsInNvdXJjZVZlcnRleE5hbWUiLCJ0YXJnZXRWZXJ0ZXhOYW1lIiwiZ2V0U291cmNlVmVydGV4TmFtZSIsImdldFRhcmdldFZlcnRleE5hbWUiLCJtYXRjaCIsImVkZ2UiLCJtYXRjaGVzIiwibWF0Y2hWZXJ0ZXhOYW1lIiwidmVydGV4TmFtZSIsIm1hdGNoVmVydGV4TmFtZXMiLCJtYXRjaFNvdXJjZVZlcnRleE5hbWUiLCJtYXRjaFRhcmdldFZlcnRleE5hbWUiLCJmcm9tU291cmNlVmVydGV4QW5kVGFyZ2V0VmVydGV4Iiwic291cmNlVmVydGV4IiwidGFyZ2V0VmVydGV4IiwiZ2V0TmFtZSIsImZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZSJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7K0JBRUE7OztlQUFxQkE7OztBQUFOLE1BQU1BO0lBQ25CLFlBQVlDLGdCQUFnQixFQUFFQyxnQkFBZ0IsQ0FBRTtRQUM5QyxJQUFJLENBQUNELGdCQUFnQixHQUFHQTtRQUN4QixJQUFJLENBQUNDLGdCQUFnQixHQUFHQTtJQUMxQjtJQUVBQyxzQkFBc0I7UUFDcEIsT0FBTyxJQUFJLENBQUNGLGdCQUFnQjtJQUM5QjtJQUVBRyxzQkFBc0I7UUFDcEIsT0FBTyxJQUFJLENBQUNGLGdCQUFnQjtJQUM5QjtJQUVBRyxNQUFNQyxJQUFJLEVBQUU7UUFDVixNQUFNTCxtQkFBbUJLLEtBQUtILG1CQUFtQixJQUMzQ0QsbUJBQW1CSSxLQUFLRixtQkFBbUIsSUFDM0NHLFVBQVcsQUFBQyxJQUFJLENBQUNOLGdCQUFnQixLQUFLQSxvQkFBc0IsSUFBSSxDQUFDQyxnQkFBZ0IsS0FBS0E7UUFFNUYsT0FBT0s7SUFDVDtJQUVBQyxnQkFBZ0JDLFVBQVUsRUFBRTtRQUMxQixNQUFNRixVQUFXLEFBQUMsSUFBSSxDQUFDTixnQkFBZ0IsS0FBS1EsY0FBZ0IsSUFBSSxDQUFDUCxnQkFBZ0IsS0FBS087UUFFdEYsT0FBT0Y7SUFDVDtJQUVBRyxpQkFBaUJULGdCQUFnQixFQUFFQyxnQkFBZ0IsRUFBRTtRQUNuRCxNQUFNSyxVQUFXLEFBQUMsSUFBSSxDQUFDTixnQkFBZ0IsS0FBS0Esb0JBQXNCLElBQUksQ0FBQ0MsZ0JBQWdCLEtBQUtBO1FBRTVGLE9BQU9LO0lBQ1Q7SUFFQUksc0JBQXNCVixnQkFBZ0IsRUFBRTtRQUN0QyxNQUFNTSxVQUFXLElBQUksQ0FBQ04sZ0JBQWdCLEtBQUtBO1FBRTNDLE9BQU9NO0lBQ1Q7SUFFQUssc0JBQXNCVixnQkFBZ0IsRUFBRTtRQUN0QyxNQUFNSyxVQUFXLElBQUksQ0FBQ0wsZ0JBQWdCLEtBQUtBO1FBRTNDLE9BQU9LO0lBQ1Q7SUFFQSxPQUFPTSxnQ0FBZ0NDLFlBQVksRUFBRUMsWUFBWSxFQUFFO1FBQ2pFLE1BQU1kLG1CQUFtQmEsYUFBYUUsT0FBTyxJQUN2Q2QsbUJBQW1CYSxhQUFhQyxPQUFPLElBQ3ZDVixPQUFPLElBQUlOLEtBQUtDLGtCQUFrQkM7UUFFeEMsT0FBT0k7SUFDVDtJQUVBLE9BQU9XLHdDQUF3Q2hCLGdCQUFnQixFQUFFQyxnQkFBZ0IsRUFBRTtRQUNqRixNQUFNSSxPQUFPLElBQUlOLEtBQUtDLGtCQUFrQkM7UUFFeEMsT0FBT0k7SUFDVDtBQUNGIn0=
@@ -12,10 +12,37 @@ _export(exports, {
12
12
  get backwardsDepthFirstSearch () {
13
13
  return backwardsDepthFirstSearch;
14
14
  },
15
+ get depthFirstSearch () {
16
+ return depthFirstSearch;
17
+ },
15
18
  get forwardsDepthFirstSearch () {
16
19
  return forwardsDepthFirstSearch;
17
20
  }
18
21
  });
22
+ function depthFirstSearch(vertex, callback, visitedVertexes, predecessorVertexes = []) {
23
+ let terminate = false;
24
+ const visitedVertexesIncludesVertex = visitedVertexes.includes(vertex);
25
+ if (!visitedVertexesIncludesVertex) {
26
+ const visitedVertex = vertex; ///
27
+ visitedVertexes.push(visitedVertex);
28
+ terminate = callback(vertex, predecessorVertexes);
29
+ if (!terminate) {
30
+ const predecessorVertex = vertex; ///
31
+ predecessorVertexes = [
32
+ ...predecessorVertexes,
33
+ predecessorVertex
34
+ ];
35
+ terminate = vertex.someImmediateSuccessorVertex((immediateSuccessorVertex)=>{
36
+ const vertex = immediateSuccessorVertex; ///
37
+ const terminate = depthFirstSearch(vertex, callback, visitedVertexes, predecessorVertexes);
38
+ if (terminate) {
39
+ return true;
40
+ }
41
+ });
42
+ }
43
+ }
44
+ return terminate;
45
+ }
19
46
  function forwardsDepthFirstSearch(vertex, callback, visitedVertexes, predecessorVertexes = []) {
20
47
  let terminate = false;
21
48
  const visitedVertexesIncludesVertex = visitedVertexes.includes(vertex);
@@ -69,4 +96,4 @@ function backwardsDepthFirstSearch(vertex, callback, visitedVertexes, successorV
69
96
  return terminate;
70
97
  }
71
98
 
72
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlsaXRpZXMvc2VhcmNoLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnQgZnVuY3Rpb24gZm9yd2FyZHNEZXB0aEZpcnN0U2VhcmNoKHZlcnRleCwgY2FsbGJhY2ssIHZpc2l0ZWRWZXJ0ZXhlcywgcHJlZGVjZXNzb3JWZXJ0ZXhlcyA9IFtdKSB7XG4gIGxldCB0ZXJtaW5hdGUgPSBmYWxzZTtcblxuICBjb25zdCB2aXNpdGVkVmVydGV4ZXNJbmNsdWRlc1ZlcnRleCA9IHZpc2l0ZWRWZXJ0ZXhlcy5pbmNsdWRlcyh2ZXJ0ZXgpO1xuXG4gIGlmICghdmlzaXRlZFZlcnRleGVzSW5jbHVkZXNWZXJ0ZXgpIHtcbiAgICBjb25zdCB2aXNpdGVkVmVydGV4ID0gdmVydGV4OyAvLy9cblxuICAgIHZpc2l0ZWRWZXJ0ZXhlcy5wdXNoKHZpc2l0ZWRWZXJ0ZXgpO1xuXG4gICAgdGVybWluYXRlID0gY2FsbGJhY2sodmVydGV4LCBwcmVkZWNlc3NvclZlcnRleGVzKTtcblxuICAgIGlmICghdGVybWluYXRlKSB7XG4gICAgICBjb25zdCBwcmVkZWNlc3NvclZlcnRleCA9IHZlcnRleDsgIC8vL1xuXG4gICAgICBwcmVkZWNlc3NvclZlcnRleGVzID0gWyAvLy9cbiAgICAgICAgLi4ucHJlZGVjZXNzb3JWZXJ0ZXhlcyxcbiAgICAgICAgcHJlZGVjZXNzb3JWZXJ0ZXhcbiAgICAgIF07XG5cbiAgICAgIHRlcm1pbmF0ZSA9IHZlcnRleC5zb21lSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KChpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgpID0+IHtcbiAgICAgICAgY29uc3QgdmVydGV4ID0gaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4LCAgLy8vXG4gICAgICAgICAgICAgIHZlcnRleEluZGV4ID0gdmVydGV4LmdldEluZGV4KCksXG4gICAgICAgICAgICAgIHByZWRlY2Vzc29yVmVydGV4SW5kZXggPSBwcmVkZWNlc3NvclZlcnRleC5nZXRJbmRleCgpO1xuXG4gICAgICAgIGlmICh2ZXJ0ZXhJbmRleCA+IHByZWRlY2Vzc29yVmVydGV4SW5kZXgpIHtcbiAgICAgICAgICBjb25zdCB0ZXJtaW5hdGUgPSBmb3J3YXJkc0RlcHRoRmlyc3RTZWFyY2godmVydGV4LCBjYWxsYmFjaywgdmlzaXRlZFZlcnRleGVzLCBwcmVkZWNlc3NvclZlcnRleGVzKTtcblxuICAgICAgICAgIGlmICh0ZXJtaW5hdGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRlcm1pbmF0ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJhY2t3YXJkc0RlcHRoRmlyc3RTZWFyY2godmVydGV4LCBjYWxsYmFjaywgdmlzaXRlZFZlcnRleGVzLCBzdWNjZXNzb3JWZXJ0ZXhlcyA9IFtdKSB7XG4gIGxldCB0ZXJtaW5hdGUgPSBmYWxzZTtcblxuICBjb25zdCB2aXNpdGVkVmVydGV4ZXNJbmNsdWRlc1ZlcnRleCA9IHZpc2l0ZWRWZXJ0ZXhlcy5pbmNsdWRlcyh2ZXJ0ZXgpO1xuXG4gIGlmICghdmlzaXRlZFZlcnRleGVzSW5jbHVkZXNWZXJ0ZXgpIHtcbiAgICBjb25zdCB2aXNpdGVkVmVydGV4ID0gdmVydGV4OyAvLy9cblxuICAgIHZpc2l0ZWRWZXJ0ZXhlcy5wdXNoKHZpc2l0ZWRWZXJ0ZXgpO1xuXG4gICAgdGVybWluYXRlID0gY2FsbGJhY2sodmVydGV4LCBzdWNjZXNzb3JWZXJ0ZXhlcyk7XG5cbiAgICBpZiAoIXRlcm1pbmF0ZSkge1xuICAgICAgY29uc3Qgc3VjY2Vzc29yVmVydGV4ID0gdmVydGV4OyAgLy8vXG5cbiAgICAgIHN1Y2Nlc3NvclZlcnRleGVzID0gWyAvLy9cbiAgICAgICAgLi4uc3VjY2Vzc29yVmVydGV4ZXMsXG4gICAgICAgIHN1Y2Nlc3NvclZlcnRleFxuICAgICAgXTtcblxuICAgICAgdGVybWluYXRlID0gdmVydGV4LnNvbWVJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCgoaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgpID0+IHtcbiAgICAgICAgY29uc3QgdmVydGV4ID0gaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgsICAvLy9cbiAgICAgICAgICAgICAgdmVydGV4SW5kZXggPSB2ZXJ0ZXguZ2V0SW5kZXgoKSxcbiAgICAgICAgICAgICAgc3VjY2Vzc29yVmVydGV4SW5kZXggPSBzdWNjZXNzb3JWZXJ0ZXguZ2V0SW5kZXgoKTtcblxuICAgICAgICBpZiAodmVydGV4SW5kZXggPCBzdWNjZXNzb3JWZXJ0ZXhJbmRleCkge1xuICAgICAgICAgIGNvbnN0IHRlcm1pbmF0ZSA9IGJhY2t3YXJkc0RlcHRoRmlyc3RTZWFyY2godmVydGV4LCBjYWxsYmFjaywgdmlzaXRlZFZlcnRleGVzLCBzdWNjZXNzb3JWZXJ0ZXhlcyk7XG5cbiAgICAgICAgICBpZiAodGVybWluYXRlKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0ZXJtaW5hdGU7XG59XG4iXSwibmFtZXMiOlsiYmFja3dhcmRzRGVwdGhGaXJzdFNlYXJjaCIsImZvcndhcmRzRGVwdGhGaXJzdFNlYXJjaCIsInZlcnRleCIsImNhbGxiYWNrIiwidmlzaXRlZFZlcnRleGVzIiwicHJlZGVjZXNzb3JWZXJ0ZXhlcyIsInRlcm1pbmF0ZSIsInZpc2l0ZWRWZXJ0ZXhlc0luY2x1ZGVzVmVydGV4IiwiaW5jbHVkZXMiLCJ2aXNpdGVkVmVydGV4IiwicHVzaCIsInByZWRlY2Vzc29yVmVydGV4Iiwic29tZUltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsImltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsInZlcnRleEluZGV4IiwiZ2V0SW5kZXgiLCJwcmVkZWNlc3NvclZlcnRleEluZGV4Iiwic3VjY2Vzc29yVmVydGV4ZXMiLCJzdWNjZXNzb3JWZXJ0ZXgiLCJzb21lSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCIsInN1Y2Nlc3NvclZlcnRleEluZGV4Il0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7UUF5Q2dCQTtlQUFBQTs7UUF2Q0FDO2VBQUFBOzs7QUFBVCxTQUFTQSx5QkFBeUJDLE1BQU0sRUFBRUMsUUFBUSxFQUFFQyxlQUFlLEVBQUVDLHNCQUFzQixFQUFFO0lBQ2xHLElBQUlDLFlBQVk7SUFFaEIsTUFBTUMsZ0NBQWdDSCxnQkFBZ0JJLFFBQVEsQ0FBQ047SUFFL0QsSUFBSSxDQUFDSywrQkFBK0I7UUFDbEMsTUFBTUUsZ0JBQWdCUCxRQUFRLEdBQUc7UUFFakNFLGdCQUFnQk0sSUFBSSxDQUFDRDtRQUVyQkgsWUFBWUgsU0FBU0QsUUFBUUc7UUFFN0IsSUFBSSxDQUFDQyxXQUFXO1lBQ2QsTUFBTUssb0JBQW9CVCxRQUFTLEdBQUc7WUFFdENHLHNCQUFzQjttQkFDakJBO2dCQUNITTthQUNEO1lBRURMLFlBQVlKLE9BQU9VLDRCQUE0QixDQUFDLENBQUNDO2dCQUMvQyxNQUFNWCxTQUFTVywwQkFDVEMsY0FBY1osT0FBT2EsUUFBUSxJQUM3QkMseUJBQXlCTCxrQkFBa0JJLFFBQVE7Z0JBRXpELElBQUlELGNBQWNFLHdCQUF3QjtvQkFDeEMsTUFBTVYsWUFBWUwseUJBQXlCQyxRQUFRQyxVQUFVQyxpQkFBaUJDO29CQUU5RSxJQUFJQyxXQUFXO3dCQUNiLE9BQU87b0JBQ1Q7Z0JBQ0Y7WUFDRjtRQUNGO0lBQ0Y7SUFFQSxPQUFPQTtBQUNUO0FBRU8sU0FBU04sMEJBQTBCRSxNQUFNLEVBQUVDLFFBQVEsRUFBRUMsZUFBZSxFQUFFYSxvQkFBb0IsRUFBRTtJQUNqRyxJQUFJWCxZQUFZO0lBRWhCLE1BQU1DLGdDQUFnQ0gsZ0JBQWdCSSxRQUFRLENBQUNOO0lBRS9ELElBQUksQ0FBQ0ssK0JBQStCO1FBQ2xDLE1BQU1FLGdCQUFnQlAsUUFBUSxHQUFHO1FBRWpDRSxnQkFBZ0JNLElBQUksQ0FBQ0Q7UUFFckJILFlBQVlILFNBQVNELFFBQVFlO1FBRTdCLElBQUksQ0FBQ1gsV0FBVztZQUNkLE1BQU1ZLGtCQUFrQmhCLFFBQVMsR0FBRztZQUVwQ2Usb0JBQW9CO21CQUNmQTtnQkFDSEM7YUFDRDtZQUVEWixZQUFZSixPQUFPaUIsOEJBQThCLENBQUMsQ0FBQ0M7Z0JBQ2pELE1BQU1sQixTQUFTa0IsNEJBQ1ROLGNBQWNaLE9BQU9hLFFBQVEsSUFDN0JNLHVCQUF1QkgsZ0JBQWdCSCxRQUFRO2dCQUVyRCxJQUFJRCxjQUFjTyxzQkFBc0I7b0JBQ3RDLE1BQU1mLFlBQVlOLDBCQUEwQkUsUUFBUUMsVUFBVUMsaUJBQWlCYTtvQkFFL0UsSUFBSVgsV0FBVzt3QkFDYixPQUFPO29CQUNUO2dCQUNGO1lBQ0Y7UUFDRjtJQUNGO0lBRUEsT0FBT0E7QUFDVCJ9
99
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlsaXRpZXMvc2VhcmNoLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnQgZnVuY3Rpb24gZGVwdGhGaXJzdFNlYXJjaCh2ZXJ0ZXgsIGNhbGxiYWNrLCB2aXNpdGVkVmVydGV4ZXMsIHByZWRlY2Vzc29yVmVydGV4ZXMgPSBbXSkge1xuICBsZXQgdGVybWluYXRlID0gZmFsc2U7XG5cbiAgY29uc3QgdmlzaXRlZFZlcnRleGVzSW5jbHVkZXNWZXJ0ZXggPSB2aXNpdGVkVmVydGV4ZXMuaW5jbHVkZXModmVydGV4KTtcblxuICBpZiAoIXZpc2l0ZWRWZXJ0ZXhlc0luY2x1ZGVzVmVydGV4KSB7XG4gICAgY29uc3QgdmlzaXRlZFZlcnRleCA9IHZlcnRleDsgLy8vXG5cbiAgICB2aXNpdGVkVmVydGV4ZXMucHVzaCh2aXNpdGVkVmVydGV4KTtcblxuICAgIHRlcm1pbmF0ZSA9IGNhbGxiYWNrKHZlcnRleCwgcHJlZGVjZXNzb3JWZXJ0ZXhlcyk7XG5cbiAgICBpZiAoIXRlcm1pbmF0ZSkge1xuICAgICAgY29uc3QgcHJlZGVjZXNzb3JWZXJ0ZXggPSB2ZXJ0ZXg7ICAvLy9cblxuICAgICAgcHJlZGVjZXNzb3JWZXJ0ZXhlcyA9IFsgLy8vXG4gICAgICAgIC4uLnByZWRlY2Vzc29yVmVydGV4ZXMsXG4gICAgICAgIHByZWRlY2Vzc29yVmVydGV4XG4gICAgICBdO1xuXG4gICAgICB0ZXJtaW5hdGUgPSB2ZXJ0ZXguc29tZUltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCgoaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IHZlcnRleCA9IGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleDsgIC8vL1xuXG4gICAgICAgIGNvbnN0IHRlcm1pbmF0ZSA9IGRlcHRoRmlyc3RTZWFyY2godmVydGV4LCBjYWxsYmFjaywgdmlzaXRlZFZlcnRleGVzLCBwcmVkZWNlc3NvclZlcnRleGVzKTtcblxuICAgICAgICBpZiAodGVybWluYXRlKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0ZXJtaW5hdGU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmb3J3YXJkc0RlcHRoRmlyc3RTZWFyY2godmVydGV4LCBjYWxsYmFjaywgdmlzaXRlZFZlcnRleGVzLCBwcmVkZWNlc3NvclZlcnRleGVzID0gW10pIHtcbiAgbGV0IHRlcm1pbmF0ZSA9IGZhbHNlO1xuXG4gIGNvbnN0IHZpc2l0ZWRWZXJ0ZXhlc0luY2x1ZGVzVmVydGV4ID0gdmlzaXRlZFZlcnRleGVzLmluY2x1ZGVzKHZlcnRleCk7XG5cbiAgaWYgKCF2aXNpdGVkVmVydGV4ZXNJbmNsdWRlc1ZlcnRleCkge1xuICAgIGNvbnN0IHZpc2l0ZWRWZXJ0ZXggPSB2ZXJ0ZXg7IC8vL1xuXG4gICAgdmlzaXRlZFZlcnRleGVzLnB1c2godmlzaXRlZFZlcnRleCk7XG5cbiAgICB0ZXJtaW5hdGUgPSBjYWxsYmFjayh2ZXJ0ZXgsIHByZWRlY2Vzc29yVmVydGV4ZXMpO1xuXG4gICAgaWYgKCF0ZXJtaW5hdGUpIHtcbiAgICAgIGNvbnN0IHByZWRlY2Vzc29yVmVydGV4ID0gdmVydGV4OyAgLy8vXG5cbiAgICAgIHByZWRlY2Vzc29yVmVydGV4ZXMgPSBbIC8vL1xuICAgICAgICAuLi5wcmVkZWNlc3NvclZlcnRleGVzLFxuICAgICAgICBwcmVkZWNlc3NvclZlcnRleFxuICAgICAgXTtcblxuICAgICAgdGVybWluYXRlID0gdmVydGV4LnNvbWVJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgoKGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCkgPT4ge1xuICAgICAgICBjb25zdCB2ZXJ0ZXggPSBpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgsICAvLy9cbiAgICAgICAgICAgICAgdmVydGV4SW5kZXggPSB2ZXJ0ZXguZ2V0SW5kZXgoKSxcbiAgICAgICAgICAgICAgcHJlZGVjZXNzb3JWZXJ0ZXhJbmRleCA9IHByZWRlY2Vzc29yVmVydGV4LmdldEluZGV4KCk7XG5cbiAgICAgICAgaWYgKHZlcnRleEluZGV4ID4gcHJlZGVjZXNzb3JWZXJ0ZXhJbmRleCkge1xuICAgICAgICAgIGNvbnN0IHRlcm1pbmF0ZSA9IGZvcndhcmRzRGVwdGhGaXJzdFNlYXJjaCh2ZXJ0ZXgsIGNhbGxiYWNrLCB2aXNpdGVkVmVydGV4ZXMsIHByZWRlY2Vzc29yVmVydGV4ZXMpO1xuXG4gICAgICAgICAgaWYgKHRlcm1pbmF0ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGVybWluYXRlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYmFja3dhcmRzRGVwdGhGaXJzdFNlYXJjaCh2ZXJ0ZXgsIGNhbGxiYWNrLCB2aXNpdGVkVmVydGV4ZXMsIHN1Y2Nlc3NvclZlcnRleGVzID0gW10pIHtcbiAgbGV0IHRlcm1pbmF0ZSA9IGZhbHNlO1xuXG4gIGNvbnN0IHZpc2l0ZWRWZXJ0ZXhlc0luY2x1ZGVzVmVydGV4ID0gdmlzaXRlZFZlcnRleGVzLmluY2x1ZGVzKHZlcnRleCk7XG5cbiAgaWYgKCF2aXNpdGVkVmVydGV4ZXNJbmNsdWRlc1ZlcnRleCkge1xuICAgIGNvbnN0IHZpc2l0ZWRWZXJ0ZXggPSB2ZXJ0ZXg7IC8vL1xuXG4gICAgdmlzaXRlZFZlcnRleGVzLnB1c2godmlzaXRlZFZlcnRleCk7XG5cbiAgICB0ZXJtaW5hdGUgPSBjYWxsYmFjayh2ZXJ0ZXgsIHN1Y2Nlc3NvclZlcnRleGVzKTtcblxuICAgIGlmICghdGVybWluYXRlKSB7XG4gICAgICBjb25zdCBzdWNjZXNzb3JWZXJ0ZXggPSB2ZXJ0ZXg7ICAvLy9cblxuICAgICAgc3VjY2Vzc29yVmVydGV4ZXMgPSBbIC8vL1xuICAgICAgICAuLi5zdWNjZXNzb3JWZXJ0ZXhlcyxcbiAgICAgICAgc3VjY2Vzc29yVmVydGV4XG4gICAgICBdO1xuXG4gICAgICB0ZXJtaW5hdGUgPSB2ZXJ0ZXguc29tZUltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KChpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCkgPT4ge1xuICAgICAgICBjb25zdCB2ZXJ0ZXggPSBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCwgIC8vL1xuICAgICAgICAgICAgICB2ZXJ0ZXhJbmRleCA9IHZlcnRleC5nZXRJbmRleCgpLFxuICAgICAgICAgICAgICBzdWNjZXNzb3JWZXJ0ZXhJbmRleCA9IHN1Y2Nlc3NvclZlcnRleC5nZXRJbmRleCgpO1xuXG4gICAgICAgIGlmICh2ZXJ0ZXhJbmRleCA8IHN1Y2Nlc3NvclZlcnRleEluZGV4KSB7XG4gICAgICAgICAgY29uc3QgdGVybWluYXRlID0gYmFja3dhcmRzRGVwdGhGaXJzdFNlYXJjaCh2ZXJ0ZXgsIGNhbGxiYWNrLCB2aXNpdGVkVmVydGV4ZXMsIHN1Y2Nlc3NvclZlcnRleGVzKTtcblxuICAgICAgICAgIGlmICh0ZXJtaW5hdGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRlcm1pbmF0ZTtcbn1cbiJdLCJuYW1lcyI6WyJiYWNrd2FyZHNEZXB0aEZpcnN0U2VhcmNoIiwiZGVwdGhGaXJzdFNlYXJjaCIsImZvcndhcmRzRGVwdGhGaXJzdFNlYXJjaCIsInZlcnRleCIsImNhbGxiYWNrIiwidmlzaXRlZFZlcnRleGVzIiwicHJlZGVjZXNzb3JWZXJ0ZXhlcyIsInRlcm1pbmF0ZSIsInZpc2l0ZWRWZXJ0ZXhlc0luY2x1ZGVzVmVydGV4IiwiaW5jbHVkZXMiLCJ2aXNpdGVkVmVydGV4IiwicHVzaCIsInByZWRlY2Vzc29yVmVydGV4Iiwic29tZUltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsImltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsInZlcnRleEluZGV4IiwiZ2V0SW5kZXgiLCJwcmVkZWNlc3NvclZlcnRleEluZGV4Iiwic3VjY2Vzc29yVmVydGV4ZXMiLCJzdWNjZXNzb3JWZXJ0ZXgiLCJzb21lSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCIsInN1Y2Nlc3NvclZlcnRleEluZGV4Il0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7UUE0RWdCQTtlQUFBQTs7UUExRUFDO2VBQUFBOztRQW1DQUM7ZUFBQUE7OztBQW5DVCxTQUFTRCxpQkFBaUJFLE1BQU0sRUFBRUMsUUFBUSxFQUFFQyxlQUFlLEVBQUVDLHNCQUFzQixFQUFFO0lBQzFGLElBQUlDLFlBQVk7SUFFaEIsTUFBTUMsZ0NBQWdDSCxnQkFBZ0JJLFFBQVEsQ0FBQ047SUFFL0QsSUFBSSxDQUFDSywrQkFBK0I7UUFDbEMsTUFBTUUsZ0JBQWdCUCxRQUFRLEdBQUc7UUFFakNFLGdCQUFnQk0sSUFBSSxDQUFDRDtRQUVyQkgsWUFBWUgsU0FBU0QsUUFBUUc7UUFFN0IsSUFBSSxDQUFDQyxXQUFXO1lBQ2QsTUFBTUssb0JBQW9CVCxRQUFTLEdBQUc7WUFFdENHLHNCQUFzQjttQkFDakJBO2dCQUNITTthQUNEO1lBRURMLFlBQVlKLE9BQU9VLDRCQUE0QixDQUFDLENBQUNDO2dCQUMvQyxNQUFNWCxTQUFTVywwQkFBMkIsR0FBRztnQkFFN0MsTUFBTVAsWUFBWU4saUJBQWlCRSxRQUFRQyxVQUFVQyxpQkFBaUJDO2dCQUV0RSxJQUFJQyxXQUFXO29CQUNiLE9BQU87Z0JBQ1Q7WUFDRjtRQUNGO0lBQ0Y7SUFFQSxPQUFPQTtBQUNUO0FBRU8sU0FBU0wseUJBQXlCQyxNQUFNLEVBQUVDLFFBQVEsRUFBRUMsZUFBZSxFQUFFQyxzQkFBc0IsRUFBRTtJQUNsRyxJQUFJQyxZQUFZO0lBRWhCLE1BQU1DLGdDQUFnQ0gsZ0JBQWdCSSxRQUFRLENBQUNOO0lBRS9ELElBQUksQ0FBQ0ssK0JBQStCO1FBQ2xDLE1BQU1FLGdCQUFnQlAsUUFBUSxHQUFHO1FBRWpDRSxnQkFBZ0JNLElBQUksQ0FBQ0Q7UUFFckJILFlBQVlILFNBQVNELFFBQVFHO1FBRTdCLElBQUksQ0FBQ0MsV0FBVztZQUNkLE1BQU1LLG9CQUFvQlQsUUFBUyxHQUFHO1lBRXRDRyxzQkFBc0I7bUJBQ2pCQTtnQkFDSE07YUFDRDtZQUVETCxZQUFZSixPQUFPVSw0QkFBNEIsQ0FBQyxDQUFDQztnQkFDL0MsTUFBTVgsU0FBU1csMEJBQ1RDLGNBQWNaLE9BQU9hLFFBQVEsSUFDN0JDLHlCQUF5Qkwsa0JBQWtCSSxRQUFRO2dCQUV6RCxJQUFJRCxjQUFjRSx3QkFBd0I7b0JBQ3hDLE1BQU1WLFlBQVlMLHlCQUF5QkMsUUFBUUMsVUFBVUMsaUJBQWlCQztvQkFFOUUsSUFBSUMsV0FBVzt3QkFDYixPQUFPO29CQUNUO2dCQUNGO1lBQ0Y7UUFDRjtJQUNGO0lBRUEsT0FBT0E7QUFDVDtBQUVPLFNBQVNQLDBCQUEwQkcsTUFBTSxFQUFFQyxRQUFRLEVBQUVDLGVBQWUsRUFBRWEsb0JBQW9CLEVBQUU7SUFDakcsSUFBSVgsWUFBWTtJQUVoQixNQUFNQyxnQ0FBZ0NILGdCQUFnQkksUUFBUSxDQUFDTjtJQUUvRCxJQUFJLENBQUNLLCtCQUErQjtRQUNsQyxNQUFNRSxnQkFBZ0JQLFFBQVEsR0FBRztRQUVqQ0UsZ0JBQWdCTSxJQUFJLENBQUNEO1FBRXJCSCxZQUFZSCxTQUFTRCxRQUFRZTtRQUU3QixJQUFJLENBQUNYLFdBQVc7WUFDZCxNQUFNWSxrQkFBa0JoQixRQUFTLEdBQUc7WUFFcENlLG9CQUFvQjttQkFDZkE7Z0JBQ0hDO2FBQ0Q7WUFFRFosWUFBWUosT0FBT2lCLDhCQUE4QixDQUFDLENBQUNDO2dCQUNqRCxNQUFNbEIsU0FBU2tCLDRCQUNUTixjQUFjWixPQUFPYSxRQUFRLElBQzdCTSx1QkFBdUJILGdCQUFnQkgsUUFBUTtnQkFFckQsSUFBSUQsY0FBY08sc0JBQXNCO29CQUN0QyxNQUFNZixZQUFZUCwwQkFBMEJHLFFBQVFDLFVBQVVDLGlCQUFpQmE7b0JBRS9FLElBQUlYLFdBQVc7d0JBQ2IsT0FBTztvQkFDVDtnQkFDRjtZQUNGO1FBQ0Y7SUFDRjtJQUVBLE9BQU9BO0FBQ1QifQ==
package/lib/vertex.js CHANGED
@@ -35,10 +35,18 @@ class Vertex {
35
35
  const immediateSuccessorVertexesLength = this.immediateSuccessorVertexes.length, immediatePredecessorVertexesLength = this.immediatePredecessorVertexes.length, stranded = immediateSuccessorVertexesLength === 0 && immediatePredecessorVertexesLength === 0;
36
36
  return stranded;
37
37
  }
38
+ isVertexReachable(vertex) {
39
+ const reachableVertexes = this.retrieveReachableVertexes(vertex), lastReachableVertex = last(reachableVertexes), vertexReachable = vertex === lastReachableVertex;
40
+ return vertexReachable;
41
+ }
38
42
  isVertexForwardsReachable(vertex) {
39
43
  const forwardsReachableVertexes = this.retrieveForwardsReachableVertexes(vertex), lastForwardsReachableVertex = last(forwardsReachableVertexes), vertexForwardsReachable = vertex === lastForwardsReachableVertex;
40
44
  return vertexForwardsReachable;
41
45
  }
46
+ isVertexBackwardsReachable(vertex) {
47
+ const backwardsReachableVertexes = this.retrieveBackwardsReachableVertexes(vertex), lastBackwardsReachableVertex = last(backwardsReachableVertexes), vertexBackwardsReachable = vertex === lastBackwardsReachableVertex;
48
+ return vertexBackwardsReachable;
49
+ }
42
50
  isEdgePresentBySourceVertex(sourceVertex) {
43
51
  const sourceVertexImmediatePredecessorVertex = this.isVertexImmediatePredecessorVertex(sourceVertex), edgePresent = sourceVertexImmediatePredecessorVertex; ///
44
52
  return edgePresent;
@@ -55,10 +63,19 @@ class Vertex {
55
63
  const backwardsReachableVertexes = this.retrieveBackwardsReachableVertexes(), backwardsReachableVertexesTail = tail(backwardsReachableVertexes), predecessorVertexes = backwardsReachableVertexesTail, predecessorVertexNames = (0, _vertex.vertexNamesFromVertexes)(predecessorVertexes);
56
64
  return predecessorVertexNames;
57
65
  }
66
+ retrieveReachableVertexes(vertex = null) {
67
+ const vertexA = vertex, visitedVertexes = this.depthFirstSearch((vertex)=>{
68
+ const vertexB = vertex; ///
69
+ if (vertexA === vertexB) {
70
+ return true;
71
+ }
72
+ }), reachableVertexes = visitedVertexes; ///
73
+ return reachableVertexes;
74
+ }
58
75
  retrieveForwardsReachableVertexes(vertex = null) {
59
76
  const vertexA = vertex, visitedVertexes = this.forwardsDepthFirstSearch((vertex)=>{
60
- const vertexB = vertex, terminate = vertexA === vertexB;
61
- if (terminate) {
77
+ const vertexB = vertex; ///
78
+ if (vertexA === vertexB) {
62
79
  return true;
63
80
  }
64
81
  }), forwardsReachableVertexes = visitedVertexes; ///
@@ -66,8 +83,8 @@ class Vertex {
66
83
  }
67
84
  retrieveBackwardsReachableVertexes(vertex = null) {
68
85
  const vertexA = vertex, visitedVertexes = this.backwardsDepthFirstSearch((vertex)=>{
69
- const vertexB = vertex, terminate = vertexA === vertexB;
70
- if (terminate) {
86
+ const vertexB = vertex; ///
87
+ if (vertexA === vertexB) {
71
88
  return true;
72
89
  }
73
90
  }), backwardsReachableVertexes = visitedVertexes; ///
@@ -118,6 +135,11 @@ class Vertex {
118
135
  const index = this.immediatePredecessorVertexes.indexOf(immediatePredecessorVertex), start = index, deleteCount = 1;
119
136
  this.immediatePredecessorVertexes.splice(start, deleteCount);
120
137
  }
138
+ depthFirstSearch(callback) {
139
+ const vertex = this, visitedVertexes = [];
140
+ (0, _search.depthFirstSearch)(vertex, callback, visitedVertexes);
141
+ return visitedVertexes;
142
+ }
121
143
  forwardsDepthFirstSearch(callback) {
122
144
  const vertex = this, visitedVertexes = [];
123
145
  (0, _search.forwardsDepthFirstSearch)(vertex, callback, visitedVertexes);
@@ -146,4 +168,4 @@ class Vertex {
146
168
  }
147
169
  }
148
170
 
149
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy92ZXJ0ZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbmltcG9ydCB7IGFycmF5VXRpbGl0aWVzIH0gZnJvbSBcIm5lY2Vzc2FyeVwiO1xuXG5pbXBvcnQgeyB2ZXJ0ZXhOYW1lc0Zyb21WZXJ0ZXhlcyB9IGZyb20gXCIuL3V0aWxpdGllcy92ZXJ0ZXhcIjtcbmltcG9ydCB7IGZvcndhcmRzRGVwdGhGaXJzdFNlYXJjaCwgYmFja3dhcmRzRGVwdGhGaXJzdFNlYXJjaCB9IGZyb20gXCIuL3V0aWxpdGllcy9zZWFyY2hcIjtcblxuY29uc3QgeyBsYXN0LCB0YWlsIH0gPSBhcnJheVV0aWxpdGllcztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmVydGV4IHtcbiAgY29uc3RydWN0b3IobmFtZSwgaW5kZXgsIGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzLCBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzKSB7XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICB0aGlzLmluZGV4ID0gaW5kZXg7XG4gICAgdGhpcy5pbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhlcyA9IGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzO1xuICAgIHRoaXMuaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhlcyA9IGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXM7XG4gIH1cblxuICBnZXROYW1lKCkge1xuICAgIHJldHVybiB0aGlzLm5hbWU7XG4gIH1cblxuICBnZXRJbmRleCgpIHtcbiAgICByZXR1cm4gdGhpcy5pbmRleDtcbiAgfVxuXG4gIGdldEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzKCkge1xuICAgIHJldHVybiB0aGlzLmltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzO1xuICB9XG5cbiAgZ2V0SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhlcygpIHtcbiAgICByZXR1cm4gdGhpcy5pbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzO1xuICB9XG5cbiAgaXNTdHJhbmRlZCgpIHtcbiAgICBjb25zdCBpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhlc0xlbmd0aCA9IHRoaXMuaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMubGVuZ3RoLFxuICAgICAgICAgIGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXNMZW5ndGggPSB0aGlzLmltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMubGVuZ3RoLFxuICAgICAgICAgIHN0cmFuZGVkID0gKChpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhlc0xlbmd0aCA9PT0gMCkgJiYgKGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXNMZW5ndGggPT09IDApKTtcblxuICAgIHJldHVybiBzdHJhbmRlZDtcbiAgfVxuXG4gIGlzVmVydGV4Rm9yd2FyZHNSZWFjaGFibGUodmVydGV4KSB7XG4gICAgY29uc3QgZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyA9IHRoaXMucmV0cmlldmVGb3J3YXJkc1JlYWNoYWJsZVZlcnRleGVzKHZlcnRleCksXG4gICAgICAgICAgbGFzdEZvcndhcmRzUmVhY2hhYmxlVmVydGV4ID0gbGFzdChmb3J3YXJkc1JlYWNoYWJsZVZlcnRleGVzKSxcbiAgICAgICAgICB2ZXJ0ZXhGb3J3YXJkc1JlYWNoYWJsZSA9ICh2ZXJ0ZXggPT09IGxhc3RGb3J3YXJkc1JlYWNoYWJsZVZlcnRleCk7XG5cbiAgICByZXR1cm4gdmVydGV4Rm9yd2FyZHNSZWFjaGFibGU7XG4gIH1cblxuICBpc0VkZ2VQcmVzZW50QnlTb3VyY2VWZXJ0ZXgoc291cmNlVmVydGV4KSB7XG4gICAgY29uc3Qgc291cmNlVmVydGV4SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXggPSB0aGlzLmlzVmVydGV4SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgoc291cmNlVmVydGV4KSxcbiAgICAgICAgICBlZGdlUHJlc2VudCA9IHNvdXJjZVZlcnRleEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4OyAvLy9cblxuICAgIHJldHVybiBlZGdlUHJlc2VudDtcbiAgfVxuXG4gIGlzRWRnZVByZXNlbnRCeVRhcmdldFZlcnRleCh0YXJnZXRWZXJ0ZXgpIHtcbiAgICBjb25zdCB0YXJnZXRWZXJ0ZXhJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXggPSB0aGlzLmlzVmVydGV4SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KHRhcmdldFZlcnRleCksXG4gICAgICAgICAgZWRnZVByZXNlbnQgPSB0YXJnZXRWZXJ0ZXhJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXg7IC8vL1xuXG4gICAgcmV0dXJuIGVkZ2VQcmVzZW50O1xuICB9XG5cbiAgcmV0cmlldmVTdWNjZXNzb3JWZXJ0ZXhOYW1lcygpIHtcbiAgICBjb25zdCBmb3J3YXJkc1JlYWNoYWJsZVZlcnRleGVzID0gdGhpcy5yZXRyaWV2ZUZvcndhcmRzUmVhY2hhYmxlVmVydGV4ZXMoKSxcbiAgICAgICAgICBmb3J3YXJkc1JlYWNoYWJsZVZlcnRleGVzVGFpbCA9IHRhaWwoZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyksXG4gICAgICAgICAgc3VjY2Vzc29yVmVydGV4ZXMgPSBmb3J3YXJkc1JlYWNoYWJsZVZlcnRleGVzVGFpbCxcbiAgICAgICAgICBzdWNjZXNzb3JWZXJ0ZXhOYW1lcyA9IHZlcnRleE5hbWVzRnJvbVZlcnRleGVzKHN1Y2Nlc3NvclZlcnRleGVzKTtcblxuICAgIHJldHVybiBzdWNjZXNzb3JWZXJ0ZXhOYW1lcztcbiAgfVxuXG4gIHJldHJpZXZlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcygpIHtcbiAgICBjb25zdCBiYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyA9IHRoaXMucmV0cmlldmVCYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcygpLFxuICAgICAgICAgIGJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzVGFpbCA9IHRhaWwoYmFja3dhcmRzUmVhY2hhYmxlVmVydGV4ZXMpLFxuICAgICAgICAgIHByZWRlY2Vzc29yVmVydGV4ZXMgPSBiYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlc1RhaWwsXG4gICAgICAgICAgcHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcyA9IHZlcnRleE5hbWVzRnJvbVZlcnRleGVzKHByZWRlY2Vzc29yVmVydGV4ZXMpO1xuXG4gICAgcmV0dXJuIHByZWRlY2Vzc29yVmVydGV4TmFtZXM7XG4gIH1cblxuICByZXRyaWV2ZUZvcndhcmRzUmVhY2hhYmxlVmVydGV4ZXModmVydGV4ID0gbnVsbCkge1xuICAgIGNvbnN0IHZlcnRleEEgPSB2ZXJ0ZXgsIC8vL1xuICAgICAgICAgIHZpc2l0ZWRWZXJ0ZXhlcyA9IHRoaXMuZm9yd2FyZHNEZXB0aEZpcnN0U2VhcmNoKCh2ZXJ0ZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHZlcnRleEIgPSB2ZXJ0ZXgsIC8vL1xuICAgICAgICAgICAgICAgICAgdGVybWluYXRlID0gKHZlcnRleEEgPT09IHZlcnRleEIpO1xuXG4gICAgICAgICAgICBpZiAodGVybWluYXRlKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLFxuICAgICAgICAgIGZvcndhcmRzUmVhY2hhYmxlVmVydGV4ZXMgPSB2aXNpdGVkVmVydGV4ZXM7ICAvLy9cblxuICAgIHJldHVybiBmb3J3YXJkc1JlYWNoYWJsZVZlcnRleGVzO1xuICB9XG5cbiAgcmV0cmlldmVCYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyh2ZXJ0ZXggPSBudWxsKSB7XG4gICAgY29uc3QgdmVydGV4QSA9IHZlcnRleCwgLy8vXG4gICAgICAgICAgdmlzaXRlZFZlcnRleGVzID0gdGhpcy5iYWNrd2FyZHNEZXB0aEZpcnN0U2VhcmNoKCh2ZXJ0ZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHZlcnRleEIgPSB2ZXJ0ZXgsIC8vL1xuICAgICAgICAgICAgICAgICAgdGVybWluYXRlID0gKHZlcnRleEEgPT09IHZlcnRleEIpO1xuXG4gICAgICAgICAgICBpZiAodGVybWluYXRlKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLFxuICAgICAgICAgIGJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzID0gdmlzaXRlZFZlcnRleGVzOyAgLy8vXG5cbiAgICByZXR1cm4gYmFja3dhcmRzUmVhY2hhYmxlVmVydGV4ZXM7XG4gIH1cblxuICBpc1ZlcnRleEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCh2ZXJ0ZXgpIHtcbiAgICBjb25zdCB2ZXJ0ZXhJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXggPSB0aGlzLmltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzLmluY2x1ZGVzKHZlcnRleCk7XG5cbiAgICByZXR1cm4gdmVydGV4SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4O1xuICB9XG5cbiAgaXNWZXJ0ZXhJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCh2ZXJ0ZXgpIHtcbiAgICBjb25zdCB2ZXJ0ZXhJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCA9IHRoaXMuaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhlcy5pbmNsdWRlcyh2ZXJ0ZXgpO1xuXG4gICAgcmV0dXJuIHZlcnRleEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4O1xuICB9XG5cbiAgZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4TmFtZXMoKSB7XG4gICAgY29uc3QgaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4TmFtZXMgPSB2ZXJ0ZXhOYW1lc0Zyb21WZXJ0ZXhlcyh0aGlzLmltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzKTtcblxuICAgIHJldHVybiBpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lcztcbiAgfVxuXG4gIGdldEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXMoKSB7XG4gICAgY29uc3QgaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcyA9IHZlcnRleE5hbWVzRnJvbVZlcnRleGVzKHRoaXMuaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhlcyk7XG5cbiAgICByZXR1cm4gaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcztcbiAgfVxuXG4gIHNldE5hbWUobmFtZSkge1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gIH1cblxuICBzZXRJbmRleChpbmRleCkge1xuICAgIHRoaXMuaW5kZXggPSBpbmRleDtcbiAgfVxuXG4gIHNldEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzKGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzKSB7XG4gICAgdGhpcy5pbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhlcyA9IGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzO1xuICB9XG5cbiAgc2V0SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhlcyhpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzKSB7XG4gICAgdGhpcy5pbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzID0gaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhlcztcbiAgfVxuXG4gIGRlY3JlbWVudEluZGV4KCkge1xuICAgIHRoaXMuaW5kZXgtLTtcbiAgfVxuXG4gIGFkZEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleChpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgpIHtcbiAgICB0aGlzLmltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzLnB1c2goaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KTtcbiAgfVxuXG4gIGFkZEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KSB7XG4gICAgdGhpcy5pbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzLnB1c2goaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgpO1xuICB9XG5cbiAgcmVtb3ZlSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCkge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5pbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhlcy5pbmRleE9mKGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCksXG4gICAgICAgICAgc3RhcnQgPSBpbmRleCwgIC8vL1xuICAgICAgICAgIGRlbGV0ZUNvdW50ID0gMTtcblxuICAgIHRoaXMuaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMuc3BsaWNlKHN0YXJ0LCBkZWxldGVDb3VudCk7XG4gIH1cblxuICByZW1vdmVJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleChpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCkge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5pbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzLmluZGV4T2YoaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgpLFxuICAgICAgICAgIHN0YXJ0ID0gaW5kZXgsICAvLy9cbiAgICAgICAgICBkZWxldGVDb3VudCA9IDE7XG5cbiAgICB0aGlzLmltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMuc3BsaWNlKHN0YXJ0LCBkZWxldGVDb3VudCk7XG4gIH1cblxuICBmb3J3YXJkc0RlcHRoRmlyc3RTZWFyY2goY2FsbGJhY2spIHtcbiAgICBjb25zdCB2ZXJ0ZXggPSB0aGlzLCAgLy8vXG4gICAgICAgICAgdmlzaXRlZFZlcnRleGVzID0gW107XG5cbiAgICBmb3J3YXJkc0RlcHRoRmlyc3RTZWFyY2godmVydGV4LCBjYWxsYmFjaywgdmlzaXRlZFZlcnRleGVzKTtcblxuICAgIHJldHVybiB2aXNpdGVkVmVydGV4ZXM7XG4gIH1cblxuICBiYWNrd2FyZHNEZXB0aEZpcnN0U2VhcmNoKGNhbGxiYWNrKSB7XG4gICAgY29uc3QgdmVydGV4ID0gdGhpcywgIC8vL1xuICAgICAgICAgIHZpc2l0ZWRWZXJ0ZXhlcyA9IFtdO1xuXG4gICAgYmFja3dhcmRzRGVwdGhGaXJzdFNlYXJjaCh2ZXJ0ZXgsIGNhbGxiYWNrLCB2aXNpdGVkVmVydGV4ZXMpO1xuXG4gICAgcmV0dXJuIHZpc2l0ZWRWZXJ0ZXhlcztcbiAgfVxuXG4gIHNvbWVJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgoY2FsbGJhY2spIHtcbiAgICByZXR1cm4gdGhpcy5pbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhlcy5zb21lKGNhbGxiYWNrKTtcbiAgfVxuXG4gIHNvbWVJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleChjYWxsYmFjaykge1xuICAgIHJldHVybiB0aGlzLmltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMuc29tZShjYWxsYmFjayk7XG4gIH1cblxuICBmb3JFYWNoSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KGNhbGxiYWNrKSB7XG4gICAgdGhpcy5pbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhlcy5mb3JFYWNoKGNhbGxiYWNrKTtcbiAgfVxuXG4gIGZvckVhY2hJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleChjYWxsYmFjaykge1xuICAgIHRoaXMuaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhlcy5mb3JFYWNoKGNhbGxiYWNrKTtcbiAgfVxuXG4gIHN0YXRpYyBmcm9tTmFtZUFuZEluZGV4KG5hbWUsIGluZGV4KSB7XG4gICAgY29uc3QgaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMgPSBbXSxcbiAgICAgICAgICBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzID0gW10sXG4gICAgICAgICAgZGVwZW5kZW5jeVZlcnRleCA9IG5ldyBWZXJ0ZXgobmFtZSwgaW5kZXgsIGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzLCBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzKTtcblxuICAgIHJldHVybiBkZXBlbmRlbmN5VmVydGV4O1xuICB9XG59XG4iXSwibmFtZXMiOlsiVmVydGV4IiwibGFzdCIsInRhaWwiLCJhcnJheVV0aWxpdGllcyIsIm5hbWUiLCJpbmRleCIsImltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzIiwiaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhlcyIsImdldE5hbWUiLCJnZXRJbmRleCIsImdldEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzIiwiZ2V0SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhlcyIsImlzU3RyYW5kZWQiLCJpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhlc0xlbmd0aCIsImxlbmd0aCIsImltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXNMZW5ndGgiLCJzdHJhbmRlZCIsImlzVmVydGV4Rm9yd2FyZHNSZWFjaGFibGUiLCJ2ZXJ0ZXgiLCJmb3J3YXJkc1JlYWNoYWJsZVZlcnRleGVzIiwicmV0cmlldmVGb3J3YXJkc1JlYWNoYWJsZVZlcnRleGVzIiwibGFzdEZvcndhcmRzUmVhY2hhYmxlVmVydGV4IiwidmVydGV4Rm9yd2FyZHNSZWFjaGFibGUiLCJpc0VkZ2VQcmVzZW50QnlTb3VyY2VWZXJ0ZXgiLCJzb3VyY2VWZXJ0ZXgiLCJzb3VyY2VWZXJ0ZXhJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCIsImlzVmVydGV4SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJlZGdlUHJlc2VudCIsImlzRWRnZVByZXNlbnRCeVRhcmdldFZlcnRleCIsInRhcmdldFZlcnRleCIsInRhcmdldFZlcnRleEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsImlzVmVydGV4SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4IiwicmV0cmlldmVTdWNjZXNzb3JWZXJ0ZXhOYW1lcyIsImZvcndhcmRzUmVhY2hhYmxlVmVydGV4ZXNUYWlsIiwic3VjY2Vzc29yVmVydGV4ZXMiLCJzdWNjZXNzb3JWZXJ0ZXhOYW1lcyIsInZlcnRleE5hbWVzRnJvbVZlcnRleGVzIiwicmV0cmlldmVQcmVkZWNlc3NvclZlcnRleE5hbWVzIiwiYmFja3dhcmRzUmVhY2hhYmxlVmVydGV4ZXMiLCJyZXRyaWV2ZUJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzIiwiYmFja3dhcmRzUmVhY2hhYmxlVmVydGV4ZXNUYWlsIiwicHJlZGVjZXNzb3JWZXJ0ZXhlcyIsInByZWRlY2Vzc29yVmVydGV4TmFtZXMiLCJ2ZXJ0ZXhBIiwidmlzaXRlZFZlcnRleGVzIiwiZm9yd2FyZHNEZXB0aEZpcnN0U2VhcmNoIiwidmVydGV4QiIsInRlcm1pbmF0ZSIsImJhY2t3YXJkc0RlcHRoRmlyc3RTZWFyY2giLCJ2ZXJ0ZXhJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgiLCJpbmNsdWRlcyIsInZlcnRleEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4IiwiZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4TmFtZXMiLCJpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lcyIsImdldEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXMiLCJpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleE5hbWVzIiwic2V0TmFtZSIsInNldEluZGV4Iiwic2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMiLCJzZXRJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzIiwiZGVjcmVtZW50SW5kZXgiLCJhZGRJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgiLCJpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgiLCJwdXNoIiwiYWRkSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCIsInJlbW92ZUltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsImluZGV4T2YiLCJzdGFydCIsImRlbGV0ZUNvdW50Iiwic3BsaWNlIiwicmVtb3ZlSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJjYWxsYmFjayIsInNvbWVJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgiLCJzb21lIiwic29tZUltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4IiwiZm9yRWFjaEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsImZvckVhY2giLCJmb3JFYWNoSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJmcm9tTmFtZUFuZEluZGV4IiwiZGVwZW5kZW5jeVZlcnRleCJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7K0JBU0E7OztlQUFxQkE7OzsyQkFQVTt3QkFFUzt3QkFDNEI7QUFFcEUsTUFBTSxFQUFFQyxJQUFJLEVBQUVDLElBQUksRUFBRSxHQUFHQyx5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
171
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy92ZXJ0ZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbmltcG9ydCB7IGFycmF5VXRpbGl0aWVzIH0gZnJvbSBcIm5lY2Vzc2FyeVwiO1xuXG5pbXBvcnQgeyB2ZXJ0ZXhOYW1lc0Zyb21WZXJ0ZXhlcyB9IGZyb20gXCIuL3V0aWxpdGllcy92ZXJ0ZXhcIjtcbmltcG9ydCB7IGRlcHRoRmlyc3RTZWFyY2gsIGZvcndhcmRzRGVwdGhGaXJzdFNlYXJjaCwgYmFja3dhcmRzRGVwdGhGaXJzdFNlYXJjaCB9IGZyb20gXCIuL3V0aWxpdGllcy9zZWFyY2hcIjtcblxuY29uc3QgeyBsYXN0LCB0YWlsIH0gPSBhcnJheVV0aWxpdGllcztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmVydGV4IHtcbiAgY29uc3RydWN0b3IobmFtZSwgaW5kZXgsIGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzLCBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzKSB7XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICB0aGlzLmluZGV4ID0gaW5kZXg7XG4gICAgdGhpcy5pbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhlcyA9IGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzO1xuICAgIHRoaXMuaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhlcyA9IGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXM7XG4gIH1cblxuICBnZXROYW1lKCkge1xuICAgIHJldHVybiB0aGlzLm5hbWU7XG4gIH1cblxuICBnZXRJbmRleCgpIHtcbiAgICByZXR1cm4gdGhpcy5pbmRleDtcbiAgfVxuXG4gIGdldEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzKCkge1xuICAgIHJldHVybiB0aGlzLmltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzO1xuICB9XG5cbiAgZ2V0SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhlcygpIHtcbiAgICByZXR1cm4gdGhpcy5pbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzO1xuICB9XG5cbiAgaXNTdHJhbmRlZCgpIHtcbiAgICBjb25zdCBpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhlc0xlbmd0aCA9IHRoaXMuaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMubGVuZ3RoLFxuICAgICAgICAgIGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXNMZW5ndGggPSB0aGlzLmltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMubGVuZ3RoLFxuICAgICAgICAgIHN0cmFuZGVkID0gKChpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhlc0xlbmd0aCA9PT0gMCkgJiYgKGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXNMZW5ndGggPT09IDApKTtcblxuICAgIHJldHVybiBzdHJhbmRlZDtcbiAgfVxuXG4gIGlzVmVydGV4UmVhY2hhYmxlKHZlcnRleCkge1xuICAgIGNvbnN0IHJlYWNoYWJsZVZlcnRleGVzID0gdGhpcy5yZXRyaWV2ZVJlYWNoYWJsZVZlcnRleGVzKHZlcnRleCksXG4gICAgICAgICAgbGFzdFJlYWNoYWJsZVZlcnRleCA9IGxhc3QocmVhY2hhYmxlVmVydGV4ZXMpLFxuICAgICAgICAgIHZlcnRleFJlYWNoYWJsZSA9ICh2ZXJ0ZXggPT09IGxhc3RSZWFjaGFibGVWZXJ0ZXgpO1xuXG4gICAgcmV0dXJuIHZlcnRleFJlYWNoYWJsZTtcbiAgfVxuXG4gIGlzVmVydGV4Rm9yd2FyZHNSZWFjaGFibGUodmVydGV4KSB7XG4gICAgY29uc3QgZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyA9IHRoaXMucmV0cmlldmVGb3J3YXJkc1JlYWNoYWJsZVZlcnRleGVzKHZlcnRleCksXG4gICAgICAgICAgbGFzdEZvcndhcmRzUmVhY2hhYmxlVmVydGV4ID0gbGFzdChmb3J3YXJkc1JlYWNoYWJsZVZlcnRleGVzKSxcbiAgICAgICAgICB2ZXJ0ZXhGb3J3YXJkc1JlYWNoYWJsZSA9ICh2ZXJ0ZXggPT09IGxhc3RGb3J3YXJkc1JlYWNoYWJsZVZlcnRleCk7XG5cbiAgICByZXR1cm4gdmVydGV4Rm9yd2FyZHNSZWFjaGFibGU7XG4gIH1cblxuICBpc1ZlcnRleEJhY2t3YXJkc1JlYWNoYWJsZSh2ZXJ0ZXgpIHtcbiAgICBjb25zdCBiYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyA9IHRoaXMucmV0cmlldmVCYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyh2ZXJ0ZXgpLFxuICAgICAgICAgIGxhc3RCYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXggPSBsYXN0KGJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzKSxcbiAgICAgICAgICB2ZXJ0ZXhCYWNrd2FyZHNSZWFjaGFibGUgPSAodmVydGV4ID09PSBsYXN0QmFja3dhcmRzUmVhY2hhYmxlVmVydGV4KTtcblxuICAgIHJldHVybiB2ZXJ0ZXhCYWNrd2FyZHNSZWFjaGFibGU7XG4gIH1cblxuICBpc0VkZ2VQcmVzZW50QnlTb3VyY2VWZXJ0ZXgoc291cmNlVmVydGV4KSB7XG4gICAgY29uc3Qgc291cmNlVmVydGV4SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXggPSB0aGlzLmlzVmVydGV4SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgoc291cmNlVmVydGV4KSxcbiAgICAgICAgICBlZGdlUHJlc2VudCA9IHNvdXJjZVZlcnRleEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4OyAvLy9cblxuICAgIHJldHVybiBlZGdlUHJlc2VudDtcbiAgfVxuXG4gIGlzRWRnZVByZXNlbnRCeVRhcmdldFZlcnRleCh0YXJnZXRWZXJ0ZXgpIHtcbiAgICBjb25zdCB0YXJnZXRWZXJ0ZXhJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXggPSB0aGlzLmlzVmVydGV4SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KHRhcmdldFZlcnRleCksXG4gICAgICAgICAgZWRnZVByZXNlbnQgPSB0YXJnZXRWZXJ0ZXhJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXg7IC8vL1xuXG4gICAgcmV0dXJuIGVkZ2VQcmVzZW50O1xuICB9XG5cbiAgcmV0cmlldmVTdWNjZXNzb3JWZXJ0ZXhOYW1lcygpIHtcbiAgICBjb25zdCBmb3J3YXJkc1JlYWNoYWJsZVZlcnRleGVzID0gdGhpcy5yZXRyaWV2ZUZvcndhcmRzUmVhY2hhYmxlVmVydGV4ZXMoKSxcbiAgICAgICAgICBmb3J3YXJkc1JlYWNoYWJsZVZlcnRleGVzVGFpbCA9IHRhaWwoZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyksXG4gICAgICAgICAgc3VjY2Vzc29yVmVydGV4ZXMgPSBmb3J3YXJkc1JlYWNoYWJsZVZlcnRleGVzVGFpbCxcbiAgICAgICAgICBzdWNjZXNzb3JWZXJ0ZXhOYW1lcyA9IHZlcnRleE5hbWVzRnJvbVZlcnRleGVzKHN1Y2Nlc3NvclZlcnRleGVzKTtcblxuICAgIHJldHVybiBzdWNjZXNzb3JWZXJ0ZXhOYW1lcztcbiAgfVxuXG4gIHJldHJpZXZlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcygpIHtcbiAgICBjb25zdCBiYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyA9IHRoaXMucmV0cmlldmVCYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcygpLFxuICAgICAgICAgIGJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzVGFpbCA9IHRhaWwoYmFja3dhcmRzUmVhY2hhYmxlVmVydGV4ZXMpLFxuICAgICAgICAgIHByZWRlY2Vzc29yVmVydGV4ZXMgPSBiYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlc1RhaWwsXG4gICAgICAgICAgcHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcyA9IHZlcnRleE5hbWVzRnJvbVZlcnRleGVzKHByZWRlY2Vzc29yVmVydGV4ZXMpO1xuXG4gICAgcmV0dXJuIHByZWRlY2Vzc29yVmVydGV4TmFtZXM7XG4gIH1cblxuICByZXRyaWV2ZVJlYWNoYWJsZVZlcnRleGVzKHZlcnRleCA9IG51bGwpIHtcbiAgICBjb25zdCB2ZXJ0ZXhBID0gdmVydGV4LCAvLy9cbiAgICAgICAgICB2aXNpdGVkVmVydGV4ZXMgPSB0aGlzLmRlcHRoRmlyc3RTZWFyY2goKHZlcnRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdmVydGV4QiA9IHZlcnRleDsgLy8vXG5cbiAgICAgICAgICAgIGlmICh2ZXJ0ZXhBID09PSB2ZXJ0ZXhCKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHJlYWNoYWJsZVZlcnRleGVzID0gdmlzaXRlZFZlcnRleGVzOyAgLy8vXG5cbiAgICByZXR1cm4gcmVhY2hhYmxlVmVydGV4ZXM7XG4gIH1cblxuICByZXRyaWV2ZUZvcndhcmRzUmVhY2hhYmxlVmVydGV4ZXModmVydGV4ID0gbnVsbCkge1xuICAgIGNvbnN0IHZlcnRleEEgPSB2ZXJ0ZXgsIC8vL1xuICAgICAgICAgIHZpc2l0ZWRWZXJ0ZXhlcyA9IHRoaXMuZm9yd2FyZHNEZXB0aEZpcnN0U2VhcmNoKCh2ZXJ0ZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHZlcnRleEIgPSB2ZXJ0ZXg7IC8vL1xuXG4gICAgICAgICAgICBpZiAodmVydGV4QSA9PT0gdmVydGV4Qikge1xuICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KSxcbiAgICAgICAgICBmb3J3YXJkc1JlYWNoYWJsZVZlcnRleGVzID0gdmlzaXRlZFZlcnRleGVzOyAgLy8vXG5cbiAgICByZXR1cm4gZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcztcbiAgfVxuXG4gIHJldHJpZXZlQmFja3dhcmRzUmVhY2hhYmxlVmVydGV4ZXModmVydGV4ID0gbnVsbCkge1xuICAgIGNvbnN0IHZlcnRleEEgPSB2ZXJ0ZXgsIC8vL1xuICAgICAgICAgIHZpc2l0ZWRWZXJ0ZXhlcyA9IHRoaXMuYmFja3dhcmRzRGVwdGhGaXJzdFNlYXJjaCgodmVydGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB2ZXJ0ZXhCID0gdmVydGV4OyAvLy9cblxuICAgICAgICAgICAgaWYgKHZlcnRleEEgPT09IHZlcnRleEIpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgICAgYmFja3dhcmRzUmVhY2hhYmxlVmVydGV4ZXMgPSB2aXNpdGVkVmVydGV4ZXM7ICAvLy9cblxuICAgIHJldHVybiBiYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcztcbiAgfVxuXG4gIGlzVmVydGV4SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KHZlcnRleCkge1xuICAgIGNvbnN0IHZlcnRleEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCA9IHRoaXMuaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMuaW5jbHVkZXModmVydGV4KTtcblxuICAgIHJldHVybiB2ZXJ0ZXhJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXg7XG4gIH1cblxuICBpc1ZlcnRleEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KHZlcnRleCkge1xuICAgIGNvbnN0IHZlcnRleEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ID0gdGhpcy5pbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzLmluY2x1ZGVzKHZlcnRleCk7XG5cbiAgICByZXR1cm4gdmVydGV4SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXg7XG4gIH1cblxuICBnZXRJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lcygpIHtcbiAgICBjb25zdCBpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lcyA9IHZlcnRleE5hbWVzRnJvbVZlcnRleGVzKHRoaXMuaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMpO1xuXG4gICAgcmV0dXJuIGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleE5hbWVzO1xuICB9XG5cbiAgZ2V0SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcygpIHtcbiAgICBjb25zdCBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleE5hbWVzID0gdmVydGV4TmFtZXNGcm9tVmVydGV4ZXModGhpcy5pbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzKTtcblxuICAgIHJldHVybiBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleE5hbWVzO1xuICB9XG5cbiAgc2V0TmFtZShuYW1lKSB7XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgfVxuXG4gIHNldEluZGV4KGluZGV4KSB7XG4gICAgdGhpcy5pbmRleCA9IGluZGV4O1xuICB9XG5cbiAgc2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMoaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMpIHtcbiAgICB0aGlzLmltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzID0gaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXM7XG4gIH1cblxuICBzZXRJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzKGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMpIHtcbiAgICB0aGlzLmltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMgPSBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzO1xuICB9XG5cbiAgZGVjcmVtZW50SW5kZXgoKSB7XG4gICAgdGhpcy5pbmRleC0tO1xuICB9XG5cbiAgYWRkSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCkge1xuICAgIHRoaXMuaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMucHVzaChpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgpO1xuICB9XG5cbiAgYWRkSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgoaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgpIHtcbiAgICB0aGlzLmltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMucHVzaChpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCk7XG4gIH1cblxuICByZW1vdmVJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgoaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KSB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLmltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzLmluZGV4T2YoaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KSxcbiAgICAgICAgICBzdGFydCA9IGluZGV4LCAgLy8vXG4gICAgICAgICAgZGVsZXRlQ291bnQgPSAxO1xuXG4gICAgdGhpcy5pbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhlcy5zcGxpY2Uoc3RhcnQsIGRlbGV0ZUNvdW50KTtcbiAgfVxuXG4gIHJlbW92ZUltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KSB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLmltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMuaW5kZXhPZihpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCksXG4gICAgICAgICAgc3RhcnQgPSBpbmRleCwgIC8vL1xuICAgICAgICAgIGRlbGV0ZUNvdW50ID0gMTtcblxuICAgIHRoaXMuaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhlcy5zcGxpY2Uoc3RhcnQsIGRlbGV0ZUNvdW50KTtcbiAgfVxuXG4gIGRlcHRoRmlyc3RTZWFyY2goY2FsbGJhY2spIHtcbiAgICBjb25zdCB2ZXJ0ZXggPSB0aGlzLCAgLy8vXG4gICAgICAgICAgdmlzaXRlZFZlcnRleGVzID0gW107XG5cbiAgICBkZXB0aEZpcnN0U2VhcmNoKHZlcnRleCwgY2FsbGJhY2ssIHZpc2l0ZWRWZXJ0ZXhlcyk7XG5cbiAgICByZXR1cm4gdmlzaXRlZFZlcnRleGVzO1xuICB9XG5cbiAgZm9yd2FyZHNEZXB0aEZpcnN0U2VhcmNoKGNhbGxiYWNrKSB7XG4gICAgY29uc3QgdmVydGV4ID0gdGhpcywgIC8vL1xuICAgICAgICAgIHZpc2l0ZWRWZXJ0ZXhlcyA9IFtdO1xuXG4gICAgZm9yd2FyZHNEZXB0aEZpcnN0U2VhcmNoKHZlcnRleCwgY2FsbGJhY2ssIHZpc2l0ZWRWZXJ0ZXhlcyk7XG5cbiAgICByZXR1cm4gdmlzaXRlZFZlcnRleGVzO1xuICB9XG5cbiAgYmFja3dhcmRzRGVwdGhGaXJzdFNlYXJjaChjYWxsYmFjaykge1xuICAgIGNvbnN0IHZlcnRleCA9IHRoaXMsICAvLy9cbiAgICAgICAgICB2aXNpdGVkVmVydGV4ZXMgPSBbXTtcblxuICAgIGJhY2t3YXJkc0RlcHRoRmlyc3RTZWFyY2godmVydGV4LCBjYWxsYmFjaywgdmlzaXRlZFZlcnRleGVzKTtcblxuICAgIHJldHVybiB2aXNpdGVkVmVydGV4ZXM7XG4gIH1cblxuICBzb21lSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHRoaXMuaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMuc29tZShjYWxsYmFjayk7XG4gIH1cblxuICBzb21lSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgoY2FsbGJhY2spIHtcbiAgICByZXR1cm4gdGhpcy5pbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzLnNvbWUoY2FsbGJhY2spO1xuICB9XG5cbiAgZm9yRWFjaEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleChjYWxsYmFjaykge1xuICAgIHRoaXMuaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMuZm9yRWFjaChjYWxsYmFjayk7XG4gIH1cblxuICBmb3JFYWNoSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgoY2FsbGJhY2spIHtcbiAgICB0aGlzLmltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMuZm9yRWFjaChjYWxsYmFjayk7XG4gIH1cblxuICBzdGF0aWMgZnJvbU5hbWVBbmRJbmRleChuYW1lLCBpbmRleCkge1xuICAgIGNvbnN0IGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzID0gW10sXG4gICAgICAgICAgaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhlcyA9IFtdLFxuICAgICAgICAgIGRlcGVuZGVuY3lWZXJ0ZXggPSBuZXcgVmVydGV4KG5hbWUsIGluZGV4LCBpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhlcywgaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhlcyk7XG5cbiAgICByZXR1cm4gZGVwZW5kZW5jeVZlcnRleDtcbiAgfVxufVxuIl0sIm5hbWVzIjpbIlZlcnRleCIsImxhc3QiLCJ0YWlsIiwiYXJyYXlVdGlsaXRpZXMiLCJuYW1lIiwiaW5kZXgiLCJpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhlcyIsImltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMiLCJnZXROYW1lIiwiZ2V0SW5kZXgiLCJnZXRJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhlcyIsImdldEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMiLCJpc1N0cmFuZGVkIiwiaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXNMZW5ndGgiLCJsZW5ndGgiLCJpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzTGVuZ3RoIiwic3RyYW5kZWQiLCJpc1ZlcnRleFJlYWNoYWJsZSIsInZlcnRleCIsInJlYWNoYWJsZVZlcnRleGVzIiwicmV0cmlldmVSZWFjaGFibGVWZXJ0ZXhlcyIsImxhc3RSZWFjaGFibGVWZXJ0ZXgiLCJ2ZXJ0ZXhSZWFjaGFibGUiLCJpc1ZlcnRleEZvcndhcmRzUmVhY2hhYmxlIiwiZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyIsInJldHJpZXZlRm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyIsImxhc3RGb3J3YXJkc1JlYWNoYWJsZVZlcnRleCIsInZlcnRleEZvcndhcmRzUmVhY2hhYmxlIiwiaXNWZXJ0ZXhCYWNrd2FyZHNSZWFjaGFibGUiLCJiYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyIsInJldHJpZXZlQmFja3dhcmRzUmVhY2hhYmxlVmVydGV4ZXMiLCJsYXN0QmFja3dhcmRzUmVhY2hhYmxlVmVydGV4IiwidmVydGV4QmFja3dhcmRzUmVhY2hhYmxlIiwiaXNFZGdlUHJlc2VudEJ5U291cmNlVmVydGV4Iiwic291cmNlVmVydGV4Iiwic291cmNlVmVydGV4SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJpc1ZlcnRleEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4IiwiZWRnZVByZXNlbnQiLCJpc0VkZ2VQcmVzZW50QnlUYXJnZXRWZXJ0ZXgiLCJ0YXJnZXRWZXJ0ZXgiLCJ0YXJnZXRWZXJ0ZXhJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgiLCJpc1ZlcnRleEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsInJldHJpZXZlU3VjY2Vzc29yVmVydGV4TmFtZXMiLCJmb3J3YXJkc1JlYWNoYWJsZVZlcnRleGVzVGFpbCIsInN1Y2Nlc3NvclZlcnRleGVzIiwic3VjY2Vzc29yVmVydGV4TmFtZXMiLCJ2ZXJ0ZXhOYW1lc0Zyb21WZXJ0ZXhlcyIsInJldHJpZXZlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcyIsImJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzVGFpbCIsInByZWRlY2Vzc29yVmVydGV4ZXMiLCJwcmVkZWNlc3NvclZlcnRleE5hbWVzIiwidmVydGV4QSIsInZpc2l0ZWRWZXJ0ZXhlcyIsImRlcHRoRmlyc3RTZWFyY2giLCJ2ZXJ0ZXhCIiwiZm9yd2FyZHNEZXB0aEZpcnN0U2VhcmNoIiwiYmFja3dhcmRzRGVwdGhGaXJzdFNlYXJjaCIsInZlcnRleEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsImluY2x1ZGVzIiwidmVydGV4SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJnZXRJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lcyIsImltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleE5hbWVzIiwiZ2V0SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcyIsImltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXMiLCJzZXROYW1lIiwic2V0SW5kZXgiLCJzZXRJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhlcyIsInNldEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMiLCJkZWNyZW1lbnRJbmRleCIsImFkZEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsImltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsInB1c2giLCJhZGRJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCIsImltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4IiwicmVtb3ZlSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4IiwiaW5kZXhPZiIsInN0YXJ0IiwiZGVsZXRlQ291bnQiLCJzcGxpY2UiLCJyZW1vdmVJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCIsImNhbGxiYWNrIiwic29tZUltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsInNvbWUiLCJzb21lSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJmb3JFYWNoSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4IiwiZm9yRWFjaCIsImZvckVhY2hJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCIsImZyb21OYW1lQW5kSW5kZXgiLCJkZXBlbmRlbmN5VmVydGV4Il0sIm1hcHBpbmdzIjoiQUFBQTs7OzsrQkFTQTs7O2VBQXFCQTs7OzJCQVBVO3dCQUVTO3dCQUM4QztBQUV0RixNQUFNLEVBQUVDLElBQUksRUFBRUMsSUFBSSxFQUFFLEdBQUdDLHlCQUFjO0FBRXRCLE1BQU1IO0lBQ25CLFlBQVlJLElBQUksRUFBRUMsS0FBSyxFQUFFQywwQkFBMEIsRUFBRUMsNEJBQTRCLENBQUU7UUFDakYsSUFBSSxDQUFDSCxJQUFJLEdBQUdBO1FBQ1osSUFBSSxDQUFDQyxLQUFLLEdBQUdBO1FBQ2IsSUFBSSxDQUFDQywwQkFBMEIsR0FBR0E7UUFDbEMsSUFBSSxDQUFDQyw0QkFBNEIsR0FBR0E7SUFDdEM7SUFFQUMsVUFBVTtRQUNSLE9BQU8sSUFBSSxDQUFDSixJQUFJO0lBQ2xCO0lBRUFLLFdBQVc7UUFDVCxPQUFPLElBQUksQ0FBQ0osS0FBSztJQUNuQjtJQUVBSyxnQ0FBZ0M7UUFDOUIsT0FBTyxJQUFJLENBQUNKLDBCQUEwQjtJQUN4QztJQUVBSyxrQ0FBa0M7UUFDaEMsT0FBTyxJQUFJLENBQUNKLDRCQUE0QjtJQUMxQztJQUVBSyxhQUFhO1FBQ1gsTUFBTUMsbUNBQW1DLElBQUksQ0FBQ1AsMEJBQTBCLENBQUNRLE1BQU0sRUFDekVDLHFDQUFxQyxJQUFJLENBQUNSLDRCQUE0QixDQUFDTyxNQUFNLEVBQzdFRSxXQUFZLEFBQUNILHFDQUFx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
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "occam-directed-graphs",
3
3
  "author": "James Smith",
4
- "version": "3.0.107",
4
+ "version": "3.0.109",
5
5
  "license": "MIT, Anti-996",
6
6
  "homepage": "https://github.com/djalbat/occam-directed-graphs",
7
7
  "description": "Occam's directed graphs.",
@@ -14,16 +14,13 @@
14
14
  },
15
15
  "devDependencies": {
16
16
  "@swc/core": "1.13.20",
17
- "decaf-cli": "^1.0.38",
18
- "esbuild": "0.11.14",
19
- "express": "^5.1.0",
17
+ "decaf-cli": "^1.1.1",
20
18
  "lively-cli": "^3.0.3",
21
19
  "watchful-cli": "^1.7.102"
22
20
  },
23
21
  "scripts": {
24
- "start": "node ./bin/main.js",
25
22
  "clean": "rm -rf ./lib",
26
- "watchful": "watchful -m --transpiler=swc --bundler=esbuild --source-directory=./src --lib-directory=./lib --entry-file=example.js --bundle-file=./example.js --wait=100",
23
+ "watchful": "watchful -m --transpiler=swc --source-directory=./src --lib-directory=./lib --wait=100",
27
24
  "batch": "npm run watchful batch --",
28
25
  "batch-debug": "npm run watchful batch -- --debug",
29
26
  "incremental": "npm run watchful incremental --",
package/src/cycle.js CHANGED
@@ -11,6 +11,31 @@ export default class Cycle {
11
11
  return this.vertexNames;
12
12
  }
13
13
 
14
+ static fromBackEdgeAndDirectedGraph(backEdge, directedGraph) {
15
+ let cycle;
16
+
17
+ const sourceVertexName = backEdge.getSourceVertexName(), ///
18
+ targetVertexName = backEdge.getTargetVertexName(), ///
19
+ sourceVertex = directedGraph.getVertexByVertexName(sourceVertexName),
20
+ targetVertex = directedGraph.getVertexByVertexName(targetVertexName);
21
+
22
+ targetVertex.forwardsDepthFirstSearch((vertex, predecessorVertexes) => {
23
+ if (vertex === sourceVertex) {
24
+ const vertexes = [
25
+ ...predecessorVertexes,
26
+ sourceVertex
27
+ ],
28
+ vertexNames = vertexNamesFromVertexes(vertexes);
29
+
30
+ cycle = new Cycle(vertexNames);
31
+
32
+ return true;
33
+ }
34
+ });
35
+
36
+ return cycle;
37
+ }
38
+
14
39
  static fromSourceVertexAndPredecessorVertexes(sourceVertex, predecessorVertexes) {
15
40
  const vertexes = [
16
41
  ...predecessorVertexes,
@@ -16,7 +16,7 @@ export default class DirectedGraph {
16
16
  this.vertexMap = vertexMap;
17
17
  }
18
18
 
19
- getVertexNap() {
19
+ getVertexMap() {
20
20
  return this.vertexMap;
21
21
  }
22
22
 
@@ -60,11 +60,10 @@ export default class DirectedGraph {
60
60
 
61
61
  if (sourceVertex !== null) {
62
62
  const immediateSuccessorVertexes = sourceVertex.getImmediateSuccessorVertexes(),
63
- immediateSuccessorVertexNames = vertexNamesFromVertexes(immediateSuccessorVertexes),
64
- targetVertexNames = immediateSuccessorVertexNames; ///
63
+ targetVertexes = immediateSuccessorVertexes; ///
65
64
 
66
- targetVertexNames.forEach((targetVertexName) => {
67
- const edge = Edge.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
65
+ targetVertexes.forEach((targetVertex) => {
66
+ const edge = Edge.fromSourceVertexAndTargetVertex(sourceVertex, targetVertex);
68
67
 
69
68
  edges.push(edge);
70
69
  });
@@ -79,11 +78,10 @@ export default class DirectedGraph {
79
78
 
80
79
  if (targetVertex !== null) {
81
80
  const immediatePredecessorVertexes = targetVertex.getImmediatePredecessorVertexes(),
82
- immediatePredecessorVertexNames = vertexNamesFromVertexes(immediatePredecessorVertexes),
83
- sourceVertexNames = immediatePredecessorVertexNames; ///
81
+ sourceVertexes = immediatePredecessorVertexes; ///
84
82
 
85
- sourceVertexNames.forEach((sourceVertexName) => {
86
- const edge = Edge.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
83
+ sourceVertexes.forEach((sourceVertex) => {
84
+ const edge = Edge.fromSourceVertexAndTargetVertex(sourceVertex, targetVertex);
87
85
 
88
86
  edges.push(edge);
89
87
  });
@@ -92,39 +90,48 @@ export default class DirectedGraph {
92
90
  return edges;
93
91
  }
94
92
 
95
- getFirstCycle() {
96
- let firstCycle = null;
93
+ areCyclesPresent() {
94
+ const vertexes = this.getVertexes(),
95
+ cyclesPresent = vertexes.some((vertex) => {
96
+ const sourceVertex = vertex, ///
97
+ sourceVertexIndex = sourceVertex.getIndex(),
98
+ cyclicEdgePresent = vertex.someImmediateSuccessorVertex((immediateSuccessorVertex) => {
99
+ const targetVertex = immediateSuccessorVertex, ///
100
+ targetVertexIndex = targetVertex.getIndex();
97
101
 
98
- const cyclesPresent = this.areCyclesPresent();
102
+ if (targetVertexIndex < sourceVertexIndex) {
103
+ return true;
104
+ }
105
+ });
99
106
 
100
- if (cyclesPresent) {
101
- const cyclicEdges = this.getCyclicEdges(),
102
- firstCyclicEdge = first(cyclicEdges),
103
- sourceVertexName = firstCyclicEdge.getSourceVertexName(), ///
104
- targetVertexName = firstCyclicEdge.getTargetVertexName(), ///
105
- sourceVertex = this.getVertexByVertexName(sourceVertexName),
106
- targetVertex = this.getVertexByVertexName(targetVertexName);
107
+ if (cyclicEdgePresent) {
108
+ return true;
109
+ }
110
+ });
107
111
 
108
- targetVertex.forwardsDepthFirstSearch((vertex, predecessorVertexes) => {
109
- let terminate = false;
112
+ return cyclesPresent;
113
+ }
110
114
 
111
- if (vertex === sourceVertex) {
112
- terminate = true;
115
+ getFirstCycle() {
116
+ let firstCycle = null;
113
117
 
114
- const cycle = Cycle.fromSourceVertexAndPredecessorVertexes(sourceVertex, predecessorVertexes); ///
118
+ const cyclesPresent = this.areCyclesPresent();
115
119
 
116
- firstCycle = cycle; ///
117
- }
120
+ if (cyclesPresent) {
121
+ const backEdges = this.getBackEdges(),
122
+ firstBackEdge = first(backEdges),
123
+ directedGraph = this, ///
124
+ backEdge = firstBackEdge, ///
125
+ cycle = Cycle.fromBackEdgeAndDirectedGraph(backEdge, directedGraph);
118
126
 
119
- return terminate;
120
- });
127
+ firstCycle = cycle; ///
121
128
  }
122
129
 
123
130
  return firstCycle;
124
131
  }
125
132
 
126
- getCyclicEdges() {
127
- const cyclicEdges = [],
133
+ getBackEdges() {
134
+ const backEdges = [],
128
135
  vertexes = this.getVertexes();
129
136
 
130
137
  vertexes.forEach((vertex) => {
@@ -136,56 +143,27 @@ export default class DirectedGraph {
136
143
  targetVertexIndex = targetVertex.getIndex();
137
144
 
138
145
  if (targetVertexIndex < sourceVertexIndex) {
139
- const sourceVertexName = sourceVertex.getName(),
140
- targetVertexName = targetVertex.getName(),
141
- edge = Edge.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName),
142
- cyclicEdge = edge; ///
146
+ const edge = Edge.fromSourceVertexAndTargetVertex(sourceVertex, targetVertex),
147
+ backEdge = edge; ///
143
148
 
144
- cyclicEdges.push(cyclicEdge);
149
+ backEdges.push(backEdge);
145
150
  }
146
151
  });
147
-
148
- sourceVertex
149
152
  });
150
153
 
151
- return cyclicEdges;
152
- }
153
-
154
- areCyclesPresent() {
155
- const vertexes = this.getVertexes(),
156
- cyclesPresent = vertexes.some((vertex) => {
157
- const sourceVertex = vertex, ///
158
- sourceVertexIndex = sourceVertex.getIndex(),
159
- cyclicEdgePresent = vertex.someImmediateSuccessorVertex((immediateSuccessorVertex) => {
160
- const targetVertex = immediateSuccessorVertex, ///
161
- targetVertexIndex = targetVertex.getIndex();
162
-
163
- if (targetVertexIndex < sourceVertexIndex) {
164
- return true;
165
- }
166
- });
167
-
168
- if (cyclicEdgePresent) {
169
- return true;
170
- }
171
- });
172
-
173
- return cyclesPresent;
154
+ return backEdges;
174
155
  }
175
156
 
176
157
  isEdgePresent(edge) {
177
158
  let edgePresent = false;
178
159
 
179
160
  const sourceVertexName = edge.getSourceVertexName(),
180
- sourceVertex = this.getVertexByVertexName(sourceVertexName);
181
-
182
- if (sourceVertex !== null) {
183
- const targetVertexName = edge.getTargetVertexName(),
184
- targetVertex = this.getVertexByVertexName(targetVertexName);
161
+ targetVertexName = edge.getTargetVertexName(),
162
+ sourceVertex = this.getVertexByVertexName(sourceVertexName),
163
+ targetVertex = this.getVertexByVertexName(targetVertexName);
185
164
 
186
- if (targetVertex !== null) {
187
- edgePresent = sourceVertex.isEdgePresentByTargetVertex(targetVertex);
188
- }
165
+ if ((targetVertex !== null) && (sourceVertex !== null)) {
166
+ edgePresent = sourceVertex.isEdgePresentByTargetVertex(targetVertex);
189
167
  }
190
168
 
191
169
  return edgePresent;
@@ -238,7 +216,7 @@ export default class DirectedGraph {
238
216
  return vertex;
239
217
  }
240
218
 
241
- removeVertexByVertexName(vertexName) {
219
+ removeVertexByVertexName(vertexName, filterBackEdges = true) {
242
220
  const vertexPresent = this.isVertexPresentByVertexName(vertexName);
243
221
 
244
222
  if (!vertexPresent) {
@@ -273,7 +251,9 @@ export default class DirectedGraph {
273
251
  }
274
252
  });
275
253
 
276
- this.filterCyclicEdges();
254
+ if (filterBackEdges) {
255
+ this.filterBackEdges();
256
+ }
277
257
  }
278
258
 
279
259
  addVertexesByVertexNames(vertexNames) {
@@ -282,10 +262,16 @@ export default class DirectedGraph {
282
262
  });
283
263
  }
284
264
 
285
- removeVertexesByVertexNames(vertexNames) {
265
+ removeVertexesByVertexNames(vertexNames, filterBackEdges = true) {
286
266
  vertexNames.forEach((vertexName) => {
287
- this.removeVertexByVertexName(vertexName);
267
+ const filterBackEdges = false;
268
+
269
+ this.removeVertexByVertexName(vertexName, filterBackEdges);
288
270
  });
271
+
272
+ if (filterBackEdges) {
273
+ this.filterBackEdges();
274
+ }
289
275
  }
290
276
 
291
277
  addEdge(edge) {
@@ -325,35 +311,41 @@ export default class DirectedGraph {
325
311
  });
326
312
  }
327
313
 
328
- removeEdge(edge, removeStrandedVertexes) {
329
- const sourceVertexName = edge.getSourceVertexName(),
330
- targetVertexName = edge.getTargetVertexName(),
331
- sourceVertex = this.addVertexByVertexName(sourceVertexName),
332
- targetVertex = this.addVertexByVertexName(targetVertexName),
333
- edgePresent = sourceVertex.isEdgePresentByTargetVertex(targetVertex);
314
+ removeEdge(edge, removeStrandedVertexes = false) {
315
+ const edgePresent = this.isEdgePresent(edge);
334
316
 
335
317
  if (!edgePresent) {
336
318
  return;
337
319
  }
338
320
 
321
+ const edgeCyclic = this.isEdgeCyclic(edge),
322
+ filterBackEdges = edgeCyclic, ///
323
+ sourceVertexName = edge.getSourceVertexName(),
324
+ targetVertexName = edge.getTargetVertexName(),
325
+ sourceVertex = this.getVertexByVertexName(sourceVertexName),
326
+ targetVertex = this.getVertexByVertexName(targetVertexName);
327
+
339
328
  sourceVertex.removeImmediateSuccessorVertex(targetVertex);
340
329
 
341
330
  targetVertex.removeImmediatePredecessorVertex(sourceVertex);
342
331
 
343
332
  if (removeStrandedVertexes) {
344
- const sourceVertexStranded = sourceVertex.isStranded(),
333
+ const filterBackEdges = false,
334
+ sourceVertexStranded = sourceVertex.isStranded(),
345
335
  targetVertexStranded = targetVertex.isStranded();
346
336
 
347
337
  if (sourceVertexStranded) {
348
- this.removeVertexByVertexName(sourceVertexName);
338
+ this.removeVertexByVertexName(sourceVertexName, filterBackEdges);
349
339
  }
350
340
 
351
341
  if (targetVertexStranded) {
352
- this.removeVertexByVertexName(targetVertexName);
342
+ this.removeVertexByVertexName(targetVertexName, filterBackEdges);
353
343
  }
354
344
  }
355
345
 
356
- this.filterCyclicEdges();
346
+ if (filterBackEdges) {
347
+ this.filterBackEdges();
348
+ }
357
349
  }
358
350
 
359
351
  removeEdges(edges, removeStrandedVertexes = false) {
@@ -403,9 +395,20 @@ export default class DirectedGraph {
403
395
  });
404
396
  }
405
397
 
406
- filterCyclicEdges() {
407
- const cyclicEdges = this.getCyclicEdges(),
408
- edges = cyclicEdges; ///
398
+ isEdgeCyclic(edge) {
399
+ const sourceVertexName = edge.getSourceVertexName(),
400
+ targetVertexName = edge.getTargetVertexName(),
401
+ sourceVertex = this.getVertexByVertexName(sourceVertexName),
402
+ targetVertex = this.getVertexByVertexName(targetVertexName),
403
+ sourceVertexReachable = targetVertex.isVertexReachable(sourceVertex),
404
+ edgeCyclic = sourceVertexReachable; ///
405
+
406
+ return edgeCyclic;
407
+ }
408
+
409
+ filterBackEdges() {
410
+ const backEdges = this.getBackEdges(),
411
+ edges = backEdges; ///
409
412
 
410
413
  edges.forEach((edge) => {
411
414
  const sourceVertexName = edge.getSourceVertexName(),
package/src/edge.js CHANGED
@@ -28,6 +28,12 @@ export default class Edge {
28
28
  return matches;
29
29
  }
30
30
 
31
+ matchVertexNames(sourceVertexName, targetVertexName) {
32
+ const matches = ((this.sourceVertexName === sourceVertexName) && (this.targetVertexName === targetVertexName));
33
+
34
+ return matches;
35
+ }
36
+
31
37
  matchSourceVertexName(sourceVertexName) {
32
38
  const matches = (this.sourceVertexName === sourceVertexName);
33
39
 
@@ -40,10 +46,12 @@ export default class Edge {
40
46
  return matches;
41
47
  }
42
48
 
43
- matchVertexNames(sourceVertexName, targetVertexName) {
44
- const matches = ((this.sourceVertexName === sourceVertexName) && (this.targetVertexName === targetVertexName));
45
-
46
- return matches;
49
+ static fromSourceVertexAndTargetVertex(sourceVertex, targetVertex) {
50
+ const sourceVertexName = sourceVertex.getName(),
51
+ targetVertexName = targetVertex.getName(),
52
+ edge = new Edge(sourceVertexName, targetVertexName);
53
+
54
+ return edge;
47
55
  }
48
56
 
49
57
  static fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName) {
@@ -1,5 +1,40 @@
1
1
  "use strict";
2
2
 
3
+ export function depthFirstSearch(vertex, callback, visitedVertexes, predecessorVertexes = []) {
4
+ let terminate = false;
5
+
6
+ const visitedVertexesIncludesVertex = visitedVertexes.includes(vertex);
7
+
8
+ if (!visitedVertexesIncludesVertex) {
9
+ const visitedVertex = vertex; ///
10
+
11
+ visitedVertexes.push(visitedVertex);
12
+
13
+ terminate = callback(vertex, predecessorVertexes);
14
+
15
+ if (!terminate) {
16
+ const predecessorVertex = vertex; ///
17
+
18
+ predecessorVertexes = [ ///
19
+ ...predecessorVertexes,
20
+ predecessorVertex
21
+ ];
22
+
23
+ terminate = vertex.someImmediateSuccessorVertex((immediateSuccessorVertex) => {
24
+ const vertex = immediateSuccessorVertex; ///
25
+
26
+ const terminate = depthFirstSearch(vertex, callback, visitedVertexes, predecessorVertexes);
27
+
28
+ if (terminate) {
29
+ return true;
30
+ }
31
+ });
32
+ }
33
+ }
34
+
35
+ return terminate;
36
+ }
37
+
3
38
  export function forwardsDepthFirstSearch(vertex, callback, visitedVertexes, predecessorVertexes = []) {
4
39
  let terminate = false;
5
40
 
package/src/vertex.js CHANGED
@@ -3,7 +3,7 @@
3
3
  import { arrayUtilities } from "necessary";
4
4
 
5
5
  import { vertexNamesFromVertexes } from "./utilities/vertex";
6
- import { forwardsDepthFirstSearch, backwardsDepthFirstSearch } from "./utilities/search";
6
+ import { depthFirstSearch, forwardsDepthFirstSearch, backwardsDepthFirstSearch } from "./utilities/search";
7
7
 
8
8
  const { last, tail } = arrayUtilities;
9
9
 
@@ -39,6 +39,14 @@ export default class Vertex {
39
39
  return stranded;
40
40
  }
41
41
 
42
+ isVertexReachable(vertex) {
43
+ const reachableVertexes = this.retrieveReachableVertexes(vertex),
44
+ lastReachableVertex = last(reachableVertexes),
45
+ vertexReachable = (vertex === lastReachableVertex);
46
+
47
+ return vertexReachable;
48
+ }
49
+
42
50
  isVertexForwardsReachable(vertex) {
43
51
  const forwardsReachableVertexes = this.retrieveForwardsReachableVertexes(vertex),
44
52
  lastForwardsReachableVertex = last(forwardsReachableVertexes),
@@ -47,6 +55,14 @@ export default class Vertex {
47
55
  return vertexForwardsReachable;
48
56
  }
49
57
 
58
+ isVertexBackwardsReachable(vertex) {
59
+ const backwardsReachableVertexes = this.retrieveBackwardsReachableVertexes(vertex),
60
+ lastBackwardsReachableVertex = last(backwardsReachableVertexes),
61
+ vertexBackwardsReachable = (vertex === lastBackwardsReachableVertex);
62
+
63
+ return vertexBackwardsReachable;
64
+ }
65
+
50
66
  isEdgePresentBySourceVertex(sourceVertex) {
51
67
  const sourceVertexImmediatePredecessorVertex = this.isVertexImmediatePredecessorVertex(sourceVertex),
52
68
  edgePresent = sourceVertexImmediatePredecessorVertex; ///
@@ -79,13 +95,26 @@ export default class Vertex {
79
95
  return predecessorVertexNames;
80
96
  }
81
97
 
98
+ retrieveReachableVertexes(vertex = null) {
99
+ const vertexA = vertex, ///
100
+ visitedVertexes = this.depthFirstSearch((vertex) => {
101
+ const vertexB = vertex; ///
102
+
103
+ if (vertexA === vertexB) {
104
+ return true;
105
+ }
106
+ }),
107
+ reachableVertexes = visitedVertexes; ///
108
+
109
+ return reachableVertexes;
110
+ }
111
+
82
112
  retrieveForwardsReachableVertexes(vertex = null) {
83
113
  const vertexA = vertex, ///
84
114
  visitedVertexes = this.forwardsDepthFirstSearch((vertex) => {
85
- const vertexB = vertex, ///
86
- terminate = (vertexA === vertexB);
115
+ const vertexB = vertex; ///
87
116
 
88
- if (terminate) {
117
+ if (vertexA === vertexB) {
89
118
  return true;
90
119
  }
91
120
  }),
@@ -97,10 +126,9 @@ export default class Vertex {
97
126
  retrieveBackwardsReachableVertexes(vertex = null) {
98
127
  const vertexA = vertex, ///
99
128
  visitedVertexes = this.backwardsDepthFirstSearch((vertex) => {
100
- const vertexB = vertex, ///
101
- terminate = (vertexA === vertexB);
129
+ const vertexB = vertex; ///
102
130
 
103
- if (terminate) {
131
+ if (vertexA === vertexB) {
104
132
  return true;
105
133
  }
106
134
  }),
@@ -177,6 +205,15 @@ export default class Vertex {
177
205
  this.immediatePredecessorVertexes.splice(start, deleteCount);
178
206
  }
179
207
 
208
+ depthFirstSearch(callback) {
209
+ const vertex = this, ///
210
+ visitedVertexes = [];
211
+
212
+ depthFirstSearch(vertex, callback, visitedVertexes);
213
+
214
+ return visitedVertexes;
215
+ }
216
+
180
217
  forwardsDepthFirstSearch(callback) {
181
218
  const vertex = this, ///
182
219
  visitedVertexes = [];
package/lib/example.js DELETED
@@ -1,15 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- const _index = require("./index");
6
- const edge1 = _index.Edge.fromSourceVertexNameAndTargetVertexName("./easy-with-style", "./easy-layout"), edge2 = _index.Edge.fromSourceVertexNameAndTargetVertexName("./with-style", "./easy-with-style"), edge3 = _index.Edge.fromSourceVertexNameAndTargetVertexName("./easy-layout", "./occam-lexers"), edge4 = _index.Edge.fromSourceVertexNameAndTargetVertexName("./easy-with-style", "./easy-layout"), edge5 = _index.Edge.fromSourceVertexNameAndTargetVertexName("./occam-lexers", "./with-style");
7
- const directedGraph = _index.DirectedGraph.fromNothing();
8
- directedGraph.addEdge(edge1);
9
- directedGraph.addEdge(edge2);
10
- directedGraph.addEdge(edge3);
11
- directedGraph.addEdge(edge4);
12
- directedGraph.addEdge(edge5);
13
- directedGraph.removeVertexByVertexName("./occam-lexers");
14
-
15
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9leGFtcGxlLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQgeyBFZGdlLCBEaXJlY3RlZEdyYXBoIH0gZnJvbSBcIi4vaW5kZXhcIjsgIC8vL1xuXG5jb25zdCBlZGdlMSA9IEVkZ2UuZnJvbVNvdXJjZVZlcnRleE5hbWVBbmRUYXJnZXRWZXJ0ZXhOYW1lKFwiLi9lYXN5LXdpdGgtc3R5bGVcIiwgXCIuL2Vhc3ktbGF5b3V0XCIpLFxuICAgICAgZWRnZTIgPSBFZGdlLmZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZShcIi4vd2l0aC1zdHlsZVwiLCBcIi4vZWFzeS13aXRoLXN0eWxlXCIpLFxuICAgICAgZWRnZTMgPSBFZGdlLmZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZShcIi4vZWFzeS1sYXlvdXRcIiwgXCIuL29jY2FtLWxleGVyc1wiKSxcbiAgICAgIGVkZ2U0ID0gRWRnZS5mcm9tU291cmNlVmVydGV4TmFtZUFuZFRhcmdldFZlcnRleE5hbWUoXCIuL2Vhc3ktd2l0aC1zdHlsZVwiLCBcIi4vZWFzeS1sYXlvdXRcIiksXG4gICAgICBlZGdlNSA9IEVkZ2UuZnJvbVNvdXJjZVZlcnRleE5hbWVBbmRUYXJnZXRWZXJ0ZXhOYW1lKFwiLi9vY2NhbS1sZXhlcnNcIiwgXCIuL3dpdGgtc3R5bGVcIik7XG5cbmNvbnN0IGRpcmVjdGVkR3JhcGggPSBEaXJlY3RlZEdyYXBoLmZyb21Ob3RoaW5nKCk7XG5cbmRpcmVjdGVkR3JhcGguYWRkRWRnZShlZGdlMSk7XG5kaXJlY3RlZEdyYXBoLmFkZEVkZ2UoZWRnZTIpO1xuZGlyZWN0ZWRHcmFwaC5hZGRFZGdlKGVkZ2UzKTtcbmRpcmVjdGVkR3JhcGguYWRkRWRnZShlZGdlNCk7XG5kaXJlY3RlZEdyYXBoLmFkZEVkZ2UoZWRnZTUpO1xuXG5kaXJlY3RlZEdyYXBoLnJlbW92ZVZlcnRleEJ5VmVydGV4TmFtZShcIi4vb2NjYW0tbGV4ZXJzXCIpO1xuIl0sIm5hbWVzIjpbImVkZ2UxIiwiRWRnZSIsImZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZSIsImVkZ2UyIiwiZWRnZTMiLCJlZGdlNCIsImVkZ2U1IiwiZGlyZWN0ZWRHcmFwaCIsIkRpcmVjdGVkR3JhcGgiLCJmcm9tTm90aGluZyIsImFkZEVkZ2UiLCJyZW1vdmVWZXJ0ZXhCeVZlcnRleE5hbWUiXSwibWFwcGluZ3MiOiJBQUFBOzs7O3VCQUVvQztBQUVwQyxNQUFNQSxRQUFRQyxXQUFJLENBQUNDLHVDQUF1QyxDQUFDLHFCQUFxQixrQkFDMUVDLFFBQVFGLFdBQUksQ0FBQ0MsdUNBQXVDLENBQUMsZ0JBQWdCLHNCQUNyRUUsUUFBUUgsV0FBSSxDQUFDQyx1Q0FBdUMsQ0FBQyxpQkFBaUIsbUJBQ3RFRyxRQUFRSixXQUFJLENBQUNDLHVDQUF1QyxDQUFDLHFCQUFxQixrQkFDMUVJLFFBQVFMLFdBQUksQ0FBQ0MsdUNBQXVDLENBQUMsa0JBQWtCO0FBRTdFLE1BQU1LLGdCQUFnQkMsb0JBQWEsQ0FBQ0MsV0FBVztBQUUvQ0YsY0FBY0csT0FBTyxDQUFDVjtBQUN0Qk8sY0FBY0csT0FBTyxDQUFDUDtBQUN0QkksY0FBY0csT0FBTyxDQUFDTjtBQUN0QkcsY0FBY0csT0FBTyxDQUFDTDtBQUN0QkUsY0FBY0csT0FBTyxDQUFDSjtBQUV0QkMsY0FBY0ksd0JBQXdCLENBQUMifQ==
package/src/example.js DELETED
@@ -1,19 +0,0 @@
1
- "use strict";
2
-
3
- import { Edge, DirectedGraph } from "./index"; ///
4
-
5
- const edge1 = Edge.fromSourceVertexNameAndTargetVertexName("./easy-with-style", "./easy-layout"),
6
- edge2 = Edge.fromSourceVertexNameAndTargetVertexName("./with-style", "./easy-with-style"),
7
- edge3 = Edge.fromSourceVertexNameAndTargetVertexName("./easy-layout", "./occam-lexers"),
8
- edge4 = Edge.fromSourceVertexNameAndTargetVertexName("./easy-with-style", "./easy-layout"),
9
- edge5 = Edge.fromSourceVertexNameAndTargetVertexName("./occam-lexers", "./with-style");
10
-
11
- const directedGraph = DirectedGraph.fromNothing();
12
-
13
- directedGraph.addEdge(edge1);
14
- directedGraph.addEdge(edge2);
15
- directedGraph.addEdge(edge3);
16
- directedGraph.addEdge(edge4);
17
- directedGraph.addEdge(edge5);
18
-
19
- directedGraph.removeVertexByVertexName("./occam-lexers");