From 7a58e8261f2b3939f2117e2296ea49a47f6d2590 Mon Sep 17 00:00:00 2001 From: knsv Date: Fri, 30 Oct 2015 10:47:25 +0100 Subject: [PATCH] Simple rendering of class diagrams --- dist/mermaid.js | 3380 ++++++++++++++------ package.json | 1 + src/diagrams/classDiagram/classDb.js | 2 +- src/diagrams/classDiagram/classRenderer.js | 111 +- src/mermaidAPI.js | 14 + src/utils.js | 5 + 6 files changed, 2439 insertions(+), 1074 deletions(-) diff --git a/dist/mermaid.js b/dist/mermaid.js index 792886dfa..84820d5c0 100644 --- a/dist/mermaid.js +++ b/dist/mermaid.js @@ -1,322 +1,4 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.mermaid=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === '.') { - parts.splice(i, 1); - } else if (last === '..') { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; - } - } - - // if the path is allowed to go above the root, restore leading ..s - if (allowAboveRoot) { - for (; up--; up) { - parts.unshift('..'); - } - } - - return parts; -} - -// Split a filename into [root, dir, basename, ext], unix version -// 'root' is just a slash, or nothing. -var splitPathRe = - /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; -var splitPath = function(filename) { - return splitPathRe.exec(filename).slice(1); -}; - -// path.resolve([from ...], to) -// posix version -exports.resolve = function() { - var resolvedPath = '', - resolvedAbsolute = false; - - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = (i >= 0) ? arguments[i] : process.cwd(); - - // Skip empty and invalid entries - if (typeof path !== 'string') { - throw new TypeError('Arguments to path.resolve must be strings'); - } else if (!path) { - continue; - } - - resolvedPath = path + '/' + resolvedPath; - resolvedAbsolute = path.charAt(0) === '/'; - } - - // At this point the path should be resolved to a full absolute path, but - // handle relative paths to be safe (might happen when process.cwd() fails) - - // Normalize the path - resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { - return !!p; - }), !resolvedAbsolute).join('/'); - - return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; -}; - -// path.normalize(path) -// posix version -exports.normalize = function(path) { - var isAbsolute = exports.isAbsolute(path), - trailingSlash = substr(path, -1) === '/'; - - // Normalize the path - path = normalizeArray(filter(path.split('/'), function(p) { - return !!p; - }), !isAbsolute).join('/'); - - if (!path && !isAbsolute) { - path = '.'; - } - if (path && trailingSlash) { - path += '/'; - } - - return (isAbsolute ? '/' : '') + path; -}; - -// posix version -exports.isAbsolute = function(path) { - return path.charAt(0) === '/'; -}; - -// posix version -exports.join = function() { - var paths = Array.prototype.slice.call(arguments, 0); - return exports.normalize(filter(paths, function(p, index) { - if (typeof p !== 'string') { - throw new TypeError('Arguments to path.join must be strings'); - } - return p; - }).join('/')); -}; - - -// path.relative(from, to) -// posix version -exports.relative = function(from, to) { - from = exports.resolve(from).substr(1); - to = exports.resolve(to).substr(1); - - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== '') break; - } - - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== '') break; - } - - if (start > end) return []; - return arr.slice(start, end - start + 1); - } - - var fromParts = trim(from.split('/')); - var toParts = trim(to.split('/')); - - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break; - } - } - - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push('..'); - } - - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - - return outputParts.join('/'); -}; - -exports.sep = '/'; -exports.delimiter = ':'; - -exports.dirname = function(path) { - var result = splitPath(path), - root = result[0], - dir = result[1]; - - if (!root && !dir) { - // No dirname whatsoever - return '.'; - } - - if (dir) { - // It has a dirname, strip trailing slash - dir = dir.substr(0, dir.length - 1); - } - - return root + dir; -}; - - -exports.basename = function(path, ext) { - var f = splitPath(path)[2]; - // TODO: make this comparison case-insensitive on windows? - if (ext && f.substr(-1 * ext.length) === ext) { - f = f.substr(0, f.length - ext.length); - } - return f; -}; - - -exports.extname = function(path) { - return splitPath(path)[3]; -}; - -function filter (xs, f) { - if (xs.filter) return xs.filter(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - if (f(xs[i], i, xs)) res.push(xs[i]); - } - return res; -} - -// String.prototype.substr - negative index don't work in IE8 -var substr = 'ab'.substr(-1) === 'b' - ? function (str, start, len) { return str.substr(start, len) } - : function (str, start, len) { - if (start < 0) start = str.length + start; - return str.substr(start, len); - } -; - -}).call(this,require('_process')) -},{"_process":3}],3:[function(require,module,exports){ -// shim for using process in browser - -var process = module.exports = {}; - -process.nextTick = (function () { - var canSetImmediate = typeof window !== 'undefined' - && window.setImmediate; - var canMutationObserver = typeof window !== 'undefined' - && window.MutationObserver; - var canPost = typeof window !== 'undefined' - && window.postMessage && window.addEventListener - ; - - if (canSetImmediate) { - return function (f) { return window.setImmediate(f) }; - } - - var queue = []; - - if (canMutationObserver) { - var hiddenDiv = document.createElement("div"); - var observer = new MutationObserver(function () { - var queueList = queue.slice(); - queue.length = 0; - queueList.forEach(function (fn) { - fn(); - }); - }); - - observer.observe(hiddenDiv, { attributes: true }); - - return function nextTick(fn) { - if (!queue.length) { - hiddenDiv.setAttribute('yes', 'no'); - } - queue.push(fn); - }; - } - - if (canPost) { - window.addEventListener('message', function (ev) { - var source = ev.source; - if ((source === window || source === null) && ev.data === 'process-tick') { - ev.stopPropagation(); - if (queue.length > 0) { - var fn = queue.shift(); - fn(); - } - } - }, true); - - return function nextTick(fn) { - queue.push(fn); - window.postMessage('process-tick', '*'); - }; - } - - return function nextTick(fn) { - setTimeout(fn, 0); - }; -})(); - -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; - -// TODO(shtylman) -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; - -},{}],4:[function(require,module,exports){ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.mermaid = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0; } -},{}],18:[function(require,module,exports){ +},{}],15:[function(require,module,exports){ module.exports = intersectNode; function intersectNode(node, point) { return node.intersect(point); } -},{}],19:[function(require,module,exports){ +},{}],16:[function(require,module,exports){ var intersectLine = require("./intersect-line"); module.exports = intersectPolygon; @@ -10410,7 +10092,7 @@ function intersectPolygon(node, polyPoints, point) { return intersections[0]; } -},{"./intersect-line":17}],20:[function(require,module,exports){ +},{"./intersect-line":14}],17:[function(require,module,exports){ module.exports = intersectRect; function intersectRect(node, point) { @@ -10444,7 +10126,7 @@ function intersectRect(node, point) { return {x: x + sx, y: y + sy}; } -},{}],21:[function(require,module,exports){ +},{}],18:[function(require,module,exports){ var util = require("../util"); module.exports = addHtmlLabel; @@ -10489,7 +10171,7 @@ function addHtmlLabel(root, node) { return fo; } -},{"../util":31}],22:[function(require,module,exports){ +},{"../util":28}],19:[function(require,module,exports){ var addTextLabel = require("./add-text-label"), addHtmlLabel = require("./add-html-label"), addSVGLabel = require("./add-svg-label"); @@ -10528,7 +10210,7 @@ function addLabel(root, node, location) { return labelSvg; } -},{"./add-html-label":21,"./add-svg-label":23,"./add-text-label":24}],23:[function(require,module,exports){ +},{"./add-html-label":18,"./add-svg-label":20,"./add-text-label":21}],20:[function(require,module,exports){ var util = require("../util"); module.exports = addSVGLabel; @@ -10543,7 +10225,7 @@ function addSVGLabel(root, node) { return domNode; } -},{"../util":31}],24:[function(require,module,exports){ +},{"../util":28}],21:[function(require,module,exports){ var util = require("../util"); module.exports = addTextLabel; @@ -10590,7 +10272,7 @@ function processEscapeSequences(text) { return newText; } -},{"../util":31}],25:[function(require,module,exports){ +},{"../util":28}],22:[function(require,module,exports){ /* global window */ var lodash; @@ -10607,7 +10289,7 @@ if (!lodash) { module.exports = lodash; -},{"lodash":83}],26:[function(require,module,exports){ +},{"lodash":80}],23:[function(require,module,exports){ "use strict"; var util = require("./util"), @@ -10643,7 +10325,7 @@ function positionClusters(selection, g) { } -},{"./d3":11,"./util":31}],27:[function(require,module,exports){ +},{"./d3":8,"./util":28}],24:[function(require,module,exports){ "use strict"; var util = require("./util"), @@ -10667,7 +10349,7 @@ function positionEdgeLabels(selection, g) { .attr("transform", translate); } -},{"./d3":11,"./lodash":25,"./util":31}],28:[function(require,module,exports){ +},{"./d3":8,"./lodash":22,"./util":28}],25:[function(require,module,exports){ "use strict"; var util = require("./util"), @@ -10690,7 +10372,7 @@ function positionNodes(selection, g) { .attr("transform", translate); } -},{"./d3":11,"./util":31}],29:[function(require,module,exports){ +},{"./d3":8,"./util":28}],26:[function(require,module,exports){ var _ = require("./lodash"), layout = require("./dagre").layout; @@ -10859,7 +10541,7 @@ function createOrSelectGroup(root, name) { return selection; } -},{"./arrows":6,"./create-clusters":7,"./create-edge-labels":8,"./create-edge-paths":9,"./create-nodes":10,"./dagre":12,"./lodash":25,"./position-clusters":26,"./position-edge-labels":27,"./position-nodes":28,"./shapes":30}],30:[function(require,module,exports){ +},{"./arrows":3,"./create-clusters":4,"./create-edge-labels":5,"./create-edge-paths":6,"./create-nodes":7,"./dagre":9,"./lodash":22,"./position-clusters":23,"./position-edge-labels":24,"./position-nodes":25,"./shapes":27}],27:[function(require,module,exports){ "use strict"; var intersectRect = require("./intersect/intersect-rect"), @@ -10942,7 +10624,7 @@ function diamond(parent, bbox, node) { return shapeSvg; } -},{"./intersect/intersect-circle":15,"./intersect/intersect-ellipse":16,"./intersect/intersect-polygon":19,"./intersect/intersect-rect":20}],31:[function(require,module,exports){ +},{"./intersect/intersect-circle":12,"./intersect/intersect-ellipse":13,"./intersect/intersect-polygon":16,"./intersect/intersect-rect":17}],28:[function(require,module,exports){ var _ = require("./lodash"); // Public utility functions @@ -10998,10 +10680,10 @@ function applyTransition(selection, g) { return selection; } -},{"./lodash":25}],32:[function(require,module,exports){ +},{"./lodash":22}],29:[function(require,module,exports){ module.exports = "0.4.10"; -},{}],33:[function(require,module,exports){ +},{}],30:[function(require,module,exports){ /* Copyright (c) 2012-2014 Chris Pettitt @@ -11036,7 +10718,7 @@ module.exports = { version: require("./lib/version") }; -},{"./lib/debug":38,"./lib/graphlib":39,"./lib/layout":41,"./lib/util":61,"./lib/version":62}],34:[function(require,module,exports){ +},{"./lib/debug":35,"./lib/graphlib":36,"./lib/layout":38,"./lib/util":58,"./lib/version":59}],31:[function(require,module,exports){ "use strict"; var _ = require("./lodash"), @@ -11105,7 +10787,7 @@ function undo(g) { }); } -},{"./greedy-fas":40,"./lodash":42}],35:[function(require,module,exports){ +},{"./greedy-fas":37,"./lodash":39}],32:[function(require,module,exports){ var _ = require("./lodash"), util = require("./util"); @@ -11145,7 +10827,7 @@ function addBorderNode(g, prop, prefix, sg, sgNode, rank) { } } -},{"./lodash":42,"./util":61}],36:[function(require,module,exports){ +},{"./lodash":39,"./util":58}],33:[function(require,module,exports){ "use strict"; var _ = require("./lodash"); @@ -11219,7 +10901,7 @@ function swapXYOne(attrs) { attrs.y = x; } -},{"./lodash":42}],37:[function(require,module,exports){ +},{"./lodash":39}],34:[function(require,module,exports){ /* * Simple doubly linked list implementation derived from Cormen, et al., * "Introduction to Algorithms". @@ -11277,7 +10959,7 @@ function filterOutLinks(k, v) { } } -},{}],38:[function(require,module,exports){ +},{}],35:[function(require,module,exports){ var _ = require("./lodash"), util = require("./util"), Graph = require("./graphlib").Graph; @@ -11313,7 +10995,7 @@ function debugOrdering(g) { return h; } -},{"./graphlib":39,"./lodash":42,"./util":61}],39:[function(require,module,exports){ +},{"./graphlib":36,"./lodash":39,"./util":58}],36:[function(require,module,exports){ /* global window */ var graphlib; @@ -11330,7 +11012,7 @@ if (!graphlib) { module.exports = graphlib; -},{"graphlib":63}],40:[function(require,module,exports){ +},{"graphlib":60}],37:[function(require,module,exports){ var _ = require("./lodash"), Graph = require("./graphlib").Graph, List = require("./data/list"); @@ -11450,7 +11132,7 @@ function assignBucket(buckets, zeroIdx, entry) { } } -},{"./data/list":37,"./graphlib":39,"./lodash":42}],41:[function(require,module,exports){ +},{"./data/list":34,"./graphlib":36,"./lodash":39}],38:[function(require,module,exports){ "use strict"; var _ = require("./lodash"), @@ -11844,7 +11526,7 @@ function canonicalize(attrs) { return newAttrs; } -},{"./acyclic":34,"./add-border-segments":35,"./coordinate-system":36,"./graphlib":39,"./lodash":42,"./nesting-graph":43,"./normalize":44,"./order":49,"./parent-dummy-chains":54,"./position":56,"./rank":58,"./util":61}],42:[function(require,module,exports){ +},{"./acyclic":31,"./add-border-segments":32,"./coordinate-system":33,"./graphlib":36,"./lodash":39,"./nesting-graph":40,"./normalize":41,"./order":46,"./parent-dummy-chains":51,"./position":53,"./rank":55,"./util":58}],39:[function(require,module,exports){ /* global window */ var lodash; @@ -11861,7 +11543,7 @@ if (!lodash) { module.exports = lodash; -},{"lodash":83}],43:[function(require,module,exports){ +},{"lodash":80}],40:[function(require,module,exports){ var _ = require("./lodash"), util = require("./util"); @@ -11995,7 +11677,7 @@ function cleanup(g) { }); } -},{"./lodash":42,"./util":61}],44:[function(require,module,exports){ +},{"./lodash":39,"./util":58}],41:[function(require,module,exports){ "use strict"; var _ = require("./lodash"), @@ -12087,7 +11769,7 @@ function undo(g) { }); } -},{"./lodash":42,"./util":61}],45:[function(require,module,exports){ +},{"./lodash":39,"./util":58}],42:[function(require,module,exports){ var _ = require("../lodash"); module.exports = addSubgraphConstraints; @@ -12142,7 +11824,7 @@ function addSubgraphConstraints(g, cg, vs) { */ } -},{"../lodash":42}],46:[function(require,module,exports){ +},{"../lodash":39}],43:[function(require,module,exports){ var _ = require("../lodash"); module.exports = barycenter; @@ -12172,7 +11854,7 @@ function barycenter(g, movable) { } -},{"../lodash":42}],47:[function(require,module,exports){ +},{"../lodash":39}],44:[function(require,module,exports){ var _ = require("../lodash"), Graph = require("../graphlib").Graph; @@ -12247,7 +11929,7 @@ function createRootNode(g) { return v; } -},{"../graphlib":39,"../lodash":42}],48:[function(require,module,exports){ +},{"../graphlib":36,"../lodash":39}],45:[function(require,module,exports){ "use strict"; var _ = require("../lodash"); @@ -12319,7 +12001,7 @@ function twoLayerCrossCount(g, northLayer, southLayer) { return cc; } -},{"../lodash":42}],49:[function(require,module,exports){ +},{"../lodash":39}],46:[function(require,module,exports){ "use strict"; var _ = require("../lodash"), @@ -12400,7 +12082,7 @@ function assignOrder(g, layering) { }); } -},{"../graphlib":39,"../lodash":42,"../util":61,"./add-subgraph-constraints":45,"./build-layer-graph":47,"./cross-count":48,"./init-order":50,"./sort-subgraph":52}],50:[function(require,module,exports){ +},{"../graphlib":36,"../lodash":39,"../util":58,"./add-subgraph-constraints":42,"./build-layer-graph":44,"./cross-count":45,"./init-order":47,"./sort-subgraph":49}],47:[function(require,module,exports){ "use strict"; var _ = require("../lodash"); @@ -12440,7 +12122,7 @@ function initOrder(g) { return layers; } -},{"../lodash":42}],51:[function(require,module,exports){ +},{"../lodash":39}],48:[function(require,module,exports){ "use strict"; var _ = require("../lodash"); @@ -12565,7 +12247,7 @@ function mergeEntries(target, source) { source.merged = true; } -},{"../lodash":42}],52:[function(require,module,exports){ +},{"../lodash":39}],49:[function(require,module,exports){ var _ = require("../lodash"), barycenter = require("./barycenter"), resolveConflicts = require("./resolve-conflicts"), @@ -12643,7 +12325,7 @@ function mergeBarycenters(target, other) { } } -},{"../lodash":42,"./barycenter":46,"./resolve-conflicts":51,"./sort":53}],53:[function(require,module,exports){ +},{"../lodash":39,"./barycenter":43,"./resolve-conflicts":48,"./sort":50}],50:[function(require,module,exports){ var _ = require("../lodash"), util = require("../util"); @@ -12702,7 +12384,7 @@ function compareWithBias(bias) { }; } -},{"../lodash":42,"../util":61}],54:[function(require,module,exports){ +},{"../lodash":39,"../util":58}],51:[function(require,module,exports){ var _ = require("./lodash"); module.exports = parentDummyChains; @@ -12790,7 +12472,7 @@ function postorder(g) { return result; } -},{"./lodash":42}],55:[function(require,module,exports){ +},{"./lodash":39}],52:[function(require,module,exports){ "use strict"; var _ = require("../lodash"), @@ -13190,7 +12872,7 @@ function width(g, v) { return g.node(v).width; } -},{"../graphlib":39,"../lodash":42,"../util":61}],56:[function(require,module,exports){ +},{"../graphlib":36,"../lodash":39,"../util":58}],53:[function(require,module,exports){ "use strict"; var _ = require("../lodash"), @@ -13222,7 +12904,7 @@ function positionY(g) { } -},{"../lodash":42,"../util":61,"./bk":55}],57:[function(require,module,exports){ +},{"../lodash":39,"../util":58,"./bk":52}],54:[function(require,module,exports){ "use strict"; var _ = require("../lodash"), @@ -13313,7 +12995,7 @@ function shiftRanks(t, g, delta) { }); } -},{"../graphlib":39,"../lodash":42,"./util":60}],58:[function(require,module,exports){ +},{"../graphlib":36,"../lodash":39,"./util":57}],55:[function(require,module,exports){ "use strict"; var rankUtil = require("./util"), @@ -13363,7 +13045,7 @@ function networkSimplexRanker(g) { networkSimplex(g); } -},{"./feasible-tree":57,"./network-simplex":59,"./util":60}],59:[function(require,module,exports){ +},{"./feasible-tree":54,"./network-simplex":56,"./util":57}],56:[function(require,module,exports){ "use strict"; var _ = require("../lodash"), @@ -13599,7 +13281,7 @@ function isDescendant(tree, vLabel, rootLabel) { return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; } -},{"../graphlib":39,"../lodash":42,"../util":61,"./feasible-tree":57,"./util":60}],60:[function(require,module,exports){ +},{"../graphlib":36,"../lodash":39,"../util":58,"./feasible-tree":54,"./util":57}],57:[function(require,module,exports){ "use strict"; var _ = require("../lodash"); @@ -13662,7 +13344,7 @@ function slack(g, e) { return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; } -},{"../lodash":42}],61:[function(require,module,exports){ +},{"../lodash":39}],58:[function(require,module,exports){ "use strict"; var _ = require("./lodash"), @@ -13900,10 +13582,10 @@ function notime(name, fn) { return fn(); } -},{"./graphlib":39,"./lodash":42}],62:[function(require,module,exports){ +},{"./graphlib":36,"./lodash":39}],59:[function(require,module,exports){ module.exports = "0.7.4"; -},{}],63:[function(require,module,exports){ +},{}],60:[function(require,module,exports){ /** * Copyright (c) 2014, Chris Pettitt * All rights reserved. @@ -13943,7 +13625,7 @@ module.exports = { version: lib.version }; -},{"./lib":79,"./lib/alg":70,"./lib/json":80}],64:[function(require,module,exports){ +},{"./lib":76,"./lib/alg":67,"./lib/json":77}],61:[function(require,module,exports){ var _ = require("../lodash"); module.exports = components; @@ -13972,7 +13654,7 @@ function components(g) { return cmpts; } -},{"../lodash":81}],65:[function(require,module,exports){ +},{"../lodash":78}],62:[function(require,module,exports){ var _ = require("../lodash"); module.exports = dfs; @@ -14013,7 +13695,7 @@ function doDfs(g, v, postorder, visited, acc) { } } -},{"../lodash":81}],66:[function(require,module,exports){ +},{"../lodash":78}],63:[function(require,module,exports){ var dijkstra = require("./dijkstra"), _ = require("../lodash"); @@ -14025,7 +13707,7 @@ function dijkstraAll(g, weightFunc, edgeFunc) { }, {}); } -},{"../lodash":81,"./dijkstra":67}],67:[function(require,module,exports){ +},{"../lodash":78,"./dijkstra":64}],64:[function(require,module,exports){ var _ = require("../lodash"), PriorityQueue = require("../data/priority-queue"); @@ -14081,7 +13763,7 @@ function runDijkstra(g, source, weightFn, edgeFn) { return results; } -},{"../data/priority-queue":77,"../lodash":81}],68:[function(require,module,exports){ +},{"../data/priority-queue":74,"../lodash":78}],65:[function(require,module,exports){ var _ = require("../lodash"), tarjan = require("./tarjan"); @@ -14093,7 +13775,7 @@ function findCycles(g) { }); } -},{"../lodash":81,"./tarjan":75}],69:[function(require,module,exports){ +},{"../lodash":78,"./tarjan":72}],66:[function(require,module,exports){ var _ = require("../lodash"); module.exports = floydWarshall; @@ -14145,7 +13827,7 @@ function runFloydWarshall(g, weightFn, edgeFn) { return results; } -},{"../lodash":81}],70:[function(require,module,exports){ +},{"../lodash":78}],67:[function(require,module,exports){ module.exports = { components: require("./components"), dijkstra: require("./dijkstra"), @@ -14160,7 +13842,7 @@ module.exports = { topsort: require("./topsort") }; -},{"./components":64,"./dijkstra":67,"./dijkstra-all":66,"./find-cycles":68,"./floyd-warshall":69,"./is-acyclic":71,"./postorder":72,"./preorder":73,"./prim":74,"./tarjan":75,"./topsort":76}],71:[function(require,module,exports){ +},{"./components":61,"./dijkstra":64,"./dijkstra-all":63,"./find-cycles":65,"./floyd-warshall":66,"./is-acyclic":68,"./postorder":69,"./preorder":70,"./prim":71,"./tarjan":72,"./topsort":73}],68:[function(require,module,exports){ var topsort = require("./topsort"); module.exports = isAcyclic; @@ -14177,7 +13859,7 @@ function isAcyclic(g) { return true; } -},{"./topsort":76}],72:[function(require,module,exports){ +},{"./topsort":73}],69:[function(require,module,exports){ var dfs = require("./dfs"); module.exports = postorder; @@ -14186,7 +13868,7 @@ function postorder(g, vs) { return dfs(g, vs, "post"); } -},{"./dfs":65}],73:[function(require,module,exports){ +},{"./dfs":62}],70:[function(require,module,exports){ var dfs = require("./dfs"); module.exports = preorder; @@ -14195,7 +13877,7 @@ function preorder(g, vs) { return dfs(g, vs, "pre"); } -},{"./dfs":65}],74:[function(require,module,exports){ +},{"./dfs":62}],71:[function(require,module,exports){ var _ = require("../lodash"), Graph = require("../graph"), PriorityQueue = require("../data/priority-queue"); @@ -14249,7 +13931,7 @@ function prim(g, weightFunc) { return result; } -},{"../data/priority-queue":77,"../graph":78,"../lodash":81}],75:[function(require,module,exports){ +},{"../data/priority-queue":74,"../graph":75,"../lodash":78}],72:[function(require,module,exports){ var _ = require("../lodash"); module.exports = tarjan; @@ -14298,7 +13980,7 @@ function tarjan(g) { return results; } -},{"../lodash":81}],76:[function(require,module,exports){ +},{"../lodash":78}],73:[function(require,module,exports){ var _ = require("../lodash"); module.exports = topsort; @@ -14334,7 +14016,7 @@ function topsort(g) { function CycleException() {} -},{"../lodash":81}],77:[function(require,module,exports){ +},{"../lodash":78}],74:[function(require,module,exports){ var _ = require("../lodash"); module.exports = PriorityQueue; @@ -14488,7 +14170,7 @@ PriorityQueue.prototype._swap = function(i, j) { keyIndices[origArrI.key] = j; }; -},{"../lodash":81}],78:[function(require,module,exports){ +},{"../lodash":78}],75:[function(require,module,exports){ "use strict"; var _ = require("./lodash"); @@ -15009,14 +14691,14 @@ function edgeObjToId(isDirected, edgeObj) { return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); } -},{"./lodash":81}],79:[function(require,module,exports){ +},{"./lodash":78}],76:[function(require,module,exports){ // Includes only the "core" of graphlib module.exports = { Graph: require("./graph"), version: require("./version") }; -},{"./graph":78,"./version":82}],80:[function(require,module,exports){ +},{"./graph":75,"./version":79}],77:[function(require,module,exports){ var _ = require("./lodash"), Graph = require("./graph"); @@ -15084,12 +14766,12 @@ function read(json) { return g; } -},{"./graph":78,"./lodash":81}],81:[function(require,module,exports){ -module.exports=require(42) -},{"/Users/knut/Documents/source/mermaid/node_modules/dagre-d3/node_modules/dagre/lib/lodash.js":42,"lodash":83}],82:[function(require,module,exports){ +},{"./graph":75,"./lodash":78}],78:[function(require,module,exports){ +arguments[4][39][0].apply(exports,arguments) +},{"dup":39,"lodash":80}],79:[function(require,module,exports){ module.exports = '1.0.7'; -},{}],83:[function(require,module,exports){ +},{}],80:[function(require,module,exports){ (function (global){ /** * @license @@ -27444,7 +27126,109 @@ module.exports = '1.0.7'; }.call(this)); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],84:[function(require,module,exports){ +},{}],81:[function(require,module,exports){ +arguments[4][30][0].apply(exports,arguments) +},{"./lib/debug":86,"./lib/graphlib":87,"./lib/layout":89,"./lib/util":109,"./lib/version":110,"dup":30}],82:[function(require,module,exports){ +arguments[4][31][0].apply(exports,arguments) +},{"./greedy-fas":88,"./lodash":90,"dup":31}],83:[function(require,module,exports){ +arguments[4][32][0].apply(exports,arguments) +},{"./lodash":90,"./util":109,"dup":32}],84:[function(require,module,exports){ +arguments[4][33][0].apply(exports,arguments) +},{"./lodash":90,"dup":33}],85:[function(require,module,exports){ +arguments[4][34][0].apply(exports,arguments) +},{"dup":34}],86:[function(require,module,exports){ +arguments[4][35][0].apply(exports,arguments) +},{"./graphlib":87,"./lodash":90,"./util":109,"dup":35}],87:[function(require,module,exports){ +arguments[4][36][0].apply(exports,arguments) +},{"dup":36,"graphlib":111}],88:[function(require,module,exports){ +arguments[4][37][0].apply(exports,arguments) +},{"./data/list":85,"./graphlib":87,"./lodash":90,"dup":37}],89:[function(require,module,exports){ +arguments[4][38][0].apply(exports,arguments) +},{"./acyclic":82,"./add-border-segments":83,"./coordinate-system":84,"./graphlib":87,"./lodash":90,"./nesting-graph":91,"./normalize":92,"./order":97,"./parent-dummy-chains":102,"./position":104,"./rank":106,"./util":109,"dup":38}],90:[function(require,module,exports){ +arguments[4][39][0].apply(exports,arguments) +},{"dup":39,"lodash":131}],91:[function(require,module,exports){ +arguments[4][40][0].apply(exports,arguments) +},{"./lodash":90,"./util":109,"dup":40}],92:[function(require,module,exports){ +arguments[4][41][0].apply(exports,arguments) +},{"./lodash":90,"./util":109,"dup":41}],93:[function(require,module,exports){ +arguments[4][42][0].apply(exports,arguments) +},{"../lodash":90,"dup":42}],94:[function(require,module,exports){ +arguments[4][43][0].apply(exports,arguments) +},{"../lodash":90,"dup":43}],95:[function(require,module,exports){ +arguments[4][44][0].apply(exports,arguments) +},{"../graphlib":87,"../lodash":90,"dup":44}],96:[function(require,module,exports){ +arguments[4][45][0].apply(exports,arguments) +},{"../lodash":90,"dup":45}],97:[function(require,module,exports){ +arguments[4][46][0].apply(exports,arguments) +},{"../graphlib":87,"../lodash":90,"../util":109,"./add-subgraph-constraints":93,"./build-layer-graph":95,"./cross-count":96,"./init-order":98,"./sort-subgraph":100,"dup":46}],98:[function(require,module,exports){ +arguments[4][47][0].apply(exports,arguments) +},{"../lodash":90,"dup":47}],99:[function(require,module,exports){ +arguments[4][48][0].apply(exports,arguments) +},{"../lodash":90,"dup":48}],100:[function(require,module,exports){ +arguments[4][49][0].apply(exports,arguments) +},{"../lodash":90,"./barycenter":94,"./resolve-conflicts":99,"./sort":101,"dup":49}],101:[function(require,module,exports){ +arguments[4][50][0].apply(exports,arguments) +},{"../lodash":90,"../util":109,"dup":50}],102:[function(require,module,exports){ +arguments[4][51][0].apply(exports,arguments) +},{"./lodash":90,"dup":51}],103:[function(require,module,exports){ +arguments[4][52][0].apply(exports,arguments) +},{"../graphlib":87,"../lodash":90,"../util":109,"dup":52}],104:[function(require,module,exports){ +arguments[4][53][0].apply(exports,arguments) +},{"../lodash":90,"../util":109,"./bk":103,"dup":53}],105:[function(require,module,exports){ +arguments[4][54][0].apply(exports,arguments) +},{"../graphlib":87,"../lodash":90,"./util":108,"dup":54}],106:[function(require,module,exports){ +arguments[4][55][0].apply(exports,arguments) +},{"./feasible-tree":105,"./network-simplex":107,"./util":108,"dup":55}],107:[function(require,module,exports){ +arguments[4][56][0].apply(exports,arguments) +},{"../graphlib":87,"../lodash":90,"../util":109,"./feasible-tree":105,"./util":108,"dup":56}],108:[function(require,module,exports){ +arguments[4][57][0].apply(exports,arguments) +},{"../lodash":90,"dup":57}],109:[function(require,module,exports){ +arguments[4][58][0].apply(exports,arguments) +},{"./graphlib":87,"./lodash":90,"dup":58}],110:[function(require,module,exports){ +arguments[4][59][0].apply(exports,arguments) +},{"dup":59}],111:[function(require,module,exports){ +arguments[4][60][0].apply(exports,arguments) +},{"./lib":127,"./lib/alg":118,"./lib/json":128,"dup":60}],112:[function(require,module,exports){ +arguments[4][61][0].apply(exports,arguments) +},{"../lodash":129,"dup":61}],113:[function(require,module,exports){ +arguments[4][62][0].apply(exports,arguments) +},{"../lodash":129,"dup":62}],114:[function(require,module,exports){ +arguments[4][63][0].apply(exports,arguments) +},{"../lodash":129,"./dijkstra":115,"dup":63}],115:[function(require,module,exports){ +arguments[4][64][0].apply(exports,arguments) +},{"../data/priority-queue":125,"../lodash":129,"dup":64}],116:[function(require,module,exports){ +arguments[4][65][0].apply(exports,arguments) +},{"../lodash":129,"./tarjan":123,"dup":65}],117:[function(require,module,exports){ +arguments[4][66][0].apply(exports,arguments) +},{"../lodash":129,"dup":66}],118:[function(require,module,exports){ +arguments[4][67][0].apply(exports,arguments) +},{"./components":112,"./dijkstra":115,"./dijkstra-all":114,"./find-cycles":116,"./floyd-warshall":117,"./is-acyclic":119,"./postorder":120,"./preorder":121,"./prim":122,"./tarjan":123,"./topsort":124,"dup":67}],119:[function(require,module,exports){ +arguments[4][68][0].apply(exports,arguments) +},{"./topsort":124,"dup":68}],120:[function(require,module,exports){ +arguments[4][69][0].apply(exports,arguments) +},{"./dfs":113,"dup":69}],121:[function(require,module,exports){ +arguments[4][70][0].apply(exports,arguments) +},{"./dfs":113,"dup":70}],122:[function(require,module,exports){ +arguments[4][71][0].apply(exports,arguments) +},{"../data/priority-queue":125,"../graph":126,"../lodash":129,"dup":71}],123:[function(require,module,exports){ +arguments[4][72][0].apply(exports,arguments) +},{"../lodash":129,"dup":72}],124:[function(require,module,exports){ +arguments[4][73][0].apply(exports,arguments) +},{"../lodash":129,"dup":73}],125:[function(require,module,exports){ +arguments[4][74][0].apply(exports,arguments) +},{"../lodash":129,"dup":74}],126:[function(require,module,exports){ +arguments[4][75][0].apply(exports,arguments) +},{"./lodash":129,"dup":75}],127:[function(require,module,exports){ +arguments[4][76][0].apply(exports,arguments) +},{"./graph":126,"./version":130,"dup":76}],128:[function(require,module,exports){ +arguments[4][77][0].apply(exports,arguments) +},{"./graph":126,"./lodash":129,"dup":77}],129:[function(require,module,exports){ +arguments[4][39][0].apply(exports,arguments) +},{"dup":39,"lodash":131}],130:[function(require,module,exports){ +arguments[4][79][0].apply(exports,arguments) +},{"dup":79}],131:[function(require,module,exports){ +arguments[4][80][0].apply(exports,arguments) +},{"dup":80}],132:[function(require,module,exports){ (function (global){ /*! http://mths.be/he v0.5.0 by @mathias | MIT license */ ;(function(root) { @@ -27777,7 +27561,7 @@ module.exports = '1.0.7'; }(this)); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],85:[function(require,module,exports){ +},{}],133:[function(require,module,exports){ //! moment.js //! version : 2.10.6 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors @@ -30973,7 +30757,7 @@ module.exports = '1.0.7'; return _moment; })); -},{}],86:[function(require,module,exports){ +},{}],134:[function(require,module,exports){ module.exports={ "name": "mermaid", "version": "0.5.5", @@ -31014,6 +30798,7 @@ module.exports={ "dependencies": { "chalk": "^0.5.1", "d3": "~3.5.6", + "dagre": "^0.7.4", "dagre-d3": "~0.4.8", "he": "^0.5.0", "minimist": "^1.1.0", @@ -31086,7 +30871,7 @@ module.exports={ } } -},{}],87:[function(require,module,exports){ +},{}],135:[function(require,module,exports){ /* global window */ //log.debug('Setting up d3'); 'use strict'; @@ -31557,7 +31342,1139 @@ module.exports = d3; })(); /* jshint ignore:end */ -},{"d3":4}],88:[function(require,module,exports){ +},{"d3":1}],136:[function(require,module,exports){ +'use strict'; + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +var _logger = require('../../logger'); + +var Logger = _interopRequireWildcard(_logger); + +var log = new Logger.Log(); + +var relations = []; +var classes = new Map(); + +// Functions to be run after graph rendering +var funs = []; +/** + * Function called by parser when a node definition has been found + * @param id + * @param text + * @param type + * @param style + */ +exports.addClass = function (id) { + console.log('Adding: ' + id); + if (typeof classes.get(id) === 'undefined') { + classes.set(id, { + id: id, + methods: [] + }); + } +}; + +exports.clear = function () { + relations = []; + classes.clear(); +}; + +module.exports.getClass = function (id) { + return classes.get(id); +}; +module.exports.getClasses = function (id) { + return classes; +}; + +module.exports.getRelations = function () { + return relations; +}; + +exports.addRelation = function (relation) { + console.log('Adding relation: ' + JSON.stringify(relation)); + exports.addClass(relation.id1); + exports.addClass(relation.id2); + + relations.push(relation); +}; + +exports.addMembers = function (className, MembersArr) {}; + +exports.lineType = { + LINE: 0, + DOTTED_LINE: 1 +}; + +exports.relationType = { + AGGREGATION: 0, + EXTENSION: 1, + COMPOSITION: 2, + DEPENDENCY: 3 +}; + +},{"../../logger":154}],137:[function(require,module,exports){ +/** + * Created by knut on 14-11-23. + */ + +'use strict'; + +var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +var _logger = require('../../logger'); + +var Logger = _interopRequireWildcard(_logger); + +var _dagre = require('dagre'); + +var dagre = _interopRequireWildcard(_dagre); + +var cd = require('./parser/classDiagram').parser; +var cDDb = require('./classDb'); +cd.yy = cDDb; +var d3 = require('../../d3'); + +var log = new Logger.Log(); + +var idCache = new Map(); +var classCnt = 0; +var conf = {}; + +// Todo optimize +var getGraphId = function getGraphId(label) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = idCache[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var _step$value = _slicedToArray(_step.value, 2); + + var id = _step$value[0]; + var classInfo = _step$value[1]; + + if (classInfo.label === label) { + return id; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator['return']) { + _iterator['return'](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return undefined; +}; + +var drawEdge = function drawEdge(elem, path) { + //The data for our line + var lineData = path.points; + + //This is the accessor function we talked about above + var lineFunction = d3.svg.line().x(function (d) { + return d.x; + }).y(function (d) { + return d.y; + }).interpolate('linear'); + + elem.append('path').attr('d', lineFunction(lineData)).attr('stroke', 'black').attr('stroke-width', 1).attr('fill', 'none'); +}; + +var drawClass = function drawClass(elem, classDef) { + log.info('Rendering class ' + classDef); + //var rect = svgDraw.getNoteRect(); + //rect.x = startx; + //rect.y = verticalPos; + //rect.width = conf.width; + //rect.class = 'note'; + // + //var g = elem.append('g'); + //var rectElem = svgDraw.drawRect(g, rect); + // + //var textObj = svgDraw.getTextObj(); + //textObj.x = startx-4; + //textObj.y = verticalPos-13; + //textObj.textMargin = conf.noteMargin; + //textObj.dy = '1em'; + //textObj.text = msg.message; + //textObj.class = 'noteText'; + // + //var textElem = svgDraw.drawText(g,textObj, conf.width-conf.noteMargin); + // + //var textHeight = textElem[0][0].getBBox().height; + //if(textHeight > conf.width){ + // textElem.remove(); + // g = elem.append('g'); + // + // //textObj.x = textObj.x - conf.width; + // //textElem = svgDraw.drawText(g,textObj, 2*conf.noteMargin); + // textElem = svgDraw.drawText(g,textObj, 2*conf.width-conf.noteMargin); + // textHeight = textElem[0][0].getBBox().height; + // rectElem.attr('width',2*conf.width); + // exports.bounds.insert(startx, verticalPos, startx + 2*conf.width, verticalPos + 2*conf.noteMargin + textHeight); + //}else{ + // exports.bounds.insert(startx, verticalPos, startx + conf.width, verticalPos + 2*conf.noteMargin + textHeight); + //} + // + //rectElem.attr('height',textHeight+ 2*conf.noteMargin); + //exports.bounds.bumpVerticalPos(textHeight+ 2*conf.noteMargin); + var id = 'classId' + classCnt; + var classInfo = { + id: id, + label: classDef.id, + width: 0, + height: 0 + }; + + var g = elem.append('g').attr('id', id); + var textElem = g.append('text') // text label for the x axis + .attr('x', '10').attr('y', '17').attr('fill', 'white').attr('class', 'classText').text(classDef.id); + var box = textElem.node().getBBox(); + + g.insert('rect', ':first-child').attr('x', 0).attr('y', 0).attr('fill', 'darkgrey').attr('width', box.width + 20).attr('height', box.height + 10); + + classInfo.width = box.width + 20; + classInfo.height = box.height + 10; + + idCache.set(id, classInfo); + classCnt++; + return classInfo; +}; + +module.exports.setConf = function (cnf) { + var keys = Object.keys(cnf); + + keys.forEach(function (key) { + conf[key] = cnf[key]; + }); +}; +/** + * Draws a flowchart in the tag with id: id based on the graph definition in text. + * @param text + * @param id + */ +module.exports.draw = function (text, id) { + cd.yy.clear(); + cd.parse(text); + + log.info('Rendering diagram ' + text); + + //// Fetch the default direction, use TD if none was found + var diagram = d3.select('#' + id); + //var svg = diagram.append('svg'); + + // Layout graph, Create a new directed graph + var g = new dagre.graphlib.Graph(); + + // Set an object for the graph label + g.setGraph({}); + + // Default to assigning a new object as a label for each new edge. + g.setDefaultEdgeLabel(function () { + return {}; + }); + + var classes = cDDb.getClasses(); + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = classes.values()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var classDef = _step2.value; + + var node = drawClass(diagram, classDef); + // Add nodes to the graph. The first argument is the node id. The second is + // metadata about the node. In this case we're going to add labels to each of + // our nodes. + g.setNode(node.id, node); + log.info('Org height: ' + node.height); + //g.setNode("swilliams", { label: "Saul Williams", width: 160, height: 100 }); + //g.setNode("bpitt", { label: "Brad Pitt", width: 108, height: 100 }); + //g.setNode("hford", { label: "Harrison Ford", width: 168, height: 100 }); + //g.setNode("lwilson", { label: "Luke Wilson", width: 144, height: 100 }); + //g.setNode("kbacon", { label: "Kevin Bacon", width: 121, height: 100 }); + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2['return']) { + _iterator2['return'](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + var relations = cDDb.getRelations(); + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = relations[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var relation = _step3.value; + + g.setEdge(getGraphId(relation.id1), getGraphId(relation.id2)); + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3['return']) { + _iterator3['return'](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + dagre.layout(g); + g.nodes().forEach(function (v) { + log.debug('Node ' + v + ': ' + JSON.stringify(g.node(v))); + d3.select('#' + v).attr('transform', 'translate(' + (g.node(v).x - g.node(v).width / 2) + ',' + (g.node(v).y - g.node(v).height / 2) + ' )'); + //d3.select('#' +v +' rect').attr('x',(g.node(v).x-(g.node(v).width/2))) + //.attr('y',(g.node(v).y-(g.node(v).height/2))); + }); + g.edges().forEach(function (e) { + log.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(g.edge(e))); + drawEdge(diagram, g.edge(e)); + }); + + // + diagram.attr('height', '100%'); + diagram.attr('width', '100%'); + // + // + // + // + //if(conf.useMaxWidth) { + // diagram.attr('height', '100%'); + // diagram.attr('width', '100%'); + // diagram.attr('style', 'max-width:' + (width) + 'px;'); + //}else{ + // diagram.attr('height',height); + // diagram.attr('width', width ); + //} + //diagram.attr('viewBox', (box.startx-conf.diagramMarginX) + ' -' +conf.diagramMarginY + ' ' + width + ' ' + height); +}; + +},{"../../d3":135,"../../logger":154,"./classDb":136,"./parser/classDiagram":138,"dagre":81}],138:[function(require,module,exports){ +(function (process){ +/* parser generated by jison 0.4.15 */ +/* + Returns a Parser object of the following structure: + + Parser: { + yy: {} + } + + Parser.prototype: { + yy: {}, + trace: function(), + symbols_: {associative list: name ==> number}, + terminals_: {associative list: number ==> name}, + productions_: [...], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$), + table: [...], + defaultActions: {...}, + parseError: function(str, hash), + parse: function(input), + + lexer: { + EOF: 1, + parseError: function(str, hash), + setInput: function(input), + input: function(), + unput: function(str), + more: function(), + less: function(n), + pastInput: function(), + upcomingInput: function(), + showPosition: function(), + test_match: function(regex_match_array, rule_index), + next: function(), + lex: function(), + begin: function(condition), + popState: function(), + _currentRules: function(), + topState: function(), + pushState: function(condition), + + options: { + ranges: boolean (optional: true ==> token location info will include a .range[] member) + flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match) + backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code) + }, + + performAction: function(yy, yy_, $avoiding_name_collisions, YY_START), + rules: [...], + conditions: {associative list: name ==> set}, + } + } + + + token location info (@$, _$, etc.): { + first_line: n, + last_line: n, + first_column: n, + last_column: n, + range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based) + } + + + the parseError function receives a 'hash' object with these members for lexer and parser errors: { + text: (matched text) + token: (the produced terminal token, if any) + line: (yylineno) + } + while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: { + loc: (yylloc) + expected: (string describing the set of expected tokens) + recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) + } +*/ +"use strict"; + +var classDiagram = (function () { + var o = function o(k, v, _o, l) { + for (_o = _o || {}, l = k.length; l--; _o[k[l]] = v);return _o; + }, + $V0 = [1, 11], + $V1 = [1, 12], + $V2 = [1, 13], + $V3 = [1, 15], + $V4 = [1, 16], + $V5 = [1, 17], + $V6 = [6, 8], + $V7 = [1, 26], + $V8 = [1, 27], + $V9 = [1, 28], + $Va = [1, 29], + $Vb = [1, 30], + $Vc = [1, 31], + $Vd = [6, 8, 13, 17, 23, 26, 27, 28, 29, 30, 31], + $Ve = [6, 8, 13, 17, 23, 26, 27, 28, 29, 30, 31, 45, 46, 47], + $Vf = [23, 45, 46, 47], + $Vg = [23, 30, 31, 45, 46, 47], + $Vh = [23, 26, 27, 28, 29, 45, 46, 47], + $Vi = [6, 8, 13], + $Vj = [1, 46]; + var parser = { trace: function trace() {}, + yy: {}, + symbols_: { "error": 2, "mermaidDoc": 3, "graphConfig": 4, "CLASS_DIAGRAM": 5, "NEWLINE": 6, "statements": 7, "EOF": 8, "statement": 9, "className": 10, "alphaNumToken": 11, "relationStatement": 12, "LABEL": 13, "classStatement": 14, "methodStatement": 15, "CLASS": 16, "STRUCT_START": 17, "members": 18, "STRUCT_STOP": 19, "MEMBER": 20, "SEPARATOR": 21, "relation": 22, "STR": 23, "relationType": 24, "lineType": 25, "AGGREGATION": 26, "EXTENSION": 27, "COMPOSITION": 28, "DEPENDENCY": 29, "LINE": 30, "DOTTED_LINE": 31, "commentToken": 32, "textToken": 33, "graphCodeTokens": 34, "textNoTagsToken": 35, "TAGSTART": 36, "TAGEND": 37, "==": 38, "--": 39, "PCT": 40, "DEFAULT": 41, "SPACE": 42, "MINUS": 43, "keywords": 44, "UNICODE_TEXT": 45, "NUM": 46, "ALPHA": 47, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 5: "CLASS_DIAGRAM", 6: "NEWLINE", 8: "EOF", 13: "LABEL", 16: "CLASS", 17: "STRUCT_START", 19: "STRUCT_STOP", 20: "MEMBER", 21: "SEPARATOR", 23: "STR", 26: "AGGREGATION", 27: "EXTENSION", 28: "COMPOSITION", 29: "DEPENDENCY", 30: "LINE", 31: "DOTTED_LINE", 34: "graphCodeTokens", 36: "TAGSTART", 37: "TAGEND", 38: "==", 39: "--", 40: "PCT", 41: "DEFAULT", 42: "SPACE", 43: "MINUS", 44: "keywords", 45: "UNICODE_TEXT", 46: "NUM", 47: "ALPHA" }, + productions_: [0, [3, 1], [4, 4], [7, 1], [7, 3], [10, 2], [10, 1], [9, 1], [9, 2], [9, 1], [9, 1], [14, 2], [14, 5], [18, 1], [18, 2], [15, 1], [15, 2], [15, 1], [15, 1], [12, 3], [12, 4], [12, 4], [12, 5], [22, 3], [22, 2], [22, 2], [22, 1], [24, 1], [24, 1], [24, 1], [24, 1], [25, 1], [25, 1], [32, 1], [32, 1], [33, 1], [33, 1], [33, 1], [33, 1], [33, 1], [33, 1], [33, 1], [35, 1], [35, 1], [35, 1], [35, 1], [11, 1], [11, 1], [11, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, /* action[1] */$$, /* vstack */_$ /* lstack */) { + /* this == yyval */ + + var $0 = $$.length - 1; + switch (yystate) { + case 5: + this.$ = $$[$0 - 1] + $$[$0]; + break; + case 6: + this.$ = $$[$0]; + break; + case 7: + yy.addRelation($$[$0]); + break; + case 8: + $$[$0 - 1].title = $$[$0];yy.addRelation($$[$0 - 1]); + break; + case 12: + /*console.log($$[$0-3],JSON.stringify($$[$0-1]));*/yy.addMembers($$[$0 - 3], $$[$0 - 1]); + break; + case 13: + this.$ = [$$[$0]]; + break; + case 14: + $$[$0].push($$[$0 - 1]);this.$ = $$[$0]; + break; + case 15: + /*console.log('Rel found',$$[$0]);*/ + break; + case 18: + /*console.log('sep found',$$[$0]);*/ + break; + case 19: + this.$ = { 'id1': $$[$0 - 2], 'id2': $$[$0], relation: $$[$0 - 1], relationTitle1: 'none', relationTitle2: 'none' }; + break; + case 20: + this.$ = { id1: $$[$0 - 3], id2: $$[$0], relation: $$[$0 - 1], relationTitle1: $$[$0 - 2], relationTitle2: 'none' }; + break; + case 21: + this.$ = { id1: $$[$0 - 3], id2: $$[$0], relation: $$[$0 - 2], relationTitle1: 'none', relationTitle2: $$[$0 - 1] }; + break; + case 22: + this.$ = { id1: $$[$0 - 4], id2: $$[$0], relation: $$[$0 - 2], relationTitle1: $$[$0 - 3], relationTitle2: $$[$0 - 1] }; + break; + case 23: + this.$ = { type1: $$[$0 - 2], type2: $$[$0], lineType: $$[$0 - 1] }; + break; + case 24: + this.$ = { type1: 'none', type2: $$[$0], lineType: $$[$0 - 1] }; + break; + case 25: + this.$ = { type1: $$[$0 - 1], type2: 'none', lineType: $$[$0] }; + break; + case 26: + this.$ = { type1: 'none', type2: 'none', lineType: $$[$0] }; + break; + case 27: + this.$ = yy.relationType.AGGREGATION; + break; + case 28: + this.$ = yy.relationType.EXTENSION; + break; + case 29: + this.$ = yy.relationType.COMPOSITION; + break; + case 30: + this.$ = yy.relationType.DEPENDENCY; + break; + case 31: + this.$ = yy.lineType.LINE; + break; + case 32: + this.$ = yy.lineType.DOTTED_LINE; + break; + } + }, + table: [{ 3: 1, 4: 2, 5: [1, 3] }, { 1: [3] }, { 1: [2, 1] }, { 6: [1, 4] }, { 7: 5, 9: 6, 10: 10, 11: 14, 12: 7, 14: 8, 15: 9, 16: $V0, 20: $V1, 21: $V2, 45: $V3, 46: $V4, 47: $V5 }, { 8: [1, 18] }, { 6: [1, 19], 8: [2, 3] }, o($V6, [2, 7], { 13: [1, 20] }), o($V6, [2, 9]), o($V6, [2, 10]), o($V6, [2, 15], { 22: 21, 24: 24, 25: 25, 13: [1, 23], 23: [1, 22], 26: $V7, 27: $V8, 28: $V9, 29: $Va, 30: $Vb, 31: $Vc }), { 10: 32, 11: 14, 45: $V3, 46: $V4, 47: $V5 }, o($V6, [2, 17]), o($V6, [2, 18]), o($Vd, [2, 6], { 11: 14, 10: 33, 45: $V3, 46: $V4, 47: $V5 }), o($Ve, [2, 46]), o($Ve, [2, 47]), o($Ve, [2, 48]), { 1: [2, 2] }, { 7: 34, 9: 6, 10: 10, 11: 14, 12: 7, 14: 8, 15: 9, 16: $V0, 20: $V1, 21: $V2, 45: $V3, 46: $V4, 47: $V5 }, o($V6, [2, 8]), { 10: 35, 11: 14, 23: [1, 36], 45: $V3, 46: $V4, 47: $V5 }, { 22: 37, 24: 24, 25: 25, 26: $V7, 27: $V8, 28: $V9, 29: $Va, 30: $Vb, 31: $Vc }, o($V6, [2, 16]), { 25: 38, 30: $Vb, 31: $Vc }, o($Vf, [2, 26], { 24: 39, 26: $V7, 27: $V8, 28: $V9, 29: $Va }), o($Vg, [2, 27]), o($Vg, [2, 28]), o($Vg, [2, 29]), o($Vg, [2, 30]), o($Vh, [2, 31]), o($Vh, [2, 32]), o($V6, [2, 11], { 17: [1, 40] }), o($Vd, [2, 5]), { 8: [2, 4] }, o($Vi, [2, 19]), { 10: 41, 11: 14, 45: $V3, 46: $V4, 47: $V5 }, { 10: 42, 11: 14, 23: [1, 43], 45: $V3, 46: $V4, 47: $V5 }, o($Vf, [2, 25], { 24: 44, 26: $V7, 27: $V8, 28: $V9, 29: $Va }), o($Vf, [2, 24]), { 18: 45, 20: $Vj }, o($Vi, [2, 21]), o($Vi, [2, 20]), { 10: 47, 11: 14, 45: $V3, 46: $V4, 47: $V5 }, o($Vf, [2, 23]), { 19: [1, 48] }, { 18: 49, 19: [2, 13], 20: $Vj }, o($Vi, [2, 22]), o($V6, [2, 12]), { 19: [2, 14] }], + defaultActions: { 2: [2, 1], 18: [2, 2], 34: [2, 4], 49: [2, 14] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var _parseError = function _parseError(msg, hash) { + this.message = msg; + this.hash = hash; + }; + + _parseError.prototype = new Error(); + + throw new _parseError(str, hash); + } + }, + parse: function parse(input) { + var self = this, + stack = [0], + tstack = [], + vstack = [null], + lstack = [], + table = this.table, + yytext = '', + yylineno = 0, + yyleng = 0, + recovering = 0, + TERROR = 2, + EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer; + sharedState.yy.parser = this; + if (typeof lexer.yylloc == 'undefined') { + lexer.yylloc = {}; + } + var yyloc = lexer.yylloc; + lstack.push(yyloc); + var ranges = lexer.options && lexer.options.ranges; + if (typeof sharedState.yy.parseError === 'function') { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function popStack(n) { + stack.length = stack.length - 2 * n; + vstack.length = vstack.length - n; + lstack.length = lstack.length - n; + } + _token_stack: var lex = function lex() { + var token; + token = lexer.lex() || EOF; + if (typeof token !== 'number') { + token = self.symbols_[token] || token; + } + return token; + }; + var symbol, + preErrorSymbol, + state, + action, + a, + r, + yyval = {}, + p, + len, + newState, + expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == 'undefined') { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === 'undefined' || !action.length || !action[0]) { + var errStr = ''; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push('\'' + this.terminals_[p] + '\''); + } + } + if (lexer.showPosition) { + errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; + } else { + errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); + } + this.parseError(errStr, { + text: lexer.match, + token: this.terminals_[symbol] || symbol, + line: lexer.yylineno, + loc: yyloc, + expected: expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer.yytext); + lstack.push(lexer.yylloc); + stack.push(action[1]); + symbol = null; + if (!preErrorSymbol) { + yyleng = lexer.yyleng; + yytext = lexer.yytext; + yylineno = lexer.yylineno; + yyloc = lexer.yylloc; + if (recovering > 0) { + recovering--; + } + } else { + symbol = preErrorSymbol; + preErrorSymbol = null; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]]; + } + r = this.performAction.apply(yyval, [yytext, yyleng, yylineno, sharedState.yy, action[1], vstack, lstack].concat(args)); + if (typeof r !== 'undefined') { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } }; + + /* generated by jison-lex 0.3.4 */ + var lexer = (function () { + var lexer = { + + EOF: 1, + + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + + // resets the lexer, sets new input + setInput: function setInput(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ''; + this.conditionStack = ['INITIAL']; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + + // consumes and returns one char from the input + input: function input() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + + this._input = this._input.slice(1); + return ch; + }, + + // unshifts one char (or a string) into the input + unput: function unput(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + //this.yyleng -= len; + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + + // When called from action, caches matched text and appends it on next action + more: function more() { + this._more = true; + return this; + }, + + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function reject() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + + // retain first n characters of the match + less: function less(n) { + this.unput(this.match.slice(n)); + }, + + // displays already matched input, i.e. for error messages + pastInput: function pastInput() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, ""); + }, + + // displays upcoming input, i.e. for error messages + upcomingInput: function upcomingInput() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); + }, + + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function showPosition() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function test_match(match, indexed_rule) { + var token, lines, backup; + + if (this.options.backtrack_lexer) { + // save context + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + // recover context + for (var k in backup) { + this[k] = backup[k]; + } + return false; // rule action called reject() implying the next rule should be tested instead. + } + return false; + }, + + // return next match in input + next: function next() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ''; + this.match = ''; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; // rule action called reject() implying a rule MISmatch. + } else { + // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: {}, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + var YYSTATE = YY_START; + switch ($avoiding_name_collisions) { + case 0: + /* do nothing */ + break; + case 1: + return 6; + break; + case 2: + /* skip whitespace */ + break; + case 3: + return 5; + break; + case 4: + this.begin("struct"); /*console.log('Starting struct');*/return 17; + break; + case 5: + /*console.log('Ending struct');*/this.popState();return 19; + break; + case 6: + /* nothing */ + break; + case 7: + /*console.log('lex-member: ' + yy_.yytext);*/return "MEMBER"; + break; + case 8: + return 16; + break; + case 9: + this.begin("string"); + break; + case 10: + this.popState(); + break; + case 11: + return "STR"; + break; + case 12: + return 27; + break; + case 13: + return 27; + break; + case 14: + return 29; + break; + case 15: + return 29; + break; + case 16: + return 28; + break; + case 17: + return 26; + break; + case 18: + return 30; + break; + case 19: + return 31; + break; + case 20: + return 13; + break; + case 21: + return 43; + break; + case 22: + return 'DOT'; + break; + case 23: + return 'PLUS'; + break; + case 24: + return 40; + break; + case 25: + return 'EQUALS'; + break; + case 26: + return 'EQUALS'; + break; + case 27: + return 47; + break; + case 28: + return 'PUNCTUATION'; + break; + case 29: + return 46; + break; + case 30: + return 45; + break; + case 31: + return 42; + break; + case 32: + return 8; + break; + } + }, + rules: [/^(?:%%[^\n]*)/, /^(?:\n+)/, /^(?:\s+)/, /^(?:classDiagram\b)/, /^(?:[\{])/, /^(?:\})/, /^(?:[\n])/, /^(?:[^\{\}\n]*)/, /^(?:class\b)/, /^(?:["])/, /^(?:["])/, /^(?:[^"]*)/, /^(?:\s*<\|)/, /^(?:\s*\|>)/, /^(?:\s*>)/, /^(?:\s*<)/, /^(?:\s*\*)/, /^(?:\s*o\b)/, /^(?:--)/, /^(?:\.\.)/, /^(?::[^#\n;]+)/, /^(?:-)/, /^(?:\.)/, /^(?:\+)/, /^(?:%)/, /^(?:=)/, /^(?:=)/, /^(?:[A-Za-z]+)/, /^(?:[!"#$%&'*+,-.`?\\_\/])/, /^(?:[0-9]+)/, /^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/, /^(?:\s)/, /^(?:$)/], + conditions: { "string": { "rules": [10, 11], "inclusive": false }, "struct": { "rules": [5, 6, 7], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 8, 9, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32], "inclusive": true } } + }; + return lexer; + })(); + parser.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser;parser.Parser = Parser; + return new Parser(); +})(); + +if (typeof require !== 'undefined' && typeof exports !== 'undefined') { + exports.parser = classDiagram; + exports.Parser = classDiagram.Parser; + exports.parse = function () { + return classDiagram.parse.apply(classDiagram, arguments); + }; + exports.main = function commonjsMain(args) { + if (!args[1]) { + console.log('Usage: ' + args[0] + ' FILE'); + process.exit(1); + } + var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8"); + return exports.parser.parse(source); + }; + if (typeof module !== 'undefined' && require.main === module) { + exports.main(process.argv.slice(1)); + } +} + +}).call(this,require('_process')) +},{"_process":159,"fs":157,"path":158}],139:[function(require,module,exports){ (function (global){ /** * Created by knut on 15-01-14. @@ -31597,7 +32514,7 @@ exports.parseError = function (err, hash) { }; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../../logger":103}],89:[function(require,module,exports){ +},{"../../logger":154}],140:[function(require,module,exports){ /** * Created by knut on 14-12-11. */ @@ -31646,7 +32563,7 @@ exports.draw = function (txt, id, ver) { //svg.attr('viewBox', '0 0 300 150'); }; -},{"../../d3":87,"../../logger":103,"./exampleDb":88,"./parser/example.js":90}],90:[function(require,module,exports){ +},{"../../d3":135,"../../logger":154,"./exampleDb":139,"./parser/example.js":141}],141:[function(require,module,exports){ (function (process){ /* parser generated by jison 0.4.15 */ /* @@ -32292,7 +33209,7 @@ if (typeof require !== 'undefined' && typeof exports !== 'undefined') { } }).call(this,require('_process')) -},{"_process":3,"fs":1,"path":2}],91:[function(require,module,exports){ +},{"_process":159,"fs":157,"path":158}],142:[function(require,module,exports){ /* global window */ 'use strict'; @@ -32321,7 +33238,7 @@ if (!dagreD3) { module.exports = dagreD3; -},{"../../logger":103,"dagre-d3":5}],92:[function(require,module,exports){ +},{"../../logger":154,"dagre-d3":2}],143:[function(require,module,exports){ /** * Created by knut on 14-12-11. */ @@ -32762,7 +33679,7 @@ exports.draw = function (text, id, isDot) { } }; -},{"../../d3":87,"../../logger":103,"./dagre-d3":91,"./graphDb":93,"./parser/dot":94,"./parser/flow":95}],93:[function(require,module,exports){ +},{"../../d3":135,"../../logger":154,"./dagre-d3":142,"./graphDb":144,"./parser/dot":145,"./parser/flow":146}],144:[function(require,module,exports){ (function (global){ /** * Created by knut on 14-11-03. @@ -33156,7 +34073,7 @@ exports.parseError = function (err, hash) { }; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../../d3":87,"../../logger":103}],94:[function(require,module,exports){ +},{"../../d3":135,"../../logger":154}],145:[function(require,module,exports){ (function (process){ /* parser generated by jison 0.4.15 */ /* @@ -33987,7 +34904,7 @@ if (typeof require !== 'undefined' && typeof exports !== 'undefined') { } }).call(this,require('_process')) -},{"_process":3,"fs":1,"path":2}],95:[function(require,module,exports){ +},{"_process":159,"fs":157,"path":158}],146:[function(require,module,exports){ (function (process){ /* parser generated by jison 0.4.15 */ /* @@ -35097,7 +36014,7 @@ if (typeof require !== 'undefined' && typeof exports !== 'undefined') { } }).call(this,require('_process')) -},{"_process":3,"fs":1,"path":2}],96:[function(require,module,exports){ +},{"_process":159,"fs":157,"path":158}],147:[function(require,module,exports){ (function (global){ /** * Created by knut on 15-01-14. @@ -35490,7 +36407,7 @@ exports.parseError = function (err, hash) { }; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../../logger":103,"moment":85}],97:[function(require,module,exports){ +},{"../../logger":154,"moment":133}],148:[function(require,module,exports){ 'use strict'; var gantt = require('./parser/gantt').parser; @@ -35844,7 +36761,7 @@ module.exports.draw = function (text, id) { } }; -},{"../../d3":87,"./ganttDb":96,"./parser/gantt":98,"moment":85}],98:[function(require,module,exports){ +},{"../../d3":135,"./ganttDb":147,"./parser/gantt":149,"moment":133}],149:[function(require,module,exports){ (function (process){ /* parser generated by jison 0.4.15 */ /* @@ -36527,7 +37444,7 @@ if (typeof require !== 'undefined' && typeof exports !== 'undefined') { } }).call(this,require('_process')) -},{"_process":3,"fs":1,"path":2}],99:[function(require,module,exports){ +},{"_process":159,"fs":157,"path":158}],150:[function(require,module,exports){ (function (process){ /* parser generated by jison 0.4.15 */ /* @@ -37329,7 +38246,7 @@ if (typeof require !== 'undefined' && typeof exports !== 'undefined') { } }).call(this,require('_process')) -},{"_process":3,"fs":1,"path":2}],100:[function(require,module,exports){ +},{"_process":159,"fs":157,"path":158}],151:[function(require,module,exports){ (function (global){ /** * Created by knut on 14-11-19. @@ -37473,7 +38390,7 @@ exports.apply = function (param) { }; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../../logger":103}],101:[function(require,module,exports){ +},{"../../logger":154}],152:[function(require,module,exports){ /** * Created by knut on 14-11-23. */ @@ -37871,7 +38788,7 @@ module.exports.draw = function (text, id) { diagram.attr('viewBox', box.startx - conf.diagramMarginX + ' -' + conf.diagramMarginY + ' ' + width + ' ' + height); }; -},{"../../d3":87,"../../logger":103,"./parser/sequenceDiagram":99,"./sequenceDb":100,"./svgDraw":102}],102:[function(require,module,exports){ +},{"../../d3":135,"../../logger":154,"./parser/sequenceDiagram":150,"./sequenceDb":151,"./svgDraw":153}],153:[function(require,module,exports){ /** * Created by knut on 14-12-20. */ @@ -38078,7 +38995,7 @@ exports.getNoteRect = function () { return rect; }; -},{}],103:[function(require,module,exports){ +},{}],154:[function(require,module,exports){ /** * #logger * logger = require('logger').create() @@ -38196,7 +39113,988 @@ var Log = (function () { exports.Log = Log; -},{}],104:[function(require,module,exports){ +},{}],155:[function(require,module,exports){ +(function (global){ +/** + * --- + * title: mermaidAPI + * order: 5 + * --- + * # mermaidAPI + * This is the api to be used when handling the integration with the web page instead of using the default integration + * (mermaid.js). + * + * The core of this api is the **render** function that given a graph definitionas text renders the graph/diagram and + * returns a svg element for the graph. It is is then up to the user of the API to make use of the svg, either insert it + * somewhere in the page or something completely different. + */ +'use strict'; + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +var _logger = require('./logger'); + +var Logger = _interopRequireWildcard(_logger); + +var log = new Logger.Log(); + +var graph = require('./diagrams/flowchart/graphDb'); +var utils = require('./utils'); +var flowRenderer = require('./diagrams/flowchart/flowRenderer'); +var seq = require('./diagrams/sequenceDiagram/sequenceRenderer'); +var info = require('./diagrams/example/exampleRenderer'); +var infoParser = require('./diagrams/example/parser/example'); +var flowParser = require('./diagrams/flowchart/parser/flow'); +var dotParser = require('./diagrams/flowchart/parser/dot'); +var sequenceParser = require('./diagrams/sequenceDiagram/parser/sequenceDiagram'); +var sequenceDb = require('./diagrams/sequenceDiagram/sequenceDb'); +var infoDb = require('./diagrams/example/exampleDb'); +var gantt = require('./diagrams/gantt/ganttRenderer'); +var ganttParser = require('./diagrams/gantt/parser/gantt'); +var ganttDb = require('./diagrams/gantt/ganttDb'); +var classParser = require('./diagrams/classDiagram/parser/classDiagram'); +var classRenderer = require('./diagrams/classDiagram/classRenderer'); +var classDb = require('./diagrams/classDiagram/classDb'); +var d3 = require('./d3'); + +/** + * ## Configuration + * These are the default options which can be overridden with the initialization call as in the example below: + * ``` + * mermaid.initialize({ + * flowchart:{ + * htmlLabels: false + * } + * }); + * ``` + */ +var config = { + /** + * logLevel , decides the amount of logging to be used. + * * debug: 1 + * * info: 2 + * * warn: 3 + * * error: 4 + * * fatal: 5 + */ + logLevel: 5, + /** + * **cloneCssStyles** - This options controls whether or not the css rules should be copied into the generated svg + */ + cloneCssStyles: true, + + /** + * **startOnLoad** - This options controls whether or mermaid starts when the page loads + */ + startOnLoad: true, + + /** + * ### flowchart + * *The object containing configurations specific for flowcharts* + */ + flowchart: { + /** + * **htmlLabels** - Flag for setting whether or not a html tag should be used for rendering labels + * on the edges + */ + htmlLabels: true, + /** + * **useMaxWidth** - Flag for setting whether or not a all available width should be used for + * the diagram. + */ + useMaxWidth: true + }, + + /** + * ### sequenceDiagram + * The object containing configurations specific for sequence diagrams + */ + sequenceDiagram: { + + /** + * **diagramMarginX** - margin to the right and left of the sequence diagram + */ + diagramMarginX: 50, + + /** + * **diagramMarginY** - margin to the over and under the sequence diagram + */ + diagramMarginY: 10, + + /** + * **actorMargin** - Margin between actors + */ + actorMargin: 50, + + /** + * **width** - Width of actor boxes + */ + width: 150, + + /** + * **height** - Height of actor boxes + */ + height: 65, + + /** + * **boxMargin** - Margin around loop boxes + */ + boxMargin: 10, + + /** + * **boxTextMargin** - margin around the text in loop/alt/opt boxes + */ + boxTextMargin: 5, + + /** + * **noteMargin** - margin around notes + */ + noteMargin: 10, + + /** + * **messageMargin** - Space between messages + */ + messageMargin: 35, + + /** + * **mirrorActors** - mirror actors under diagram + */ + mirrorActors: true, + + /** + * **bottomMarginAdj** - Depending on css styling this might need adjustment. + * Prolongs the edge of the diagram downwards + */ + bottomMarginAdj: 1, + + /** + * **useMaxWidth** - when this flag is set the height and width is set to 100% and is then scaling with the + * available space if not the absolute space required is used + */ + useMaxWidth: true + }, + + /** ### gantt + * The object containing configurations specific for gantt diagrams* + */ + gantt: { + /** + * **titleTopMargin** - margin top for the text over the gantt diagram + */ + titleTopMargin: 25, + + /** + * **barHeight** - the height of the bars in the graph + */ + barHeight: 20, + + /** + * **barGap** - the margin between the different activities in the gantt diagram + */ + barGap: 4, + + /** + * **topPadding** - margin between title and gantt diagram and between axis and gantt diagram. + */ + topPadding: 50, + + /** + * **sidePadding** - the space allocated for the section name to the left of the activities. + */ + sidePadding: 75, + + /** + * **gridLineStartPadding** - Vertical starting position of the grid lines + */ + gridLineStartPadding: 35, + + /** + * **fontSize** - font size ... + */ + fontSize: 11, + + /** + * **fontFamily** - font family ... + */ + fontFamily: '"Open-Sans", "sans-serif"', + + /** + * **numberSectionStyles** - the number of alternating section styles + */ + numberSectionStyles: 3, + + /** + * **axisFormatter** - formatting of the axis, this might need adjustment to match your locale and preferences + */ + axisFormatter: [ + + // Within a day + ['%I:%M', function (d) { + return d.getHours(); + }], + // Monday a week + ['w. %U', function (d) { + return d.getDay() == 1; + }], + // Day within a week (not monday) + ['%a %d', function (d) { + return d.getDay() && d.getDate() != 1; + }], + // within a month + ['%b %d', function (d) { + return d.getDate() != 1; + }], + // Month + ['%m-%y', function (d) { + return d.getMonth(); + }]] + } +}; + +Logger.setLogLevel(config.logLevel); + +/** + * ## parse + * Function that parses a mermaid diagram definition. If parsing fails the parseError callback is called and an error is + * thrown and + * @param text + */ +var parse = function parse(text) { + var graphType = utils.detectType(text); + var parser; + + switch (graphType) { + case 'graph': + parser = flowParser; + parser.parser.yy = graph; + break; + case 'dotGraph': + parser = dotParser; + parser.parser.yy = graph; + break; + case 'sequenceDiagram': + parser = sequenceParser; + parser.parser.yy = sequenceDb; + break; + case 'info': + parser = infoParser; + parser.parser.yy = infoDb; + break; + case 'gantt': + parser = ganttParser; + parser.parser.yy = ganttDb; + break; + case 'classDiagram': + parser = classParser; + parser.parser.yy = classDb; + break; + } + + try { + parser.parse(text); + return true; + } catch (err) { + return false; + } +}; +exports.parse = parse; + +/** + * ## version + * Function returning version information + * @returns {string} A string containing the version info + */ +exports.version = function () { + return require('../package.json').version; +}; + +exports.encodeEntities = function (text) { + var txt = text; + + txt = txt.replace(/style.*:\S*#.*;/g, function (s) { + var innerTxt = s.substring(0, s.length - 1); + return innerTxt; + }); + txt = txt.replace(/classDef.*:\S*#.*;/g, function (s) { + var innerTxt = s.substring(0, s.length - 1); + return innerTxt; + }); + + txt = txt.replace(/#\w+\;/g, function (s) { + var innerTxt = s.substring(1, s.length - 1); + + var isInt = /^\+?\d+$/.test(innerTxt); + if (isInt) { + return 'fl°°' + innerTxt + '¶ß'; + } else { + return 'fl°' + innerTxt + '¶ß'; + } + }); + + return txt; +}; + +exports.decodeEntities = function (text) { + var txt = text; + + txt = txt.replace(/\fl\°\°/g, function () { + return '&#'; + }); + txt = txt.replace(/\fl\°/g, function () { + return '&'; + }); + txt = txt.replace(/¶ß/g, function () { + return ';'; + }); + + return txt; +}; +/** + * ##render + * Function that renders an svg with a graph from a chart definition. Usage example below. + * + * ``` + * mermaidAPI.initialize({ + * startOnLoad:true + * }); + * $(function(){ + * var graphDefinition = 'graph TB\na-->b'; + * var cb = function(svgGraph){ + * console.log(svgGraph); + * }; + * mermaidAPI.render('id1',graphDefinition,cb); + * }); + *``` + * @param id the id of the element to be rendered + * @param txt the graph definition + * @param cb callback which is called after rendering is finished with the svg code as inparam. + * @param container selector to element in which a div with the graph temporarily will be inserted. In one is + * provided a hidden div will be inserted in the body of the page instead. The element will be removed when rendering is + * completed. + */ +var render = function render(id, txt, cb, container) { + + if (typeof container !== 'undefined') { + d3.select(container).append('div').attr('id', 'd' + id).append('svg').attr('id', id).attr('width', '100%').attr('xmlns', 'http://www.w3.org/2000/svg').append('g'); + } else { + d3.select('body').append('div').attr('id', 'd' + id).append('svg').attr('id', id).attr('width', '100%').attr('xmlns', 'http://www.w3.org/2000/svg').append('g'); + } + + window.txt = txt; + txt = exports.encodeEntities(txt); + //console.warn('mermaid encode: '); + //console.warn(txt); + + var element = d3.select('#d' + id).node(); + var graphType = utils.detectType(txt); + var classes = {}; + switch (graphType) { + case 'graph': + + flowRenderer.setConf(config.flowchart); + flowRenderer.draw(txt, id, false); + if (config.cloneCssStyles) { + classes = flowRenderer.getClasses(txt, false); + utils.cloneCssStyles(element.firstChild, classes); + } + break; + case 'dotGraph': + flowRenderer.setConf(config.flowchart); + flowRenderer.draw(txt, id, true); + if (config.cloneCssStyles) { + classes = flowRenderer.getClasses(txt, true); + utils.cloneCssStyles(element.firstChild, classes); + } + break; + case 'sequenceDiagram': + seq.setConf(config.sequenceDiagram); + seq.draw(txt, id); + if (config.cloneCssStyles) { + utils.cloneCssStyles(element.firstChild, []); + } + break; + case 'gantt': + gantt.setConf(config.gantt); + gantt.draw(txt, id); + if (config.cloneCssStyles) { + utils.cloneCssStyles(element.firstChild, []); + } + break; + case 'classDiagram': + classRenderer.setConf(config.gantt); + classRenderer.draw(txt, id); + if (config.cloneCssStyles) { + utils.cloneCssStyles(element.firstChild, []); + } + break; + case 'info': + info.draw(txt, id, exports.version()); + if (config.cloneCssStyles) { + utils.cloneCssStyles(element.firstChild, []); + } + break; + } + + d3.select('#d' + id).selectAll('foreignobject div').attr('xmlns', 'http://www.w3.org/1999/xhtml'); + + var url = window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, '\\('); + url = url.replace(/\)/g, '\\)'); + // Fix for when the base tag is used + var svgCode = d3.select('#d' + id).node().innerHTML.replace(/url\(#arrowhead/g, 'url(' + url + '#arrowhead', 'g'); + + svgCode = exports.decodeEntities(svgCode); + //console.warn('mermaid decode: '); + //console.warn(svgCode); + //var he = require('he'); + //svgCode = he.decode(svgCode); + if (typeof cb !== 'undefined') { + cb(svgCode, graph.bindFunctions); + } else { + log.warn('CB = undefined'); + } + + var node = d3.select('#d' + id).node(); + if (node !== null && typeof node.remove === 'function') { + d3.select('#d' + id).node().remove(); + } +}; + +exports.render = function (id, text, cb, containerElement) { + if (typeof document === 'undefined') { + // Todo handle rendering serverside using phantomjs + } else { + // In browser + render(id, text, cb, containerElement); + } +}; + +var setConf = function setConf(cnf) { + // Top level initially mermaid, gflow, sequenceDiagram and gantt + var lvl1Keys = Object.keys(cnf); + var i; + for (i = 0; i < lvl1Keys.length; i++) { + + if (typeof cnf[lvl1Keys[i]] === 'object') { + var lvl2Keys = Object.keys(cnf[lvl1Keys[i]]); + + var j; + for (j = 0; j < lvl2Keys.length; j++) { + log.debug('Setting conf ', lvl1Keys[i], '-', lvl2Keys[j]); + if (typeof config[lvl1Keys[i]] === 'undefined') { + + config[lvl1Keys[i]] = {}; + } + log.debug('Setting config: ' + lvl1Keys[i] + ' ' + lvl2Keys[j] + ' to ' + cnf[lvl1Keys[i]][lvl2Keys[j]]); + config[lvl1Keys[i]][lvl2Keys[j]] = cnf[lvl1Keys[i]][lvl2Keys[j]]; + } + } else { + config[lvl1Keys[i]] = cnf[lvl1Keys[i]]; + } + } +}; +exports.initialize = function (options) { + log.debug('Initializing mermaidAPI'); + // Update default config with options supplied at initialization + if (typeof options === 'object') { + setConf(options); + } + Logger.setLogLevel(config.logLevel); +}; +exports.getConfig = function () { + return config; +}; + +exports.parseError = function (err, hash) { + if (typeof mermaid !== 'undefined') { + global.mermaid.parseError(err, hash); + } else { + log.debug('Mermaid Syntax error:'); + log.debug(err); + } +}; +global.mermaidAPI = { + render: exports.render, + parse: exports.parse, + initialize: exports.initialize, + detectType: utils.detectType, + parseError: exports.parseError, + getConfig: exports.getConfig +}; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"../package.json":134,"./d3":135,"./diagrams/classDiagram/classDb":136,"./diagrams/classDiagram/classRenderer":137,"./diagrams/classDiagram/parser/classDiagram":138,"./diagrams/example/exampleDb":139,"./diagrams/example/exampleRenderer":140,"./diagrams/example/parser/example":141,"./diagrams/flowchart/flowRenderer":143,"./diagrams/flowchart/graphDb":144,"./diagrams/flowchart/parser/dot":145,"./diagrams/flowchart/parser/flow":146,"./diagrams/gantt/ganttDb":147,"./diagrams/gantt/ganttRenderer":148,"./diagrams/gantt/parser/gantt":149,"./diagrams/sequenceDiagram/parser/sequenceDiagram":150,"./diagrams/sequenceDiagram/sequenceDb":151,"./diagrams/sequenceDiagram/sequenceRenderer":152,"./logger":154,"./utils":156}],156:[function(require,module,exports){ +/** + * Created by knut on 14-11-23. + */ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +var _logger = require('./logger'); + +var Logger = _interopRequireWildcard(_logger); + +var log = new Logger.Log(); + +/** + * @function detectType + * Detects the type of the graph text. + * ```mermaid + * graph LR + * a-->b + * b-->c + * c-->d + * d-->e + * e-->f + * f-->g + * g-->h + * ``` + * + * @param {string} text The text defining the graph + * @returns {string} A graph definition key + */ +var detectType = function detectType(text) { + text = text.replace(/^\s*%%.*\n/g, '\n'); + if (text.match(/^\s*sequenceDiagram/)) { + return 'sequenceDiagram'; + } + + if (text.match(/^\s*digraph/)) { + //log.debug('Detected dot syntax'); + return 'dotGraph'; + } + + if (text.match(/^\s*info/)) { + //log.debug('Detected info syntax'); + return 'info'; + } + + if (text.match(/^\s*gantt/)) { + //log.debug('Detected info syntax'); + return 'gantt'; + } + + if (text.match(/^\s*classDiagram/)) { + log.debug('Detected classDiagram syntax'); + return 'classDiagram'; + } + + return 'graph'; +}; +exports.detectType = detectType; + +/** + * Copies all relevant CSS content into the graph SVG. + * This allows the SVG to be copied as is while keeping class based styling + * @param {element} svg The root element of the SVG + * @param {object} Hash table of class definitions from the graph definition + */ +var cloneCssStyles = function cloneCssStyles(svg, classes) { + var usedStyles = ''; + var sheets = document.styleSheets; + var rule; + for (var i = 0; i < sheets.length; i++) { + // Avoid multiple inclusion on pages with multiple graphs + if (sheets[i].title !== 'mermaid-svg-internal-css') { + try { + + var rules = sheets[i].cssRules; + if (rules !== null) { + for (var j = 0; j < rules.length; j++) { + rule = rules[j]; + if (typeof rule.style !== 'undefined') { + var elems; + elems = svg.querySelectorAll(rule.selectorText); + if (elems.length > 0) { + usedStyles += rule.selectorText + ' { ' + rule.style.cssText + ' }\n'; + } + } + } + } + } catch (err) { + if (rule !== 'undefined') { + log.warn('Invalid CSS selector "' + rule.selectorText + '"', err); + } + } + } + } + + var defaultStyles = ''; + var embeddedStyles = ''; + + for (var className in classes) { + if (classes.hasOwnProperty(className) && typeof className != 'undefined') { + if (className === 'default') { + if (classes['default'].styles instanceof Array) { + defaultStyles += '#' + svg.id.trim() + ' .node' + '>rect { ' + classes[className].styles.join('; ') + '; }\n'; + } + if (classes['default'].nodeLabelStyles instanceof Array) { + defaultStyles += '#' + svg.id.trim() + ' .node text ' + ' { ' + classes[className].nodeLabelStyles.join('; ') + '; }\n'; + } + if (classes['default'].edgeLabelStyles instanceof Array) { + defaultStyles += '#' + svg.id.trim() + ' .edgeLabel text ' + ' { ' + classes[className].edgeLabelStyles.join('; ') + '; }\n'; + } + if (classes['default'].clusterStyles instanceof Array) { + defaultStyles += '#' + svg.id.trim() + ' .cluster rect ' + ' { ' + classes[className].clusterStyles.join('; ') + '; }\n'; + } + } else { + if (classes[className].styles instanceof Array) { + embeddedStyles += '#' + svg.id.trim() + ' .' + className + '>rect { ' + classes[className].styles.join('; ') + '; }\n'; + } + } + } + } + + if (usedStyles !== '' || defaultStyles !== '' || embeddedStyles !== '') { + var s = document.createElement('style'); + s.setAttribute('type', 'text/css'); + s.setAttribute('title', 'mermaid-svg-internal-css'); + s.innerHTML = '/* */\n'; + svg.insertBefore(s, svg.firstChild); + } +}; + +exports.cloneCssStyles = cloneCssStyles; + +},{"./logger":154}],157:[function(require,module,exports){ + +},{}],158:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// resolves . and .. elements in a path array with directory names there +// must be no slashes, empty elements, or device names (c:\) in the array +// (so also no leading and trailing slashes - it does not distinguish +// relative and absolute paths) +function normalizeArray(parts, allowAboveRoot) { + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === '.') { + parts.splice(i, 1); + } else if (last === '..') { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (; up--; up) { + parts.unshift('..'); + } + } + + return parts; +} + +// Split a filename into [root, dir, basename, ext], unix version +// 'root' is just a slash, or nothing. +var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; +var splitPath = function(filename) { + return splitPathRe.exec(filename).slice(1); +}; + +// path.resolve([from ...], to) +// posix version +exports.resolve = function() { + var resolvedPath = '', + resolvedAbsolute = false; + + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? arguments[i] : process.cwd(); + + // Skip empty and invalid entries + if (typeof path !== 'string') { + throw new TypeError('Arguments to path.resolve must be strings'); + } else if (!path) { + continue; + } + + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = path.charAt(0) === '/'; + } + + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + + // Normalize the path + resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { + return !!p; + }), !resolvedAbsolute).join('/'); + + return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; +}; + +// path.normalize(path) +// posix version +exports.normalize = function(path) { + var isAbsolute = exports.isAbsolute(path), + trailingSlash = substr(path, -1) === '/'; + + // Normalize the path + path = normalizeArray(filter(path.split('/'), function(p) { + return !!p; + }), !isAbsolute).join('/'); + + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + + return (isAbsolute ? '/' : '') + path; +}; + +// posix version +exports.isAbsolute = function(path) { + return path.charAt(0) === '/'; +}; + +// posix version +exports.join = function() { + var paths = Array.prototype.slice.call(arguments, 0); + return exports.normalize(filter(paths, function(p, index) { + if (typeof p !== 'string') { + throw new TypeError('Arguments to path.join must be strings'); + } + return p; + }).join('/')); +}; + + +// path.relative(from, to) +// posix version +exports.relative = function(from, to) { + from = exports.resolve(from).substr(1); + to = exports.resolve(to).substr(1); + + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== '') break; + } + + var end = arr.length - 1; + for (; end >= 0; end--) { + if (arr[end] !== '') break; + } + + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + + var fromParts = trim(from.split('/')); + var toParts = trim(to.split('/')); + + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + + return outputParts.join('/'); +}; + +exports.sep = '/'; +exports.delimiter = ':'; + +exports.dirname = function(path) { + var result = splitPath(path), + root = result[0], + dir = result[1]; + + if (!root && !dir) { + // No dirname whatsoever + return '.'; + } + + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.substr(0, dir.length - 1); + } + + return root + dir; +}; + + +exports.basename = function(path, ext) { + var f = splitPath(path)[2]; + // TODO: make this comparison case-insensitive on windows? + if (ext && f.substr(-1 * ext.length) === ext) { + f = f.substr(0, f.length - ext.length); + } + return f; +}; + + +exports.extname = function(path) { + return splitPath(path)[3]; +}; + +function filter (xs, f) { + if (xs.filter) return xs.filter(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (f(xs[i], i, xs)) res.push(xs[i]); + } + return res; +} + +// String.prototype.substr - negative index don't work in IE8 +var substr = 'ab'.substr(-1) === 'b' + ? function (str, start, len) { return str.substr(start, len) } + : function (str, start, len) { + if (start < 0) start = str.length + start; + return str.substr(start, len); + } +; + +}).call(this,require('_process')) +},{"_process":159}],159:[function(require,module,exports){ +// shim for using process in browser + +var process = module.exports = {}; +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = setTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + currentQueue[queueIndex].run(); + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + clearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + setTimeout(drainQueue, 0); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],160:[function(require,module,exports){ (function (global){ //(function (root, factory) { // if (typeof exports === 'object') { @@ -38472,645 +40370,5 @@ if (typeof document !== 'undefined') { //})); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../package.json":86,"./logger":103,"./mermaidAPI":105,"he":84}],105:[function(require,module,exports){ -(function (global){ -/** - * --- - * title: mermaidAPI - * order: 5 - * --- - * # mermaidAPI - * This is the api to be used when handling the integration with the web page instead of using the default integration - * (mermaid.js). - * - * The core of this api is the **render** function that given a graph definitionas text renders the graph/diagram and - * returns a svg element for the graph. It is is then up to the user of the API to make use of the svg, either insert it - * somewhere in the page or something completely different. - */ -'use strict'; - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } - -var _logger = require('./logger'); - -var Logger = _interopRequireWildcard(_logger); - -var log = new Logger.Log(); - -var graph = require('./diagrams/flowchart/graphDb'); -var utils = require('./utils'); -var flowRenderer = require('./diagrams/flowchart/flowRenderer'); -var seq = require('./diagrams/sequenceDiagram/sequenceRenderer'); -var info = require('./diagrams/example/exampleRenderer'); -var infoParser = require('./diagrams/example/parser/example'); -var flowParser = require('./diagrams/flowchart/parser/flow'); -var dotParser = require('./diagrams/flowchart/parser/dot'); -var sequenceParser = require('./diagrams/sequenceDiagram/parser/sequenceDiagram'); -var sequenceDb = require('./diagrams/sequenceDiagram/sequenceDb'); -var infoDb = require('./diagrams/example/exampleDb'); -var gantt = require('./diagrams/gantt/ganttRenderer'); -var ganttParser = require('./diagrams/gantt/parser/gantt'); -var ganttDb = require('./diagrams/gantt/ganttDb'); -var d3 = require('./d3'); - -/** - * ## Configuration - * These are the default options which can be overridden with the initialization call as in the example below: - * ``` - * mermaid.initialize({ - * flowchart:{ - * htmlLabels: false - * } - * }); - * ``` - */ -var config = { - /** - * logLevel , decides the amount of logging to be used. - * * debug: 1 - * * info: 2 - * * warn: 3 - * * error: 4 - * * fatal: 5 - */ - logLevel: 5, - /** - * **cloneCssStyles** - This options controls whether or not the css rules should be copied into the generated svg - */ - cloneCssStyles: true, - - /** - * **startOnLoad** - This options controls whether or mermaid starts when the page loads - */ - startOnLoad: true, - - /** - * ### flowchart - * *The object containing configurations specific for flowcharts* - */ - flowchart: { - /** - * **htmlLabels** - Flag for setting whether or not a html tag should be used for rendering labels - * on the edges - */ - htmlLabels: true, - /** - * **useMaxWidth** - Flag for setting whether or not a all available width should be used for - * the diagram. - */ - useMaxWidth: true - }, - - /** - * ### sequenceDiagram - * The object containing configurations specific for sequence diagrams - */ - sequenceDiagram: { - - /** - * **diagramMarginX** - margin to the right and left of the sequence diagram - */ - diagramMarginX: 50, - - /** - * **diagramMarginY** - margin to the over and under the sequence diagram - */ - diagramMarginY: 10, - - /** - * **actorMargin** - Margin between actors - */ - actorMargin: 50, - - /** - * **width** - Width of actor boxes - */ - width: 150, - - /** - * **height** - Height of actor boxes - */ - height: 65, - - /** - * **boxMargin** - Margin around loop boxes - */ - boxMargin: 10, - - /** - * **boxTextMargin** - margin around the text in loop/alt/opt boxes - */ - boxTextMargin: 5, - - /** - * **noteMargin** - margin around notes - */ - noteMargin: 10, - - /** - * **messageMargin** - Space between messages - */ - messageMargin: 35, - - /** - * **mirrorActors** - mirror actors under diagram - */ - mirrorActors: true, - - /** - * **bottomMarginAdj** - Depending on css styling this might need adjustment. - * Prolongs the edge of the diagram downwards - */ - bottomMarginAdj: 1, - - /** - * **useMaxWidth** - when this flag is set the height and width is set to 100% and is then scaling with the - * available space if not the absolute space required is used - */ - useMaxWidth: true - }, - - /** ### gantt - * The object containing configurations specific for gantt diagrams* - */ - gantt: { - /** - * **titleTopMargin** - margin top for the text over the gantt diagram - */ - titleTopMargin: 25, - - /** - * **barHeight** - the height of the bars in the graph - */ - barHeight: 20, - - /** - * **barGap** - the margin between the different activities in the gantt diagram - */ - barGap: 4, - - /** - * **topPadding** - margin between title and gantt diagram and between axis and gantt diagram. - */ - topPadding: 50, - - /** - * **sidePadding** - the space allocated for the section name to the left of the activities. - */ - sidePadding: 75, - - /** - * **gridLineStartPadding** - Vertical starting position of the grid lines - */ - gridLineStartPadding: 35, - - /** - * **fontSize** - font size ... - */ - fontSize: 11, - - /** - * **fontFamily** - font family ... - */ - fontFamily: '"Open-Sans", "sans-serif"', - - /** - * **numberSectionStyles** - the number of alternating section styles - */ - numberSectionStyles: 3, - - /** - * **axisFormatter** - formatting of the axis, this might need adjustment to match your locale and preferences - */ - axisFormatter: [ - - // Within a day - ['%I:%M', function (d) { - return d.getHours(); - }], - // Monday a week - ['w. %U', function (d) { - return d.getDay() == 1; - }], - // Day within a week (not monday) - ['%a %d', function (d) { - return d.getDay() && d.getDate() != 1; - }], - // within a month - ['%b %d', function (d) { - return d.getDate() != 1; - }], - // Month - ['%m-%y', function (d) { - return d.getMonth(); - }]] - } -}; - -Logger.setLogLevel(config.logLevel); - -/** - * ## parse - * Function that parses a mermaid diagram definition. If parsing fails the parseError callback is called and an error is - * thrown and - * @param text - */ -var parse = function parse(text) { - var graphType = utils.detectType(text); - var parser; - - switch (graphType) { - case 'graph': - parser = flowParser; - parser.parser.yy = graph; - break; - case 'dotGraph': - parser = dotParser; - parser.parser.yy = graph; - break; - case 'sequenceDiagram': - parser = sequenceParser; - parser.parser.yy = sequenceDb; - break; - case 'info': - parser = infoParser; - parser.parser.yy = infoDb; - break; - case 'gantt': - parser = ganttParser; - parser.parser.yy = ganttDb; - break; - } - - try { - parser.parse(text); - return true; - } catch (err) { - return false; - } -}; -exports.parse = parse; - -/** - * ## version - * Function returning version information - * @returns {string} A string containing the version info - */ -exports.version = function () { - return require('../package.json').version; -}; - -exports.encodeEntities = function (text) { - var txt = text; - - txt = txt.replace(/style.*:\S*#.*;/g, function (s) { - var innerTxt = s.substring(0, s.length - 1); - return innerTxt; - }); - txt = txt.replace(/classDef.*:\S*#.*;/g, function (s) { - var innerTxt = s.substring(0, s.length - 1); - return innerTxt; - }); - - txt = txt.replace(/#\w+\;/g, function (s) { - var innerTxt = s.substring(1, s.length - 1); - - var isInt = /^\+?\d+$/.test(innerTxt); - if (isInt) { - return 'fl°°' + innerTxt + '¶ß'; - } else { - return 'fl°' + innerTxt + '¶ß'; - } - }); - - return txt; -}; - -exports.decodeEntities = function (text) { - var txt = text; - - txt = txt.replace(/\fl\°\°/g, function () { - return '&#'; - }); - txt = txt.replace(/\fl\°/g, function () { - return '&'; - }); - txt = txt.replace(/¶ß/g, function () { - return ';'; - }); - - return txt; -}; -/** - * ##render - * Function that renders an svg with a graph from a chart definition. Usage example below. - * - * ``` - * mermaidAPI.initialize({ - * startOnLoad:true - * }); - * $(function(){ - * var graphDefinition = 'graph TB\na-->b'; - * var cb = function(svgGraph){ - * console.log(svgGraph); - * }; - * mermaidAPI.render('id1',graphDefinition,cb); - * }); - *``` - * @param id the id of the element to be rendered - * @param txt the graph definition - * @param cb callback which is called after rendering is finished with the svg code as inparam. - * @param container selector to element in which a div with the graph temporarily will be inserted. In one is - * provided a hidden div will be inserted in the body of the page instead. The element will be removed when rendering is - * completed. - */ -var render = function render(id, txt, cb, container) { - - if (typeof container !== 'undefined') { - d3.select(container).append('div').attr('id', 'd' + id).append('svg').attr('id', id).attr('width', '100%').attr('xmlns', 'http://www.w3.org/2000/svg').append('g'); - } else { - d3.select('body').append('div').attr('id', 'd' + id).append('svg').attr('id', id).attr('width', '100%').attr('xmlns', 'http://www.w3.org/2000/svg').append('g'); - } - - window.txt = txt; - txt = exports.encodeEntities(txt); - //console.warn('mermaid encode: '); - //console.warn(txt); - - var element = d3.select('#d' + id).node(); - var graphType = utils.detectType(txt); - var classes = {}; - switch (graphType) { - case 'graph': - - flowRenderer.setConf(config.flowchart); - flowRenderer.draw(txt, id, false); - if (config.cloneCssStyles) { - classes = flowRenderer.getClasses(txt, false); - utils.cloneCssStyles(element.firstChild, classes); - } - break; - case 'dotGraph': - flowRenderer.setConf(config.flowchart); - flowRenderer.draw(txt, id, true); - if (config.cloneCssStyles) { - classes = flowRenderer.getClasses(txt, true); - utils.cloneCssStyles(element.firstChild, classes); - } - break; - case 'sequenceDiagram': - seq.setConf(config.sequenceDiagram); - seq.draw(txt, id); - if (config.cloneCssStyles) { - utils.cloneCssStyles(element.firstChild, []); - } - break; - case 'gantt': - gantt.setConf(config.gantt); - gantt.draw(txt, id); - if (config.cloneCssStyles) { - utils.cloneCssStyles(element.firstChild, []); - } - break; - case 'info': - info.draw(txt, id, exports.version()); - if (config.cloneCssStyles) { - utils.cloneCssStyles(element.firstChild, []); - } - break; - } - - d3.select('#d' + id).selectAll('foreignobject div').attr('xmlns', 'http://www.w3.org/1999/xhtml'); - - var url = window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search; - url = url.replace(/\(/g, '\\('); - url = url.replace(/\)/g, '\\)'); - // Fix for when the base tag is used - var svgCode = d3.select('#d' + id).node().innerHTML.replace(/url\(#arrowhead/g, 'url(' + url + '#arrowhead', 'g'); - - svgCode = exports.decodeEntities(svgCode); - //console.warn('mermaid decode: '); - //console.warn(svgCode); - //var he = require('he'); - //svgCode = he.decode(svgCode); - if (typeof cb !== 'undefined') { - cb(svgCode, graph.bindFunctions); - } else { - log.warn('CB = undefined'); - } - - var node = d3.select('#d' + id).node(); - if (node !== null && typeof node.remove === 'function') { - d3.select('#d' + id).node().remove(); - } -}; - -exports.render = function (id, text, cb, containerElement) { - if (typeof document === 'undefined') { - // Todo handle rendering serverside using phantomjs - } else { - // In browser - render(id, text, cb, containerElement); - } -}; - -var setConf = function setConf(cnf) { - // Top level initially mermaid, gflow, sequenceDiagram and gantt - var lvl1Keys = Object.keys(cnf); - var i; - for (i = 0; i < lvl1Keys.length; i++) { - - if (typeof cnf[lvl1Keys[i]] === 'object') { - var lvl2Keys = Object.keys(cnf[lvl1Keys[i]]); - - var j; - for (j = 0; j < lvl2Keys.length; j++) { - log.debug('Setting conf ', lvl1Keys[i], '-', lvl2Keys[j]); - if (typeof config[lvl1Keys[i]] === 'undefined') { - - config[lvl1Keys[i]] = {}; - } - log.debug('Setting config: ' + lvl1Keys[i] + ' ' + lvl2Keys[j] + ' to ' + cnf[lvl1Keys[i]][lvl2Keys[j]]); - config[lvl1Keys[i]][lvl2Keys[j]] = cnf[lvl1Keys[i]][lvl2Keys[j]]; - } - } else { - config[lvl1Keys[i]] = cnf[lvl1Keys[i]]; - } - } -}; -exports.initialize = function (options) { - log.debug('Initializing mermaidAPI'); - // Update default config with options supplied at initialization - if (typeof options === 'object') { - setConf(options); - } - Logger.setLogLevel(config.logLevel); -}; -exports.getConfig = function () { - return config; -}; - -exports.parseError = function (err, hash) { - if (typeof mermaid !== 'undefined') { - global.mermaid.parseError(err, hash); - } else { - log.debug('Mermaid Syntax error:'); - log.debug(err); - } -}; -global.mermaidAPI = { - render: exports.render, - parse: exports.parse, - initialize: exports.initialize, - detectType: utils.detectType, - parseError: exports.parseError, - getConfig: exports.getConfig -}; - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../package.json":86,"./d3":87,"./diagrams/example/exampleDb":88,"./diagrams/example/exampleRenderer":89,"./diagrams/example/parser/example":90,"./diagrams/flowchart/flowRenderer":92,"./diagrams/flowchart/graphDb":93,"./diagrams/flowchart/parser/dot":94,"./diagrams/flowchart/parser/flow":95,"./diagrams/gantt/ganttDb":96,"./diagrams/gantt/ganttRenderer":97,"./diagrams/gantt/parser/gantt":98,"./diagrams/sequenceDiagram/parser/sequenceDiagram":99,"./diagrams/sequenceDiagram/sequenceDb":100,"./diagrams/sequenceDiagram/sequenceRenderer":101,"./logger":103,"./utils":106}],106:[function(require,module,exports){ -/** - * Created by knut on 14-11-23. - */ -'use strict'; - -Object.defineProperty(exports, '__esModule', { - value: true -}); - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } - -var _logger = require('./logger'); - -var Logger = _interopRequireWildcard(_logger); - -var log = new Logger.Log(); - -/** - * @function detectType - * Detects the type of the graph text. - * ```mermaid - * graph LR - * a-->b - * b-->c - * c-->d - * d-->e - * e-->f - * f-->g - * g-->h - * ``` - * - * @param {string} text The text defining the graph - * @returns {string} A graph definition key - */ -var detectType = function detectType(text) { - text = text.replace(/^\s*%%.*\n/g, '\n'); - if (text.match(/^\s*sequenceDiagram/)) { - return 'sequenceDiagram'; - } - - if (text.match(/^\s*digraph/)) { - //log.debug('Detected dot syntax'); - return 'dotGraph'; - } - - if (text.match(/^\s*info/)) { - //log.debug('Detected info syntax'); - return 'info'; - } - - if (text.match(/^\s*gantt/)) { - //log.debug('Detected info syntax'); - return 'gantt'; - } - - return 'graph'; -}; -exports.detectType = detectType; - -/** - * Copies all relevant CSS content into the graph SVG. - * This allows the SVG to be copied as is while keeping class based styling - * @param {element} svg The root element of the SVG - * @param {object} Hash table of class definitions from the graph definition - */ -var cloneCssStyles = function cloneCssStyles(svg, classes) { - var usedStyles = ''; - var sheets = document.styleSheets; - var rule; - for (var i = 0; i < sheets.length; i++) { - // Avoid multiple inclusion on pages with multiple graphs - if (sheets[i].title !== 'mermaid-svg-internal-css') { - try { - - var rules = sheets[i].cssRules; - if (rules !== null) { - for (var j = 0; j < rules.length; j++) { - rule = rules[j]; - if (typeof rule.style !== 'undefined') { - var elems; - elems = svg.querySelectorAll(rule.selectorText); - if (elems.length > 0) { - usedStyles += rule.selectorText + ' { ' + rule.style.cssText + ' }\n'; - } - } - } - } - } catch (err) { - if (rule !== 'undefined') { - log.warn('Invalid CSS selector "' + rule.selectorText + '"', err); - } - } - } - } - - var defaultStyles = ''; - var embeddedStyles = ''; - - for (var className in classes) { - if (classes.hasOwnProperty(className) && typeof className != 'undefined') { - if (className === 'default') { - if (classes['default'].styles instanceof Array) { - defaultStyles += '#' + svg.id.trim() + ' .node' + '>rect { ' + classes[className].styles.join('; ') + '; }\n'; - } - if (classes['default'].nodeLabelStyles instanceof Array) { - defaultStyles += '#' + svg.id.trim() + ' .node text ' + ' { ' + classes[className].nodeLabelStyles.join('; ') + '; }\n'; - } - if (classes['default'].edgeLabelStyles instanceof Array) { - defaultStyles += '#' + svg.id.trim() + ' .edgeLabel text ' + ' { ' + classes[className].edgeLabelStyles.join('; ') + '; }\n'; - } - if (classes['default'].clusterStyles instanceof Array) { - defaultStyles += '#' + svg.id.trim() + ' .cluster rect ' + ' { ' + classes[className].clusterStyles.join('; ') + '; }\n'; - } - } else { - if (classes[className].styles instanceof Array) { - embeddedStyles += '#' + svg.id.trim() + ' .' + className + '>rect { ' + classes[className].styles.join('; ') + '; }\n'; - } - } - } - } - - if (usedStyles !== '' || defaultStyles !== '' || embeddedStyles !== '') { - var s = document.createElement('style'); - s.setAttribute('type', 'text/css'); - s.setAttribute('title', 'mermaid-svg-internal-css'); - s.innerHTML = '/* */\n'; - svg.insertBefore(s, svg.firstChild); - } -}; - -exports.cloneCssStyles = cloneCssStyles; - -},{"./logger":103}]},{},[104])(104) +},{"../package.json":134,"./logger":154,"./mermaidAPI":155,"he":132}]},{},[160])(160) }); \ No newline at end of file diff --git a/package.json b/package.json index 18e8aef0d..16d0754fe 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "dependencies": { "chalk": "^0.5.1", "d3": "~3.5.6", + "dagre": "^0.7.4", "dagre-d3": "~0.4.8", "he": "^0.5.0", "minimist": "^1.1.0", diff --git a/src/diagrams/classDiagram/classDb.js b/src/diagrams/classDiagram/classDb.js index b5684635e..726bc219c 100644 --- a/src/diagrams/classDiagram/classDb.js +++ b/src/diagrams/classDiagram/classDb.js @@ -36,7 +36,7 @@ module.exports.getClasses = function (id) { return classes; }; -module.exports.getRelations = function (id) { +module.exports.getRelations = function () { return relations; }; diff --git a/src/diagrams/classDiagram/classRenderer.js b/src/diagrams/classDiagram/classRenderer.js index 2fa195312..c724c6018 100644 --- a/src/diagrams/classDiagram/classRenderer.js +++ b/src/diagrams/classDiagram/classRenderer.js @@ -7,22 +7,44 @@ var cDDb = require('./classDb'); cd.yy = cDDb; var d3 = require('../../d3'); import * as Logger from '../../logger'; +import * as dagre from 'dagre'; var log = new Logger.Log(); - +let idCache = new Map(); +let classCnt = 0; var conf = { }; +// Todo optimize +var getGraphId = function(label){ + for (var [id, classInfo] of idCache) { + if(classInfo.label === label){ + return id; + } + } + return undefined; +} +var drawEdge = function(elem, path) { + //The data for our line + var lineData = path.points; + + //This is the accessor function we talked about above + var lineFunction = d3.svg.line() + .x(function(d) { return d.x; }) + .y(function(d) { return d.y; }) + .interpolate('linear'); + + elem.append('path') + .attr('d', lineFunction(lineData)) + .attr('stroke', 'black') + .attr('stroke-width', 1) + .attr('fill', 'none'); +} -/** - * Draws an actor in the diagram with the attaced line - * @param center - The center of the the actor - * @param pos The position if the actor in the liost of actors - * @param description The text in the box - */ var drawClass = function(elem, classDef){ + log.info('Rendering class '+classDef); //var rect = svgDraw.getNoteRect(); //rect.x = startx; //rect.y = verticalPos; @@ -59,12 +81,37 @@ var drawClass = function(elem, classDef){ // //rectElem.attr('height',textHeight+ 2*conf.noteMargin); //exports.bounds.bumpVerticalPos(textHeight+ 2*conf.noteMargin); - var g = elem.append('g'); + let id = 'classId'+classCnt; + let classInfo = { + id:id, + label:classDef.id, + width:0, + height:0 + }; + + var g = elem.append('g') + .attr('id',id); var textElem = g.append('text') // text label for the x axis - .style('text-anchor', 'middle') + .attr('x', '10') + .attr('y', '17') + .attr('fill', 'white') .attr('class', 'classText') .text(classDef.id); + var box = textElem.node().getBBox(); + g.insert('rect',':first-child') + .attr('x',0) + .attr('y',0) + .attr('fill','darkgrey') + .attr('width',box.width+20) + .attr('height',box.height+10); + + classInfo.width = box.width+20; + classInfo.height = box.height+10; + + idCache.set(id,classInfo); + classCnt++; + return classInfo; }; @@ -85,18 +132,58 @@ module.exports.draw = function (text, id) { cd.yy.clear(); cd.parse(text); + log.info('Rendering diagram '+text); + + //// Fetch the default direction, use TD if none was found var diagram = d3.select('#'+id); - var svg = diagram.append('svg'); + //var svg = diagram.append('svg'); + // Layout graph, Create a new directed graph + var g = new dagre.graphlib.Graph(); + + // Set an object for the graph label + g.setGraph({}); + + // Default to assigning a new object as a label for each new edge. + g.setDefaultEdgeLabel(function() { return {}; }); let classes = cDDb.getClasses(); for(let classDef of classes.values()){ - drawClass(svg, classDef) + let node = drawClass(diagram, classDef) + // Add nodes to the graph. The first argument is the node id. The second is + // metadata about the node. In this case we're going to add labels to each of + // our nodes. + g.setNode(node.id, node); + log.info('Org height: '+node.height); + //g.setNode("swilliams", { label: "Saul Williams", width: 160, height: 100 }); + //g.setNode("bpitt", { label: "Brad Pitt", width: 108, height: 100 }); + //g.setNode("hford", { label: "Harrison Ford", width: 168, height: 100 }); + //g.setNode("lwilson", { label: "Luke Wilson", width: 144, height: 100 }); + //g.setNode("kbacon", { label: "Kevin Bacon", width: 121, height: 100 }); } - // + let relations = cDDb.getRelations(); + for(let relation of relations){ + g.setEdge(getGraphId(relation.id1), getGraphId(relation.id2)); + } + dagre.layout(g); + g.nodes().forEach(function(v) { + log.debug('Node ' + v + ': ' + JSON.stringify(g.node(v))); + d3.select('#'+v).attr('transform','translate(' + (g.node(v).x-(g.node(v).width/2)) + ',' + (g.node(v).y-(g.node(v).height/2)) + ' )'); + //d3.select('#' +v +' rect').attr('x',(g.node(v).x-(g.node(v).width/2))) + //.attr('y',(g.node(v).y-(g.node(v).height/2))); + }); + g.edges().forEach(function(e) { + log.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(g.edge(e))); + drawEdge(diagram, g.edge(e)) + }); + + + // + diagram.attr('height', '100%'); + diagram.attr('width', '100%'); // // // diff --git a/src/mermaidAPI.js b/src/mermaidAPI.js index 8d0af2af8..249d8df7f 100644 --- a/src/mermaidAPI.js +++ b/src/mermaidAPI.js @@ -28,6 +28,9 @@ var infoDb = require('./diagrams/example/exampleDb'); var gantt = require('./diagrams/gantt/ganttRenderer'); var ganttParser = require('./diagrams/gantt/parser/gantt'); var ganttDb = require('./diagrams/gantt/ganttDb'); +var classParser = require('./diagrams/classDiagram/parser/classDiagram'); +var classRenderer = require('./diagrams/classDiagram/classRenderer'); +var classDb = require('./diagrams/classDiagram/classDb'); var d3 = require('./d3'); /** @@ -259,6 +262,10 @@ var parse = function(text){ parser = ganttParser; parser.parser.yy = ganttDb; break; + case 'classDiagram': + parser = classParser; + parser.parser.yy = classDb; + break; } try{ @@ -408,6 +415,13 @@ var render = function(id, txt, cb, container){ utils.cloneCssStyles(element.firstChild, []); } break; + case 'classDiagram': + classRenderer.setConf(config.gantt); + classRenderer.draw(txt,id); + if(config.cloneCssStyles) { + utils.cloneCssStyles(element.firstChild, []); + } + break; case 'info': info.draw(txt,id,exports.version()); if(config.cloneCssStyles) { diff --git a/src/utils.js b/src/utils.js index d3b0fcfb4..4f661946c 100644 --- a/src/utils.js +++ b/src/utils.js @@ -42,6 +42,11 @@ var detectType = function(text){ return 'gantt'; } + if(text.match(/^\s*classDiagram/)) { + log.debug('Detected classDiagram syntax'); + return 'classDiagram'; + } + return 'graph'; }; export {detectType};