diff --git a/Gemfile b/Gemfile
index 4e8e184498c42f638ae12f70a446069f57e6068a..7ae6cb7c58f269cfa3441dfb81c0b2c4a78a3ec3 100644
--- a/Gemfile
+++ b/Gemfile
@@ -15,7 +15,6 @@ gem "jekyll", "3.7.4"
 # If you have any plugins, put them here!
 group :jekyll_plugins do
   gem 'execjs'
-  gem 'jekyll-seo-tag'
   gem 'jekyll-redirect-from'
   gem 'jekyll-target-blank'
   gem "jekyll-feed"
diff --git a/Gemfile.lock b/Gemfile.lock
deleted file mode 100644
index ecd5d235c394aebfe8791651f65c67b0f42a4484..0000000000000000000000000000000000000000
--- a/Gemfile.lock
+++ /dev/null
@@ -1,171 +0,0 @@
-PATH
-  remote: .
-  specs:
-    jekyll-theme-cayman (0.1.1)
-      jekyll (~> 3.1)
-      jekyll-seo-tag (~> 2.0)
-
-GEM
-  remote: https://rubygems.org/
-  specs:
-    addressable (2.7.0)
-      public_suffix (>= 2.0.2, < 5.0)
-    ast (2.4.0)
-    colorator (1.1.0)
-    concurrent-ruby (1.1.6)
-    em-websocket (0.5.1)
-      eventmachine (>= 0.12.9)
-      http_parser.rb (~> 0.6.0)
-    ethon (0.12.0)
-      ffi (>= 1.3.0)
-    eventmachine (1.2.7)
-    execjs (2.7.0)
-    extras (0.3.0)
-      forwardable-extended (~> 2.5)
-    fastimage (2.1.7)
-    ffi (1.12.2)
-    font-awesome-sass (5.12.0)
-      sassc (>= 1.11)
-    forwardable-extended (2.6.0)
-    hpricot (0.8.6)
-    html-proofer (3.15.1)
-      addressable (~> 2.3)
-      mercenary (~> 0.3)
-      nokogumbo (~> 2.0)
-      parallel (~> 1.3)
-      rainbow (~> 3.0)
-      typhoeus (~> 1.3)
-      yell (~> 2.0)
-    http_parser.rb (0.6.0)
-    i18n (0.9.5)
-      concurrent-ruby (~> 1.0)
-    jaro_winkler (1.5.4)
-    jekyll (3.7.4)
-      addressable (~> 2.4)
-      colorator (~> 1.0)
-      em-websocket (~> 0.5)
-      i18n (~> 0.7)
-      jekyll-sass-converter (~> 1.0)
-      jekyll-watch (~> 2.0)
-      kramdown (~> 1.14)
-      liquid (~> 4.0)
-      mercenary (~> 0.3.3)
-      pathutil (~> 0.9)
-      rouge (>= 1.7, < 4)
-      safe_yaml (~> 1.0)
-    jekyll-assets (2.4.0)
-      concurrent-ruby (~> 1.0)
-      extras (~> 0.2)
-      fastimage (~> 2.0, >= 1.8)
-      jekyll (~> 3.1, >= 3.0)
-      pathutil (>= 0.8)
-      rack (~> 1.6)
-      sprockets (~> 3.3, < 3.8)
-    jekyll-contentblocks (1.2.0)
-      jekyll
-    jekyll-feed (0.13.0)
-      jekyll (>= 3.7, < 5.0)
-    jekyll-font-awesome-sass (0.1.1)
-      font-awesome-sass (>= 4)
-      jekyll (>= 2.5, < 4.0)
-    jekyll-mermaid (1.0.0)
-    jekyll-paginate (1.1.0)
-    jekyll-redirect-from (0.16.0)
-      jekyll (>= 3.3, < 5.0)
-    jekyll-sass-converter (1.5.2)
-      sass (~> 3.4)
-    jekyll-seo-tag (2.6.1)
-      jekyll (>= 3.3, < 5.0)
-    jekyll-target-blank (2.0.0)
-      jekyll (>= 3.0, < 5.0)
-      nokogiri (~> 1.10)
-    jekyll-watch (2.2.1)
-      listen (~> 3.0)
-    json (2.3.0)
-    kramdown (1.17.0)
-    libv8 (3.16.14.19)
-    liquid (4.0.3)
-    listen (3.2.1)
-      rb-fsevent (~> 0.10, >= 0.10.3)
-      rb-inotify (~> 0.9, >= 0.9.10)
-    mercenary (0.3.6)
-    mini_portile2 (2.4.0)
-    nokogiri (1.10.8)
-      mini_portile2 (~> 2.4.0)
-    nokogumbo (2.0.2)
-      nokogiri (~> 1.8, >= 1.8.4)
-    parallel (1.19.1)
-    parser (2.7.0.2)
-      ast (~> 2.4.0)
-    pathutil (0.16.2)
-      forwardable-extended (~> 2.6)
-    public_suffix (4.0.3)
-    rack (1.6.10)
-    rainbow (3.0.0)
-    rb-fsevent (0.10.3)
-    rb-inotify (0.10.1)
-      ffi (~> 1.0)
-    ref (2.0.0)
-    remark (0.3.2)
-      hpricot (~> 0.8.2)
-    rexml (3.2.4)
-    rouge (3.16.0)
-    rubocop (0.80.0)
-      jaro_winkler (~> 1.5.1)
-      parallel (~> 1.10)
-      parser (>= 2.7.0.1)
-      rainbow (>= 2.2.2, < 4.0)
-      rexml
-      ruby-progressbar (~> 1.7)
-      unicode-display_width (>= 1.4.0, < 1.7)
-    ruby-progressbar (1.10.1)
-    safe_yaml (1.0.5)
-    sass (3.7.4)
-      sass-listen (~> 4.0.0)
-    sass-listen (4.0.0)
-      rb-fsevent (~> 0.9, >= 0.9.4)
-      rb-inotify (~> 0.9, >= 0.9.7)
-    sassc (2.2.1)
-      ffi (~> 1.9)
-    sprockets (3.7.2)
-      concurrent-ruby (~> 1.0)
-      rack (> 1, < 3)
-    therubyracer (0.12.3)
-      libv8 (~> 3.16.14.15)
-      ref
-    typhoeus (1.3.1)
-      ethon (>= 0.9.0)
-    uglifier (4.2.0)
-      execjs (>= 0.3.0, < 3)
-    unicode-display_width (1.6.1)
-    w3c_validators (1.3.4)
-      json (>= 1.8)
-      nokogiri (~> 1.6)
-    yell (2.2.2)
-
-PLATFORMS
-  ruby
-
-DEPENDENCIES
-  execjs
-  html-proofer (~> 3.0)
-  jekyll (= 3.7.4)
-  jekyll-assets (= 2.4.0)
-  jekyll-contentblocks
-  jekyll-feed
-  jekyll-font-awesome-sass
-  jekyll-mermaid
-  jekyll-paginate
-  jekyll-redirect-from
-  jekyll-seo-tag
-  jekyll-target-blank
-  jekyll-theme-cayman!
-  remark
-  rubocop (~> 0.50)
-  therubyracer
-  tzinfo-data
-  uglifier
-  w3c_validators (~> 1.3)
-
-BUNDLED WITH
-   1.17.3
diff --git a/_submodules/mermaid/.ackrc b/_submodules/mermaid/.ackrc
deleted file mode 100644
index 5390d7b92156fb09773917c6b453ec3cf18d5948..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/.ackrc
+++ /dev/null
@@ -1,4 +0,0 @@
---ignore-dir=dist
---ignore-file=match:/^yarn\.lock$/
---ignore-file=match:/^yarn-error\.log$/
---ignore-dir=coverage
diff --git a/_submodules/mermaid/.babelrc b/_submodules/mermaid/.babelrc
deleted file mode 100644
index b207aefdded3fae007f56bcc2f28d7a6c958fb26..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/.babelrc
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "presets": [
-    "env"
-  ]
-}
diff --git a/_submodules/mermaid/.editorconfig b/_submodules/mermaid/.editorconfig
deleted file mode 100644
index ab70fef5e64a0b2cf3dcb28e5781c98fa7c36679..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/.editorconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-root = true
-
-[*]
-indent_style = space
-indent_size = 2
-charset = utf-8
-trim_trailing_whitespace = true
-insert_final_newline = true
-
-[*.md]
-indent_size = 4
diff --git a/_submodules/mermaid/.gitignore b/_submodules/mermaid/.gitignore
deleted file mode 100644
index f2c5e769955120f6793cbe1b3322a802dda60f47..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/.gitignore
+++ /dev/null
@@ -1,9 +0,0 @@
-.DS_Store
-
-node_modules/
-coverage/
-
-dist/*.js
-dist/*.map
-
-yarn-error.log
diff --git a/_submodules/mermaid/.travis.yml b/_submodules/mermaid/.travis.yml
deleted file mode 100644
index d28528ef6b5ed96a03761e97e2fec02f1d759b46..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/.travis.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-dist: trusty
-language: node_js
-node_js:
-  - "8"
-script:
-  - yarn test --coverage
-after_success:
-  - cat ./coverage/lcov.info | ./node_modules/.bin/coveralls
diff --git a/_submodules/mermaid/CHANGELOG.md b/_submodules/mermaid/CHANGELOG.md
deleted file mode 100644
index 3bbf313664ce7ec9f3820c9ba2c97c8a4a959e02..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/CHANGELOG.md
+++ /dev/null
@@ -1,386 +0,0 @@
-# Change Log
-
-## [Unreleased](https://github.com/knsv/mermaid/tree/HEAD)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.4.0...HEAD)
-
-**Implemented enhancements:**
-
-- Add a css file, mermaid.css, with default styling [\#122](https://github.com/knsv/mermaid/issues/122)
-
-**Closed issues:**
-
-- Some examples not displayed on Firefox 36.0.1 [\#138](https://github.com/knsv/mermaid/issues/138)
-
-- inoperable in an AMD/requirejs environment: IPython Notebook [\#127](https://github.com/knsv/mermaid/issues/127)
-
-- Add capability for gantt diagrams [\#118](https://github.com/knsv/mermaid/issues/118)
-
-- lower case v causes error in the parser [\#108](https://github.com/knsv/mermaid/issues/108)
-
-- Label's css conflict with boostrap's .label [\#67](https://github.com/knsv/mermaid/issues/67)
-
-**Merged pull requests:**
-
-- Adding init argument to the global API [\#137](https://github.com/knsv/mermaid/pull/137) ([bollwyvl](https://github.com/bollwyvl))
-
-- Add description of manual calling of init [\#136](https://github.com/knsv/mermaid/pull/136) ([bollwyvl](https://github.com/bollwyvl))
-
-- Allow other forms of node selection for init\(\) [\#135](https://github.com/knsv/mermaid/pull/135) ([bollwyvl](https://github.com/bollwyvl))
-
-- Use a library-level variable for assigning ids [\#134](https://github.com/knsv/mermaid/pull/134) ([bollwyvl](https://github.com/bollwyvl))
-
-## [0.4.0](https://github.com/knsv/mermaid/tree/0.4.0) (2015-03-01)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.3.5...0.4.0)
-
-**Implemented enhancements:**
-
-- Assymetric shapes not documented [\#82](https://github.com/knsv/mermaid/issues/82)
-
-- Improve arrows [\#3](https://github.com/knsv/mermaid/issues/3)
-
-**Fixed bugs:**
-
-- NoModificationAllowedError [\#23](https://github.com/knsv/mermaid/issues/23)
-
-**Closed issues:**
-
-- subgraph background is black in rendered flowchart PNG via CLI [\#121](https://github.com/knsv/mermaid/issues/121)
-
-- Integrate editor at https://github.com/naseer/mermaid-webapp [\#110](https://github.com/knsv/mermaid/issues/110)
-
-- Internet Explorer Support [\#99](https://github.com/knsv/mermaid/issues/99)
-
-## [0.3.5](https://github.com/knsv/mermaid/tree/0.3.5) (2015-02-15)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.3.4...0.3.5)
-
-## [0.3.4](https://github.com/knsv/mermaid/tree/0.3.4) (2015-02-15)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.3.3...0.3.4)
-
-**Implemented enhancements:**
-
-- Apply styling from css when using the CLI utility [\#85](https://github.com/knsv/mermaid/issues/85)
-
-- Generated SVG works poorly outside web browsers [\#58](https://github.com/knsv/mermaid/issues/58)
-
-- Generating SVG text blob for use in Node [\#2](https://github.com/knsv/mermaid/issues/2)
-
-**Closed issues:**
-
-- Subgraph syntax bug? [\#120](https://github.com/knsv/mermaid/issues/120)
-
-- Live editor [\#115](https://github.com/knsv/mermaid/issues/115)
-
-- Error in "Basic Syntax" wiki page [\#113](https://github.com/knsv/mermaid/issues/113)
-
-- semicolons, anyone? [\#111](https://github.com/knsv/mermaid/issues/111)
-
-- undefined `sequenceConfig` fails [\#109](https://github.com/knsv/mermaid/issues/109)
-
-- Sequence Diagrams: Show Actors below as well [\#106](https://github.com/knsv/mermaid/issues/106)
-
-- Allow overriding sequence diagram configuration \(SVG properties\) [\#103](https://github.com/knsv/mermaid/issues/103)
-
-- Error when rendering A-- This is the text -- B [\#102](https://github.com/knsv/mermaid/issues/102)
-
-- Clipping in documentation [\#97](https://github.com/knsv/mermaid/issues/97)
-
-- isolate class styling to the svg container [\#92](https://github.com/knsv/mermaid/issues/92)
-
-- Make the new graph declaration more visual [\#40](https://github.com/knsv/mermaid/issues/40)
-
-**Merged pull requests:**
-
-- Add live editor [\#119](https://github.com/knsv/mermaid/pull/119) ([naseer](https://github.com/naseer))
-
-- Adds CSS option to the CLI [\#116](https://github.com/knsv/mermaid/pull/116) ([fardog](https://github.com/fardog))
-
-- Update flowchart.md in response Issue \#113 [\#114](https://github.com/knsv/mermaid/pull/114) ([vijay40](https://github.com/vijay40))
-
-- Ignore all files except the license and dist/ folder when installing with Bower. [\#112](https://github.com/knsv/mermaid/pull/112) ([jasonbellamy](https://github.com/jasonbellamy))
-
-## [0.3.3](https://github.com/knsv/mermaid/tree/0.3.3) (2015-01-25)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.3.2...0.3.3)
-
-**Implemented enhancements:**
-
-- Support for dotted links [\#26](https://github.com/knsv/mermaid/issues/26)
-
-**Closed issues:**
-
-- Missing arrows in sequence diagram [\#98](https://github.com/knsv/mermaid/issues/98)
-
-- Error with \>9 linkStyles [\#95](https://github.com/knsv/mermaid/issues/95)
-
-**Merged pull requests:**
-
-- Require d3 directly to better support Node usage [\#107](https://github.com/knsv/mermaid/pull/107) ([markdalgleish](https://github.com/markdalgleish))
-
-- update doc with -c option [\#105](https://github.com/knsv/mermaid/pull/105) ([jjmr](https://github.com/jjmr))
-
-- Add new parameter to the console client to override the svg configuration in sequence diagrams [\#104](https://github.com/knsv/mermaid/pull/104) ([jjmr](https://github.com/jjmr))
-
-- Text based labels, new shape [\#101](https://github.com/knsv/mermaid/pull/101) ([bjowes](https://github.com/bjowes))
-
-- fix html tags in example usage [\#100](https://github.com/knsv/mermaid/pull/100) ([deiwin](https://github.com/deiwin))
-
-## [0.3.2](https://github.com/knsv/mermaid/tree/0.3.2) (2015-01-11)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.3.1...0.3.2)
-
-**Implemented enhancements:**
-
-- Make link text look like it is on the line [\#53](https://github.com/knsv/mermaid/issues/53)
-
-**Closed issues:**
-
-- disable auto render [\#91](https://github.com/knsv/mermaid/issues/91)
-
-- Tidy breaks mermaid \(linebreaks in <div\>\) [\#87](https://github.com/knsv/mermaid/issues/87)
-
-- Bug: <br\> being rendered as text in node [\#73](https://github.com/knsv/mermaid/issues/73)
-
-- Graph edges appear to render outside of the canvas [\#70](https://github.com/knsv/mermaid/issues/70)
-
-**Merged pull requests:**
-
-- Merge pull request \#1 from knsv/master [\#96](https://github.com/knsv/mermaid/pull/96) ([gkchic](https://github.com/gkchic))
-
-- Removed duplicated section in flowchart docs [\#94](https://github.com/knsv/mermaid/pull/94) ([kaime](https://github.com/kaime))
-
-- Grammar changes to sequence page [\#93](https://github.com/knsv/mermaid/pull/93) ([gkchic](https://github.com/gkchic))
-
-- Grammar changes to development page [\#90](https://github.com/knsv/mermaid/pull/90) ([gkchic](https://github.com/gkchic))
-
-- Github buttons [\#89](https://github.com/knsv/mermaid/pull/89) ([gkchic](https://github.com/gkchic))
-
-- Template change [\#88](https://github.com/knsv/mermaid/pull/88) ([gkchic](https://github.com/gkchic))
-
-- New content template [\#86](https://github.com/knsv/mermaid/pull/86) ([gkchic](https://github.com/gkchic))
-
-## [0.3.1](https://github.com/knsv/mermaid/tree/0.3.1) (2015-01-05)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.3.0...0.3.1)
-
-**Implemented enhancements:**
-
-- Support for sequence diagrams [\#16](https://github.com/knsv/mermaid/issues/16)
-
-- Client utility for mermaid [\#6](https://github.com/knsv/mermaid/issues/6)
-
-**Closed issues:**
-
-- Non ASCII chars in labels [\#84](https://github.com/knsv/mermaid/issues/84)
-
-- 'undefined' titles of Quicklinks on the usage page [\#80](https://github.com/knsv/mermaid/issues/80)
-
-- \[cli\] Enhancement proposal: not fail --version / --help if phantomjs isn't installed [\#71](https://github.com/knsv/mermaid/issues/71)
-
-**Merged pull requests:**
-
-- Formatting of the CONTRIBUTING file [\#83](https://github.com/knsv/mermaid/pull/83) ([Grahack](https://github.com/Grahack))
-
-- Flowchart doc: Text in the circle now in a circle [\#81](https://github.com/knsv/mermaid/pull/81) ([Grahack](https://github.com/Grahack))
-
-- Fix for issue \#73 [\#79](https://github.com/knsv/mermaid/pull/79) ([it0a](https://github.com/it0a))
-
-- Ink template [\#78](https://github.com/knsv/mermaid/pull/78) ([gkchic](https://github.com/gkchic))
-
-- Index template file [\#77](https://github.com/knsv/mermaid/pull/77) ([gkchic](https://github.com/gkchic))
-
-- Index template file [\#76](https://github.com/knsv/mermaid/pull/76) ([gkchic](https://github.com/gkchic))
-
-- Show help and version even if phantom isn't present. Fixes \#71 [\#75](https://github.com/knsv/mermaid/pull/75) ([fardog](https://github.com/fardog))
-
-- Add apostrophe & 'and' [\#72](https://github.com/knsv/mermaid/pull/72) ([sudodoki](https://github.com/sudodoki))
-
-## [0.3.0](https://github.com/knsv/mermaid/tree/0.3.0) (2014-12-22)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.16...0.3.0)
-
-**Implemented enhancements:**
-
-- How do I do comments? [\#47](https://github.com/knsv/mermaid/issues/47)
-
-- Improve readability with new line as terminator and whitespace [\#38](https://github.com/knsv/mermaid/issues/38)
-
-**Fixed bugs:**
-
-- This characters failed the lexical parsing [\#46](https://github.com/knsv/mermaid/issues/46)
-
-**Closed issues:**
-
-- Trailing whitespace at the end of lines is not ignored [\#55](https://github.com/knsv/mermaid/issues/55)
-
-- Use classes instead of inline style for easy styling [\#24](https://github.com/knsv/mermaid/issues/24)
-
-**Merged pull requests:**
-
-- Adds Command Line Interface for generating PNGs from mermaid description files [\#69](https://github.com/knsv/mermaid/pull/69) ([fardog](https://github.com/fardog))
-
-- Allow special symbols for direction along with acronyms [\#66](https://github.com/knsv/mermaid/pull/66) ([vijay40](https://github.com/vijay40))
-
-## [0.2.16](https://github.com/knsv/mermaid/tree/0.2.16) (2014-12-15)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.15...0.2.16)
-
-**Fixed bugs:**
-
-- Lines routed outside visible area [\#19](https://github.com/knsv/mermaid/issues/19)
-
-**Closed issues:**
-
-- Mermaid not rendering properly on Wordpress pages [\#59](https://github.com/knsv/mermaid/issues/59)
-
-- Improve example page with live demo [\#52](https://github.com/knsv/mermaid/issues/52)
-
-- Does not render upon AngularJS Updates [\#45](https://github.com/knsv/mermaid/issues/45)
-
-- Download link in README.MD doesn't work. [\#42](https://github.com/knsv/mermaid/issues/42)
-
-- linkStyle usage is not obvious [\#41](https://github.com/knsv/mermaid/issues/41)
-
-- Move \*.spec.js in src/ to test/ [\#35](https://github.com/knsv/mermaid/issues/35)
-
-**Merged pull requests:**
-
-- New grammar will allow statements ending without semicolon as disccused in Issue \#38 [\#63](https://github.com/knsv/mermaid/pull/63) ([vijay40](https://github.com/vijay40))
-
-- Class based styling [\#62](https://github.com/knsv/mermaid/pull/62) ([bjowes](https://github.com/bjowes))
-
-- Update from master [\#61](https://github.com/knsv/mermaid/pull/61) ([bjowes](https://github.com/bjowes))
-
-- Fix typos [\#60](https://github.com/knsv/mermaid/pull/60) ([sublimino](https://github.com/sublimino))
-
-- Included .DS\_Store in gitignore [\#57](https://github.com/knsv/mermaid/pull/57) ([alvynmcq](https://github.com/alvynmcq))
-
-- Improves readablity discussed in issue \#38 [\#56](https://github.com/knsv/mermaid/pull/56) ([vijay40](https://github.com/vijay40))
-
-- Added a linting task for gulp [\#43](https://github.com/knsv/mermaid/pull/43) ([serv](https://github.com/serv))
-
-## [0.2.15](https://github.com/knsv/mermaid/tree/0.2.15) (2014-12-05)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.14...0.2.15)
-
-**Fixed bugs:**
-
-- Error with some characters [\#25](https://github.com/knsv/mermaid/issues/25)
-
-- Cap-cased words break parser [\#8](https://github.com/knsv/mermaid/issues/8)
-
-**Closed issues:**
-
-- Question marks don't render properly with /dist/mermaid.full.min.js [\#30](https://github.com/knsv/mermaid/issues/30)
-
-- Provide parse function in browser widthout `require`? [\#21](https://github.com/knsv/mermaid/issues/21)
-
-- Better label text support [\#18](https://github.com/knsv/mermaid/issues/18)
-
-**Merged pull requests:**
-
-- Include bower\_components/ to .gitignore [\#33](https://github.com/knsv/mermaid/pull/33) ([serv](https://github.com/serv))
-
-- Fixed reference to Git repo. [\#32](https://github.com/knsv/mermaid/pull/32) ([guyellis](https://github.com/guyellis))
-
-## [0.2.14](https://github.com/knsv/mermaid/tree/0.2.14) (2014-12-03)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.13...0.2.14)
-
-## [0.2.13](https://github.com/knsv/mermaid/tree/0.2.13) (2014-12-03)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.10...0.2.13)
-
-**Implemented enhancements:**
-
-- Publish to NPM [\#7](https://github.com/knsv/mermaid/issues/7)
-
-**Closed issues:**
-
-- modified init to be applied more than once [\#29](https://github.com/knsv/mermaid/issues/29)
-
-- Wanted to know build process for the project. [\#28](https://github.com/knsv/mermaid/issues/28)
-
-- can not support Chinese description [\#20](https://github.com/knsv/mermaid/issues/20)
-
-- Support unicode chars in labels [\#9](https://github.com/knsv/mermaid/issues/9)
-
-**Merged pull requests:**
-
-- initial setup for editor page to generate graph through textarea input [\#14](https://github.com/knsv/mermaid/pull/14) ([ImanimalXI](https://github.com/ImanimalXI))
-
-## [0.2.10](https://github.com/knsv/mermaid/tree/0.2.10) (2014-12-01)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.9...0.2.10)
-
-## [0.2.9](https://github.com/knsv/mermaid/tree/0.2.9) (2014-12-01)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.8...0.2.9)
-
-**Closed issues:**
-
-- Add link to jsbin playground to README [\#11](https://github.com/knsv/mermaid/issues/11)
-
-- What are the requirements ? [\#10](https://github.com/knsv/mermaid/issues/10)
-
-**Merged pull requests:**
-
-- Allow unicode chars in labels [\#13](https://github.com/knsv/mermaid/pull/13) ([codebeige](https://github.com/codebeige))
-
-- Formatting Update [\#12](https://github.com/knsv/mermaid/pull/12) ([darrencauthon](https://github.com/darrencauthon))
-
-## [0.2.8](https://github.com/knsv/mermaid/tree/0.2.8) (2014-12-01)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.7...0.2.8)
-
-## [0.2.7](https://github.com/knsv/mermaid/tree/0.2.7) (2014-12-01)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.6...0.2.7)
-
-**Closed issues:**
-
-- Provide parser as separate module [\#4](https://github.com/knsv/mermaid/issues/4)
-
-## [0.2.6](https://github.com/knsv/mermaid/tree/0.2.6) (2014-11-27)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.5...0.2.6)
-
-## [0.2.5](https://github.com/knsv/mermaid/tree/0.2.5) (2014-11-27)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.4...0.2.5)
-
-**Merged pull requests:**
-
-- Added new shapes! [\#1](https://github.com/knsv/mermaid/pull/1) ([bjowes](https://github.com/bjowes))
-
-## [0.2.4](https://github.com/knsv/mermaid/tree/0.2.4) (2014-11-25)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.3...0.2.4)
-
-## [0.2.3](https://github.com/knsv/mermaid/tree/0.2.3) (2014-11-24)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.2...0.2.3)
-
-## [0.2.2](https://github.com/knsv/mermaid/tree/0.2.2) (2014-11-22)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.1...0.2.2)
-
-## [0.2.1](https://github.com/knsv/mermaid/tree/0.2.1) (2014-11-22)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.0...0.2.1)
-
-## [0.2.0](https://github.com/knsv/mermaid/tree/0.2.0) (2014-11-22)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.1.1...0.2.0)
-
-## [0.1.1](https://github.com/knsv/mermaid/tree/0.1.1) (2014-11-17)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.1.0...0.1.1)
-
-## [0.1.0](https://github.com/knsv/mermaid/tree/0.1.0) (2014-11-16)
-
-
-\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
\ No newline at end of file
diff --git a/_submodules/mermaid/LICENSE b/_submodules/mermaid/LICENSE
deleted file mode 100644
index 77b04c3aba988265626d86accec3a33d3979305b..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2014 - 2018 Knut Sveidqvist
-
-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.
diff --git a/_submodules/mermaid/README.md b/_submodules/mermaid/README.md
deleted file mode 100644
index 45464c0ea22edc7152814c4d504d80a9e131d5e4..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/README.md
+++ /dev/null
@@ -1,206 +0,0 @@
-# mermaid
-
-[![Build Status](https://travis-ci.org/knsv/mermaid.svg?branch=master)](https://travis-ci.org/knsv/mermaid)
-[![Coverage Status](https://coveralls.io/repos/github/knsv/mermaid/badge.svg?branch=master)](https://coveralls.io/github/knsv/mermaid?branch=master)
-[![Join the chat at https://gitter.im/knsv/mermaid](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/knsv/mermaid?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-![banner](./img/header.png)
-
-Generation of diagrams and flowcharts from text in a similar manner as markdown.
-
-Ever wanted to simplify documentation and avoid heavy tools like Visio when explaining your code?
-
-This is why mermaid was born, a simple markdown-like script language for generating charts from text via javascript.
-
-
-### Flowchart
-
-```
-graph TD;
-    A-->B;
-    A-->C;
-    B-->D;
-    C-->D;
-```
-![Flowchart](./img/flow.png)
-
-
-### Sequence diagram
-
-```
-sequenceDiagram
-    participant Alice
-    participant Bob
-    Alice->>John: Hello John, how are you?
-    loop Healthcheck
-        John->>John: Fight against hypochondria
-    end
-    Note right of John: Rational thoughts <br/>prevail...
-    John-->>Alice: Great!
-    John->>Bob: How about you?
-    Bob-->>John: Jolly good!
-```
-![Sequence diagram](./img/sequence.png)
-
-
-### Gantt diagram
-
-```
-gantt
-dateFormat  YYYY-MM-DD
-title Adding GANTT diagram to mermaid
-
-section A section
-Completed task            :done,    des1, 2014-01-06,2014-01-08
-Active task               :active,  des2, 2014-01-09, 3d
-Future task               :         des3, after des2, 5d
-Future task2               :         des4, after des3, 5d
-```
-![Gantt diagram](./img/gantt.png)
-
-
-### Class diagram - :exclamation: experimental
-
-```
-classDiagram
-Class01 <|-- AveryLongClass : Cool
-Class03 *-- Class04
-Class05 o-- Class06
-Class07 .. Class08
-Class09 --> C2 : Where am i?
-Class09 --* C3
-Class09 --|> Class07
-Class07 : equals()
-Class07 : Object[] elementData
-Class01 : size()
-Class01 : int chimp
-Class01 : int gorilla
-Class08 <--> C2: Cool label
-```
-![Class diagram](./img/class.png)
-
-
-### Git graph - :exclamation: experimental
-
-```
-gitGraph:
-options
-{
-    "nodeSpacing": 150,
-    "nodeRadius": 10
-}
-end
-commit
-branch newbranch
-checkout newbranch
-commit
-commit
-checkout master
-commit
-commit
-merge newbranch
-
-```
-
-![Git graph](./img/git.png)
-
-
-## Installation
-
-### CDN
-
-```
-https://unpkg.com/mermaid@<version>/dist/
-```
-
-Replace `<version>` with expected version number.
-
-Example: https://unpkg.com/mermaid@7.1.0/dist/
-
-### Node.js
-
-```
-yarn add mermaid
-```
-
-
-## Documentation
-
-https://mermaidjs.github.io
-
-
-## Sibling projects
-
-- [mermaid CLI](https://github.com/mermaidjs/mermaid.cli)
-- [mermaid live editor](https://github.com/mermaidjs/mermaid-live-editor)
-- [mermaid webpack demo](https://github.com/mermaidjs/mermaid-webpack-demo)
-- [mermaid Parcel demo](https://github.com/mermaidjs/mermaid-parcel-demo)
-
-
-# Request for assistance
-
-Things are piling up and I have hard time keeping up. To remedy this
-it would be great if we could form a core team of developers to cooperate
-with the future development mermaid.
-
-As part of this team you would get write access to the repository and would
-represent the project when answering questions and issues.
-
-Together we could continue the work with things like:
-* adding more typers of diagrams like mindmaps, ert digrams etc
-* improving existing diagrams
-
-Don't hesitate to contact me if you want to get involved.
-
-
-# For contributors
-
-## Setup
-
-    yarn install
-
-
-## Build
-
-    yarn build:watch
-
-
-## Lint
-
-    yarn lint
-
-We use [JavaScript Standard Style](https://github.com/feross/standard).
-We recommend you installing [editor plugins](https://github.com/feross/standard#are-there-text-editor-plugins) so you can get real time lint result.
-
-
-## Test
-
-    yarn test
-
-Manual test in browser:
-
-    open dist/index.html
-
-
-## Release
-
-For those who have the permission to do so:
-
-Update version number in `package.json`.
-
-    npm publish
-
-Command above generates files into the `dist` folder and publishes them to npmjs.org.
-
-
-# Credits
-
-Many thanks to the [d3](http://d3js.org/) and [dagre-d3](https://github.com/cpettitt/dagre-d3) projects for providing the graphical layout and drawing libraries!
-
-Thanks also to the [js-sequence-diagram](http://bramp.github.io/js-sequence-diagrams) project for usage of the grammar for the sequence diagrams. Thanks to Jessica Peter for inspiration and starting point for gantt rendering.
-
-*Mermaid was created by Knut Sveidqvist for easier documentation.*
-
-*[Tyler Long](https://github.com/tylerlong) has became a collaborator since April 2017.*
-
-Here is the full list of the projects [contributors](https://github.com/knsv/mermaid/graphs/contributors).
diff --git a/_submodules/mermaid/__mocks__/d3.js b/_submodules/mermaid/__mocks__/d3.js
deleted file mode 100644
index 218ed9754f70b895a3e1310c43e3be269b74fd2d..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/__mocks__/d3.js
+++ /dev/null
@@ -1,38 +0,0 @@
-let NewD3 = function () {
-  return {
-    append: function () {
-      return NewD3()
-    },
-    attr: function () {
-      return this
-    },
-    style: function () {
-      return this
-    },
-    text: function () {
-      return this
-    },
-    0: {
-      0: {
-        getBBox: function () {
-          return {
-            height: 10,
-            width: 20
-          }
-        }
-      }
-    }
-  }
-}
-
-export const select = function () {
-  return new NewD3()
-}
-
-export const selectAll = function () {
-  return new NewD3()
-}
-
-export const curveBasis = 'basis'
-export const curveLinear = 'linear'
-export const curveCardinal = 'cardinal'
diff --git a/_submodules/mermaid/gulpfile.js b/_submodules/mermaid/gulpfile.js
deleted file mode 100644
index 613cf83c1430012153d05236eede68bd0ee060a2..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/gulpfile.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import gulp from 'gulp'
-import jison from 'gulp-jison'
-import filelog from 'gulp-filelog'
-
-gulp.task('jison', function () {
-  return gulp.src('./src/**/*.jison')
-    .pipe(filelog('Jison file:'))
-    .pipe(jison({ 'token-stack': true }))
-    .pipe(gulp.dest('./src/'))
-})
diff --git a/_submodules/mermaid/img/class.png b/_submodules/mermaid/img/class.png
deleted file mode 100644
index bf6e379e1abf5db97fcd3d7bb06cad26400b8a7f..0000000000000000000000000000000000000000
Binary files a/_submodules/mermaid/img/class.png and /dev/null differ
diff --git a/_submodules/mermaid/img/flow.png b/_submodules/mermaid/img/flow.png
deleted file mode 100644
index e324299764ef1540b37b891a76484514ce5d6d15..0000000000000000000000000000000000000000
Binary files a/_submodules/mermaid/img/flow.png and /dev/null differ
diff --git a/_submodules/mermaid/img/gantt.png b/_submodules/mermaid/img/gantt.png
deleted file mode 100644
index 64645cb5baf307d7804bf2050ab7f4fb1b2cb312..0000000000000000000000000000000000000000
Binary files a/_submodules/mermaid/img/gantt.png and /dev/null differ
diff --git a/_submodules/mermaid/img/git.png b/_submodules/mermaid/img/git.png
deleted file mode 100644
index 2da331a1eda912e1fb6057726dc8608985b045ac..0000000000000000000000000000000000000000
Binary files a/_submodules/mermaid/img/git.png and /dev/null differ
diff --git a/_submodules/mermaid/img/header.png b/_submodules/mermaid/img/header.png
deleted file mode 100644
index 06159b2c94e22cc09fb507db6c7a1562fe4bdeb7..0000000000000000000000000000000000000000
Binary files a/_submodules/mermaid/img/header.png and /dev/null differ
diff --git a/_submodules/mermaid/img/sequence.png b/_submodules/mermaid/img/sequence.png
deleted file mode 100644
index b35e3b74db9e96de970ec63af9345f0046ec9fcd..0000000000000000000000000000000000000000
Binary files a/_submodules/mermaid/img/sequence.png and /dev/null differ
diff --git a/_submodules/mermaid/package.json b/_submodules/mermaid/package.json
deleted file mode 100644
index 3c2a5b38f7448fa7827728acc36e46f067d61ea2..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/package.json
+++ /dev/null
@@ -1,80 +0,0 @@
-{
-  "name": "mermaid",
-  "version": "8.0.0-rc.8",
-  "description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
-  "main": "dist/mermaid.core.js",
-  "keywords": [
-    "diagram",
-    "markdown",
-    "flowchart",
-    "sequence diagram",
-    "gantt",
-    "class diagram",
-    "git graph"
-  ],
-  "scripts": {
-    "build": "webpack --progress --colors",
-    "build:watch": "yarn build --watch",
-    "release": "yarn build -p --config webpack.config.prod.babel.js",
-    "upgrade": "yarn-upgrade-all",
-    "lint": "standard",
-    "test": "yarn lint && jest",
-    "test:watch": "jest --watch",
-    "jison": "node -r babel-register node_modules/.bin/gulp jison",
-    "prepublishOnly": "yarn build && yarn release && yarn test",
-    "prepush": "yarn test"
-  },
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/knsv/mermaid"
-  },
-  "author": "Knut Sveidqvist",
-  "license": "MIT",
-  "standard": {
-    "ignore": [
-      "**/parser/*.js",
-      "dist/**/*.js"
-    ]
-  },
-  "dependencies": {
-    "d3": "^4.13.0",
-    "dagre-d3-renderer": "^0.5.8",
-    "dagre-layout": "^0.8.8",
-    "graphlibrary": "^2.2.0",
-    "he": "^1.1.1",
-    "lodash": "^4.17.5",
-    "moment": "^2.21.0",
-    "scope-css": "^1.0.5"
-  },
-  "devDependencies": {
-    "babel-core": "^6.26.0",
-    "babel-loader": "^7.1.4",
-    "babel-preset-env": "^1.6.1",
-    "coveralls": "^3.0.0",
-    "css-loader": "^0.28.11",
-    "css-to-string-loader": "^0.1.3",
-    "gulp": "^3.9.1",
-    "gulp-filelog": "^0.4.1",
-    "gulp-jison": "^1.2.0",
-    "husky": "^0.14.3",
-    "identity-obj-proxy": "^3.0.0",
-    "jest": "^22.4.2",
-    "jison": "^0.4.18",
-    "node-sass": "^4.7.2",
-    "sass-loader": "^6.0.7",
-    "standard": "^11.0.1",
-    "webpack": "^4.1.1",
-    "webpack-cli": "^2.0.12",
-    "webpack-node-externals": "^1.6.0",
-    "yarn-upgrade-all": "^0.3.0"
-  },
-  "files": [
-    "dist",
-    "src"
-  ],
-  "jest": {
-    "moduleNameMapper": {
-      "\\.(css|scss)$": "identity-obj-proxy"
-    }
-  }
-}
diff --git a/_submodules/mermaid/src/diagrams/class/classDb.js b/_submodules/mermaid/src/diagrams/class/classDb.js
deleted file mode 100644
index 6be4bb7736a1d5a324846d8618f3555d09e7e8c9..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/class/classDb.js
+++ /dev/null
@@ -1,89 +0,0 @@
-
-import { logger } from '../../logger'
-
-let relations = []
-let classes = {}
-
-/**
- * Function called by parser when a node definition has been found.
- * @param id
- * @param text
- * @param type
- * @param style
- */
-export const addClass = function (id) {
-  if (typeof classes[id] === 'undefined') {
-    classes[id] = {
-      id: id,
-      methods: [],
-      members: []
-    }
-  }
-}
-
-export const clear = function () {
-  relations = []
-  classes = {}
-}
-
-export const getClass = function (id) {
-  return classes[id]
-}
-export const getClasses = function () {
-  return classes
-}
-
-export const getRelations = function () {
-  return relations
-}
-
-export const addRelation = function (relation) {
-  logger.debug('Adding relation: ' + JSON.stringify(relation))
-  addClass(relation.id1)
-  addClass(relation.id2)
-  relations.push(relation)
-}
-
-export const addMembers = function (className, MembersArr) {
-  const theClass = classes[className]
-  if (typeof MembersArr === 'string') {
-    if (MembersArr.substr(-1) === ')') {
-      theClass.methods.push(MembersArr)
-    } else {
-      theClass.members.push(MembersArr)
-    }
-  }
-}
-
-export const cleanupLabel = function (label) {
-  if (label.substring(0, 1) === ':') {
-    return label.substr(2).trim()
-  } else {
-    return label.trim()
-  }
-}
-
-export const lineType = {
-  LINE: 0,
-  DOTTED_LINE: 1
-}
-
-export const relationType = {
-  AGGREGATION: 0,
-  EXTENSION: 1,
-  COMPOSITION: 2,
-  DEPENDENCY: 3
-}
-
-export default {
-  addClass,
-  clear,
-  getClass,
-  getClasses,
-  getRelations,
-  addRelation,
-  addMembers,
-  cleanupLabel,
-  lineType,
-  relationType
-}
diff --git a/_submodules/mermaid/src/diagrams/class/classDiagram.spec.js b/_submodules/mermaid/src/diagrams/class/classDiagram.spec.js
deleted file mode 100644
index 38657e11d2d0fa22a72e8c54f503df09acb420c4..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/class/classDiagram.spec.js
+++ /dev/null
@@ -1,208 +0,0 @@
-/* eslint-env jasmine */
-import { parser } from './parser/classDiagram'
-import classDb from './classDb'
-
-describe('class diagram, ', function () {
-  describe('when parsing an info graph it', function () {
-    beforeEach(function () {
-      parser.yy = classDb
-    })
-
-    it('should handle relation definitions', function () {
-      const str = 'classDiagram\n' +
-'Class01 <|-- Class02\n' +
-'Class03 *-- Class04\n' +
-'Class05 o-- Class06\n' +
-'Class07 .. Class08\n' +
-'Class09 -- Class1'
-
-      parser.parse(str)
-    })
-    it('should handle relation definition of different types and directions', function () {
-      const str = 'classDiagram\n' +
-'Class11 <|.. Class12\n' +
-'Class13 --> Class14\n' +
-'Class15 ..> Class16\n' +
-'Class17 ..|> Class18\n' +
-'Class19 <--* Class20'
-
-      parser.parse(str)
-    })
-
-    it('should handle cardinality and labels', function () {
-      const str = 'classDiagram\n' +
-'Class01 "1" *-- "many" Class02 : contains\n' +
-'Class03 o-- Class04 : aggregation\n' +
-'Class05 --> "1" Class06'
-
-      parser.parse(str)
-    })
-    it('should handle class definitions', function () {
-      const str = 'classDiagram\n' +
-'class Car\n' +
-'Driver -- Car : drives >\n' +
-'Car *-- Wheel : have 4 >\n' +
-'Car -- Person : < owns'
-
-      parser.parse(str)
-    })
-
-    it('should handle method statements', function () {
-      const str = 'classDiagram\n' +
-'Object <|-- ArrayList\n' +
-'Object : equals()\n' +
-'ArrayList : Object[] elementData\n' +
-'ArrayList : size()'
-
-      parser.parse(str)
-    })
-    it('should handle parsing of method statements  grouped by brackets', function () {
-      const str = 'classDiagram\n' +
-'class Dummy {\n' +
-'String data\n' +
-'  void methods()\n' +
-'}\n' +
-'\n' +
-'class Flight {\n' +
-'   flightNumber : Integer\n' +
-'   departureTime : Date\n' +
-'}'
-
-      parser.parse(str)
-    })
-
-    it('should handle parsing of separators', function () {
-      const str = 'classDiagram\n' +
-                'class Foo1 {\n' +
-                '  You can use\n' +
-                '  several lines\n' +
-                '..\n' +
-                'as you want\n' +
-                'and group\n' +
-                '==\n' +
-                'things together.\n' +
-                '__\n' +
-                'You can have as many groups\n' +
-                'as you want\n' +
-                '--\n' +
-                'End of class\n' +
-                '}\n' +
-                '\n' +
-                'class User {\n' +
-                '.. Simple Getter ..\n' +
-                '+ getName()\n' +
-                '+ getAddress()\n' +
-                '.. Some setter ..\n' +
-                '+ setName()\n' +
-                '__ private data __\n' +
-                'int age\n' +
-                '-- encrypted --\n' +
-                'String password\n' +
-                '}'
-
-      parser.parse(str)
-    })
-  })
-
-  describe('when fetching data from an classDiagram graph it', function () {
-    beforeEach(function () {
-      parser.yy = classDb
-      parser.yy.clear()
-    })
-    it('should handle relation definitions EXTENSION', function () {
-      const str = 'classDiagram\n' +
-                        'Class01 <|-- Class02'
-
-      parser.parse(str)
-
-      const relations = parser.yy.getRelations()
-
-      expect(parser.yy.getClass('Class01').id).toBe('Class01')
-      expect(parser.yy.getClass('Class02').id).toBe('Class02')
-      expect(relations[0].relation.type1).toBe(classDb.relationType.EXTENSION)
-      expect(relations[0].relation.type2).toBe('none')
-      expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE)
-    })
-    it('should handle relation definitions AGGREGATION and dotted line', function () {
-      const str = 'classDiagram\n' +
-                        'Class01 o.. Class02'
-
-      parser.parse(str)
-
-      const relations = parser.yy.getRelations()
-
-      expect(parser.yy.getClass('Class01').id).toBe('Class01')
-      expect(parser.yy.getClass('Class02').id).toBe('Class02')
-      expect(relations[0].relation.type1).toBe(classDb.relationType.AGGREGATION)
-      expect(relations[0].relation.type2).toBe('none')
-      expect(relations[0].relation.lineType).toBe(classDb.lineType.DOTTED_LINE)
-    })
-    it('should handle relation definitions COMPOSITION on both sides', function () {
-      const str = 'classDiagram\n' +
-                       'Class01 *--* Class02'
-
-      parser.parse(str)
-
-      const relations = parser.yy.getRelations()
-
-      expect(parser.yy.getClass('Class01').id).toBe('Class01')
-      expect(parser.yy.getClass('Class02').id).toBe('Class02')
-      expect(relations[0].relation.type1).toBe(classDb.relationType.COMPOSITION)
-      expect(relations[0].relation.type2).toBe(classDb.relationType.COMPOSITION)
-      expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE)
-    })
-    it('should handle relation definitions no types', function () {
-      const str = 'classDiagram\n' +
-                        'Class01 -- Class02'
-
-      parser.parse(str)
-
-      const relations = parser.yy.getRelations()
-
-      expect(parser.yy.getClass('Class01').id).toBe('Class01')
-      expect(parser.yy.getClass('Class02').id).toBe('Class02')
-      expect(relations[0].relation.type1).toBe('none')
-      expect(relations[0].relation.type2).toBe('none')
-      expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE)
-    })
-    it('should handle relation definitions with type only on right side', function () {
-      const str = 'classDiagram\n' +
-                       'Class01 --|> Class02'
-
-      parser.parse(str)
-
-      const relations = parser.yy.getRelations()
-
-      expect(parser.yy.getClass('Class01').id).toBe('Class01')
-      expect(parser.yy.getClass('Class02').id).toBe('Class02')
-      expect(relations[0].relation.type1).toBe('none')
-      expect(relations[0].relation.type2).toBe(classDb.relationType.EXTENSION)
-      expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE)
-    })
-
-    it('should handle multiple classes and relation definitions', function () {
-      const str = 'classDiagram\n' +
-                        'Class01 <|-- Class02\n' +
-                        'Class03 *-- Class04\n' +
-                        'Class05 o-- Class06\n' +
-                        'Class07 .. Class08\n' +
-                        'Class09 -- Class10'
-
-      parser.parse(str)
-
-      const relations = parser.yy.getRelations()
-
-      expect(parser.yy.getClass('Class01').id).toBe('Class01')
-      expect(parser.yy.getClass('Class10').id).toBe('Class10')
-
-      expect(relations.length).toBe(5)
-
-      expect(relations[0].relation.type1).toBe(classDb.relationType.EXTENSION)
-      expect(relations[0].relation.type2).toBe('none')
-      expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE)
-      expect(relations[3].relation.type1).toBe('none')
-      expect(relations[3].relation.type2).toBe('none')
-      expect(relations[3].relation.lineType).toBe(classDb.lineType.DOTTED_LINE)
-    })
-  })
-})
diff --git a/_submodules/mermaid/src/diagrams/class/classRenderer.js b/_submodules/mermaid/src/diagrams/class/classRenderer.js
deleted file mode 100644
index 5169fce4bf3db14087082700cd498423855a3a2c..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/class/classRenderer.js
+++ /dev/null
@@ -1,365 +0,0 @@
-import dagre from 'dagre-layout'
-import graphlib from 'graphlibrary'
-import * as d3 from 'd3'
-
-import classDb from './classDb'
-import { logger } from '../../logger'
-import { parser } from './parser/classDiagram'
-
-parser.yy = classDb
-
-const idCache = {}
-
-let classCnt = 0
-const conf = {
-  dividerMargin: 10,
-  padding: 5,
-  textHeight: 10
-}
-
-// Todo optimize
-const getGraphId = function (label) {
-  const keys = Object.keys(idCache)
-
-  for (let i = 0; i < keys.length; i++) {
-    if (idCache[keys[i]].label === label) {
-      return keys[i]
-    }
-  }
-
-  return undefined
-}
-
-/**
- * Setup arrow head and define the marker. The result is appended to the svg.
- */
-const insertMarkers = function (elem) {
-  elem.append('defs').append('marker')
-    .attr('id', 'extensionStart')
-    .attr('class', 'extension')
-    .attr('refX', 0)
-    .attr('refY', 7)
-    .attr('markerWidth', 190)
-    .attr('markerHeight', 240)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 1,7 L18,13 V 1 Z')
-
-  elem.append('defs').append('marker')
-    .attr('id', 'extensionEnd')
-    .attr('refX', 19)
-    .attr('refY', 7)
-    .attr('markerWidth', 20)
-    .attr('markerHeight', 28)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 1,1 V 13 L18,7 Z') // this is actual shape for arrowhead
-
-  elem.append('defs').append('marker')
-    .attr('id', 'compositionStart')
-    .attr('class', 'extension')
-    .attr('refX', 0)
-    .attr('refY', 7)
-    .attr('markerWidth', 190)
-    .attr('markerHeight', 240)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
-
-  elem.append('defs').append('marker')
-    .attr('id', 'compositionEnd')
-    .attr('refX', 19)
-    .attr('refY', 7)
-    .attr('markerWidth', 20)
-    .attr('markerHeight', 28)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
-
-  elem.append('defs').append('marker')
-    .attr('id', 'aggregationStart')
-    .attr('class', 'extension')
-    .attr('refX', 0)
-    .attr('refY', 7)
-    .attr('markerWidth', 190)
-    .attr('markerHeight', 240)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
-
-  elem.append('defs').append('marker')
-    .attr('id', 'aggregationEnd')
-    .attr('refX', 19)
-    .attr('refY', 7)
-    .attr('markerWidth', 20)
-    .attr('markerHeight', 28)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
-
-  elem.append('defs').append('marker')
-    .attr('id', 'dependencyStart')
-    .attr('class', 'extension')
-    .attr('refX', 0)
-    .attr('refY', 7)
-    .attr('markerWidth', 190)
-    .attr('markerHeight', 240)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 5,7 L9,13 L1,7 L9,1 Z')
-
-  elem.append('defs').append('marker')
-    .attr('id', 'dependencyEnd')
-    .attr('refX', 19)
-    .attr('refY', 7)
-    .attr('markerWidth', 20)
-    .attr('markerHeight', 28)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z')
-}
-
-let edgeCount = 0
-const drawEdge = function (elem, path, relation) {
-  const getRelationType = function (type) {
-    switch (type) {
-      case classDb.relationType.AGGREGATION:
-        return 'aggregation'
-      case classDb.relationType.EXTENSION:
-        return 'extension'
-      case classDb.relationType.COMPOSITION:
-        return 'composition'
-      case classDb.relationType.DEPENDENCY:
-        return 'dependency'
-    }
-  }
-
-  // The data for our line
-  const lineData = path.points
-
-  // This is the accessor function we talked about above
-  const lineFunction = d3.line()
-    .x(function (d) {
-      return d.x
-    })
-    .y(function (d) {
-      return d.y
-    })
-    .curve(d3.curveBasis)
-
-  const svgPath = elem.append('path')
-    .attr('d', lineFunction(lineData))
-    .attr('id', 'edge' + edgeCount)
-    .attr('class', 'relation')
-  let url = ''
-  if (conf.arrowMarkerAbsolute) {
-    url = window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search
-    url = url.replace(/\(/g, '\\(')
-    url = url.replace(/\)/g, '\\)')
-  }
-
-  if (relation.relation.type1 !== 'none') {
-    svgPath.attr('marker-start', 'url(' + url + '#' + getRelationType(relation.relation.type1) + 'Start' + ')')
-  }
-  if (relation.relation.type2 !== 'none') {
-    svgPath.attr('marker-end', 'url(' + url + '#' + getRelationType(relation.relation.type2) + 'End' + ')')
-  }
-
-  let x, y
-  const l = path.points.length
-  if ((l % 2) !== 0) {
-    const p1 = path.points[Math.floor(l / 2)]
-    const p2 = path.points[Math.ceil(l / 2)]
-    x = (p1.x + p2.x) / 2
-    y = (p1.y + p2.y) / 2
-  } else {
-    const p = path.points[Math.floor(l / 2)]
-    x = p.x
-    y = p.y
-  }
-
-  if (typeof relation.title !== 'undefined') {
-    const g = elem.append('g')
-      .attr('class', 'classLabel')
-    const label = g.append('text')
-      .attr('class', 'label')
-      .attr('x', x)
-      .attr('y', y)
-      .attr('fill', 'red')
-      .attr('text-anchor', 'middle')
-      .text(relation.title)
-
-    window.label = label
-    const bounds = label.node().getBBox()
-
-    g.insert('rect', ':first-child')
-      .attr('class', 'box')
-      .attr('x', bounds.x - conf.padding / 2)
-      .attr('y', bounds.y - conf.padding / 2)
-      .attr('width', bounds.width + conf.padding)
-      .attr('height', bounds.height + conf.padding)
-  }
-
-  edgeCount++
-}
-
-const drawClass = function (elem, classDef) {
-  logger.info('Rendering class ' + classDef)
-
-  const addTspan = function (textEl, txt, isFirst) {
-    const tSpan = textEl.append('tspan')
-      .attr('x', conf.padding)
-      .text(txt)
-    if (!isFirst) {
-      tSpan.attr('dy', conf.textHeight)
-    }
-  }
-
-  const id = 'classId' + classCnt
-  const classInfo = {
-    id: id,
-    label: classDef.id,
-    width: 0,
-    height: 0
-  }
-
-  const g = elem.append('g')
-    .attr('id', id)
-    .attr('class', 'classGroup')
-  const title = g.append('text')
-    .attr('x', conf.padding)
-    .attr('y', conf.textHeight + conf.padding)
-    .text(classDef.id)
-
-  const titleHeight = title.node().getBBox().height
-
-  const membersLine = g.append('line') // text label for the x axis
-    .attr('x1', 0)
-    .attr('y1', conf.padding + titleHeight + conf.dividerMargin / 2)
-    .attr('y2', conf.padding + titleHeight + conf.dividerMargin / 2)
-
-  const members = g.append('text') // text label for the x axis
-    .attr('x', conf.padding)
-    .attr('y', titleHeight + (conf.dividerMargin) + conf.textHeight)
-    .attr('fill', 'white')
-    .attr('class', 'classText')
-
-  let isFirst = true
-  classDef.members.forEach(function (member) {
-    addTspan(members, member, isFirst)
-    isFirst = false
-  })
-
-  const membersBox = members.node().getBBox()
-
-  const methodsLine = g.append('line') // text label for the x axis
-    .attr('x1', 0)
-    .attr('y1', conf.padding + titleHeight + conf.dividerMargin + membersBox.height)
-    .attr('y2', conf.padding + titleHeight + conf.dividerMargin + membersBox.height)
-
-  const methods = g.append('text') // text label for the x axis
-    .attr('x', conf.padding)
-    .attr('y', titleHeight + 2 * conf.dividerMargin + membersBox.height + conf.textHeight)
-    .attr('fill', 'white')
-    .attr('class', 'classText')
-
-  isFirst = true
-
-  classDef.methods.forEach(function (method) {
-    addTspan(methods, method, isFirst)
-    isFirst = false
-  })
-
-  const classBox = g.node().getBBox()
-  g.insert('rect', ':first-child')
-    .attr('x', 0)
-    .attr('y', 0)
-    .attr('width', classBox.width + 2 * conf.padding)
-    .attr('height', classBox.height + conf.padding + 0.5 * conf.dividerMargin)
-
-  membersLine.attr('x2', classBox.width + 2 * conf.padding)
-  methodsLine.attr('x2', classBox.width + 2 * conf.padding)
-
-  classInfo.width = classBox.width + 2 * conf.padding
-  classInfo.height = classBox.height + conf.padding + 0.5 * conf.dividerMargin
-
-  idCache[id] = classInfo
-  classCnt++
-  return classInfo
-}
-
-export const setConf = function (cnf) {
-  const 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
- */
-export const draw = function (text, id) {
-  parser.yy.clear()
-  parser.parse(text)
-
-  logger.info('Rendering diagram ' + text)
-
-  /// / Fetch the default direction, use TD if none was found
-  const diagram = d3.select(`[id="${id}"]`)
-  insertMarkers(diagram)
-
-  // Layout graph, Create a new directed graph
-  const g = new graphlib.Graph({
-    multigraph: true
-  })
-
-  // Set an object for the graph label
-  g.setGraph({
-    isMultiGraph: true
-  })
-
-  // Default to assigning a new object as a label for each new edge.
-  g.setDefaultEdgeLabel(function () {
-    return {}
-  })
-
-  const classes = classDb.getClasses()
-  const keys = Object.keys(classes)
-  for (let i = 0; i < keys.length; i++) {
-    const classDef = classes[keys[i]]
-    const 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)
-    logger.info('Org height: ' + node.height)
-  }
-
-  const relations = classDb.getRelations()
-  relations.forEach(function (relation) {
-    logger.info('tjoho' + getGraphId(relation.id1) + getGraphId(relation.id2) + JSON.stringify(relation))
-    g.setEdge(getGraphId(relation.id1), getGraphId(relation.id2), { relation: relation })
-  })
-  dagre.layout(g)
-  g.nodes().forEach(function (v) {
-    if (typeof v !== 'undefined') {
-      logger.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)) + ' )')
-    }
-  })
-  g.edges().forEach(function (e) {
-    logger.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(g.edge(e)))
-    drawEdge(diagram, g.edge(e), g.edge(e).relation)
-  })
-
-  diagram.attr('height', '100%')
-  diagram.attr('width', '100%')
-  diagram.attr('viewBox', '0 0 ' + (g.graph().width + 20) + ' ' + (g.graph().height + 20))
-}
-
-export default {
-  setConf,
-  draw
-}
diff --git a/_submodules/mermaid/src/diagrams/class/parser/classDiagram.jison b/_submodules/mermaid/src/diagrams/class/parser/classDiagram.jison
deleted file mode 100644
index f633d144cb260a86c0ffaf05fa80bfcc43825751..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/class/parser/classDiagram.jison
+++ /dev/null
@@ -1,196 +0,0 @@
-/** mermaid
- *  https://mermaidjs.github.io/
- *  (c) 2015 Knut Sveidqvist
- *  MIT license.
- */
-
-/* lexical grammar */
-%lex
-%x string struct
-
-%%
-\%\%[^\n]*            /* do nothing */
-\n+                   return 'NEWLINE';
-\s+                     /* skip whitespace */
-"classDiagram"          return 'CLASS_DIAGRAM';
-[\{]                    { this.begin("struct"); /*console.log('Starting struct');*/return 'STRUCT_START';}
-<struct>\}           { /*console.log('Ending struct');*/this.popState(); return 'STRUCT_STOP';}}
-<struct>[\n]              /* nothing */
-<struct>[^\{\}\n]*     { /*console.log('lex-member: ' + yytext);*/  return "MEMBER";}
-
-
-
-"class"               return 'CLASS';
-["]                   this.begin("string");
-<string>["]           this.popState();
-<string>[^"]*         return "STR";
-
-
-\s*\<\|               return 'EXTENSION';
-\s*\|\>               return 'EXTENSION';
-\s*\>                 return 'DEPENDENCY';
-\s*\<                 return 'DEPENDENCY';
-\s*\*                  return 'COMPOSITION';
-\s*o                  return 'AGGREGATION';
-\-\-                  return 'LINE';
-\.\.                  return 'DOTTED_LINE';
-":"[^#\n;]+        return 'LABEL';
-\-                    return 'MINUS';
-"."                   return 'DOT';
-\+                    return 'PLUS';
-\%                    return 'PCT';
-"="                   return 'EQUALS';
-\=                    return 'EQUALS';
-[A-Za-z]+             return 'ALPHA';
-[!"#$%&'*+,-.`?\\_/]  return 'PUNCTUATION';
-[0-9]+                 return 'NUM';
-[\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]
-                      return 'UNICODE_TEXT';
-\s                    return 'SPACE';
-<<EOF>>               return 'EOF';
-
-/lex
-
-/* operator associations and precedence */
-
-%left '^'
-
-%start mermaidDoc
-
-%% /* language grammar */
-
-mermaidDoc: graphConfig;
-
-graphConfig
-    : CLASS_DIAGRAM NEWLINE statements EOF
-    ;
-
-statements
-    : statement
-    | statement NEWLINE statements
-    ;
-
-
-className
-    : alphaNumToken className { $$=$1+$2; }
-    | alphaNumToken { $$=$1; }
-    ;
-
-statement
-    : relationStatement       { yy.addRelation($1); }
-    | relationStatement LABEL { $1.title =  yy.cleanupLabel($2); yy.addRelation($1);        }
-    | classStatement
-    | methodStatement
-    ;
-
-classStatement
-    : CLASS className
-    | CLASS className STRUCT_START members STRUCT_STOP {/*console.log($2,JSON.stringify($4));*/yy.addMembers($2,$4);}
-    ;
-
-members
-    : MEMBER { $$ = [$1]; }
-    | MEMBER members { $2.push($1);$$=$2;}
-    ;
-
-methodStatement
-    : className {/*console.log('Rel found',$1);*/}
-    | className LABEL {yy.addMembers($1,yy.cleanupLabel($2));}
-    | MEMBER {console.warn('Member',$1);}
-    | SEPARATOR {/*console.log('sep found',$1);*/}
-    ;
-
-relationStatement
-    : className relation className          { $$ = {'id1':$1,'id2':$3, relation:$2, relationTitle1:'none', relationTitle2:'none'}; }
-    | className STR relation className      { $$ = {id1:$1, id2:$4, relation:$3, relationTitle1:$2, relationTitle2:'none'}}
-    | className relation STR className      { $$ = {id1:$1, id2:$4, relation:$2, relationTitle1:'none', relationTitle2:$3}; }
-    | className STR relation STR className  { $$ = {id1:$1, id2:$5, relation:$3, relationTitle1:$2, relationTitle2:$4} }
-    ;
-
-relation
-    : relationType lineType relationType { $$={type1:$1,type2:$3,lineType:$2}; }
-    | lineType relationType { $$={type1:'none',type2:$2,lineType:$1}; }
-    | relationType lineType { $$={type1:$1,type2:'none',lineType:$2}; }
-    | lineType { $$={type1:'none',type2:'none',lineType:$1}; }
-    ;
-
-relationType
-    : AGGREGATION { $$=yy.relationType.AGGREGATION;}
-    | EXTENSION   { $$=yy.relationType.EXTENSION;}
-    | COMPOSITION { $$=yy.relationType.COMPOSITION;}
-    | DEPENDENCY  { $$=yy.relationType.DEPENDENCY;}
-    ;
-
-lineType
-    : LINE          {$$=yy.lineType.LINE;}
-    | DOTTED_LINE   {$$=yy.lineType.DOTTED_LINE;}
-    ;
-
-commentToken   : textToken | graphCodeTokens ;
-
-textToken      : textNoTagsToken | TAGSTART | TAGEND | '=='  | '--' | PCT | DEFAULT;
-
-textNoTagsToken: alphaNumToken | SPACE | MINUS | keywords ;
-
-alphaNumToken  : UNICODE_TEXT | NUM | ALPHA;
-%%
diff --git a/_submodules/mermaid/src/diagrams/class/parser/classDiagram.js b/_submodules/mermaid/src/diagrams/class/parser/classDiagram.js
deleted file mode 100644
index 5ff57a54d2a1b6d0baa3c3ce6a50f75381c4e3c9..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/class/parser/classDiagram.js
+++ /dev/null
@@ -1,740 +0,0 @@
-/* parser generated by jison 0.4.18 */
-/*
-  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 {
-        var error = new Error(str);
-        error.hash = hash;
-        throw error;
-    }
-},
-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;
-    }
-            function lex() {
-            var token;
-            token = tstack.pop() || lexer.lex() || EOF;
-            if (typeof token !== 'number') {
-                if (token instanceof Array) {
-                    tstack = token;
-                    token = tstack.pop();
-                }
-                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["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 = parser;
-exports.Parser = parser.Parser;
-exports.parse = function () { return parser.parse.apply(parser, 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));
-}
-}
\ No newline at end of file
diff --git a/_submodules/mermaid/src/diagrams/flowchart/flowDb.js b/_submodules/mermaid/src/diagrams/flowchart/flowDb.js
deleted file mode 100644
index 275e9c39df5c52839455f0adff0af0c4f131115f..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/flowchart/flowDb.js
+++ /dev/null
@@ -1,423 +0,0 @@
-import * as d3 from 'd3'
-
-import { logger } from '../../logger'
-import utils from '../../utils'
-
-let vertices = {}
-let edges = []
-let classes = []
-let subGraphs = []
-let tooltips = {}
-let subCount = 0
-let direction
-// Functions to be run after graph rendering
-let funs = []
-/**
- * Function called by parser when a node definition has been found
- * @param id
- * @param text
- * @param type
- * @param style
- */
-export const addVertex = function (id, text, type, style) {
-  let 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
- */
-export const addLink = function (start, end, type, linktext) {
-  logger.info('Got edge...', start, end)
-  const 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
- */
-export const 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
- */
-export const 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
-  }
-}
-
-export const 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
- */
-export const setDirection = function (dir) {
-  direction = dir
-}
-
-/**
- * Called by parser when a graph definition is found, stores the direction of the chart.
- * @param dir
- */
-export const 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)
-    }
-  }
-}
-
-const setTooltip = function (id, tooltip) {
-  if (typeof tooltip !== 'undefined') {
-    tooltips[id] = tooltip
-  }
-}
-
-const setClickFun = function (id, functionName) {
-  if (typeof functionName === 'undefined') {
-    return
-  }
-  if (typeof vertices[id] !== 'undefined') {
-    funs.push(function (element) {
-      const elem = d3.select(element).select(`[id="${id}"]`)
-      if (elem !== null) {
-        elem.on('click', function () {
-          window[functionName](id)
-        })
-      }
-    })
-  }
-}
-
-const setLink = function (id, linkStr) {
-  if (typeof linkStr === 'undefined') {
-    return
-  }
-  if (typeof vertices[id] !== 'undefined') {
-    funs.push(function (element) {
-      const elem = d3.select(element).select(`[id="${id}"]`)
-      if (elem !== null) {
-        elem.on('click', function () {
-          window.open(linkStr, 'newTab')
-        })
-      }
-    })
-  }
-}
-export const getTooltip = function (id) {
-  return tooltips[id]
-}
-
-/**
- * Called by parser when a graph definition is found, stores the direction of the chart.
- * @param dir
- */
-export const setClickEvent = function (id, functionName, link, tooltip) {
-  if (id.indexOf(',') > 0) {
-    id.split(',').forEach(function (id2) {
-      setTooltip(id2, tooltip)
-      setClickFun(id2, functionName)
-      setLink(id2, link)
-      setClass(id, 'clickable')
-    })
-  } else {
-    setTooltip(id, tooltip)
-    setClickFun(id, functionName)
-    setLink(id, link)
-    setClass(id, 'clickable')
-  }
-}
-
-export const bindFunctions = function (element) {
-  funs.forEach(function (fun) {
-    fun(element)
-  })
-}
-export const getDirection = function () {
-  return direction
-}
-/**
- * Retrieval function for fetching the found nodes after parsing has completed.
- * @returns {{}|*|vertices}
- */
-export const getVertices = function () {
-  return vertices
-}
-
-/**
- * Retrieval function for fetching the found links after parsing has completed.
- * @returns {{}|*|edges}
- */
-export const getEdges = function () {
-  return edges
-}
-
-/**
- * Retrieval function for fetching the found class definitions after parsing has completed.
- * @returns {{}|*|classes}
- */
-export const getClasses = function () {
-  return classes
-}
-
-const setupToolTips = function (element) {
-  let tooltipElem = d3.select('.mermaidTooltip')
-  if ((tooltipElem._groups || tooltipElem)[0][0] === null) {
-    tooltipElem = d3.select('body')
-      .append('div')
-      .attr('class', 'mermaidTooltip')
-      .style('opacity', 0)
-  }
-
-  const svg = d3.select(element).select('svg')
-
-  const nodes = svg.selectAll('g.node')
-  nodes
-    .on('mouseover', function () {
-      const el = d3.select(this)
-      const title = el.attr('title')
-      // Dont try to draw a tooltip if no data is provided
-      if (title === null) {
-        return
-      }
-      const 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)
-      const el = d3.select(this)
-      el.classed('hover', false)
-    })
-}
-funs.push(setupToolTips)
-
-/**
- * Clears the internal graph db so that a new graph can be parsed.
- */
-export const clear = function () {
-  vertices = {}
-  classes = {}
-  edges = []
-  funs = []
-  funs.push(setupToolTips)
-  subGraphs = []
-  subCount = 0
-  tooltips = []
-}
-/**
- *
- * @returns {string}
- */
-export const 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.
- */
-export const addSubGraph = function (list, title) {
-  function uniq (a) {
-    const prims = { 'boolean': {}, 'number': {}, 'string': {} }
-    const objs = []
-
-    return a.filter(function (item) {
-      const type = typeof item
-      if (item.trim() === '') {
-        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) }
-    })
-  }
-
-  let nodeList = []
-
-  nodeList = uniq(nodeList.concat.apply(nodeList, list))
-
-  const subGraph = { id: 'subGraph' + subCount, nodes: nodeList, title: title.trim() }
-  subGraphs.push(subGraph)
-  subCount = subCount + 1
-  return subGraph.id
-}
-
-const getPosForId = function (id) {
-  for (let i = 0; i < subGraphs.length; i++) {
-    if (subGraphs[i].id === id) {
-      return i
-    }
-  }
-  return -1
-}
-let secCount = -1
-const posCrossRef = []
-const indexNodes2 = function (id, pos) {
-  const 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
-    }
-  }
-
-  let count = 0
-  let posCount = 1
-  while (count < nodes.length) {
-    const childPos = getPosForId(nodes[count])
-    // Ignore regular nodes (pos will be -1)
-    if (childPos >= 0) {
-      const res = indexNodes2(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
-  }
-}
-
-export const getDepthFirstPos = function (pos) {
-  return posCrossRef[pos]
-}
-export const indexNodes = function () {
-  secCount = -1
-  if (subGraphs.length > 0) {
-    indexNodes2('none', subGraphs.length - 1, 0)
-  }
-}
-
-export const getSubGraphs = function () {
-  return subGraphs
-}
-
-export default {
-  addVertex,
-  addLink,
-  updateLinkInterpolate,
-  updateLink,
-  addClass,
-  setDirection,
-  setClass,
-  getTooltip,
-  setClickEvent,
-  bindFunctions,
-  getDirection,
-  getVertices,
-  getEdges,
-  getClasses,
-  clear,
-  defaultStyle,
-  addSubGraph,
-  getDepthFirstPos,
-  indexNodes,
-  getSubGraphs
-}
diff --git a/_submodules/mermaid/src/diagrams/flowchart/flowRenderer.js b/_submodules/mermaid/src/diagrams/flowchart/flowRenderer.js
deleted file mode 100644
index 2375265055373bbbc2a609e7717fe0a3eadd8069..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/flowchart/flowRenderer.js
+++ /dev/null
@@ -1,473 +0,0 @@
-import graphlib from 'graphlibrary'
-import * as d3 from 'd3'
-
-import flowDb from './flowDb'
-import flow from './parser/flow'
-import dagreD3 from 'dagre-d3-renderer'
-import { logger } from '../../logger'
-import { interpolateToCurve } from '../../utils'
-
-const conf = {
-}
-export const setConf = function (cnf) {
-  const keys = Object.keys(cnf)
-  for (let i = 0; i < keys.length; i++) {
-    conf[keys[i]] = cnf[keys[i]]
-  }
-}
-
-/**
- * Function that adds the vertices found in the graph definition to the graph to be rendered.
- * @param vert Object containing the vertices.
- * @param g The graph that is to be drawn.
- */
-export const addVertices = function (vert, g) {
-  const keys = Object.keys(vert)
-
-  const styleFromStyleArr = function (styleStr, arr) {
-    // Create a compound style definition from the style definitions found for the node in the graph definition
-    for (let i = 0; i < arr.length; i++) {
-      if (typeof arr[i] !== 'undefined') {
-        styleStr = styleStr + arr[i] + ';'
-      }
-    }
-
-    return styleStr
-  }
-
-  // Iterate through each item in the vertice object (containing all the vertices found) in the graph definition
-  keys.forEach(function (id) {
-    const vertice = vert[id]
-    let verticeText
-
-    /**
-     * Variable for storing the classes for the vertice
-     * @type {string}
-     */
-    let classStr = ''
-    if (vertice.classes.length > 0) {
-      classStr = vertice.classes.join(' ')
-    }
-
-    /**
-     * Variable for storing the extracted style for the vertice
-     * @type {string}
-     */
-    let style = ''
-    // Create a compound style definition from the style definitions found for the node in the graph definition
-    style = styleFromStyleArr(style, vertice.styles)
-
-    // Use vertice id as text in the box if no text is provided by the graph definition
-    if (typeof vertice.text === 'undefined') {
-      verticeText = vertice.id
-    } else {
-      verticeText = vertice.text
-    }
-
-    let labelTypeStr = ''
-    if (conf.htmlLabels) {
-      labelTypeStr = 'html'
-      verticeText = verticeText.replace(/fa:fa[\w-]+/g, function (s) {
-        return '<i class="fa ' + s.substring(3) + '"></i>'
-      })
-    } else {
-      const svgLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text')
-
-      const rows = verticeText.split(/<br>/)
-
-      for (let j = 0; j < rows.length; j++) {
-        const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan')
-        tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve')
-        tspan.setAttribute('dy', '1em')
-        tspan.setAttribute('x', '1')
-        tspan.textContent = rows[j]
-        svgLabel.appendChild(tspan)
-      }
-
-      labelTypeStr = 'svg'
-      verticeText = svgLabel
-    }
-
-    let radious = 0
-    let _shape = ''
-    // Set the shape based parameters
-    switch (vertice.type) {
-      case 'round':
-        radious = 5
-        _shape = 'rect'
-        break
-      case 'square':
-        _shape = 'rect'
-        break
-      case 'diamond':
-        _shape = 'question'
-        break
-      case 'odd':
-        _shape = 'rect_left_inv_arrow'
-        break
-      case 'odd_right':
-        _shape = 'rect_left_inv_arrow'
-        break
-      case 'circle':
-        _shape = 'circle'
-        break
-      case 'ellipse':
-        _shape = 'ellipse'
-        break
-      case 'group':
-        _shape = 'rect'
-        // Need to create a text node if using svg labels, see #367
-        verticeText = conf.htmlLabels ? '' : document.createElementNS('http://www.w3.org/2000/svg', 'text')
-        break
-      default:
-        _shape = 'rect'
-    }
-    // Add the node
-    g.setNode(vertice.id, { labelType: labelTypeStr, shape: _shape, label: verticeText, rx: radious, ry: radious, 'class': classStr, style: style, id: vertice.id })
-  })
-}
-
-/**
- * Add edges to graph based on parsed graph defninition
- * @param {Object} edges The edges to add to the graph
- * @param {Object} g The graph object
- */
-export const addEdges = function (edges, g) {
-  let cnt = 0
-
-  let defaultStyle
-  if (typeof edges.defaultStyle !== 'undefined') {
-    defaultStyle = edges.defaultStyle.toString().replace(/,/g, ';')
-  }
-
-  edges.forEach(function (edge) {
-    cnt++
-    const edgeData = {}
-
-    // Set link type for rendering
-    if (edge.type === 'arrow_open') {
-      edgeData.arrowhead = 'none'
-    } else {
-      edgeData.arrowhead = 'normal'
-    }
-
-    let style = ''
-    if (typeof edge.style !== 'undefined') {
-      edge.style.forEach(function (s) {
-        style = style + s + ';'
-      })
-    } else {
-      switch (edge.stroke) {
-        case 'normal':
-          style = 'fill:none'
-          if (typeof defaultStyle !== 'undefined') {
-            style = defaultStyle
-          }
-          break
-        case 'dotted':
-          style = 'stroke: #333; fill:none;stroke-width:2px;stroke-dasharray:3;'
-          break
-        case 'thick':
-          style = 'stroke: #333; stroke-width: 3.5px;fill:none'
-          break
-      }
-    }
-    edgeData.style = style
-
-    if (typeof edge.interpolate !== 'undefined') {
-      edgeData.curve = interpolateToCurve(edge.interpolate, d3.curveLinear)
-    } else if (typeof edges.defaultInterpolate !== 'undefined') {
-      edgeData.curve = interpolateToCurve(edges.defaultInterpolate, d3.curveLinear)
-    } else {
-      edgeData.curve = interpolateToCurve(conf.curve, d3.curveLinear)
-    }
-
-    if (typeof edge.text === 'undefined') {
-      if (typeof edge.style !== 'undefined') {
-        edgeData.arrowheadStyle = 'fill: #333'
-      }
-    } else {
-      edgeData.arrowheadStyle = 'fill: #333'
-      if (typeof edge.style === 'undefined') {
-        edgeData.labelpos = 'c'
-        if (conf.htmlLabels) {
-          edgeData.labelType = 'html'
-          edgeData.label = '<span class="edgeLabel">' + edge.text + '</span>'
-        } else {
-          edgeData.labelType = 'text'
-          edgeData.style = 'stroke: #333; stroke-width: 1.5px;fill:none'
-          edgeData.label = edge.text.replace(/<br>/g, '\n')
-        }
-      } else {
-        edgeData.label = edge.text.replace(/<br>/g, '\n')
-      }
-    }
-    // Add the edge to the graph
-    g.setEdge(edge.start, edge.end, edgeData, cnt)
-  })
-}
-
-/**
- * Returns the all the styles from classDef statements in the graph definition.
- * @returns {object} classDef styles
- */
-export const getClasses = function (text) {
-  flowDb.clear()
-  const parser = flow.parser
-  parser.yy = flowDb
-
-  // Parse the graph definition
-  parser.parse(text)
-  return flowDb.getClasses()
-}
-
-/**
- * Draws a flowchart in the tag with id: id based on the graph definition in text.
- * @param text
- * @param id
- */
-export const draw = function (text, id) {
-  logger.debug('Drawing flowchart')
-  flowDb.clear()
-  const parser = flow.parser
-  parser.yy = flowDb
-
-  // Parse the graph definition
-  try {
-    parser.parse(text)
-  } catch (err) {
-    logger.debug('Parsing failed')
-  }
-
-  // Fetch the default direction, use TD if none was found
-  let dir = flowDb.getDirection()
-  if (typeof dir === 'undefined') {
-    dir = 'TD'
-  }
-
-  // Create the input mermaid.graph
-  const g = new graphlib.Graph({
-    multigraph: true,
-    compound: true
-  })
-    .setGraph({
-      rankdir: dir,
-      marginx: 20,
-      marginy: 20
-
-    })
-    .setDefaultEdgeLabel(function () {
-      return {}
-    })
-
-  let subG
-  const subGraphs = flowDb.getSubGraphs()
-  for (let i = subGraphs.length - 1; i >= 0; i--) {
-    subG = subGraphs[i]
-    flowDb.addVertex(subG.id, subG.title, 'group', undefined)
-  }
-
-  // Fetch the verices/nodes and edges/links from the parsed graph definition
-  const vert = flowDb.getVertices()
-
-  const edges = flowDb.getEdges()
-
-  let i = 0
-  for (i = subGraphs.length - 1; i >= 0; i--) {
-    subG = subGraphs[i]
-
-    d3.selectAll('cluster').append('text')
-
-    for (let j = 0; j < subG.nodes.length; j++) {
-      g.setParent(subG.nodes[j], subG.id)
-    }
-  }
-  addVertices(vert, g)
-  addEdges(edges, g)
-
-  // Create the renderer
-  const Render = dagreD3.render
-  const render = new Render()
-
-  // Add custom shape for rhombus type of boc (decision)
-  render.shapes().question = function (parent, bbox, node) {
-    const w = bbox.width
-    const h = bbox.height
-    const s = (w + h) * 0.9
-    const points = [
-      { x: s / 2, y: 0 },
-      { x: s, y: -s / 2 },
-      { x: s / 2, y: -s },
-      { x: 0, y: -s / 2 }
-    ]
-    const shapeSvg = parent.insert('polygon', ':first-child')
-      .attr('points', points.map(function (d) {
-        return d.x + ',' + d.y
-      }).join(' '))
-      .attr('rx', 5)
-      .attr('ry', 5)
-      .attr('transform', 'translate(' + (-s / 2) + ',' + (s * 2 / 4) + ')')
-    node.intersect = function (point) {
-      return dagreD3.intersect.polygon(node, points, point)
-    }
-    return shapeSvg
-  }
-
-  // Add custom shape for box with inverted arrow on left side
-  render.shapes().rect_left_inv_arrow = function (parent, bbox, node) {
-    const w = bbox.width
-    const h = bbox.height
-    const points = [
-      { x: -h / 2, y: 0 },
-      { x: w, y: 0 },
-      { x: w, y: -h },
-      { x: -h / 2, y: -h },
-      { x: 0, y: -h / 2 }
-    ]
-    const shapeSvg = parent.insert('polygon', ':first-child')
-      .attr('points', points.map(function (d) {
-        return d.x + ',' + d.y
-      }).join(' '))
-      .attr('transform', 'translate(' + (-w / 2) + ',' + (h * 2 / 4) + ')')
-    node.intersect = function (point) {
-      return dagreD3.intersect.polygon(node, points, point)
-    }
-    return shapeSvg
-  }
-
-  // Add custom shape for box with inverted arrow on right side
-  render.shapes().rect_right_inv_arrow = function (parent, bbox, node) {
-    const w = bbox.width
-    const h = bbox.height
-    const points = [
-      { x: 0, y: 0 },
-      { x: w + h / 2, y: 0 },
-      { x: w, y: -h / 2 },
-      { x: w + h / 2, y: -h },
-      { x: 0, y: -h }
-    ]
-    const shapeSvg = parent.insert('polygon', ':first-child')
-      .attr('points', points.map(function (d) {
-        return d.x + ',' + d.y
-      }).join(' '))
-      .attr('transform', 'translate(' + (-w / 2) + ',' + (h * 2 / 4) + ')')
-    node.intersect = function (point) {
-      return dagreD3.intersect.polygon(node, points, point)
-    }
-    return shapeSvg
-  }
-
-  // Add our custom arrow - an empty arrowhead
-  render.arrows().none = function normal (parent, id, edge, type) {
-    const marker = parent.append('marker')
-      .attr('id', id)
-      .attr('viewBox', '0 0 10 10')
-      .attr('refX', 9)
-      .attr('refY', 5)
-      .attr('markerUnits', 'strokeWidth')
-      .attr('markerWidth', 8)
-      .attr('markerHeight', 6)
-      .attr('orient', 'auto')
-
-    const path = marker.append('path')
-      .attr('d', 'M 0 0 L 0 0 L 0 0 z')
-    dagreD3.util.applyStyle(path, edge[type + 'Style'])
-  }
-
-  // Override normal arrowhead defined in d3. Remove style & add class to allow css styling.
-  render.arrows().normal = function normal (parent, id, edge, type) {
-    const marker = parent.append('marker')
-      .attr('id', id)
-      .attr('viewBox', '0 0 10 10')
-      .attr('refX', 9)
-      .attr('refY', 5)
-      .attr('markerUnits', 'strokeWidth')
-      .attr('markerWidth', 8)
-      .attr('markerHeight', 6)
-      .attr('orient', 'auto')
-
-    marker.append('path')
-      .attr('d', 'M 0 0 L 10 5 L 0 10 z')
-      .attr('class', 'arrowheadPath')
-      .style('stroke-width', 1)
-      .style('stroke-dasharray', '1,0')
-  }
-
-  // Set up an SVG group so that we can translate the final graph.
-  const svg = d3.select(`[id="${id}"]`)
-
-  // Run the renderer. This is what draws the final graph.
-  const element = d3.select('#' + id + ' g')
-  render(element, g)
-
-  element.selectAll('g.node')
-    .attr('title', function () {
-      return flowDb.getTooltip(this.id)
-    })
-
-  const padding = 8
-  const width = g.maxX - g.minX + padding * 2
-  const height = g.maxY - g.minY + padding * 2
-  svg.attr('width', '100%')
-  svg.attr('style', `max-width: ${width}px;`)
-  svg.attr('viewBox', `0 0 ${width} ${height}`)
-  svg.select('g').attr('transform', `translate(${padding - g.minX}, ${padding - g.minY})`)
-
-  // Index nodes
-  flowDb.indexNodes('subGraph' + i)
-
-  for (i = 0; i < subGraphs.length; i++) {
-    subG = subGraphs[i]
-
-    if (subG.title !== 'undefined') {
-      const clusterRects = document.querySelectorAll('#' + id + ' #' + subG.id + ' rect')
-      const clusterEl = document.querySelectorAll('#' + id + ' #' + subG.id)
-
-      const xPos = clusterRects[0].x.baseVal.value
-      const yPos = clusterRects[0].y.baseVal.value
-      const width = clusterRects[0].width.baseVal.value
-      const cluster = d3.select(clusterEl[0])
-      const te = cluster.append('text')
-      te.attr('x', xPos + width / 2)
-      te.attr('y', yPos + 14)
-      te.attr('fill', 'black')
-      te.attr('stroke', 'none')
-      te.attr('id', id + 'Text')
-      te.style('text-anchor', 'middle')
-
-      if (typeof subG.title === 'undefined') {
-        te.text('Undef')
-      } else {
-        te.text(subG.title)
-      }
-    }
-  }
-
-  // Add label rects for non html labels
-  if (!conf.htmlLabels) {
-    const labels = document.querySelectorAll('#' + id + ' .edgeLabel .label')
-    for (let k = 0; k < labels.length; k++) {
-      const label = labels[k]
-
-      // Get dimensions of label
-      const dim = label.getBBox()
-
-      const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
-      rect.setAttribute('rx', 0)
-      rect.setAttribute('ry', 0)
-      rect.setAttribute('width', dim.width)
-      rect.setAttribute('height', dim.height)
-      rect.setAttribute('style', 'fill:#e8e8e8;')
-
-      label.insertBefore(rect, label.firstChild)
-    }
-  }
-}
-
-export default {
-  setConf,
-  addVertices,
-  addEdges,
-  getClasses,
-  draw
-}
diff --git a/_submodules/mermaid/src/diagrams/flowchart/parser/flow.jison b/_submodules/mermaid/src/diagrams/flowchart/parser/flow.jison
deleted file mode 100644
index 0bbb4281eafe0d5cf53a1b1f842e11d9acd455b1..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/flowchart/parser/flow.jison
+++ /dev/null
@@ -1,452 +0,0 @@
-/** mermaid
- *  https://mermaidjs.github.io/
- *  (c) 2015 Knut Sveidqvist
- *  MIT license.
- */
-
-/* lexical grammar */
-%lex
-%x string
-
-%%
-\%\%[^\n]*            /* do nothing */
-["]                     this.begin("string");
-<string>["]             this.popState();
-<string>[^"]*           return "STR";
-"style"               return 'STYLE';
-"default"             return 'DEFAULT';
-"linkStyle"           return 'LINKSTYLE';
-"interpolate"         return 'INTERPOLATE';
-"classDef"            return 'CLASSDEF';
-"class"               return 'CLASS';
-"click"               return 'CLICK';
-"graph"               return 'GRAPH';
-"subgraph"            return 'subgraph';
-"end"\b\s*            return 'end';
-"LR"                  return 'DIR';
-"RL"                  return 'DIR';
-"TB"                  return 'DIR';
-"BT"                  return 'DIR';
-"TD"                  return 'DIR';
-"BR"                  return 'DIR';
-[0-9]+                 return 'NUM';
-\#                    return 'BRKT';
-":"                   return 'COLON';
-";"                   return 'SEMI';
-","                   return 'COMMA';
-"*"                   return 'MULT';
-"<"                   return 'TAGSTART';
-">"                   return 'TAGEND';
-"^"                   return 'UP';
-"v"                   return 'DOWN';
-\s*\-\-[x]\s*            return 'ARROW_CROSS';
-\s*\-\-\>\s*             return 'ARROW_POINT';
-\s*\-\-[o]\s*            return 'ARROW_CIRCLE';
-\s*\-\-\-\s*             return 'ARROW_OPEN';
-\s*\-\.\-[x]\s*          return 'DOTTED_ARROW_CROSS';
-\s*\-\.\-\>\s*           return 'DOTTED_ARROW_POINT';
-\s*\-\.\-[o]\s*          return 'DOTTED_ARROW_CIRCLE';
-\s*\-\.\-\s*             return 'DOTTED_ARROW_OPEN';
-\s*.\-[x]\s*             return 'DOTTED_ARROW_CROSS';
-\s*\.\-\>\s*             return 'DOTTED_ARROW_POINT';
-\s*\.\-[o]\s*            return 'DOTTED_ARROW_CIRCLE';
-\s*\.\-\s*               return 'DOTTED_ARROW_OPEN';
-\s*\=\=[x]\s*            return 'THICK_ARROW_CROSS';
-\s*\=\=\>\s*             return 'THICK_ARROW_POINT';
-\s*\=\=[o]\s*            return 'THICK_ARROW_CIRCLE';
-\s*\=\=[\=]\s*           return 'THICK_ARROW_OPEN';
-\s*\-\-\s*               return '--';
-\s*\-\.\s*               return '-.';
-\s*\=\=\s*               return '==';
-"(-"                  return '(-';
-"-)"                  return '-)';
-\-                    return 'MINUS';
-"."                   return 'DOT';
-\+                    return 'PLUS';
-\%                    return 'PCT';
-"="                   return 'EQUALS';
-\=                    return 'EQUALS';
-[A-Za-z]+             return 'ALPHA';
-[!"#$%&'*+,-.`?\\_/]  return 'PUNCTUATION';
-[\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]
-                      return 'UNICODE_TEXT';
-"|"                   return 'PIPE';
-"("                   return 'PS';
-")"                   return 'PE';
-"["                   return 'SQS';
-"]"                   return 'SQE';
-"{"                   return 'DIAMOND_START'
-"}"                   return 'DIAMOND_STOP'
-"\""                  return 'QUOTE';
-\n+                   return 'NEWLINE';
-\s                    return 'SPACE';
-<<EOF>>               return 'EOF';
-
-/lex
-
-/* operator associations and precedence */
-
-%left '^'
-
-%start mermaidDoc
-
-%% /* language grammar */
-
-mermaidDoc: graphConfig document;
-
-document
-	: /* empty */
-	{ $$ = [];}
-	| document line
-	{
-	    if($2 !== []){
-	        $1.push($2);
-	    }
-	    $$=$1;}
-	;
-
-line
-	: statement
-	{$$=$1;}
-	| SEMI
-	| NEWLINE
-	| SPACE
-	| EOF
-	;
-
-graphConfig
-    : SPACE graphConfig
-    | NEWLINE graphConfig
-    | GRAPH SPACE DIR FirstStmtSeperator
-        { yy.setDirection($3);$$ = $3;}
-    | GRAPH SPACE TAGEND FirstStmtSeperator
-        { yy.setDirection("LR");$$ = $3;}
-    | GRAPH SPACE TAGSTART FirstStmtSeperator
-        { yy.setDirection("RL");$$ = $3;}
-    | GRAPH SPACE UP FirstStmtSeperator
-        { yy.setDirection("BT");$$ = $3;}
-    | GRAPH SPACE DOWN FirstStmtSeperator
-        { yy.setDirection("TB");$$ = $3;}
-    ;
-
-ending: endToken ending
-      | endToken
-      ;
-
-endToken: NEWLINE | SPACE | EOF;
-
-FirstStmtSeperator
-    : SEMI | NEWLINE | spaceList NEWLINE ;
-
-
-spaceListNewline
-    : SPACE spaceListNewline
-    | NEWLINE spaceListNewline
-    | NEWLINE
-    | SPACE
-    ;
-
-
-spaceList
-    : SPACE spaceList
-    | SPACE
-    ;
-
-statement
-    : verticeStatement separator
-    {$$=$1}
-    | styleStatement separator
-    {$$=[];}
-    | linkStyleStatement separator
-    {$$=[];}
-    | classDefStatement separator
-    {$$=[];}
-    | classStatement separator
-    {$$=[];}
-    | clickStatement separator
-    {$$=[];}
-    | subgraph text separator document end
-    {$$=yy.addSubGraph($4,$2);}
-    | subgraph separator document end
-    {$$=yy.addSubGraph($3,undefined);}
-    ;
-
-separator: NEWLINE | SEMI | EOF ;
-
-verticeStatement:
-     vertex link vertex
-        { yy.addLink($1,$3,$2);$$ = [$1,$3];}
-     | vertex
-        {$$ = [$1];}
-    ;
-
-vertex:  alphaNum SQS text SQE
-        {$$ = $1;yy.addVertex($1,$3,'square');}
-    |  alphaNum SQS text SQE spaceList
-        {$$ = $1;yy.addVertex($1,$3,'square');}
-    | alphaNum PS PS text PE PE
-        {$$ = $1;yy.addVertex($1,$4,'circle');}
-    | alphaNum PS PS text PE PE spaceList
-        {$$ = $1;yy.addVertex($1,$4,'circle');}
-    | alphaNum '(-' text '-)'
-        {$$ = $1;yy.addVertex($1,$3,'ellipse');}
-    | alphaNum '(-' text '-)' spaceList
-        {$$ = $1;yy.addVertex($1,$3,'ellipse');}
-    | alphaNum PS text PE
-        {$$ = $1;yy.addVertex($1,$3,'round');}
-    | alphaNum PS text PE spaceList
-        {$$ = $1;yy.addVertex($1,$3,'round');}
-    | alphaNum DIAMOND_START text DIAMOND_STOP
-        {$$ = $1;yy.addVertex($1,$3,'diamond');}
-    | alphaNum DIAMOND_START text DIAMOND_STOP spaceList
-        {$$ = $1;yy.addVertex($1,$3,'diamond');}
-    | alphaNum TAGEND text SQE
-        {$$ = $1;yy.addVertex($1,$3,'odd');}
-    | alphaNum TAGEND text SQE spaceList
-        {$$ = $1;yy.addVertex($1,$3,'odd');}
-/*  | alphaNum SQS text TAGSTART
-        {$$ = $1;yy.addVertex($1,$3,'odd_right');}
-    | alphaNum SQS text TAGSTART spaceList
-        {$$ = $1;yy.addVertex($1,$3,'odd_right');} */
-    | alphaNum
-        {$$ = $1;yy.addVertex($1);}
-    | alphaNum spaceList
-        {$$ = $1;yy.addVertex($1);}
-    ;
-
-alphaNum
-    : alphaNumStatement
-    {$$=$1;}
-    | alphaNum alphaNumStatement
-    {$$=$1+''+$2;}
-    ;
-
-alphaNumStatement
-    : DIR
-        {$$=$1;}
-    | alphaNumToken
-        {$$=$1;}
-    | DOWN
-        {$$='v';}
-    | MINUS
-        {$$='-';}
-    ;
-
-link: linkStatement arrowText
-    {$1.text = $2;$$ = $1;}
-    | linkStatement TESTSTR SPACE
-    {$1.text = $2;$$ = $1;}
-    | linkStatement arrowText SPACE
-    {$1.text = $2;$$ = $1;}
-    | linkStatement
-    {$$ = $1;}
-    | '--' text ARROW_POINT
-        {$$ = {"type":"arrow","stroke":"normal","text":$2};}
-    | '--' text ARROW_CIRCLE
-        {$$ = {"type":"arrow_circle","stroke":"normal","text":$2};}
-    | '--' text ARROW_CROSS
-        {$$ = {"type":"arrow_cross","stroke":"normal","text":$2};}
-    | '--' text ARROW_OPEN
-        {$$ = {"type":"arrow_open","stroke":"normal","text":$2};}
-    | '-.' text DOTTED_ARROW_POINT
-        {$$ = {"type":"arrow","stroke":"dotted","text":$2};}
-    | '-.' text DOTTED_ARROW_CIRCLE
-        {$$ = {"type":"arrow_circle","stroke":"dotted","text":$2};}
-    | '-.' text DOTTED_ARROW_CROSS
-        {$$ = {"type":"arrow_cross","stroke":"dotted","text":$2};}
-    | '-.' text DOTTED_ARROW_OPEN
-        {$$ = {"type":"arrow_open","stroke":"dotted","text":$2};}
-    | '==' text THICK_ARROW_POINT
-        {$$ = {"type":"arrow","stroke":"thick","text":$2};}
-    | '==' text THICK_ARROW_CIRCLE
-        {$$ = {"type":"arrow_circle","stroke":"thick","text":$2};}
-    | '==' text THICK_ARROW_CROSS
-        {$$ = {"type":"arrow_cross","stroke":"thick","text":$2};}
-    | '==' text THICK_ARROW_OPEN
-        {$$ = {"type":"arrow_open","stroke":"thick","text":$2};}
-    ;
-
-linkStatement: ARROW_POINT
-        {$$ = {"type":"arrow","stroke":"normal"};}
-    | ARROW_CIRCLE
-        {$$ = {"type":"arrow_circle","stroke":"normal"};}
-    | ARROW_CROSS
-        {$$ = {"type":"arrow_cross","stroke":"normal"};}
-    | ARROW_OPEN
-        {$$ = {"type":"arrow_open","stroke":"normal"};}
-    | DOTTED_ARROW_POINT
-        {$$ = {"type":"arrow","stroke":"dotted"};}
-    | DOTTED_ARROW_CIRCLE
-        {$$ = {"type":"arrow_circle","stroke":"dotted"};}
-    | DOTTED_ARROW_CROSS
-        {$$ = {"type":"arrow_cross","stroke":"dotted"};}
-    | DOTTED_ARROW_OPEN
-        {$$ = {"type":"arrow_open","stroke":"dotted"};}
-    | THICK_ARROW_POINT
-        {$$ = {"type":"arrow","stroke":"thick"};}
-    | THICK_ARROW_CIRCLE
-        {$$ = {"type":"arrow_circle","stroke":"thick"};}
-    | THICK_ARROW_CROSS
-        {$$ = {"type":"arrow_cross","stroke":"thick"};}
-    | THICK_ARROW_OPEN
-        {$$ = {"type":"arrow_open","stroke":"thick"};}
-        ;
-
-arrowText:
-    PIPE text PIPE
-    {$$ = $2;}
-    ;
-
-text: textToken
-    {$$=$1;}
-    | text textToken
-    {$$=$1+''+$2;}
-    | STR
-    {$$=$1;}
-    ;
-
-
-
-commentText: commentToken
-    {$$=$1;}
-    | commentText commentToken
-    {$$=$1+''+$2;}
-    ;
-
-
-keywords
-    : STYLE | LINKSTYLE | CLASSDEF | CLASS | CLICK | GRAPH | DIR | subgraph | end | DOWN | UP;
-
-
-textNoTags: textNoTagsToken
-    {$$=$1;}
-    | textNoTags textNoTagsToken
-    {$$=$1+''+$2;}
-    ;
-
-
-classDefStatement:CLASSDEF SPACE DEFAULT SPACE stylesOpt
-    {$$ = $1;yy.addClass($3,$5);}
-    | CLASSDEF SPACE alphaNum SPACE stylesOpt
-          {$$ = $1;yy.addClass($3,$5);}
-    ;
-
-classStatement:CLASS SPACE alphaNum SPACE alphaNum
-    {$$ = $1;yy.setClass($3, $5);}
-    ;
-
-clickStatement
-    : CLICK SPACE alphaNum SPACE alphaNum           {$$ = $1;yy.setClickEvent($3,        $5, undefined, undefined);}
-    | CLICK SPACE alphaNum SPACE alphaNum SPACE STR {$$ = $1;yy.setClickEvent($3,        $5, undefined, $7)       ;}
-    | CLICK SPACE alphaNum SPACE STR                {$$ = $1;yy.setClickEvent($3, undefined,        $5, undefined);}
-    | CLICK SPACE alphaNum SPACE STR SPACE STR      {$$ = $1;yy.setClickEvent($3, undefined,        $5, $7       );}
-    ;
-
-styleStatement:STYLE SPACE alphaNum SPACE stylesOpt
-    {$$ = $1;yy.addVertex($3,undefined,undefined,$5);}
-    | STYLE SPACE HEX SPACE stylesOpt
-          {$$ = $1;yy.updateLink($3,$5);}
-    ;
-
-linkStyleStatement
-    : LINKSTYLE SPACE DEFAULT SPACE stylesOpt
-          {$$ = $1;yy.updateLink($3,$5);}
-    | LINKSTYLE SPACE NUM SPACE stylesOpt
-          {$$ = $1;yy.updateLink($3,$5);}
-    | LINKSTYLE SPACE DEFAULT SPACE INTERPOLATE SPACE alphaNum SPACE stylesOpt
-          {$$ = $1;yy.updateLinkInterpolate($3,$7);yy.updateLink($3,$9);}
-    | LINKSTYLE SPACE NUM SPACE INTERPOLATE SPACE alphaNum SPACE stylesOpt
-          {$$ = $1;yy.updateLinkInterpolate($3,$7);yy.updateLink($3,$9);}
-    | LINKSTYLE SPACE DEFAULT SPACE INTERPOLATE SPACE alphaNum
-          {$$ = $1;yy.updateLinkInterpolate($3,$7);}
-    | LINKSTYLE SPACE NUM SPACE INTERPOLATE SPACE alphaNum
-          {$$ = $1;yy.updateLinkInterpolate($3,$7);}
-    ;
-
-commentStatement: PCT PCT commentText;
-
-stylesOpt: style
-        {$$ = [$1]}
-    | stylesOpt COMMA style
-        {$1.push($3);$$ = $1;}
-    ;
-
-style: styleComponent
-    |style styleComponent
-    {$$ = $1 + $2;}
-    ;
-
-styleComponent: ALPHA | COLON | MINUS | NUM | UNIT | SPACE | HEX | BRKT | DOT | STYLE | PCT ;
-
-/* Token lists */
-
-commentToken   : textToken | graphCodeTokens ;
-
-textToken      : textNoTagsToken | TAGSTART | TAGEND | '=='  | '--' | PCT | DEFAULT;
-
-textNoTagsToken: alphaNumToken | SPACE | MINUS | keywords ;
-
-alphaNumToken  : ALPHA | PUNCTUATION | UNICODE_TEXT | NUM | COLON | COMMA | PLUS | EQUALS | MULT | DOT | BRKT ;
-
-graphCodeTokens:  PIPE | PS | PE | SQS | SQE | DIAMOND_START | DIAMOND_STOP | TAG_START | TAG_END | ARROW_CROSS | ARROW_POINT | ARROW_CIRCLE | ARROW_OPEN | QUOTE | SEMI ;
-%%
diff --git a/_submodules/mermaid/src/diagrams/flowchart/parser/flow.js b/_submodules/mermaid/src/diagrams/flowchart/parser/flow.js
deleted file mode 100644
index f45c6fd71d64f1a4567f1f0c4ffd65c44331166f..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/flowchart/parser/flow.js
+++ /dev/null
@@ -1,961 +0,0 @@
-/* parser generated by jison 0.4.18 */
-/*
-  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,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:
- yy.addLink($$[$0-2],$$[$0],$$[$0-1]);this.$ = [$$[$0-2],$$[$0]];
-break;
-case 42:
-this.$ = [$$[$0]];
-break;
-case 43:
-this.$ = $$[$0-3];yy.addVertex($$[$0-3],$$[$0-1],'square');
-break;
-case 44:
-this.$ = $$[$0-4];yy.addVertex($$[$0-4],$$[$0-2],'square');
-break;
-case 45:
-this.$ = $$[$0-5];yy.addVertex($$[$0-5],$$[$0-2],'circle');
-break;
-case 46:
-this.$ = $$[$0-6];yy.addVertex($$[$0-6],$$[$0-3],'circle');
-break;
-case 47:
-this.$ = $$[$0-3];yy.addVertex($$[$0-3],$$[$0-1],'ellipse');
-break;
-case 48:
-this.$ = $$[$0-4];yy.addVertex($$[$0-4],$$[$0-2],'ellipse');
-break;
-case 49:
-this.$ = $$[$0-3];yy.addVertex($$[$0-3],$$[$0-1],'round');
-break;
-case 50:
-this.$ = $$[$0-4];yy.addVertex($$[$0-4],$$[$0-2],'round');
-break;
-case 51:
-this.$ = $$[$0-3];yy.addVertex($$[$0-3],$$[$0-1],'diamond');
-break;
-case 52:
-this.$ = $$[$0-4];yy.addVertex($$[$0-4],$$[$0-2],'diamond');
-break;
-case 53:
-this.$ = $$[$0-3];yy.addVertex($$[$0-3],$$[$0-1],'odd');
-break;
-case 54:
-this.$ = $$[$0-4];yy.addVertex($$[$0-4],$$[$0-2],'odd');
-break;
-case 55:
-this.$ = $$[$0];yy.addVertex($$[$0]);
-break;
-case 56:
-this.$ = $$[$0-1];yy.addVertex($$[$0-1]);
-break;
-case 58: case 93: case 96: case 109:
-this.$=$$[$0-1]+''+$$[$0];
-break;
-case 61:
-this.$='v';
-break;
-case 62:
-this.$='-';
-break;
-case 63:
-$$[$0-1].text = $$[$0];this.$ = $$[$0-1];
-break;
-case 64: case 65:
-$$[$0-2].text = $$[$0-1];this.$ = $$[$0-2];
-break;
-case 66:
-this.$ = $$[$0];
-break;
-case 67:
-this.$ = {"type":"arrow","stroke":"normal","text":$$[$0-1]};
-break;
-case 68:
-this.$ = {"type":"arrow_circle","stroke":"normal","text":$$[$0-1]};
-break;
-case 69:
-this.$ = {"type":"arrow_cross","stroke":"normal","text":$$[$0-1]};
-break;
-case 70:
-this.$ = {"type":"arrow_open","stroke":"normal","text":$$[$0-1]};
-break;
-case 71:
-this.$ = {"type":"arrow","stroke":"dotted","text":$$[$0-1]};
-break;
-case 72:
-this.$ = {"type":"arrow_circle","stroke":"dotted","text":$$[$0-1]};
-break;
-case 73:
-this.$ = {"type":"arrow_cross","stroke":"dotted","text":$$[$0-1]};
-break;
-case 74:
-this.$ = {"type":"arrow_open","stroke":"dotted","text":$$[$0-1]};
-break;
-case 75:
-this.$ = {"type":"arrow","stroke":"thick","text":$$[$0-1]};
-break;
-case 76:
-this.$ = {"type":"arrow_circle","stroke":"thick","text":$$[$0-1]};
-break;
-case 77:
-this.$ = {"type":"arrow_cross","stroke":"thick","text":$$[$0-1]};
-break;
-case 78:
-this.$ = {"type":"arrow_open","stroke":"thick","text":$$[$0-1]};
-break;
-case 79:
-this.$ = {"type":"arrow","stroke":"normal"};
-break;
-case 80:
-this.$ = {"type":"arrow_circle","stroke":"normal"};
-break;
-case 81:
-this.$ = {"type":"arrow_cross","stroke":"normal"};
-break;
-case 82:
-this.$ = {"type":"arrow_open","stroke":"normal"};
-break;
-case 83:
-this.$ = {"type":"arrow","stroke":"dotted"};
-break;
-case 84:
-this.$ = {"type":"arrow_circle","stroke":"dotted"};
-break;
-case 85:
-this.$ = {"type":"arrow_cross","stroke":"dotted"};
-break;
-case 86:
-this.$ = {"type":"arrow_open","stroke":"dotted"};
-break;
-case 87:
-this.$ = {"type":"arrow","stroke":"thick"};
-break;
-case 88:
-this.$ = {"type":"arrow_circle","stroke":"thick"};
-break;
-case 89:
-this.$ = {"type":"arrow_cross","stroke":"thick"};
-break;
-case 90:
-this.$ = {"type":"arrow_open","stroke":"thick"};
-break;
-case 91:
-this.$ = $$[$0-1];
-break;
-case 110: case 111:
-this.$ = $$[$0-4];yy.addClass($$[$0-2],$$[$0]);
-break;
-case 112:
-this.$ = $$[$0-4];yy.setClass($$[$0-2], $$[$0]);
-break;
-case 113:
-this.$ = $$[$0-4];yy.setClickEvent($$[$0-2],        $$[$0], undefined, undefined);
-break;
-case 114:
-this.$ = $$[$0-6];yy.setClickEvent($$[$0-4],        $$[$0-2], undefined, $$[$0])       ;
-break;
-case 115:
-this.$ = $$[$0-4];yy.setClickEvent($$[$0-2], undefined,        $$[$0], undefined);
-break;
-case 116:
-this.$ = $$[$0-6];yy.setClickEvent($$[$0-4], undefined,        $$[$0-2], $$[$0]       );
-break;
-case 117:
-this.$ = $$[$0-4];yy.addVertex($$[$0-2],undefined,undefined,$$[$0]);
-break;
-case 118: case 119: case 120:
-this.$ = $$[$0-4];yy.updateLink($$[$0-2],$$[$0]);
-break;
-case 121: case 122:
-this.$ = $$[$0-8];yy.updateLinkInterpolate($$[$0-6],$$[$0-2]);yy.updateLink($$[$0-6],$$[$0]);
-break;
-case 123: case 124:
-this.$ = $$[$0-6];yy.updateLinkInterpolate($$[$0-4],$$[$0]);
-break;
-case 126:
-this.$ = [$$[$0]]
-break;
-case 127:
-$$[$0-2].push($$[$0]);this.$ = $$[$0-2];
-break;
-case 129:
-this.$ = $$[$0-1] + $$[$0];
-break;
-}
-},
-table: [{3:1,4:2,9:$V0,10:$V1,12:$V2},{1:[3]},o($V3,$V4,{5:6}),{4:7,9:$V0,10:$V1,12:$V2},{4:8,9:$V0,10:$V1,12:$V2},{10:[1,9]},{1:[2,1],6:10,7:11,8:$V5,9:$V6,10:$V7,11:$V8,13:$V9,18:$Va,23:16,25:17,26:18,27:19,28:20,29:21,30:$Vb,33:23,35:29,44:30,45:32,46:$Vc,71:$Vd,72:$Ve,73:$Vf,74:$Vg,75:$Vh,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($V3,[2,9]),o($V3,[2,10]),{13:[1,46],15:[1,47],16:[1,48],17:[1,49],18:[1,50]},o($Vt,[2,3]),o($Vt,[2,4]),o($Vt,[2,5]),o($Vt,[2,6]),o($Vt,[2,7]),o($Vt,[2,8]),{8:$Vu,9:$Vv,11:$Vw,24:51},{8:$Vu,9:$Vv,11:$Vw,24:55},{8:$Vu,9:$Vv,11:$Vw,24:56},{8:$Vu,9:$Vv,11:$Vw,24:57},{8:$Vu,9:$Vv,11:$Vw,24:58},{8:$Vu,9:$Vv,11:$Vw,24:59},{8:$Vu,9:$Vv,10:$Vx,11:$Vw,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,24:61,30:$VE,31:60,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($VR,[2,42],{34:86,47:87,50:[1,88],51:[1,91],52:[1,92],53:[1,93],54:[1,94],55:[1,89],56:[1,95],57:[1,96],58:[1,97],59:[1,98],60:[1,90],61:[1,99],62:[1,100],63:[1,101],64:[1,102]}),{10:[1,103]},{10:[1,104]},{10:[1,105]},{10:[1,106]},{10:[1,107]},o($VS,[2,55],{45:32,21:113,44:114,10:$VT,13:$V9,15:[1,112],18:$Va,36:[1,108],38:[1,109],40:[1,110],42:[1,111],46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs}),o($VU,[2,57]),o($VU,[2,59]),o($VU,[2,60]),o($VU,[2,61]),o($VU,[2,62]),o($VV,[2,154]),o($VV,[2,155]),o($VV,[2,156]),o($VV,[2,157]),o($VV,[2,158]),o($VV,[2,159]),o($VV,[2,160]),o($VV,[2,161]),o($VV,[2,162]),o($VV,[2,163]),o($VV,[2,164]),{8:$VW,9:$VX,10:$VT,14:116,21:119},{8:$VW,9:$VX,10:$VT,14:120,21:119},{8:$VW,9:$VX,10:$VT,14:121,21:119},{8:$VW,9:$VX,10:$VT,14:122,21:119},{8:$VW,9:$VX,10:$VT,14:123,21:119},o($Vt,[2,30]),o($Vt,[2,38]),o($Vt,[2,39]),o($Vt,[2,40]),o($Vt,[2,31]),o($Vt,[2,32]),o($Vt,[2,33]),o($Vt,[2,34]),o($Vt,[2,35]),{8:$Vu,9:$Vv,10:$Vx,11:$Vw,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,24:124,30:$VE,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($VY,$V4,{5:126}),o($VZ,[2,92]),o($VZ,[2,94]),o($VZ,[2,143]),o($VZ,[2,144]),o($VZ,[2,145]),o($VZ,[2,146]),o($VZ,[2,147]),o($VZ,[2,148]),o($VZ,[2,149]),o($VZ,[2,150]),o($VZ,[2,151]),o($VZ,[2,152]),o($VZ,[2,153]),o($VZ,[2,97]),o($VZ,[2,98]),o($VZ,[2,99]),o($VZ,[2,100]),o($VZ,[2,101]),o($VZ,[2,102]),o($VZ,[2,103]),o($VZ,[2,104]),o($VZ,[2,105]),o($VZ,[2,106]),o($VZ,[2,107]),{13:$V9,18:$Va,33:127,35:29,44:30,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($V_,[2,66],{48:128,49:[1,129],65:[1,130]}),{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:131,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:132,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:133,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($V$,[2,79]),o($V$,[2,80]),o($V$,[2,81]),o($V$,[2,82]),o($V$,[2,83]),o($V$,[2,84]),o($V$,[2,85]),o($V$,[2,86]),o($V$,[2,87]),o($V$,[2,88]),o($V$,[2,89]),o($V$,[2,90]),{13:$V9,18:$Va,35:134,44:30,45:32,46:$Vc,80:[1,135],81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{78:[1,136],81:[1,137]},{13:$V9,18:$Va,35:139,44:30,45:32,46:$Vc,78:[1,138],81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{13:$V9,18:$Va,35:140,44:30,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{13:$V9,18:$Va,35:141,44:30,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:142,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:144,32:$VF,38:[1,143],45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:145,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:146,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:147,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($VS,[2,56]),o($VU,[2,58]),o($VS,[2,29],{21:148,10:$VT}),o($V3,[2,11]),o($V3,[2,21]),o($V3,[2,22]),{9:[1,149]},o($V3,[2,12]),o($V3,[2,13]),o($V3,[2,14]),o($V3,[2,15]),o($VY,$V4,{5:150}),o($VZ,[2,93]),{6:10,7:11,8:$V5,9:$V6,10:$V7,11:$V8,13:$V9,18:$Va,23:16,25:17,26:18,27:19,28:20,29:21,30:$Vb,32:[1,151],33:23,35:29,44:30,45:32,46:$Vc,71:$Vd,72:$Ve,73:$Vf,74:$Vg,75:$Vh,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($VR,[2,41]),o($V_,[2,63],{10:[1,152]}),{10:[1,153]},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:154,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,45:71,46:$VG,50:$VH,51:[1,155],52:[1,156],53:[1,157],54:[1,158],60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,45:71,46:$VG,50:$VH,56:[1,159],57:[1,160],58:[1,161],59:[1,162],60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,45:71,46:$VG,50:$VH,60:$VI,61:[1,163],62:[1,164],63:[1,165],64:[1,166],66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:[1,167],13:$V9,18:$Va,44:114,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:[1,168]},{10:[1,169]},{10:[1,170]},{10:[1,171]},{10:[1,172],13:$V9,18:$Va,44:114,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:[1,173],13:$V9,18:$Va,44:114,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:[1,174],13:$V9,18:$Va,44:114,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,37:[1,175],45:71,46:$VG,50:$VH,60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:176,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,39:[1,177],45:71,46:$VG,50:$VH,60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,41:[1,178],45:71,46:$VG,50:$VH,60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,43:[1,179],45:71,46:$VG,50:$VH,60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,37:[1,180],45:71,46:$VG,50:$VH,60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($VS,[2,28]),o($V3,[2,23]),{6:10,7:11,8:$V5,9:$V6,10:$V7,11:$V8,13:$V9,18:$Va,23:16,25:17,26:18,27:19,28:20,29:21,30:$Vb,32:[1,181],33:23,35:29,44:30,45:32,46:$Vc,71:$Vd,72:$Ve,73:$Vf,74:$Vg,75:$Vh,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($Vt,[2,37]),o($V_,[2,65]),o($V_,[2,64]),{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,45:71,46:$VG,50:$VH,60:$VI,65:[1,182],66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($V_,[2,67]),o($V_,[2,68]),o($V_,[2,69]),o($V_,[2,70]),o($V_,[2,71]),o($V_,[2,72]),o($V_,[2,73]),o($V_,[2,74]),o($V_,[2,75]),o($V_,[2,76]),o($V_,[2,77]),o($V_,[2,78]),{10:$V01,46:$V11,71:$V21,79:183,80:$V31,81:$V41,84:$V51,85:184,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},{10:$V01,46:$V11,71:$V21,79:197,80:$V31,81:$V41,84:$V51,85:184,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},{10:$V01,46:$V11,71:$V21,79:198,80:$V31,81:$V41,82:[1,199],84:$V51,85:184,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},{10:$V01,46:$V11,71:$V21,79:200,80:$V31,81:$V41,82:[1,201],84:$V51,85:184,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},{10:$V01,46:$V11,71:$V21,79:202,80:$V31,81:$V41,84:$V51,85:184,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},{10:$V01,46:$V11,71:$V21,79:203,80:$V31,81:$V41,84:$V51,85:184,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},{13:$V9,18:$Va,35:204,44:30,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{13:$V9,18:$Va,35:205,44:30,45:32,46:$Vc,67:[1,206],81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($VS,[2,43],{21:207,10:$VT}),{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,39:[1,208],45:71,46:$VG,50:$VH,60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($VS,[2,49],{21:209,10:$VT}),o($VS,[2,47],{21:210,10:$VT}),o($VS,[2,51],{21:211,10:$VT}),o($VS,[2,53],{21:212,10:$VT}),o($Vt,[2,36]),o([10,13,18,46,81,86,88,89,91,92,94,95,96,97,98],[2,91]),o($VR,[2,117],{86:$Vb1}),o($Vc1,[2,126],{87:214,10:$V01,46:$V11,71:$V21,80:$V31,81:$V41,84:$V51,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1}),o($Vd1,[2,128]),o($Vd1,[2,130]),o($Vd1,[2,131]),o($Vd1,[2,132]),o($Vd1,[2,133]),o($Vd1,[2,134]),o($Vd1,[2,135]),o($Vd1,[2,136]),o($Vd1,[2,137]),o($Vd1,[2,138]),o($Vd1,[2,139]),o($Vd1,[2,140]),o($VR,[2,118],{86:$Vb1}),o($VR,[2,119],{86:$Vb1}),{10:[1,215]},o($VR,[2,120],{86:$Vb1}),{10:[1,216]},o($VR,[2,110],{86:$Vb1}),o($VR,[2,111],{86:$Vb1}),o($VR,[2,112],{45:32,44:114,13:$V9,18:$Va,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs}),o($VR,[2,113],{45:32,44:114,10:[1,217],13:$V9,18:$Va,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs}),o($VR,[2,115],{10:[1,218]}),o($VS,[2,44]),{39:[1,219]},o($VS,[2,50]),o($VS,[2,48]),o($VS,[2,52]),o($VS,[2,54]),{10:$V01,46:$V11,71:$V21,80:$V31,81:$V41,84:$V51,85:220,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},o($Vd1,[2,129]),{13:$V9,18:$Va,35:221,44:30,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{13:$V9,18:$Va,35:222,44:30,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{67:[1,223]},{67:[1,224]},o($VS,[2,45],{21:225,10:$VT}),o($Vc1,[2,127],{87:214,10:$V01,46:$V11,71:$V21,80:$V31,81:$V41,84:$V51,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1}),o($VR,[2,123],{45:32,44:114,10:[1,226],13:$V9,18:$Va,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs}),o($VR,[2,124],{45:32,44:114,10:[1,227],13:$V9,18:$Va,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs}),o($VR,[2,114]),o($VR,[2,116]),o($VS,[2,46]),{10:$V01,46:$V11,71:$V21,79:228,80:$V31,81:$V41,84:$V51,85:184,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},{10:$V01,46:$V11,71:$V21,79:229,80:$V31,81:$V41,84:$V51,85:184,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},o($VR,[2,121],{86:$Vb1}),o($VR,[2,122],{86:$Vb1})],
-defaultActions: {},
-parseError: function parseError(str, hash) {
-    if (hash.recoverable) {
-        this.trace(str);
-    } else {
-        var error = new Error(str);
-        error.hash = hash;
-        throw error;
-    }
-},
-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;
-    }
-            function lex() {
-            var token;
-            token = tstack.pop() || lexer.lex() || EOF;
-            if (typeof token !== 'number') {
-                if (token instanceof Array) {
-                    tstack = token;
-                    token = tstack.pop();
-                }
-                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["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:this.begin("string");
-break;
-case 2:this.popState();
-break;
-case 3:return "STR";
-break;
-case 4:return 71;
-break;
-case 5:return 78;
-break;
-case 6:return 72;
-break;
-case 7:return 82;
-break;
-case 8:return 73;
-break;
-case 9:return 74;
-break;
-case 10:return 75;
-break;
-case 11:return 12;
-break;
-case 12:return 30;
-break;
-case 13:return 32;
-break;
-case 14:return 13;
-break;
-case 15:return 13;
-break;
-case 16:return 13;
-break;
-case 17:return 13;
-break;
-case 18:return 13;
-break;
-case 19:return 13;
-break;
-case 20:return 81;
-break;
-case 21:return 91;
-break;
-case 22:return 89;
-break;
-case 23:return 8;
-break;
-case 24:return 86;
-break;
-case 25:return 98;
-break;
-case 26:return 16;
-break;
-case 27:return 15;
-break;
-case 28:return 17;
-break;
-case 29:return 18;
-break;
-case 30:return 53;
-break;
-case 31:return 51;
-break;
-case 32:return 52;
-break;
-case 33:return 54;
-break;
-case 34:return 58;
-break;
-case 35:return 56;
-break;
-case 36:return 57;
-break;
-case 37:return 59;
-break;
-case 38:return 58;
-break;
-case 39:return 56;
-break;
-case 40:return 57;
-break;
-case 41:return 59;
-break;
-case 42:return 63;
-break;
-case 43:return 61;
-break;
-case 44:return 62;
-break;
-case 45:return 64;
-break;
-case 46:return 50;
-break;
-case 47:return 55;
-break;
-case 48:return 60;
-break;
-case 49:return 40;
-break;
-case 50:return 41;
-break;
-case 51:return 46;
-break;
-case 52:return 92;
-break;
-case 53:return 96;
-break;
-case 54:return 84;
-break;
-case 55:return 97;
-break;
-case 56:return 97;
-break;
-case 57:return 88;
-break;
-case 58:return 94;
-break;
-case 59:return 95;
-break;
-case 60:return 65;
-break;
-case 61:return 38;
-break;
-case 62:return 39;
-break;
-case 63:return 36;
-break;
-case 64:return 37;
-break;
-case 65:return 42
-break;
-case 66:return 43
-break;
-case 67:return 101;
-break;
-case 68:return 9;
-break;
-case 69:return 10;
-break;
-case 70:return 11;
-break;
-}
-},
-rules: [/^(?:%%[^\n]*)/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:click\b)/,/^(?:graph\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:LR\b)/,/^(?:RL\b)/,/^(?:TB\b)/,/^(?:BT\b)/,/^(?:TD\b)/,/^(?:BR\b)/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:v\b)/,/^(?:\s*--[x]\s*)/,/^(?:\s*-->\s*)/,/^(?:\s*--[o]\s*)/,/^(?:\s*---\s*)/,/^(?:\s*-\.-[x]\s*)/,/^(?:\s*-\.->\s*)/,/^(?:\s*-\.-[o]\s*)/,/^(?:\s*-\.-\s*)/,/^(?:\s*.-[x]\s*)/,/^(?:\s*\.->\s*)/,/^(?:\s*\.-[o]\s*)/,/^(?:\s*\.-\s*)/,/^(?:\s*==[x]\s*)/,/^(?:\s*==>\s*)/,/^(?:\s*==[o]\s*)/,/^(?:\s*==[\=]\s*)/,/^(?:\s*--\s*)/,/^(?:\s*-\.\s*)/,/^(?:\s*==\s*)/,/^(?:\(-)/,/^(?:-\))/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:[A-Za-z]+)/,/^(?:[!"#$%&'*+,-.`?\\_\/])/,/^(?:[\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])/,/^(?:\|)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\{)/,/^(?:\})/,/^(?:")/,/^(?:\n+)/,/^(?:\s)/,/^(?:$)/],
-conditions: {"string":{"rules":[2,3],"inclusive":false},"INITIAL":{"rules":[0,1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70],"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 = parser;
-exports.Parser = parser.Parser;
-exports.parse = function () { return parser.parse.apply(parser, 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));
-}
-}
\ No newline at end of file
diff --git a/_submodules/mermaid/src/diagrams/flowchart/parser/flow.spec.js b/_submodules/mermaid/src/diagrams/flowchart/parser/flow.spec.js
deleted file mode 100644
index 28d273bafe26097bf32323451349027b0decd928..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/flowchart/parser/flow.spec.js
+++ /dev/null
@@ -1,1346 +0,0 @@
-import flowDb from '../flowDb'
-import flow from './flow'
-
-describe('when parsing ', function () {
-  beforeEach(function () {
-    flow.parser.yy = flowDb
-    flow.parser.yy.clear()
-  })
-
-  it('should handle a nodes and edges', function () {
-    const res = flow.parser.parse('graph TD;\nA-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle subgraph with tab indentation', function () {
-    const res = flow.parser.parse('graph TB\nsubgraph One\n\ta1-->a2\nend')
-    const subgraphs = flow.parser.yy.getSubGraphs()
-    expect(subgraphs.length).toBe(1)
-    const subgraph = subgraphs[0]
-    expect(subgraph.nodes.length).toBe(2)
-    expect(subgraph.nodes[0]).toBe('a1')
-    expect(subgraph.nodes[1]).toBe('a2')
-    expect(subgraph.title).toBe('One')
-  })
-
-  it('should handle angle bracket ' > ' as direction LR', function () {
-    const res = flow.parser.parse('graph >;A-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-    const direction = flow.parser.yy.getDirection()
-
-    expect(direction).toBe('LR')
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle angle bracket ' < ' as direction RL', function () {
-    const res = flow.parser.parse('graph <;A-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-    const direction = flow.parser.yy.getDirection()
-
-    expect(direction).toBe('RL')
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle caret ' ^ ' as direction BT', function () {
-    const res = flow.parser.parse('graph ^;A-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-    const direction = flow.parser.yy.getDirection()
-
-    expect(direction).toBe('BT')
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle lower-case \'v\' as direction TB', function () {
-    const res = flow.parser.parse('graph v;A-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-    const direction = flow.parser.yy.getDirection()
-
-    expect(direction).toBe('TB')
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle a nodes and edges and a space between link and node', function () {
-    const res = flow.parser.parse('graph TD;A --> B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle a nodes and edges, a space between link and node and each line ending without semicolon', function () {
-    const res = flow.parser.parse('graph TD\nA --> B\n style e red')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-  it('should handle statements ending without semicolon', function () {
-    const res = flow.parser.parse('graph TD\nA-->B\nB-->C')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(2)
-    expect(edges[1].start).toBe('B')
-    expect(edges[1].end).toBe('C')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle a comments', function () {
-    const res = flow.parser.parse('graph TD;\n%% CComment\n A-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-  it('should handle comments a at the start', function () {
-    const res = flow.parser.parse('%% Comment\ngraph TD;\n A-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-  it('should handle comments at the end', function () {
-    const res = flow.parser.parse('graph TD;\n A-->B\n %% Comment at the find\n')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-  it('should handle comments at the end no trailing newline', function () {
-    const res = flow.parser.parse('graph TD;\n A-->B\n%% Commento')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-  it('should handle comments at the end many trailing newlines', function () {
-    const res = flow.parser.parse('graph TD;\n A-->B\n%% Commento\n\n\n')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-  it('should handle no trailing newlines', function () {
-    const res = flow.parser.parse('graph TD;\n A-->B')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-  it('should handle many trailing newlines', function () {
-    const res = flow.parser.parse('graph TD;\n A-->B\n\n')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-  it('should handle a comments with blank rows in-between', function () {
-    const res = flow.parser.parse('graph TD;\n\n\n %% Comment\n A-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle a comments mermaid flowchart code in them', function () {
-    const res = flow.parser.parse('graph TD;\n\n\n %% Test od>Odd shape]-->|Two line<br>edge comment|ro;\n A-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('it should handle a trailing whitespaces after statememnts', function () {
-    const res = flow.parser.parse('graph TD;\n\n\n %% Comment\n A-->B; \n B-->C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(2)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle node names with "end" substring', function () {
-    const res = flow.parser.parse('graph TD\nendpoint --> sender')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['endpoint'].id).toBe('endpoint')
-    expect(vert['sender'].id).toBe('sender')
-    expect(edges[0].start).toBe('endpoint')
-    expect(edges[0].end).toBe('sender')
-  })
-
-  it('should handle node names ending with keywords', function () {
-    const res = flow.parser.parse('graph TD\nblend --> monograph')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['blend'].id).toBe('blend')
-    expect(vert['monograph'].id).toBe('monograph')
-    expect(edges[0].start).toBe('blend')
-    expect(edges[0].end).toBe('monograph')
-  })
-
-  it('should handle open ended edges', function () {
-    const res = flow.parser.parse('graph TD;A---B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow_open')
-  })
-
-  it('should handle cross ended edges', function () {
-    const res = flow.parser.parse('graph TD;A--xB;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow_cross')
-  })
-
-  it('should handle open ended edges', function () {
-    const res = flow.parser.parse('graph TD;A--oB;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow_circle')
-  })
-  it('should handle subgraphs', function () {
-    const res = flow.parser.parse('graph TD;A-->B;subgraph myTitle;c-->d;end;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow')
-  })
-
-  it('should handle subgraphs', function () {
-    const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\n\n c-->d \nend\n')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow')
-  })
-
-  it('should handle nested subgraphs', function () {
-    const str = 'graph TD\n' +
-            'A-->B\n' +
-            'subgraph myTitle\n\n' +
-            ' c-->d \n\n' +
-            ' subgraph inner\n\n   e-->f \n end \n\n' +
-            ' subgraph inner\n\n   h-->i \n end \n\n' +
-            'end\n'
-    const res = flow.parser.parse(str)
-  })
-
-  it('should handle subgraphs', function () {
-    const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\nc-->d\nend;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow')
-  })
-
-  it('should handle subgraphs', function () {
-    const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\nc-- text -->d\nd-->e\n end;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow')
-  })
-
-  it('should handle classDefs with style in classes', function () {
-    const res = flow.parser.parse('graph TD\nA-->B\nclassDef exClass font-style:bold;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow')
-  })
-
-  it('should handle classDefs with % in classes', function () {
-    const res = flow.parser.parse('graph TD\nA-->B\nclassDef exClass fill:#f96,stroke:#333,stroke-width:4px,font-size:50%,font-style:bold;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow')
-  })
-
-  it('should handle style definitons with more then 1 digit in a row', function () {
-    const res = flow.parser.parse('graph TD\n' +
-        'A-->B1\n' +
-        'A-->B2\n' +
-        'A-->B3\n' +
-        'A-->B4\n' +
-        'A-->B5\n' +
-        'A-->B6\n' +
-        'A-->B7\n' +
-        'A-->B8\n' +
-        'A-->B9\n' +
-        'A-->B10\n' +
-        'A-->B11\n' +
-        'linkStyle 10 stroke-width:1px;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow')
-  })
-
-  it('should handle line interpolation default definitions', function () {
-    const res = flow.parser.parse('graph TD\n' +
-        'A-->B\n' +
-        'linkStyle default interpolate basis')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.defaultInterpolate).toBe('basis')
-  })
-
-  it('should handle line interpolation numbered definitions', function () {
-    const res = flow.parser.parse('graph TD\n' +
-        'A-->B\n' +
-        'A-->C\n' +
-        'linkStyle 0 interpolate basis\n' +
-        'linkStyle 1 interpolate cardinal')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].interpolate).toBe('basis')
-    expect(edges[1].interpolate).toBe('cardinal')
-  })
-
-  it('should handle line interpolation default with style', function () {
-    const res = flow.parser.parse('graph TD\n' +
-        'A-->B\n' +
-        'linkStyle default interpolate basis stroke-width:1px;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.defaultInterpolate).toBe('basis')
-  })
-
-  it('should handle line interpolation numbered with style', function () {
-    const res = flow.parser.parse('graph TD\n' +
-        'A-->B\n' +
-        'A-->C\n' +
-        'linkStyle 0 interpolate basis stroke-width:1px;\n' +
-        'linkStyle 1 interpolate cardinal stroke-width:1px;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].interpolate).toBe('basis')
-    expect(edges[1].interpolate).toBe('cardinal')
-  })
-
-  describe('it should handle interaction, ', function () {
-    it('it should be possible to use click to a callback', function () {
-      spyOn(flowDb, 'setClickEvent')
-      const res = flow.parser.parse('graph TD\nA-->B\nclick A callback')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', 'callback', undefined, undefined)
-    })
-
-    it('it should be possible to use click to a callback with toolip', function () {
-      spyOn(flowDb, 'setClickEvent')
-      const res = flow.parser.parse('graph TD\nA-->B\nclick A callback "tooltip"')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', 'callback', undefined, 'tooltip')
-    })
-
-    it('should handle interaction - click to a link', function () {
-      spyOn(flowDb, 'setClickEvent')
-      const res = flow.parser.parse('graph TD\nA-->B\nclick A "click.html"')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', undefined, 'click.html', undefined)
-    })
-    it('should handle interaction - click to a link with tooltip', function () {
-      spyOn(flowDb, 'setClickEvent')
-      const res = flow.parser.parse('graph TD\nA-->B\nclick A "click.html" "tooltip"')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', undefined, 'click.html', 'tooltip')
-    })
-  })
-
-  describe('it should handle text on edges', function () {
-    it('it should handle text without space', function () {
-      const res = flow.parser.parse('graph TD;A--x|textNoSpace|B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('should handle  with space', function () {
-      const res = flow.parser.parse('graph TD;A--x|text including space|B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('it should handle text with /', function () {
-      const res = flow.parser.parse('graph TD;A--x|text with / should work|B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].text).toBe('text with / should work')
-    })
-
-    it('it should handle space and space between vertices and link', function () {
-      const res = flow.parser.parse('graph TD;A --x|textNoSpace| B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('should handle space and CAPS', function () {
-      const res = flow.parser.parse('graph TD;A--x|text including CAPS space|B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('should handle space and dir', function () {
-      const res = flow.parser.parse('graph TD;A--x|text including URL space|B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(edges[0].text).toBe('text including URL space')
-    })
-
-    it('should handle space and send', function () {
-      const res = flow.parser.parse('graph TD;A--text including URL space and send-->B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow')
-      expect(edges[0].text).toBe('text including URL space and send')
-    })
-    it('should handle space and send', function () {
-      const res = flow.parser.parse('graph TD;A-- text including URL space and send -->B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow')
-      expect(edges[0].text).toBe('text including URL space and send')
-    })
-
-    it('should handle space and dir (TD)', function () {
-      const res = flow.parser.parse('graph TD;A--x|text including R TD space|B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(edges[0].text).toBe('text including R TD space')
-    })
-    it('should handle `', function () {
-      const res = flow.parser.parse('graph TD;A--x|text including `|B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(edges[0].text).toBe('text including `')
-    })
-    it('should handle v in node ids only v', function () {
-            // only v
-      const res = flow.parser.parse('graph TD;A--xv(my text);')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(vert['v'].text).toBe('my text')
-    })
-    it('should handle v in node ids v at end', function () {
-            // v at end
-      const res = flow.parser.parse('graph TD;A--xcsv(my text);')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(vert['csv'].text).toBe('my text')
-    })
-    it('should handle v in node ids v in middle', function () {
-            // v in middle
-      const res = flow.parser.parse('graph TD;A--xava(my text);')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(vert['ava'].text).toBe('my text')
-    })
-    it('should handle v in node ids, v at start', function () {
-            // v at start
-      const res = flow.parser.parse('graph TD;A--xva(my text);')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(vert['va'].text).toBe('my text')
-    })
-    it('should handle keywords', function () {
-      const res = flow.parser.parse('graph TD;A--x|text including graph space|B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].text).toBe('text including graph space')
-    })
-    it('should handle keywords', function () {
-      const res = flow.parser.parse('graph TD;V-->a[v]')
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-      expect(vert['a'].text).toBe('v')
-    })
-    it('should handle keywords', function () {
-      const res = flow.parser.parse('graph TD;V-->a[v]')
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-      expect(vert['a'].text).toBe('v')
-    })
-    it('should handle quoted text', function () {
-      const res = flow.parser.parse('graph TD;V-- "test string()" -->a[v]')
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-      expect(edges[0].text).toBe('test string()')
-    })
-  })
-
-  describe('it should handle new line type notation', function () {
-    it('it should handle regular lines', function () {
-      const res = flow.parser.parse('graph TD;A-->B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].stroke).toBe('normal')
-    })
-    it('it should handle dotted lines', function () {
-      const res = flow.parser.parse('graph TD;A-.->B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].stroke).toBe('dotted')
-    })
-    it('it should handle dotted lines', function () {
-      const res = flow.parser.parse('graph TD;A==>B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].stroke).toBe('thick')
-    })
-    it('it should handle text on lines', function () {
-      const res = flow.parser.parse('graph TD;A-- test text with == -->B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].stroke).toBe('normal')
-    })
-    it('it should handle text on lines', function () {
-      const res = flow.parser.parse('graph TD;A-. test text with == .->B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].stroke).toBe('dotted')
-    })
-    it('it should handle text on lines', function () {
-      const res = flow.parser.parse('graph TD;A== test text with - ==>B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].stroke).toBe('thick')
-    })
-  })
-
-  describe('it should handle text on edges using the new notation', function () {
-    it('it should handle text without space', function () {
-      const res = flow.parser.parse('graph TD;A-- textNoSpace --xB;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('it should handle text with multiple leading space', function () {
-      const res = flow.parser.parse('graph TD;A--    textNoSpace --xB;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('should handle  with space', function () {
-      const res = flow.parser.parse('graph TD;A-- text including space --xB;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('it should handle text with /', function () {
-      const res = flow.parser.parse('graph TD;A -- text with / should work --x B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].text).toBe('text with / should work')
-    })
-
-    it('it should handle space and space between vertices and link', function () {
-      const res = flow.parser.parse('graph TD;A -- textNoSpace --x B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('should handle space and CAPS', function () {
-      const res = flow.parser.parse('graph TD;A-- text including CAPS space --xB;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('should handle space and dir', function () {
-      const res = flow.parser.parse('graph TD;A-- text including URL space --xB;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(edges[0].text).toBe('text including URL space')
-    })
-
-    it('should handle space and dir (TD)', function () {
-      const res = flow.parser.parse('graph TD;A-- text including R TD space --xB;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(edges[0].text).toBe('text including R TD space')
-    })
-    it('should handle keywords', function () {
-      const res = flow.parser.parse('graph TD;A-- text including graph space and v --xB;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].text).toBe('text including graph space and v')
-    })
-    it('should handle keywords', function () {
-      const res = flow.parser.parse('graph TD;A-- text including graph space and v --xB[blav]')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].text).toBe('text including graph space and v')
-    })
-        // xit('should handle text on open links',function(){
-        //    const res = flow.parser.parse('graph TD;A-- text including graph space --B');
-        //
-        //    const vert = flow.parser.yy.getVertices();
-        //    const edges = flow.parser.yy.getEdges();
-        //
-        //    expect(edges[0].text).toBe('text including graph space');
-        //
-        // });
-  })
-
-  it('should handle multi-line text', function () {
-    const res = flow.parser.parse('graph TD;A--o|text space|B;\n B-->|more text with space|C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow_circle')
-    expect(edges[1].type).toBe('arrow')
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(vert['C'].id).toBe('C')
-    expect(edges.length).toBe(2)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-        // expect(edges[0].text).toBe('text space');
-    expect(edges[1].start).toBe('B')
-    expect(edges[1].end).toBe('C')
-    expect(edges[1].text).toBe('more text with space')
-  })
-
-  it('should handle multiple edges', function () {
-    const res = flow.parser.parse('graph TD;A---|This is the 123 s text|B;\nA---|This is the second edge|B;')
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(2)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].text).toBe('This is the 123 s text')
-    expect(edges[1].start).toBe('A')
-    expect(edges[1].end).toBe('B')
-    expect(edges[1].text).toBe('This is the second edge')
-  })
-
-  it('should handle text in vertices with space', function () {
-    const res = flow.parser.parse('graph TD;A[chimpansen hoppar]-->C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].type).toBe('square')
-    expect(vert['A'].text).toBe('chimpansen hoppar')
-  })
-
-  it('should handle text in vertices with space with spaces between vertices and link', function () {
-    const res = flow.parser.parse('graph TD;A[chimpansen hoppar] --> C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].type).toBe('square')
-    expect(vert['A'].text).toBe('chimpansen hoppar')
-  })
-
-  it('should handle quoted text in vertices ', function () {
-    const res = flow.parser.parse('graph TD;A["chimpansen hoppar ()[]"] --> C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].type).toBe('square')
-    expect(vert['A'].text).toBe('chimpansen hoppar ()[]')
-  })
-
-  it('should handle text in circle vertices with space', function () {
-    const res = flow.parser.parse('graph TD;A((chimpansen hoppar))-->C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].type).toBe('circle')
-    expect(vert['A'].text).toBe('chimpansen hoppar')
-  })
-
-  it('should handle text in ellipse vertices', function () {
-    const res = flow.parser.parse('graph TD\nA(-this is an ellipse-)-->B')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].type).toBe('ellipse')
-    expect(vert['A'].text).toBe('this is an ellipse')
-  })
-
-  it('should handle text in diamond vertices with space', function () {
-    const res = flow.parser.parse('graph TD;A(chimpansen hoppar)-->C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].type).toBe('round')
-    expect(vert['A'].text).toBe('chimpansen hoppar')
-  })
-
-  it('should handle text in with ?', function () {
-    const res = flow.parser.parse('graph TD;A(?)-->|?|C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].text).toBe('?')
-    expect(edges[0].text).toBe('?')
-  })
-  it('should handle text in with éèêàçô', function () {
-    const res = flow.parser.parse('graph TD;A(éèêàçô)-->|éèêàçô|C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].text).toBe('éèêàçô')
-    expect(edges[0].text).toBe('éèêàçô')
-  })
-
-  it('should handle text in with ,.?!+-*', function () {
-    const res = flow.parser.parse('graph TD;A(,.?!+-*)-->|,.?!+-*|C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].text).toBe(',.?!+-*')
-    expect(edges[0].text).toBe(',.?!+-*')
-  })
-
-  describe('it should handle text in vertices, ', function () {
-    it('it should handle space', function () {
-      const res = flow.parser.parse('graph TD;A-->C(Chimpansen hoppar);')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(vert['C'].type).toBe('round')
-      expect(vert['C'].text).toBe('Chimpansen hoppar')
-    })
-    it('it should handle åäö and minus', function () {
-      const res = flow.parser.parse('graph TD;A-->C{Chimpansen hoppar åäö-ÅÄÖ};')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(vert['C'].type).toBe('diamond')
-      expect(vert['C'].text).toBe('Chimpansen hoppar åäö-ÅÄÖ')
-    })
-
-    it('it should handle with åäö, minus and space and br', function () {
-      const res = flow.parser.parse('graph TD;A-->C(Chimpansen hoppar åäö  <br> -  ÅÄÖ);')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(vert['C'].type).toBe('round')
-      expect(vert['C'].text).toBe('Chimpansen hoppar åäö  <br> -  ÅÄÖ')
-    })
-        // xit('it should handle åäö, minus and space and br',function(){
-        //    const res = flow.parser.parse('graph TD; A[Object&#40;foo,bar&#41;]-->B(Thing);');
-        //
-        //    const vert = flow.parser.yy.getVertices();
-        //    const edges = flow.parser.yy.getEdges();
-        //
-        //    expect(vert['C'].type).toBe('round');
-        //    expect(vert['C'].text).toBe(' A[Object&#40;foo,bar&#41;]-->B(Thing);');
-        // });
-    it('it should handle unicode chars', function () {
-      const res = flow.parser.parse('graph TD;A-->C(Начало);')
-
-      const vert = flow.parser.yy.getVertices()
-
-      expect(vert['C'].text).toBe('Начало')
-    })
-    it('it should handle backslask', function () {
-      const res = flow.parser.parse('graph TD;A-->C(c:\\windows);')
-
-      const vert = flow.parser.yy.getVertices()
-
-      expect(vert['C'].text).toBe('c:\\windows')
-    })
-    it('it should handle CAPS', function () {
-      const res = flow.parser.parse('graph TD;A-->C(some CAPS);')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(vert['C'].type).toBe('round')
-      expect(vert['C'].text).toBe('some CAPS')
-    })
-    it('it should handle directions', function () {
-      const res = flow.parser.parse('graph TD;A-->C(some URL);')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(vert['C'].type).toBe('round')
-      expect(vert['C'].text).toBe('some URL')
-    })
-  })
-
-  it('should handle a single node', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;A;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['A'].styles.length).toBe(0)
-  })
-
-  it('should handle a single square node', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;a[A];')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['a'].styles.length).toBe(0)
-    expect(vert['a'].type).toBe('square')
-  })
-  it('should handle a single round square node', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;a[A];')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['a'].styles.length).toBe(0)
-    expect(vert['a'].type).toBe('square')
-  })
-  it('should handle a single circle node', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;a((A));')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['a'].type).toBe('circle')
-  })
-  it('should handle a single round node', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;a(A);')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['a'].type).toBe('round')
-  })
-  it('should handle a single odd node', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;a>A];')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['a'].type).toBe('odd')
-  })
-  it('should handle a single diamond node', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;a{A};')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['a'].type).toBe('diamond')
-  })
-  it('should handle a single diamond node with html in it', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;a{A <br> end};')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['a'].type).toBe('diamond')
-    expect(vert['a'].text).toBe('A <br> end')
-  })
-  it('should handle a single round node with html in it', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;a(A <br> end);')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['a'].type).toBe('round')
-    expect(vert['a'].text).toBe('A <br> end')
-  })
-  it('should handle a single node with alphanumerics starting on a char', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;id1;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['id1'].styles.length).toBe(0)
-  })
-  it('should handle a single node with alphanumerics starting on a num', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;1id;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['1id'].styles.length).toBe(0)
-  })
-  it('should handle a single node with alphanumerics containing a minus sign', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;i-d;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['i-d'].styles.length).toBe(0)
-  })
-    // log.debug(flow.parser.parse('graph TD;style Q background:#fff;'));
-  it('should handle styles for vertices', function () {
-    const res = flow.parser.parse('graph TD;style Q background:#fff;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    const style = vert['Q'].styles[0]
-
-    expect(vert['Q'].styles.length).toBe(1)
-    expect(vert['Q'].styles[0]).toBe('background:#fff')
-  })
-
-    // log.debug(flow.parser.parse('graph TD;style Q background:#fff;'));
-  it('should handle styles for edges', function () {
-    const res = flow.parser.parse('graph TD;a-->b;\nstyle #0 stroke: #f66;')
-
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(1)
-  })
-
-  it('should handle multiple styles for a vortex', function () {
-    const res = flow.parser.parse('graph TD;style R background:#fff,border:1px solid red;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['R'].styles.length).toBe(2)
-    expect(vert['R'].styles[0]).toBe('background:#fff')
-    expect(vert['R'].styles[1]).toBe('border:1px solid red')
-  })
-
-  it('should handle multiple styles in a graph', function () {
-    const res = flow.parser.parse('graph TD;style S background:#aaa;\nstyle T background:#bbb,border:1px solid red;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['S'].styles.length).toBe(1)
-    expect(vert['T'].styles.length).toBe(2)
-    expect(vert['S'].styles[0]).toBe('background:#aaa')
-    expect(vert['T'].styles[0]).toBe('background:#bbb')
-    expect(vert['T'].styles[1]).toBe('border:1px solid red')
-  })
-
-  it('should handle styles and graph definitons in a graph', function () {
-    const res = flow.parser.parse('graph TD;S-->T;\nstyle S background:#aaa;\nstyle T background:#bbb,border:1px solid red;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['S'].styles.length).toBe(1)
-    expect(vert['T'].styles.length).toBe(2)
-    expect(vert['S'].styles[0]).toBe('background:#aaa')
-    expect(vert['T'].styles[0]).toBe('background:#bbb')
-    expect(vert['T'].styles[1]).toBe('border:1px solid red')
-  })
-  it('should handle styles and graph definitons in a graph', function () {
-    const res = flow.parser.parse('graph TD;style T background:#bbb,border:1px solid red;')
-        // const res = flow.parser.parse('graph TD;style T background: #bbb;');
-
-    const vert = flow.parser.yy.getVertices()
-
-    expect(vert['T'].styles.length).toBe(2)
-    expect(vert['T'].styles[0]).toBe('background:#bbb')
-    expect(vert['T'].styles[1]).toBe('border:1px solid red')
-  })
-
-  describe('special characters should be be handled.', function () {
-    const charTest = function (char) {
-      const res = flow.parser.parse('graph TD;A(' + char + ')-->B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(vert['A'].id).toBe('A')
-      expect(vert['B'].id).toBe('B')
-      expect(vert['A'].text).toBe(char)
-    }
-
-    it('it should be able to parse a \'.\'', function () {
-      charTest('.')
-      charTest('Start 103a.a1')
-    })
-
-    it('it should be able to parse text containing \'_\'', function () {
-      charTest('_')
-    })
-
-    it('it should be able to parse a \':\'', function () {
-      charTest(':')
-    })
-
-    it('it should be able to parse a \',\'', function () {
-      charTest(',')
-    })
-
-    it('it should be able to parse text containing \'-\'', function () {
-      charTest('a-b')
-    })
-
-    it('it should be able to parse a \'+\'', function () {
-      charTest('+')
-    })
-
-    it('it should be able to parse a \'*\'', function () {
-      charTest('*')
-    })
-
-    it('it should be able to parse a \'<\'', function () {
-      charTest('<')
-    })
-
-    it('it should be able to parse a \'>\'', function () {
-      charTest('>')
-    })
-
-    it('it should be able to parse a \'=\'', function () {
-      charTest('=')
-    })
-  })
-
-  it('should be possible to declare a class', function () {
-    const res = flow.parser.parse('graph TD;classDef exClass background:#bbb,border:1px solid red;')
-        // const res = flow.parser.parse('graph TD;style T background: #bbb;');
-
-    const classes = flow.parser.yy.getClasses()
-
-    expect(classes['exClass'].styles.length).toBe(2)
-    expect(classes['exClass'].styles[0]).toBe('background:#bbb')
-    expect(classes['exClass'].styles[1]).toBe('border:1px solid red')
-  })
-
-  it('should be possible to declare a class with a dot in the style', function () {
-    const res = flow.parser.parse('graph TD;classDef exClass background:#bbb,border:1.5px solid red;')
-        // const res = flow.parser.parse('graph TD;style T background: #bbb;');
-
-    const classes = flow.parser.yy.getClasses()
-
-    expect(classes['exClass'].styles.length).toBe(2)
-    expect(classes['exClass'].styles[0]).toBe('background:#bbb')
-    expect(classes['exClass'].styles[1]).toBe('border:1.5px solid red')
-  })
-  it('should be possible to declare a class with a space in the style', function () {
-    const res = flow.parser.parse('graph TD;classDef exClass background:  #bbb,border:1.5px solid red;')
-        // const res = flow.parser.parse('graph TD;style T background  :  #bbb;');
-
-    const classes = flow.parser.yy.getClasses()
-
-    expect(classes['exClass'].styles.length).toBe(2)
-    expect(classes['exClass'].styles[0]).toBe('background:  #bbb')
-    expect(classes['exClass'].styles[1]).toBe('border:1.5px solid red')
-  })
-  it('should be possible to apply a class to a vertex', function () {
-    let statement = ''
-
-    statement = statement + 'graph TD;' + '\n'
-    statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n'
-    statement = statement + 'a-->b;' + '\n'
-    statement = statement + 'class a exClass;'
-
-    const res = flow.parser.parse(statement)
-
-    const classes = flow.parser.yy.getClasses()
-
-    expect(classes['exClass'].styles.length).toBe(2)
-    expect(classes['exClass'].styles[0]).toBe('background:#bbb')
-    expect(classes['exClass'].styles[1]).toBe('border:1px solid red')
-  })
-  it('should be possible to apply a class to a comma separated list of vertices', function () {
-    let statement = ''
-
-    statement = statement + 'graph TD;' + '\n'
-    statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n'
-    statement = statement + 'a-->b;' + '\n'
-    statement = statement + 'class a,b exClass;'
-
-    const res = flow.parser.parse(statement)
-
-    const classes = flow.parser.yy.getClasses()
-    const vertices = flow.parser.yy.getVertices()
-
-    expect(classes['exClass'].styles.length).toBe(2)
-    expect(classes['exClass'].styles[0]).toBe('background:#bbb')
-    expect(classes['exClass'].styles[1]).toBe('border:1px solid red')
-    expect(vertices['a'].classes[0]).toBe('exClass')
-    expect(vertices['b'].classes[0]).toBe('exClass')
-  })
-})
diff --git a/_submodules/mermaid/src/diagrams/gantt/gantt.spec.js b/_submodules/mermaid/src/diagrams/gantt/gantt.spec.js
deleted file mode 100644
index a170be6e1ffc4ba4dcf4a5366e5ed5c2d9e6a97b..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/gantt/gantt.spec.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/* eslint-env jasmine */
-import { parser } from './parser/gantt'
-import ganttDb from './ganttDb'
-
-describe('when parsing a gantt diagram it', function () {
-  beforeEach(function () {
-    parser.yy = ganttDb
-  })
-
-  it('should handle a dateFormat definition', function () {
-    const str = 'gantt\ndateFormat yyyy-mm-dd'
-
-    parser.parse(str)
-  })
-  it('should handle a title definition', function () {
-    const str = 'gantt\ndateFormat yyyy-mm-dd\ntitle Adding gantt diagram functionality to mermaid'
-
-    parser.parse(str)
-  })
-  it('should handle a section definition', function () {
-    const str = 'gantt\n' +
-      'dateFormat yyyy-mm-dd\n' +
-      'title Adding gantt diagram functionality to mermaid\n' +
-      'section Documentation'
-
-    parser.parse(str)
-  })
-  /**
-   * Beslutsflöde inligt nedan. Obs bla bla bla
-   * ```
-   * graph TD
-   * A[Hard pledge] -- text on link -->B(Round edge)
-   * B --> C{to do or not to do}
-   * C -->|Too| D[Result one]
-   * C -->|Doo| E[Result two]
-   ```
-   * params bapa - a unique bapap
-   */
-  it('should handle a task definition', function () {
-    const str = 'gantt\n' +
-      'dateFormat yyyy-mm-dd\n' +
-      'title Adding gantt diagram functionality to mermaid\n' +
-      'section Documentation\n' +
-      'Design jison grammar:des1, 2014-01-01, 2014-01-04'
-
-    parser.parse(str)
-  })
-})
diff --git a/_submodules/mermaid/src/diagrams/gantt/ganttDb.js b/_submodules/mermaid/src/diagrams/gantt/ganttDb.js
deleted file mode 100644
index b4e4fda763a9305d5d7b3fb5065d8aacc6e213a2..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/gantt/ganttDb.js
+++ /dev/null
@@ -1,363 +0,0 @@
-import moment from 'moment'
-import { logger } from '../../logger'
-
-let dateFormat = ''
-let axisFormat = ''
-let title = ''
-let sections = []
-let tasks = []
-let currentSection = ''
-
-export const clear = function () {
-  sections = []
-  tasks = []
-  currentSection = ''
-  title = ''
-  taskCnt = 0
-  lastTask = undefined
-  lastTaskID = undefined
-  rawTasks = []
-}
-
-export const setAxisFormat = function (txt) {
-  axisFormat = txt
-}
-
-export const getAxisFormat = function () {
-  return axisFormat
-}
-
-export const setDateFormat = function (txt) {
-  dateFormat = txt
-}
-
-export const setTitle = function (txt) {
-  title = txt
-}
-
-export const getTitle = function () {
-  return title
-}
-
-export const addSection = function (txt) {
-  currentSection = txt
-  sections.push(txt)
-}
-
-export const getTasks = function () {
-  let allItemsPricessed = compileTasks()
-  const maxDepth = 10
-  let iterationCount = 0
-  while (!allItemsPricessed && (iterationCount < maxDepth)) {
-    allItemsPricessed = compileTasks()
-    iterationCount++
-  }
-
-  tasks = rawTasks
-
-  return tasks
-}
-
-const getStartDate = function (prevTime, dateFormat, str) {
-  str = str.trim()
-
-  // Test for after
-  const re = /^after\s+([\d\w-]+)/
-  const afterStatement = re.exec(str.trim())
-
-  if (afterStatement !== null) {
-    const task = findTaskById(afterStatement[1])
-
-    if (typeof task === 'undefined') {
-      const dt = new Date()
-      dt.setHours(0, 0, 0, 0)
-      return dt
-    }
-    return task.endTime
-  }
-
-  // Check for actual date set
-  if (moment(str, dateFormat.trim(), true).isValid()) {
-    return moment(str, dateFormat.trim(), true).toDate()
-  } else {
-    logger.debug('Invalid date:' + str)
-    logger.debug('With date format:' + dateFormat.trim())
-  }
-
-  // Default date - now
-  return new Date()
-}
-
-const getEndDate = function (prevTime, dateFormat, str) {
-  str = str.trim()
-
-  // Check for actual date
-  if (moment(str, dateFormat.trim(), true).isValid()) {
-    return moment(str, dateFormat.trim()).toDate()
-  }
-
-  const d = moment(prevTime)
-  // Check for length
-  const re = /^([\d]+)([wdhms])/
-  const durationStatement = re.exec(str.trim())
-
-  if (durationStatement !== null) {
-    switch (durationStatement[2]) {
-      case 's':
-        d.add(durationStatement[1], 'seconds')
-        break
-      case 'm':
-        d.add(durationStatement[1], 'minutes')
-        break
-      case 'h':
-        d.add(durationStatement[1], 'hours')
-        break
-      case 'd':
-        d.add(durationStatement[1], 'days')
-        break
-      case 'w':
-        d.add(durationStatement[1], 'weeks')
-        break
-    }
-    return d.toDate()
-  }
-  // Default date - now
-  return d.toDate()
-}
-
-let taskCnt = 0
-const parseId = function (idStr) {
-  if (typeof idStr === 'undefined') {
-    taskCnt = taskCnt + 1
-    return 'task' + taskCnt
-  }
-  return idStr
-}
-// id, startDate, endDate
-// id, startDate, length
-// id, after x, endDate
-// id, after x, length
-// startDate, endDate
-// startDate, length
-// after x, endDate
-// after x, length
-// endDate
-// length
-
-const compileData = function (prevTask, dataStr) {
-  let ds
-
-  if (dataStr.substr(0, 1) === ':') {
-    ds = dataStr.substr(1, dataStr.length)
-  } else {
-    ds = dataStr
-  }
-
-  const data = ds.split(',')
-
-  const task = {}
-
-  // Get tags like active, done cand crit
-  let matchFound = true
-  while (matchFound) {
-    matchFound = false
-    if (data[0].match(/^\s*active\s*$/)) {
-      task.active = true
-      data.shift(1)
-      matchFound = true
-    }
-    if (data[0].match(/^\s*done\s*$/)) {
-      task.done = true
-      data.shift(1)
-      matchFound = true
-    }
-    if (data[0].match(/^\s*crit\s*$/)) {
-      task.crit = true
-      data.shift(1)
-      matchFound = true
-    }
-  }
-  for (let i = 0; i < data.length; i++) {
-    data[i] = data[i].trim()
-  }
-
-  switch (data.length) {
-    case 1:
-      task.id = parseId()
-      task.startTime = prevTask.endTime
-      task.endTime = getEndDate(task.startTime, dateFormat, data[0])
-      break
-    case 2:
-      task.id = parseId()
-      task.startTime = getStartDate(undefined, dateFormat, data[0])
-      task.endTime = getEndDate(task.startTime, dateFormat, data[1])
-      break
-    case 3:
-      task.id = parseId(data[0])
-      task.startTime = getStartDate(undefined, dateFormat, data[1])
-      task.endTime = getEndDate(task.startTime, dateFormat, data[2])
-      break
-    default:
-  }
-
-  return task
-}
-
-const parseData = function (prevTaskId, dataStr) {
-  let ds
-  if (dataStr.substr(0, 1) === ':') {
-    ds = dataStr.substr(1, dataStr.length)
-  } else {
-    ds = dataStr
-  }
-
-  const data = ds.split(',')
-
-  const task = {}
-
-  // Get tags like active, done cand crit
-  let matchFound = true
-  while (matchFound) {
-    matchFound = false
-    if (data[0].match(/^\s*active\s*$/)) {
-      task.active = true
-      data.shift(1)
-      matchFound = true
-    }
-    if (data[0].match(/^\s*done\s*$/)) {
-      task.done = true
-      data.shift(1)
-      matchFound = true
-    }
-    if (data[0].match(/^\s*crit\s*$/)) {
-      task.crit = true
-      data.shift(1)
-      matchFound = true
-    }
-  }
-  for (let i = 0; i < data.length; i++) {
-    data[i] = data[i].trim()
-  }
-
-  switch (data.length) {
-    case 1:
-      task.id = parseId()
-      task.startTime = { type: 'prevTaskEnd', id: prevTaskId }
-      task.endTime = { data: data[0] }
-      break
-    case 2:
-      task.id = parseId()
-      task.startTime = { type: 'getStartDate', startData: data[0] }
-      task.endTime = { data: data[1] }
-      break
-    case 3:
-      task.id = parseId(data[0])
-      task.startTime = { type: 'getStartDate', startData: data[1] }
-      task.endTime = { data: data[2] }
-      break
-    default:
-  }
-
-  return task
-}
-
-let lastTask
-let lastTaskID
-let rawTasks = []
-const taskDb = {}
-export const addTask = function (descr, data) {
-  const rawTask = {
-    section: currentSection,
-    type: currentSection,
-    processed: false,
-    raw: { data: data },
-    task: descr
-  }
-  const taskInfo = parseData(lastTaskID, data)
-  rawTask.raw.startTime = taskInfo.startTime
-  rawTask.raw.endTime = taskInfo.endTime
-  rawTask.id = taskInfo.id
-  rawTask.prevTaskId = lastTaskID
-  rawTask.active = taskInfo.active
-  rawTask.done = taskInfo.done
-  rawTask.crit = taskInfo.crit
-
-  const pos = rawTasks.push(rawTask)
-
-  lastTaskID = rawTask.id
-  // Store cross ref
-  taskDb[rawTask.id] = pos - 1
-}
-
-export const findTaskById = function (id) {
-  const pos = taskDb[id]
-  return rawTasks[pos]
-}
-
-export const addTaskOrg = function (descr, data) {
-  const newTask = {
-    section: currentSection,
-    type: currentSection,
-    description: descr,
-    task: descr
-  }
-  const taskInfo = compileData(lastTask, data)
-  newTask.startTime = taskInfo.startTime
-  newTask.endTime = taskInfo.endTime
-  newTask.id = taskInfo.id
-  newTask.active = taskInfo.active
-  newTask.done = taskInfo.done
-  newTask.crit = taskInfo.crit
-  lastTask = newTask
-  tasks.push(newTask)
-}
-
-const compileTasks = function () {
-  const compileTask = function (pos) {
-    const task = rawTasks[pos]
-    let startTime = ''
-    switch (rawTasks[pos].raw.startTime.type) {
-      case 'prevTaskEnd':
-        const prevTask = findTaskById(task.prevTaskId)
-        task.startTime = prevTask.endTime
-        break
-      case 'getStartDate':
-        startTime = getStartDate(undefined, dateFormat, rawTasks[pos].raw.startTime.startData)
-        if (startTime) {
-          rawTasks[pos].startTime = startTime
-        }
-        break
-    }
-
-    if (rawTasks[pos].startTime) {
-      rawTasks[pos].endTime = getEndDate(rawTasks[pos].startTime, dateFormat, rawTasks[pos].raw.endTime.data)
-      if (rawTasks[pos].endTime) {
-        rawTasks[pos].processed = true
-      }
-    }
-
-    return rawTasks[pos].processed
-  }
-
-  let allProcessed = true
-  for (let i = 0; i < rawTasks.length; i++) {
-    compileTask(i)
-
-    allProcessed = allProcessed && rawTasks[i].processed
-  }
-  return allProcessed
-}
-
-export default {
-  clear,
-  setDateFormat,
-  setAxisFormat,
-  getAxisFormat,
-  setTitle,
-  getTitle,
-  addSection,
-  getTasks,
-  addTask,
-  findTaskById,
-  addTaskOrg
-}
diff --git a/_submodules/mermaid/src/diagrams/gantt/ganttDb.spec.js b/_submodules/mermaid/src/diagrams/gantt/ganttDb.spec.js
deleted file mode 100644
index a956e3605324b0bf9b671071856444f03c6b262e..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/gantt/ganttDb.spec.js
+++ /dev/null
@@ -1,175 +0,0 @@
-/* eslint-env jasmine */
-import moment from 'moment'
-import ganttDb from './ganttDb'
-
-describe('when using the ganttDb', function () {
-  beforeEach(function () {
-    ganttDb.clear()
-  })
-
-  it('should handle an fixed dates', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2013-01-12')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[0].startTime).toEqual(moment('2013-01-01', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].endTime).toEqual(moment('2013-01-12', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].id).toEqual('id1')
-    expect(tasks[0].task).toEqual('test1')
-  })
-  it('should handle duration (days) instead of fixed date to determine end date', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2d')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[0].startTime).toEqual(moment('2013-01-01', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].endTime).toEqual(moment('2013-01-03', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].id).toEqual('id1')
-    expect(tasks[0].task).toEqual('test1')
-  })
-  it('should handle duration (hours) instead of fixed date to determine end date', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2h')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[0].startTime).toEqual(moment('2013-01-01', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].endTime).toEqual(moment('2013-01-01 2:00', 'YYYY-MM-DD hh:mm').toDate())
-    expect(tasks[0].id).toEqual('id1')
-    expect(tasks[0].task).toEqual('test1')
-  })
-  it('should handle duration (minutes) instead of fixed date to determine end date', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2m')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[0].startTime).toEqual(moment('2013-01-01', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].endTime).toEqual(moment('2013-01-01 00:02', 'YYYY-MM-DD hh:mm').toDate())
-    expect(tasks[0].id).toEqual('id1')
-    expect(tasks[0].task).toEqual('test1')
-  })
-  it('should handle duration (seconds) instead of fixed date to determine end date', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2s')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[0].startTime).toEqual(moment('2013-01-01', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].endTime).toEqual(moment('2013-01-01 00:00:02', 'YYYY-MM-DD hh:mm:ss').toDate())
-    expect(tasks[0].id).toEqual('id1')
-    expect(tasks[0].task).toEqual('test1')
-  })
-  it('should handle duration (weeks) instead of fixed date to determine end date', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2w')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[0].startTime).toEqual(moment('2013-01-01', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].endTime).toEqual(moment('2013-01-15', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].id).toEqual('id1')
-    expect(tasks[0].task).toEqual('test1')
-  })
-
-  it('should handle relative start date based on id', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2w')
-    ganttDb.addTask('test2', 'id2,after id1,1d')
-
-    const tasks = ganttDb.getTasks()
-
-    expect(tasks[1].startTime).toEqual(moment('2013-01-15', 'YYYY-MM-DD').toDate())
-    expect(tasks[1].id).toEqual('id2')
-    expect(tasks[1].task).toEqual('test2')
-  })
-
-  it('should handle relative start date based on id when id is invalid', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2w')
-    ganttDb.addTask('test2', 'id2,after id3,1d')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[1].startTime).toEqual(new Date((new Date()).setHours(0, 0, 0, 0)))
-    expect(tasks[1].id).toEqual('id2')
-    expect(tasks[1].task).toEqual('test2')
-  })
-
-  it('should handle fixed dates without id', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', '2013-01-01,2013-01-12')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[0].startTime).toEqual(moment('2013-01-01', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].endTime).toEqual(moment('2013-01-12', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].id).toEqual('task1')
-    expect(tasks[0].task).toEqual('test1')
-  })
-
-  it('should handle duration instead of a fixed date to determine end date without id', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', '2013-01-01,4d')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[0].startTime).toEqual(moment('2013-01-01', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].endTime).toEqual(moment('2013-01-05', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].id).toEqual('task1')
-    expect(tasks[0].task).toEqual('test1')
-  })
-
-  it('should handle relative start date of a fixed date to determine end date without id', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2w')
-    ganttDb.addTask('test2', 'after id1,1d')
-
-    const tasks = ganttDb.getTasks()
-
-    expect(tasks[1].startTime).toEqual(moment('2013-01-15', 'YYYY-MM-DD').toDate())
-    expect(tasks[1].id).toEqual('task1')
-    expect(tasks[1].task).toEqual('test2')
-  })
-  it('should handle a new task with only an end date as definition', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2w')
-    ganttDb.addTask('test2', '2013-01-26')
-
-    const tasks = ganttDb.getTasks()
-
-    expect(tasks[1].startTime).toEqual(moment('2013-01-15', 'YYYY-MM-DD').toDate())
-    expect(tasks[1].endTime).toEqual(moment('2013-01-26', 'YYYY-MM-DD').toDate())
-    expect(tasks[1].id).toEqual('task1')
-    expect(tasks[1].task).toEqual('test2')
-  })
-  it('should handle a new task with only an end date as definition', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2w')
-    ganttDb.addTask('test2', '2d')
-
-    const tasks = ganttDb.getTasks()
-
-    expect(tasks[1].startTime).toEqual(moment('2013-01-15', 'YYYY-MM-DD').toDate())
-    expect(tasks[1].endTime).toEqual(moment('2013-01-17', 'YYYY-MM-DD').toDate())
-    expect(tasks[1].id).toEqual('task1')
-    expect(tasks[1].task).toEqual('test2')
-  })
-  it('should handle relative start date based on id regardless of sections', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2w')
-    ganttDb.addTask('test2', 'id2,after id3,1d')
-    ganttDb.addSection('testa2')
-    ganttDb.addTask('test3', 'id3,after id1,2d')
-
-    const tasks = ganttDb.getTasks()
-
-    expect(tasks[1].startTime).toEqual(moment('2013-01-17', 'YYYY-MM-DD').toDate())
-    expect(tasks[1].endTime).toEqual(moment('2013-01-18', 'YYYY-MM-DD').toDate())
-    expect(tasks[1].id).toEqual('id2')
-    expect(tasks[1].task).toEqual('test2')
-
-    expect(tasks[2].id).toEqual('id3')
-    expect(tasks[2].task).toEqual('test3')
-    expect(tasks[2].startTime).toEqual(moment('2013-01-15', 'YYYY-MM-DD').toDate())
-    expect(tasks[2].endTime).toEqual(moment('2013-01-17', 'YYYY-MM-DD').toDate())
-  })
-})
diff --git a/_submodules/mermaid/src/diagrams/gantt/ganttRenderer.js b/_submodules/mermaid/src/diagrams/gantt/ganttRenderer.js
deleted file mode 100644
index 7d24df2a4c4defa0cd12be30e28a0bbd478f0063..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/gantt/ganttRenderer.js
+++ /dev/null
@@ -1,344 +0,0 @@
-import * as d3 from 'd3'
-
-import { parser } from './parser/gantt'
-import ganttDb from './ganttDb'
-
-parser.yy = ganttDb
-
-const conf = {
-  titleTopMargin: 25,
-  barHeight: 20,
-  barGap: 4,
-  topPadding: 50,
-  rightPadding: 75,
-  leftPadding: 75,
-  gridLineStartPadding: 35,
-  fontSize: 11,
-  fontFamily: '"Open-Sans", "sans-serif"'
-}
-export const setConf = function (cnf) {
-  const keys = Object.keys(cnf)
-
-  keys.forEach(function (key) {
-    conf[key] = cnf[key]
-  })
-}
-let w
-export const draw = function (text, id) {
-  parser.yy.clear()
-  parser.parse(text)
-
-  const elem = document.getElementById(id)
-  w = elem.parentElement.offsetWidth
-
-  if (typeof w === 'undefined') {
-    w = 1200
-  }
-
-  if (typeof conf.useWidth !== 'undefined') {
-    w = conf.useWidth
-  }
-
-  const taskArray = parser.yy.getTasks()
-
-  // Set height based on number of tasks
-  const h = taskArray.length * (conf.barHeight + conf.barGap) + 2 * conf.topPadding
-
-  elem.setAttribute('height', '100%')
-  // Set viewBox
-  elem.setAttribute('viewBox', '0 0 ' + w + ' ' + h)
-  const svg = d3.select(`[id="${id}"]`)
-
-  // Set timescale
-  const timeScale = d3.scaleTime()
-    .domain([d3.min(taskArray, function (d) {
-      return d.startTime
-    }),
-    d3.max(taskArray, function (d) {
-      return d.endTime
-    })])
-    .rangeRound([0, w - conf.leftPadding - conf.rightPadding])
-
-  let categories = []
-
-  for (let i = 0; i < taskArray.length; i++) {
-    categories.push(taskArray[i].type)
-  }
-
-  const catsUnfiltered = categories // for vert labels
-
-  categories = checkUnique(categories)
-
-  makeGant(taskArray, w, h)
-  if (typeof conf.useWidth !== 'undefined') {
-    elem.setAttribute('width', w)
-  }
-
-  svg.append('text')
-    .text(parser.yy.getTitle())
-    .attr('x', w / 2)
-    .attr('y', conf.titleTopMargin)
-    .attr('class', 'titleText')
-
-  function makeGant (tasks, pageWidth, pageHeight) {
-    const barHeight = conf.barHeight
-    const gap = barHeight + conf.barGap
-    const topPadding = conf.topPadding
-    const leftPadding = conf.leftPadding
-
-    const colorScale = d3.scaleLinear()
-      .domain([0, categories.length])
-      .range(['#00B9FA', '#F95002'])
-      .interpolate(d3.interpolateHcl)
-
-    makeGrid(leftPadding, topPadding, pageWidth, pageHeight)
-    drawRects(tasks, gap, topPadding, leftPadding, barHeight, colorScale, pageWidth, pageHeight)
-    vertLabels(gap, topPadding, leftPadding, barHeight, colorScale)
-    drawToday(leftPadding, topPadding, pageWidth, pageHeight)
-  }
-
-  function drawRects (theArray, theGap, theTopPad, theSidePad, theBarHeight, theColorScale, w, h) {
-    svg.append('g')
-      .selectAll('rect')
-      .data(theArray)
-      .enter()
-      .append('rect')
-      .attr('x', 0)
-      .attr('y', function (d, i) {
-        return i * theGap + theTopPad - 2
-      })
-      .attr('width', function () {
-        return w - conf.rightPadding / 2
-      })
-      .attr('height', theGap)
-      .attr('class', function (d) {
-        for (let i = 0; i < categories.length; i++) {
-          if (d.type === categories[i]) {
-            return 'section section' + (i % conf.numberSectionStyles)
-          }
-        }
-        return 'section section0'
-      })
-
-    const rectangles = svg.append('g')
-      .selectAll('rect')
-      .data(theArray)
-      .enter()
-
-    rectangles.append('rect')
-      .attr('rx', 3)
-      .attr('ry', 3)
-      .attr('x', function (d) {
-        return timeScale(d.startTime) + theSidePad
-      })
-      .attr('y', function (d, i) {
-        return i * theGap + theTopPad
-      })
-      .attr('width', function (d) {
-        return (timeScale(d.endTime) - timeScale(d.startTime))
-      })
-      .attr('height', theBarHeight)
-      .attr('class', function (d) {
-        const res = 'task '
-
-        let secNum = 0
-        for (let i = 0; i < categories.length; i++) {
-          if (d.type === categories[i]) {
-            secNum = (i % conf.numberSectionStyles)
-          }
-        }
-
-        if (d.active) {
-          if (d.crit) {
-            return res + ' activeCrit' + secNum
-          } else {
-            return res + ' active' + secNum
-          }
-        }
-
-        if (d.done) {
-          if (d.crit) {
-            return res + ' doneCrit' + secNum
-          } else {
-            return res + ' done' + secNum
-          }
-        }
-
-        if (d.crit) {
-          return res + ' crit' + secNum
-        }
-
-        return res + ' task' + secNum
-      })
-
-    rectangles.append('text')
-      .text(function (d) {
-        return d.task
-      })
-      .attr('font-size', conf.fontSize)
-      .attr('x', function (d) {
-        const startX = timeScale(d.startTime)
-        const endX = timeScale(d.endTime)
-        const textWidth = this.getBBox().width
-
-        // Check id text width > width of rectangle
-        if (textWidth > (endX - startX)) {
-          if (endX + textWidth + 1.5 * conf.leftPadding > w) {
-            return startX + theSidePad - 5
-          } else {
-            return endX + theSidePad + 5
-          }
-        } else {
-          return (endX - startX) / 2 + startX + theSidePad
-        }
-      })
-      .attr('y', function (d, i) {
-        return i * theGap + (conf.barHeight / 2) + (conf.fontSize / 2 - 2) + theTopPad
-      })
-      .attr('text-height', theBarHeight)
-      .attr('class', function (d) {
-        const startX = timeScale(d.startTime)
-        const endX = timeScale(d.endTime)
-        const textWidth = this.getBBox().width
-        let secNum = 0
-        for (let i = 0; i < categories.length; i++) {
-          if (d.type === categories[i]) {
-            secNum = (i % conf.numberSectionStyles)
-          }
-        }
-
-        let taskType = ''
-        if (d.active) {
-          if (d.crit) {
-            taskType = 'activeCritText' + secNum
-          } else {
-            taskType = 'activeText' + secNum
-          }
-        }
-
-        if (d.done) {
-          if (d.crit) {
-            taskType = taskType + ' doneCritText' + secNum
-          } else {
-            taskType = taskType + ' doneText' + secNum
-          }
-        } else {
-          if (d.crit) {
-            taskType = taskType + ' critText' + secNum
-          }
-        }
-
-        // Check id text width > width of rectangle
-        if (textWidth > (endX - startX)) {
-          if (endX + textWidth + 1.5 * conf.leftPadding > w) {
-            return 'taskTextOutsideLeft taskTextOutside' + secNum + ' ' + taskType
-          } else {
-            return 'taskTextOutsideRight taskTextOutside' + secNum + ' ' + taskType
-          }
-        } else {
-          return 'taskText taskText' + secNum + ' ' + taskType
-        }
-      })
-  }
-
-  function makeGrid (theSidePad, theTopPad, w, h) {
-    let xAxis = d3.axisBottom(timeScale)
-      .tickSize(-h + theTopPad + conf.gridLineStartPadding)
-      .tickFormat(d3.timeFormat(parser.yy.getAxisFormat() || conf.axisFormat || '%Y-%m-%d'))
-
-    svg.append('g')
-      .attr('class', 'grid')
-      .attr('transform', 'translate(' + theSidePad + ', ' + (h - 50) + ')')
-      .call(xAxis)
-      .selectAll('text')
-      .style('text-anchor', 'middle')
-      .attr('fill', '#000')
-      .attr('stroke', 'none')
-      .attr('font-size', 10)
-      .attr('dy', '1em')
-  }
-
-  function vertLabels (theGap, theTopPad) {
-    const numOccurances = []
-    let prevGap = 0
-
-    for (let i = 0; i < categories.length; i++) {
-      numOccurances[i] = [categories[i], getCount(categories[i], catsUnfiltered)]
-    }
-
-    svg.append('g') // without doing this, impossible to put grid lines behind text
-      .selectAll('text')
-      .data(numOccurances)
-      .enter()
-      .append('text')
-      .text(function (d) {
-        return d[0]
-      })
-      .attr('x', 10)
-      .attr('y', function (d, i) {
-        if (i > 0) {
-          for (let j = 0; j < i; j++) {
-            prevGap += numOccurances[i - 1][1]
-            return d[1] * theGap / 2 + prevGap * theGap + theTopPad
-          }
-        } else {
-          return d[1] * theGap / 2 + theTopPad
-        }
-      })
-      .attr('class', function (d) {
-        for (let i = 0; i < categories.length; i++) {
-          if (d[0] === categories[i]) {
-            return 'sectionTitle sectionTitle' + (i % conf.numberSectionStyles)
-          }
-        }
-        return 'sectionTitle'
-      })
-  }
-
-  function drawToday (theSidePad, theTopPad, w, h) {
-    const todayG = svg.append('g')
-      .attr('class', 'today')
-
-    const today = new Date()
-
-    todayG.append('line')
-      .attr('x1', timeScale(today) + theSidePad)
-      .attr('x2', timeScale(today) + theSidePad)
-      .attr('y1', conf.titleTopMargin)
-      .attr('y2', h - conf.titleTopMargin)
-      .attr('class', 'today')
-  }
-
-  // from this stackexchange question: http://stackoverflow.com/questions/1890203/unique-for-arrays-in-javascript
-  function checkUnique (arr) {
-    const hash = {}
-    const result = []
-    for (let i = 0, l = arr.length; i < l; ++i) {
-      if (!hash.hasOwnProperty(arr[i])) { // it works with objects! in FF, at least
-        hash[arr[i]] = true
-        result.push(arr[i])
-      }
-    }
-    return result
-  }
-
-  // from this stackexchange question: http://stackoverflow.com/questions/14227981/count-how-many-strings-in-an-array-have-duplicates-in-the-same-array
-  function getCounts (arr) {
-    let i = arr.length // const to loop over
-    const obj = {} // obj to store results
-    while (i) {
-      obj[arr[--i]] = (obj[arr[i]] || 0) + 1 // count occurrences
-    }
-    return obj
-  }
-
-  // get specific from everything
-  function getCount (word, arr) {
-    return getCounts(arr)[word] || 0
-  }
-}
-
-export default {
-  setConf,
-  draw
-}
diff --git a/_submodules/mermaid/src/diagrams/gantt/parser/gantt.jison b/_submodules/mermaid/src/diagrams/gantt/parser/gantt.jison
deleted file mode 100644
index 49ab3ad477e027544f2ef62de2c709c7caeda6af..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/gantt/parser/gantt.jison
+++ /dev/null
@@ -1,64 +0,0 @@
-/** mermaid
- *  https://mermaidjs.github.io/
- *  (c) 2015 Knut Sveidqvist
- *  MIT license.
- */
-%lex
-
-%options case-insensitive
-
-%{
-	// Pre-lexer code can go here
-%}
-
-%%
-
-[\n]+                   return 'NL';
-\s+                     /* skip whitespace */
-\#[^\n]*                /* skip comments */
-\%%[^\n]*               /* skip comments */
-"gantt"     	        return 'gantt';
-"dateFormat"\s[^#\n;]+  return 'dateFormat';
-"axisFormat"\s[^#\n;]+  return 'axisFormat';
-\d\d\d\d"-"\d\d"-"\d\d  return 'date';
-"title"\s[^#\n;]+       return 'title';
-"section"\s[^#:\n;]+    return 'section';
-[^#:\n;]+               return 'taskTxt';
-":"[^#\n;]+             return 'taskData';
-":"                         return ':';
-<<EOF>>                     return 'EOF';
-.                           return 'INVALID';
-
-/lex
-
-%left '^'
-
-%start start
-
-%% /* language grammar */
-
-start
-	: gantt document 'EOF' { return $2; }
-	;
-
-document
-	: /* empty */ { $$ = [] }
-	| document line {$1.push($2);$$ = $1}
-	;
-
-line
-	: SPACE statement { $$ = $2 }
-	| statement { $$ = $1 }
-	| NL { $$=[];}
-	| EOF { $$=[];}
-	;
-
-statement
-	: 'dateFormat' {yy.setDateFormat($1.substr(11));$$=$1.substr(11);}
-  | 'axisFormat' {yy.setAxisFormat($1.substr(11));$$=$1.substr(11);}
-	| title {yy.setTitle($1.substr(6));$$=$1.substr(6);}
-	| section {yy.addSection($1.substr(8));$$=$1.substr(8);}
-	| taskTxt taskData {yy.addTask($1,$2);$$='task';}
-	;
-
-%%
diff --git a/_submodules/mermaid/src/diagrams/gantt/parser/gantt.js b/_submodules/mermaid/src/diagrams/gantt/parser/gantt.js
deleted file mode 100644
index 38ff324ee092da87330859d58b37870f000f39b8..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/gantt/parser/gantt.js
+++ /dev/null
@@ -1,661 +0,0 @@
-/* parser generated by jison 0.4.18 */
-/*
-  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=[6,8,10,11,12,13,14,15],$V1=[1,9],$V2=[1,10],$V3=[1,11],$V4=[1,12],$V5=[1,13];
-var parser = {trace: function trace() { },
-yy: {},
-symbols_: {"error":2,"start":3,"gantt":4,"document":5,"EOF":6,"line":7,"SPACE":8,"statement":9,"NL":10,"dateFormat":11,"axisFormat":12,"title":13,"section":14,"taskTxt":15,"taskData":16,"$accept":0,"$end":1},
-terminals_: {2:"error",4:"gantt",6:"EOF",8:"SPACE",10:"NL",11:"dateFormat",12:"axisFormat",13:"title",14:"section",15:"taskTxt",16:"taskData"},
-productions_: [0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,1],[9,1],[9,1],[9,2]],
-performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
-/* this == yyval */
-
-var $0 = $$.length - 1;
-switch (yystate) {
-case 1:
- return $$[$0-1]; 
-break;
-case 2:
- this.$ = [] 
-break;
-case 3:
-$$[$0-1].push($$[$0]);this.$ = $$[$0-1]
-break;
-case 4: case 5:
- this.$ = $$[$0] 
-break;
-case 6: case 7:
- this.$=[];
-break;
-case 8:
-yy.setDateFormat($$[$0].substr(11));this.$=$$[$0].substr(11);
-break;
-case 9:
-yy.setAxisFormat($$[$0].substr(11));this.$=$$[$0].substr(11);
-break;
-case 10:
-yy.setTitle($$[$0].substr(6));this.$=$$[$0].substr(6);
-break;
-case 11:
-yy.addSection($$[$0].substr(8));this.$=$$[$0].substr(8);
-break;
-case 12:
-yy.addTask($$[$0-1],$$[$0]);this.$='task';
-break;
-}
-},
-table: [{3:1,4:[1,2]},{1:[3]},o($V0,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:$V1,12:$V2,13:$V3,14:$V4,15:$V5},o($V0,[2,7],{1:[2,1]}),o($V0,[2,3]),{9:14,11:$V1,12:$V2,13:$V3,14:$V4,15:$V5},o($V0,[2,5]),o($V0,[2,6]),o($V0,[2,8]),o($V0,[2,9]),o($V0,[2,10]),o($V0,[2,11]),{16:[1,15]},o($V0,[2,4]),o($V0,[2,12])],
-defaultActions: {},
-parseError: function parseError(str, hash) {
-    if (hash.recoverable) {
-        this.trace(str);
-    } else {
-        var error = new Error(str);
-        error.hash = hash;
-        throw error;
-    }
-},
-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;
-    }
-            function lex() {
-            var token;
-            token = tstack.pop() || lexer.lex() || EOF;
-            if (typeof token !== 'number') {
-                if (token instanceof Array) {
-                    tstack = token;
-                    token = tstack.pop();
-                }
-                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["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: {"case-insensitive":true},
-performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
-	// Pre-lexer code can go here
-
-var YYSTATE=YY_START;
-switch($avoiding_name_collisions) {
-case 0:return 10;
-break;
-case 1:/* skip whitespace */
-break;
-case 2:/* skip comments */
-break;
-case 3:/* skip comments */
-break;
-case 4:return 4;
-break;
-case 5:return 11;
-break;
-case 6:return 12;
-break;
-case 7:return 'date';
-break;
-case 8:return 13;
-break;
-case 9:return 14;
-break;
-case 10:return 15;
-break;
-case 11:return 16;
-break;
-case 12:return ':';
-break;
-case 13:return 6;
-break;
-case 14:return 'INVALID';
-break;
-}
-},
-rules: [/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],
-conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14],"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 = parser;
-exports.Parser = parser.Parser;
-exports.parse = function () { return parser.parse.apply(parser, 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));
-}
-}
\ No newline at end of file
diff --git a/_submodules/mermaid/src/diagrams/git/gitGraphAst.js b/_submodules/mermaid/src/diagrams/git/gitGraphAst.js
deleted file mode 100644
index e734453b761e66a73d1ab5ef5d668774fb166e83..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/git/gitGraphAst.js
+++ /dev/null
@@ -1,228 +0,0 @@
-import _ from 'lodash'
-
-import { logger } from '../../logger'
-
-let commits = {}
-let head = null
-let branches = { 'master': head }
-let curBranch = 'master'
-let direction = 'LR'
-let seq = 0
-
-function getRandomInt (min, max) {
-  return Math.floor(Math.random() * (max - min)) + min
-}
-
-function getId () {
-  const pool = '0123456789abcdef'
-  let id = ''
-  for (let i = 0; i < 7; i++) {
-    id += pool[getRandomInt(0, 16)]
-  }
-  return id
-}
-
-function isfastforwardable (currentCommit, otherCommit) {
-  logger.debug('Entering isfastforwardable:', currentCommit.id, otherCommit.id)
-  while (currentCommit.seq <= otherCommit.seq && currentCommit !== otherCommit) {
-    // only if other branch has more commits
-    if (otherCommit.parent == null) break
-    if (Array.isArray(otherCommit.parent)) {
-      logger.debug('In merge commit:', otherCommit.parent)
-      return isfastforwardable(currentCommit, commits[otherCommit.parent[0]]) ||
-        isfastforwardable(currentCommit, commits[otherCommit.parent[1]])
-    } else {
-      otherCommit = commits[otherCommit.parent]
-    }
-  }
-  logger.debug(currentCommit.id, otherCommit.id)
-  return currentCommit.id === otherCommit.id
-}
-
-function isReachableFrom (currentCommit, otherCommit) {
-  const currentSeq = currentCommit.seq
-  const otherSeq = otherCommit.seq
-  if (currentSeq > otherSeq) return isfastforwardable(otherCommit, currentCommit)
-  return false
-}
-
-export const setDirection = function (dir) {
-  direction = dir
-}
-let options = {}
-export const setOptions = function (rawOptString) {
-  logger.debug('options str', rawOptString)
-  rawOptString = rawOptString && rawOptString.trim()
-  rawOptString = rawOptString || '{}'
-  try {
-    options = JSON.parse(rawOptString)
-  } catch (e) {
-    logger.error('error while parsing gitGraph options', e.message)
-  }
-}
-
-export const getOptions = function () {
-  return options
-}
-
-export const commit = function (msg) {
-  const commit = {
-    id: getId(),
-    message: msg,
-    seq: seq++,
-    parent: head == null ? null : head.id
-  }
-  head = commit
-  commits[commit.id] = commit
-  branches[curBranch] = commit.id
-  logger.debug('in pushCommit ' + commit.id)
-}
-
-export const branch = function (name) {
-  branches[name] = head != null ? head.id : null
-  logger.debug('in createBranch')
-}
-
-export const merge = function (otherBranch) {
-  const currentCommit = commits[branches[curBranch]]
-  const otherCommit = commits[branches[otherBranch]]
-  if (isReachableFrom(currentCommit, otherCommit)) {
-    logger.debug('Already merged')
-    return
-  }
-  if (isfastforwardable(currentCommit, otherCommit)) {
-    branches[curBranch] = branches[otherBranch]
-    head = commits[branches[curBranch]]
-  } else {
-    // create merge commit
-    const commit = {
-      id: getId(),
-      message: 'merged branch ' + otherBranch + ' into ' + curBranch,
-      seq: seq++,
-      parent: [head == null ? null : head.id, branches[otherBranch]]
-    }
-    head = commit
-    commits[commit.id] = commit
-    branches[curBranch] = commit.id
-  }
-  logger.debug(branches)
-  logger.debug('in mergeBranch')
-}
-
-export const checkout = function (branch) {
-  logger.debug('in checkout')
-  curBranch = branch
-  const id = branches[curBranch]
-  head = commits[id]
-}
-
-export const reset = function (commitRef) {
-  logger.debug('in reset', commitRef)
-  const ref = commitRef.split(':')[0]
-  let parentCount = parseInt(commitRef.split(':')[1])
-  let commit = ref === 'HEAD' ? head : commits[branches[ref]]
-  logger.debug(commit, parentCount)
-  while (parentCount > 0) {
-    commit = commits[commit.parent]
-    parentCount--
-    if (!commit) {
-      const err = 'Critical error - unique parent commit not found during reset'
-      logger.error(err)
-      throw err
-    }
-  }
-  head = commit
-  branches[curBranch] = commit.id
-}
-
-function upsert (arr, key, newval) {
-  const index = arr.indexOf(key)
-  if (index === -1) {
-    arr.push(newval)
-  } else {
-    arr.splice(index, 1, newval)
-  }
-}
-
-function prettyPrintCommitHistory (commitArr) {
-  const commit = _.maxBy(commitArr, 'seq')
-  let line = ''
-  commitArr.forEach(function (c) {
-    if (c === commit) {
-      line += '\t*'
-    } else {
-      line += '\t|'
-    }
-  })
-  const label = [line, commit.id, commit.seq]
-  _.each(branches, function (value, key) {
-    if (value === commit.id) label.push(key)
-  })
-  logger.debug(label.join(' '))
-  if (Array.isArray(commit.parent)) {
-    const newCommit = commits[commit.parent[0]]
-    upsert(commitArr, commit, newCommit)
-    commitArr.push(commits[commit.parent[1]])
-  } else if (commit.parent == null) {
-    return
-  } else {
-    const nextCommit = commits[commit.parent]
-    upsert(commitArr, commit, nextCommit)
-  }
-  commitArr = _.uniqBy(commitArr, 'id')
-  prettyPrintCommitHistory(commitArr)
-}
-
-export const prettyPrint = function () {
-  logger.debug(commits)
-  const node = getCommitsArray()[0]
-  prettyPrintCommitHistory([node])
-}
-
-export const clear = function () {
-  commits = {}
-  head = null
-  branches = { 'master': head }
-  curBranch = 'master'
-  seq = 0
-}
-
-export const getBranchesAsObjArray = function () {
-  const branchArr = _.map(branches, function (value, key) {
-    return { 'name': key, 'commit': commits[value] }
-  })
-  return branchArr
-}
-
-export const getBranches = function () { return branches }
-export const getCommits = function () { return commits }
-export const getCommitsArray = function () {
-  const commitArr = Object.keys(commits).map(function (key) {
-    return commits[key]
-  })
-  commitArr.forEach(function (o) { logger.debug(o.id) })
-  return _.orderBy(commitArr, ['seq'], ['desc'])
-}
-export const getCurrentBranch = function () { return curBranch }
-export const getDirection = function () { return direction }
-export const getHead = function () { return head }
-
-export default {
-  setDirection,
-  setOptions,
-  getOptions,
-  commit,
-  branch,
-  merge,
-  checkout,
-  reset,
-  prettyPrint,
-  clear,
-  getBranchesAsObjArray,
-  getBranches,
-  getCommits,
-  getCommitsArray,
-  getCurrentBranch,
-  getDirection,
-  getHead
-}
diff --git a/_submodules/mermaid/src/diagrams/git/gitGraphParser.spec.js b/_submodules/mermaid/src/diagrams/git/gitGraphParser.spec.js
deleted file mode 100644
index aba2812d99ac3e2166a694de1fb700960ea9b30e..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/git/gitGraphParser.spec.js
+++ /dev/null
@@ -1,241 +0,0 @@
-/* eslint-env jasmine */
-import gitGraphAst from './gitGraphAst'
-import { parser } from './parser/gitGraph'
-
-describe('when parsing a gitGraph', function () {
-  beforeEach(function () {
-    parser.yy = gitGraphAst
-    parser.yy.clear()
-  })
-  it('should handle a gitGraph defintion', function () {
-    const str = 'gitGraph:\n' +
-      'commit\n'
-
-    parser.parse(str)
-    const commits = parser.yy.getCommits()
-
-    expect(Object.keys(commits).length).toBe(1)
-    expect(parser.yy.getCurrentBranch()).toBe('master')
-    expect(parser.yy.getDirection()).toBe('LR')
-    expect(Object.keys(parser.yy.getBranches()).length).toBe(1)
-  })
-
-  it('should handle a gitGraph defintion with empty options', function () {
-    const str = 'gitGraph:\n' +
-      'options\n' +
-      'end\n' +
-      'commit\n'
-
-    parser.parse(str)
-    const commits = parser.yy.getCommits()
-
-    expect(parser.yy.getOptions()).toEqual({})
-    expect(Object.keys(commits).length).toBe(1)
-    expect(parser.yy.getCurrentBranch()).toBe('master')
-    expect(parser.yy.getDirection()).toBe('LR')
-    expect(Object.keys(parser.yy.getBranches()).length).toBe(1)
-  })
-
-  it('should handle a gitGraph defintion with valid options', function () {
-    const str = 'gitGraph:\n' +
-      'options\n' +
-      '{"key": "value"}\n' +
-      'end\n' +
-      'commit\n'
-
-    parser.parse(str)
-    const commits = parser.yy.getCommits()
-    expect(parser.yy.getOptions()['key']).toBe('value')
-    expect(Object.keys(commits).length).toBe(1)
-    expect(parser.yy.getCurrentBranch()).toBe('master')
-    expect(parser.yy.getDirection()).toBe('LR')
-    expect(Object.keys(parser.yy.getBranches()).length).toBe(1)
-  })
-
-  it('should not fail on a gitGraph with malformed json', function () {
-    const str = 'gitGraph:\n' +
-      'options\n' +
-      '{"key": "value"\n' +
-      'end\n' +
-      'commit\n'
-
-    parser.parse(str)
-    const commits = parser.yy.getCommits()
-    expect(Object.keys(commits).length).toBe(1)
-    expect(parser.yy.getCurrentBranch()).toBe('master')
-    expect(parser.yy.getDirection()).toBe('LR')
-    expect(Object.keys(parser.yy.getBranches()).length).toBe(1)
-  })
-
-  it('should handle set direction', function () {
-    const str = 'gitGraph BT:\n' +
-      'commit\n'
-
-    parser.parse(str)
-    const commits = parser.yy.getCommits()
-
-    expect(Object.keys(commits).length).toBe(1)
-    expect(parser.yy.getCurrentBranch()).toBe('master')
-    expect(parser.yy.getDirection()).toBe('BT')
-    expect(Object.keys(parser.yy.getBranches()).length).toBe(1)
-  })
-
-  it('should checkout a branch', function () {
-    const str = 'gitGraph:\n' +
-      'branch new\n' +
-      'checkout new\n'
-
-    parser.parse(str)
-    const commits = parser.yy.getCommits()
-
-    expect(Object.keys(commits).length).toBe(0)
-    expect(parser.yy.getCurrentBranch()).toBe('new')
-  })
-
-  it('should add commits to checked out branch', function () {
-    const str = 'gitGraph:\n' +
-      'branch new\n' +
-      'checkout new\n' +
-      'commit\n' +
-      'commit\n'
-
-    parser.parse(str)
-    const commits = parser.yy.getCommits()
-
-    expect(Object.keys(commits).length).toBe(2)
-    expect(parser.yy.getCurrentBranch()).toBe('new')
-    const branchCommit = parser.yy.getBranches()['new']
-    expect(branchCommit).not.toBeNull()
-    expect(commits[branchCommit].parent).not.toBeNull()
-  })
-  it('should handle commit with args', function () {
-    const str = 'gitGraph:\n' +
-      'commit "a commit"\n'
-
-    parser.parse(str)
-    const commits = parser.yy.getCommits()
-
-    expect(Object.keys(commits).length).toBe(1)
-    const key = Object.keys(commits)[0]
-    expect(commits[key].message).toBe('a commit')
-    expect(parser.yy.getCurrentBranch()).toBe('master')
-  })
-
-  it('it should reset a branch', function () {
-    const str = 'gitGraph:\n' +
-      'commit\n' +
-      'commit\n' +
-      'branch newbranch\n' +
-      'checkout newbranch\n' +
-      'commit\n' +
-      'reset master\n'
-
-    parser.parse(str)
-
-    const commits = parser.yy.getCommits()
-    expect(Object.keys(commits).length).toBe(3)
-    expect(parser.yy.getCurrentBranch()).toBe('newbranch')
-    expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master'])
-    expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['newbranch'])
-  })
-
-  it('reset can take an argument', function () {
-    const str = 'gitGraph:\n' +
-      'commit\n' +
-      'commit\n' +
-      'branch newbranch\n' +
-      'checkout newbranch\n' +
-      'commit\n' +
-      'reset master^\n'
-
-    parser.parse(str)
-
-    const commits = parser.yy.getCommits()
-    expect(Object.keys(commits).length).toBe(3)
-    expect(parser.yy.getCurrentBranch()).toBe('newbranch')
-    const master = commits[parser.yy.getBranches()['master']]
-    expect(parser.yy.getHead().id).toEqual(master.parent)
-  })
-
-  it('it should handle fast forwardable merges', function () {
-    const str = 'gitGraph:\n' +
-      'commit\n' +
-      'branch newbranch\n' +
-      'checkout newbranch\n' +
-      'commit\n' +
-      'commit\n' +
-      'checkout master\n' +
-      'merge newbranch\n'
-
-    parser.parse(str)
-
-    const commits = parser.yy.getCommits()
-    expect(Object.keys(commits).length).toBe(3)
-    expect(parser.yy.getCurrentBranch()).toBe('master')
-    expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master'])
-    expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['newbranch'])
-  })
-
-  it('it should handle cases when merge is a noop', function () {
-    const str = 'gitGraph:\n' +
-      'commit\n' +
-      'branch newbranch\n' +
-      'checkout newbranch\n' +
-      'commit\n' +
-      'commit\n' +
-      'merge master\n'
-
-    parser.parse(str)
-
-    const commits = parser.yy.getCommits()
-    expect(Object.keys(commits).length).toBe(3)
-    expect(parser.yy.getCurrentBranch()).toBe('newbranch')
-    expect(parser.yy.getBranches()['newbranch']).not.toEqual(parser.yy.getBranches()['master'])
-    expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['newbranch'])
-  })
-
-  it('it should handle merge with 2 parents', function () {
-    const str = 'gitGraph:\n' +
-      'commit\n' +
-      'branch newbranch\n' +
-      'checkout newbranch\n' +
-      'commit\n' +
-      'commit\n' +
-      'checkout master\n' +
-      'commit\n' +
-      'merge newbranch\n'
-
-    parser.parse(str)
-
-    const commits = parser.yy.getCommits()
-    expect(Object.keys(commits).length).toBe(5)
-    expect(parser.yy.getCurrentBranch()).toBe('master')
-    expect(parser.yy.getBranches()['newbranch']).not.toEqual(parser.yy.getBranches()['master'])
-    expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['master'])
-  })
-
-  it('it should handle ff merge when history walk has two parents (merge commit)', function () {
-    const str = 'gitGraph:\n' +
-      'commit\n' +
-      'branch newbranch\n' +
-      'checkout newbranch\n' +
-      'commit\n' +
-      'commit\n' +
-      'checkout master\n' +
-      'commit\n' +
-      'merge newbranch\n' +
-      'commit\n' +
-      'checkout newbranch\n' +
-      'merge master\n'
-
-    parser.parse(str)
-
-    const commits = parser.yy.getCommits()
-    expect(Object.keys(commits).length).toBe(6)
-    expect(parser.yy.getCurrentBranch()).toBe('newbranch')
-    expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master'])
-    expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['master'])
-
-    parser.yy.prettyPrint()
-  })
-})
diff --git a/_submodules/mermaid/src/diagrams/git/gitGraphRenderer.js b/_submodules/mermaid/src/diagrams/git/gitGraphRenderer.js
deleted file mode 100644
index 3ef56478da7e4d3ffddd0c9d23c0dd639c5dcc84..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/git/gitGraphRenderer.js
+++ /dev/null
@@ -1,280 +0,0 @@
-import _ from 'lodash'
-import * as d3 from 'd3'
-
-import db from './gitGraphAst'
-import gitGraphParser from './parser/gitGraph'
-import { logger } from '../../logger'
-import { interpolateToCurve } from '../../utils'
-
-let allCommitsDict = {}
-let branchNum
-let config = {
-  nodeSpacing: 150,
-  nodeFillColor: 'yellow',
-  nodeStrokeWidth: 2,
-  nodeStrokeColor: 'grey',
-  lineStrokeWidth: 4,
-  branchOffset: 50,
-  lineColor: 'grey',
-  leftMargin: 50,
-  branchColors: ['#442f74', '#983351', '#609732', '#AA9A39'],
-  nodeRadius: 10,
-  nodeLabel: {
-    width: 75,
-    height: 100,
-    x: -25,
-    y: 0
-  }
-}
-let apiConfig = {}
-export const setConf = function (c) {
-  apiConfig = c
-}
-
-function svgCreateDefs (svg) {
-  svg
-    .append('defs')
-    .append('g')
-    .attr('id', 'def-commit')
-    .append('circle')
-    .attr('r', config.nodeRadius)
-    .attr('cx', 0)
-    .attr('cy', 0)
-  svg.select('#def-commit')
-    .append('foreignObject')
-    .attr('width', config.nodeLabel.width)
-    .attr('height', config.nodeLabel.height)
-    .attr('x', config.nodeLabel.x)
-    .attr('y', config.nodeLabel.y)
-    .attr('class', 'node-label')
-    .attr('requiredFeatures', 'http://www.w3.org/TR/SVG11/feature#Extensibility')
-    .append('p')
-    .html('')
-}
-
-function svgDrawLine (svg, points, colorIdx, interpolate) {
-  const curve = interpolateToCurve(interpolate, d3.curveBasis)
-  const color = config.branchColors[colorIdx % config.branchColors.length]
-  const lineGen = d3.line()
-    .x(function (d) {
-      return Math.round(d.x)
-    })
-    .y(function (d) {
-      return Math.round(d.y)
-    })
-    .curve(curve)
-
-  svg
-    .append('svg:path')
-    .attr('d', lineGen(points))
-    .style('stroke', color)
-    .style('stroke-width', config.lineStrokeWidth)
-    .style('fill', 'none')
-}
-
-// Pass in the element and its pre-transform coords
-function getElementCoords (element, coords) {
-  coords = coords || element.node().getBBox()
-  const ctm = element.node().getCTM()
-  const xn = ctm.e + coords.x * ctm.a
-  const yn = ctm.f + coords.y * ctm.d
-  return {
-    left: xn,
-    top: yn,
-    width: coords.width,
-    height: coords.height
-  }
-}
-
-function svgDrawLineForCommits (svg, fromId, toId, direction, color) {
-  logger.debug('svgDrawLineForCommits: ', fromId, toId)
-  const fromBbox = getElementCoords(svg.select('#node-' + fromId + ' circle'))
-  const toBbox = getElementCoords(svg.select('#node-' + toId + ' circle'))
-  switch (direction) {
-    case 'LR':
-      // (toBbox)
-      //  +--------
-      //          + (fromBbox)
-      if (fromBbox.left - toBbox.left > config.nodeSpacing) {
-        const lineStart = { x: fromBbox.left - config.nodeSpacing, y: toBbox.top + toBbox.height / 2 }
-        const lineEnd = { x: toBbox.left + toBbox.width, y: toBbox.top + toBbox.height / 2 }
-        svgDrawLine(svg, [lineStart, lineEnd], color, 'linear')
-        svgDrawLine(svg, [
-          { x: fromBbox.left, y: fromBbox.top + fromBbox.height / 2 },
-          { x: fromBbox.left - config.nodeSpacing / 2, y: fromBbox.top + fromBbox.height / 2 },
-          { x: fromBbox.left - config.nodeSpacing / 2, y: lineStart.y },
-          lineStart], color)
-      } else {
-        svgDrawLine(svg, [{
-          'x': fromBbox.left,
-          'y': fromBbox.top + fromBbox.height / 2
-        }, {
-          'x': fromBbox.left - config.nodeSpacing / 2,
-          'y': fromBbox.top + fromBbox.height / 2
-        }, {
-          'x': fromBbox.left - config.nodeSpacing / 2,
-          'y': toBbox.top + toBbox.height / 2
-        }, {
-          'x': toBbox.left + toBbox.width,
-          'y': toBbox.top + toBbox.height / 2
-        }], color)
-      }
-      break
-    case 'BT':
-      //      +           (fromBbox)
-      //      |
-      //      |
-      //              +   (toBbox)
-      if (toBbox.top - fromBbox.top > config.nodeSpacing) {
-        const lineStart = { x: toBbox.left + toBbox.width / 2, y: fromBbox.top + fromBbox.height + config.nodeSpacing }
-        const lineEnd = { x: toBbox.left + toBbox.width / 2, y: toBbox.top }
-        svgDrawLine(svg, [lineStart, lineEnd], color, 'linear')
-        svgDrawLine(svg, [
-          { x: fromBbox.left + fromBbox.width / 2, y: fromBbox.top + fromBbox.height },
-          { x: fromBbox.left + fromBbox.width / 2, y: fromBbox.top + fromBbox.height + config.nodeSpacing / 2 },
-          { x: toBbox.left + toBbox.width / 2, y: lineStart.y - config.nodeSpacing / 2 },
-          lineStart], color)
-      } else {
-        svgDrawLine(svg, [{
-          'x': fromBbox.left + fromBbox.width / 2,
-          'y': fromBbox.top + fromBbox.height
-        }, {
-          'x': fromBbox.left + fromBbox.width / 2,
-          'y': fromBbox.top + config.nodeSpacing / 2
-        }, {
-          'x': toBbox.left + toBbox.width / 2,
-          'y': toBbox.top - config.nodeSpacing / 2
-        }, {
-          'x': toBbox.left + toBbox.width / 2,
-          'y': toBbox.top
-        }], color)
-      }
-      break
-  }
-}
-
-function cloneNode (svg, selector) {
-  return svg.select(selector).node().cloneNode(true)
-}
-
-function renderCommitHistory (svg, commitid, branches, direction) {
-  let commit
-  const numCommits = Object.keys(allCommitsDict).length
-  if (_.isString(commitid)) {
-    do {
-      commit = allCommitsDict[commitid]
-      logger.debug('in renderCommitHistory', commit.id, commit.seq)
-      if (svg.select('#node-' + commitid).size() > 0) {
-        return
-      }
-      svg
-        .append(function () {
-          return cloneNode(svg, '#def-commit')
-        })
-        .attr('class', 'commit')
-        .attr('id', function () {
-          return 'node-' + commit.id
-        })
-        .attr('transform', function () {
-          switch (direction) {
-            case 'LR':
-              return 'translate(' + (commit.seq * config.nodeSpacing + config.leftMargin) + ', ' +
-                (branchNum * config.branchOffset) + ')'
-            case 'BT':
-              return 'translate(' + (branchNum * config.branchOffset + config.leftMargin) + ', ' +
-                ((numCommits - commit.seq) * config.nodeSpacing) + ')'
-          }
-        })
-        .attr('fill', config.nodeFillColor)
-        .attr('stroke', config.nodeStrokeColor)
-        .attr('stroke-width', config.nodeStrokeWidth)
-
-      const branch = _.find(branches, ['commit', commit])
-      if (branch) {
-        logger.debug('found branch ', branch.name)
-        svg.select('#node-' + commit.id + ' p')
-          .append('xhtml:span')
-          .attr('class', 'branch-label')
-          .text(branch.name + ', ')
-      }
-      svg.select('#node-' + commit.id + ' p')
-        .append('xhtml:span')
-        .attr('class', 'commit-id')
-        .text(commit.id)
-      if (commit.message !== '' && direction === 'BT') {
-        svg.select('#node-' + commit.id + ' p')
-          .append('xhtml:span')
-          .attr('class', 'commit-msg')
-          .text(', ' + commit.message)
-      }
-      commitid = commit.parent
-    } while (commitid && allCommitsDict[commitid])
-  }
-
-  if (_.isArray(commitid)) {
-    logger.debug('found merge commmit', commitid)
-    renderCommitHistory(svg, commitid[0], branches, direction)
-    branchNum++
-    renderCommitHistory(svg, commitid[1], branches, direction)
-    branchNum--
-  }
-}
-
-function renderLines (svg, commit, direction, branchColor) {
-  branchColor = branchColor || 0
-  while (commit.seq > 0 && !commit.lineDrawn) {
-    if (_.isString(commit.parent)) {
-      svgDrawLineForCommits(svg, commit.id, commit.parent, direction, branchColor)
-      commit.lineDrawn = true
-      commit = allCommitsDict[commit.parent]
-    } else if (_.isArray(commit.parent)) {
-      svgDrawLineForCommits(svg, commit.id, commit.parent[0], direction, branchColor)
-      svgDrawLineForCommits(svg, commit.id, commit.parent[1], direction, branchColor + 1)
-      renderLines(svg, allCommitsDict[commit.parent[1]], direction, branchColor + 1)
-      commit.lineDrawn = true
-      commit = allCommitsDict[commit.parent[0]]
-    }
-  }
-}
-
-export const draw = function (txt, id, ver) {
-  try {
-    const parser = gitGraphParser.parser
-    parser.yy = db
-
-    logger.debug('in gitgraph renderer', txt, id, ver)
-    // Parse the graph definition
-    parser.parse(txt + '\n')
-
-    config = _.extend(config, apiConfig, db.getOptions())
-    logger.debug('effective options', config)
-    const direction = db.getDirection()
-    allCommitsDict = db.getCommits()
-    const branches = db.getBranchesAsObjArray()
-    if (direction === 'BT') {
-      config.nodeLabel.x = branches.length * config.branchOffset
-      config.nodeLabel.width = '100%'
-      config.nodeLabel.y = -1 * 2 * config.nodeRadius
-    }
-    const svg = d3.select(`[id="${id}"]`)
-    svgCreateDefs(svg)
-    branchNum = 1
-    _.each(branches, function (v) {
-      renderCommitHistory(svg, v.commit.id, branches, direction)
-      renderLines(svg, v.commit, direction)
-      branchNum++
-    })
-    svg.attr('height', function () {
-      if (direction === 'BT') return Object.keys(allCommitsDict).length * config.nodeSpacing
-      return (branches.length + 1) * config.branchOffset
-    })
-  } catch (e) {
-    logger.error('Error while rendering gitgraph')
-    logger.error(e.message)
-  }
-}
-
-export default {
-  setConf,
-  draw
-}
diff --git a/_submodules/mermaid/src/diagrams/git/parser/gitGraph.jison b/_submodules/mermaid/src/diagrams/git/parser/gitGraph.jison
deleted file mode 100644
index e675a56e45fba82802e940bc7b8eb074a3d89192..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/git/parser/gitGraph.jison
+++ /dev/null
@@ -1,92 +0,0 @@
-
-/*
- * Parse following
- * gitGraph:
- *  commit
- *  commit
- *  branch 
- */
-%lex
-
-%x string
-%x options
-%options case-insensitive
-
-%%
-
-(\r?\n)+                           return 'NL';
-\s+                             /* skip all whitespace */
-\#[^\n]*                        /* skip comments */
-\%%[^\n]*                       /* skip comments */
-"gitGraph"                      return 'GG';
-"commit"                        return 'COMMIT';
-"branch"                        return 'BRANCH';
-"merge"                         return 'MERGE';
-"reset"                         return 'RESET';
-"checkout"                         return 'CHECKOUT';
-"LR"                            return 'DIR';
-"BT"                            return 'DIR';
-":"                             return ':';
-"^"                             return 'CARET'
-"options"\r?\n                       this.begin("options");
-<options>"end"\r?\n                   this.popState();
-<options>[^\n]+\r?\n                 return 'OPT';
-["]                             this.begin("string");
-<string>["]                     this.popState();
-<string>[^"]*                     return 'STR';
-[a-zA-Z][a-zA-Z0-9_]+           return 'ID';
-<<EOF>>                         return 'EOF';
-
-/lex
-
-%left '^'
-
-%start start
-
-%% /* language grammar */
-
-start
-    : GG ':' document EOF{ return $3; }
-    | GG DIR ':' document EOF {yy.setDirection($2); return $4;}
-    ;
-
-
-document
-    : /*empty*/
-    | options body { yy.setOptions($1); $$ = $2}
-    ;
-
-options
-    : options OPT {$1 +=$2; $$=$1}
-    | NL
-    ;
-body
-    : /*emmpty*/ {$$ = []}
-    | body line {$1.push($2); $$=$1;}
-    ;
-line
-    : statement NL{$$ =$1}
-    | NL
-    ;
-
-statement
-    : COMMIT commit_arg {yy.commit($2)}
-    | BRANCH ID {yy.branch($2)}
-    | CHECKOUT ID {yy.checkout($2)}
-    | MERGE ID {yy.merge($2)}
-    | RESET reset_arg {yy.reset($2)}
-    ;
-
-commit_arg
-    : /* empty */ {$$ = ""}
-    | STR {$$=$1}
-    ;
-
-reset_arg
-    : 'HEAD' reset_parents{$$ = $1+ ":" + $2 }
-    | ID reset_parents{$$ = $1+ ":"  + yy.count; yy.count = 0}
-    ;
-reset_parents
-    : /* empty */ {yy.count = 0}
-    | CARET reset_parents { yy.count += 1 }
-    ;
diff --git a/_submodules/mermaid/src/diagrams/git/parser/gitGraph.js b/_submodules/mermaid/src/diagrams/git/parser/gitGraph.js
deleted file mode 100644
index fd981cafb53fe346f0457b00a881b850530ce586..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/git/parser/gitGraph.js
+++ /dev/null
@@ -1,696 +0,0 @@
-/* parser generated by jison 0.4.18 */
-/*
-  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=[2,3],$V1=[1,7],$V2=[7,12,15,17,19,20,21],$V3=[7,11,12,15,17,19,20,21],$V4=[2,20],$V5=[1,32];
-var parser = {trace: function trace() { },
-yy: {},
-symbols_: {"error":2,"start":3,"GG":4,":":5,"document":6,"EOF":7,"DIR":8,"options":9,"body":10,"OPT":11,"NL":12,"line":13,"statement":14,"COMMIT":15,"commit_arg":16,"BRANCH":17,"ID":18,"CHECKOUT":19,"MERGE":20,"RESET":21,"reset_arg":22,"STR":23,"HEAD":24,"reset_parents":25,"CARET":26,"$accept":0,"$end":1},
-terminals_: {2:"error",4:"GG",5:":",7:"EOF",8:"DIR",11:"OPT",12:"NL",15:"COMMIT",17:"BRANCH",18:"ID",19:"CHECKOUT",20:"MERGE",21:"RESET",23:"STR",24:"HEAD",26:"CARET"},
-productions_: [0,[3,4],[3,5],[6,0],[6,2],[9,2],[9,1],[10,0],[10,2],[13,2],[13,1],[14,2],[14,2],[14,2],[14,2],[14,2],[16,0],[16,1],[22,2],[22,2],[25,0],[25,2]],
-performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
-/* this == yyval */
-
-var $0 = $$.length - 1;
-switch (yystate) {
-case 1:
- return $$[$0-1]; 
-break;
-case 2:
-yy.setDirection($$[$0-3]); return $$[$0-1];
-break;
-case 4:
- yy.setOptions($$[$0-1]); this.$ = $$[$0]
-break;
-case 5:
-$$[$0-1] +=$$[$0]; this.$=$$[$0-1]
-break;
-case 7:
-this.$ = []
-break;
-case 8:
-$$[$0-1].push($$[$0]); this.$=$$[$0-1];
-break;
-case 9:
-this.$ =$$[$0-1]
-break;
-case 11:
-yy.commit($$[$0])
-break;
-case 12:
-yy.branch($$[$0])
-break;
-case 13:
-yy.checkout($$[$0])
-break;
-case 14:
-yy.merge($$[$0])
-break;
-case 15:
-yy.reset($$[$0])
-break;
-case 16:
-this.$ = ""
-break;
-case 17:
-this.$=$$[$0]
-break;
-case 18:
-this.$ = $$[$0-1]+ ":" + $$[$0] 
-break;
-case 19:
-this.$ = $$[$0-1]+ ":"  + yy.count; yy.count = 0
-break;
-case 20:
-yy.count = 0
-break;
-case 21:
- yy.count += 1 
-break;
-}
-},
-table: [{3:1,4:[1,2]},{1:[3]},{5:[1,3],8:[1,4]},{6:5,7:$V0,9:6,12:$V1},{5:[1,8]},{7:[1,9]},o($V2,[2,7],{10:10,11:[1,11]}),o($V3,[2,6]),{6:12,7:$V0,9:6,12:$V1},{1:[2,1]},{7:[2,4],12:[1,15],13:13,14:14,15:[1,16],17:[1,17],19:[1,18],20:[1,19],21:[1,20]},o($V3,[2,5]),{7:[1,21]},o($V2,[2,8]),{12:[1,22]},o($V2,[2,10]),{12:[2,16],16:23,23:[1,24]},{18:[1,25]},{18:[1,26]},{18:[1,27]},{18:[1,30],22:28,24:[1,29]},{1:[2,2]},o($V2,[2,9]),{12:[2,11]},{12:[2,17]},{12:[2,12]},{12:[2,13]},{12:[2,14]},{12:[2,15]},{12:$V4,25:31,26:$V5},{12:$V4,25:33,26:$V5},{12:[2,18]},{12:$V4,25:34,26:$V5},{12:[2,19]},{12:[2,21]}],
-defaultActions: {9:[2,1],21:[2,2],23:[2,11],24:[2,17],25:[2,12],26:[2,13],27:[2,14],28:[2,15],31:[2,18],33:[2,19],34:[2,21]},
-parseError: function parseError(str, hash) {
-    if (hash.recoverable) {
-        this.trace(str);
-    } else {
-        var error = new Error(str);
-        error.hash = hash;
-        throw error;
-    }
-},
-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;
-    }
-            function lex() {
-            var token;
-            token = tstack.pop() || lexer.lex() || EOF;
-            if (typeof token !== 'number') {
-                if (token instanceof Array) {
-                    tstack = token;
-                    token = tstack.pop();
-                }
-                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["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: {"case-insensitive":true},
-performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
-var YYSTATE=YY_START;
-switch($avoiding_name_collisions) {
-case 0:return 12;
-break;
-case 1:/* skip all whitespace */
-break;
-case 2:/* skip comments */
-break;
-case 3:/* skip comments */
-break;
-case 4:return 4;
-break;
-case 5:return 15;
-break;
-case 6:return 17;
-break;
-case 7:return 20;
-break;
-case 8:return 21;
-break;
-case 9:return 19;
-break;
-case 10:return 8;
-break;
-case 11:return 8;
-break;
-case 12:return 5;
-break;
-case 13:return 26
-break;
-case 14:this.begin("options");
-break;
-case 15:this.popState();
-break;
-case 16:return 11;
-break;
-case 17:this.begin("string");
-break;
-case 18:this.popState();
-break;
-case 19:return 23;
-break;
-case 20:return 18;
-break;
-case 21:return 7;
-break;
-}
-},
-rules: [/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gitGraph\b)/i,/^(?:commit\b)/i,/^(?:branch\b)/i,/^(?:merge\b)/i,/^(?:reset\b)/i,/^(?:checkout\b)/i,/^(?:LR\b)/i,/^(?:BT\b)/i,/^(?::)/i,/^(?:\^)/i,/^(?:options\r?\n)/i,/^(?:end\r?\n)/i,/^(?:[^\n]+\r?\n)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[a-zA-Z][a-zA-Z0-9_]+)/i,/^(?:$)/i],
-conditions: {"options":{"rules":[15,16],"inclusive":false},"string":{"rules":[18,19],"inclusive":false},"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,20,21],"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 = parser;
-exports.Parser = parser.Parser;
-exports.parse = function () { return parser.parse.apply(parser, 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));
-}
-}
\ No newline at end of file
diff --git a/_submodules/mermaid/src/diagrams/sequence/parser/sequenceDiagram.jison b/_submodules/mermaid/src/diagrams/sequence/parser/sequenceDiagram.jison
deleted file mode 100644
index 507956ee49ad978027602a9350f8b53a4039c295..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/sequence/parser/sequenceDiagram.jison
+++ /dev/null
@@ -1,192 +0,0 @@
-/** mermaid
- *  https://mermaidjs.github.io/
- *  (c) 2014-2015 Knut Sveidqvist
- *  MIT license.
- *
- *  Based on js sequence diagrams jison grammr
- *  http://bramp.github.io/js-sequence-diagrams/
- *  (c) 2012-2013 Andrew Brampton (bramp.net)
- *  Simplified BSD license.
- */
-%lex
-
-%options case-insensitive
-
-// Special states for recognizing aliases
-%x ID
-%x ALIAS
-
-// A special state for grabbing text up to the first comment/newline
-%x LINE
-
-%%
-
-[\n]+                            return 'NL';
-\s+                              /* skip all whitespace */
-<ID,ALIAS,LINE>((?!\n)\s)+       /* skip same-line whitespace */
-<INITIAL,ID,ALIAS,LINE>\#[^\n]*  /* skip comments */
-\%%[^\n]*                        /* skip comments */
-"participant"     { this.begin('ID'); return 'participant'; }
-<ID>[^\->:\n,;]+?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$)  { this.begin('ALIAS'); return 'ACTOR'; }
-<ALIAS>"as"       { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; }
-<ALIAS>(?:)       { this.popState(); this.popState(); return 'NL'; }
-"loop"            { this.begin('LINE'); return 'loop'; }
-"opt"             { this.begin('LINE'); return 'opt'; }
-"alt"             { this.begin('LINE'); return 'alt'; }
-"else"            { this.begin('LINE'); return 'else'; }
-"par"             { this.begin('LINE'); return 'par'; }
-"and"             { this.begin('LINE'); return 'and'; }
-<LINE>[^#\n;]*    { this.popState(); return 'restOfLine'; }
-"end"             return 'end';
-"left of"         return 'left_of';
-"right of"        return 'right_of';
-"over"            return 'over';
-"note"            return 'note';
-"activate"        { this.begin('ID'); return 'activate'; }
-"deactivate"      { this.begin('ID'); return 'deactivate'; }
-"title"           return 'title';
-"sequenceDiagram" return 'SD';
-","               return ',';
-";"               return 'NL';
-[^\+\->:\n,;]+      { yytext = yytext.trim(); return 'ACTOR'; }
-"->>"             return 'SOLID_ARROW';
-"-->>"            return 'DOTTED_ARROW';
-"->"              return 'SOLID_OPEN_ARROW';
-"-->"             return 'DOTTED_OPEN_ARROW';
-\-[x]             return 'SOLID_CROSS';
-\-\-[x]           return 'DOTTED_CROSS';
-":"[^#\n;]+       return 'TXT';
-"+"               return '+';
-"-"               return '-';
-<<EOF>>           return 'NL';
-.                 return 'INVALID';
-
-/lex
-
-%left '^'
-
-%start start
-
-%% /* language grammar */
-
-start
-	: SPACE start
-	| NL start
-	| SD document { yy.apply($2);return $2; }
-	;
-
-document
-	: /* empty */ { $$ = [] }
-	| document line {$1.push($2);$$ = $1}
-	;
-
-line
-	: SPACE statement { $$ = $2 }
-	| statement { $$ = $1 }
-	| NL { $$=[];}
-	;
-
-statement
-	: 'participant' actor 'AS' restOfLine 'NL' {$2.description=$4; $$=$2;}
-	| 'participant' actor 'NL' {$$=$2;}
-	| signal 'NL'
-	| 'activate' actor 'NL' {$$={type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $2};}
-	| 'deactivate' actor 'NL' {$$={type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $2};}
-	| note_statement 'NL'
-	| title text2 'NL' {$$=[{type:'setTitle', text:$2}]}
-	| 'loop' restOfLine document end
-	{
-		$3.unshift({type: 'loopStart', loopText:$2, signalType: yy.LINETYPE.LOOP_START});
-		$3.push({type: 'loopEnd', loopText:$2, signalType: yy.LINETYPE.LOOP_END});
-		$$=$3;}
-	| opt restOfLine document end
-	{
-		$3.unshift({type: 'optStart', optText:$2, signalType: yy.LINETYPE.OPT_START});
-		$3.push({type: 'optEnd', optText:$2, signalType: yy.LINETYPE.OPT_END});
-		$$=$3;}
-	| alt restOfLine else_sections end
-	{
-		// Alt start
-		$3.unshift({type: 'altStart', altText:$2, signalType: yy.LINETYPE.ALT_START});
-		// Content in alt is already in $3
-		// End
-		$3.push({type: 'altEnd', signalType: yy.LINETYPE.ALT_END});
-		$$=$3;}
-	| par restOfLine par_sections end
-	{
-		// Parallel start
-		$3.unshift({type: 'parStart', parText:$2, signalType: yy.LINETYPE.PAR_START});
-		// Content in par is already in $3
-		// End
-		$3.push({type: 'parEnd', signalType: yy.LINETYPE.PAR_END});
-		$$=$3;}
-	;
-
-par_sections
-	: document
-	| document and restOfLine par_sections
-	{ $$ = $1.concat([{type: 'and', parText:$3, signalType: yy.LINETYPE.PAR_AND}, $4]); }
-	;
-
-else_sections
-	: document
-	| document else restOfLine else_sections
-	{ $$ = $1.concat([{type: 'else', altText:$3, signalType: yy.LINETYPE.ALT_ELSE}, $4]); }
-	;
-
-note_statement
-	: 'note' placement actor text2
-	{
-		$$ = [$3, {type:'addNote', placement:$2, actor:$3.actor, text:$4}];}
-	| 'note' 'over' actor_pair text2
-	{
-		// Coerce actor_pair into a [to, from, ...] array
-		$2 = [].concat($3, $3).slice(0, 2);
-		$2[0] = $2[0].actor;
-		$2[1] = $2[1].actor;
-		$$ = [$3, {type:'addNote', placement:yy.PLACEMENT.OVER, actor:$2.slice(0, 2), text:$4}];}
-	;
-
-spaceList
-    : SPACE spaceList
-    | SPACE
-    ;
-actor_pair
-	: actor ',' actor   { $$ = [$1, $3]; }
-	| actor             { $$ = $1; }
-	;
-
-placement
-	: 'left_of'   { $$ = yy.PLACEMENT.LEFTOF; }
-	| 'right_of'  { $$ = yy.PLACEMENT.RIGHTOF; }
-	;
-
-signal
-	: actor signaltype '+' actor text2
-	{ $$ = [$1,$4,{type: 'addMessage', from:$1.actor, to:$4.actor, signalType:$2, msg:$5},
-	              {type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $4}
-	             ]}
-	| actor signaltype '-' actor text2
-	{ $$ = [$1,$4,{type: 'addMessage', from:$1.actor, to:$4.actor, signalType:$2, msg:$5},
-	             {type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $1}
-	             ]}
-	| actor signaltype actor text2
-	{ $$ = [$1,$3,{type: 'addMessage', from:$1.actor, to:$3.actor, signalType:$2, msg:$4}]}
-	;
-
-actor
-	: ACTOR {$$={type: 'addActor', actor:$1}}
-	;
-
-signaltype
-	: SOLID_OPEN_ARROW  { $$ = yy.LINETYPE.SOLID_OPEN; }
-	| DOTTED_OPEN_ARROW { $$ = yy.LINETYPE.DOTTED_OPEN; }
-	| SOLID_ARROW       { $$ = yy.LINETYPE.SOLID; }
-	| DOTTED_ARROW      { $$ = yy.LINETYPE.DOTTED; }
-	| SOLID_CROSS       { $$ = yy.LINETYPE.SOLID_CROSS; }
-	| DOTTED_CROSS      { $$ = yy.LINETYPE.DOTTED_CROSS; }
-	;
-
-text2: TXT {$$ = $1.substring(1).trim().replace(/\\n/gm, "\n");} ;
-
-%%
diff --git a/_submodules/mermaid/src/diagrams/sequence/parser/sequenceDiagram.js b/_submodules/mermaid/src/diagrams/sequence/parser/sequenceDiagram.js
deleted file mode 100644
index aa94350990f6cfb09cfe3160f6e4bf2040307fd0..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/sequence/parser/sequenceDiagram.js
+++ /dev/null
@@ -1,804 +0,0 @@
-/* parser generated by jison 0.4.18 */
-/*
-  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,2],$V1=[1,3],$V2=[1,4],$V3=[2,4],$V4=[1,9],$V5=[1,11],$V6=[1,12],$V7=[1,14],$V8=[1,15],$V9=[1,17],$Va=[1,18],$Vb=[1,19],$Vc=[1,20],$Vd=[1,21],$Ve=[1,23],$Vf=[1,24],$Vg=[1,4,5,10,15,16,18,20,21,22,23,25,27,28,29,40],$Vh=[1,32],$Vi=[4,5,10,15,16,18,20,21,22,23,25,29,40],$Vj=[4,5,10,15,16,18,20,21,22,23,25,28,29,40],$Vk=[4,5,10,15,16,18,20,21,22,23,25,27,29,40],$Vl=[38,39,40];
-var parser = {trace: function trace() { },
-yy: {},
-symbols_: {"error":2,"start":3,"SPACE":4,"NL":5,"SD":6,"document":7,"line":8,"statement":9,"participant":10,"actor":11,"AS":12,"restOfLine":13,"signal":14,"activate":15,"deactivate":16,"note_statement":17,"title":18,"text2":19,"loop":20,"end":21,"opt":22,"alt":23,"else_sections":24,"par":25,"par_sections":26,"and":27,"else":28,"note":29,"placement":30,"over":31,"actor_pair":32,"spaceList":33,",":34,"left_of":35,"right_of":36,"signaltype":37,"+":38,"-":39,"ACTOR":40,"SOLID_OPEN_ARROW":41,"DOTTED_OPEN_ARROW":42,"SOLID_ARROW":43,"DOTTED_ARROW":44,"SOLID_CROSS":45,"DOTTED_CROSS":46,"TXT":47,"$accept":0,"$end":1},
-terminals_: {2:"error",4:"SPACE",5:"NL",6:"SD",10:"participant",12:"AS",13:"restOfLine",15:"activate",16:"deactivate",18:"title",20:"loop",21:"end",22:"opt",23:"alt",25:"par",27:"and",28:"else",29:"note",31:"over",34:",",35:"left_of",36:"right_of",38:"+",39:"-",40:"ACTOR",41:"SOLID_OPEN_ARROW",42:"DOTTED_OPEN_ARROW",43:"SOLID_ARROW",44:"DOTTED_ARROW",45:"SOLID_CROSS",46:"DOTTED_CROSS",47:"TXT"},
-productions_: [0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,5],[9,3],[9,2],[9,3],[9,3],[9,2],[9,3],[9,4],[9,4],[9,4],[9,4],[26,1],[26,4],[24,1],[24,4],[17,4],[17,4],[33,2],[33,1],[32,3],[32,1],[30,1],[30,1],[14,5],[14,5],[14,4],[11,1],[37,1],[37,1],[37,1],[37,1],[37,1],[37,1],[19,1]],
-performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
-/* this == yyval */
-
-var $0 = $$.length - 1;
-switch (yystate) {
-case 3:
- yy.apply($$[$0]);return $$[$0]; 
-break;
-case 4:
- this.$ = [] 
-break;
-case 5:
-$$[$0-1].push($$[$0]);this.$ = $$[$0-1]
-break;
-case 6: case 7:
- this.$ = $$[$0] 
-break;
-case 8:
- this.$=[];
-break;
-case 9:
-$$[$0-3].description=$$[$0-1]; this.$=$$[$0-3];
-break;
-case 10:
-this.$=$$[$0-1];
-break;
-case 12:
-this.$={type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $$[$0-1]};
-break;
-case 13:
-this.$={type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $$[$0-1]};
-break;
-case 15:
-this.$=[{type:'setTitle', text:$$[$0-1]}]
-break;
-case 16:
-
-		$$[$0-1].unshift({type: 'loopStart', loopText:$$[$0-2], signalType: yy.LINETYPE.LOOP_START});
-		$$[$0-1].push({type: 'loopEnd', loopText:$$[$0-2], signalType: yy.LINETYPE.LOOP_END});
-		this.$=$$[$0-1];
-break;
-case 17:
-
-		$$[$0-1].unshift({type: 'optStart', optText:$$[$0-2], signalType: yy.LINETYPE.OPT_START});
-		$$[$0-1].push({type: 'optEnd', optText:$$[$0-2], signalType: yy.LINETYPE.OPT_END});
-		this.$=$$[$0-1];
-break;
-case 18:
-
-		// Alt start
-		$$[$0-1].unshift({type: 'altStart', altText:$$[$0-2], signalType: yy.LINETYPE.ALT_START});
-		// Content in alt is already in $$[$0-1]
-		// End
-		$$[$0-1].push({type: 'altEnd', signalType: yy.LINETYPE.ALT_END});
-		this.$=$$[$0-1];
-break;
-case 19:
-
-		// Parallel start
-		$$[$0-1].unshift({type: 'parStart', parText:$$[$0-2], signalType: yy.LINETYPE.PAR_START});
-		// Content in par is already in $$[$0-1]
-		// End
-		$$[$0-1].push({type: 'parEnd', signalType: yy.LINETYPE.PAR_END});
-		this.$=$$[$0-1];
-break;
-case 21:
- this.$ = $$[$0-3].concat([{type: 'and', parText:$$[$0-1], signalType: yy.LINETYPE.PAR_AND}, $$[$0]]); 
-break;
-case 23:
- this.$ = $$[$0-3].concat([{type: 'else', altText:$$[$0-1], signalType: yy.LINETYPE.ALT_ELSE}, $$[$0]]); 
-break;
-case 24:
-
-		this.$ = [$$[$0-1], {type:'addNote', placement:$$[$0-2], actor:$$[$0-1].actor, text:$$[$0]}];
-break;
-case 25:
-
-		// Coerce actor_pair into a [to, from, ...] array
-		$$[$0-2] = [].concat($$[$0-1], $$[$0-1]).slice(0, 2);
-		$$[$0-2][0] = $$[$0-2][0].actor;
-		$$[$0-2][1] = $$[$0-2][1].actor;
-		this.$ = [$$[$0-1], {type:'addNote', placement:yy.PLACEMENT.OVER, actor:$$[$0-2].slice(0, 2), text:$$[$0]}];
-break;
-case 28:
- this.$ = [$$[$0-2], $$[$0]]; 
-break;
-case 29:
- this.$ = $$[$0]; 
-break;
-case 30:
- this.$ = yy.PLACEMENT.LEFTOF; 
-break;
-case 31:
- this.$ = yy.PLACEMENT.RIGHTOF; 
-break;
-case 32:
- this.$ = [$$[$0-4],$$[$0-1],{type: 'addMessage', from:$$[$0-4].actor, to:$$[$0-1].actor, signalType:$$[$0-3], msg:$$[$0]},
-	              {type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $$[$0-1]}
-	             ]
-break;
-case 33:
- this.$ = [$$[$0-4],$$[$0-1],{type: 'addMessage', from:$$[$0-4].actor, to:$$[$0-1].actor, signalType:$$[$0-3], msg:$$[$0]},
-	             {type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $$[$0-4]}
-	             ]
-break;
-case 34:
- this.$ = [$$[$0-3],$$[$0-1],{type: 'addMessage', from:$$[$0-3].actor, to:$$[$0-1].actor, signalType:$$[$0-2], msg:$$[$0]}]
-break;
-case 35:
-this.$={type: 'addActor', actor:$$[$0]}
-break;
-case 36:
- this.$ = yy.LINETYPE.SOLID_OPEN; 
-break;
-case 37:
- this.$ = yy.LINETYPE.DOTTED_OPEN; 
-break;
-case 38:
- this.$ = yy.LINETYPE.SOLID; 
-break;
-case 39:
- this.$ = yy.LINETYPE.DOTTED; 
-break;
-case 40:
- this.$ = yy.LINETYPE.SOLID_CROSS; 
-break;
-case 41:
- this.$ = yy.LINETYPE.DOTTED_CROSS; 
-break;
-case 42:
-this.$ = $$[$0].substring(1).trim().replace(/\\n/gm, "\n");
-break;
-}
-},
-table: [{3:1,4:$V0,5:$V1,6:$V2},{1:[3]},{3:5,4:$V0,5:$V1,6:$V2},{3:6,4:$V0,5:$V1,6:$V2},o([1,4,5,10,15,16,18,20,22,23,25,29,40],$V3,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:$V4,5:$V5,8:8,9:10,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,22:$Vb,23:$Vc,25:$Vd,29:$Ve,40:$Vf},o($Vg,[2,5]),{9:25,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,22:$Vb,23:$Vc,25:$Vd,29:$Ve,40:$Vf},o($Vg,[2,7]),o($Vg,[2,8]),{11:26,40:$Vf},{5:[1,27]},{11:28,40:$Vf},{11:29,40:$Vf},{5:[1,30]},{19:31,47:$Vh},{13:[1,33]},{13:[1,34]},{13:[1,35]},{13:[1,36]},{37:37,41:[1,38],42:[1,39],43:[1,40],44:[1,41],45:[1,42],46:[1,43]},{30:44,31:[1,45],35:[1,46],36:[1,47]},o([5,12,34,41,42,43,44,45,46,47],[2,35]),o($Vg,[2,6]),{5:[1,49],12:[1,48]},o($Vg,[2,11]),{5:[1,50]},{5:[1,51]},o($Vg,[2,14]),{5:[1,52]},{5:[2,42]},o($Vi,$V3,{7:53}),o($Vi,$V3,{7:54}),o($Vj,$V3,{24:55,7:56}),o($Vk,$V3,{26:57,7:58}),{11:61,38:[1,59],39:[1,60],40:$Vf},o($Vl,[2,36]),o($Vl,[2,37]),o($Vl,[2,38]),o($Vl,[2,39]),o($Vl,[2,40]),o($Vl,[2,41]),{11:62,40:$Vf},{11:64,32:63,40:$Vf},{40:[2,30]},{40:[2,31]},{13:[1,65]},o($Vg,[2,10]),o($Vg,[2,12]),o($Vg,[2,13]),o($Vg,[2,15]),{4:$V4,5:$V5,8:8,9:10,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[1,66],22:$Vb,23:$Vc,25:$Vd,29:$Ve,40:$Vf},{4:$V4,5:$V5,8:8,9:10,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[1,67],22:$Vb,23:$Vc,25:$Vd,29:$Ve,40:$Vf},{21:[1,68]},{4:$V4,5:$V5,8:8,9:10,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[2,22],22:$Vb,23:$Vc,25:$Vd,28:[1,69],29:$Ve,40:$Vf},{21:[1,70]},{4:$V4,5:$V5,8:8,9:10,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[2,20],22:$Vb,23:$Vc,25:$Vd,27:[1,71],29:$Ve,40:$Vf},{11:72,40:$Vf},{11:73,40:$Vf},{19:74,47:$Vh},{19:75,47:$Vh},{19:76,47:$Vh},{34:[1,77],47:[2,29]},{5:[1,78]},o($Vg,[2,16]),o($Vg,[2,17]),o($Vg,[2,18]),{13:[1,79]},o($Vg,[2,19]),{13:[1,80]},{19:81,47:$Vh},{19:82,47:$Vh},{5:[2,34]},{5:[2,24]},{5:[2,25]},{11:83,40:$Vf},o($Vg,[2,9]),o($Vj,$V3,{7:56,24:84}),o($Vk,$V3,{7:58,26:85}),{5:[2,32]},{5:[2,33]},{47:[2,28]},{21:[2,23]},{21:[2,21]}],
-defaultActions: {5:[2,1],6:[2,2],32:[2,42],46:[2,30],47:[2,31],74:[2,34],75:[2,24],76:[2,25],81:[2,32],82:[2,33],83:[2,28],84:[2,23],85:[2,21]},
-parseError: function parseError(str, hash) {
-    if (hash.recoverable) {
-        this.trace(str);
-    } else {
-        var error = new Error(str);
-        error.hash = hash;
-        throw error;
-    }
-},
-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;
-    }
-            function lex() {
-            var token;
-            token = tstack.pop() || lexer.lex() || EOF;
-            if (typeof token !== 'number') {
-                if (token instanceof Array) {
-                    tstack = token;
-                    token = tstack.pop();
-                }
-                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["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: {"case-insensitive":true},
-performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
-var YYSTATE=YY_START;
-switch($avoiding_name_collisions) {
-case 0:return 5;
-break;
-case 1:/* skip all whitespace */
-break;
-case 2:/* skip same-line whitespace */
-break;
-case 3:/* skip comments */
-break;
-case 4:/* skip comments */
-break;
-case 5: this.begin('ID'); return 10; 
-break;
-case 6: this.begin('ALIAS'); return 40; 
-break;
-case 7: this.popState(); this.popState(); this.begin('LINE'); return 12; 
-break;
-case 8: this.popState(); this.popState(); return 5; 
-break;
-case 9: this.begin('LINE'); return 20; 
-break;
-case 10: this.begin('LINE'); return 22; 
-break;
-case 11: this.begin('LINE'); return 23; 
-break;
-case 12: this.begin('LINE'); return 28; 
-break;
-case 13: this.begin('LINE'); return 25; 
-break;
-case 14: this.begin('LINE'); return 27; 
-break;
-case 15: this.popState(); return 13; 
-break;
-case 16:return 21;
-break;
-case 17:return 35;
-break;
-case 18:return 36;
-break;
-case 19:return 31;
-break;
-case 20:return 29;
-break;
-case 21: this.begin('ID'); return 15; 
-break;
-case 22: this.begin('ID'); return 16; 
-break;
-case 23:return 18;
-break;
-case 24:return 6;
-break;
-case 25:return 34;
-break;
-case 26:return 5;
-break;
-case 27: yy_.yytext = yy_.yytext.trim(); return 40; 
-break;
-case 28:return 43;
-break;
-case 29:return 44;
-break;
-case 30:return 41;
-break;
-case 31:return 42;
-break;
-case 32:return 45;
-break;
-case 33:return 46;
-break;
-case 34:return 47;
-break;
-case 35:return 38;
-break;
-case 36:return 39;
-break;
-case 37:return 5;
-break;
-case 38:return 'INVALID';
-break;
-}
-},
-rules: [/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:participant\b)/i,/^(?:[^\->:\n,;]+?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:and\b)/i,/^(?:[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\b)/i,/^(?:sequenceDiagram\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\->:\n,;]+)/i,/^(?:->>)/i,/^(?:-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?::[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],
-conditions: {"LINE":{"rules":[2,3,15],"inclusive":false},"ALIAS":{"rules":[2,3,7,8],"inclusive":false},"ID":{"rules":[2,3,6],"inclusive":false},"INITIAL":{"rules":[0,1,3,4,5,9,10,11,12,13,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"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 = parser;
-exports.Parser = parser.Parser;
-exports.parse = function () { return parser.parse.apply(parser, 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));
-}
-}
\ No newline at end of file
diff --git a/_submodules/mermaid/src/diagrams/sequence/sequenceDb.js b/_submodules/mermaid/src/diagrams/sequence/sequenceDb.js
deleted file mode 100644
index 665ca820d82c9d1d67863896196c76727bcad069..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/sequence/sequenceDb.js
+++ /dev/null
@@ -1,172 +0,0 @@
-import { logger } from '../../logger'
-
-let actors = {}
-let messages = []
-const notes = []
-let title = ''
-
-export const addActor = function (id, name, description) {
-  // Don't allow description nulling
-  const old = actors[id]
-  if (old && name === old.name && description == null) return
-
-  // Don't allow null descriptions, either
-  if (description == null) description = name
-
-  actors[id] = { name: name, description: description }
-}
-
-export const addMessage = function (idFrom, idTo, message, answer) {
-  messages.push({ from: idFrom, to: idTo, message: message, answer: answer })
-}
-
-export const addSignal = function (idFrom, idTo, message, messageType) {
-  logger.debug('Adding message from=' + idFrom + ' to=' + idTo + ' message=' + message + ' type=' + messageType)
-  messages.push({ from: idFrom, to: idTo, message: message, type: messageType })
-}
-
-export const getMessages = function () {
-  return messages
-}
-
-export const getActors = function () {
-  return actors
-}
-export const getActor = function (id) {
-  return actors[id]
-}
-export const getActorKeys = function () {
-  return Object.keys(actors)
-}
-export const getTitle = function () {
-  return title
-}
-
-export const clear = function () {
-  actors = {}
-  messages = []
-}
-
-export const LINETYPE = {
-  SOLID: 0,
-  DOTTED: 1,
-  NOTE: 2,
-  SOLID_CROSS: 3,
-  DOTTED_CROSS: 4,
-  SOLID_OPEN: 5,
-  DOTTED_OPEN: 6,
-  LOOP_START: 10,
-  LOOP_END: 11,
-  ALT_START: 12,
-  ALT_ELSE: 13,
-  ALT_END: 14,
-  OPT_START: 15,
-  OPT_END: 16,
-  ACTIVE_START: 17,
-  ACTIVE_END: 18,
-  PAR_START: 19,
-  PAR_AND: 20,
-  PAR_END: 21
-}
-
-export const ARROWTYPE = {
-  FILLED: 0,
-  OPEN: 1
-}
-
-export const PLACEMENT = {
-  LEFTOF: 0,
-  RIGHTOF: 1,
-  OVER: 2
-}
-
-export const addNote = function (actor, placement, message) {
-  const note = { actor: actor, placement: placement, message: message }
-
-  // Coerce actor into a [to, from, ...] array
-  const actors = [].concat(actor, actor)
-
-  notes.push(note)
-  messages.push({ from: actors[0], to: actors[1], message: message, type: LINETYPE.NOTE, placement: placement })
-}
-
-export const setTitle = function (titleText) {
-  title = titleText
-}
-
-export const apply = function (param) {
-  if (param instanceof Array) {
-    param.forEach(function (item) {
-      apply(item)
-    })
-  } else {
-    switch (param.type) {
-      case 'addActor':
-        addActor(param.actor, param.actor, param.description)
-        break
-      case 'activeStart':
-        addSignal(param.actor, undefined, undefined, param.signalType)
-        break
-      case 'activeEnd':
-        addSignal(param.actor, undefined, undefined, param.signalType)
-        break
-      case 'addNote':
-        addNote(param.actor, param.placement, param.text)
-        break
-      case 'addMessage':
-        addSignal(param.from, param.to, param.msg, param.signalType)
-        break
-      case 'loopStart':
-        addSignal(undefined, undefined, param.loopText, param.signalType)
-        break
-      case 'loopEnd':
-        addSignal(undefined, undefined, undefined, param.signalType)
-        break
-      case 'optStart':
-        addSignal(undefined, undefined, param.optText, param.signalType)
-        break
-      case 'optEnd':
-        addSignal(undefined, undefined, undefined, param.signalType)
-        break
-      case 'altStart':
-        addSignal(undefined, undefined, param.altText, param.signalType)
-        break
-      case 'else':
-        addSignal(undefined, undefined, param.altText, param.signalType)
-        break
-      case 'altEnd':
-        addSignal(undefined, undefined, undefined, param.signalType)
-        break
-      case 'setTitle':
-        setTitle(param.text)
-        break
-      case 'parStart':
-        addSignal(undefined, undefined, param.parText, param.signalType)
-        break
-      case 'and':
-        addSignal(undefined, undefined, param.parText, param.signalType)
-        break
-      case 'parEnd':
-        addSignal(undefined, undefined, undefined, param.signalType)
-        break
-    }
-  }
-}
-
-export default {
-  addActor,
-  addMessage,
-  addSignal,
-  getMessages,
-  getActors,
-  getActor,
-  getActorKeys,
-  getTitle,
-  clear,
-  LINETYPE,
-  ARROWTYPE,
-  PLACEMENT,
-  addNote,
-  setTitle,
-  apply
-}
diff --git a/_submodules/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js b/_submodules/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js
deleted file mode 100644
index 0631d1a610f743133fe7005a936ae51979dd35c8..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js
+++ /dev/null
@@ -1,962 +0,0 @@
-/* eslint-env jasmine */
-import { parser } from './parser/sequenceDiagram'
-import sequenceDb from './sequenceDb'
-import renderer from './sequenceRenderer'
-
-function addConf (conf, key, value) {
-  if (value !== undefined) {
-    conf[key] = value
-  }
-  return conf
-}
-
-describe('when parsing a sequenceDiagram', function () {
-  beforeEach(function () {
-    parser.yy = sequenceDb
-    parser.yy.clear()
-  })
-  it('it should handle a sequenceDiagram defintion', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob:Hello Bob, how are you?\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'Bob-->Alice: I am good thanks!'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(3)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[2].from).toBe('Bob')
-  })
-  it('it should handle a sequenceDiagram definition with a title', function () {
-    const str = 'sequenceDiagram\n' +
-      'title: Diagram Title\n' +
-      'Alice->Bob:Hello Bob, how are you?\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'Bob-->Alice: I am good thanks!'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-    const title = parser.yy.getTitle()
-
-    expect(messages.length).toBe(3)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[2].from).toBe('Bob')
-    expect(title).toBe('Diagram Title')
-  })
-  it('it should space in actor names', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob:Hello Bob, how are - you?\n' +
-      'Bob-->Alice: I am good thanks!'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(2)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[1].from).toBe('Bob')
-  })
-  it('it should alias participants', function () {
-    const str = 'sequenceDiagram\n' +
-      'participant A as Alice\n' +
-      'participant B as Bob\n' +
-      'A->B:Hello Bob, how are you?\n' +
-      'B-->A: I am good thanks!'
-
-    parser.parse(str)
-
-    const actors = parser.yy.getActors()
-    expect(Object.keys(actors)).toEqual(['A', 'B'])
-    expect(actors.A.description).toBe('Alice')
-    expect(actors.B.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-    expect(messages.length).toBe(2)
-    expect(messages[0].from).toBe('A')
-    expect(messages[1].from).toBe('B')
-  })
-  it('it should handle in async messages', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice-xBob:Hello Bob, how are you?'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    expect(actors.Bob.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(1)
-    expect(messages[0].type).toBe(parser.yy.LINETYPE.SOLID_CROSS)
-  })
-  it('it should handle in async dotted messages', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice--xBob:Hello Bob, how are you?'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    expect(actors.Bob.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(1)
-    expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED_CROSS)
-  })
-  it('it should handle in arrow messages', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->>Bob:Hello Bob, how are you?'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    expect(actors.Bob.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(1)
-    expect(messages[0].type).toBe(parser.yy.LINETYPE.SOLID)
-  })
-  it('it should handle in arrow messages', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice-->>Bob:Hello Bob, how are you?'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    expect(actors.Bob.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(1)
-    expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED)
-  })
-  it('it should handle actor activation', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice-->>Bob:Hello Bob, how are you?\n' +
-      'activate Bob\n' +
-      'Bob-->>Alice:Hello Alice, I\'m fine and  you?\n' +
-      'deactivate Bob'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    expect(actors.Bob.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(4)
-    expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED)
-    expect(messages[1].type).toBe(parser.yy.LINETYPE.ACTIVE_START)
-    expect(messages[1].from.actor).toBe('Bob')
-    expect(messages[2].type).toBe(parser.yy.LINETYPE.DOTTED)
-    expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_END)
-    expect(messages[3].from.actor).toBe('Bob')
-  })
-  it('it should handle actor one line notation activation', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice-->>+Bob:Hello Bob, how are you?\n' +
-      'Bob-->>- Alice:Hello Alice, I\'m fine and  you?'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    expect(actors.Bob.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(4)
-    expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED)
-    expect(messages[1].type).toBe(parser.yy.LINETYPE.ACTIVE_START)
-    expect(messages[1].from.actor).toBe('Bob')
-    expect(messages[2].type).toBe(parser.yy.LINETYPE.DOTTED)
-    expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_END)
-    expect(messages[3].from.actor).toBe('Bob')
-  })
-  it('it should handle stacked activations', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice-->>+Bob:Hello Bob, how are you?\n' +
-      'Bob-->>+Carol:Carol, let me introduce Alice?\n' +
-      'Bob-->>- Alice:Hello Alice, please meet Carol?\n' +
-      'Carol->>- Bob:Oh Bob, I\'m so happy to be here!'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    expect(actors.Bob.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(8)
-    expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED)
-    expect(messages[1].type).toBe(parser.yy.LINETYPE.ACTIVE_START)
-    expect(messages[1].from.actor).toBe('Bob')
-    expect(messages[2].type).toBe(parser.yy.LINETYPE.DOTTED)
-    expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_START)
-    expect(messages[3].from.actor).toBe('Carol')
-    expect(messages[5].type).toBe(parser.yy.LINETYPE.ACTIVE_END)
-    expect(messages[5].from.actor).toBe('Bob')
-    expect(messages[7].type).toBe(parser.yy.LINETYPE.ACTIVE_END)
-    expect(messages[7].from.actor).toBe('Carol')
-  })
-  it('it should handle comments in a sequenceDiagram', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      '%% Comment\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'Bob-->Alice: I am good thanks!'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(3)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[2].from).toBe('Bob')
-  })
-  it('it should handle new lines in a sequenceDiagram', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n\n' +
-      '%% Comment\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'Bob-->Alice: I am good thanks!\n'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(3)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[2].from).toBe('Bob')
-  })
-  it('it should handle semicolons', function () {
-    const str = 'sequenceDiagram;' +
-      'Alice->Bob: Hello Bob, how are you?;' +
-      'Note right of Bob: Bob thinks;' +
-      'Bob-->Alice: I am good thanks!;'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(3)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[2].from).toBe('Bob')
-  })
-  it('it should handle one leading space in lines in a sequenceDiagram', function () {
-    const str = 'sequenceDiagram\n' +
-      ' Alice->Bob: Hello Bob, how are you?\n\n' +
-      '%% Comment\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'Bob-->Alice: I am good thanks!'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(3)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[2].from).toBe('Bob')
-  })
-  it('it should handle several leading spaces in lines in a sequenceDiagram', function () {
-    const str = 'sequenceDiagram\n' +
-      '   Alice->Bob: Hello Bob, how are you?\n\n' +
-      '%% Comment\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'Bob-->Alice: I am good thanks!'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(3)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[2].from).toBe('Bob')
-  })
-  it('it should handle several leading spaces in lines in a sequenceDiagram', function () {
-    const str = 'sequenceDiagram\n' +
-      'participant Alice\n' +
-      'participant Bob\n' +
-      'Alice->John: Hello John, how are you?\n' +
-      '    loop Healthcheck\n' +
-      'John->John: Fight against hypochondria\n' +
-      ' end\n' +
-      'Note right of John: Rational thoughts<br/>prevail...\n' +
-      '    John-->Alice: Great!\n' +
-      '    John->Bob: How about you?\n' +
-      'Bob-->John: Jolly good!'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(8)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[2].from).toBe('John')
-  })
-  it('it should handle notes over a single actor', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'Note over Bob: Bob thinks\n'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].from).toBe('Bob')
-    expect(messages[1].to).toBe('Bob')
-  })
-  it('it should handle notes over multiple actors', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'Note over Alice,Bob: confusion\n' +
-      'Note over Bob,Alice: resolution\n'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].from).toBe('Alice')
-    expect(messages[1].to).toBe('Bob')
-    expect(messages[2].from).toBe('Bob')
-    expect(messages[2].to).toBe('Alice')
-  })
-  it('it should handle loop statements', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n\n' +
-      '%% Comment\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'loop Multiple happy responses\n\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(5)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[1].from).toBe('Bob')
-  })
-  it('it should handle opt statements', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n\n' +
-      '%% Comment\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'opt Perhaps a happy response\n\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(5)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[1].from).toBe('Bob')
-  })
-  it('it should handle alt statements', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n\n' +
-      '%% Comment\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'alt isWell\n\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'else isSick\n' +
-      'Bob-->Alice: Feel sick...\n' +
-      'end'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(7)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[1].from).toBe('Bob')
-  })
-  it('it should handle alt statements with multiple elses', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n\n' +
-      '%% Comment\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'alt isWell\n\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'else isSick\n' +
-      'Bob-->Alice: Feel sick...\n' +
-      'else default\n' +
-      'Bob-->Alice: :-)\n' +
-      'end'
-    parser.parse(str)
-    const messages = parser.yy.getMessages()
-    expect(messages.length).toBe(9)
-    expect(messages[1].from).toBe('Bob')
-    expect(messages[2].type).toBe(parser.yy.LINETYPE.ALT_START)
-    expect(messages[3].from).toBe('Bob')
-    expect(messages[4].type).toBe(parser.yy.LINETYPE.ALT_ELSE)
-    expect(messages[5].from).toBe('Bob')
-    expect(messages[6].type).toBe(parser.yy.LINETYPE.ALT_ELSE)
-    expect(messages[7].from).toBe('Bob')
-    expect(messages[8].type).toBe(parser.yy.LINETYPE.ALT_END)
-  })
-  it('it should handle par statements a sequenceDiagram', function () {
-    const str = 'sequenceDiagram\n' +
-      'par Parallel one\n' +
-      'Alice->>Bob: Hello Bob, how are you?\n' +
-      'Bob-->>Alice: I am good thanks!\n' +
-      'and Parallel two\n' +
-      'Alice->>Bob: Are you OK?\n' +
-      'Bob-->>Alice: Fine!\n' +
-      'and Parallel three\n' +
-      'Alice->>Bob: What do you think about it?\n' +
-      'Bob-->>Alice: It\'s good!\n' +
-      'end'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-
-    expect(actors.Alice.description).toBe('Alice')
-    expect(actors.Bob.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(10)
-    expect(messages[0].message).toBe('Parallel one')
-    expect(messages[1].from).toBe('Alice')
-    expect(messages[2].from).toBe('Bob')
-  })
-  it('it should handle special characters in signals', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: -:<>,;# comment'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[0].message).toBe('-:<>,')
-  })
-  it('it should handle special characters in notes', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'Note right of Bob: -:<>,;# comment'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('-:<>,')
-  })
-  it('it should handle special characters in loop', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'loop -:<>,;# comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('-:<>,')
-  })
-  it('it should handle special characters in opt', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'opt -:<>,;# comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('-:<>,')
-  })
-  it('it should handle special characters in alt', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'alt -:<>,;# comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'else ,<>:-#; comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('-:<>,')
-    expect(messages[3].message).toBe(',<>:-')
-  })
-  it('it should handle special characters in par', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'par -:<>,;# comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'and ,<>:-#; comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('-:<>,')
-    expect(messages[3].message).toBe(',<>:-')
-  })
-  it('it should handle no-label loop', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'loop\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('')
-    expect(messages[2].message).toBe('I am good thanks!')
-  })
-  it('it should handle no-label opt', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'opt # comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('')
-    expect(messages[2].message).toBe('I am good thanks!')
-  })
-  it('it should handle no-label alt', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'alt;' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'else # comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('')
-    expect(messages[2].message).toBe('I am good thanks!')
-    expect(messages[3].message).toBe('')
-    expect(messages[4].message).toBe('I am good thanks!')
-  })
-  it('it should handle no-label par', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'par;' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'and # comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('')
-    expect(messages[2].message).toBe('I am good thanks!')
-    expect(messages[3].message).toBe('')
-    expect(messages[4].message).toBe('I am good thanks!')
-  })
-})
-
-describe('when checking the bounds in a sequenceDiagram', function () {
-  let conf
-  beforeEach(function () {
-    parser.yy = sequenceDb
-    parser.yy.clear()
-    conf = {
-      diagramMarginX: 50,
-      diagramMarginY: 10,
-      actorMargin: 50,
-      width: 150,
-      // Height of actor boxes
-      height: 65,
-      boxMargin: 10,
-      messageMargin: 40,
-      boxTextMargin: 15,
-      noteMargin: 25
-    }
-    renderer.setConf(conf)
-  })
-  it('it should handle a simple bound call', function () {
-    renderer.bounds.init()
-
-    renderer.bounds.insert(100, 100, 200, 200)
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(100)
-    expect(bounds.starty).toBe(100)
-    expect(bounds.stopx).toBe(200)
-    expect(bounds.stopy).toBe(200)
-  })
-  it('it should handle an expanding bound', function () {
-    renderer.bounds.init()
-
-    renderer.bounds.insert(100, 100, 200, 200)
-    renderer.bounds.insert(25, 50, 300, 400)
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(25)
-    expect(bounds.starty).toBe(50)
-    expect(bounds.stopx).toBe(300)
-    expect(bounds.stopy).toBe(400)
-  })
-  it('it should handle inserts within the bound without changing the outer bounds', function () {
-    renderer.bounds.init()
-
-    renderer.bounds.insert(100, 100, 200, 200)
-    renderer.bounds.insert(25, 50, 300, 400)
-    renderer.bounds.insert(125, 150, 150, 200)
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(25)
-    expect(bounds.starty).toBe(50)
-    expect(bounds.stopx).toBe(300)
-    expect(bounds.stopy).toBe(400)
-  })
-  it('it should handle a loop without expanding the area', function () {
-    renderer.bounds.init()
-
-    renderer.bounds.insert(25, 50, 300, 400)
-    renderer.bounds.verticalPos = 150
-    renderer.bounds.newLoop()
-    renderer.bounds.insert(125, 150, 150, 200)
-
-    const loop = renderer.bounds.endLoop()
-
-    expect(loop.startx).toBe(125 - conf.boxMargin)
-    expect(loop.starty).toBe(150 - conf.boxMargin)
-    expect(loop.stopx).toBe(150 + conf.boxMargin)
-    expect(loop.stopy).toBe(200 + conf.boxMargin)
-
-    // Check bounds of first loop
-    const bounds = renderer.bounds.getBounds()
-
-    expect(bounds.startx).toBe(25)
-    expect(bounds.starty).toBe(50)
-    expect(bounds.stopx).toBe(300)
-    expect(bounds.stopy).toBe(400)
-  })
-  it('it should handle multiple loops withtout expanding the bounds', function () {
-    renderer.bounds.init()
-
-    renderer.bounds.insert(100, 100, 1000, 1000)
-    renderer.bounds.verticalPos = 200
-    renderer.bounds.newLoop()
-    renderer.bounds.newLoop()
-    renderer.bounds.insert(200, 200, 300, 300)
-
-    // Check bounds of first loop
-    let loop = renderer.bounds.endLoop()
-
-    expect(loop.startx).toBe(200 - conf.boxMargin)
-    expect(loop.starty).toBe(200 - conf.boxMargin)
-    expect(loop.stopx).toBe(300 + conf.boxMargin)
-    expect(loop.stopy).toBe(300 + conf.boxMargin)
-
-    // Check bounds of second loop
-    loop = renderer.bounds.endLoop()
-
-    expect(loop.startx).toBe(200 - 2 * conf.boxMargin)
-    expect(loop.starty).toBe(200 - 2 * conf.boxMargin)
-    expect(loop.stopx).toBe(300 + 2 * conf.boxMargin)
-    expect(loop.stopy).toBe(300 + 2 * conf.boxMargin)
-
-    // Check bounds of first loop
-    const bounds = renderer.bounds.getBounds()
-
-    expect(bounds.startx).toBe(100)
-    expect(bounds.starty).toBe(100)
-    expect(bounds.stopx).toBe(1000)
-    expect(bounds.stopy).toBe(1000)
-  })
-  it('it should handle a loop that expands the area', function () {
-    renderer.bounds.init()
-
-    renderer.bounds.insert(100, 100, 200, 200)
-    renderer.bounds.verticalPos = 200
-    renderer.bounds.newLoop()
-    renderer.bounds.insert(50, 50, 300, 300)
-
-    const loop = renderer.bounds.endLoop()
-
-    expect(loop.startx).toBe(50 - conf.boxMargin)
-    expect(loop.starty).toBe(50 - conf.boxMargin)
-    expect(loop.stopx).toBe(300 + conf.boxMargin)
-    expect(loop.stopy).toBe(300 + conf.boxMargin)
-
-    // Check bounds after the loop
-    const bounds = renderer.bounds.getBounds()
-
-    expect(bounds.startx).toBe(loop.startx)
-    expect(bounds.starty).toBe(loop.starty)
-    expect(bounds.stopx).toBe(loop.stopx)
-    expect(bounds.stopy).toBe(loop.stopy)
-  })
-})
-
-describe('when rendering a sequenceDiagram', function () {
-  let conf
-  beforeEach(function () {
-    parser.yy = sequenceDb
-    parser.yy.clear()
-
-    conf = {
-      diagramMarginX: 50,
-      diagramMarginY: 10,
-      actorMargin: 50,
-      width: 150,
-      // Height of actor boxes
-      height: 65,
-      boxMargin: 10,
-      messageMargin: 40,
-      boxTextMargin: 15,
-      noteMargin: 25
-    }
-    renderer.setConf(conf)
-  });
-  ['tspan', 'fo', 'old', undefined].forEach(function (textPlacement) {
-    it('it should handle one actor, when textPlacement is ' + textPlacement, function () {
-      renderer.setConf(addConf(conf, 'textPlacement', textPlacement))
-      renderer.bounds.init()
-      const str = 'sequenceDiagram\n' +
-        'participant Alice'
-
-      parser.parse(str)
-      renderer.draw(str, 'tst')
-
-      const bounds = renderer.bounds.getBounds()
-      expect(bounds.startx).toBe(0)
-      expect(bounds.starty).toBe(0)
-      expect(bounds.stopx).toBe(conf.width)
-      expect(bounds.stopy).toBe(conf.height)
-    })
-  })
-  it('it should handle one actor and a centered note', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'participant Alice\n' +
-      'Note over Alice: Alice thinks\n'
-
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(0)
-    expect(bounds.starty).toBe(0)
-    expect(bounds.stopx).toBe(conf.width)
-    // 10 comes from mock of text height
-    expect(bounds.stopy).toBe(conf.height + conf.boxMargin + 2 * conf.noteMargin + 10)
-  })
-  it('it should handle one actor and a note to the left', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'participant Alice\n' +
-      'Note left of Alice: Alice thinks'
-
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(-(conf.width / 2) - (conf.actorMargin / 2))
-    expect(bounds.starty).toBe(0)
-    expect(bounds.stopx).toBe(conf.width)
-    // 10 comes from mock of text height
-    expect(bounds.stopy).toBe(conf.height + conf.boxMargin + 2 * conf.noteMargin + 10)
-  })
-  it('it should handle one actor and a note to the right', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'participant Alice\n' +
-      'Note right of Alice: Alice thinks'
-
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(0)
-    expect(bounds.starty).toBe(0)
-    expect(bounds.stopx).toBe((conf.width / 2) + (conf.actorMargin / 2) + conf.width)
-    // 10 comes from mock of text height
-    expect(bounds.stopy).toBe(conf.height + conf.boxMargin + 2 * conf.noteMargin + 10)
-  })
-  it('it should handle two actors', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?'
-
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(0)
-    expect(bounds.starty).toBe(0)
-    expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin)
-    expect(bounds.stopy).toBe(0 + conf.messageMargin + conf.height)
-  })
-  it('it should handle two actors and two centered shared notes', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'Note over Alice,Bob: Looks\n' +
-      'Note over Bob,Alice: Looks back\n'
-
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(0)
-    expect(bounds.starty).toBe(0)
-    expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin)
-    expect(bounds.stopy).toBe(conf.height + conf.messageMargin + 2 * (conf.boxMargin + 2 * conf.noteMargin + 10))
-  })
-  it('it should draw two actors and two messages', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'Bob->Alice: Fine!'
-
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(0)
-    expect(bounds.starty).toBe(0)
-    expect(bounds.stopx).toBe(0 + conf.width * 2 + conf.actorMargin)
-    expect(bounds.stopy).toBe(0 + 2 * conf.messageMargin + conf.height)
-  })
-  it('it should draw two actors notes to the right', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'Bob->Alice: Fine!'
-
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(0)
-    expect(bounds.starty).toBe(0)
-
-    const expStopX = conf.actorMargin + conf.width + (conf.width / 2) + conf.noteMargin + conf.width
-
-    expect(bounds.stopx).toBe(expStopX)
-    expect(bounds.stopy).toBe(2 * conf.messageMargin + conf.height + conf.boxMargin + 10 + 2 * conf.noteMargin)
-  })
-  it('it should draw two actors notes to the left', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'Note left of Alice: Bob thinks\n' +
-      'Bob->Alice: Fine!'
-
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(-(conf.width / 2) - (conf.actorMargin / 2))
-    expect(bounds.starty).toBe(0)
-
-    expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin)
-    expect(bounds.stopy).toBe(2 * conf.messageMargin + conf.height + conf.boxMargin + 10 + 2 * conf.noteMargin)
-  })
-  it('it should draw two loops', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'loop Cheers\n' +
-      'Bob->Alice: Fine!\n' +
-      'end'
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(0)
-    expect(bounds.starty).toBe(0)
-
-    expect(bounds.stopx).toBe(0 + conf.width * 2 + conf.actorMargin)
-    expect(bounds.stopy).toBe(0 + 2 * conf.messageMargin + conf.height + 3 * conf.boxMargin + conf.boxTextMargin)
-  })
-})
-
-describe('when rendering a sequenceDiagram with actor mirror activated', function () {
-  let conf
-  beforeEach(function () {
-    parser.yy = sequenceDb
-    parser.yy.clear()
-
-    conf = {
-      diagramMarginX: 50,
-      diagramMarginY: 10,
-      actorMargin: 50,
-      width: 150,
-      // Height of actor boxes
-      height: 65,
-      boxMargin: 10,
-      messageMargin: 40,
-      boxTextMargin: 15,
-      noteMargin: 25,
-      mirrorActors: true,
-      // Depending on css styling this might need adjustment
-      // Prolongs the edge of the diagram downwards
-      bottomMarginAdj: 1
-    }
-    renderer.setConf(conf)
-  });
-  ['tspan', 'fo', 'old', undefined].forEach(function (textPlacement) {
-    it('it should handle one actor, when textPlacement is' + textPlacement, function () {
-      renderer.setConf(addConf(conf, 'textPlacement', textPlacement))
-      renderer.bounds.init()
-      const str = 'sequenceDiagram\n' +
-        'participant Alice'
-
-      parser.parse(str)
-      renderer.draw(str, 'tst')
-
-      const bounds = renderer.bounds.getBounds()
-      expect(bounds.startx).toBe(0)
-      expect(bounds.starty).toBe(0)
-      expect(bounds.stopx).toBe(conf.width)
-      expect(bounds.stopy).toBe(2 * conf.height + 2 * conf.boxMargin)
-    })
-  })
-})
diff --git a/_submodules/mermaid/src/diagrams/sequence/sequenceRenderer.js b/_submodules/mermaid/src/diagrams/sequence/sequenceRenderer.js
deleted file mode 100644
index fcf41d28eabb88c092f29264c50e067cd6c28109..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/sequence/sequenceRenderer.js
+++ /dev/null
@@ -1,496 +0,0 @@
-import * as d3 from 'd3'
-
-import svgDraw from './svgDraw'
-import { logger } from '../../logger'
-import { parser } from './parser/sequenceDiagram'
-import sequenceDb from './sequenceDb'
-
-parser.yy = sequenceDb
-
-const conf = {
-
-  diagramMarginX: 50,
-  diagramMarginY: 30,
-  // Margin between actors
-  actorMargin: 50,
-  // Width of actor boxes
-  width: 150,
-  // Height of actor boxes
-  height: 65,
-  // Margin around loop boxes
-  boxMargin: 10,
-  boxTextMargin: 5,
-  noteMargin: 10,
-  // Space between messages
-  messageMargin: 35,
-  // mirror actors under diagram
-  mirrorActors: false,
-  // Depending on css styling this might need adjustment
-  // Prolongs the edge of the diagram downwards
-  bottomMarginAdj: 1,
-
-  // width of activation box
-  activationWidth: 10,
-
-  // text placement as: tspan | fo | old only text as before
-  textPlacement: 'tspan'
-}
-
-export const bounds = {
-  data: {
-    startx: undefined,
-    stopx: undefined,
-    starty: undefined,
-    stopy: undefined
-  },
-  verticalPos: 0,
-
-  sequenceItems: [],
-  activations: [],
-  init: function () {
-    this.sequenceItems = []
-    this.activations = []
-    this.data = {
-      startx: undefined,
-      stopx: undefined,
-      starty: undefined,
-      stopy: undefined
-    }
-    this.verticalPos = 0
-  },
-  updateVal: function (obj, key, val, fun) {
-    if (typeof obj[key] === 'undefined') {
-      obj[key] = val
-    } else {
-      obj[key] = fun(val, obj[key])
-    }
-  },
-  updateBounds: function (startx, starty, stopx, stopy) {
-    const _self = this
-    let cnt = 0
-    function updateFn (type) {
-      return function updateItemBounds (item) {
-        cnt++
-        // The loop sequenceItems is a stack so the biggest margins in the beginning of the sequenceItems
-        const n = _self.sequenceItems.length - cnt + 1
-
-        _self.updateVal(item, 'starty', starty - n * conf.boxMargin, Math.min)
-        _self.updateVal(item, 'stopy', stopy + n * conf.boxMargin, Math.max)
-
-        _self.updateVal(bounds.data, 'startx', startx - n * conf.boxMargin, Math.min)
-        _self.updateVal(bounds.data, 'stopx', stopx + n * conf.boxMargin, Math.max)
-
-        if (!(type === 'activation')) {
-          _self.updateVal(item, 'startx', startx - n * conf.boxMargin, Math.min)
-          _self.updateVal(item, 'stopx', stopx + n * conf.boxMargin, Math.max)
-
-          _self.updateVal(bounds.data, 'starty', starty - n * conf.boxMargin, Math.min)
-          _self.updateVal(bounds.data, 'stopy', stopy + n * conf.boxMargin, Math.max)
-        }
-      }
-    }
-
-    this.sequenceItems.forEach(updateFn())
-    this.activations.forEach(updateFn('activation'))
-  },
-  insert: function (startx, starty, stopx, stopy) {
-    const _startx = Math.min(startx, stopx)
-    const _stopx = Math.max(startx, stopx)
-    const _starty = Math.min(starty, stopy)
-    const _stopy = Math.max(starty, stopy)
-
-    this.updateVal(bounds.data, 'startx', _startx, Math.min)
-    this.updateVal(bounds.data, 'starty', _starty, Math.min)
-    this.updateVal(bounds.data, 'stopx', _stopx, Math.max)
-    this.updateVal(bounds.data, 'stopy', _stopy, Math.max)
-
-    this.updateBounds(_startx, _starty, _stopx, _stopy)
-  },
-  newActivation: function (message, diagram) {
-    const actorRect = parser.yy.getActors()[message.from.actor]
-    const stackedSize = actorActivations(message.from.actor).length
-    const x = actorRect.x + conf.width / 2 + (stackedSize - 1) * conf.activationWidth / 2
-    this.activations.push({
-      startx: x,
-      starty: this.verticalPos + 2,
-      stopx: x + conf.activationWidth,
-      stopy: undefined,
-      actor: message.from.actor,
-      anchored: svgDraw.anchorElement(diagram)
-    })
-  },
-  endActivation: function (message) {
-    // find most recent activation for given actor
-    const lastActorActivationIdx = this.activations
-      .map(function (activation) { return activation.actor })
-      .lastIndexOf(message.from.actor)
-    const activation = this.activations.splice(lastActorActivationIdx, 1)[0]
-    return activation
-  },
-  newLoop: function (title) {
-    this.sequenceItems.push({ startx: undefined, starty: this.verticalPos, stopx: undefined, stopy: undefined, title: title })
-  },
-  endLoop: function () {
-    const loop = this.sequenceItems.pop()
-    return loop
-  },
-  addSectionToLoop: function (message) {
-    const loop = this.sequenceItems.pop()
-    loop.sections = loop.sections || []
-    loop.sectionTitles = loop.sectionTitles || []
-    loop.sections.push(bounds.getVerticalPos())
-    loop.sectionTitles.push(message)
-    this.sequenceItems.push(loop)
-  },
-  bumpVerticalPos: function (bump) {
-    this.verticalPos = this.verticalPos + bump
-    this.data.stopy = this.verticalPos
-  },
-  getVerticalPos: function () {
-    return this.verticalPos
-  },
-  getBounds: function () {
-    return this.data
-  }
-}
-
-const _drawLongText = (text, x, y, g, width) => {
-  let textHeight = 0
-  const lines = text.split(/<br\/?>/ig)
-  for (const line of lines) {
-    const textObj = svgDraw.getTextObj()
-    textObj.x = x
-    textObj.y = y + textHeight
-    textObj.textMargin = conf.noteMargin
-    textObj.dy = '1em'
-    textObj.text = line
-    textObj.class = 'noteText'
-    const textElem = svgDraw.drawText(g, textObj, width)
-    textHeight += (textElem._groups || textElem)[0][0].getBBox().height
-  }
-  return textHeight
-}
-
-/**
- * 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
- */
-const drawNote = function (elem, startx, verticalPos, msg, forceWidth) {
-  const rect = svgDraw.getNoteRect()
-  rect.x = startx
-  rect.y = verticalPos
-  rect.width = forceWidth || conf.width
-  rect.class = 'note'
-
-  let g = elem.append('g')
-  const rectElem = svgDraw.drawRect(g, rect)
-
-  const textHeight = _drawLongText(msg.message, startx - 4, verticalPos + 24, g, rect.width - conf.noteMargin)
-
-  bounds.insert(startx, verticalPos, startx + rect.width, verticalPos + 2 * conf.noteMargin + textHeight)
-  rectElem.attr('height', textHeight + 2 * conf.noteMargin)
-  bounds.bumpVerticalPos(textHeight + 2 * conf.noteMargin)
-}
-
-/**
- * Draws a message
- * @param elem
- * @param startx
- * @param stopx
- * @param verticalPos
- * @param txtCenter
- * @param msg
- */
-const drawMessage = function (elem, startx, stopx, verticalPos, msg) {
-  const g = elem.append('g')
-  const txtCenter = startx + (stopx - startx) / 2
-
-  const textElem = g.append('text') // text label for the x axis
-    .attr('x', txtCenter)
-    .attr('y', verticalPos - 7)
-    .style('text-anchor', 'middle')
-    .attr('class', 'messageText')
-    .text(msg.message)
-
-  let textWidth = (textElem._groups || textElem)[0][0].getBBox().width
-
-  let line
-  if (startx === stopx) {
-    line = g.append('path')
-      .attr('d', 'M ' + startx + ',' + verticalPos + ' C ' + (startx + 60) + ',' + (verticalPos - 10) + ' ' + (startx + 60) + ',' +
-      (verticalPos + 30) + ' ' + startx + ',' + (verticalPos + 20))
-
-    bounds.bumpVerticalPos(30)
-    const dx = Math.max(textWidth / 2, 100)
-    bounds.insert(startx - dx, bounds.getVerticalPos() - 10, stopx + dx, bounds.getVerticalPos())
-  } else {
-    line = g.append('line')
-    line.attr('x1', startx)
-    line.attr('y1', verticalPos)
-    line.attr('x2', stopx)
-    line.attr('y2', verticalPos)
-    bounds.insert(startx, bounds.getVerticalPos() - 10, stopx, bounds.getVerticalPos())
-  }
-  // Make an SVG Container
-  // Draw the line
-  if (msg.type === parser.yy.LINETYPE.DOTTED || msg.type === parser.yy.LINETYPE.DOTTED_CROSS || msg.type === parser.yy.LINETYPE.DOTTED_OPEN) {
-    line.style('stroke-dasharray', ('3, 3'))
-    line.attr('class', 'messageLine1')
-  } else {
-    line.attr('class', 'messageLine0')
-  }
-
-  let url = ''
-  if (conf.arrowMarkerAbsolute) {
-    url = window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search
-    url = url.replace(/\(/g, '\\(')
-    url = url.replace(/\)/g, '\\)')
-  }
-
-  line.attr('stroke-width', 2)
-  line.attr('stroke', 'black')
-  line.style('fill', 'none') // remove any fill colour
-  if (msg.type === parser.yy.LINETYPE.SOLID || msg.type === parser.yy.LINETYPE.DOTTED) {
-    line.attr('marker-end', 'url(' + url + '#arrowhead)')
-  }
-
-  if (msg.type === parser.yy.LINETYPE.SOLID_CROSS || msg.type === parser.yy.LINETYPE.DOTTED_CROSS) {
-    line.attr('marker-end', 'url(' + url + '#crosshead)')
-  }
-}
-
-export const drawActors = function (diagram, actors, actorKeys, verticalPos) {
-  // Draw the actors
-  for (let i = 0; i < actorKeys.length; i++) {
-    const key = actorKeys[i]
-
-    // Add some rendering data to the object
-    actors[key].x = i * conf.actorMargin + i * conf.width
-    actors[key].y = verticalPos
-    actors[key].width = conf.diagramMarginX
-    actors[key].height = conf.diagramMarginY
-
-    // Draw the box with the attached line
-    svgDraw.drawActor(diagram, actors[key].x, verticalPos, actors[key].description, conf)
-    bounds.insert(actors[key].x, verticalPos, actors[key].x + conf.width, conf.height)
-  }
-
-  // Add a margin between the actor boxes and the first arrow
-  bounds.bumpVerticalPos(conf.height)
-}
-
-export const setConf = function (cnf) {
-  const keys = Object.keys(cnf)
-
-  keys.forEach(function (key) {
-    conf[key] = cnf[key]
-  })
-}
-
-const actorActivations = function (actor) {
-  return bounds.activations.filter(function (activation) {
-    return activation.actor === actor
-  })
-}
-
-const actorFlowVerticaBounds = function (actor) {
-  // handle multiple stacked activations for same actor
-  const actors = parser.yy.getActors()
-  const activations = actorActivations(actor)
-
-  const left = activations.reduce(function (acc, activation) { return Math.min(acc, activation.startx) }, actors[actor].x + conf.width / 2)
-  const right = activations.reduce(function (acc, activation) { return Math.max(acc, activation.stopx) }, actors[actor].x + conf.width / 2)
-  return [left, right]
-}
-
-/**
- * Draws a flowchart in the tag with id: id based on the graph definition in text.
- * @param text
- * @param id
- */
-export const draw = function (text, id) {
-  parser.yy.clear()
-  parser.parse(text + '\n')
-
-  bounds.init()
-  const diagram = d3.select(`[id="${id}"]`)
-
-  let startx
-  let stopx
-  let forceWidth
-
-  // Fetch data from the parsing
-  const actors = parser.yy.getActors()
-  const actorKeys = parser.yy.getActorKeys()
-  const messages = parser.yy.getMessages()
-  const title = parser.yy.getTitle()
-  drawActors(diagram, actors, actorKeys, 0)
-
-  // The arrow head definition is attached to the svg once
-  svgDraw.insertArrowHead(diagram)
-  svgDraw.insertArrowCrossHead(diagram)
-
-  function activeEnd (msg, verticalPos) {
-    const activationData = bounds.endActivation(msg)
-    if (activationData.starty + 18 > verticalPos) {
-      activationData.starty = verticalPos - 6
-      verticalPos += 12
-    }
-    svgDraw.drawActivation(diagram, activationData, verticalPos, conf)
-
-    bounds.insert(activationData.startx, verticalPos - 10, activationData.stopx, verticalPos)
-  }
-
-  // const lastMsg
-
-  // Draw the messages/signals
-  messages.forEach(function (msg) {
-    let loopData
-    switch (msg.type) {
-      case parser.yy.LINETYPE.NOTE:
-        bounds.bumpVerticalPos(conf.boxMargin)
-
-        startx = actors[msg.from].x
-        stopx = actors[msg.to].x
-
-        if (msg.placement === parser.yy.PLACEMENT.RIGHTOF) {
-          drawNote(diagram, startx + (conf.width + conf.actorMargin) / 2, bounds.getVerticalPos(), msg)
-        } else if (msg.placement === parser.yy.PLACEMENT.LEFTOF) {
-          drawNote(diagram, startx - (conf.width + conf.actorMargin) / 2, bounds.getVerticalPos(), msg)
-        } else if (msg.to === msg.from) {
-          // Single-actor over
-          drawNote(diagram, startx, bounds.getVerticalPos(), msg)
-        } else {
-          // Multi-actor over
-          forceWidth = Math.abs(startx - stopx) + conf.actorMargin
-          drawNote(diagram, (startx + stopx + conf.width - forceWidth) / 2, bounds.getVerticalPos(), msg,
-            forceWidth)
-        }
-        break
-      case parser.yy.LINETYPE.ACTIVE_START:
-        bounds.newActivation(msg, diagram)
-        break
-      case parser.yy.LINETYPE.ACTIVE_END:
-        activeEnd(msg, bounds.getVerticalPos())
-        break
-      case parser.yy.LINETYPE.LOOP_START:
-        bounds.bumpVerticalPos(conf.boxMargin)
-        bounds.newLoop(msg.message)
-        bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin)
-        break
-      case parser.yy.LINETYPE.LOOP_END:
-        loopData = bounds.endLoop()
-
-        svgDraw.drawLoop(diagram, loopData, 'loop', conf)
-        bounds.bumpVerticalPos(conf.boxMargin)
-        break
-      case parser.yy.LINETYPE.OPT_START:
-        bounds.bumpVerticalPos(conf.boxMargin)
-        bounds.newLoop(msg.message)
-        bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin)
-        break
-      case parser.yy.LINETYPE.OPT_END:
-        loopData = bounds.endLoop()
-
-        svgDraw.drawLoop(diagram, loopData, 'opt', conf)
-        bounds.bumpVerticalPos(conf.boxMargin)
-        break
-      case parser.yy.LINETYPE.ALT_START:
-        bounds.bumpVerticalPos(conf.boxMargin)
-        bounds.newLoop(msg.message)
-        bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin)
-        break
-      case parser.yy.LINETYPE.ALT_ELSE:
-        bounds.bumpVerticalPos(conf.boxMargin)
-        loopData = bounds.addSectionToLoop(msg.message)
-        bounds.bumpVerticalPos(conf.boxMargin)
-        break
-      case parser.yy.LINETYPE.ALT_END:
-        loopData = bounds.endLoop()
-
-        svgDraw.drawLoop(diagram, loopData, 'alt', conf)
-        bounds.bumpVerticalPos(conf.boxMargin)
-        break
-      case parser.yy.LINETYPE.PAR_START:
-        bounds.bumpVerticalPos(conf.boxMargin)
-        bounds.newLoop(msg.message)
-        bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin)
-        break
-      case parser.yy.LINETYPE.PAR_AND:
-        bounds.bumpVerticalPos(conf.boxMargin)
-        loopData = bounds.addSectionToLoop(msg.message)
-        bounds.bumpVerticalPos(conf.boxMargin)
-        break
-      case parser.yy.LINETYPE.PAR_END:
-        loopData = bounds.endLoop()
-        svgDraw.drawLoop(diagram, loopData, 'par', conf)
-        bounds.bumpVerticalPos(conf.boxMargin)
-        break
-      default:
-        try {
-          // lastMsg = msg
-          bounds.bumpVerticalPos(conf.messageMargin)
-          const fromBounds = actorFlowVerticaBounds(msg.from)
-          const toBounds = actorFlowVerticaBounds(msg.to)
-          const fromIdx = fromBounds[0] <= toBounds[0] ? 1 : 0
-          const toIdx = fromBounds[0] < toBounds[0] ? 0 : 1
-          startx = fromBounds[fromIdx]
-          stopx = toBounds[toIdx]
-
-          const verticalPos = bounds.getVerticalPos()
-          drawMessage(diagram, startx, stopx, verticalPos, msg)
-          const allBounds = fromBounds.concat(toBounds)
-          bounds.insert(Math.min.apply(null, allBounds), verticalPos, Math.max.apply(null, allBounds), verticalPos)
-        } catch (e) {
-          logger.error('error while drawing message', e)
-        }
-    }
-  })
-
-  if (conf.mirrorActors) {
-    // Draw actors below diagram
-    bounds.bumpVerticalPos(conf.boxMargin * 2)
-    drawActors(diagram, actors, actorKeys, bounds.getVerticalPos())
-  }
-
-  const box = bounds.getBounds()
-
-  // Adjust line height of actor lines now that the height of the diagram is known
-  logger.debug('For line height fix Querying: #' + id + ' .actor-line')
-  const actorLines = d3.selectAll('#' + id + ' .actor-line')
-  actorLines.attr('y2', box.stopy)
-
-  let height = box.stopy - box.starty + 2 * conf.diagramMarginY
-  if (conf.mirrorActors) {
-    height = height - conf.boxMargin + conf.bottomMarginAdj
-  }
-
-  const width = (box.stopx - box.startx) + (2 * conf.diagramMarginX)
-
-  if (title) {
-    diagram.append('text')
-      .text(title)
-      .attr('x', ((box.stopx - box.startx) / 2) - (2 * conf.diagramMarginX))
-      .attr('y', -25)
-  }
-
-  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)
-  }
-  const extraVertForTitle = title ? 40 : 0
-  diagram.attr('viewBox', (box.startx - conf.diagramMarginX) + ' -' + (conf.diagramMarginY + extraVertForTitle) + ' ' + width + ' ' + (height + extraVertForTitle))
-}
-
-export default {
-  bounds,
-  drawActors,
-  setConf,
-  draw
-}
diff --git a/_submodules/mermaid/src/diagrams/sequence/svgDraw.js b/_submodules/mermaid/src/diagrams/sequence/svgDraw.js
deleted file mode 100644
index 29dbbafba57237f9ec987edc7c030c2df474dca8..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/sequence/svgDraw.js
+++ /dev/null
@@ -1,313 +0,0 @@
-export const drawRect = function (elem, rectData) {
-  const rectElem = elem.append('rect')
-  rectElem.attr('x', rectData.x)
-  rectElem.attr('y', rectData.y)
-  rectElem.attr('fill', rectData.fill)
-  rectElem.attr('stroke', rectData.stroke)
-  rectElem.attr('width', rectData.width)
-  rectElem.attr('height', rectData.height)
-  rectElem.attr('rx', rectData.rx)
-  rectElem.attr('ry', rectData.ry)
-
-  if (typeof rectData.class !== 'undefined') {
-    rectElem.attr('class', rectData.class)
-  }
-
-  return rectElem
-}
-
-export const drawText = function (elem, textData, width) {
-  // Remove and ignore br:s
-  const nText = textData.text.replace(/<br\/?>/ig, ' ')
-
-  const textElem = elem.append('text')
-  textElem.attr('x', textData.x)
-  textElem.attr('y', textData.y)
-  textElem.style('text-anchor', textData.anchor)
-  textElem.attr('fill', textData.fill)
-  if (typeof textData.class !== 'undefined') {
-    textElem.attr('class', textData.class)
-  }
-
-  const span = textElem.append('tspan')
-  span.attr('x', textData.x + textData.textMargin * 2)
-  span.attr('fill', textData.fill)
-  span.text(nText)
-
-  return textElem
-}
-
-export const drawLabel = function (elem, txtObject) {
-  function genPoints (x, y, width, height, cut) {
-    return x + ',' + y + ' ' +
-      (x + width) + ',' + y + ' ' +
-      (x + width) + ',' + (y + height - cut) + ' ' +
-      (x + width - cut * 1.2) + ',' + (y + height) + ' ' +
-      (x) + ',' + (y + height)
-  }
-  const polygon = elem.append('polygon')
-  polygon.attr('points', genPoints(txtObject.x, txtObject.y, 50, 20, 7))
-  polygon.attr('class', 'labelBox')
-
-  txtObject.y = txtObject.y + txtObject.labelMargin
-  txtObject.x = txtObject.x + 0.5 * txtObject.labelMargin
-  drawText(elem, txtObject)
-}
-
-let actorCnt = -1
-/**
- * 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
- */
-export const drawActor = function (elem, left, verticalPos, description, conf) {
-  const center = left + (conf.width / 2)
-  const g = elem.append('g')
-  if (verticalPos === 0) {
-    actorCnt++
-    g.append('line')
-      .attr('id', 'actor' + actorCnt)
-      .attr('x1', center)
-      .attr('y1', 5)
-      .attr('x2', center)
-      .attr('y2', 2000)
-      .attr('class', 'actor-line')
-      .attr('stroke-width', '0.5px')
-      .attr('stroke', '#999')
-  }
-
-  const rect = getNoteRect()
-  rect.x = left
-  rect.y = verticalPos
-  rect.fill = '#eaeaea'
-  rect.width = conf.width
-  rect.height = conf.height
-  rect.class = 'actor'
-  rect.rx = 3
-  rect.ry = 3
-  drawRect(g, rect)
-
-  _drawTextCandidateFunc(conf)(description, g,
-    rect.x, rect.y, rect.width, rect.height, { 'class': 'actor' })
-}
-
-export const anchorElement = function (elem) {
-  return elem.append('g')
-}
-/**
- * Draws an actor in the diagram with the attaced line
- * @param elem - element to append activation rect
- * @param bounds - activation box bounds
- * @param verticalPos - precise y cooridnate of bottom activation box edge
- */
-export const drawActivation = function (elem, bounds, verticalPos) {
-  const rect = getNoteRect()
-  const g = bounds.anchored
-  rect.x = bounds.startx
-  rect.y = bounds.starty
-  rect.fill = '#f4f4f4'
-  rect.width = bounds.stopx - bounds.startx
-  rect.height = verticalPos - bounds.starty
-  drawRect(g, rect)
-}
-
-/**
- * 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 list of actors
- * @param description The text in the box
- */
-export const drawLoop = function (elem, bounds, labelText, conf) {
-  const g = elem.append('g')
-  const drawLoopLine = function (startx, starty, stopx, stopy) {
-    return g.append('line')
-      .attr('x1', startx)
-      .attr('y1', starty)
-      .attr('x2', stopx)
-      .attr('y2', stopy)
-      .attr('class', 'loopLine')
-  }
-  drawLoopLine(bounds.startx, bounds.starty, bounds.stopx, bounds.starty)
-  drawLoopLine(bounds.stopx, bounds.starty, bounds.stopx, bounds.stopy)
-  drawLoopLine(bounds.startx, bounds.stopy, bounds.stopx, bounds.stopy)
-  drawLoopLine(bounds.startx, bounds.starty, bounds.startx, bounds.stopy)
-  if (typeof bounds.sections !== 'undefined') {
-    bounds.sections.forEach(function (item) {
-      drawLoopLine(bounds.startx, item, bounds.stopx, item).style('stroke-dasharray', '3, 3')
-    })
-  }
-
-  let txt = getTextObj()
-  txt.text = labelText
-  txt.x = bounds.startx
-  txt.y = bounds.starty
-  txt.labelMargin = 1.5 * 10 // This is the small box that says "loop"
-  txt.class = 'labelText' // Its size & position are fixed.
-
-  drawLabel(g, txt)
-
-  txt = getTextObj()
-  txt.text = '[ ' + bounds.title + ' ]'
-  txt.x = bounds.startx + (bounds.stopx - bounds.startx) / 2
-  txt.y = bounds.starty + 1.5 * conf.boxMargin
-  txt.anchor = 'middle'
-  txt.class = 'loopText'
-
-  drawText(g, txt)
-
-  if (typeof bounds.sectionTitles !== 'undefined') {
-    bounds.sectionTitles.forEach(function (item, idx) {
-      if (item !== '') {
-        txt.text = '[ ' + item + ' ]'
-        txt.y = bounds.sections[idx] + 1.5 * conf.boxMargin
-        drawText(g, txt)
-      }
-    })
-  }
-}
-
-/**
- * Setup arrow head and define the marker. The result is appended to the svg.
- */
-export const insertArrowHead = function (elem) {
-  elem.append('defs').append('marker')
-    .attr('id', 'arrowhead')
-    .attr('refX', 5)
-    .attr('refY', 2)
-    .attr('markerWidth', 6)
-    .attr('markerHeight', 4)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 0,0 V 4 L6,2 Z') // this is actual shape for arrowhead
-}
-/**
- * Setup arrow head and define the marker. The result is appended to the svg.
- */
-export const insertArrowCrossHead = function (elem) {
-  const defs = elem.append('defs')
-  const marker = defs.append('marker')
-    .attr('id', 'crosshead')
-    .attr('markerWidth', 15)
-    .attr('markerHeight', 8)
-    .attr('orient', 'auto')
-    .attr('refX', 16)
-    .attr('refY', 4)
-
-  // The arrow
-  marker.append('path')
-    .attr('fill', 'black')
-    .attr('stroke', '#000000')
-    .style('stroke-dasharray', ('0, 0'))
-    .attr('stroke-width', '1px')
-    .attr('d', 'M 9,2 V 6 L16,4 Z')
-
-  // The cross
-  marker.append('path')
-    .attr('fill', 'none')
-    .attr('stroke', '#000000')
-    .style('stroke-dasharray', ('0, 0'))
-    .attr('stroke-width', '1px')
-    .attr('d', 'M 0,1 L 6,7 M 6,1 L 0,7')
-  // this is actual shape for arrowhead
-}
-
-export const getTextObj = function () {
-  const txt = {
-    x: 0,
-    y: 0,
-    'fill': 'black',
-    'text-anchor': 'start',
-    style: '#666',
-    width: 100,
-    height: 100,
-    textMargin: 0,
-    rx: 0,
-    ry: 0
-  }
-  return txt
-}
-
-export const getNoteRect = function () {
-  const rect = {
-    x: 0,
-    y: 0,
-    fill: '#EDF2AE',
-    stroke: '#666',
-    width: 100,
-    anchor: 'start',
-    height: 100,
-    rx: 0,
-    ry: 0
-  }
-  return rect
-}
-
-const _drawTextCandidateFunc = (function () {
-  function byText (content, g, x, y, width, height, textAttrs) {
-    const text = g.append('text')
-      .attr('x', x + width / 2).attr('y', y + height / 2 + 5)
-      .style('text-anchor', 'middle')
-      .text(content)
-    _setTextAttrs(text, textAttrs)
-  }
-
-  function byTspan (content, g, x, y, width, height, textAttrs) {
-    const text = g.append('text')
-      .attr('x', x + width / 2).attr('y', y)
-      .style('text-anchor', 'middle')
-    text.append('tspan')
-      .attr('x', x + width / 2).attr('dy', '0')
-      .text(content)
-
-    text.attr('y', y + height / 2.0)
-      .attr('dominant-baseline', 'central')
-      .attr('alignment-baseline', 'central')
-
-    _setTextAttrs(text, textAttrs)
-  }
-
-  function byFo (content, g, x, y, width, height, textAttrs) {
-    const s = g.append('switch')
-    const f = s.append('foreignObject')
-      .attr('x', x).attr('y', y)
-      .attr('width', width).attr('height', height)
-
-    const text = f.append('div').style('display', 'table')
-      .style('height', '100%').style('width', '100%')
-
-    text.append('div').style('display', 'table-cell')
-      .style('text-align', 'center').style('vertical-align', 'middle')
-      .text(content)
-
-    byTspan(content, s, x, y, width, height, textAttrs)
-    _setTextAttrs(text, textAttrs)
-  }
-
-  function _setTextAttrs (toText, fromTextAttrsDict) {
-    for (const key in fromTextAttrsDict) {
-      if (fromTextAttrsDict.hasOwnProperty(key)) {
-        toText.attr(key, fromTextAttrsDict[key])
-      }
-    }
-  }
-
-  return function (conf) {
-    return conf.textPlacement === 'fo' ? byFo : (
-      conf.textPlacement === 'old' ? byText : byTspan)
-  }
-})()
-
-export default {
-  drawRect,
-  drawText,
-  drawLabel,
-  drawActor,
-  anchorElement,
-  drawActivation,
-  drawLoop,
-  insertArrowHead,
-  insertArrowCrossHead,
-  getTextObj,
-  getNoteRect
-}
diff --git a/_submodules/mermaid/src/logger.js b/_submodules/mermaid/src/logger.js
deleted file mode 100644
index adaadf31d34554bec1e13a0aacda57cfbf3703b3..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/logger.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import moment from 'moment'
-
-export const LEVELS = {
-  debug: 1,
-  info: 2,
-  warn: 3,
-  error: 4,
-  fatal: 5
-}
-
-export const logger = {
-  debug: () => {},
-  info: () => {},
-  warn: () => {},
-  error: () => {},
-  fatal: () => {}
-}
-
-export const setLogLevel = function (level) {
-  logger.debug = () => {}
-  logger.info = () => {}
-  logger.warn = () => {}
-  logger.error = () => {}
-  logger.fatal = () => {}
-  if (level <= LEVELS.fatal) {
-    logger.fatal = console.log.bind(console, '\x1b[35m', format('FATAL'))
-  }
-  if (level <= LEVELS.error) {
-    logger.error = console.log.bind(console, '\x1b[31m', format('ERROR'))
-  }
-  if (level <= LEVELS.warn) {
-    logger.warn = console.log.bind(console, `\x1b[33m`, format('WARN'))
-  }
-  if (level <= LEVELS.info) {
-    logger.info = console.log.bind(console, '\x1b[34m', format('INFO'))
-  }
-  if (level <= LEVELS.debug) {
-    logger.debug = console.log.bind(console, '\x1b[32m', format('DEBUG'))
-  }
-}
-
-const format = (level) => {
-  const time = moment().format('HH:mm:ss.SSS')
-  return `${time} : ${level} : `
-}
diff --git a/_submodules/mermaid/src/mermaid.js b/_submodules/mermaid/src/mermaid.js
deleted file mode 100644
index a8f05ffea1df32ef3a8f80bf9112b3fe30a199b8..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/mermaid.js
+++ /dev/null
@@ -1,167 +0,0 @@
-/**
- * Web page integration module for the mermaid framework. It uses the mermaidAPI for mermaid functionality and to render
- * the diagrams to svg code.
- */
-import he from 'he'
-
-import mermaidAPI from './mermaidAPI'
-import { logger } from './logger'
-
-/**
- * ## init
- * Function that goes through the document to find the chart definitions in there and render them.
- *
- * The function tags the processed attributes with the attribute data-processed and ignores found elements with the
- * attribute already set. This way the init function can be triggered several times.
- *
- * Optionally, `init` can accept in the second argument one of the following:
- * - a DOM Node
- * - an array of DOM nodes (as would come from a jQuery selector)
- * - a W3C selector, a la `.mermaid`
- *
- * ```mermaid
- * graph LR;
- *  a(Find elements)-->b{Processed}
- *  b-->|Yes|c(Leave element)
- *  b-->|No |d(Transform)
- * ```
- * Renders the mermaid diagrams
- * @param nodes a css selector or an array of nodes
- */
-const init = function () {
-  const conf = mermaidAPI.getConfig()
-  logger.debug('Starting rendering diagrams')
-  let nodes
-  if (arguments.length >= 2) {
-    /*! sequence config was passed as #1 */
-    if (typeof arguments[0] !== 'undefined') {
-      mermaid.sequenceConfig = arguments[0]
-    }
-
-    nodes = arguments[1]
-  } else {
-    nodes = arguments[0]
-  }
-
-  // if last argument is a function this is the callback function
-  let callback
-  if (typeof arguments[arguments.length - 1] === 'function') {
-    callback = arguments[arguments.length - 1]
-    logger.debug('Callback function found')
-  } else {
-    if (typeof conf.mermaid !== 'undefined') {
-      if (typeof conf.mermaid.callback === 'function') {
-        callback = conf.mermaid.callback
-        logger.debug('Callback function found')
-      } else {
-        logger.debug('No Callback function found')
-      }
-    }
-  }
-  nodes = nodes === undefined ? document.querySelectorAll('.mermaid')
-    : typeof nodes === 'string' ? document.querySelectorAll(nodes)
-      : nodes instanceof window.Node ? [nodes]
-        : nodes // Last case  - sequence config was passed pick next
-
-  logger.debug('Start On Load before: ' + mermaid.startOnLoad)
-  if (typeof mermaid.startOnLoad !== 'undefined') {
-    logger.debug('Start On Load inner: ' + mermaid.startOnLoad)
-    mermaidAPI.initialize({ startOnLoad: mermaid.startOnLoad })
-  }
-
-  if (typeof mermaid.ganttConfig !== 'undefined') {
-    mermaidAPI.initialize({ gantt: mermaid.ganttConfig })
-  }
-
-  let txt
-
-  for (let i = 0; i < nodes.length; i++) {
-    const element = nodes[i]
-
-    /*! Check if previously processed */
-    if (!element.getAttribute('data-processed')) {
-      element.setAttribute('data-processed', true)
-    } else {
-      continue
-    }
-
-    const id = `mermaid-${Date.now()}`
-
-    // Fetch the graph definition including tags
-    txt = element.innerHTML
-
-    // transforms the html to pure text
-    txt = he.decode(txt).trim().replace(/<br>/ig, '<br/>')
-
-    mermaidAPI.render(id, txt, (svgCode, bindFunctions) => {
-      element.innerHTML = svgCode
-      if (typeof callback !== 'undefined') {
-        callback(id)
-      }
-      bindFunctions(element)
-    }, element)
-  }
-}
-
-const initialize = function (config) {
-  logger.debug('Initializing mermaid')
-  if (typeof config.mermaid !== 'undefined') {
-    if (typeof config.mermaid.startOnLoad !== 'undefined') {
-      mermaid.startOnLoad = config.mermaid.startOnLoad
-    }
-    if (typeof config.mermaid.htmlLabels !== 'undefined') {
-      mermaid.htmlLabels = config.mermaid.htmlLabels
-    }
-  }
-  mermaidAPI.initialize(config)
-}
-
-/**
- * ##contentLoaded
- * Callback function that is called when page is loaded. This functions fetches configuration for mermaid rendering and
- * calls init for rendering the mermaid diagrams on the page.
- */
-const contentLoaded = function () {
-  let config
-
-  if (mermaid.startOnLoad) {
-    // No config found, do check API config
-    config = mermaidAPI.getConfig()
-    if (config.startOnLoad) {
-      mermaid.init()
-    }
-  } else {
-    if (typeof mermaid.startOnLoad === 'undefined') {
-      logger.debug('In start, no config')
-      config = mermaidAPI.getConfig()
-      if (config.startOnLoad) {
-        mermaid.init()
-      }
-    }
-  }
-}
-
-if (typeof document !== 'undefined') {
-  /*!
-   * Wait for document loaded before starting the execution
-   */
-  window.addEventListener('load', function () {
-    contentLoaded()
-  }, false)
-}
-
-const mermaid = {
-  startOnLoad: true,
-  htmlLabels: true,
-
-  mermaidAPI,
-  parse: mermaidAPI.parse,
-  render: mermaidAPI.render,
-
-  init,
-  initialize,
-
-  contentLoaded
-}
-
-export default mermaid
diff --git a/_submodules/mermaid/src/mermaid.spec.js b/_submodules/mermaid/src/mermaid.spec.js
deleted file mode 100644
index 996ad21f56078261dad2752e45bd629f1f159569..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/mermaid.spec.js
+++ /dev/null
@@ -1,217 +0,0 @@
-/* eslint-env jasmine */
-import mermaid from './mermaid'
-import flowDb from './diagrams/flowchart/flowDb'
-import flowParser from './diagrams/flowchart/parser/flow'
-import flowRenderer from './diagrams/flowchart/flowRenderer'
-
-describe('when using mermaid and ', function () {
-  describe('when detecting chart type ', function () {
-    it('should not start rendering with mermaid.startOnLoad set to false', function () {
-      mermaid.startOnLoad = false
-      document.body.innerHTML = '<div class="mermaid">graph TD;\na;</div>'
-      spyOn(mermaid, 'init')
-      mermaid.contentLoaded()
-      expect(mermaid.init).not.toHaveBeenCalled()
-    })
-
-    it('should start rendering with both startOnLoad set', function () {
-      mermaid.startOnLoad = true
-      document.body.innerHTML = '<div class="mermaid">graph TD;\na;</div>'
-      spyOn(mermaid, 'init')
-      mermaid.contentLoaded()
-      expect(mermaid.init).toHaveBeenCalled()
-    })
-
-    it('should start rendering with mermaid.startOnLoad', function () {
-      mermaid.startOnLoad = true
-      document.body.innerHTML = '<div class="mermaid">graph TD;\na;</div>'
-      spyOn(mermaid, 'init')
-      mermaid.contentLoaded()
-      expect(mermaid.init).toHaveBeenCalled()
-    })
-
-    it('should start rendering as a default with no changes performed', function () {
-      document.body.innerHTML = '<div class="mermaid">graph TD;\na;</div>'
-      spyOn(mermaid, 'init')
-      mermaid.contentLoaded()
-      expect(mermaid.init).toHaveBeenCalled()
-    })
-  })
-
-  describe('when calling addEdges ', function () {
-    beforeEach(function () {
-      flowParser.parser.yy = flowDb
-      flowDb.clear()
-    })
-    it('it should handle edges with text', function () {
-      flowParser.parser.parse('graph TD;A-->|text ex|B;')
-      flowParser.parser.yy.getVertices()
-      const edges = flowParser.parser.yy.getEdges()
-
-      const mockG = {
-        setEdge: function (start, end, options) {
-          expect(start).toBe('A')
-          expect(end).toBe('B')
-          expect(options.arrowhead).toBe('normal')
-          expect(options.label.match('text ex')).toBeTruthy()
-        }
-      }
-
-      flowRenderer.addEdges(edges, mockG)
-    })
-
-    it('should handle edges without text', function () {
-      flowParser.parser.parse('graph TD;A-->B;')
-      flowParser.parser.yy.getVertices()
-      const edges = flowParser.parser.yy.getEdges()
-
-      const mockG = {
-        setEdge: function (start, end, options) {
-          expect(start).toBe('A')
-          expect(end).toBe('B')
-          expect(options.arrowhead).toBe('normal')
-        }
-      }
-
-      flowRenderer.addEdges(edges, mockG)
-    })
-
-    it('should handle open-ended edges', function () {
-      flowParser.parser.parse('graph TD;A---B;')
-      flowParser.parser.yy.getVertices()
-      const edges = flowParser.parser.yy.getEdges()
-
-      const mockG = {
-        setEdge: function (start, end, options) {
-          expect(start).toBe('A')
-          expect(end).toBe('B')
-          expect(options.arrowhead).toBe('none')
-        }
-      }
-
-      flowRenderer.addEdges(edges, mockG)
-    })
-
-    it('should handle edges with styles defined', function () {
-      flowParser.parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;')
-      flowParser.parser.yy.getVertices()
-      const edges = flowParser.parser.yy.getEdges()
-
-      const mockG = {
-        setEdge: function (start, end, options) {
-          expect(start).toBe('A')
-          expect(end).toBe('B')
-          expect(options.arrowhead).toBe('none')
-          expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;')
-        }
-      }
-
-      flowRenderer.addEdges(edges, mockG)
-    })
-    it('should handle edges with interpolation defined', function () {
-      flowParser.parser.parse('graph TD;A---B; linkStyle 0 interpolate basis')
-      flowParser.parser.yy.getVertices()
-      const edges = flowParser.parser.yy.getEdges()
-
-      const mockG = {
-        setEdge: function (start, end, options) {
-          expect(start).toBe('A')
-          expect(end).toBe('B')
-          expect(options.arrowhead).toBe('none')
-          expect(options.curve).toBe('basis') // mocked as string
-        }
-      }
-
-      flowRenderer.addEdges(edges, mockG)
-    })
-    it('should handle edges with text and styles defined', function () {
-      flowParser.parser.parse('graph TD;A---|the text|B; linkStyle 0 stroke:val1,stroke-width:val2;')
-      flowParser.parser.yy.getVertices()
-      const edges = flowParser.parser.yy.getEdges()
-
-      const mockG = {
-        setEdge: function (start, end, options) {
-          expect(start).toBe('A')
-          expect(end).toBe('B')
-          expect(options.arrowhead).toBe('none')
-          expect(options.label.match('the text')).toBeTruthy()
-          expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;')
-        }
-      }
-
-      flowRenderer.addEdges(edges, mockG)
-    })
-
-    it('should set fill to "none" by default when handling edges', function () {
-      flowParser.parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;')
-      flowParser.parser.yy.getVertices()
-      const edges = flowParser.parser.yy.getEdges()
-
-      const mockG = {
-        setEdge: function (start, end, options) {
-          expect(start).toBe('A')
-          expect(end).toBe('B')
-          expect(options.arrowhead).toBe('none')
-          expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;')
-        }
-      }
-
-      flowRenderer.addEdges(edges, mockG)
-    })
-
-    it('should not set fill to none if fill is set in linkStyle', function () {
-      flowParser.parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2,fill:blue;')
-      flowParser.parser.yy.getVertices()
-      const edges = flowParser.parser.yy.getEdges()
-      const mockG = {
-        setEdge: function (start, end, options) {
-          expect(start).toBe('A')
-          expect(end).toBe('B')
-          expect(options.arrowhead).toBe('none')
-          expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:blue;')
-        }
-      }
-
-      flowRenderer.addEdges(edges, mockG)
-    })
-  })
-
-  describe('checking validity of input ', function () {
-    it('it should throw for an invalid definiton', function () {
-      expect(() => mermaid.parse('this is not a mermaid diagram definition')).toThrow()
-    })
-
-    it('it should not throw for a valid flow definition', function () {
-      expect(() => mermaid.parse('graph TD;A--x|text including URL space|B;')).not.toThrow()
-    })
-    it('it should throw for an invalid flow definition', function () {
-      expect(() => mermaid.parse('graph TQ;A--x|text including URL space|B;')).toThrow()
-    })
-
-    it('it should not throw for a valid sequenceDiagram definition', function () {
-      const text = 'sequenceDiagram\n' +
-        'Alice->Bob: Hello Bob, how are you?\n\n' +
-        '%% Comment\n' +
-        'Note right of Bob: Bob thinks\n' +
-        'alt isWell\n\n' +
-        'Bob-->Alice: I am good thanks!\n' +
-        'else isSick\n' +
-        'Bob-->Alice: Feel sick...\n' +
-        'end'
-      expect(() => mermaid.parse(text)).not.toThrow()
-    })
-
-    it('it should throw for an invalid sequenceDiagram definition', function () {
-      const text = 'sequenceDiagram\n' +
-        'Alice:->Bob: Hello Bob, how are you?\n\n' +
-        '%% Comment\n' +
-        'Note right of Bob: Bob thinks\n' +
-        'alt isWell\n\n' +
-        'Bob-->Alice: I am good thanks!\n' +
-        'else isSick\n' +
-        'Bob-->Alice: Feel sick...\n' +
-        'end'
-      expect(() => mermaid.parse(text)).toThrow()
-    })
-  })
-})
diff --git a/_submodules/mermaid/src/mermaidAPI.js b/_submodules/mermaid/src/mermaidAPI.js
deleted file mode 100644
index d40c336c4290e95d9b84bd817e910fb68028fc8f..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/mermaidAPI.js
+++ /dev/null
@@ -1,487 +0,0 @@
-/**
- * ---
- * 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.
-*/
-import * as d3 from 'd3'
-import scope from 'scope-css'
-
-import { logger, setLogLevel } from './logger'
-import utils from './utils'
-import flowRenderer from './diagrams/flowchart/flowRenderer'
-import flowParser from './diagrams/flowchart/parser/flow'
-import flowDb from './diagrams/flowchart/flowDb'
-import sequenceRenderer from './diagrams/sequence/sequenceRenderer'
-import sequenceParser from './diagrams/sequence/parser/sequenceDiagram'
-import sequenceDb from './diagrams/sequence/sequenceDb'
-import ganttRenderer from './diagrams/gantt/ganttRenderer'
-import ganttParser from './diagrams/gantt/parser/gantt'
-import ganttDb from './diagrams/gantt/ganttDb'
-import classRenderer from './diagrams/class/classRenderer'
-import classParser from './diagrams/class/parser/classDiagram'
-import classDb from './diagrams/class/classDb'
-import gitGraphRenderer from './diagrams/git/gitGraphRenderer'
-import gitGraphParser from './diagrams/git/parser/gitGraph'
-import gitGraphAst from './diagrams/git/gitGraphAst'
-
-const themes = {}
-for (const themeName of ['default', 'forest', 'dark', 'neutral']) {
-  themes[themeName] = require(`./themes/${themeName}/index.scss`)
-}
-
-/**
- * ## Configuration
- * These are the default options which can be overridden with the initialization call as in the example below:
- * ```
- * mermaid.initialize({
- *   flowchart:{
- *      htmlLabels: false
- *   }
- * });
- * ```
- */
-const config = {
-  theme: 'default',
-  themeCSS: undefined,
-
-  /**
-   * logLevel , decides the amount of logging to be used.
-   *    * debug: 1
-   *    * info: 2
-   *    * warn: 3
-   *    * error: 4
-   *    * fatal: 5
-   */
-  logLevel: 5,
-
-  /**
-   * **startOnLoad** - This options controls whether or mermaid starts when the page loads
-   */
-  startOnLoad: true,
-
-  /**
-   * **arrowMarkerAbsolute** - This options controls whether or arrow markers in html code will be absolute paths or
-   * an anchor, #. This matters if you are using base tag settings.
-   */
-  arrowMarkerAbsolute: false,
-
-  /**
-   * ### 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,
-
-    curve: 'linear'
-  },
-
-  /**
-   * ###  sequenceDiagram
-   * The object containing configurations specific for sequence diagrams
-   */
-  sequence: {
-
-    /**
-     * **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,
-
-    /**
-     *  **leftPadding** - the space allocated for the section name to the left of the activities.
-     */
-    leftPadding: 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: 4,
-
-    /**
-     * **axisFormat** - datetime format of the axis, this might need adjustment to match your locale and preferences
-     */
-    axisFormat: '%Y-%m-%d'
-  },
-  class: {},
-  git: {}
-}
-
-setLogLevel(config.logLevel)
-
-function parse (text) {
-  const graphType = utils.detectType(text)
-  let parser
-
-  switch (graphType) {
-    case 'git':
-      parser = gitGraphParser
-      parser.parser.yy = gitGraphAst
-      break
-    case 'flowchart':
-      parser = flowParser
-      parser.parser.yy = flowDb
-      break
-    case 'sequence':
-      parser = sequenceParser
-      parser.parser.yy = sequenceDb
-      break
-    case 'gantt':
-      parser = ganttParser
-      parser.parser.yy = ganttDb
-      break
-    case 'class':
-      parser = classParser
-      parser.parser.yy = classDb
-      break
-  }
-
-  parser.parser.yy.parseError = (str, hash) => {
-    const error = { str, hash }
-    throw error
-  }
-
-  parser.parse(text)
-}
-
-export const encodeEntities = function (text) {
-  let txt = text
-
-  txt = txt.replace(/style.*:\S*#.*;/g, function (s) {
-    const innerTxt = s.substring(0, s.length - 1)
-    return innerTxt
-  })
-  txt = txt.replace(/classDef.*:\S*#.*;/g, function (s) {
-    const innerTxt = s.substring(0, s.length - 1)
-    return innerTxt
-  })
-
-  txt = txt.replace(/#\w+;/g, function (s) {
-    const innerTxt = s.substring(1, s.length - 1)
-
-    const isInt = /^\+?\d+$/.test(innerTxt)
-    if (isInt) {
-      return 'fl°°' + innerTxt + '¶ß'
-    } else {
-      return 'fl°' + innerTxt + '¶ß'
-    }
-  })
-
-  return txt
-}
-
-export const decodeEntities = function (text) {
-  let 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(){
- *      const graphDefinition = 'graph TB\na-->b';
- *      const 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.
- */
-const render = function (id, txt, cb, container) {
-  if (typeof container !== 'undefined') {
-    container.innerHTML = ''
-
-    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 {
-    const element = document.querySelector('#' + 'd' + id)
-    if (element) {
-      element.innerHTML = ''
-    }
-
-    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 = encodeEntities(txt)
-
-  const element = d3.select('#d' + id).node()
-  const graphType = utils.detectType(txt)
-
-  // insert inline style into svg
-  const svg = element.firstChild
-  const firstChild = svg.firstChild
-
-  // pre-defined theme
-  let style = themes[config.theme]
-  if (style === undefined) {
-    style = ''
-  }
-
-  // user provided theme CSS
-  if (config.themeCSS !== undefined) {
-    style += `\n${config.themeCSS}`
-  }
-
-  // classDef
-  if (graphType === 'flowchart') {
-    const classes = flowRenderer.getClasses(txt)
-    for (const className in classes) {
-      style += `\n.${className} > * { ${classes[className].styles.join(' !important; ')} !important; }`
-    }
-  }
-
-  const style1 = document.createElement('style')
-  style1.innerHTML = scope(style, `#${id}`)
-  svg.insertBefore(style1, firstChild)
-
-  const style2 = document.createElement('style')
-  const cs = window.getComputedStyle(svg)
-  style2.innerHTML = `#${id} {
-    color: ${cs.color};
-    font: ${cs.font};
-  }`
-  svg.insertBefore(style2, firstChild)
-
-  switch (graphType) {
-    case 'git':
-      config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute
-      gitGraphRenderer.setConf(config.git)
-      gitGraphRenderer.draw(txt, id, false)
-      break
-    case 'flowchart':
-      config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute
-      flowRenderer.setConf(config.flowchart)
-      flowRenderer.draw(txt, id, false)
-      break
-    case 'sequence':
-      config.sequence.arrowMarkerAbsolute = config.arrowMarkerAbsolute
-      if (config.sequenceDiagram) { // backwards compatibility
-        sequenceRenderer.setConf(Object.assign(config.sequence, config.sequenceDiagram))
-        console.error('`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.')
-      } else {
-        sequenceRenderer.setConf(config.sequence)
-      }
-      sequenceRenderer.draw(txt, id)
-      break
-    case 'gantt':
-      config.gantt.arrowMarkerAbsolute = config.arrowMarkerAbsolute
-      ganttRenderer.setConf(config.gantt)
-      ganttRenderer.draw(txt, id)
-      break
-    case 'class':
-      config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute
-      classRenderer.setConf(config.class)
-      classRenderer.draw(txt, id)
-      break
-  }
-
-  d3.select(`[id="${id}"]`).selectAll('foreignobject > *').attr('xmlns', 'http://www.w3.org/1999/xhtml')
-
-  let url = ''
-  if (config.arrowMarkerAbsolute) {
-    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
-  let svgCode = d3.select('#d' + id).node().innerHTML.replace(/url\(#arrowhead/g, 'url(' + url + '#arrowhead', 'g')
-
-  svgCode = decodeEntities(svgCode)
-
-  if (typeof cb !== 'undefined') {
-    cb(svgCode, flowDb.bindFunctions)
-  } else {
-    logger.warn('CB = undefined!')
-  }
-
-  const node = d3.select('#d' + id).node()
-  if (node !== null && typeof node.remove === 'function') {
-    d3.select('#d' + id).node().remove()
-  }
-
-  return svgCode
-}
-
-const setConf = function (cnf) {
-  // Top level initially mermaid, gflow, sequenceDiagram and gantt
-  const lvl1Keys = Object.keys(cnf)
-  for (let i = 0; i < lvl1Keys.length; i++) {
-    if (typeof cnf[lvl1Keys[i]] === 'object' && cnf[lvl1Keys[i]] != null) {
-      const lvl2Keys = Object.keys(cnf[lvl1Keys[i]])
-
-      for (let j = 0; j < lvl2Keys.length; j++) {
-        logger.debug('Setting conf ', lvl1Keys[i], '-', lvl2Keys[j])
-        if (typeof config[lvl1Keys[i]] === 'undefined') {
-          config[lvl1Keys[i]] = {}
-        }
-        logger.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]]
-    }
-  }
-}
-
-function initialize (options) {
-  logger.debug('Initializing mermaidAPI')
-  // Update default config with options supplied at initialization
-  if (typeof options === 'object') {
-    setConf(options)
-  }
-  setLogLevel(config.logLevel)
-}
-
-function getConfig () {
-  return config
-}
-
-const mermaidAPI = {
-  render,
-  parse,
-  initialize,
-  getConfig
-}
-
-export default mermaidAPI
diff --git a/_submodules/mermaid/src/mermaidAPI.spec.js b/_submodules/mermaid/src/mermaidAPI.spec.js
deleted file mode 100644
index 51749677cd7090172b2dec138d96e71f5d365d73..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/mermaidAPI.spec.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* eslint-env jasmine */
-import mermaidAPI from './mermaidAPI'
-
-describe('when using mermaidAPI and ', function () {
-  describe('doing initialize ', function () {
-    beforeEach(function () {
-      document.body.innerHTML = ''
-    })
-
-    it('should copy a literal into the configuration', function () {
-      const orgConfig = mermaidAPI.getConfig()
-      expect(orgConfig.testLiteral).toBe(undefined)
-
-      mermaidAPI.initialize({ 'testLiteral': true })
-      const config = mermaidAPI.getConfig()
-
-      expect(config.testLiteral).toBe(true)
-    })
-    it('should copy a an object into the configuration', function () {
-      const orgConfig = mermaidAPI.getConfig()
-      expect(orgConfig.testObject).toBe(undefined)
-
-      const object = {
-        test1: 1,
-        test2: false
-      }
-
-      mermaidAPI.initialize({ 'testObject': object })
-      mermaidAPI.initialize({ 'testObject': { 'test3': true } })
-      const config = mermaidAPI.getConfig()
-
-      expect(config.testObject.test1).toBe(1)
-      expect(config.testObject.test2).toBe(false)
-      expect(config.testObject.test3).toBe(true)
-    })
-  })
-  describe('checking validity of input ', function () {
-    it('it should throw for an invalid definiton', function () {
-      expect(() => mermaidAPI.parse('this is not a mermaid diagram definition')).toThrow()
-    })
-    it('it should not throw for a valid definiton', function () {
-      expect(() => mermaidAPI.parse('graph TD;A--x|text including URL space|B;')).not.toThrow()
-    })
-  })
-})
diff --git a/_submodules/mermaid/src/themes/class.scss b/_submodules/mermaid/src/themes/class.scss
deleted file mode 100644
index 5e7de91503d085c62ad225d75c6edf8633eb00ed..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/class.scss
+++ /dev/null
@@ -1,78 +0,0 @@
-g.classGroup text {
-  fill: $nodeBorder;
-  stroke: none;
-  font-family: 'trebuchet ms', verdana, arial;
-  font-size: 10px;
-}
-
-g.classGroup rect {
-  fill: $nodeBkg;
-  stroke: $nodeBorder;
-}
-
-g.classGroup line {
-  stroke: $nodeBorder;
-  stroke-width: 1;
-}
-
-.classLabel .box {
-  stroke: none;
-  stroke-width: 0;
-  fill: $nodeBkg;
-  opacity: 0.5;
-}
-
-.classLabel .label {
-  fill: $nodeBorder;
-  font-size: 10px;
-}
-
-.relation {
-  stroke: $nodeBorder;
-  stroke-width: 1;
-  fill: none;
-}
-
-@mixin composition {
-  fill: $nodeBorder;
-  stroke: $nodeBorder;
-  stroke-width: 1;
-}
-
-#compositionStart {
-  @include composition;
-}
-
-#compositionEnd {
-  @include composition;
-}
-
-@mixin aggregation {
-  fill: $nodeBkg;
-  stroke: $nodeBorder;
-  stroke-width: 1;
-}
-
-#aggregationStart {
-  @include aggregation;
-}
-
-#aggregationEnd {
-  @include aggregation;
-}
-
-#dependencyStart {
-  @include composition;
-}
-
-#dependencyEnd {
-  @include composition;
-}
-
-#extensionStart {
-  @include composition;
-}
-
-#extensionEnd {
-  @include composition;
-}
diff --git a/_submodules/mermaid/src/themes/default/index.scss b/_submodules/mermaid/src/themes/default/index.scss
deleted file mode 100644
index e98fc0741e34cc34363934f6db1489a5bfc2db4a..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/default/index.scss
+++ /dev/null
@@ -1,52 +0,0 @@
-$mainBkg: #ECECFF;
-$secondBkg: #ffffde;
-$lineColor: #333333;
-$border1: #CCCCFF;
-$border2: #aaaa33;
-$arrowheadColor: #333333;
-
-/* Flowchart variables */
-
-$nodeBkg: $mainBkg;
-$nodeBorder: #9370DB;
-$clusterBkg: $secondBkg;
-$clusterBorder: $border2;
-$defaultLinkColor: $lineColor;
-$titleColor: #333;
-$edgeLabelBackground: #e8e8e8;
-
-/* Sequence Diagram variables */
-
-$actorBorder: $border1;
-$actorBkg: $mainBkg;
-$actorTextColor: black;
-$actorLineColor: grey;
-$signalColor: #333;
-$signalTextColor: #333;
-$labelBoxBkgColor: $actorBkg;
-$labelBoxBorderColor: $actorBorder;
-$labelTextColor: $actorTextColor;
-$noteBorderColor: $border2;
-$noteBkgColor: #fff5ad;
-
-/* Gantt chart variables */
-
-$sectionBkgColor: rgba(102, 102, 255, 0.49);
-$altSectionBkgColor: white;
-$sectionBkgColor2: #fff400;
-$taskBorderColor: #534fbc;
-$taskBkgColor: #8a90dd;
-$taskTextLightColor: white;
-$taskTextColor: $taskTextLightColor;
-$taskTextDarkColor: black;
-$taskTextOutsideColor: $taskTextDarkColor;
-$activeTaskBorderColor: #534fbc;
-$activeTaskBkgColor: #bfc7ff;
-$gridColor: lightgrey;
-$doneTaskBkgColor: lightgrey;
-$doneTaskBorderColor: grey;
-$critBorderColor: #ff8888;
-$critBkgColor: red;
-$todayLineColor: red;
-
-@import '../mermaid';
diff --git a/_submodules/mermaid/src/themes/flowchart.scss b/_submodules/mermaid/src/themes/flowchart.scss
deleted file mode 100644
index edafcf5e75e4d52906c291cce0703878ec92454e..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/flowchart.scss
+++ /dev/null
@@ -1,54 +0,0 @@
-.label {
-  font-family: 'trebuchet ms', verdana, arial;
-  color: #333;
-}
-
-.node rect,
-.node circle,
-.node ellipse,
-.node polygon {
-  fill: $mainBkg;
-  stroke: $nodeBorder;
-  stroke-width: 1px;
-}
-
-.node.clickable {
-  cursor: pointer;
-}
-
-.arrowheadPath {
-  fill: $arrowheadColor;
-}
-
-.edgePath .path {
-  stroke: $lineColor;
-  stroke-width: 1.5px;
-}
-
-.edgeLabel {
-  background-color: $edgeLabelBackground;
-}
-
-.cluster rect {
-  fill: $secondBkg !important;
-  stroke: $clusterBorder !important;
-  stroke-width: 1px !important;
-}
-
-.cluster text {
-  fill: $titleColor;
-}
-
-div.mermaidTooltip {
-  position: absolute;
-  text-align: center;
-  max-width: 200px;
-  padding: 2px;
-  font-family: 'trebuchet ms', verdana, arial;
-  font-size: 12px;
-  background: $secondBkg;
-  border: 1px solid $border2;
-  border-radius: 2px;
-  pointer-events: none;
-  z-index: 100;
-}
diff --git a/_submodules/mermaid/src/themes/forest/index.scss b/_submodules/mermaid/src/themes/forest/index.scss
deleted file mode 100644
index f6e1a1dae7fd6c12d6533d8e7fa8914c764d943a..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/forest/index.scss
+++ /dev/null
@@ -1,53 +0,0 @@
-$mainBkg: #cde498;
-$secondBkg: #cdffb2;
-$lineColor: #1a3318;
-$lineColor: green;
-$border1: #13540c;
-$border2: #6eaa49;
-$arrowheadColor: green;
-
-/* Flowchart variables */
-
-$nodeBkg: $mainBkg;
-$nodeBorder: $border1;
-$clusterBkg: $secondBkg;
-$clusterBorder: $border2;
-$defaultLinkColor: $lineColor;
-$titleColor: #333;
-$edgeLabelBackground: #e8e8e8;
-
-/* Sequence Diagram variables */
-
-$actorBorder: $border1;
-$actorBkg: $mainBkg;
-$actorTextColor: black;
-$actorLineColor: grey;
-$signalColor: #333;
-$signalTextColor: #333;
-$labelBoxBkgColor: $actorBkg;
-$labelBoxBorderColor: #326932;
-$labelTextColor: $actorTextColor;
-$noteBorderColor: $border2;
-$noteBkgColor: #fff5ad;
-
-/* Gantt chart variables */
-
-$sectionBkgColor: #6eaa49;
-$altSectionBkgColor: white;
-$sectionBkgColor2: #6eaa49;
-$taskBorderColor: $border1;
-$taskBkgColor: #487e3a;
-$taskTextLightColor: white;
-$taskTextColor: $taskTextLightColor;
-$taskTextDarkColor: black;
-$taskTextOutsideColor: $taskTextDarkColor;
-$activeTaskBorderColor: $taskBorderColor;
-$activeTaskBkgColor: $mainBkg;
-$gridColor: lightgrey;
-$doneTaskBkgColor: lightgrey;
-$doneTaskBorderColor: grey;
-$critBorderColor: #ff8888;
-$critBkgColor: red;
-$todayLineColor: red;
-
-@import '../mermaid';
diff --git a/_submodules/mermaid/src/themes/gantt.scss b/_submodules/mermaid/src/themes/gantt.scss
deleted file mode 100644
index 6793135ec854b44e26f15d006c1a5cb151f5d1f8..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/gantt.scss
+++ /dev/null
@@ -1,209 +0,0 @@
-/** Section styling */
-
-.section {
-  stroke: none;
-  opacity: 0.2;
-}
-
-.section0 {
-  fill: $sectionBkgColor;
-}
-
-.section2 {
-  fill: $sectionBkgColor2;
-}
-
-.section1,
-.section3 {
-  fill: $altSectionBkgColor;
-  opacity: 0.2;
-}
-
-.sectionTitle0 {
-  fill: $titleColor;
-}
-
-.sectionTitle1 {
-  fill: $titleColor;
-}
-
-.sectionTitle2 {
-  fill: $titleColor;
-}
-
-.sectionTitle3 {
-  fill: $titleColor;
-}
-
-.sectionTitle {
-  text-anchor: start;
-  font-size: 11px;
-  text-height: 14px;
-}
-
-
-/* Grid and axis */
-
-.grid .tick {
-  stroke: $gridColor;
-  opacity: 0.3;
-  shape-rendering: crispEdges;
-}
-
-.grid path {
-  stroke-width: 0;
-}
-
-
-/* Today line */
-
-.today {
-  fill: none;
-  stroke: $todayLineColor;
-  stroke-width: 2px;
-}
-
-
-/* Task styling */
-
-
-/* Default task */
-
-.task {
-  stroke-width: 2;
-}
-
-.taskText {
-  text-anchor: middle;
-  font-size: 11px;
-}
-
-.taskTextOutsideRight {
-  fill: $taskTextDarkColor;
-  text-anchor: start;
-  font-size: 11px;
-}
-
-.taskTextOutsideLeft {
-  fill: $taskTextDarkColor;
-  text-anchor: end;
-  font-size: 11px;
-}
-
-
-/* Specific task settings for the sections*/
-
-.taskText0,
-.taskText1,
-.taskText2,
-.taskText3 {
-  fill: $taskTextColor;
-}
-
-.task0,
-.task1,
-.task2,
-.task3 {
-  fill: $taskBkgColor;
-  stroke: $taskBorderColor;
-}
-
-.taskTextOutside0,
-.taskTextOutside2,
-{
-  fill: $taskTextOutsideColor;
-}
-
-.taskTextOutside1,
-.taskTextOutside3 {
-  fill: $taskTextOutsideColor;
-}
-
-
-/* Active task */
-
-.active0,
-.active1,
-.active2,
-.active3 {
-  fill: $activeTaskBkgColor;
-  stroke: $activeTaskBorderColor;
-}
-
-.activeText0,
-.activeText1,
-.activeText2,
-.activeText3 {
-  fill: $taskTextDarkColor !important;
-}
-
-
-/* Completed task */
-
-.done0,
-.done1,
-.done2,
-.done3 {
-  stroke: $doneTaskBorderColor;
-  fill: $doneTaskBkgColor;
-  stroke-width: 2;
-}
-
-.doneText0,
-.doneText1,
-.doneText2,
-.doneText3 {
-  fill: $taskTextDarkColor !important;
-}
-
-
-/* Tasks on the critical line */
-
-.crit0,
-.crit1,
-.crit2,
-.crit3 {
-  stroke: $critBorderColor;
-  fill: $critBkgColor;
-  stroke-width: 2;
-}
-
-.activeCrit0,
-.activeCrit1,
-.activeCrit2,
-.activeCrit3 {
-  stroke: $critBorderColor;
-  fill: $activeTaskBkgColor;
-  stroke-width: 2;
-}
-
-.doneCrit0,
-.doneCrit1,
-.doneCrit2,
-.doneCrit3 {
-  stroke: $critBorderColor;
-  fill: $doneTaskBkgColor;
-  stroke-width: 2;
-  cursor: pointer;
-  shape-rendering: crispEdges;
-}
-
-.doneCritText0,
-.doneCritText1,
-.doneCritText2,
-.doneCritText3 {
-  fill: $taskTextDarkColor !important;
-}
-
-.activeCritText0,
-.activeCritText1,
-.activeCritText2,
-.activeCritText3 {
-  fill: $taskTextDarkColor !important;
-}
-
-.titleText {
-  text-anchor: middle;
-  font-size: 18px;
-  fill: $taskTextDarkColor;
-}
diff --git a/_submodules/mermaid/src/themes/git.scss b/_submodules/mermaid/src/themes/git.scss
deleted file mode 100644
index f4072ef6526819fb162af3b02146ceb4f79f8dcb..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/git.scss
+++ /dev/null
@@ -1,6 +0,0 @@
-.commit-id,
-.commit-msg,
-.branch-label {
-  fill: lightgrey;
-  color: lightgrey;
-}
diff --git a/_submodules/mermaid/src/themes/mermaid.scss b/_submodules/mermaid/src/themes/mermaid.scss
deleted file mode 100644
index 9a46f5142e06ce354a2dad513acc5a678360c314..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/mermaid.scss
+++ /dev/null
@@ -1,5 +0,0 @@
-@import 'flowchart';
-@import 'sequence';
-@import 'gantt';
-@import 'class';
-@import 'git';
diff --git a/_submodules/mermaid/src/themes/neutral/index.scss b/_submodules/mermaid/src/themes/neutral/index.scss
deleted file mode 100644
index f0560142f0d87358ce74356362e49fd805f818b1..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/neutral/index.scss
+++ /dev/null
@@ -1,57 +0,0 @@
-$mainBkg: #eee;
-$contrast: #26a;
-$secondBkg: lighten($contrast, 55%);
-$lineColor: #666;
-$border1: #999;
-$border2: $contrast;
-$note: #ffa;
-$text: #333;
-$critical: #d42;
-$done: #bbb;
-$arrowheadColor: #333333;
-
-/* Flowchart variables */
-
-$nodeBkg: $mainBkg;
-$nodeBorder: $border1;
-$clusterBkg: $secondBkg;
-$clusterBorder: $border2;
-$defaultLinkColor: $lineColor;
-$titleColor: $text;
-$edgeLabelBackground: white;
-
-/* Sequence Diagram variables */
-
-$actorBorder: $border1;
-$actorBkg: $mainBkg;
-$actorTextColor: $text;
-$actorLineColor: $lineColor;
-$signalColor: $text;
-$signalTextColor: $text;
-$labelBoxBkgColor: $actorBkg;
-$labelBoxBorderColor: $actorBorder;
-$labelTextColor: white;
-$noteBorderColor: darken($note, 60%);
-$noteBkgColor: $note;
-
-/* Gantt chart variables */
-
-$sectionBkgColor: lighten($contrast, 30%);
-$altSectionBkgColor: white;
-$sectionBkgColor2: lighten($contrast, 30%);
-$taskBorderColor: darken($contrast, 10%);
-$taskBkgColor: $contrast;
-$taskTextLightColor: white;
-$taskTextColor: $taskTextLightColor;
-$taskTextDarkColor: $text;
-$taskTextOutsideColor: $taskTextDarkColor;
-$activeTaskBorderColor: $taskBorderColor;
-$activeTaskBkgColor: $mainBkg;
-$gridColor: lighten($border1, 30%);
-$doneTaskBkgColor: $done;
-$doneTaskBorderColor: $lineColor;
-$critBkgColor: $critical;
-$critBorderColor: darken($critBkgColor, 10%);
-$todayLineColor: $critBkgColor;
-
-@import '../mermaid';
diff --git a/_submodules/mermaid/src/themes/sequence.scss b/_submodules/mermaid/src/themes/sequence.scss
deleted file mode 100644
index 780e8ecf5dc74059d24730fe46a01937667c99f8..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/sequence.scss
+++ /dev/null
@@ -1,75 +0,0 @@
-.actor {
-  stroke: $actorBorder;
-  fill: $actorBkg;
-}
-
-text.actor {
-  fill: $actorTextColor;
-  stroke: none;
-}
-
-.actor-line {
-  stroke: $actorLineColor;
-}
-
-.messageLine0 {
-  stroke-width: 1.5;
-  stroke-dasharray: '2 2';
-  marker-end: 'url(#arrowhead)';
-  stroke: $signalColor;
-}
-
-.messageLine1 {
-  stroke-width: 1.5;
-  stroke-dasharray: '2 2';
-  stroke: $signalColor;
-}
-
-#arrowhead {
-  fill: $signalColor;
-}
-
-#crosshead path {
-  fill: $signalColor !important;
-  stroke: $signalColor !important;
-}
-
-.messageText {
-  fill: $signalTextColor;
-  stroke: none;
-}
-
-.labelBox {
-  stroke: $labelBoxBorderColor;
-  fill: $labelBoxBkgColor;
-}
-
-.labelText {
-  fill: $labelTextColor;
-  stroke: none;
-}
-
-.loopText {
-  fill: $labelTextColor;
-  stroke: none;
-}
-
-.loopLine {
-  stroke-width: 2;
-  stroke-dasharray: '2 2';
-  marker-end: 'url(#arrowhead)';
-  stroke: $labelBoxBorderColor;
-}
-
-.note {
-  //stroke: #decc93;
-  stroke: $noteBorderColor;
-  fill: $noteBkgColor;
-}
-
-.noteText {
-  fill: black;
-  stroke: none;
-  font-family: 'trebuchet ms', verdana, arial;
-  font-size: 14px;
-}
diff --git a/_submodules/mermaid/src/utils.js b/_submodules/mermaid/src/utils.js
deleted file mode 100644
index a18bed14a61f89aef49dc423976d83cc0dfa59bf..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/utils.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import * as d3 from 'd3'
-
-/**
- * @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
- */
-export const detectType = function (text) {
-  text = text.replace(/^\s*%%.*\n/g, '\n')
-  if (text.match(/^\s*sequenceDiagram/)) {
-    return 'sequence'
-  }
-
-  if (text.match(/^\s*gantt/)) {
-    return 'gantt'
-  }
-
-  if (text.match(/^\s*classDiagram/)) {
-    return 'class'
-  }
-
-  if (text.match(/^\s*gitGraph/)) {
-    return 'git'
-  }
-  return 'flowchart'
-}
-
-/**
- * @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
- **/
-export const isSubstringInArray = function (str, arr) {
-  for (let i = 0; i < arr.length; i++) {
-    if (arr[i].match(str)) return i
-  }
-  return -1
-}
-
-export const interpolateToCurve = (interpolate, defaultCurve) => {
-  if (!interpolate) {
-    return defaultCurve
-  }
-  const curveName = `curve${interpolate.charAt(0).toUpperCase() + interpolate.slice(1)}`
-  return d3[curveName] || defaultCurve
-}
-
-export default {
-  detectType,
-  isSubstringInArray,
-  interpolateToCurve
-}
diff --git a/_submodules/mermaid/src/utils.spec.js b/_submodules/mermaid/src/utils.spec.js
deleted file mode 100644
index 43341fb6d116b0a8f9af03ee6a3b33b9964c1d59..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/utils.spec.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* eslint-env jasmine */
-import utils from './utils'
-
-describe('when detecting chart type ', function () {
-  it('should handle a graph defintion', function () {
-    const str = 'graph TB\nbfs1:queue'
-    const type = utils.detectType(str)
-    expect(type).toBe('flowchart')
-  })
-  it('should handle a graph defintion with leading spaces', function () {
-    const str = '    graph TB\nbfs1:queue'
-    const type = utils.detectType(str)
-    expect(type).toBe('flowchart')
-  })
-
-  it('should handle a graph defintion with leading spaces and newline', function () {
-    const str = '  \n  graph TB\nbfs1:queue'
-    const type = utils.detectType(str)
-    expect(type).toBe('flowchart')
-  })
-  it('should handle a graph defintion for gitGraph', function () {
-    const str = '  \n  gitGraph TB:\nbfs1:queue'
-    const type = utils.detectType(str)
-    expect(type).toBe('git')
-  })
-})
-
-describe('when finding substring in array ', function () {
-  it('should return the array index that contains the substring', function () {
-    const arr = ['stroke:val1', 'fill:val2']
-    const result = utils.isSubstringInArray('fill', arr)
-    expect(result).toEqual(1)
-  })
-  it('should return -1 if the substring is not found in the array', function () {
-    const arr = ['stroke:val1', 'stroke-width:val2']
-    const result = utils.isSubstringInArray('fill', arr)
-    expect(result).toEqual(-1)
-  })
-})
diff --git a/_submodules/mermaid/todo.md b/_submodules/mermaid/todo.md
deleted file mode 100644
index 615856d5a1626e59b1974b30ef2d904717e9fa93..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/todo.md
+++ /dev/null
@@ -1,4 +0,0 @@
-- Get familar with jison
-- git graph requires a blank line at the end. why?
-- Create a desktop client
-- Do the rendering in an iframe to avoid global CSS to affect rendering.
diff --git a/_submodules/mermaid/webpack.config.babel.js b/_submodules/mermaid/webpack.config.babel.js
deleted file mode 100644
index 73faab7840d7fcfa6826a556c55aa9319c270c60..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/webpack.config.babel.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import nodeExternals from 'webpack-node-externals'
-
-import { jsConfig } from './webpack.config.base'
-
-const config = jsConfig()
-
-const coreConfig = jsConfig()
-coreConfig.externals = [nodeExternals()]
-coreConfig.output.filename = '[name].core.js'
-
-export default [config, coreConfig]
diff --git a/_submodules/mermaid/webpack.config.base.js b/_submodules/mermaid/webpack.config.base.js
deleted file mode 100644
index 727880fd64d4c649df1bb8bd6b3ac0b4aff3663f..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/webpack.config.base.js
+++ /dev/null
@@ -1,48 +0,0 @@
-import path from 'path'
-
-const amdRule = {
-  parser: {
-    amd: false // https://github.com/lodash/lodash/issues/3052
-  }
-}
-
-const jsRule = {
-  test: /\.js$/,
-  exclude: /node_modules/,
-  use: {
-    loader: 'babel-loader'
-  }
-}
-
-const scssRule = { // load scss to string
-  test: /\.scss$/,
-  use: [
-    { loader: 'css-to-string-loader' },
-    { loader: 'css-loader' },
-    { loader: 'sass-loader' }
-  ]
-}
-
-export const jsConfig = () => {
-  return {
-    mode: 'development',
-    target: 'web',
-    entry: {
-      mermaid: './src/mermaid.js'
-    },
-    node: {
-      fs: 'empty' // jison generated code requires 'fs'
-    },
-    output: {
-      path: path.join(__dirname, './dist/'),
-      filename: '[name].js',
-      library: 'mermaid',
-      libraryTarget: 'umd',
-      libraryExport: 'default'
-    },
-    module: {
-      rules: [amdRule, jsRule, scssRule]
-    },
-    devtool: 'source-map'
-  }
-}
diff --git a/assets/img/favicon.ico b/assets/img/favicon.ico
index ab8b4f414a5efddf26f976d9ce62347ade1d9567..3de0ab46720fce42c4729feab729cefe27aa7dcf 100644
Binary files a/assets/img/favicon.ico and b/assets/img/favicon.ico differ