mermaid
Version:
Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.
1,364 lines (1,265 loc) • 386 kB
JavaScript
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;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // 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 = 29);
/******/ })
/************************************************************************/
/******/ ([
/* 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) {
const time = formatTime(new Date());
return '%c ' + time + ' :%c' + level + ': ';
}
var debug = function () {};
var info = function () {};
var warn = function () {};
var error = function () {};
var fatal = function () {};
/**
* 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";
const d3 = __webpack_require__(30);
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 (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 (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 === '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 (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 (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 (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, __webpack_require__) {
"use strict";
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 Logger = __webpack_require__(0);
var log = Logger.Log;
var relations = [];
var classes;
classes = {};
/**
* Function called by parser when a node definition has been found.
* @param id
* @param text
* @param type
* @param style
*/
exports.addClass = function (id) {
if (typeof classes[id] === 'undefined') {
classes[id] = {
id: id,
methods: [],
members: []
};
}
};
exports.clear = function () {
relations = [];
classes = {};
};
module.exports.getClass = function (id) {
return classes[id];
};
module.exports.getClasses = function () {
return classes;
};
module.exports.getRelations = function () {
return relations;
};
exports.addRelation = function (relation) {
log.warn('Adding relation: ' + JSON.stringify(relation));
exports.addClass(relation.id1);
exports.addClass(relation.id2);
relations.push(relation);
};
exports.addMembers = function (className, MembersArr) {
var theClass = classes[className];
if (typeof MembersArr === 'string') {
if (MembersArr.substr(-1) === ')') {
theClass.methods.push(MembersArr);
} else {
theClass.members.push(MembersArr);
}
}
};
exports.cleanupLabel = function (label) {
if (label.substring(0, 1) === ':') {
return label.substr(2).trim();
} else {
return label.trim();
}
};
exports.lineType = {
LINE: 0,
DOTTED_LINE: 1
};
exports.relationType = {
AGGREGATION: 0,
EXTENSION: 1,
COMPOSITION: 2,
DEPENDENCY: 3
};
/***/ }),
/* 6 */
/***/ (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 (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 = yy.cleanupLabel($$[$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 16:
yy.addMembers($$[$0 - 1], yy.cleanupLabel($$[$0]));
break;
case 17:
console.warn('Member', $$[$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 {
function _parseError(msg, hash) {
this.message = msg;
this.hash = hash;
}
_parseError.prototype = 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;
}
var lex = function () {
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 (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 () {
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 (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 () {
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 () {
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 (n) {
this.unput(this.match.slice(n));
},
// displays already matched input, i.e. for error messages
pastInput: function () {
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 () {
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 () {
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 (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 () {
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['IN