PageRenderTime 68ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/js/vendor/dagre.js

https://github.com/marthlab/iseqtools-portal
JavaScript | 4047 lines | 3579 code | 262 blank | 206 comment | 250 complexity | 18735894fa52e88fd37884823f2dd51d MD5 | raw file
  1. /*
  2. Copyright (c) 2012 Chris Pettitt
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to deal
  5. in the Software without restriction, including without limitation the rights
  6. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  17. THE SOFTWARE.
  18. */
  19. (function() {
  20. dagre = {};
  21. dagre.version = "0.0.6";
  22. /*
  23. * Directed multi-graph used during layout.
  24. */
  25. dagre.graph = {};
  26. /*
  27. * Creates a new directed multi-graph. This should be invoked with
  28. * `var g = dagre.graph()` and _not_ `var g = new dagre.graph()`.
  29. */
  30. dagre.graph = function() {
  31. var nodes = {},
  32. inEdges = {},
  33. outEdges = {},
  34. edges = {},
  35. graph = {},
  36. idCounter = 0;
  37. graph.addNode = function(u, value) {
  38. if (graph.hasNode(u)) {
  39. throw new Error("Graph already has node '" + u + "':\n" + graph.toString());
  40. }
  41. nodes[u] = { id: u, value: value };
  42. inEdges[u] = {};
  43. outEdges[u] = {};
  44. }
  45. graph.delNode = function(u) {
  46. strictGetNode(u);
  47. graph.edges(u).forEach(function(e) { graph.delEdge(e); });
  48. delete inEdges[u];
  49. delete outEdges[u];
  50. delete nodes[u];
  51. }
  52. graph.node = function(u) {
  53. return strictGetNode(u).value;
  54. }
  55. graph.hasNode = function(u) {
  56. return u in nodes;
  57. }
  58. graph.addEdge = function(e, source, target, value) {
  59. strictGetNode(source);
  60. strictGetNode(target);
  61. if (e === null) {
  62. e = "_ANON-" + ++idCounter;
  63. }
  64. else if (graph.hasEdge(e)) {
  65. throw new Error("Graph already has edge '" + e + "':\n" + graph.toString());
  66. }
  67. edges[e] = { id: e, source: source, target: target, value: value };
  68. addEdgeToMap(inEdges[target], source, e);
  69. addEdgeToMap(outEdges[source], target, e);
  70. }
  71. graph.delEdge = function(e) {
  72. var edge = strictGetEdge(e);
  73. delEdgeFromMap(inEdges[edge.target], edge.source, e)
  74. delEdgeFromMap(outEdges[edge.source], edge.target, e)
  75. delete edges[e];
  76. }
  77. graph.edge = function(e) {
  78. return strictGetEdge(e).value;
  79. }
  80. graph.source = function(e) {
  81. return strictGetEdge(e).source;
  82. }
  83. graph.target = function(e) {
  84. return strictGetEdge(e).target;
  85. }
  86. graph.hasEdge = function(e) {
  87. return e in edges;
  88. }
  89. graph.successors = function(u) {
  90. strictGetNode(u);
  91. return keys(outEdges[u]).map(function(v) { return nodes[v].id; });
  92. }
  93. graph.predecessors = function(u) {
  94. strictGetNode(u);
  95. return keys(inEdges[u]).map(function(v) { return nodes[v].id; });
  96. }
  97. graph.neighbors = function(u) {
  98. strictGetNode(u);
  99. var vs = {};
  100. keys(outEdges[u]).map(function(v) { vs[v] = true; });
  101. keys(inEdges[u]).map(function(v) { vs[v] = true; });
  102. return keys(vs).map(function(v) { return nodes[v].id; });
  103. }
  104. graph.nodes = function() {
  105. var nodes = [];
  106. graph.eachNode(function(id, _) { nodes.push(id); });
  107. return nodes;
  108. }
  109. graph.eachNode = function(func) {
  110. for (var k in nodes) {
  111. var node = nodes[k];
  112. func(node.id, node.value);
  113. }
  114. }
  115. /*
  116. * Return all edges with no arguments,
  117. * the ones that are incident on a node (one argument),
  118. * or all edges from a source to a target (two arguments)
  119. */
  120. graph.edges = function(u, v) {
  121. var es, sourceEdges;
  122. if (!arguments.length) {
  123. es = [];
  124. graph.eachEdge(function(id) { es.push(id); });
  125. return es;
  126. } else if (arguments.length === 1) {
  127. return union([graph.inEdges(u), graph.outEdges(u)]);
  128. } else if (arguments.length === 2) {
  129. strictGetNode(u);
  130. strictGetNode(v);
  131. sourceEdges = outEdges[u];
  132. es = (v in sourceEdges) ? keys(sourceEdges[v].edges) : [];
  133. return es.map(function(e) { return edges[e].id });
  134. }
  135. };
  136. graph.eachEdge = function(func) {
  137. for (var k in edges) {
  138. var edge = edges[k];
  139. func(edge.id, edge.source, edge.target, edge.value);
  140. }
  141. }
  142. /*
  143. * Return all in edges to a target node
  144. */
  145. graph.inEdges = function(target) {
  146. strictGetNode(target);
  147. return concat(values(inEdges[target]).map(function(es) { return keys(es.edges); }));
  148. };
  149. /*
  150. * Return all out edges from a source node
  151. */
  152. graph.outEdges = function(source) {
  153. strictGetNode(source);
  154. return concat(values(outEdges[source]).map(function(es) { return keys(es.edges); }));
  155. };
  156. graph.subgraph = function(us) {
  157. var g = dagre.graph();
  158. us.forEach(function(u) {
  159. g.addNode(u, graph.node(u));
  160. });
  161. values(edges).forEach(function(e) {
  162. if (g.hasNode(e.source) && g.hasNode(e.target)) {
  163. g.addEdge(e.id, e.source, e.target, graph.edge(e.id));
  164. }
  165. });
  166. return g;
  167. };
  168. graph.toString = function() {
  169. var str = "GRAPH:\n";
  170. str += " Nodes:\n";
  171. keys(nodes).forEach(function(u) {
  172. str += " " + u + ": " + JSON.stringify(nodes[u].value) + "\n";
  173. });
  174. str += " Edges:\n";
  175. keys(edges).forEach(function(e) {
  176. var edge = edges[e];
  177. str += " " + e + " (" + edge.source + " -> " + edge.target + "): " + JSON.stringify(edges[e].value) + "\n";
  178. });
  179. return str;
  180. };
  181. function addEdgeToMap(map, v, e) {
  182. var vEntry = map[v];
  183. if (!vEntry) {
  184. vEntry = map[v] = { count: 0, edges: {} };
  185. }
  186. vEntry.count++;
  187. vEntry.edges[e] = true;
  188. }
  189. function delEdgeFromMap(map, v, e) {
  190. var vEntry = map[v];
  191. if (--vEntry.count == 0) {
  192. delete map[v];
  193. } else {
  194. delete vEntry.edges[e];
  195. }
  196. }
  197. function strictGetNode(u) {
  198. var node = nodes[u];
  199. if (!(u in nodes)) {
  200. throw new Error("Node '" + u + "' is not in graph:\n" + graph.toString());
  201. }
  202. return node;
  203. }
  204. function strictGetEdge(e) {
  205. var edge = edges[e];
  206. if (!edge) {
  207. throw new Error("Edge '" + e + "' is not in graph:\n" + graph.toString());
  208. }
  209. return edge;
  210. }
  211. return graph;
  212. }
  213. dagre.layout = function() {
  214. // External configuration
  215. var config = {
  216. // Nodes to lay out. At minimum must have `width` and `height` attributes.
  217. nodes: [],
  218. // Edges to lay out. At mimimum must have `source` and `target` attributes.
  219. edges: [],
  220. // How much debug information to include?
  221. debugLevel: 0,
  222. };
  223. var timer = createTimer();
  224. // Phase functions
  225. var
  226. acyclic = dagre.layout.acyclic(),
  227. rank = dagre.layout.rank(),
  228. order = dagre.layout.order(),
  229. position = dagre.layout.position();
  230. // This layout object
  231. var self = {};
  232. self.nodes = propertyAccessor(self, config, "nodes");
  233. self.edges = propertyAccessor(self, config, "edges");
  234. self.orderIters = delegateProperty(order.iterations);
  235. self.nodeSep = delegateProperty(position.nodeSep);
  236. self.edgeSep = delegateProperty(position.edgeSep);
  237. self.rankSep = delegateProperty(position.rankSep);
  238. self.rankDir = delegateProperty(position.rankDir);
  239. self.debugAlignment = delegateProperty(position.debugAlignment);
  240. self.debugLevel = propertyAccessor(self, config, "debugLevel", function(x) {
  241. timer.enabled(x);
  242. acyclic.debugLevel(x);
  243. rank.debugLevel(x);
  244. order.debugLevel(x);
  245. position.debugLevel(x);
  246. });
  247. self.run = timer.wrap("Total layout", run);
  248. return self;
  249. // Build graph and save mapping of generated ids to original nodes and edges
  250. function init() {
  251. var g = dagre.graph();
  252. var nextId = 0;
  253. // Tag each node so that we can properly represent relationships when
  254. // we add edges. Also copy relevant dimension information.
  255. config.nodes.forEach(function(u) {
  256. var id = "id" in u ? u.id : "_N" + nextId++;
  257. u.dagre = { id: id, width: u.width, height: u.height, offsetwidth: u.offsetwidth || u.width/2, offsetheight: u.offsetheight || u.height/2};
  258. g.addNode(id, u.dagre);
  259. });
  260. config.edges.forEach(function(e) {
  261. var source = e.source.dagre.id;
  262. if (!g.hasNode(source)) {
  263. throw new Error("Source node for '" + e + "' not in node list");
  264. }
  265. var target = e.target.dagre.id;
  266. if (!g.hasNode(target)) {
  267. throw new Error("Target node for '" + e + "' not in node list");
  268. }
  269. e.dagre = {
  270. points: []
  271. };
  272. // Track edges that aren't self loops - layout does nothing for self
  273. // loops, so they can be skipped.
  274. if (source !== target) {
  275. var id = "id" in e ? e.id : "_E" + nextId++;
  276. e.dagre.id = id;
  277. e.dagre.minLen = e.minLen || 1;
  278. e.dagre.width = e.width || 0;
  279. e.dagre.height = e.height || 0;
  280. g.addEdge(id, source, target, e.dagre);
  281. }
  282. });
  283. return g;
  284. }
  285. function run () {
  286. var rankSep = self.rankSep();
  287. try {
  288. if (!config.nodes.length) {
  289. return;
  290. }
  291. // Build internal graph
  292. var g = init();
  293. // Make space for edge labels
  294. g.eachEdge(function(e, s, t, a) {
  295. a.minLen *= 2;
  296. });
  297. self.rankSep(rankSep / 2);
  298. // Reverse edges to get an acyclic graph, we keep the graph in an acyclic
  299. // state until the very end.
  300. acyclic.run(g);
  301. // Determine the rank for each node. Nodes with a lower rank will appear
  302. // above nodes of higher rank.
  303. rank.run(g);
  304. // Normalize the graph by ensuring that every edge is proper (each edge has
  305. // a length of 1). We achieve this by adding dummy nodes to long edges,
  306. // thus shortening them.
  307. normalize(g);
  308. // Order the nodes so that edge crossings are minimized.
  309. order.run(g);
  310. // Find the x and y coordinates for every node in the graph.
  311. position.run(g);
  312. // De-normalize the graph by removing dummy nodes and augmenting the
  313. // original long edges with coordinate information.
  314. undoNormalize(g);
  315. // Reverses points for edges that are in a reversed state.
  316. fixupEdgePoints(g);
  317. // Reverse edges that were revered previously to get an acyclic graph.
  318. acyclic.undo(g);
  319. } finally {
  320. self.rankSep(rankSep);
  321. }
  322. return self;
  323. }
  324. // Assumes input graph has no self-loops and is otherwise acyclic.
  325. function normalize(g) {
  326. var dummyCount = 0;
  327. g.eachEdge(function(e, s, t, a) {
  328. var sourceRank = g.node(s).rank;
  329. var targetRank = g.node(t).rank;
  330. if (sourceRank + 1 < targetRank) {
  331. for (var u = s, rank = sourceRank + 1, i = 0; rank < targetRank; ++rank, ++i) {
  332. var v = "_D" + ++dummyCount;
  333. var node = {
  334. width: a.width,
  335. height: a.height,
  336. offsetwidth: a.width/2,
  337. offsetheight: a.height/2,
  338. edge: { id: e, source: s, target: t, attrs: a },
  339. rank: rank,
  340. dummy: true
  341. };
  342. // If this node represents a bend then we will use it as a control
  343. // point. For edges with 2 segments this will be the center dummy
  344. // node. For edges with more than two segments, this will be the
  345. // first and last dummy node.
  346. if (i === 0) node.index = 0;
  347. else if (rank + 1 === targetRank) node.index = 1;
  348. g.addNode(v, node);
  349. g.addEdge(null, u, v, {});
  350. u = v;
  351. }
  352. g.addEdge(null, u, t, {});
  353. g.delEdge(e);
  354. }
  355. });
  356. }
  357. function undoNormalize(g) {
  358. var visited = {};
  359. g.eachNode(function(u, a) {
  360. if (a.dummy && "index" in a) {
  361. var edge = a.edge;
  362. if (!g.hasEdge(edge.id)) {
  363. g.addEdge(edge.id, edge.source, edge.target, edge.attrs);
  364. }
  365. var points = g.edge(edge.id).points;
  366. points[a.index] = { x: a.x, y: a.y };
  367. g.delNode(u);
  368. }
  369. });
  370. }
  371. function fixupEdgePoints(g) {
  372. g.eachEdge(function(e, s, t, a) { if (a.reversed) a.points.reverse(); });
  373. }
  374. function delegateProperty(f) {
  375. return function() {
  376. if (!arguments.length) return f();
  377. f.apply(null, arguments);
  378. return self;
  379. }
  380. }
  381. }
  382. dagre.layout.acyclic = function() {
  383. // External configuration
  384. var config = {
  385. debugLevel: 0
  386. }
  387. var timer = createTimer();
  388. var self = {};
  389. self.debugLevel = propertyAccessor(self, config, "debugLevel", function(x) {
  390. timer.enabled(x);
  391. });
  392. self.run = timer.wrap("Acyclic Phase", run);
  393. self.undo = function(g) {
  394. g.eachEdge(function(e, s, t, a) {
  395. if (a.reversed) {
  396. delete a.reversed;
  397. g.delEdge(e);
  398. g.addEdge(e, t, s, a);
  399. }
  400. });
  401. }
  402. return self;
  403. function run(g) {
  404. var onStack = {},
  405. visited = {},
  406. reverseCount = 0;
  407. function dfs(u) {
  408. if (u in visited) return;
  409. visited[u] = onStack[u] = true;
  410. g.outEdges(u).forEach(function(e) {
  411. var t = g.target(e),
  412. a;
  413. if (t in onStack) {
  414. a = g.edge(e);
  415. g.delEdge(e);
  416. a.reversed = true;
  417. ++reverseCount;
  418. g.addEdge(e, t, u, a);
  419. } else {
  420. dfs(t);
  421. }
  422. });
  423. delete onStack[u];
  424. }
  425. g.eachNode(function(u) { dfs(u); });
  426. if (config.debugLevel >= 2) console.log("Acyclic Phase: reversed " + reverseCount + " edge(s)");
  427. }
  428. };
  429. dagre.layout.rank = function() {
  430. // External configuration
  431. var config = {
  432. debugLevel: 0
  433. };
  434. var timer = createTimer();
  435. var self = {};
  436. self.debugLevel = propertyAccessor(self, config, "debugLevel", function(x) {
  437. timer.enabled(x);
  438. });
  439. self.run = timer.wrap("Rank Phase", run);
  440. return self;
  441. function run(g) {
  442. initRank(g);
  443. components(g).forEach(function(cmpt) {
  444. var subgraph = g.subgraph(cmpt);
  445. feasibleTree(subgraph);
  446. normalize(subgraph);
  447. });
  448. };
  449. function initRank(g) {
  450. var minRank = {};
  451. var pq = priorityQueue();
  452. g.eachNode(function(u) {
  453. pq.add(u, g.inEdges(u).length);
  454. minRank[u] = 0;
  455. });
  456. while (pq.size() > 0) {
  457. var minId = pq.min();
  458. if (pq.priority(minId) > 0) {
  459. throw new Error("Input graph is not acyclic: " + g.toString());
  460. }
  461. pq.removeMin();
  462. var rank = minRank[minId];
  463. g.node(minId).rank = rank;
  464. g.outEdges(minId).forEach(function(e) {
  465. var target = g.target(e);
  466. minRank[target] = Math.max(minRank[target], rank + (g.edge(e).minLen || 1));
  467. pq.decrease(target, pq.priority(target) - 1);
  468. });
  469. }
  470. }
  471. function feasibleTree(g) {
  472. // Precompute minimum lengths for each directed edge
  473. var minLen = {};
  474. g.eachEdge(function(e, source, target, edge) {
  475. var id = incidenceId(source, target);
  476. minLen[id] = Math.max(minLen[id] || 1, edge.minLen || 1);
  477. });
  478. var tree = dagre.util.prim(g, function(u, v) {
  479. return Math.abs(g.node(u).rank - g.node(v).rank) - minLen[incidenceId(u, v)];
  480. });
  481. var visited = {};
  482. function dfs(u, rank) {
  483. visited[u] = true;
  484. g.node(u).rank = rank;
  485. tree[u].forEach(function(v) {
  486. if (!(v in visited)) {
  487. var delta = minLen[incidenceId(u, v)];
  488. dfs(v, rank + (g.edges(u, v).length ? delta : -delta));
  489. }
  490. });
  491. }
  492. dfs(g.nodes()[0], 0);
  493. return tree;
  494. }
  495. function normalize(g) {
  496. var m = min(g.nodes().map(function(u) { return g.node(u).rank; }));
  497. g.eachNode(function(u, node) { node.rank -= m; });
  498. }
  499. /*
  500. * This id can be used to group (in an undirected manner) multi-edges
  501. * incident on the same two nodes.
  502. */
  503. function incidenceId(u, v) {
  504. return u < v ? u.length + ":" + u + "-" + v : v.length + ":" + v + "-" + u;
  505. }
  506. }
  507. dagre.layout.order = function() {
  508. var config = {
  509. iterations: 24, // max number of iterations
  510. debugLevel: 0
  511. };
  512. var timer = createTimer();
  513. var self = {};
  514. self.iterations = propertyAccessor(self, config, "iterations");
  515. self.debugLevel = propertyAccessor(self, config, "debugLevel", function(x) {
  516. timer.enabled(x);
  517. });
  518. self.run = timer.wrap("Order Phase", run);
  519. return self;
  520. function run(g) {
  521. var layering = initOrder(g);
  522. var bestLayering = copyLayering(layering);
  523. var bestCC = crossCount(g, layering);
  524. if (config.debugLevel >= 2) {
  525. console.log("Order phase start cross count: " + bestCC);
  526. }
  527. var cc, i, lastBest;
  528. for (i = 0, lastBest = 0; lastBest < 4 && i < config.iterations; ++i, ++lastBest) {
  529. cc = sweep(g, i, layering);
  530. if (cc < bestCC) {
  531. bestLayering = copyLayering(layering);
  532. bestCC = cc;
  533. lastBest = 0;
  534. }
  535. if (config.debugLevel >= 3) {
  536. console.log("Order phase iter " + i + " cross count: " + bestCC);
  537. }
  538. }
  539. bestLayering.forEach(function(layer) {
  540. layer.forEach(function(u, i) {
  541. g.node(u).order = i;
  542. });
  543. });
  544. if (config.debugLevel >= 2) {
  545. console.log("Order iterations: " + i);
  546. console.log("Order phase best cross count: " + bestCC);
  547. }
  548. return bestLayering;
  549. }
  550. function initOrder(g) {
  551. var layering = [];
  552. g.eachNode(function(n, a) {
  553. var layer = layering[a.rank] || (layering[a.rank] = []);
  554. layer.push(n);
  555. });
  556. return layering;
  557. }
  558. /*
  559. * Returns a function that will return the predecessors for a node. This
  560. * function differs from `g.predecessors(u)` in that a predecessor appears
  561. * for each incident edge (`g.predecessors(u)` treats predecessors as a set).
  562. * This allows pseudo-weighting of predecessor nodes.
  563. */
  564. function multiPredecessors(g) {
  565. return function(u) {
  566. var preds = [];
  567. g.inEdges(u).forEach(function(e) {
  568. preds.push(g.source(e));
  569. });
  570. return preds;
  571. }
  572. }
  573. /*
  574. * Same as `multiPredecessors(g)` but for successors.
  575. */
  576. function multiSuccessors(g) {
  577. return function(u) {
  578. var sucs = [];
  579. g.outEdges(u).forEach(function(e) {
  580. sucs.push(g.target(e));
  581. });
  582. return sucs;
  583. }
  584. }
  585. function sweep(g, iter, layering) {
  586. if (iter % 2 === 0) {
  587. for (var i = 1; i < layering.length; ++i) {
  588. barycenterLayer(layering[i - 1], layering[i], multiPredecessors(g));
  589. }
  590. } else {
  591. for (var i = layering.length - 2; i >= 0; --i) {
  592. barycenterLayer(layering[i + 1], layering[i], multiSuccessors(g));
  593. }
  594. }
  595. return crossCount(g, layering);
  596. }
  597. /*
  598. * Given a fixed layer and a movable layer in a graph this function will
  599. * attempt to find an improved ordering for the movable layer such that
  600. * edge crossings may be reduced.
  601. *
  602. * This algorithm is based on the barycenter method.
  603. */
  604. function barycenterLayer(fixed, movable, predecessors) {
  605. var pos = layerPos(movable);
  606. var bs = barycenters(fixed, movable, predecessors);
  607. var toSort = movable.slice(0).sort(function(x, y) {
  608. return bs[x] - bs[y] || pos[x] - pos[y];
  609. });
  610. for (var i = movable.length - 1; i >= 0; --i) {
  611. if (bs[movable[i]] !== -1) {
  612. movable[i] = toSort.pop();
  613. }
  614. }
  615. }
  616. /*
  617. * Given a fixed layer and a movable layer in a graph, this function will
  618. * return weights for the movable layer that can be used to reorder the layer
  619. * for potentially reduced edge crossings.
  620. */
  621. function barycenters(fixed, movable, predecessors) {
  622. var pos = layerPos(fixed), // Position of node in fixed list
  623. bs = {}; // Barycenters for each node
  624. movable.forEach(function(u) {
  625. var b = -1;
  626. var preds = predecessors(u);
  627. if (preds.length > 0) {
  628. b = 0;
  629. preds.forEach(function(v) { b += pos[v]; });
  630. b = b / preds.length;
  631. }
  632. bs[u] = b;
  633. });
  634. return bs;
  635. }
  636. function copyLayering(layering) {
  637. return layering.map(function(l) { return l.slice(0); });
  638. }
  639. }
  640. var crossCount = dagre.layout.order.crossCount = function(g, layering) {
  641. var cc = 0;
  642. var prevLayer;
  643. layering.forEach(function(layer) {
  644. if (prevLayer) {
  645. cc += bilayerCrossCount(g, prevLayer, layer);
  646. }
  647. prevLayer = layer;
  648. });
  649. return cc;
  650. }
  651. /*
  652. * This function searches through a ranked and ordered graph and counts the
  653. * number of edges that cross. This algorithm is derived from:
  654. *
  655. * W. Barth et al., Bilayer Cross Counting, JGAA, 8(2) 179–194 (2004)
  656. */
  657. var bilayerCrossCount = dagre.layout.order.bilayerCrossCount = function(g, layer1, layer2) {
  658. var layer2Pos = layerPos(layer2);
  659. var indices = [];
  660. layer1.forEach(function(u) {
  661. var nodeIndices = [];
  662. g.outEdges(u).forEach(function(e) { nodeIndices.push(layer2Pos[g.target(e)]); });
  663. nodeIndices.sort(function(x, y) { return x - y; });
  664. indices = indices.concat(nodeIndices);
  665. });
  666. var firstIndex = 1;
  667. while (firstIndex < layer2.length) firstIndex <<= 1;
  668. var treeSize = 2 * firstIndex - 1;
  669. firstIndex -= 1;
  670. var tree = [];
  671. for (var i = 0; i < treeSize; ++i) { tree[i] = 0; }
  672. var cc = 0;
  673. indices.forEach(function(i) {
  674. var treeIndex = i + firstIndex;
  675. ++tree[treeIndex];
  676. var weightSum = 0;
  677. while (treeIndex > 0) {
  678. if (treeIndex % 2) {
  679. cc += tree[treeIndex + 1];
  680. }
  681. treeIndex = (treeIndex - 1) >> 1;
  682. ++tree[treeIndex];
  683. }
  684. });
  685. return cc;
  686. }
  687. function layerPos(layer) {
  688. var pos = {};
  689. layer.forEach(function(u, i) { pos[u] = i; });
  690. return pos;
  691. }
  692. /*
  693. * The algorithms here are based on Brandes and KĂśpf, "Fast and Simple
  694. * Horizontal Coordinate Assignment".
  695. */
  696. dagre.layout.position = function() {
  697. // External configuration
  698. var config = {
  699. nodeSep: 50,
  700. edgeSep: 10,
  701. rankSep: 30,
  702. rankDir: "TB",
  703. debugAlignment: null,
  704. debugLevel: 0
  705. };
  706. var timer = createTimer();
  707. var self = {};
  708. self.nodeSep = propertyAccessor(self, config, "nodeSep");
  709. self.edgeSep = propertyAccessor(self, config, "edgeSep");
  710. self.rankSep = propertyAccessor(self, config, "rankSep");
  711. self.rankDir = propertyAccessor(self, config, "rankDir");
  712. self.debugAlignment = propertyAccessor(self, config, "debugAlignment");
  713. self.debugLevel = propertyAccessor(self, config, "debugLevel", function(x) {
  714. timer.enabled(x);
  715. });
  716. self.run = timer.wrap("Position Phase", run);
  717. return self;
  718. function run(g) {
  719. var layering = [];
  720. g.eachNode(function(u, node) {
  721. var layer = layering[node.rank] || (layering[node.rank] = []);
  722. layer[node.order] = u;
  723. });
  724. var conflicts = findConflicts(g, layering);
  725. var xss = {};
  726. ["up", "down"].forEach(function(vertDir) {
  727. if (vertDir === "down") layering.reverse();
  728. ["left", "right"].forEach(function(horizDir) {
  729. if (horizDir === "right") reverseInnerOrder(layering);
  730. var dir = vertDir + "-" + horizDir;
  731. if (!config.debugAlignment || config.debugAlignment === dir) {
  732. var align = verticalAlignment(g, layering, conflicts, vertDir === "up" ? "predecessors" : "successors");
  733. xss[dir]= horizontalCompaction(g, layering, align.pos, align.root, align.align);
  734. if (horizDir === "right") flipHorizontally(layering, xss[dir]);
  735. }
  736. if (horizDir === "right") reverseInnerOrder(layering);
  737. });
  738. if (vertDir === "down") layering.reverse();
  739. });
  740. if (config.debugAlignment) {
  741. // In debug mode we allow forcing layout to a particular alignment.
  742. g.eachNode(function(u, node) { x(g, u, xss[config.debugAlignment][u]); });
  743. } else {
  744. balance(g, layering, xss);
  745. }
  746. balance(g, layering, xss);
  747. //g.eachNode(function(u) { x(g, u, x(g, u) + offsetWidth(g, u) - width(g,u)/2); });
  748. // Translate layout so left edge of bounding rectangle has coordinate 0
  749. var minX = min(g.nodes().map(function(u) { return x(g, u) - width(g, u) / 2; }));
  750. g.eachNode(function(u) { x(g, u, x(g, u) - minX); });
  751. // Align y coordinates with ranks
  752. var posY = 0;
  753. layering.forEach(function(layer) {
  754. var maxHeight = max(layer.map(function(u) { return height(g, u); }));
  755. posY += maxHeight / 2;
  756. layer.forEach(function(u) { y(g, u, posY); });
  757. posY += maxHeight / 2 + config.rankSep;
  758. });
  759. };
  760. /*
  761. * Generate an ID that can be used to represent any undirected edge that is
  762. * incident on `u` and `v`.
  763. */
  764. function undirEdgeId(u, v) {
  765. return u < v
  766. ? u.toString().length + ":" + u + "-" + v
  767. : v.toString().length + ":" + v + "-" + u;
  768. }
  769. function findConflicts(g, layering) {
  770. var conflicts = {}, // Set of conflicting edge ids
  771. pos = {}; // Position of node in its layer
  772. if (layering.length <= 2) return conflicts;
  773. layering[1].forEach(function(u, i) { pos[u] = i; });
  774. for (var i = 1; i < layering.length - 1; ++i) {
  775. prevLayer = layering[i];
  776. currLayer = layering[i+1];
  777. var k0 = 0; // Position of the last inner segment in the previous layer
  778. var l = 0; // Current position in the current layer (for iteration up to `l1`)
  779. // Scan current layer for next node that is incident to an inner segement
  780. // between layering[i+1] and layering[i].
  781. for (var l1 = 0; l1 < currLayer.length; ++l1) {
  782. var u = currLayer[l1]; // Next inner segment in the current layer or
  783. // last node in the current layer
  784. pos[u] = l1;
  785. var k1 = undefined; // Position of the next inner segment in the previous layer or
  786. // the position of the last element in the previous layer
  787. if (g.node(u).dummy) {
  788. var uPred = g.predecessors(u)[0];
  789. if (g.node(uPred).dummy)
  790. k1 = pos[uPred];
  791. }
  792. if (k1 === undefined && l1 === currLayer.length - 1)
  793. k1 = prevLayer.length - 1;
  794. if (k1 !== undefined) {
  795. for (; l <= l1; ++l) {
  796. g.predecessors(currLayer[l]).forEach(function(v) {
  797. var k = pos[v];
  798. if (k < k0 || k > k1)
  799. conflicts[undirEdgeId(currLayer[l], v)] = true;
  800. });
  801. }
  802. k0 = k1;
  803. }
  804. }
  805. }
  806. return conflicts;
  807. }
  808. function verticalAlignment(g, layering, conflicts, relationship) {
  809. var pos = {}, // Position for a node in its layer
  810. root = {}, // Root of the block that the node participates in
  811. align = {}; // Points to the next node in the block or, if the last
  812. // element in the block, points to the first block's root
  813. layering.forEach(function(layer) {
  814. layer.forEach(function(u, i) {
  815. root[u] = u;
  816. align[u] = u;
  817. pos[u] = i;
  818. });
  819. });
  820. layering.forEach(function(layer) {
  821. var prevIdx = -1;
  822. layer.forEach(function(v) {
  823. var related = g[relationship](v), // Adjacent nodes from the previous layer
  824. m; // The mid point in the related array
  825. if (related.length > 0) {
  826. related.sort(function(x, y) { return pos[x] - pos[y]; });
  827. mid = (related.length - 1) / 2;
  828. related.slice(Math.floor(mid), Math.ceil(mid) + 1).forEach(function(u) {
  829. if (align[v] === v) {
  830. if (!conflicts[undirEdgeId(u, v)] && prevIdx < pos[u]) {
  831. align[u] = v;
  832. align[v] = root[v] = root[u];
  833. prevIdx = pos[u];
  834. }
  835. }
  836. });
  837. }
  838. });
  839. });
  840. return { pos: pos, root: root, align: align };
  841. }
  842. /*
  843. * Determines how much spacing u needs from its origin (center) to satisfy
  844. * width and node separation.
  845. */
  846. function deltaX(g, u) {
  847. var sep = g.node(u).dummy ? config.edgeSep : config.nodeSep;
  848. return width(g, u) / 2 + sep / 2;
  849. }
  850. // This function deviates from the standard BK algorithm in two ways. First
  851. // it takes into account the size of the nodes. Second it includes a fix to
  852. // the original algorithm that is described in Carstens, "Node and Label
  853. // Placement in a Layered Layout Algorithm".
  854. function horizontalCompaction(g, layering, pos, root, align) {
  855. var sink = {}, // Mapping of node id -> sink node id for class
  856. shift = {}, // Mapping of sink node id -> x delta
  857. pred = {}, // Mapping of node id -> predecessor node (or null)
  858. xs = {}; // Calculated X positions
  859. layering.forEach(function(layer) {
  860. layer.forEach(function(u, i) {
  861. sink[u] = u;
  862. if (i > 0)
  863. pred[u] = layer[i - 1];
  864. });
  865. });
  866. function placeBlock(v) {
  867. if (!(v in xs)) {
  868. xs[v] = 0;
  869. var w = v;
  870. do {
  871. if (pos[w] > 0) {
  872. var u = root[pred[w]];
  873. placeBlock(u);
  874. if (sink[v] === v) {
  875. sink[v] = sink[u];
  876. }
  877. var delta = deltaX(g, pred[w]) + deltaX(g, w);
  878. if (sink[v] !== sink[u]) {
  879. shift[sink[u]] = Math.min(shift[sink[u]] || Number.POSITIVE_INFINITY, xs[v] - xs[u] - delta);
  880. } else {
  881. xs[v] = Math.max(xs[v], xs[u] + delta);
  882. }
  883. }
  884. w = align[w];
  885. } while (w !== v);
  886. }
  887. }
  888. // Root coordinates relative to sink
  889. values(root).forEach(function(v) {
  890. placeBlock(v);
  891. });
  892. // Absolute coordinates
  893. layering.forEach(function(layer) {
  894. layer.forEach(function(v) {
  895. xs[v] = xs[root[v]];
  896. var xDelta = shift[sink[v]];
  897. if (root[v] === v && xDelta < Number.POSITIVE_INFINITY)
  898. xs[v] += xDelta;
  899. });
  900. });
  901. return xs;
  902. }
  903. function findMinCoord(g, layering, xs) {
  904. return min(layering.map(function(layer) {
  905. var u = layer[0];
  906. return xs[u] - width(g, u) / 2;
  907. }));
  908. }
  909. function findMaxCoord(g, layering, xs) {
  910. return max(layering.map(function(layer) {
  911. var u = layer[layer.length - 1];
  912. return xs[u] - width(g, u) / 2;
  913. }));
  914. }
  915. function balance(g, layering, xss) {
  916. var min = {}, // Min coordinate for the alignment
  917. max = {}, // Max coordinate for the alginment
  918. smallestAlignment,
  919. shift = {}; // Amount to shift a given alignment
  920. var smallest = Number.POSITIVE_INFINITY;
  921. for (var alignment in xss) {
  922. var xs = xss[alignment];
  923. min[alignment] = findMinCoord(g, layering, xs);
  924. max[alignment] = findMaxCoord(g, layering, xs);
  925. var w = max[alignment] - min[alignment];
  926. if (w < smallest) {
  927. smallest = w;
  928. smallestAlignment = alignment;
  929. }
  930. }
  931. // Determine how much to adjust positioning for each alignment
  932. ["up", "down"].forEach(function(vertDir) {
  933. ["left", "right"].forEach(function(horizDir) {
  934. var alignment = vertDir + "-" + horizDir;
  935. shift[alignment] = horizDir === "left"
  936. ? min[smallestAlignment] - min[alignment]
  937. : max[smallestAlignment] - max[alignment];
  938. });
  939. });
  940. // Find average of medians for xss array
  941. g.eachNode(function(v) {
  942. var xs = [];
  943. for (alignment in xss)
  944. xs.push(xss[alignment][v] + shift[alignment]);
  945. xs.sort(function(x, y) { return x - y; });
  946. x(g, v, (xs[1] + xs[2]) / 2);
  947. });
  948. }
  949. function flipHorizontally(layering, xs) {
  950. var maxCenter = max(values(xs));
  951. Object.keys(xs).forEach(function(u) {
  952. xs[u] = maxCenter - xs[u];
  953. });
  954. }
  955. function reverseInnerOrder(layering) {
  956. layering.forEach(function(layer) {
  957. layer.reverse();
  958. });
  959. }
  960. function width(g, u) {
  961. switch (config.rankDir) {
  962. case "LR": return g.node(u).height;
  963. default: return g.node(u).width;
  964. }
  965. }
  966. function offsetWidth(g, u) {
  967. //console.log(g.node(u));
  968. switch (config.rankDir) {
  969. case "LR": return g.node(u).offsetheight;
  970. default: return g.node(u).offsetwidth;
  971. }
  972. }
  973. function height(g, u) {
  974. switch(config.rankDir) {
  975. case "LR": return g.node(u).width;
  976. default: return g.node(u).height;
  977. }
  978. }
  979. function x(g, u, x) {
  980. switch (config.rankDir) {
  981. case "LR":
  982. if (arguments.length < 3) {
  983. return g.node(u).y;
  984. } else {
  985. g.node(u).y = x;
  986. }
  987. break;
  988. default:
  989. if (arguments.length < 3) {
  990. return g.node(u).x;
  991. } else {
  992. g.node(u).x = x;
  993. }
  994. }
  995. }
  996. function y(g, u, y) {
  997. switch (config.rankDir) {
  998. case "LR":
  999. if (arguments.length < 3) {
  1000. return g.node(u).x;
  1001. } else {
  1002. g.node(u).x = y;
  1003. }
  1004. break;
  1005. default:
  1006. if (arguments.length < 3) {
  1007. return g.node(u).y;
  1008. } else {
  1009. g.node(u).y = y;
  1010. }
  1011. }
  1012. }
  1013. }
  1014. dagre.util = {};
  1015. /*
  1016. * Copies attributes from `src` to `dst`. If an attribute name is in both
  1017. * `src` and `dst` then the attribute value from `src` takes precedence.
  1018. */
  1019. function mergeAttributes(src, dst) {
  1020. Object.keys(src).forEach(function(k) { dst[k] = src[k]; });
  1021. }
  1022. function min(values) {
  1023. return Math.min.apply(null, values);
  1024. }
  1025. function max(values) {
  1026. return Math.max.apply(null, values);
  1027. }
  1028. function concat(arrays) {
  1029. return Array.prototype.concat.apply([], arrays);
  1030. }
  1031. var keys = dagre.util.keys = Object.keys;
  1032. /*
  1033. * Returns an array of all values in the given object.
  1034. */
  1035. function values(obj) {
  1036. return Object.keys(obj).map(function(k) { return obj[k]; });
  1037. }
  1038. function union(arrays) {
  1039. var obj = {};
  1040. for (var i = 0; i < arrays.length; ++i) {
  1041. var a = arrays[i];
  1042. for (var j = 0; j < a.length; ++j) {
  1043. var v = a[j];
  1044. obj[v] = v;
  1045. }
  1046. }
  1047. var results = [];
  1048. for (var k in obj) {
  1049. results.push(obj[k]);
  1050. }
  1051. return results;
  1052. }
  1053. /*
  1054. * Returns all components in the graph using undirected navigation.
  1055. */
  1056. var components = dagre.util.components = function(g) {
  1057. var results = [];
  1058. var visited = {};
  1059. function dfs(u, component) {
  1060. if (!(u in visited)) {
  1061. visited[u] = true;
  1062. component.push(u);
  1063. g.neighbors(u).forEach(function(v) {
  1064. dfs(v, component);
  1065. });
  1066. }
  1067. };
  1068. g.eachNode(function(u) {
  1069. var component = [];
  1070. dfs(u, component);
  1071. if (component.length > 0) {
  1072. results.push(component);
  1073. }
  1074. });
  1075. return results;
  1076. };
  1077. /*
  1078. * This algorithm uses undirected traversal to find a miminum spanning tree
  1079. * using the supplied weight function. The algorithm is described in
  1080. * Cormen, et al., "Introduction to Algorithms". The returned structure
  1081. * is an array of node id to an array of adjacent nodes.
  1082. */
  1083. var prim = dagre.util.prim = function(g, weight) {
  1084. var result = {};
  1085. var parent = {};
  1086. var q = priorityQueue();
  1087. if (g.nodes().length === 0) {
  1088. return result;
  1089. }
  1090. g.eachNode(function(u) {
  1091. q.add(u, Number.POSITIVE_INFINITY);
  1092. result[u] = [];
  1093. });
  1094. // Start from arbitrary node
  1095. q.decrease(g.nodes()[0], 0);
  1096. var u;
  1097. var init = false;
  1098. while (q.size() > 0) {
  1099. u = q.removeMin();
  1100. if (u in parent) {
  1101. result[u].push(parent[u]);
  1102. result[parent[u]].push(u);
  1103. } else if (init) {
  1104. throw new Error("Input graph is not connected:\n" + g.toString());
  1105. } else {
  1106. init = true;
  1107. }
  1108. g.neighbors(u).forEach(function(v) {
  1109. var pri = q.priority(v);
  1110. if (pri !== undefined) {
  1111. var edgeWeight = weight(u, v);
  1112. if (edgeWeight < pri) {
  1113. parent[v] = u;
  1114. q.decrease(v, edgeWeight);
  1115. }
  1116. }
  1117. });
  1118. }
  1119. return result;
  1120. };
  1121. var intersectRect = dagre.util.intersectRect = function(rect, point) {
  1122. var x = rect.x;
  1123. var y = rect.y;
  1124. // For now we only support rectangles
  1125. // Rectangle intersection algorithm from:
  1126. // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes
  1127. var dx = point.x - x;
  1128. var dy = point.y - y;
  1129. var w = rect.width / 2;
  1130. var h = rect.height / 2;
  1131. var sx, sy;
  1132. if (Math.abs(dy) * w > Math.abs(dx) * h) {
  1133. // Intersection is top or bottom of rect.
  1134. if (dy < 0) {
  1135. h = -h;
  1136. }
  1137. sx = dy === 0 ? 0 : h * dx / dy;
  1138. sy = h;
  1139. } else {
  1140. // Intersection is left or right of rect.
  1141. if (dx < 0) {
  1142. w = -w;
  1143. }
  1144. sx = w;
  1145. sy = dx === 0 ? 0 : w * dy / dx;
  1146. }
  1147. return {x: x + sx, y: y + sy};
  1148. }
  1149. var pointStr = dagre.util.pointStr = function(point) {
  1150. return point.x + "," + point.y;
  1151. }
  1152. var createTimer = function() {
  1153. var self = {},
  1154. enabled = false;
  1155. self.enabled = function(x) {
  1156. if (!arguments.length) return enabled;
  1157. enabled = x;
  1158. return self;
  1159. };
  1160. self.wrap = function(name, func) {
  1161. return function() {
  1162. var start = enabled ? new Date().getTime() : null;
  1163. try {
  1164. return func.apply(null, arguments);
  1165. } finally {
  1166. if (start) console.log(name + " time: " + (new Date().getTime() - start) + "ms");
  1167. }
  1168. }
  1169. };
  1170. return self;
  1171. }
  1172. function propertyAccessor(self, config, field, setHook) {
  1173. return function(x) {
  1174. if (!arguments.length) return config[field];
  1175. config[field] = x;
  1176. if (setHook) setHook(x);
  1177. return self;
  1178. };
  1179. }
  1180. function priorityQueue() {
  1181. var _arr = [];
  1182. var _keyIndices = {};
  1183. function _heapify(i) {
  1184. var arr = _arr;
  1185. var l = 2 * i,
  1186. r = l + 1,
  1187. largest = i;
  1188. if (l < arr.length) {
  1189. largest = arr[l].pri < arr[largest].pri ? l : largest;
  1190. if (r < arr.length) {
  1191. largest = arr[r].pri < arr[largest].pri ? r : largest;
  1192. }
  1193. if (largest !== i) {
  1194. _swap(i, largest);
  1195. _heapify(largest);
  1196. }
  1197. }
  1198. }
  1199. function _decrease(index) {
  1200. var arr = _arr;
  1201. var pri = arr[index].pri;
  1202. var parent;
  1203. while (index > 0) {
  1204. parent = index >> 1;
  1205. if (arr[parent].pri < pri) {
  1206. break;
  1207. }
  1208. _swap(index, parent);
  1209. index = parent;
  1210. }
  1211. }
  1212. function _swap(i, j) {
  1213. var arr = _arr;
  1214. var keyIndices = _keyIndices;
  1215. var tmp = arr[i];
  1216. arr[i] = arr[j];
  1217. arr[j] = tmp;
  1218. keyIndices[arr[i].key] = i;
  1219. keyIndices[arr[j].key] = j;
  1220. }
  1221. function size() { return _arr.length; }
  1222. function keys() { return Object.keys(_keyIndices); }
  1223. function has(key) { return key in _keyIndices; }
  1224. function priority(key) {
  1225. var index = _keyIndices[key];
  1226. if (index !== undefined) {
  1227. return _arr[index].pri;
  1228. }
  1229. }
  1230. function add(key, pri) {
  1231. if (!(key in _keyIndices)) {
  1232. var entry = {key: key, pri: pri};
  1233. var index = _arr.length;
  1234. _keyIndices[key] = index;
  1235. _arr.push(entry);
  1236. _decrease(index);
  1237. return true;
  1238. }
  1239. return false;
  1240. }
  1241. function min() {
  1242. if (size() > 0) {
  1243. return _arr[0].key;
  1244. }
  1245. }
  1246. function removeMin() {
  1247. _swap(0, _arr.length - 1);
  1248. var min = _arr.pop();
  1249. delete _keyIndices[min.key];
  1250. _heapify(0);
  1251. return min.key;
  1252. }
  1253. function decrease(key, pri) {
  1254. var index = _keyIndices[key];
  1255. if (pri > _arr[index].pri) {
  1256. throw new Error("New priority is greater than current priority. " +
  1257. "Key: " + key + " Old: " + _arr[index].pri + " New: " + pri);
  1258. }
  1259. _arr[index].pri = pri;
  1260. _decrease(index);
  1261. }
  1262. return {
  1263. size: size,
  1264. keys: keys,
  1265. has: has,
  1266. priority: priority,
  1267. add: add,
  1268. min: min,
  1269. removeMin: removeMin,
  1270. decrease: decrease
  1271. };
  1272. }
  1273. dagre.dot = {};
  1274. dagre.dot.toGraph = function(str) {
  1275. var parseTree = dot_parser.parse(str);
  1276. var g = dagre.graph();
  1277. var undir = parseTree.type === "graph";
  1278. function createNode(id, attrs) {
  1279. if (!(g.hasNode(id))) {
  1280. g.addNode(id, { id: id, label: id });
  1281. }
  1282. if (attrs) {
  1283. mergeAttributes(attrs, g.node(id));
  1284. }
  1285. }
  1286. var edgeCount = {};
  1287. function createEdge(source, target, attrs) {
  1288. var edgeKey = source + "-" + target;
  1289. var count = edgeCount[edgeKey];
  1290. if (!count) {
  1291. count = edgeCount[edgeKey] = 0;
  1292. }
  1293. edgeCount[edgeKey]++;
  1294. var id = attrs.id || edgeKey + "-" + count;
  1295. var edge = {};
  1296. mergeAttributes(attrs, edge);
  1297. mergeAttributes({ id: id }, edge);
  1298. g.addEdge(id, source, target, edge);
  1299. }
  1300. function handleStmt(stmt) {
  1301. switch (stmt.type) {
  1302. case "node":
  1303. createNode(stmt.id, stmt.attrs);
  1304. break;
  1305. case "edge":
  1306. var prev;
  1307. stmt.elems.forEach(function(elem) {
  1308. handleStmt(elem);
  1309. switch(elem.type) {
  1310. case "node":
  1311. var curr = elem.id;
  1312. if (prev) {
  1313. createEdge(prev, curr, stmt.attrs);
  1314. if (undir) {
  1315. createEdge(curr, prev, stmt.attrs);
  1316. }
  1317. }
  1318. prev = curr;
  1319. break;
  1320. default:
  1321. // We don't currently support subgraphs incident on an edge
  1322. throw new Error("Unsupported type incident on edge: " + elem.type);
  1323. }
  1324. });
  1325. break;
  1326. case "attr":
  1327. // Ignore for now
  1328. break;
  1329. default:
  1330. throw new Error("Unsupported statement type: " + stmt.type);
  1331. }
  1332. }
  1333. if (parseTree.stmts) {
  1334. parseTree.stmts.forEach(function(stmt) {
  1335. handleStmt(stmt);
  1336. });
  1337. }
  1338. return g;
  1339. };
  1340. dagre.dot.toObjects = function(str) {
  1341. var g = dagre.dot.toGraph(str);
  1342. var nodes = g.nodes().map(function(u) { return g.node(u); });
  1343. var edges = g.edges().map(function(e) {
  1344. var edge = g.edge(e);
  1345. edge.source = g.node(g.source(e));
  1346. edge.target = g.node(g.target(e));
  1347. return edge;
  1348. });
  1349. return { nodes: nodes, edges: edges };
  1350. };
  1351. dot_parser = (function(){
  1352. /*
  1353. * Generated by PEG.js 0.7.0.
  1354. *
  1355. * http://pegjs.majda.cz/
  1356. */
  1357. function quote(s) {
  1358. /*
  1359. * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a
  1360. * string literal except for the closing quote character, backslash,
  1361. * carriage return, line separator, paragraph separator, and line feed.
  1362. * Any character may appear in the form of an escape sequence.
  1363. *
  1364. * For portability, we also escape escape all control and non-ASCII
  1365. * characters. Note that "\0" and "\v" escape sequences are not used
  1366. * because JSHint does not like the first and IE the second.
  1367. */
  1368. return '"' + s
  1369. .replace(/\\/g, '\\\\') // backslash
  1370. .replace(/"/g, '\\"') // closing quote character
  1371. .replace(/\x08/g, '\\b') // backspace
  1372. .replace(/\t/g, '\\t') // horizontal tab
  1373. .replace(/\n/g, '\\n') // line feed
  1374. .replace(/\f/g, '\\f') // form feed
  1375. .replace(/\r/g, '\\r') // carriage return
  1376. .replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape)
  1377. + '"';
  1378. }
  1379. var result = {
  1380. /*
  1381. * Parses the input with a generated parser. If the parsing is successfull,
  1382. * returns a value explicitly or implicitly specified by the grammar from
  1383. * which the parser was generated (see |PEG.buildParser|). If the parsing is
  1384. * unsuccessful, throws |PEG.parser.SyntaxError| describing the error.
  1385. */
  1386. parse: function(input, startRule) {
  1387. var parseFunctions = {
  1388. "start": parse_start,
  1389. "stmtList": parse_stmtList,
  1390. "stmt": parse_stmt,
  1391. "attrStmt": parse_attrStmt,
  1392. "inlineAttrStmt": parse_inlineAttrStmt,
  1393. "nodeStmt": parse_nodeStmt,
  1394. "edgeStmt": parse_edgeStmt,
  1395. "subgraphStmt": parse_subgraphStmt,
  1396. "attrList": parse_attrList,
  1397. "attrListBlock": parse_attrListBlock,
  1398. "aList": parse_aList,
  1399. "edgeRHS": parse_edgeRHS,
  1400. "idDef": parse_idDef,
  1401. "nodeIdOrSubgraph": parse_nodeIdOrSubgraph,
  1402. "nodeId": parse_nodeId,
  1403. "port": parse_port,
  1404. "compassPt": parse_compassPt,
  1405. "id": parse_id,
  1406. "node": parse_node,
  1407. "edge": parse_edge,
  1408. "graph": parse_graph,
  1409. "digraph": parse_digraph,
  1410. "subgraph": parse_subgraph,
  1411. "strict": parse_strict,
  1412. "graphType": parse_graphType,
  1413. "whitespace": parse_whitespace,
  1414. "comment": parse_comment,
  1415. "_": parse__
  1416. };
  1417. if (startRule !== undefined) {
  1418. if (parseFunctions[startRule] === undefined) {
  1419. throw new Error("Invalid rule name: " + quote(startRule) + ".");
  1420. }
  1421. } else {
  1422. startRule = "start";
  1423. }
  1424. var pos = 0;
  1425. var reportFailures = 0;
  1426. var rightmostFailuresPos = 0;
  1427. var rightmostFailuresExpected = [];
  1428. function padLeft(input, padding, length) {
  1429. var result = input;
  1430. var padLength = length - input.length;
  1431. for (var i = 0; i < padLength; i++) {
  1432. result = padding + result;
  1433. }
  1434. return result;
  1435. }
  1436. function escape(ch) {
  1437. var charCode = ch.charCodeAt(0);
  1438. var escapeChar;
  1439. var length;
  1440. if (charCode <= 0xFF) {
  1441. escapeChar = 'x';
  1442. length = 2;
  1443. } else {
  1444. escapeChar = 'u';
  1445. length = 4;
  1446. }
  1447. return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);
  1448. }
  1449. function matchFailed(failure) {
  1450. if (pos < rightmostFailuresPos) {
  1451. return;
  1452. }
  1453. if (pos > rightmostFailuresPos) {
  1454. rightmostFailuresPos = pos;
  1455. rightmostFailuresExpected = [];
  1456. }
  1457. rightmostFailuresExpected.push(failure);
  1458. }
  1459. function parse_start() {
  1460. var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12;
  1461. var pos0, pos1, pos2;
  1462. pos0 = pos;
  1463. pos1 = pos;
  1464. result0 = [];
  1465. result1 = parse__();
  1466. while (result1 !== null) {
  1467. result0.push(result1);
  1468. result1 = parse__();
  1469. }
  1470. if (result0 !== null) {
  1471. pos2 = pos;
  1472. result1 = parse_strict();
  1473. if (result1 !== null) {
  1474. result2 = parse__();
  1475. if (result2 !== null) {
  1476. result1 = [result1, result2];
  1477. } else {
  1478. result1 = null;
  1479. pos = pos2;
  1480. }
  1481. } else {
  1482. result1 = null;
  1483. pos = pos2;
  1484. }
  1485. result1 = result1 !== null ? result1 : "";
  1486. if (result1 !== null) {
  1487. result2 = parse_graphType();
  1488. if (result2 !== null) {
  1489. result3 = [];
  1490. result4 = parse__();
  1491. while (result4 !== null) {
  1492. result3.push(result4);
  1493. result4 = parse__();
  1494. }
  1495. if (result3 !== null) {
  1496. result4 = parse_id();
  1497. result4 = result4 !== null ? result4 : "";
  1498. if (result4 !== null) {
  1499. result5 = [];
  1500. result6 = parse__();
  1501. while (result6 !== null) {
  1502. result5.push(result6);
  1503. result6 = parse__();
  1504. }
  1505. if (result5 !== null) {
  1506. if (input.charCodeAt(pos) === 123) {
  1507. result6 = "{";
  1508. pos++;
  1509. } else {
  1510. result6 = null;
  1511. if (reportFailures === 0) {
  1512. matchFailed("\"{\"");
  1513. }
  1514. }
  1515. if (result6 !== null) {
  1516. result7 = [];
  1517. result8 = parse__();
  1518. while (result8 !== null) {
  1519. result7.push(result8);
  1520. result8 = parse__();
  1521. }
  1522. if (result7 !== null) {
  1523. result8 = parse_stmtList();
  1524. result8 = result8 !== null ? result8 : "";
  1525. if (result8 !== null) {
  1526. result9 = [];
  1527. result10 = parse__();
  1528. while (result10 !== null) {
  1529. result9.push(result10);
  1530. result10 = parse__();
  1531. }
  1532. if (result9 !== null) {
  1533. if (input.charCodeAt(pos) === 125) {
  1534. result10 = "}";
  1535. pos++;
  1536. } else {
  1537. result10 = null;
  1538. if (reportFailures === 0) {
  1539. matchFailed("\"}\"");
  1540. }
  1541. }
  1542. if (result10 !== null) {
  1543. result11 = [];
  1544. result12 = parse__();
  1545. while (result12 !== null) {
  1546. result11.push(result12);
  1547. result12 = parse__();
  1548. }
  1549. if (result11 !== null) {
  1550. result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11];
  1551. } else {
  1552. result0 = null;
  1553. pos = pos1;
  1554. }
  1555. } else {
  1556. result0 = null;
  1557. pos = pos1;
  1558. }
  1559. } else {
  1560. result0 = null;
  1561. pos = pos1;
  1562. }
  1563. } else {
  1564. result0 = null;
  1565. pos = pos1;
  1566. }
  1567. } else {
  1568. result0 = null;
  1569. pos = pos1;
  1570. }
  1571. } else {
  1572. result0 = null;
  1573. pos = pos1;
  1574. }
  1575. } else {
  1576. result0 = null;
  1577. pos = pos1;
  1578. }
  1579. } else {
  1580. result0 = null;
  1581. pos = pos1;
  1582. }
  1583. } else {
  1584. result0 = null;
  1585. pos = pos1;
  1586. }
  1587. } else {
  1588. result0 = null;
  1589. pos = pos1;
  1590. }
  1591. } else {
  1592. result0 = null;
  1593. pos = pos1;
  1594. }
  1595. } else {
  1596. result0 = null;
  1597. pos = pos1;
  1598. }
  1599. if (result0 !== null) {
  1600. result0 = (function(offset, type, id, stmts) {
  1601. return {type: type, id: id, stmts: stmts};
  1602. })(pos0, result0[2], result0[4], result0[8]);
  1603. }
  1604. if (result0 === null) {
  1605. pos = pos0;
  1606. }
  1607. return result0;
  1608. }
  1609. function parse_stmtList() {
  1610. var result0, result1, result2, result3, result4, result5, result6, result7;
  1611. var pos0, pos1, pos2;
  1612. pos0 = pos;
  1613. pos1 = pos;
  1614. result0 = parse_stmt();
  1615. if (result0 !== null) {
  1616. result1 = [];
  1617. result2 = parse__();
  1618. while (result2 !== null) {
  1619. result1.push(result2);
  1620. result2 = parse__();
  1621. }
  1622. if (result1 !== null) {
  1623. if (input.charCodeAt(pos) === 59) {
  1624. result2 = ";";
  1625. pos++;
  1626. } else {
  1627. result2 = null;
  1628. if (reportFailures === 0) {
  1629. matchFailed("\";\"");
  1630. }
  1631. }
  1632. result2 = result2 !== null ? result2 : "";
  1633. if (result2 !== null) {
  1634. result3 = [];
  1635. pos2 = pos;
  1636. result4 = [];
  1637. result5 = parse__();
  1638. while (result5 !== null) {
  1639. result4.push(result5);
  1640. result5 = parse__();
  1641. }
  1642. if (result4 !== null) {
  1643. result5 = parse_stmt();
  1644. if (result5 !== null) {
  1645. result6 = [];
  1646. result7 = parse__();
  1647. while (result7 !== null) {
  1648. result6.push(result7);
  1649. result7 = parse__();
  1650. }
  1651. if (result6 !== null) {
  1652. if (input.charCodeAt(pos) === 59) {
  1653. result7 = ";";
  1654. pos++;
  1655. } else {
  1656. result7 = null;
  1657. if (reportFailures === 0) {
  1658. matchFailed("\";\"");
  1659. }
  1660. }
  1661. result7 = result7 !== null ? result7 : "";
  1662. if (result7 !== null) {
  1663. result4 = [result4, result5, result6, result7];
  1664. } else {
  1665. result4 = null;
  1666. pos = pos2;
  1667. }
  1668. } else {
  1669. result4 = null;
  1670. pos = pos2;
  1671. }
  1672. } else {
  1673. result4 = null;
  1674. pos = pos2;
  1675. }
  1676. } else {
  1677. result4 = null;
  1678. pos = pos2;
  1679. }
  1680. while (result4 !== null) {
  1681. result3.push(result4);
  1682. pos2 = pos;
  1683. result4 = [];
  1684. result5 = parse__();
  1685. while (result5 !== null) {
  1686. result4.push(result5);
  1687. result5 = parse__();
  1688. }
  1689. if (result4 !== null) {
  1690. result5 = parse_stmt();
  1691. if (result5 !== null) {
  1692. result6 = [];
  1693. result7 = parse__();
  1694. while (result7 !== null) {
  1695. result6.push(result7);
  1696. result7 = parse__();
  1697. }
  1698. if (result6 !== null) {
  1699. if (input.charCodeAt(pos) === 59) {
  1700. result7 = ";";
  1701. pos++;
  1702. } else {
  1703. result7 = null;
  1704. if (reportFailures === 0) {
  1705. matchFailed("\";\"");
  1706. }
  1707. }
  1708. result7 = result7 !== null ? result7 : "";
  1709. if (result7 !== null) {
  1710. result4 = [result4, result5, result6, result7];
  1711. } else {
  1712. result4 = null;
  1713. pos = pos2;
  1714. }
  1715. } else {
  1716. result4 = null;
  1717. pos = pos2;
  1718. }
  1719. } else {
  1720. result4 = null;
  1721. pos = pos2;
  1722. }
  1723. } else {
  1724. result4 = null;
  1725. pos = pos2;
  1726. }
  1727. }
  1728. if (result3 !== null) {
  1729. result0 = [result0, result1, result2, result3];
  1730. } else {
  1731. result0 = null;
  1732. pos = pos1;
  1733. }
  1734. } else {
  1735. result0 = null;
  1736. pos = pos1;
  1737. }
  1738. } else {
  1739. result0 = null;
  1740. pos = pos1;
  1741. }
  1742. } else {
  1743. result0 = null;
  1744. pos = pos1;
  1745. }
  1746. if (result0 !== null) {
  1747. result0 = (function(offset, first, rest) {
  1748. var result = [first];
  1749. for (var i = 0; i < rest.length; ++i) {
  1750. result.push(rest[i][1]);
  1751. }
  1752. return result;
  1753. })(pos0, result0[0], result0[3]);
  1754. }
  1755. if (result0 === null) {
  1756. pos = pos0;
  1757. }
  1758. return result0;
  1759. }
  1760. function parse_stmt() {
  1761. var result0;
  1762. result0 = parse_attrStmt();
  1763. if (result0 === null) {
  1764. result0 = parse_subgraphStmt();
  1765. if (result0 === null) {
  1766. result0 = parse_inlineAttrStmt();
  1767. if (result0 === null) {
  1768. result0 = parse_edgeStmt();
  1769. if (result0 === null) {
  1770. result0 = parse_nodeStmt();
  1771. }
  1772. }
  1773. }
  1774. }
  1775. return result0;
  1776. }
  1777. function parse_attrStmt() {
  1778. var result0, result1, result2;
  1779. var pos0, pos1;
  1780. pos0 = pos;
  1781. pos1 = pos;
  1782. result0 = parse_graph();
  1783. if (result0 === null) {
  1784. result0 = parse_node();
  1785. if (result0 === null) {
  1786. result0 = parse_edge();
  1787. }
  1788. }
  1789. if (result0 !== null) {
  1790. result1 = [];
  1791. result2 = parse__();
  1792. while (result2 !== null) {
  1793. result1.push(result2);
  1794. result2 = parse__();
  1795. }
  1796. if (result1 !== null) {
  1797. result2 = parse_attrList();
  1798. if (result2 !== null) {
  1799. result0 = [result0, result1, result2];
  1800. } else {
  1801. result0 = null;
  1802. pos = pos1;
  1803. }
  1804. } else {
  1805. result0 = null;
  1806. pos = pos1;
  1807. }
  1808. } else {
  1809. result0 = null;
  1810. pos = pos1;
  1811. }
  1812. if (result0 !== null) {
  1813. result0 = (function(offset, type, attrs) {
  1814. return { type: "attr", attrType: type, attrs: attrs || {}};
  1815. })(pos0, result0[0], result0[2]);
  1816. }
  1817. if (result0 === null) {
  1818. pos = pos0;
  1819. }
  1820. return result0;
  1821. }
  1822. function parse_inlineAttrStmt() {
  1823. var result0, result1, result2, result3, result4;
  1824. var pos0, pos1;
  1825. pos0 = pos;
  1826. pos1 = pos;
  1827. result0 = parse_id();
  1828. if (result0 !== null) {
  1829. result1 = [];
  1830. result2 = parse__();
  1831. while (result2 !== null) {
  1832. result1.push(result2);
  1833. result2 = parse__();
  1834. }
  1835. if (result1 !== null) {
  1836. if (input.charCodeAt(pos) === 61) {
  1837. result2 = "=";
  1838. pos++;
  1839. } else {
  1840. result2 = null;
  1841. if (reportFailures === 0) {
  1842. matchFailed("\"=\"");
  1843. }
  1844. }
  1845. if (result2 !== null) {
  1846. result3 = [];
  1847. result4 = parse__();
  1848. while (result4 !== null) {
  1849. result3.push(result4);
  1850. result4 = parse__();
  1851. }
  1852. if (result3 !== null) {
  1853. result4 = parse_id();
  1854. if (result4 !== null) {
  1855. result0 = [result0, result1, result2, result3, result4];
  1856. } else {
  1857. result0 = null;
  1858. pos = pos1;
  1859. }
  1860. } else {
  1861. result0 = null;
  1862. pos = pos1;
  1863. }
  1864. } else {
  1865. result0 = null;
  1866. pos = pos1;
  1867. }
  1868. } else {
  1869. result0 = null;
  1870. pos = pos1;
  1871. }
  1872. } else {
  1873. result0 = null;
  1874. pos = pos1;
  1875. }
  1876. if (result0 !== null) {
  1877. result0 = (function(offset, k, v) {
  1878. var attrs = {};
  1879. attrs[k] = v;
  1880. return { type: "inlineAttr", attrs: attrs };
  1881. })(pos0, result0[0], result0[4]);
  1882. }
  1883. if (result0 === null) {
  1884. pos = pos0;
  1885. }
  1886. return result0;
  1887. }
  1888. function parse_nodeStmt() {
  1889. var result0, result1, result2;
  1890. var pos0, pos1;
  1891. pos0 = pos;
  1892. pos1 = pos;
  1893. result0 = parse_nodeId();
  1894. if (result0 !== null) {
  1895. result1 = [];
  1896. result2 = parse__();
  1897. while (result2 !== null) {
  1898. result1.push(result2);
  1899. result2 = parse__();
  1900. }
  1901. if (result1 !== null) {
  1902. result2 = parse_attrList();
  1903. result2 = result2 !== null ? result2 : "";
  1904. if (result2 !== null) {
  1905. result0 = [result0, result1, result2];
  1906. } else {
  1907. result0 = null;
  1908. pos = pos1;
  1909. }
  1910. } else {
  1911. result0 = null;
  1912. pos = pos1;
  1913. }
  1914. } else {
  1915. result0 = null;
  1916. pos = pos1;
  1917. }
  1918. if (result0 !== null) {
  1919. result0 = (function(offset, id, attrs) { return {type: "node", id: id, attrs: attrs || {}}; })(pos0, result0[0], result0[2]);
  1920. }
  1921. if (result0 === null) {
  1922. pos = pos0;
  1923. }
  1924. return result0;
  1925. }
  1926. function parse_edgeStmt() {
  1927. var result0, result1, result2, result3, result4;
  1928. var pos0, pos1;
  1929. pos0 = pos;
  1930. pos1 = pos;
  1931. result0 = parse_nodeIdOrSubgraph();
  1932. if (result0 !== null) {
  1933. result1 = [];
  1934. result2 = parse__();
  1935. while (result2 !== null) {
  1936. result1.push(result2);
  1937. result2 = parse__();
  1938. }
  1939. if (result1 !== null) {
  1940. result2 = parse_edgeRHS();
  1941. if (result2 !== null) {
  1942. result3 = [];
  1943. result4 = parse__();
  1944. while (result4 !== null) {
  1945. result3.push(result4);
  1946. result4 = parse__();
  1947. }
  1948. if (result3 !== null) {
  1949. result4 = parse_attrList();
  1950. result4 = result4 !== null ? result4 : "";
  1951. if (result4 !== null) {
  1952. result0 = [result0, result1, result2, result3, result4];
  1953. } else {
  1954. result0 = null;
  1955. pos = pos1;
  1956. }
  1957. } else {
  1958. result0 = null;
  1959. pos = pos1;
  1960. }
  1961. } else {
  1962. result0 = null;
  1963. pos = pos1;
  1964. }
  1965. } else {
  1966. result0 = null;
  1967. pos = pos1;
  1968. }
  1969. } else {
  1970. result0 = null;
  1971. pos = pos1;
  1972. }
  1973. if (result0 !== null) {
  1974. result0 = (function(offset, lhs, rhs, attrs) {
  1975. var elems = [lhs];
  1976. for (var i = 0; i < rhs.length; ++i) {
  1977. elems.push(rhs[i]);
  1978. }
  1979. return { type: "edge", elems: elems, attrs: attrs || {} };
  1980. })(pos0, result0[0], result0[2], result0[4]);
  1981. }
  1982. if (result0 === null) {
  1983. pos = pos0;
  1984. }
  1985. return result0;
  1986. }
  1987. function parse_subgraphStmt() {
  1988. var result0, result1, result2, result3, result4, result5;
  1989. var pos0, pos1, pos2, pos3;
  1990. pos0 = pos;
  1991. pos1 = pos;
  1992. pos2 = pos;
  1993. result0 = parse_subgraph();
  1994. if (result0 !== null) {
  1995. result1 = [];
  1996. result2 = parse__();
  1997. while (result2 !== null) {
  1998. result1.push(result2);
  1999. result2 = parse__();
  2000. }
  2001. if (result1 !== null) {
  2002. pos3 = pos;
  2003. result2 = parse_id();
  2004. if (result2 !== null) {
  2005. result3 = [];
  2006. result4 = parse__();
  2007. while (result4 !== null) {
  2008. result3.push(result4);
  2009. result4 = parse__();
  2010. }
  2011. if (result3 !== null) {
  2012. result2 = [result2, result3];
  2013. } else {
  2014. result2 = null;
  2015. pos = pos3;
  2016. }
  2017. } else {
  2018. result2 = null;
  2019. pos = pos3;
  2020. }
  2021. result2 = result2 !== null ? result2 : "";
  2022. if (result2 !== null) {
  2023. result0 = [result0, result1, result2];
  2024. } else {
  2025. result0 = null;
  2026. pos = pos2;
  2027. }
  2028. } else {
  2029. result0 = null;
  2030. pos = pos2;
  2031. }
  2032. } else {
  2033. result0 = null;
  2034. pos = pos2;
  2035. }
  2036. result0 = result0 !== null ? result0 : "";
  2037. if (result0 !== null) {
  2038. if (input.charCodeAt(pos) === 123) {
  2039. result1 = "{";
  2040. pos++;
  2041. } else {
  2042. result1 = null;
  2043. if (reportFailures === 0) {
  2044. matchFailed("\"{\"");
  2045. }
  2046. }
  2047. if (result1 !== null) {
  2048. result2 = [];
  2049. result3 = parse__();
  2050. while (result3 !== null) {
  2051. result2.push(result3);
  2052. result3 = parse__();
  2053. }
  2054. if (result2 !== null) {
  2055. result3 = parse_stmtList();
  2056. if (result3 !== null) {
  2057. result4 = [];
  2058. result5 = parse__();
  2059. while (result5 !== null) {
  2060. result4.push(result5);
  2061. result5 = parse__();
  2062. }
  2063. if (result4 !== null) {
  2064. if (input.charCodeAt(pos) === 125) {
  2065. result5 = "}";
  2066. pos++;
  2067. } else {
  2068. result5 = null;
  2069. if (reportFailures === 0) {
  2070. matchFailed("\"}\"");
  2071. }
  2072. }
  2073. if (result5 !== null) {
  2074. result0 = [result0, result1, result2, result3, result4, result5];
  2075. } else {
  2076. result0 = null;
  2077. pos = pos1;
  2078. }
  2079. } else {
  2080. result0 = null;
  2081. pos = pos1;
  2082. }
  2083. } else {
  2084. result0 = null;
  2085. pos = pos1;
  2086. }
  2087. } else {
  2088. result0 = null;
  2089. pos = pos1;
  2090. }
  2091. } else {
  2092. result0 = null;
  2093. pos = pos1;
  2094. }
  2095. } else {
  2096. result0 = null;
  2097. pos = pos1;
  2098. }
  2099. if (result0 !== null) {
  2100. result0 = (function(offset, id, stmts) {
  2101. id = id[2] || [];
  2102. return { type: "subgraph", id: id[0], stmts: stmts };
  2103. })(pos0, result0[0], result0[3]);
  2104. }
  2105. if (result0 === null) {
  2106. pos = pos0;
  2107. }
  2108. return result0;
  2109. }
  2110. function parse_attrList() {
  2111. var result0, result1, result2, result3;
  2112. var pos0, pos1, pos2;
  2113. pos0 = pos;
  2114. pos1 = pos;
  2115. result0 = parse_attrListBlock();
  2116. if (result0 !== null) {
  2117. result1 = [];
  2118. pos2 = pos;
  2119. result2 = [];
  2120. result3 = parse__();
  2121. while (result3 !== null) {
  2122. result2.push(result3);
  2123. result3 = parse__();
  2124. }
  2125. if (result2 !== null) {
  2126. result3 = parse_attrListBlock();
  2127. if (result3 !== null) {
  2128. result2 = [result2, result3];
  2129. } else {
  2130. result2 = null;
  2131. pos = pos2;
  2132. }
  2133. } else {
  2134. result2 = null;
  2135. pos = pos2;
  2136. }
  2137. while (result2 !== null) {
  2138. result1.push(result2);
  2139. pos2 = pos;
  2140. result2 = [];
  2141. result3 = parse__();
  2142. while (result3 !== null) {
  2143. result2.push(result3);
  2144. result3 = parse__();
  2145. }
  2146. if (result2 !== null) {
  2147. result3 = parse_attrListBlock();
  2148. if (result3 !== null) {
  2149. result2 = [result2, result3];
  2150. } else {
  2151. result2 = null;
  2152. pos = pos2;
  2153. }
  2154. } else {
  2155. result2 = null;
  2156. pos = pos2;
  2157. }
  2158. }
  2159. if (result1 !== null) {
  2160. result0 = [result0, result1];
  2161. } else {
  2162. result0 = null;
  2163. pos = pos1;
  2164. }
  2165. } else {
  2166. result0 = null;
  2167. pos = pos1;
  2168. }
  2169. if (result0 !== null) {
  2170. result0 = (function(offset, first, rest) {
  2171. var result = first;
  2172. for (var i = 0; i < rest.length; ++i) {
  2173. result = rightBiasedMerge(result, rest[i][1]);
  2174. }
  2175. return result;
  2176. })(pos0, result0[0], result0[1]);
  2177. }
  2178. if (result0 === null) {
  2179. pos = pos0;
  2180. }
  2181. return result0;
  2182. }
  2183. function parse_attrListBlock() {
  2184. var result0, result1, result2, result3, result4;
  2185. var pos0, pos1;
  2186. pos0 = pos;
  2187. pos1 = pos;
  2188. if (input.charCodeAt(pos) === 91) {
  2189. result0 = "[";
  2190. pos++;
  2191. } else {
  2192. result0 = null;
  2193. if (reportFailures === 0) {
  2194. matchFailed("\"[\"");
  2195. }
  2196. }
  2197. if (result0 !== null) {
  2198. result1 = [];
  2199. result2 = parse__();
  2200. while (result2 !== null) {
  2201. result1.push(result2);
  2202. result2 = parse__();
  2203. }
  2204. if (result1 !== null) {
  2205. result2 = parse_aList();
  2206. result2 = result2 !== null ? result2 : "";
  2207. if (result2 !== null) {
  2208. result3 = [];
  2209. result4 = parse__();
  2210. while (result4 !== null) {
  2211. result3.push(result4);
  2212. result4 = parse__();
  2213. }
  2214. if (result3 !== null) {
  2215. if (input.charCodeAt(pos) === 93) {
  2216. result4 = "]";
  2217. pos++;
  2218. } else {
  2219. result4 = null;
  2220. if (reportFailures === 0) {
  2221. matchFailed("\"]\"");
  2222. }
  2223. }
  2224. if (result4 !== null) {
  2225. result0 = [result0, result1, result2, result3, result4];
  2226. } else {
  2227. result0 = null;
  2228. pos = pos1;
  2229. }
  2230. } else {
  2231. result0 = null;
  2232. pos = pos1;
  2233. }
  2234. } else {
  2235. result0 = null;
  2236. pos = pos1;
  2237. }
  2238. } else {
  2239. result0 = null;
  2240. pos = pos1;
  2241. }
  2242. } else {
  2243. result0 = null;
  2244. pos = pos1;
  2245. }
  2246. if (result0 !== null) {
  2247. result0 = (function(offset, aList) { return aList; })(pos0, result0[2]);
  2248. }
  2249. if (result0 === null) {
  2250. pos = pos0;
  2251. }
  2252. return result0;
  2253. }
  2254. function parse_aList() {
  2255. var result0, result1, result2, result3, result4, result5;
  2256. var pos0, pos1, pos2;
  2257. pos0 = pos;
  2258. pos1 = pos;
  2259. result0 = parse_idDef();
  2260. if (result0 !== null) {
  2261. result1 = [];
  2262. pos2 = pos;
  2263. result2 = [];
  2264. result3 = parse__();
  2265. while (result3 !== null) {
  2266. result2.push(result3);
  2267. result3 = parse__();
  2268. }
  2269. if (result2 !== null) {
  2270. if (input.charCodeAt(pos) === 44) {
  2271. result3 = ",";
  2272. pos++;
  2273. } else {
  2274. result3 = null;
  2275. if (reportFailures === 0) {
  2276. matchFailed("\",\"");
  2277. }
  2278. }
  2279. result3 = result3 !== null ? result3 : "";
  2280. if (result3 !== null) {
  2281. result4 = [];
  2282. result5 = parse__();
  2283. while (result5 !== null) {
  2284. result4.push(result5);
  2285. result5 = parse__();
  2286. }
  2287. if (result4 !== null) {
  2288. result5 = parse_idDef();
  2289. if (result5 !== null) {
  2290. result2 = [result2, result3, result4, result5];
  2291. } else {
  2292. result2 = null;
  2293. pos = pos2;
  2294. }
  2295. } else {
  2296. result2 = null;
  2297. pos = pos2;
  2298. }
  2299. } else {
  2300. result2 = null;
  2301. pos = pos2;
  2302. }
  2303. } else {
  2304. result2 = null;
  2305. pos = pos2;
  2306. }
  2307. while (result2 !== null) {
  2308. result1.push(result2);
  2309. pos2 = pos;
  2310. result2 = [];
  2311. result3 = parse__();
  2312. while (result3 !== null) {
  2313. result2.push(result3);
  2314. result3 = parse__();
  2315. }
  2316. if (result2 !== null) {
  2317. if (input.charCodeAt(pos) === 44) {
  2318. result3 = ",";
  2319. pos++;
  2320. } else {
  2321. result3 = null;
  2322. if (reportFailures === 0) {
  2323. matchFailed("\",\"");
  2324. }
  2325. }
  2326. result3 = result3 !== null ? result3 : "";
  2327. if (result3 !== null) {
  2328. result4 = [];
  2329. result5 = parse__();
  2330. while (result5 !== null) {
  2331. result4.push(result5);
  2332. result5 = parse__();
  2333. }
  2334. if (result4 !== null) {
  2335. result5 = parse_idDef();
  2336. if (result5 !== null) {
  2337. result2 = [result2, result3, result4, result5];
  2338. } else {
  2339. result2 = null;
  2340. pos = pos2;
  2341. }
  2342. } else {
  2343. result2 = null;
  2344. pos = pos2;
  2345. }
  2346. } else {
  2347. result2 = null;
  2348. pos = pos2;
  2349. }
  2350. } else {
  2351. result2 = null;
  2352. pos = pos2;
  2353. }
  2354. }
  2355. if (result1 !== null) {
  2356. result0 = [result0, result1];
  2357. } else {
  2358. result0 = null;
  2359. pos = pos1;
  2360. }
  2361. } else {
  2362. result0 = null;
  2363. pos = pos1;
  2364. }
  2365. if (result0 !== null) {
  2366. result0 = (function(offset, first, rest) {
  2367. var result = first;
  2368. for (var i = 0; i < rest.length; ++i) {
  2369. result = rightBiasedMerge(result, rest[i][3]);
  2370. }
  2371. return result;
  2372. })(pos0, result0[0], result0[1]);
  2373. }
  2374. if (result0 === null) {
  2375. pos = pos0;
  2376. }
  2377. return result0;
  2378. }
  2379. function parse_edgeRHS() {
  2380. var result0, result1, result2, result3, result4;
  2381. var pos0, pos1, pos2;
  2382. pos0 = pos;
  2383. pos1 = pos;
  2384. pos2 = pos;
  2385. if (input.substr(pos, 2) === "--") {
  2386. result0 = "--";
  2387. pos += 2;
  2388. } else {
  2389. result0 = null;
  2390. if (reportFailures === 0) {
  2391. matchFailed("\"--\"");
  2392. }
  2393. }
  2394. if (result0 !== null) {
  2395. result1 = (function(offset) { return directed; })(pos) ? null : "";
  2396. if (result1 !== null) {
  2397. result0 = [result0, result1];
  2398. } else {
  2399. result0 = null;
  2400. pos = pos2;
  2401. }
  2402. } else {
  2403. result0 = null;
  2404. pos = pos2;
  2405. }
  2406. if (result0 === null) {
  2407. pos2 = pos;
  2408. if (input.substr(pos, 2) === "->") {
  2409. result0 = "->";
  2410. pos += 2;
  2411. } else {
  2412. result0 = null;
  2413. if (reportFailures === 0) {
  2414. matchFailed("\"->\"");
  2415. }
  2416. }
  2417. if (result0 !== null) {
  2418. result1 = (function(offset) { return directed; })(pos) ? "" : null;
  2419. if (result1 !== null) {
  2420. result0 = [result0, result1];
  2421. } else {
  2422. result0 = null;
  2423. pos = pos2;
  2424. }
  2425. } else {
  2426. result0 = null;
  2427. pos = pos2;
  2428. }
  2429. }
  2430. if (result0 !== null) {
  2431. result1 = [];
  2432. result2 = parse__();
  2433. while (result2 !== null) {
  2434. result1.push(result2);
  2435. result2 = parse__();
  2436. }
  2437. if (result1 !== null) {
  2438. result2 = parse_nodeIdOrSubgraph();
  2439. if (result2 !== null) {
  2440. result3 = [];
  2441. result4 = parse__();
  2442. while (result4 !== null) {
  2443. result3.push(result4);
  2444. result4 = parse__();
  2445. }
  2446. if (result3 !== null) {
  2447. result4 = parse_edgeRHS();
  2448. result4 = result4 !== null ? result4 : "";
  2449. if (result4 !== null) {
  2450. result0 = [result0, result1, result2, result3, result4];
  2451. } else {
  2452. result0 = null;
  2453. pos = pos1;
  2454. }
  2455. } else {
  2456. result0 = null;
  2457. pos = pos1;
  2458. }
  2459. } else {
  2460. result0 = null;
  2461. pos = pos1;
  2462. }
  2463. } else {
  2464. result0 = null;
  2465. pos = pos1;
  2466. }
  2467. } else {
  2468. result0 = null;
  2469. pos = pos1;
  2470. }
  2471. if (result0 !== null) {
  2472. result0 = (function(offset, rhs, rest) {
  2473. var result = [rhs];
  2474. for (var i = 0; i < rest.length; ++i) {
  2475. result.push(rest[i]);
  2476. }
  2477. return result;
  2478. })(pos0, result0[2], result0[4]);
  2479. }
  2480. if (result0 === null) {
  2481. pos = pos0;
  2482. }
  2483. return result0;
  2484. }
  2485. function parse_idDef() {
  2486. var result0, result1, result2, result3, result4;
  2487. var pos0, pos1, pos2;
  2488. pos0 = pos;
  2489. pos1 = pos;
  2490. result0 = parse_id();
  2491. if (result0 !== null) {
  2492. pos2 = pos;
  2493. result1 = [];
  2494. result2 = parse__();
  2495. while (result2 !== null) {
  2496. result1.push(result2);
  2497. result2 = parse__();
  2498. }
  2499. if (result1 !== null) {
  2500. if (input.charCodeAt(pos) === 61) {
  2501. result2 = "=";
  2502. pos++;
  2503. } else {
  2504. result2 = null;
  2505. if (reportFailures === 0) {
  2506. matchFailed("\"=\"");
  2507. }
  2508. }
  2509. if (result2 !== null) {
  2510. result3 = [];
  2511. result4 = parse__();
  2512. while (result4 !== null) {
  2513. result3.push(result4);
  2514. result4 = parse__();
  2515. }
  2516. if (result3 !== null) {
  2517. result4 = parse_id();
  2518. if (result4 !== null) {
  2519. result1 = [result1, result2, result3, result4];
  2520. } else {
  2521. result1 = null;
  2522. pos = pos2;
  2523. }
  2524. } else {
  2525. result1 = null;
  2526. pos = pos2;
  2527. }
  2528. } else {
  2529. result1 = null;
  2530. pos = pos2;
  2531. }
  2532. } else {
  2533. result1 = null;
  2534. pos = pos2;
  2535. }
  2536. result1 = result1 !== null ? result1 : "";
  2537. if (result1 !== null) {
  2538. result0 = [result0, result1];
  2539. } else {
  2540. result0 = null;
  2541. pos = pos1;
  2542. }
  2543. } else {
  2544. result0 = null;
  2545. pos = pos1;
  2546. }
  2547. if (result0 !== null) {
  2548. result0 = (function(offset, k, v) {
  2549. var result = {};
  2550. result[k] = v[3];
  2551. return result;
  2552. })(pos0, result0[0], result0[1]);
  2553. }
  2554. if (result0 === null) {
  2555. pos = pos0;
  2556. }
  2557. return result0;
  2558. }
  2559. function parse_nodeIdOrSubgraph() {
  2560. var result0;
  2561. var pos0;
  2562. result0 = parse_subgraphStmt();
  2563. if (result0 === null) {
  2564. pos0 = pos;
  2565. result0 = parse_nodeId();
  2566. if (result0 !== null) {
  2567. result0 = (function(offset, id) { return { type: "node", id: id, attrs: {} }; })(pos0, result0);
  2568. }
  2569. if (result0 === null) {
  2570. pos = pos0;
  2571. }
  2572. }
  2573. return result0;
  2574. }
  2575. function parse_nodeId() {
  2576. var result0, result1, result2;
  2577. var pos0, pos1;
  2578. pos0 = pos;
  2579. pos1 = pos;
  2580. result0 = parse_id();
  2581. if (result0 !== null) {
  2582. result1 = [];
  2583. result2 = parse__();
  2584. while (result2 !== null) {
  2585. result1.push(result2);
  2586. result2 = parse__();
  2587. }
  2588. if (result1 !== null) {
  2589. result2 = parse_port();
  2590. result2 = result2 !== null ? result2 : "";
  2591. if (result2 !== null) {
  2592. result0 = [result0, result1, result2];
  2593. } else {
  2594. result0 = null;
  2595. pos = pos1;
  2596. }
  2597. } else {
  2598. result0 = null;
  2599. pos = pos1;
  2600. }
  2601. } else {
  2602. result0 = null;
  2603. pos = pos1;
  2604. }
  2605. if (result0 !== null) {
  2606. result0 = (function(offset, id) { return id; })(pos0, result0[0]);
  2607. }
  2608. if (result0 === null) {
  2609. pos = pos0;
  2610. }
  2611. return result0;
  2612. }
  2613. function parse_port() {
  2614. var result0, result1, result2, result3, result4, result5, result6;
  2615. var pos0, pos1;
  2616. pos0 = pos;
  2617. if (input.charCodeAt(pos) === 58) {
  2618. result0 = ":";
  2619. pos++;
  2620. } else {
  2621. result0 = null;
  2622. if (reportFailures === 0) {
  2623. matchFailed("\":\"");
  2624. }
  2625. }
  2626. if (result0 !== null) {
  2627. result1 = [];
  2628. result2 = parse__();
  2629. while (result2 !== null) {
  2630. result1.push(result2);
  2631. result2 = parse__();
  2632. }
  2633. if (result1 !== null) {
  2634. result2 = parse_id();
  2635. if (result2 !== null) {
  2636. result3 = [];
  2637. result4 = parse__();
  2638. while (result4 !== null) {
  2639. result3.push(result4);
  2640. result4 = parse__();
  2641. }
  2642. if (result3 !== null) {
  2643. pos1 = pos;
  2644. if (input.charCodeAt(pos) === 58) {
  2645. result4 = ":";
  2646. pos++;
  2647. } else {
  2648. result4 = null;
  2649. if (reportFailures === 0) {
  2650. matchFailed("\":\"");
  2651. }
  2652. }
  2653. if (result4 !== null) {
  2654. result5 = [];
  2655. result6 = parse__();
  2656. while (result6 !== null) {
  2657. result5.push(result6);
  2658. result6 = parse__();
  2659. }
  2660. if (result5 !== null) {
  2661. result6 = parse_compassPt();
  2662. if (result6 !== null) {
  2663. result4 = [result4, result5, result6];
  2664. } else {
  2665. result4 = null;
  2666. pos = pos1;
  2667. }
  2668. } else {
  2669. result4 = null;
  2670. pos = pos1;
  2671. }
  2672. } else {
  2673. result4 = null;
  2674. pos = pos1;
  2675. }
  2676. result4 = result4 !== null ? result4 : "";
  2677. if (result4 !== null) {
  2678. result0 = [result0, result1, result2, result3, result4];
  2679. } else {
  2680. result0 = null;
  2681. pos = pos0;
  2682. }
  2683. } else {
  2684. result0 = null;
  2685. pos = pos0;
  2686. }
  2687. } else {
  2688. result0 = null;
  2689. pos = pos0;
  2690. }
  2691. } else {
  2692. result0 = null;
  2693. pos = pos0;
  2694. }
  2695. } else {
  2696. result0 = null;
  2697. pos = pos0;
  2698. }
  2699. return result0;
  2700. }
  2701. function parse_compassPt() {
  2702. var result0;
  2703. if (input.charCodeAt(pos) === 110) {
  2704. result0 = "n";
  2705. pos++;
  2706. } else {
  2707. result0 = null;
  2708. if (reportFailures === 0) {
  2709. matchFailed("\"n\"");
  2710. }
  2711. }
  2712. if (result0 === null) {
  2713. if (input.substr(pos, 2) === "ne") {
  2714. result0 = "ne";
  2715. pos += 2;
  2716. } else {
  2717. result0 = null;
  2718. if (reportFailures === 0) {
  2719. matchFailed("\"ne\"");
  2720. }
  2721. }
  2722. if (result0 === null) {
  2723. if (input.charCodeAt(pos) === 101) {
  2724. result0 = "e";
  2725. pos++;
  2726. } else {
  2727. result0 = null;
  2728. if (reportFailures === 0) {
  2729. matchFailed("\"e\"");
  2730. }
  2731. }
  2732. if (result0 === null) {
  2733. if (input.substr(pos, 2) === "se") {
  2734. result0 = "se";
  2735. pos += 2;
  2736. } else {
  2737. result0 = null;
  2738. if (reportFailures === 0) {
  2739. matchFailed("\"se\"");
  2740. }
  2741. }
  2742. if (result0 === null) {
  2743. if (input.charCodeAt(pos) === 115) {
  2744. result0 = "s";
  2745. pos++;
  2746. } else {
  2747. result0 = null;
  2748. if (reportFailures === 0) {
  2749. matchFailed("\"s\"");
  2750. }
  2751. }
  2752. if (result0 === null) {
  2753. if (input.substr(pos, 2) === "sw") {
  2754. result0 = "sw";
  2755. pos += 2;
  2756. } else {
  2757. result0 = null;
  2758. if (reportFailures === 0) {
  2759. matchFailed("\"sw\"");
  2760. }
  2761. }
  2762. if (result0 === null) {
  2763. if (input.charCodeAt(pos) === 119) {
  2764. result0 = "w";
  2765. pos++;
  2766. } else {
  2767. result0 = null;
  2768. if (reportFailures === 0) {
  2769. matchFailed("\"w\"");
  2770. }
  2771. }
  2772. if (result0 === null) {
  2773. if (input.substr(pos, 2) === "nw") {
  2774. result0 = "nw";
  2775. pos += 2;
  2776. } else {
  2777. result0 = null;
  2778. if (reportFailures === 0) {
  2779. matchFailed("\"nw\"");
  2780. }
  2781. }
  2782. if (result0 === null) {
  2783. if (input.charCodeAt(pos) === 99) {
  2784. result0 = "c";
  2785. pos++;
  2786. } else {
  2787. result0 = null;
  2788. if (reportFailures === 0) {
  2789. matchFailed("\"c\"");
  2790. }
  2791. }
  2792. if (result0 === null) {
  2793. if (input.charCodeAt(pos) === 95) {
  2794. result0 = "_";
  2795. pos++;
  2796. } else {
  2797. result0 = null;
  2798. if (reportFailures === 0) {
  2799. matchFailed("\"_\"");
  2800. }
  2801. }
  2802. }
  2803. }
  2804. }
  2805. }
  2806. }
  2807. }
  2808. }
  2809. }
  2810. }
  2811. return result0;
  2812. }
  2813. function parse_id() {
  2814. var result0, result1, result2, result3, result4;
  2815. var pos0, pos1, pos2, pos3;
  2816. reportFailures++;
  2817. pos0 = pos;
  2818. pos1 = pos;
  2819. if (/^[a-zA-Z\u0200-\u0377_]/.test(input.charAt(pos))) {
  2820. result0 = input.charAt(pos);
  2821. pos++;
  2822. } else {
  2823. result0 = null;
  2824. if (reportFailures === 0) {
  2825. matchFailed("[a-zA-Z\\u0200-\\u0377_]");
  2826. }
  2827. }
  2828. if (result0 !== null) {
  2829. result1 = [];
  2830. if (/^[a-zA-Z\u0200-\u0377_0-9]/.test(input.charAt(pos))) {
  2831. result2 = input.charAt(pos);
  2832. pos++;
  2833. } else {
  2834. result2 = null;
  2835. if (reportFailures === 0) {
  2836. matchFailed("[a-zA-Z\\u0200-\\u0377_0-9]");
  2837. }
  2838. }
  2839. while (result2 !== null) {
  2840. result1.push(result2);
  2841. if (/^[a-zA-Z\u0200-\u0377_0-9]/.test(input.charAt(pos))) {
  2842. result2 = input.charAt(pos);
  2843. pos++;
  2844. } else {
  2845. result2 = null;
  2846. if (reportFailures === 0) {
  2847. matchFailed("[a-zA-Z\\u0200-\\u0377_0-9]");
  2848. }
  2849. }
  2850. }
  2851. if (result1 !== null) {
  2852. result0 = [result0, result1];
  2853. } else {
  2854. result0 = null;
  2855. pos = pos1;
  2856. }
  2857. } else {
  2858. result0 = null;
  2859. pos = pos1;
  2860. }
  2861. if (result0 !== null) {
  2862. result0 = (function(offset, fst, rest) { return fst + rest.join(""); })(pos0, result0[0], result0[1]);
  2863. }
  2864. if (result0 === null) {
  2865. pos = pos0;
  2866. }
  2867. if (result0 === null) {
  2868. pos0 = pos;
  2869. pos1 = pos;
  2870. if (input.charCodeAt(pos) === 45) {
  2871. result0 = "-";
  2872. pos++;
  2873. } else {
  2874. result0 = null;
  2875. if (reportFailures === 0) {
  2876. matchFailed("\"-\"");
  2877. }
  2878. }
  2879. result0 = result0 !== null ? result0 : "";
  2880. if (result0 !== null) {
  2881. if (input.charCodeAt(pos) === 46) {
  2882. result1 = ".";
  2883. pos++;
  2884. } else {
  2885. result1 = null;
  2886. if (reportFailures === 0) {
  2887. matchFailed("\".\"");
  2888. }
  2889. }
  2890. if (result1 !== null) {
  2891. if (/^[0-9]/.test(input.charAt(pos))) {
  2892. result3 = input.charAt(pos);
  2893. pos++;
  2894. } else {
  2895. result3 = null;
  2896. if (reportFailures === 0) {
  2897. matchFailed("[0-9]");
  2898. }
  2899. }
  2900. if (result3 !== null) {
  2901. result2 = [];
  2902. while (result3 !== null) {
  2903. result2.push(result3);
  2904. if (/^[0-9]/.test(input.charAt(pos))) {
  2905. result3 = input.charAt(pos);
  2906. pos++;
  2907. } else {
  2908. result3 = null;
  2909. if (reportFailures === 0) {
  2910. matchFailed("[0-9]");
  2911. }
  2912. }
  2913. }
  2914. } else {
  2915. result2 = null;
  2916. }
  2917. if (result2 !== null) {
  2918. result0 = [result0, result1, result2];
  2919. } else {
  2920. result0 = null;
  2921. pos = pos1;
  2922. }
  2923. } else {
  2924. result0 = null;
  2925. pos = pos1;
  2926. }
  2927. } else {
  2928. result0 = null;
  2929. pos = pos1;
  2930. }
  2931. if (result0 !== null) {
  2932. result0 = (function(offset, sign, dot, after) { return sign + dot + after.join(""); })(pos0, result0[0], result0[1], result0[2]);
  2933. }
  2934. if (result0 === null) {
  2935. pos = pos0;
  2936. }
  2937. if (result0 === null) {
  2938. pos0 = pos;
  2939. pos1 = pos;
  2940. if (input.charCodeAt(pos) === 45) {
  2941. result0 = "-";
  2942. pos++;
  2943. } else {
  2944. result0 = null;
  2945. if (reportFailures === 0) {
  2946. matchFailed("\"-\"");
  2947. }
  2948. }
  2949. result0 = result0 !== null ? result0 : "";
  2950. if (result0 !== null) {
  2951. if (/^[0-9]/.test(input.charAt(pos))) {
  2952. result2 = input.charAt(pos);
  2953. pos++;
  2954. } else {
  2955. result2 = null;
  2956. if (reportFailures === 0) {
  2957. matchFailed("[0-9]");
  2958. }
  2959. }
  2960. if (result2 !== null) {
  2961. result1 = [];
  2962. while (result2 !== null) {
  2963. result1.push(result2);
  2964. if (/^[0-9]/.test(input.charAt(pos))) {
  2965. result2 = input.charAt(pos);
  2966. pos++;
  2967. } else {
  2968. result2 = null;
  2969. if (reportFailures === 0) {
  2970. matchFailed("[0-9]");
  2971. }
  2972. }
  2973. }
  2974. } else {
  2975. result1 = null;
  2976. }
  2977. if (result1 !== null) {
  2978. pos2 = pos;
  2979. if (input.charCodeAt(pos) === 46) {
  2980. result2 = ".";
  2981. pos++;
  2982. } else {
  2983. result2 = null;
  2984. if (reportFailures === 0) {
  2985. matchFailed("\".\"");
  2986. }
  2987. }
  2988. if (result2 !== null) {
  2989. result3 = [];
  2990. if (/^[0-9]/.test(input.charAt(pos))) {
  2991. result4 = input.charAt(pos);
  2992. pos++;
  2993. } else {
  2994. result4 = null;
  2995. if (reportFailures === 0) {
  2996. matchFailed("[0-9]");
  2997. }
  2998. }
  2999. while (result4 !== null) {
  3000. result3.push(result4);
  3001. if (/^[0-9]/.test(input.charAt(pos))) {
  3002. result4 = input.charAt(pos);
  3003. pos++;
  3004. } else {
  3005. result4 = null;
  3006. if (reportFailures === 0) {
  3007. matchFailed("[0-9]");
  3008. }
  3009. }
  3010. }
  3011. if (result3 !== null) {
  3012. result2 = [result2, result3];
  3013. } else {
  3014. result2 = null;
  3015. pos = pos2;
  3016. }
  3017. } else {
  3018. result2 = null;
  3019. pos = pos2;
  3020. }
  3021. result2 = result2 !== null ? result2 : "";
  3022. if (result2 !== null) {
  3023. result0 = [result0, result1, result2];
  3024. } else {
  3025. result0 = null;
  3026. pos = pos1;
  3027. }
  3028. } else {
  3029. result0 = null;
  3030. pos = pos1;
  3031. }
  3032. } else {
  3033. result0 = null;
  3034. pos = pos1;
  3035. }
  3036. if (result0 !== null) {
  3037. result0 = (function(offset, sign, before, after) { return sign + before.join("") + (after[0] || "") + (after[1] || []).join(""); })(pos0, result0[0], result0[1], result0[2]);
  3038. }
  3039. if (result0 === null) {
  3040. pos = pos0;
  3041. }
  3042. if (result0 === null) {
  3043. pos0 = pos;
  3044. pos1 = pos;
  3045. if (input.charCodeAt(pos) === 34) {
  3046. result0 = "\"";
  3047. pos++;
  3048. } else {
  3049. result0 = null;
  3050. if (reportFailures === 0) {
  3051. matchFailed("\"\\\"\"");
  3052. }
  3053. }
  3054. if (result0 !== null) {
  3055. pos2 = pos;
  3056. if (input.substr(pos, 2) === "\\\"") {
  3057. result2 = "\\\"";
  3058. pos += 2;
  3059. } else {
  3060. result2 = null;
  3061. if (reportFailures === 0) {
  3062. matchFailed("\"\\\\\\\"\"");
  3063. }
  3064. }
  3065. if (result2 !== null) {
  3066. result2 = (function(offset) { return '"'; })(pos2);
  3067. }
  3068. if (result2 === null) {
  3069. pos = pos2;
  3070. }
  3071. if (result2 === null) {
  3072. pos2 = pos;
  3073. pos3 = pos;
  3074. if (input.charCodeAt(pos) === 92) {
  3075. result2 = "\\";
  3076. pos++;
  3077. } else {
  3078. result2 = null;
  3079. if (reportFailures === 0) {
  3080. matchFailed("\"\\\\\"");
  3081. }
  3082. }
  3083. if (result2 !== null) {
  3084. if (/^[^"]/.test(input.charAt(pos))) {
  3085. result3 = input.charAt(pos);
  3086. pos++;
  3087. } else {
  3088. result3 = null;
  3089. if (reportFailures === 0) {
  3090. matchFailed("[^\"]");
  3091. }
  3092. }
  3093. if (result3 !== null) {
  3094. result2 = [result2, result3];
  3095. } else {
  3096. result2 = null;
  3097. pos = pos3;
  3098. }
  3099. } else {
  3100. result2 = null;
  3101. pos = pos3;
  3102. }
  3103. if (result2 !== null) {
  3104. result2 = (function(offset, ch) { return "\\" + ch; })(pos2, result2[1]);
  3105. }
  3106. if (result2 === null) {
  3107. pos = pos2;
  3108. }
  3109. if (result2 === null) {
  3110. if (/^[^"]/.test(input.charAt(pos))) {
  3111. result2 = input.charAt(pos);
  3112. pos++;
  3113. } else {
  3114. result2 = null;
  3115. if (reportFailures === 0) {
  3116. matchFailed("[^\"]");
  3117. }
  3118. }
  3119. }
  3120. }
  3121. if (result2 !== null) {
  3122. result1 = [];
  3123. while (result2 !== null) {
  3124. result1.push(result2);
  3125. pos2 = pos;
  3126. if (input.substr(pos, 2) === "\\\"") {
  3127. result2 = "\\\"";
  3128. pos += 2;
  3129. } else {
  3130. result2 = null;
  3131. if (reportFailures === 0) {
  3132. matchFailed("\"\\\\\\\"\"");
  3133. }
  3134. }
  3135. if (result2 !== null) {
  3136. result2 = (function(offset) { return '"'; })(pos2);
  3137. }
  3138. if (result2 === null) {
  3139. pos = pos2;
  3140. }
  3141. if (result2 === null) {
  3142. pos2 = pos;
  3143. pos3 = pos;
  3144. if (input.charCodeAt(pos) === 92) {
  3145. result2 = "\\";
  3146. pos++;
  3147. } else {
  3148. result2 = null;
  3149. if (reportFailures === 0) {
  3150. matchFailed("\"\\\\\"");
  3151. }
  3152. }
  3153. if (result2 !== null) {
  3154. if (/^[^"]/.test(input.charAt(pos))) {
  3155. result3 = input.charAt(pos);
  3156. pos++;
  3157. } else {
  3158. result3 = null;
  3159. if (reportFailures === 0) {
  3160. matchFailed("[^\"]");
  3161. }
  3162. }
  3163. if (result3 !== null) {
  3164. result2 = [result2, result3];
  3165. } else {
  3166. result2 = null;
  3167. pos = pos3;
  3168. }
  3169. } else {
  3170. result2 = null;
  3171. pos = pos3;
  3172. }
  3173. if (result2 !== null) {
  3174. result2 = (function(offset, ch) { return "\\" + ch; })(pos2, result2[1]);
  3175. }
  3176. if (result2 === null) {
  3177. pos = pos2;
  3178. }
  3179. if (result2 === null) {
  3180. if (/^[^"]/.test(input.charAt(pos))) {
  3181. result2 = input.charAt(pos);
  3182. pos++;
  3183. } else {
  3184. result2 = null;
  3185. if (reportFailures === 0) {
  3186. matchFailed("[^\"]");
  3187. }
  3188. }
  3189. }
  3190. }
  3191. }
  3192. } else {
  3193. result1 = null;
  3194. }
  3195. if (result1 !== null) {
  3196. if (input.charCodeAt(pos) === 34) {
  3197. result2 = "\"";
  3198. pos++;
  3199. } else {
  3200. result2 = null;
  3201. if (reportFailures === 0) {
  3202. matchFailed("\"\\\"\"");
  3203. }
  3204. }
  3205. if (result2 !== null) {
  3206. result0 = [result0, result1, result2];
  3207. } else {
  3208. result0 = null;
  3209. pos = pos1;
  3210. }
  3211. } else {
  3212. result0 = null;
  3213. pos = pos1;
  3214. }
  3215. } else {
  3216. result0 = null;
  3217. pos = pos1;
  3218. }
  3219. if (result0 !== null) {
  3220. result0 = (function(offset, id) { return id.join(""); })(pos0, result0[1]);
  3221. }
  3222. if (result0 === null) {
  3223. pos = pos0;
  3224. }
  3225. }
  3226. }
  3227. }
  3228. reportFailures--;
  3229. if (reportFailures === 0 && result0 === null) {
  3230. matchFailed("identifier");
  3231. }
  3232. return result0;
  3233. }
  3234. function parse_node() {
  3235. var result0;
  3236. var pos0;
  3237. pos0 = pos;
  3238. if (input.substr(pos, 4).toLowerCase() === "node") {
  3239. result0 = input.substr(pos, 4);
  3240. pos += 4;
  3241. } else {
  3242. result0 = null;
  3243. if (reportFailures === 0) {
  3244. matchFailed("\"node\"");
  3245. }
  3246. }
  3247. if (result0 !== null) {
  3248. result0 = (function(offset, k) { return k.toLowerCase(); })(pos0, result0);
  3249. }
  3250. if (result0 === null) {
  3251. pos = pos0;
  3252. }
  3253. return result0;
  3254. }
  3255. function parse_edge() {
  3256. var result0;
  3257. var pos0;
  3258. pos0 = pos;
  3259. if (input.substr(pos, 4).toLowerCase() === "edge") {
  3260. result0 = input.substr(pos, 4);
  3261. pos += 4;
  3262. } else {
  3263. result0 = null;
  3264. if (reportFailures === 0) {
  3265. matchFailed("\"edge\"");
  3266. }
  3267. }
  3268. if (result0 !== null) {
  3269. result0 = (function(offset, k) { return k.toLowerCase(); })(pos0, result0);
  3270. }
  3271. if (result0 === null) {
  3272. pos = pos0;
  3273. }
  3274. return result0;
  3275. }
  3276. function parse_graph() {
  3277. var result0;
  3278. var pos0;
  3279. pos0 = pos;
  3280. if (input.substr(pos, 5).toLowerCase() === "graph") {
  3281. result0 = input.substr(pos, 5);
  3282. pos += 5;
  3283. } else {
  3284. result0 = null;
  3285. if (reportFailures === 0) {
  3286. matchFailed("\"graph\"");
  3287. }
  3288. }
  3289. if (result0 !== null) {
  3290. result0 = (function(offset, k) { return k.toLowerCase(); })(pos0, result0);
  3291. }
  3292. if (result0 === null) {
  3293. pos = pos0;
  3294. }
  3295. return result0;
  3296. }
  3297. function parse_digraph() {
  3298. var result0;
  3299. var pos0;
  3300. pos0 = pos;
  3301. if (input.substr(pos, 7).toLowerCase() === "digraph") {
  3302. result0 = input.substr(pos, 7);
  3303. pos += 7;
  3304. } else {
  3305. result0 = null;
  3306. if (reportFailures === 0) {
  3307. matchFailed("\"digraph\"");
  3308. }
  3309. }
  3310. if (result0 !== null) {
  3311. result0 = (function(offset, k) { return k.toLowerCase(); })(pos0, result0);
  3312. }
  3313. if (result0 === null) {
  3314. pos = pos0;
  3315. }
  3316. return result0;
  3317. }
  3318. function parse_subgraph() {
  3319. var result0;
  3320. var pos0;
  3321. pos0 = pos;
  3322. if (input.substr(pos, 8).toLowerCase() === "subgraph") {
  3323. result0 = input.substr(pos, 8);
  3324. pos += 8;
  3325. } else {
  3326. result0 = null;
  3327. if (reportFailures === 0) {
  3328. matchFailed("\"subgraph\"");
  3329. }
  3330. }
  3331. if (result0 !== null) {
  3332. result0 = (function(offset, k) { return k.toLowerCase(); })(pos0, result0);
  3333. }
  3334. if (result0 === null) {
  3335. pos = pos0;
  3336. }
  3337. return result0;
  3338. }
  3339. function parse_strict() {
  3340. var result0;
  3341. var pos0;
  3342. pos0 = pos;
  3343. if (input.substr(pos, 6).toLowerCase() === "strict") {
  3344. result0 = input.substr(pos, 6);
  3345. pos += 6;
  3346. } else {
  3347. result0 = null;
  3348. if (reportFailures === 0) {
  3349. matchFailed("\"strict\"");
  3350. }
  3351. }
  3352. if (result0 !== null) {
  3353. result0 = (function(offset, k) { return k.toLowerCase(); })(pos0, result0);
  3354. }
  3355. if (result0 === null) {
  3356. pos = pos0;
  3357. }
  3358. return result0;
  3359. }
  3360. function parse_graphType() {
  3361. var result0;
  3362. var pos0;
  3363. result0 = parse_graph();
  3364. if (result0 === null) {
  3365. pos0 = pos;
  3366. result0 = parse_digraph();
  3367. if (result0 !== null) {
  3368. result0 = (function(offset, graph) {
  3369. directed = graph === "digraph";
  3370. return graph;
  3371. })(pos0, result0);
  3372. }
  3373. if (result0 === null) {
  3374. pos = pos0;
  3375. }
  3376. }
  3377. return result0;
  3378. }
  3379. function parse_whitespace() {
  3380. var result0, result1;
  3381. reportFailures++;
  3382. if (/^[ \t\r\n]/.test(input.charAt(pos))) {
  3383. result1 = input.charAt(pos);
  3384. pos++;
  3385. } else {
  3386. result1 = null;
  3387. if (reportFailures === 0) {
  3388. matchFailed("[ \\t\\r\\n]");
  3389. }
  3390. }
  3391. if (result1 !== null) {
  3392. result0 = [];
  3393. while (result1 !== null) {
  3394. result0.push(result1);
  3395. if (/^[ \t\r\n]/.test(input.charAt(pos))) {
  3396. result1 = input.charAt(pos);
  3397. pos++;
  3398. } else {
  3399. result1 = null;
  3400. if (reportFailures === 0) {
  3401. matchFailed("[ \\t\\r\\n]");
  3402. }
  3403. }
  3404. }
  3405. } else {
  3406. result0 = null;
  3407. }
  3408. reportFailures--;
  3409. if (reportFailures === 0 && result0 === null) {
  3410. matchFailed("whitespace");
  3411. }
  3412. return result0;
  3413. }
  3414. function parse_comment() {
  3415. var result0, result1, result2, result3;
  3416. var pos0, pos1, pos2;
  3417. reportFailures++;
  3418. pos0 = pos;
  3419. if (input.substr(pos, 2) === "//") {
  3420. result0 = "//";
  3421. pos += 2;
  3422. } else {
  3423. result0 = null;
  3424. if (reportFailures === 0) {
  3425. matchFailed("\"//\"");
  3426. }
  3427. }
  3428. if (result0 !== null) {
  3429. result1 = [];
  3430. if (/^[^\n]/.test(input.charAt(pos))) {
  3431. result2 = input.charAt(pos);
  3432. pos++;
  3433. } else {
  3434. result2 = null;
  3435. if (reportFailures === 0) {
  3436. matchFailed("[^\\n]");
  3437. }
  3438. }
  3439. while (result2 !== null) {
  3440. result1.push(result2);
  3441. if (/^[^\n]/.test(input.charAt(pos))) {
  3442. result2 = input.charAt(pos);
  3443. pos++;
  3444. } else {
  3445. result2 = null;
  3446. if (reportFailures === 0) {
  3447. matchFailed("[^\\n]");
  3448. }
  3449. }
  3450. }
  3451. if (result1 !== null) {
  3452. result0 = [result0, result1];
  3453. } else {
  3454. result0 = null;
  3455. pos = pos0;
  3456. }
  3457. } else {
  3458. result0 = null;
  3459. pos = pos0;
  3460. }
  3461. if (result0 === null) {
  3462. pos0 = pos;
  3463. if (input.substr(pos, 2) === "/*") {
  3464. result0 = "/*";
  3465. pos += 2;
  3466. } else {
  3467. result0 = null;
  3468. if (reportFailures === 0) {
  3469. matchFailed("\"/*\"");
  3470. }
  3471. }
  3472. if (result0 !== null) {
  3473. result1 = [];
  3474. pos1 = pos;
  3475. pos2 = pos;
  3476. reportFailures++;
  3477. if (input.substr(pos, 2) === "*/") {
  3478. result2 = "*/";
  3479. pos += 2;
  3480. } else {
  3481. result2 = null;
  3482. if (reportFailures === 0) {
  3483. matchFailed("\"*/\"");
  3484. }
  3485. }
  3486. reportFailures--;
  3487. if (result2 === null) {
  3488. result2 = "";
  3489. } else {
  3490. result2 = null;
  3491. pos = pos2;
  3492. }
  3493. if (result2 !== null) {
  3494. if (input.length > pos) {
  3495. result3 = input.charAt(pos);
  3496. pos++;
  3497. } else {
  3498. result3 = null;
  3499. if (reportFailures === 0) {
  3500. matchFailed("any character");
  3501. }
  3502. }
  3503. if (result3 !== null) {
  3504. result2 = [result2, result3];
  3505. } else {
  3506. result2 = null;
  3507. pos = pos1;
  3508. }
  3509. } else {
  3510. result2 = null;
  3511. pos = pos1;
  3512. }
  3513. while (result2 !== null) {
  3514. result1.push(result2);
  3515. pos1 = pos;
  3516. pos2 = pos;
  3517. reportFailures++;
  3518. if (input.substr(pos, 2) === "*/") {
  3519. result2 = "*/";
  3520. pos += 2;
  3521. } else {
  3522. result2 = null;
  3523. if (reportFailures === 0) {
  3524. matchFailed("\"*/\"");
  3525. }
  3526. }
  3527. reportFailures--;
  3528. if (result2 === null) {
  3529. result2 = "";
  3530. } else {
  3531. result2 = null;
  3532. pos = pos2;
  3533. }
  3534. if (result2 !== null) {
  3535. if (input.length > pos) {
  3536. result3 = input.charAt(pos);
  3537. pos++;
  3538. } else {
  3539. result3 = null;
  3540. if (reportFailures === 0) {
  3541. matchFailed("any character");
  3542. }
  3543. }
  3544. if (result3 !== null) {
  3545. result2 = [result2, result3];
  3546. } else {
  3547. result2 = null;
  3548. pos = pos1;
  3549. }
  3550. } else {
  3551. result2 = null;
  3552. pos = pos1;
  3553. }
  3554. }
  3555. if (result1 !== null) {
  3556. if (input.substr(pos, 2) === "*/") {
  3557. result2 = "*/";
  3558. pos += 2;
  3559. } else {
  3560. result2 = null;
  3561. if (reportFailures === 0) {
  3562. matchFailed("\"*/\"");
  3563. }
  3564. }
  3565. if (result2 !== null) {
  3566. result0 = [result0, result1, result2];
  3567. } else {
  3568. result0 = null;
  3569. pos = pos0;
  3570. }
  3571. } else {
  3572. result0 = null;
  3573. pos = pos0;
  3574. }
  3575. } else {
  3576. result0 = null;
  3577. pos = pos0;
  3578. }
  3579. }
  3580. reportFailures--;
  3581. if (reportFailures === 0 && result0 === null) {
  3582. matchFailed("comment");
  3583. }
  3584. return result0;
  3585. }
  3586. function parse__() {
  3587. var result0;
  3588. result0 = parse_whitespace();
  3589. if (result0 === null) {
  3590. result0 = parse_comment();
  3591. }
  3592. return result0;
  3593. }
  3594. function cleanupExpected(expected) {
  3595. expected.sort();
  3596. var lastExpected = null;
  3597. var cleanExpected = [];
  3598. for (var i = 0; i < expected.length; i++) {
  3599. if (expected[i] !== lastExpected) {
  3600. cleanExpected.push(expected[i]);
  3601. lastExpected = expected[i];
  3602. }
  3603. }
  3604. return cleanExpected;
  3605. }
  3606. function computeErrorPosition() {
  3607. /*
  3608. * The first idea was to use |String.split| to break the input up to the
  3609. * error position along newlines and derive the line and column from
  3610. * there. However IE's |split| implementation is so broken that it was
  3611. * enough to prevent it.
  3612. */
  3613. var line = 1;
  3614. var column = 1;
  3615. var seenCR = false;
  3616. for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) {
  3617. var ch = input.charAt(i);
  3618. if (ch === "\n") {
  3619. if (!seenCR) { line++; }
  3620. column = 1;
  3621. seenCR = false;
  3622. } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") {
  3623. line++;
  3624. column = 1;
  3625. seenCR = true;
  3626. } else {
  3627. column++;
  3628. seenCR = false;
  3629. }
  3630. }
  3631. return { line: line, column: column };
  3632. }
  3633. var directed;
  3634. function rightBiasedMerge(lhs, rhs) {
  3635. var result = {};
  3636. for (var k in lhs) {
  3637. result[k] = lhs[k];
  3638. }
  3639. for (var k in rhs) {
  3640. result[k] = rhs[k];
  3641. }
  3642. return result;
  3643. }
  3644. var result = parseFunctions[startRule]();
  3645. /*
  3646. * The parser is now in one of the following three states:
  3647. *
  3648. * 1. The parser successfully parsed the whole input.
  3649. *
  3650. * - |result !== null|
  3651. * - |pos === input.length|
  3652. * - |rightmostFailuresExpected| may or may not contain something
  3653. *
  3654. * 2. The parser successfully parsed only a part of the input.
  3655. *
  3656. * - |result !== null|
  3657. * - |pos < input.length|
  3658. * - |rightmostFailuresExpected| may or may not contain something
  3659. *
  3660. * 3. The parser did not successfully parse any part of the input.
  3661. *
  3662. * - |result === null|
  3663. * - |pos === 0|
  3664. * - |rightmostFailuresExpected| contains at least one failure
  3665. *
  3666. * All code following this comment (including called functions) must
  3667. * handle these states.
  3668. */
  3669. if (result === null || pos !== input.length) {
  3670. var offset = Math.max(pos, rightmostFailuresPos);
  3671. var found = offset < input.length ? input.charAt(offset) : null;
  3672. var errorPosition = computeErrorPosition();
  3673. throw new this.SyntaxError(
  3674. cleanupExpected(rightmostFailuresExpected),
  3675. found,
  3676. offset,
  3677. errorPosition.line,
  3678. errorPosition.column
  3679. );
  3680. }
  3681. return result;
  3682. },
  3683. /* Returns the parser source code. */
  3684. toSource: function() { return this._source; }
  3685. };
  3686. /* Thrown when a parser encounters a syntax error. */
  3687. result.SyntaxError = function(expected, found, offset, line, column) {
  3688. function buildMessage(expected, found) {
  3689. var expectedHumanized, foundHumanized;
  3690. switch (expected.length) {
  3691. case 0:
  3692. expectedHumanized = "end of input";
  3693. break;
  3694. case 1:
  3695. expectedHumanized = expected[0];
  3696. break;
  3697. default:
  3698. expectedHumanized = expected.slice(0, expected.length - 1).join(", ")
  3699. + " or "
  3700. + expected[expected.length - 1];
  3701. }
  3702. foundHumanized = found ? quote(found) : "end of input";
  3703. return "Expected " + expectedHumanized + " but " + foundHumanized + " found.";
  3704. }
  3705. this.name = "SyntaxError";
  3706. this.expected = expected;
  3707. this.found = found;
  3708. this.message = buildMessage(expected, found);
  3709. this.offset = offset;
  3710. this.line = line;
  3711. this.column = column;
  3712. };
  3713. result.SyntaxError.prototype = Error.prototype;
  3714. return result;
  3715. })();
  3716. })();