UNPKG

mermaid

Version:

Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.

1,416 lines (1,295 loc) 431 kB
module.exports = /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 21); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * #logger * logger = require('logger').create() * logger.info("blah") * => [2011-3-3T20:24:4.810 info (5021)] blah * logger.debug("boom") * => * logger.level = Logger.levels.debug * logger.debug(function() { return "booom" }) * => [2011-3-3T20:24:4.810 error (5021)] booom */ function formatTime(timestamp) { var hh = timestamp.getUTCHours(); var mm = timestamp.getUTCMinutes(); var ss = timestamp.getSeconds(); var ms = timestamp.getMilliseconds(); // If you were building a timestamp instead of a duration, you would uncomment the following line to get 12-hour (not 24) time // if (hh > 12) {hh = hh % 12;} // These lines ensure you have two-digits if (hh < 10) { hh = '0' + hh; } if (mm < 10) { mm = '0' + mm; } if (ss < 10) { ss = '0' + ss; } if (ms < 100) { ms = '0' + ms; } if (ms < 10) { ms = '00' + ms; } // This formats your string to HH:MM:SS var t = hh + ':' + mm + ':' + ss + ' (' + ms + ')'; return t; } function format(level) { var time = formatTime(new Date()); return '%c ' + time + ' :%c' + level + ': '; } var debug = function debug() {}; var info = function info() {}; var warn = function warn() {}; var error = function error() {}; var fatal = function fatal() {}; /** * logLevel , decides the amount of logging to be used. * * debug: 1 * * info: 2 * * warn: 3 * * error: 4 * * fatal: 5 */ exports.setLogLevel = function (level) { if (level < 6) { exports.Log.fatal = console.log.bind(console, format('FATAL'), 'color:grey;', 'color: red;'); } if (level < 5) { exports.Log.error = console.log.bind(console, format('ERROR'), 'color:grey;', 'color: red;'); } if (level < 4) { exports.Log.warn = console.log.bind(console, format('WARN'), 'color:grey;', 'color: orange;'); } if (level < 3) { exports.Log.info = console.log.bind(console, format('INFO'), 'color:grey;', 'color: info;'); } if (level < 2) { exports.Log.debug = console.log.bind(console, format('DEBUG'), 'color:grey;', 'color: green;'); } }; exports.Log = { debug: debug, info: info, warn: warn, error: error, fatal: fatal }; /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var d3 = __webpack_require__(22); module.exports = d3; /* D3 Text Wrap By Vijith Assar http://www.vijithassar.com http://www.github.com/vijithassar @vijithassar Detailed instructions at http://www.github.com/vijithassar/d3textwrap */ (function () { // set this variable to a string value to always force a particular // wrap method for development purposes, for example to check tspan // rendering using a foreignobject-enabled browser. set to 'tspan' to // use tspans and 'foreignobject' to use foreignobject var forceWrapMethod = false; // by default no wrap method is forced forceWrapMethod = 'tspans'; // uncomment this statement to force tspans // force_wrap_method = 'foreignobjects'; // uncomment this statement to force foreignobjects // exit immediately if something in this location // has already been defined; the plugin will defer to whatever // else you're doing in your code if (d3.selection.prototype.textwrap) { return false; } // double check the force_wrap_method flag // and reset if someone screwed up the above // settings if (typeof forceWrapMethod === 'undefined') { forceWrapMethod = false; } // create the plugin method twice, both for regular use // and again for use inside the enter() selection d3.selection.prototype.textwrap = d3.selection.enter.prototype.textwrap = function (bounds, padding) { // default value of padding is zero if it's undefined padding = parseInt(padding) || 0; // save callee into a variable so we can continue to refer to it // as the function scope changes var selection = this; // create a variable to store desired return values in var returnValue; // extract wrap boundaries from any d3-selected rect and return them // in a format that matches the simpler object argument option var extractBounds = function extractBounds(bounds) { // discard the nested array wrappers added by d3 var boundingRect = bounds[0][0]; // sanitize the svg element name so we can test against it var elementType = boundingRect.tagName.toString(); // if it's not a rect, exit if (elementType !== 'rect') { return false; // if it's a rect, proceed to extracting the position attributes } else { var boundsExtracted = {}; boundsExtracted.x = d3.select(boundingRect).attr('x') || 0; boundsExtracted.y = d3.select(boundingRect).attr('y') || 0; boundsExtracted.width = d3.select(boundingRect).attr('width') || 0; boundsExtracted.height = d3.select(boundingRect).attr('height') || 0; // also pass along the getter function boundsExtracted.attr = bounds.attr; } return boundsExtracted; }; // double check the input argument for the wrapping // boundaries to make sure it actually contains all // the information we'll need in order to wrap successfully var verifyBounds = function verifyBounds(bounds) { // quickly add a simple getter method so you can use either // bounds.x or bounds.attr('x') as your notation, // the latter being a common convention among D3 // developers if (!bounds.attr) { bounds.attr = function (property) { if (this[property]) { return this[property]; } }; } // if it's an associative array, make sure it has all the // necessary properties represented directly if ((typeof bounds === 'undefined' ? 'undefined' : _typeof(bounds)) === 'object' && typeof bounds.x !== 'undefined' && typeof bounds.y !== 'undefined' && typeof bounds.width !== 'undefined' && typeof bounds.height !== 'undefined' // if that's the case, then the bounds are fine ) { // return the lightly modified bounds return bounds; // if it's a numerically indexed array, assume it's a // d3-selected rect and try to extract the positions } else if ( // first try to make sure it's an array using Array.isArray typeof Array.isArray === 'function' && Array.isArray(bounds) || // but since Array.isArray isn't always supported, fall // back to casting to the object to string when it's not Object.prototype.toString.call(bounds) === '[object Array]') { // once you're sure it's an array, extract the boundaries // from the rect var extractedBounds = extractBounds(bounds); return extractedBounds; } else { // but if the bounds are neither an object nor a numerical // array, then the bounds argument is invalid and you'll // need to fix it return false; } }; var applyPadding = function applyPadding(bounds, padding) { var paddedBounds = bounds; if (padding !== 0) { paddedBounds.x = parseInt(paddedBounds.x) + padding; paddedBounds.y = parseInt(paddedBounds.y) + padding; paddedBounds.width -= padding * 2; paddedBounds.height -= padding * 2; } return paddedBounds; }; // verify bounds var verifiedBounds = verifyBounds(bounds); // modify bounds if a padding value is provided if (padding) { verifiedBounds = applyPadding(verifiedBounds, padding); } // check that we have the necessary conditions for this function to operate properly if ( // selection it's operating on cannot be not empty selection.length === 0 || // d3 must be available !d3 || // desired wrapping bounds must be provided as an input argument !bounds || // input bounds must validate !verifiedBounds) { // try to return the calling selection if possible // so as not to interfere with methods downstream in the // chain if (selection) { return selection; // if all else fails, just return false. if you hit this point then you're // almost certainly trying to call the textwrap() method on something that // doesn't make sense! } else { return false; } // if we've validated everything then we can finally proceed // to the meat of this operation } else { // reassign the verified bounds as the set we want // to work with from here on; this ensures that we're // using the same data structure for our bounds regardless // of whether the input argument was a simple object or // a d3 selection bounds = verifiedBounds; // wrap using html and foreignObjects if they are supported var wrapWithForeignobjects = function wrapWithForeignobjects(item) { // establish variables to quickly reference target nodes later var parent = d3.select(item[0].parentNode); var textNode = parent.select('text'); var styledLineHeight = textNode.style('line-height'); // extract our desired content from the single text element var textToWrap = textNode.text(); // remove the text node and replace with a foreign object textNode.remove(); var foreignObject = parent.append('foreignObject'); // add foreign object and set dimensions, position, etc foreignObject.attr('requiredFeatures', 'http://www.w3.org/TR/SVG11/feature#Extensibility').attr('x', bounds.x).attr('y', bounds.y).attr('width', bounds.width).attr('height', bounds.height); // insert an HTML div var wrapDiv = foreignObject.append('xhtml:div') // this class is currently hardcoded // probably not necessary but easy to // override using .classed() and for now // it's nice to avoid a litany of input // arguments .attr('class', 'wrapped'); // set div to same dimensions as foreign object wrapDiv.style('height', bounds.height).style('width', bounds.width) // insert text content .html(textToWrap); if (styledLineHeight) { wrapDiv.style('line-height', styledLineHeight); } returnValue = parent.select('foreignObject'); }; // wrap with tspans if foreignObject is undefined var wrapWithTspans = function wrapWithTspans(item) { // operate on the first text item in the selection var textNode = item[0]; var parent = textNode.parentNode; var textNodeSelected = d3.select(textNode); // measure initial size of the text node as rendered var textNodeHeight = textNode.getBBox().height; var textNodeWidth = textNode.getBBox().width; // figure out the line height, either from rendered height // of the font or attached styling var lineHeight; var renderedLineHeight = textNodeHeight; var styledLineHeight = textNodeSelected.style('line-height'); if (styledLineHeight && parseInt(styledLineHeight)) { lineHeight = parseInt(styledLineHeight.replace('px', '')); } else { lineHeight = renderedLineHeight; } // only fire the rest of this if the text content // overflows the desired dimensions if (textNodeWidth > bounds.width) { // store whatever is inside the text node // in a variable and then zero out the // initial content; we'll reinsert in a moment // using tspan elements. var textToWrap = textNodeSelected.text(); textNodeSelected.text(''); if (textToWrap) { // keep track of whether we are splitting by spaces // so we know whether to reinsert those spaces later var breakDelimiter; // split at spaces to create an array of individual words var textToWrapArray; if (textToWrap.indexOf(' ') !== -1) { breakDelimiter = ' '; textToWrapArray = textToWrap.split(' '); } else { // if there are no spaces, figure out the split // points by comparing rendered text width against // bounds and translating that into character position // cuts breakDelimiter = ''; var stringLength = textToWrap.length; var numberOfSubstrings = Math.ceil(textNodeWidth / bounds.width); var spliceInterval = Math.floor(stringLength / numberOfSubstrings); if (!(spliceInterval * numberOfSubstrings >= stringLength)) { numberOfSubstrings++; } textToWrapArray = []; var substring; var startPosition; for (var i = 0; i < numberOfSubstrings; i++) { startPosition = i * spliceInterval; substring = textToWrap.substr(startPosition, spliceInterval); textToWrapArray.push(substring); } } // new array where we'll store the words re-assembled into // substrings that have been tested against the desired // maximum wrapping width var substrings = []; // computed text length is arguably incorrectly reported for // all tspans after the first one, in that they will include // the width of previous separate tspans. to compensate we need // to manually track the computed text length of all those // previous tspans and substrings, and then use that to offset // the miscalculation. this then gives us the actual correct // position we want to use in rendering the text in the SVG. var totalOffset = 0; // object for storing the results of text length computations later var temp = {}; // loop through the words and test the computed text length // of the string against the maximum desired wrapping width for (i = 0; i < textToWrapArray.length; i++) { var word = textToWrapArray[i]; var previousString = textNodeSelected.text(); var previousWidth = textNode.getComputedTextLength(); // initialize the current word as the first word // or append to the previous string if one exists var newstring; if (previousString) { newstring = previousString + breakDelimiter + word; } else { newstring = word; } // add the newest substring back to the text node and // measure the length textNodeSelected.text(newstring); var newWidth = textNode.getComputedTextLength(); // adjust the length by the offset we've tracked // due to the misreported length discussed above // if our latest version of the string is too // big for the bounds, use the previous // version of the string (without the newest word // added) and use the latest word to restart the // process with a new tspan if (newWidth > bounds.width) { if (previousString && previousString !== '') { totalOffset = totalOffset + previousWidth; temp = { string: previousString, width: previousWidth, offset: totalOffset }; substrings.push(temp); textNodeSelected.text(''); textNodeSelected.text(word); // Handle case where there is just one more word to be wrapped if (i === textToWrapArray.length - 1) { newstring = word; textNodeSelected.text(newstring); newWidth = textNode.getComputedTextLength(); } } } // if we're up to the last word in the array, // get the computed length as is without // appending anything further to it if (i === textToWrapArray.length - 1) { textNodeSelected.text(''); var finalString = newstring; if (finalString && finalString !== '') { if (newWidth - totalOffset > 0) { newWidth = newWidth - totalOffset; } temp = { string: finalString, width: newWidth, offset: totalOffset }; substrings.push(temp); } } } // append each substring as a tspan var currentTspan; // var tspanCount // double check that the text content has been removed // before we start appending tspans textNodeSelected.text(''); for (i = 0; i < substrings.length; i++) { substring = substrings[i].string; // only append if we're sure it won't make the tspans // overflow the bounds. if (i * lineHeight < bounds.height - lineHeight * 1.5) { currentTspan = textNodeSelected.append('tspan').text(substring); // vertical shift to all tspans after the first one currentTspan.attr('dy', function (d) { if (i > 0) { return lineHeight; } }); // shift left from default position, which // is probably based on the full length of the // text string until we make this adjustment currentTspan.attr('x', function () { var xOffset = bounds.x; if (padding) { xOffset += padding; } return xOffset; }); } } } } // position the overall text node, whether wrapped or not textNodeSelected.attr('y', function () { var yOffset = bounds.y; // shift by line-height to move the baseline into // the bounds – otherwise the text baseline would be // at the top of the bounds if (lineHeight) { yOffset += lineHeight; } // shift by padding, if it's there if (padding) { yOffset += padding; } return yOffset; }); // shift to the right by the padding value textNodeSelected.attr('x', function () { var xOffset = bounds.x; if (padding) { xOffset += padding; } return xOffset; }); // assign our modified text node with tspans // to the return value returnValue = d3.select(parent).selectAll('text'); }; // variable used to hold the functions that let us // switch between the wrap methods var wrapMethod; // if a wrap method if being forced, assign that // function if (forceWrapMethod) { if (forceWrapMethod === 'foreignobjects') { wrapMethod = wrapWithForeignobjects; } else if (forceWrapMethod === 'tspans') { wrapMethod = wrapWithTspans; } } // if no wrap method is being forced, then instead // test for browser support of foreignobject and // use whichever wrap method makes sense accordingly if (!forceWrapMethod) { if (typeof SVGForeignObjectElement !== 'undefined') { wrapMethod = wrapWithForeignobjects; } else { wrapMethod = wrapWithTspans; } } // run the desired wrap function for each item // in the d3 selection that called .textwrap() for (var i = 0; i < selection.length; i++) { var item = selection[i]; wrapMethod(item); } // return the modified nodes so we can chain other // methods to them. return returnValue; } }; })(); /***/ }), /* 2 */ /***/ (function(module, exports) { module.exports = function(module) { if(!module.webpackPolyfill) { module.deprecate = function() {}; module.paths = []; // module.parent = undefined by default if(!module.children) module.children = []; Object.defineProperty(module, "loaded", { enumerable: true, get: function() { return module.l; } }); Object.defineProperty(module, "id", { enumerable: true, get: function() { return module.i; } }); module.webpackPolyfill = 1; } return module; }; /***/ }), /* 3 */ /***/ (function(module, exports) { module.exports = require("fs"); /***/ }), /* 4 */ /***/ (function(module, exports) { module.exports = require("path"); /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /** * Created by knut on 14-11-03. */ var Logger = __webpack_require__(0); var log = Logger.Log; var utils = __webpack_require__(6); var d3 = __webpack_require__(1); var vertices = {}; var edges = []; var classes = []; var subGraphs = []; var tooltips = {}; var subCount = 0; var direction; // 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.addVertex = function (id, text, type, style) { var txt; if (typeof id === 'undefined') { return; } if (id.trim().length === 0) { return; } if (typeof vertices[id] === 'undefined') { vertices[id] = { id: id, styles: [], classes: [] }; } if (typeof text !== 'undefined') { txt = text.trim(); // strip quotes if string starts and exnds with a quote if (txt[0] === '"' && txt[txt.length - 1] === '"') { txt = txt.substring(1, txt.length - 1); } vertices[id].text = txt; } if (typeof type !== 'undefined') { vertices[id].type = type; } if (typeof type !== 'undefined') { vertices[id].type = type; } if (typeof style !== 'undefined') { if (style !== null) { style.forEach(function (s) { vertices[id].styles.push(s); }); } } }; /** * Function called by parser when a link/edge definition has been found * @param start * @param end * @param type * @param linktext */ exports.addLink = function (start, end, type, linktext) { log.info('Got edge...', start, end); var edge = { start: start, end: end, type: undefined, text: '' }; linktext = type.text; if (typeof linktext !== 'undefined') { edge.text = linktext.trim(); // strip quotes if string starts and exnds with a quote if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') { edge.text = edge.text.substring(1, edge.text.length - 1); } } if (typeof type !== 'undefined') { edge.type = type.type; edge.stroke = type.stroke; } edges.push(edge); }; /** * Updates a link's line interpolation algorithm * @param pos * @param interpolate */ exports.updateLinkInterpolate = function (pos, interp) { if (pos === 'default') { edges.defaultInterpolate = interp; } else { edges[pos].interpolate = interp; } }; /** * Updates a link with a style * @param pos * @param style */ exports.updateLink = function (pos, style) { if (pos === 'default') { edges.defaultStyle = style; } else { if (utils.isSubstringInArray('fill', style) === -1) { style.push('fill:none'); } edges[pos].style = style; } }; exports.addClass = function (id, style) { if (typeof classes[id] === 'undefined') { classes[id] = { id: id, styles: [] }; } if (typeof style !== 'undefined') { if (style !== null) { style.forEach(function (s) { classes[id].styles.push(s); }); } } }; /** * Called by parser when a graph definition is found, stores the direction of the chart. * @param dir */ exports.setDirection = function (dir) { direction = dir; }; /** * Called by parser when a graph definition is found, stores the direction of the chart. * @param dir */ exports.setClass = function (id, className) { if (id.indexOf(',') > 0) { id.split(',').forEach(function (id2) { if (typeof vertices[id2] !== 'undefined') { vertices[id2].classes.push(className); } }); } else { if (typeof vertices[id] !== 'undefined') { vertices[id].classes.push(className); } } }; var setTooltip = function setTooltip(id, tooltip) { if (typeof tooltip !== 'undefined') { tooltips[id] = tooltip; } }; var setClickFun = function setClickFun(id, functionName) { if (typeof functionName === 'undefined') { return; } if (typeof vertices[id] !== 'undefined') { funs.push(function (element) { var elem = d3.select(element).select('#' + id); if (elem !== null) { elem.on('click', function () { window[functionName](id); }); } }); } }; var setLink = function setLink(id, linkStr) { if (typeof linkStr === 'undefined') { return; } if (typeof vertices[id] !== 'undefined') { funs.push(function (element) { var elem = d3.select(element).select('#' + id); if (elem !== null) { elem.on('click', function () { window.open(linkStr, 'newTab'); }); } }); } }; exports.getTooltip = function (id) { return tooltips[id]; }; /** * Called by parser when a graph definition is found, stores the direction of the chart. * @param dir */ exports.setClickEvent = function (id, functionName, link, tooltip) { if (id.indexOf(',') > 0) { id.split(',').forEach(function (id2) { setTooltip(id2, tooltip); setClickFun(id2, functionName); setLink(id2, link); }); } else { setTooltip(id, tooltip); setClickFun(id, functionName); setLink(id, link); } }; exports.bindFunctions = function (element) { funs.forEach(function (fun) { fun(element); }); }; exports.getDirection = function () { return direction; }; /** * Retrieval function for fetching the found nodes after parsing has completed. * @returns {{}|*|vertices} */ exports.getVertices = function () { return vertices; }; /** * Retrieval function for fetching the found links after parsing has completed. * @returns {{}|*|edges} */ exports.getEdges = function () { return edges; }; /** * Retrieval function for fetching the found class definitions after parsing has completed. * @returns {{}|*|classes} */ exports.getClasses = function () { return classes; }; var setupToolTips = function setupToolTips(element) { var tooltipElem = d3.select('.mermaidTooltip'); if (tooltipElem[0][0] === null) { tooltipElem = d3.select('body').append('div').attr('class', 'mermaidTooltip').style('opacity', 0); } var svg = d3.select(element).select('svg'); var nodes = svg.selectAll('g.node'); nodes.on('mouseover', function () { var el = d3.select(this); var title = el.attr('title'); // Dont try to draw a tooltip if no data is provided if (title === null) { return; } var rect = this.getBoundingClientRect(); tooltipElem.transition().duration(200).style('opacity', '.9'); tooltipElem.html(el.attr('title')).style('left', rect.left + (rect.right - rect.left) / 2 + 'px').style('top', rect.top - 14 + document.body.scrollTop + 'px'); el.classed('hover', true); }).on('mouseout', function () { tooltipElem.transition().duration(500).style('opacity', 0); var el = d3.select(this); el.classed('hover', false); }); }; funs.push(setupToolTips); /** * Clears the internal graph db so that a new graph can be parsed. */ exports.clear = function () { vertices = {}; classes = {}; edges = []; funs = []; funs.push(setupToolTips); subGraphs = []; subCount = 0; tooltips = []; }; /** * * @returns {string} */ exports.defaultStyle = function () { return 'fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;'; }; /** * Clears the internal graph db so that a new graph can be parsed. */ exports.addSubGraph = function (list, title) { function uniq(a) { var prims = { 'boolean': {}, 'number': {}, 'string': {} }; var objs = []; return a.filter(function (item) { var type = typeof item === 'undefined' ? 'undefined' : _typeof(item); if (item === ' ') { return false; } if (type in prims) { return prims[type].hasOwnProperty(item) ? false : prims[type][item] = true; } else { return objs.indexOf(item) >= 0 ? false : objs.push(item); } }); } var nodeList = []; nodeList = uniq(nodeList.concat.apply(nodeList, list)); var subGraph = { id: 'subGraph' + subCount, nodes: nodeList, title: title }; subGraphs.push(subGraph); subCount = subCount + 1; return subGraph.id; }; var getPosForId = function getPosForId(id) { var i; for (i = 0; i < subGraphs.length; i++) { if (subGraphs[i].id === id) { return i; } } return -1; }; var secCount = -1; var posCrossRef = []; var indexNodes = function indexNodes(id, pos) { var nodes = subGraphs[pos].nodes; secCount = secCount + 1; if (secCount > 2000) { return; } posCrossRef[secCount] = pos; // Check if match if (subGraphs[pos].id === id) { return { result: true, count: 0 }; } var count = 0; var posCount = 1; while (count < nodes.length) { var childPos = getPosForId(nodes[count]); // Ignore regular nodes (pos will be -1) if (childPos >= 0) { var res = indexNodes(id, childPos); if (res.result) { return { result: true, count: posCount + res.count }; } else { posCount = posCount + res.count; } } count = count + 1; } return { result: false, count: posCount }; }; exports.getDepthFirstPos = function (pos) { return posCrossRef[pos]; }; exports.indexNodes = function () { secCount = -1; if (subGraphs.length > 0) { indexNodes('none', subGraphs.length - 1, 0); } }; exports.getSubGraphs = function () { return subGraphs; }; exports.parseError = function (err, hash) { global.mermaidAPI.parseError(err, hash); }; /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * Created by knut on 14-11-23. */ var Logger = __webpack_require__(0); var log = 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/)) { return 'dotGraph'; } if (text.match(/^\s*info/)) { return 'info'; } if (text.match(/^\s*gantt/)) { return 'gantt'; } if (text.match(/^\s*classDiagram/)) { log.debug('Detected classDiagram syntax'); return 'classDiagram'; } if (text.match(/^\s*gitGraph/)) { log.debug('Detected gitGraph syntax'); return 'gitGraph'; } 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 (typeof 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, .' + className + '>polygon, .' + className + '>circle, .' + className + '>ellipse { ' + 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 = '/* <![CDATA[ */\n'; // Make this CSS local to this SVG if (defaultStyles !== '') { s.innerHTML += defaultStyles; } if (usedStyles !== '') { s.innerHTML += usedStyles; } if (embeddedStyles !== '') { s.innerHTML += embeddedStyles; } s.innerHTML += '/* ]]> */\n'; svg.insertBefore(s, svg.firstChild); } }; exports.cloneCssStyles = cloneCssStyles; /** * @function isSubstringInArray * Detects whether a substring in present in a given array * @param {string} str The substring to detect * @param {array} arr The array to search * @returns {number} the array index containing the substring or -1 if not present **/ var isSubstringInArray = function isSubstringInArray(str, arr) { for (var i = 0; i < arr.length; i++) { if (arr[i].match(str)) return i; } return -1; }; exports.isSubstringInArray = isSubstringInArray; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(module) { /* parser generated by jison 0.4.17 */ /* 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) } */ var parser = function () { var o = function o(k, v, _o, l) { for (_o = _o || {}, l = k.length; l--; _o[k[l]] = v) {}return _o; }, $V0 = [1, 4], $V1 = [1, 3], $V2 = [1, 5], $V3 = [1, 8, 9, 10, 11, 13, 18, 30, 46, 71, 72, 73, 74, 75, 81, 86, 88, 89, 91, 92, 94, 95, 96, 97, 98], $V4 = [2, 2], $V5 = [1, 12], $V6 = [1, 13], $V7 = [1, 14], $V8 = [1, 15], $V9 = [1, 31], $Va = [1, 33], $Vb = [1, 22], $Vc = [1, 34], $Vd = [1, 24], $Ve = [1, 25], $Vf = [1, 26], $Vg = [1, 27], $Vh = [1, 28], $Vi = [1, 38], $Vj = [1, 40], $Vk = [1, 35], $Vl = [1, 39], $Vm = [1, 45], $Vn = [1, 44], $Vo = [1, 36], $Vp = [1, 37], $Vq = [1, 41], $Vr = [1, 42], $Vs = [1, 43], $Vt = [1, 8, 9, 10, 11, 13, 18, 30, 32, 46, 71, 72, 73, 74, 75, 81, 86, 88, 89, 91, 92, 94, 95, 96, 97, 98], $Vu = [1, 53], $Vv = [1, 52], $Vw = [1, 54], $Vx = [1, 72], $Vy = [1, 80], $Vz = [1, 81], $VA = [1, 66], $VB = [1, 65], $VC = [1, 85], $VD = [1, 84], $VE = [1, 82], $VF = [1, 83], $VG = [1, 73], $VH = [1, 68], $VI = [1, 67], $VJ = [1, 63], $VK = [1, 75], $VL = [1, 76], $VM = [1, 77], $VN = [1, 78], $VO = [1, 79], $VP = [1, 70], $VQ = [1, 69], $VR = [8, 9, 11], $VS = [8, 9, 11, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64], $VT = [1, 115], $VU = [8, 9, 10, 11, 13, 15, 18, 36, 38, 40, 42, 46, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 81, 86, 88, 89, 91, 92, 94, 95, 96, 97, 98], $VV = [8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 30, 32, 36, 37, 38, 39, 40, 41, 42, 43, 46, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 71, 72, 73, 74, 75, 78, 81, 84, 86, 88, 89, 91, 92, 94, 95, 96, 97, 98], $VW = [1, 117], $VX = [1, 118], $VY = [8, 9, 10, 11, 13, 18, 30, 32, 46, 71, 72, 73, 74, 75, 81, 86, 88, 89, 91, 92, 94, 95, 96, 97, 98], $VZ = [8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 30, 32, 37, 39, 41, 43, 46, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 71, 72, 73, 74, 75, 78, 81, 84, 86, 88, 89, 91, 92, 94, 95, 96, 97, 98], $V_ = [13, 18, 46, 81, 86, 88, 89, 91, 92, 94, 95, 96, 97, 98], $V$ = [13, 18, 46, 49, 65, 81, 86, 88, 89, 91, 92, 94, 95, 96, 97, 98], $V01 = [1, 191], $V11 = [1, 188], $V21 = [1, 195], $V31 = [1, 192], $V41 = [1, 189], $V51 = [1, 196], $V61 = [1, 186], $V71 = [1, 187], $V81 = [1, 190], $V91 = [1, 193], $Va1 = [1, 194], $Vb1 = [1, 213], $Vc1 = [8, 9, 11, 86], $Vd1 = [8, 9, 10, 11, 46, 71, 80, 81, 84, 86, 88, 89, 90, 91, 92]; var parser = { trace: function trace() {}, yy: {}, symbols_: { "error": 2, "mermaidDoc": 3, "graphConfig": 4, "document": 5, "line": 6, "statement": 7, "SEMI": 8, "NEWLINE": 9, "SPACE": 10, "EOF": 11, "GRAPH": 12, "DIR": 13, "FirstStmtSeperator": 14, "TAGEND": 15, "TAGSTART": 16, "UP": 17, "DOWN": 18, "ending": 19, "endToken": 20, "spaceList": 21, "spaceListNewline": 22, "verticeStatement": 23, "separator": 24, "styleStatement": 25, "linkStyleStatement": 26, "classDefStatement": 27, "classStatement": 28, "clickStatement": 29, "subgraph": 30, "text": 31, "end": 32, "vertex": 33, "link": 34, "alphaNum": 35, "SQS": 36, "SQE": 37, "PS": 38, "PE": 39, "(-": 40, "-)": 41, "DIAMOND_START": 42, "DIAMOND_STOP": 43, "alphaNumStatement": 44, "alphaNumToken": 45, "MINUS": 46, "linkStatement": 47, "arrowText": 48, "TESTSTR": 49, "--": 50, "ARROW_POINT": 51, "ARROW_CIRCLE": 52, "ARROW_CROSS": 53, "ARROW_OPEN": 54, "-.": 55, "DOTTED_ARROW_POINT": 56, "DOTTED_ARROW_CIRCLE": 57, "DOTTED_ARROW_CROSS": 58, "DOTTED_ARROW_OPEN": 59, "==": 60, "THICK_ARROW_POINT": 61, "THICK_ARROW_CIRCLE": 62, "THICK_ARROW_CROSS": 63, "THICK_ARROW_OPEN": 64, "PIPE": 65, "textToken": 66, "STR": 67, "commentText": 68, "commentToken": 69, "keywords": 70, "STYLE": 71, "LINKSTYLE": 72, "CLASSDEF": 73, "CLASS": 74, "CLICK": 75, "textNoTags": 76, "textNoTagsToken": 77, "DEFAULT": 78, "stylesOpt": 79, "HEX": 80, "NUM": 81, "INTERPOLATE": 82, "commentStatement": 83, "PCT": 84, "style": 85, "COMMA": 86, "styleComponent": 87, "ALPHA": 88, "COLON": 89, "UNIT": 90, "BRKT": 91, "DOT": 92, "graphCodeTokens": 93, "PUNCTUATION": 94, "UNICODE_TEXT": 95, "PLUS": 96, "EQUALS": 97, "MULT": 98, "TAG_START": 99, "TAG_END": 100, "QUOTE": 101, "$accept": 0, "$end": 1 }, terminals_: { 2: "error", 8: "SEMI", 9: "NEWLINE", 10: "SPACE", 11: "EOF", 12: "GRAPH", 13: "DIR", 15: "TAGEND", 16: "TAGSTART", 17: "UP", 18: "DOWN", 30: "subgraph", 32: "end", 36: "SQS", 37: "SQE", 38: "PS", 39: "PE", 40: "(-", 41: "-)", 42: "DIAMOND_START", 43: "DIAMOND_STOP", 46: "MINUS", 49: "TESTSTR", 50: "--", 51: "ARROW_POINT", 52: "ARROW_CIRCLE", 53: "ARROW_CROSS", 54: "ARROW_OPEN", 55: "-.", 56: "DOTTED_ARROW_POINT", 57: "DOTTED_ARROW_CIRCLE", 58: "DOTTED_ARROW_CROSS", 59: "DOTTED_ARROW_OPEN", 60: "==", 61: "THICK_ARROW_POINT", 62: "THICK_ARROW_CIRCLE", 63: "THICK_ARROW_CROSS", 64: "THICK_ARROW_OPEN", 65: "PIPE", 67: "STR", 71: "STYLE", 72: "LINKSTYLE", 73: "CLASSDEF", 74: "CLASS", 75: "CLICK", 78: "DEFAULT", 80: "HEX", 81: "NUM", 82: "INTERPOLATE", 84: "PCT", 86: "COMMA", 88: "ALPHA", 89: "COLON", 90: "UNIT", 91: "BRKT", 92: "DOT", 94: "PUNCTUATION", 95: "UNICODE_TEXT", 96: "PLUS", 97: "EQUALS", 98: "MULT", 99: "TAG_START", 100: "TAG_END", 101: "QUOTE" }, productions_: [0, [3, 2], [5, 0], [5, 2], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [4, 2], [4, 2], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [19, 2], [19, 1], [20, 1], [20, 1], [20, 1], [14, 1], [14, 1], [14, 2], [22, 2], [22, 2], [22, 1], [22, 1], [21, 2], [21, 1], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [7, 5], [7, 4], [24, 1], [24, 1], [24, 1], [23, 3], [23, 1], [33, 4], [33, 5], [33, 6], [33, 7], [33, 4], [33, 5], [33, 4], [33, 5], [33, 4], [33, 5], [33, 4], [33, 5], [33, 1], [33, 2], [35, 1], [35, 2], [44, 1], [44, 1], [44, 1], [44, 1], [34, 2], [34, 3], [34, 3], [34, 1], [34, 3], [34, 3], [34, 3], [34, 3], [34, 3], [34, 3], [34, 3], [34, 3], [34, 3], [34, 3], [34, 3], [34, 3], [47, 1], [47, 1], [47, 1], [47, 1], [47, 1], [47, 1], [47, 1], [47, 1], [47, 1], [47, 1], [47, 1], [47, 1], [48, 3], [31, 1], [31, 2], [31, 1], [68, 1], [68, 2], [70, 1], [70, 1], [70, 1], [70, 1], [70, 1], [70, 1], [70, 1], [70, 1], [70, 1], [70, 1], [70, 1], [76, 1], [76, 2], [27, 5], [27, 5], [28, 5], [29, 5], [29, 7], [29, 5], [29, 7], [25, 5], [25, 5], [26, 5], [26, 5], [26, 9], [26, 9], [26, 7], [26, 7], [83, 3], [79, 1], [79, 3], [85, 1], [85, 2], [87, 1], [87, 1], [87, 1], [87, 1], [87, 1], [87, 1], [87, 1], [87, 1], [87, 1], [87, 1], [87, 1], [69, 1], [69, 1], [66, 1], [66, 1], [66, 1], [66, 1], [66, 1], [66, 1], [66, 1], [77, 1], [77, 1], [77, 1], [77, 1], [45, 1], [45, 1], [45, 1], [45, 1], [45, 1], [45, 1], [45, 1], [45, 1], [45, 1], [45, 1], [45, 1], [93, 1], [93, 1], [93, 1], [93, 1], [93, 1], [93, 1], [93, 1], [93, 1], [93, 1], [93, 1], [93, 1], [93, 1], [93, 1], [93, 1], [93, 1]], performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { /* this == yyval */ var $0 = $$.length - 1; switch (yystate) { case 2: this.$ = []; break; case 3: if ($$[$0] !== []) { $$[$0 - 1].push($$[$0]); } this.$ = $$[$0 - 1]; break; case 4:case 57:case 59:case 60:case 92:case 94:case 95:case 108: this.$ = $$[$0]; break; case 11: yy.setDirection($$[$0 - 1]);this.$ = $$[$0 - 1]; break; case 12: yy.setDirection("LR");this.$ = $$[$0 - 1]; break; case 13: yy.setDirection("RL");this.$ = $$[$0 - 1]; break; case 14: yy.setDirection("BT");this.$ = $$[$0 - 1]; break; case 15: yy.setDirection("TB");this.$ = $$[$0 - 1]; break; case 30: this.$ = $$[$0 - 1]; break; case 31:case 32:case 33:case 34:case 35: this.$ = []; break; case 36: this.$ = yy.addSubGraph($$[$0 - 1], $$[$0 - 3]); break; case 37: this.$ = yy.addSubGraph($$[$0 - 1], undefined); break; case 41: