This is an automated email from the ASF dual-hosted git repository.

dongjoon pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/master by this push:
     new a663c0bf0c5 [SPARK-45104][UI] Upgrade `graphlib-dot.min.js` to 1.0.2
a663c0bf0c5 is described below

commit a663c0bf0c5b104170c0612f37a0b0cdf75cd45b
Author: Kent Yao <[email protected]>
AuthorDate: Fri Sep 8 13:32:37 2023 -0700

    [SPARK-45104][UI] Upgrade `graphlib-dot.min.js` to 1.0.2
    
    ### What changes were proposed in this pull request?
    
    This PR update the `graphlib-dot` library, 
https://github.com/dagrejs/graphlib-dot/compare/v0.5.2...v1.0.2, this library 
is used to read and parse dot files to graphics.
    
    ### Why are the changes needed?
    
    Update UI js libraries
    
    ### Does this PR introduce _any_ user-facing change?
    
    no
    
    ### How was this patch tested?
    
    build and verify locally
    
    
![image](https://github.com/apache/spark/assets/8326978/d9133b44-8a95-4bb4-a2e9-3a47010ab500)
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    no
    
    Closes #42853 from yaooqinn/SPARK-45104.
    
    Authored-by: Kent Yao <[email protected]>
    Signed-off-by: Dongjoon Hyun <[email protected]>
---
 .../org/apache/spark/ui/static/graphlib-dot.min.js | 351 ++++++++++++++++++++-
 1 file changed, 347 insertions(+), 4 deletions(-)

diff --git 
a/core/src/main/resources/org/apache/spark/ui/static/graphlib-dot.min.js 
b/core/src/main/resources/org/apache/spark/ui/static/graphlib-dot.min.js
index 037316f4e4f..d76e958f0e3 100644
--- a/core/src/main/resources/org/apache/spark/ui/static/graphlib-dot.min.js
+++ b/core/src/main/resources/org/apache/spark/ui/static/graphlib-dot.min.js
@@ -1,4 +1,347 @@
-/*v0.5.2*/(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof 
require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var 
f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var 
l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return 
s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof 
require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return 
s})({1:[function(require,module,exports){(f [...]
-peg$currPos++}else{s3=peg$FAILED;if(peg$silentFails===0){peg$fail(peg$c81)}}}}while(s3!==peg$FAILED){s2.push(s3);s3=peg$currPos;if(input.substr(peg$currPos,2)===peg$c75){s4=peg$c75;peg$currPos+=2}else{s4=peg$FAILED;if(peg$silentFails===0){peg$fail(peg$c76)}}if(s4!==peg$FAILED){peg$reportedPos=s3;s4=peg$c77()}s3=s4;if(s3===peg$FAILED){s3=peg$currPos;if(input.charCodeAt(peg$currPos)===92){s4=peg$c78;peg$currPos++}else{s4=peg$FAILED;if(peg$silentFails===0){peg$fail(peg$c79)}}if(s4!==peg$FAI
 [...]
\f "+"\n\r\u2028\u2029"+" ᠎              ";var reEmptyStringLeading=/\b__p \+= 
'';/g,reEmptyStringMiddle=/\b(__p \+=) '' 
\+/g,reEmptyStringTrailing=/(__e\(.*?\)|\b__t\)) \+\n'';/g;var 
reEsTemplate=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;var reFlags=/\w*$/;var 
reFuncName=/^\s*function[ \n\r\t]+\w/;var reInterpolate=/<%=([\s\S]+?)%>/g;var 
reLeadingSpacesAndZeros=RegExp("^["+whitespace+"]*0+(?=.$)");var 
reNoMatch=/($^)/;var reThis=/\bthis\b/;var 
reUnescapedString=/['\n\r\t\u2028\u2029\\]/g;var co [...]
-var arrayRef=[];var objectProto=Object.prototype;var oldDash=context._;var 
toString=objectProto.toString;var 
reNative=RegExp("^"+String(toString).replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/toString|
 for [^\]]+/g,".*?")+"$");var 
ceil=Math.ceil,clearTimeout=context.clearTimeout,floor=Math.floor,fnToString=Function.prototype.toString,getPrototypeOf=isNative(getPrototypeOf=Object.getPrototypeOf)&&getPrototypeOf,hasOwnProperty=objectProto.hasOwnProperty,push=arrayRef.push,setTimeout=conte
 [...]
-}}else{n=callback==null||thisArg?1:callback||n}return 
slice(array,0,nativeMin(nativeMax(0,length-n),length))}function 
intersection(){var 
args=[],argsIndex=-1,argsLength=arguments.length,caches=getArray(),indexOf=getIndexOf(),trustIndexOf=indexOf===baseIndexOf,seen=getArray();while(++argsIndex<argsLength){var
 
value=arguments[argsIndex];if(isArray(value)||isArguments(value)){args.push(value);caches.push(trustIndexOf&&value.length>=largeArraySize&&createCache(argsIndex?args[argsIndex]:seen)
 [...]
+/* 
https://github.com/dagrejs/graphlib-dot/blob/v1.0.2/dist/graphlib-dot.min.js */
+(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var 
c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return 
u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw 
a.code="MODULE_NOT_FOUND",a}var 
p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return 
o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof 
require&&require,i=0;i<t.length;i++)o(t[i]);return o}return 
r})()({1:[function(require,module,expo [...]
+/*
+ * Copyright (c) 2012-2013 Chris Pettitt
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+global.graphlibDot=require("./index")}).call(this)}).call(this,typeof 
global!=="undefined"?global:typeof self!=="undefined"?self:typeof 
window!=="undefined"?window:{})},{"./index":2}],2:[function(require,module,exports){var
 read=require("./lib/read-one");var readMany=require("./lib/read-many");var 
write=require("./lib/write-one");var 
version=require("./lib/version");module.exports={graphlib:require("@dagrejs/graphlib"),
+// Parsing
+read:read,readMany:readMany,
+// Writing
+write:write,
+// Version
+version:version,
+// For levelup encoding
+type:"dot",buffer:false}},{"./lib/read-many":5,"./lib/read-one":6,"./lib/version":7,"./lib/write-one":8,"@dagrejs/graphlib":9}],3:[function(require,module,exports){"use
 strict";var 
Graph=require("@dagrejs/graphlib").Graph;module.exports=buildGraph;function 
buildGraph(parseTree){var 
isDirected=parseTree.type!=="graph",isMultigraph=!parseTree.strict,defaultStack=[{node:{},edge:{}}],id=parseTree.id,g=new
 
Graph({directed:isDirected,multigraph:isMultigraph,compound:true});g.setGraph(id===null
 [...]
+// If there are no statements remove the subgraph
+if(!g.children(id).length){g.removeNode(id)}defaultStack.pop()}function 
handleAttrStmt(g,stmt,defaultStack){Object.assign(defaultStack[defaultStack.length-1][stmt.attrType],stmt.attrs)}function
 
handleInlineAttrsStmt(g,stmt,defaultStack,sg){Object.assign(sg?g.node(sg):g.graph(),stmt.attrs)}function
 generateSubgraphId(g){var id;do{id=uniqueId("sg")}while(g.hasNode(id));return 
id}function 
maybeCreateNode(g,v,defaultStack,sg){if(!g.hasNode(v)){g.setNode(v,structuredClone(defaultStack[default
 [...]
+// Collect all nodes involved in a subgraph statement
+function collectNodeIds(stmt){var ids={},stack=[],curr;var 
push=stack.push.bind(stack);push(stmt);while(stack.length){curr=stack.pop();switch(curr.type){case"node":ids[curr.id]=true;break;case"edge":curr.elems.forEach(push);break;case"subgraph":curr.stmts.forEach(push);break}}return
 Object.keys(ids)}let idCounter=0;function uniqueId(prefix){var 
id=++idCounter;return 
toString(prefix)+id}},{"@dagrejs/graphlib":9}],4:[function(require,module,exports){module.exports=function(){
+/*
+   * Generated by PEG.js 0.8.0.
+   *
+   * http://pegjs.majda.cz/
+   */
+function peg$subclass(child,parent){function 
ctor(){this.constructor=child}ctor.prototype=parent.prototype;child.prototype=new
 ctor}function 
SyntaxError(message,expected,found,offset,line,column){this.message=message;this.expected=expected;this.found=found;this.offset=offset;this.line=line;this.column=column;this.name="SyntaxError"}peg$subclass(SyntaxError,Error);function
 parse(input){var 
options=arguments.length>1?arguments[1]:{},peg$FAILED={},peg$startRuleFunctions={start:peg$parsestar
 [...]
+// Helper object for making a pretty printer
+function 
Writer(){this._indent="";this._content="";this._shouldIndent=true}Writer.prototype.INDENT="
  
";Writer.prototype.indent=function(){this._indent+=this.INDENT};Writer.prototype.unindent=function(){this._indent=this._indent.slice(this.INDENT.length)};Writer.prototype.writeLine=function(line){this.write((line||"")+"\n");this._shouldIndent=true};Writer.prototype.write=function(str){if(this._shouldIndent){this._shouldIndent=false;this._content+=this._indent}this._content+=str};Writer.p
 [...]
+/**
+ * Copyright (c) 2014, Chris Pettitt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, 
this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its 
contributors
+ * may be used to endorse or promote products derived from this software 
without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+var 
lib=require("./lib");module.exports={Graph:lib.Graph,json:require("./lib/json"),alg:require("./lib/alg"),version:lib.version}},{"./lib":25,"./lib/alg":16,"./lib/json":26}],10:[function(require,module,exports){module.exports=components;function
 components(g){var visited={};var cmpts=[];var cmpt;function 
dfs(v){if(visited.hasOwnProperty(v))return;visited[v]=true;cmpt.push(v);g.successors(v).forEach(dfs);g.predecessors(v).forEach(dfs)}g.nodes().forEach(function(v){cmpt=[];dfs(v);if(cmpt
 [...]
+/*
+ * A helper that preforms a pre- or post-order traversal on the input graph
+ * and returns the nodes in the order they were visited. If the graph is
+ * undirected then this algorithm will navigate using neighbors. If the graph
+ * is directed then this algorithm will navigate using successors.
+ *
+ * If the order is not "post", it will be treated as "pre".
+ */function dfs(g,vs,order){if(!Array.isArray(vs)){vs=[vs]}var 
navigation=g.isDirected()?v=>g.successors(v):v=>g.neighbors(v);var 
orderFunc=order==="post"?postOrderDfs:preOrderDfs;var acc=[];var 
visited={};vs.forEach(v=>{if(!g.hasNode(v)){throw new Error("Graph does not 
have node: "+v)}orderFunc(v,navigation,visited,acc)});return acc}function 
postOrderDfs(v,navigation,visited,acc){var 
stack=[[v,false]];while(stack.length>0){var 
curr=stack.pop();if(curr[1]){acc.push(curr[0])}else{if(!visi [...]
+// Start from an arbitrary node
+pq.decrease(g.nodes()[0],0);var 
init=false;while(pq.size()>0){v=pq.removeMin();if(parents.hasOwnProperty(v)){result.setEdge(v,parents[v])}else
 if(init){throw new Error("Input graph is not connected: 
"+g)}else{init=true}g.nodeEdges(v).forEach(updateNeighbors)}return 
result}},{"../data/priority-queue":23,"../graph":24}],21:[function(require,module,exports){module.exports=tarjan;function
 tarjan(g){var index=0;var stack=[];var visited={};// node id -> { onStack, 
lowlink, index }
+var results=[];function dfs(v){var 
entry=visited[v]={onStack:true,lowlink:index,index:index++};stack.push(v);g.successors(v).forEach(function(w){if(!visited.hasOwnProperty(w)){dfs(w);entry.lowlink=Math.min(entry.lowlink,visited[w].lowlink)}else
 
if(visited[w].onStack){entry.lowlink=Math.min(entry.lowlink,visited[w].index)}});if(entry.lowlink===entry.index){var
 cmpt=[];var 
w;do{w=stack.pop();visited[w].onStack=false;cmpt.push(w)}while(v!==w);results.push(cmpt)}}g.nodes().forEach(function(v
 [...]
+/**
+ * A min-priority queue data structure. This algorithm is derived from Cormen,
+ * et al., "Introduction to Algorithms". The basic idea of a min-priority
+ * queue is that you can efficiently (in O(1) time) get the smallest key in
+ * the queue. Adding and removing elements takes O(log n) time. A key can
+ * have its priority decreased in O(log n) time.
+ */
+class PriorityQueue{#arr=[];#keyIndices={};
+/**
+   * Returns the number of elements in the queue. Takes `O(1)` time.
+   */size(){return this.#arr.length}
+/**
+   * Returns the keys that are in the queue. Takes `O(n)` time.
+   */keys(){return this.#arr.map(function(x){return x.key})}
+/**
+   * Returns `true` if **key** is in the queue and `false` if not.
+   */has(key){return this.#keyIndices.hasOwnProperty(key)}
+/**
+   * Returns the priority for **key**. If **key** is not present in the queue
+   * then this function returns `undefined`. Takes `O(1)` time.
+   *
+   * @param {Object} key
+   */priority(key){var 
index=this.#keyIndices[key];if(index!==undefined){return 
this.#arr[index].priority}}
+/**
+   * Returns the key for the minimum element in this queue. If the queue is
+   * empty this function throws an Error. Takes `O(1)` time.
+   */min(){if(this.size()===0){throw new Error("Queue underflow")}return 
this.#arr[0].key}
+/**
+   * Inserts a new key into the priority queue. If the key already exists in
+   * the queue this function returns `false`; otherwise it will return `true`.
+   * Takes `O(n)` time.
+   *
+   * @param {Object} key the key to add
+   * @param {Number} priority the initial priority for the key
+   */add(key,priority){var 
keyIndices=this.#keyIndices;key=String(key);if(!keyIndices.hasOwnProperty(key)){var
 arr=this.#arr;var 
index=arr.length;keyIndices[key]=index;arr.push({key:key,priority:priority});this.#decrease(index);return
 true}return false}
+/**
+   * Removes and returns the smallest key in the queue. Takes `O(log n)` time.
+   */removeMin(){this.#swap(0,this.#arr.length-1);var 
min=this.#arr.pop();delete this.#keyIndices[min.key];this.#heapify(0);return 
min.key}
+/**
+   * Decreases the priority for **key** to **priority**. If the new priority is
+   * greater than the previous priority, this function will throw an Error.
+   *
+   * @param {Object} key the key for which to raise priority
+   * @param {Number} priority the new priority for the key
+   */decrease(key,priority){var 
index=this.#keyIndices[key];if(priority>this.#arr[index].priority){throw new 
Error("New priority is greater than current priority. "+"Key: "+key+" Old: 
"+this.#arr[index].priority+" New: 
"+priority)}this.#arr[index].priority=priority;this.#decrease(index)}#heapify(i){var
 arr=this.#arr;var l=2*i;var r=l+1;var 
largest=i;if(l<arr.length){largest=arr[l].priority<arr[largest].priority?l:largest;if(r<arr.length){largest=arr[r].priority<arr[largest].priority?r:la
 [...]
+// Implementation notes:
+//
+//  * Node id query functions should return string ids for the nodes
+//  * Edge id query functions should return an "edgeObj", edge object, that is
+//    composed of enough information to uniquely identify an edge: {v, w, 
name}.
+//  * Internally we use an "edgeId", a stringified form of the edgeObj, to
+//    reference edges. This is because we need a performant way to look these
+//    edges up and, object properties, which have string keys, are the closest
+//    we're going to get to a performant hashtable in JavaScript.
+class Graph{#isDirected=true;#isMultigraph=false;#isCompound=false;
+// Label for the graph itself
+#label;
+// Defaults to be set when creating a new node
+#defaultNodeLabelFn=()=>undefined;
+// Defaults to be set when creating a new edge
+#defaultEdgeLabelFn=()=>undefined;
+// v -> label
+#nodes={};
+// v -> edgeObj
+#in={};
+// u -> v -> Number
+#preds={};
+// v -> edgeObj
+#out={};
+// v -> w -> Number
+#sucs={};
+// e -> edgeObj
+#edgeObjs={};
+// e -> label
+#edgeLabels={};
+/* Number of nodes in the graph. Should only be changed by the implementation. 
*/#nodeCount=0;
+/* Number of edges in the graph. Should only be changed by the implementation. 
*/#edgeCount=0;#parent;#children;constructor(opts){if(opts){this.#isDirected=opts.hasOwnProperty("directed")?opts.directed:true;this.#isMultigraph=opts.hasOwnProperty("multigraph")?opts.multigraph:false;this.#isCompound=opts.hasOwnProperty("compound")?opts.compound:false}if(this.#isCompound){
+// v -> parent
+this.#parent={};
+// v -> children
+this.#children={};this.#children[GRAPH_NODE]={}}}
+/* === Graph functions ========= */
+/**
+   * Whether graph was created with 'directed' flag set to true or not.
+   */isDirected(){return this.#isDirected}
+/**
+   * Whether graph was created with 'multigraph' flag set to true or not.
+   */isMultigraph(){return this.#isMultigraph}
+/**
+   * Whether graph was created with 'compound' flag set to true or not.
+   */isCompound(){return this.#isCompound}
+/**
+   * Sets the label of the graph.
+   */setGraph(label){this.#label=label;return this}
+/**
+   * Gets the graph label.
+   */graph(){return this.#label}
+/* === Node functions ========== */
+/**
+   * Sets the default node label. If newDefault is a function, it will be
+   * invoked ach time when setting a label for a node. Otherwise, this label
+   * will be assigned as default label in case if no label was specified while
+   * setting a node.
+   * Complexity: O(1).
+   
*/setDefaultNodeLabel(newDefault){this.#defaultNodeLabelFn=newDefault;if(typeof 
newDefault!=="function"){this.#defaultNodeLabelFn=()=>newDefault}return this}
+/**
+   * Gets the number of nodes in the graph.
+   * Complexity: O(1).
+   */nodeCount(){return this.#nodeCount}
+/**
+   * Gets all nodes of the graph. Note, the in case of compound graph subnodes 
are
+   * not included in list.
+   * Complexity: O(1).
+   */nodes(){return Object.keys(this.#nodes)}
+/**
+   * Gets list of nodes without in-edges.
+   * Complexity: O(|V|).
+   */sources(){var self=this;return 
this.nodes().filter(v=>Object.keys(self.#in[v]).length===0)}
+/**
+   * Gets list of nodes without out-edges.
+   * Complexity: O(|V|).
+   */sinks(){var self=this;return 
this.nodes().filter(v=>Object.keys(self.#out[v]).length===0)}
+/**
+   * Invokes setNode method for each node in names list.
+   * Complexity: O(|names|).
+   */setNodes(vs,value){var args=arguments;var 
self=this;vs.forEach(function(v){if(args.length>1){self.setNode(v,value)}else{self.setNode(v)}});return
 this}
+/**
+   * Creates or updates the value for the node v in the graph. If label is 
supplied
+   * it is set as the value for the node. If label is not supplied and the 
node was
+   * created by this call then the default node label will be assigned.
+   * Complexity: O(1).
+   
*/setNode(v,value){if(this.#nodes.hasOwnProperty(v)){if(arguments.length>1){this.#nodes[v]=value}return
 
this}this.#nodes[v]=arguments.length>1?value:this.#defaultNodeLabelFn(v);if(this.#isCompound){this.#parent[v]=GRAPH_NODE;this.#children[v]={};this.#children[GRAPH_NODE][v]=true}this.#in[v]={};this.#preds[v]={};this.#out[v]={};this.#sucs[v]={};++this.#nodeCount;return
 this}
+/**
+   * Gets the label of node with specified name.
+   * Complexity: O(|V|).
+   */node(v){return this.#nodes[v]}
+/**
+   * Detects whether graph has a node with specified name or not.
+   */hasNode(v){return this.#nodes.hasOwnProperty(v)}
+/**
+   * Remove the node with the name from the graph or do nothing if the node is 
not in
+   * the graph. If the node was removed this function also removes any incident
+   * edges.
+   * Complexity: O(1).
+   */removeNode(v){var self=this;if(this.#nodes.hasOwnProperty(v)){var 
removeEdge=e=>self.removeEdge(self.#edgeObjs[e]);delete 
this.#nodes[v];if(this.#isCompound){this.#removeFromParentsChildList(v);delete 
this.#parent[v];this.children(v).forEach(function(child){self.setParent(child)});delete
 this.#children[v]}Object.keys(this.#in[v]).forEach(removeEdge);delete 
this.#in[v];delete 
this.#preds[v];Object.keys(this.#out[v]).forEach(removeEdge);delete 
this.#out[v];delete this.#sucs[v];--this. [...]
+/**
+   * Sets node p as a parent for node v if it is defined, or removes the
+   * parent for v if p is undefined. Method throws an exception in case of
+   * invoking it in context of noncompound graph.
+   * Average-case complexity: O(1).
+   */setParent(v,parent){if(!this.#isCompound){throw new Error("Cannot set 
parent in a non-compound graph")}if(parent===undefined){parent=GRAPH_NODE}else{
+// Coerce parent to string
+parent+="";for(var 
ancestor=parent;ancestor!==undefined;ancestor=this.parent(ancestor)){if(ancestor===v){throw
 new Error("Setting "+parent+" as parent of "+v+" would create a 
cycle")}}this.setNode(parent)}this.setNode(v);this.#removeFromParentsChildList(v);this.#parent[v]=parent;this.#children[parent][v]=true;return
 this}#removeFromParentsChildList(v){delete this.#children[this.#parent[v]][v]}
+/**
+   * Gets parent node for node v.
+   * Complexity: O(1).
+   */parent(v){if(this.#isCompound){var 
parent=this.#parent[v];if(parent!==GRAPH_NODE){return parent}}}
+/**
+   * Gets list of direct children of node v.
+   * Complexity: O(1).
+   */children(v=GRAPH_NODE){if(this.#isCompound){var 
children=this.#children[v];if(children){return Object.keys(children)}}else 
if(v===GRAPH_NODE){return this.nodes()}else if(this.hasNode(v)){return[]}}
+/**
+   * Return all nodes that are predecessors of the specified node or undefined 
if node v is not in
+   * the graph. Behavior is undefined for undirected graphs - use neighbors 
instead.
+   * Complexity: O(|V|).
+   */predecessors(v){var predsV=this.#preds[v];if(predsV){return 
Object.keys(predsV)}}
+/**
+   * Return all nodes that are successors of the specified node or undefined 
if node v is not in
+   * the graph. Behavior is undefined for undirected graphs - use neighbors 
instead.
+   * Complexity: O(|V|).
+   */successors(v){var sucsV=this.#sucs[v];if(sucsV){return 
Object.keys(sucsV)}}
+/**
+   * Return all nodes that are predecessors or successors of the specified 
node or undefined if
+   * node v is not in the graph.
+   * Complexity: O(|V|).
+   */neighbors(v){var preds=this.predecessors(v);if(preds){const union=new 
Set(preds);for(var succ of this.successors(v)){union.add(succ)}return 
Array.from(union.values())}}isLeaf(v){var 
neighbors;if(this.isDirected()){neighbors=this.successors(v)}else{neighbors=this.neighbors(v)}return
 neighbors.length===0}
+/**
+   * Creates new graph with nodes filtered via filter. Edges incident to 
rejected node
+   * are also removed. In case of compound graph, if parent is rejected by 
filter,
+   * than all its children are rejected too.
+   * Average-case complexity: O(|E|+|V|).
+   */filterNodes(filter){var copy=new 
this.constructor({directed:this.#isDirected,multigraph:this.#isMultigraph,compound:this.#isCompound});copy.setGraph(this.graph());var
 
self=this;Object.entries(this.#nodes).forEach(function([v,value]){if(filter(v)){copy.setNode(v,value)}});Object.values(this.#edgeObjs).forEach(function(e){if(copy.hasNode(e.v)&&copy.hasNode(e.w)){copy.setEdge(e,self.edge(e))}});var
 parents={};function findParent(v){var 
parent=self.parent(v);if(parent===undefined||copy. [...]
+/* === Edge functions ========== */
+/**
+   * Sets the default edge label or factory function. This label will be
+   * assigned as default label in case if no label was specified while setting
+   * an edge or this function will be invoked each time when setting an edge
+   * with no label specified and returned value * will be used as a label for 
edge.
+   * Complexity: O(1).
+   
*/setDefaultEdgeLabel(newDefault){this.#defaultEdgeLabelFn=newDefault;if(typeof 
newDefault!=="function"){this.#defaultEdgeLabelFn=()=>newDefault}return this}
+/**
+   * Gets the number of edges in the graph.
+   * Complexity: O(1).
+   */edgeCount(){return this.#edgeCount}
+/**
+   * Gets edges of the graph. In case of compound graph subgraphs are not 
considered.
+   * Complexity: O(|E|).
+   */edges(){return Object.values(this.#edgeObjs)}
+/**
+   * Establish an edges path over the nodes in nodes list. If some edge is 
already
+   * exists, it will update its label, otherwise it will create an edge 
between pair
+   * of nodes with label provided or default label if no label provided.
+   * Complexity: O(|nodes|).
+   */setPath(vs,value){var self=this;var 
args=arguments;vs.reduce(function(v,w){if(args.length>1){self.setEdge(v,w,value)}else{self.setEdge(v,w)}return
 w});return this}
+/**
+   * Creates or updates the label for the edge (v, w) with the optionally 
supplied
+   * name. If label is supplied it is set as the value for the edge. If label 
is not
+   * supplied and the edge was created by this call then the default edge 
label will
+   * be assigned. The name parameter is only useful with multigraphs.
+   */setEdge(){var v,w,name,value;var valueSpecified=false;var 
arg0=arguments[0];if(typeof arg0==="object"&&arg0!==null&&"v"in 
arg0){v=arg0.v;w=arg0.w;name=arg0.name;if(arguments.length===2){value=arguments[1];valueSpecified=true}}else{v=arg0;w=arguments[1];name=arguments[3];if(arguments.length>2){value=arguments[2];valueSpecified=true}}v=""+v;w=""+w;if(name!==undefined){name=""+name}var
 
e=edgeArgsToId(this.#isDirected,v,w,name);if(this.#edgeLabels.hasOwnProperty(e)){if(valueSpecified){t
 [...]
+// It didn't exist, so we need to create it.
+// First ensure the nodes exist.
+this.setNode(v);this.setNode(w);this.#edgeLabels[e]=valueSpecified?value:this.#defaultEdgeLabelFn(v,w,name);var
 edgeObj=edgeArgsToObj(this.#isDirected,v,w,name);
+// Ensure we add undirected edges in a consistent way.
+v=edgeObj.v;w=edgeObj.w;Object.freeze(edgeObj);this.#edgeObjs[e]=edgeObj;incrementOrInitEntry(this.#preds[w],v);incrementOrInitEntry(this.#sucs[v],w);this.#in[w][e]=edgeObj;this.#out[v][e]=edgeObj;this.#edgeCount++;return
 this}
+/**
+   * Gets the label for the specified edge.
+   * Complexity: O(1).
+   */edge(v,w,name){var 
e=arguments.length===1?edgeObjToId(this.#isDirected,arguments[0]):edgeArgsToId(this.#isDirected,v,w,name);return
 this.#edgeLabels[e]}
+/**
+   * Gets the label for the specified edge and converts it to an object.
+   * Complexity: O(1)
+   */edgeAsObj(){const edge=this.edge(...arguments);if(typeof 
edge!=="object"){return{label:edge}}return edge}
+/**
+   * Detects whether the graph contains specified edge or not. No subgraphs 
are considered.
+   * Complexity: O(1).
+   */hasEdge(v,w,name){var 
e=arguments.length===1?edgeObjToId(this.#isDirected,arguments[0]):edgeArgsToId(this.#isDirected,v,w,name);return
 this.#edgeLabels.hasOwnProperty(e)}
+/**
+   * Removes the specified edge from the graph. No subgraphs are considered.
+   * Complexity: O(1).
+   */removeEdge(v,w,name){var 
e=arguments.length===1?edgeObjToId(this.#isDirected,arguments[0]):edgeArgsToId(this.#isDirected,v,w,name);var
 edge=this.#edgeObjs[e];if(edge){v=edge.v;w=edge.w;delete 
this.#edgeLabels[e];delete 
this.#edgeObjs[e];decrementOrRemoveEntry(this.#preds[w],v);decrementOrRemoveEntry(this.#sucs[v],w);delete
 this.#in[w][e];delete this.#out[v][e];this.#edgeCount--}return this}
+/**
+   * Return all edges that point to the node v. Optionally filters those edges 
down to just those
+   * coming from node u. Behavior is undefined for undirected graphs - use 
nodeEdges instead.
+   * Complexity: O(|E|).
+   */inEdges(v,u){var inV=this.#in[v];if(inV){var 
edges=Object.values(inV);if(!u){return edges}return 
edges.filter(edge=>edge.v===u)}}
+/**
+   * Return all edges that are pointed at by node v. Optionally filters those 
edges down to just
+   * those point to w. Behavior is undefined for undirected graphs - use 
nodeEdges instead.
+   * Complexity: O(|E|).
+   */outEdges(v,w){var outV=this.#out[v];if(outV){var 
edges=Object.values(outV);if(!w){return edges}return 
edges.filter(edge=>edge.w===w)}}
+/**
+   * Returns all edges to or from node v regardless of direction. Optionally 
filters those edges
+   * down to just those between nodes v and w regardless of direction.
+   * Complexity: O(|E|).
+   */nodeEdges(v,w){var inEdges=this.inEdges(v,w);if(inEdges){return 
inEdges.concat(this.outEdges(v,w))}}}function 
incrementOrInitEntry(map,k){if(map[k]){map[k]++}else{map[k]=1}}function 
decrementOrRemoveEntry(map,k){if(!--map[k]){delete map[k]}}function 
edgeArgsToId(isDirected,v_,w_,name){var v=""+v_;var 
w=""+w_;if(!isDirected&&v>w){var tmp=v;v=w;w=tmp}return 
v+EDGE_KEY_DELIM+w+EDGE_KEY_DELIM+(name===undefined?DEFAULT_EDGE_NAME:name)}function
 edgeArgsToObj(isDirected,v_,w_,name){var v=" [...]
+// Includes only the "core" of graphlib
+module.exports={Graph:require("./graph"),version:require("./version")}},{"./graph":24,"./version":27}],26:[function(require,module,exports){var
 Graph=require("./graph");module.exports={write:write,read:read};
+/**
+ * Creates a JSON representation of the graph that can be serialized to a 
string with
+ * JSON.stringify. The graph can later be restored using json.read.
+ */function write(g){var 
json={options:{directed:g.isDirected(),multigraph:g.isMultigraph(),compound:g.isCompound()},nodes:writeNodes(g),edges:writeEdges(g)};if(g.graph()!==undefined){json.value=structuredClone(g.graph())}return
 json}function writeNodes(g){return g.nodes().map(function(v){var 
nodeValue=g.node(v);var parent=g.parent(v);var 
node={v:v};if(nodeValue!==undefined){node.value=nodeValue}if(parent!==undefined){node.parent=parent}return
 node})}function writeEdges(g){return g.edges [...]
+/**
+ * Takes JSON as input and returns the graph representation.
+ *
+ * @example
+ * var g2 = graphlib.json.read(JSON.parse(str));
+ * g2.nodes();
+ * // ['a', 'b']
+ * g2.edges()
+ * // [ { v: 'a', w: 'b' } ]
+ */function read(json){var g=new 
Graph(json.options).setGraph(json.value);json.nodes.forEach(function(entry){g.setNode(entry.v,entry.value);if(entry.parent){g.setParent(entry.v,entry.parent)}});json.edges.forEach(function(entry){g.setEdge({v:entry.v,w:entry.w,name:entry.name},entry.value)});return
 
g}},{"./graph":24}],27:[function(require,module,exports){module.exports="2.1.13"},{}]},{},[1]);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to