UNPKG

mermaid

Version:

Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.

4 lines 89.4 kB
{ "version": 3, "sources": ["../../../src/diagrams/er/parser/erDiagram.jison", "../../../src/diagrams/er/erDb.ts", "../../../src/diagrams/er/erRenderer-unified.ts", "../../../src/diagrams/er/styles.ts", "../../../src/diagrams/er/erDiagram.ts"], "sourcesContent": ["/* parser generated by jison 0.4.18 */\n/*\n Returns a Parser object of the following structure:\n\n Parser: {\n yy: {}\n }\n\n Parser.prototype: {\n yy: {},\n trace: function(),\n symbols_: {associative list: name ==> number},\n terminals_: {associative list: number ==> name},\n productions_: [...],\n performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),\n table: [...],\n defaultActions: {...},\n parseError: function(str, hash),\n parse: function(input),\n\n lexer: {\n EOF: 1,\n parseError: function(str, hash),\n setInput: function(input),\n input: function(),\n unput: function(str),\n more: function(),\n less: function(n),\n pastInput: function(),\n upcomingInput: function(),\n showPosition: function(),\n test_match: function(regex_match_array, rule_index),\n next: function(),\n lex: function(),\n begin: function(condition),\n popState: function(),\n _currentRules: function(),\n topState: function(),\n pushState: function(condition),\n\n options: {\n ranges: boolean (optional: true ==> token location info will include a .range[] member)\n flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)\n 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)\n },\n\n performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),\n rules: [...],\n conditions: {associative list: name ==> set},\n }\n }\n\n\n token location info (@$, _$, etc.): {\n first_line: n,\n last_line: n,\n first_column: n,\n last_column: n,\n range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based)\n }\n\n\n the parseError function receives a 'hash' object with these members for lexer and parser errors: {\n text: (matched text)\n token: (the produced terminal token, if any)\n line: (yylineno)\n }\n while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {\n loc: (yylloc)\n expected: (string describing the set of expected tokens)\n recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)\n }\n*/\nvar parser = (function(){\nvar o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[6,8,10,22,24,26,28,33,34,35,36,37,40,43,44,48,50,51,52],$V1=[1,10],$V2=[1,11],$V3=[1,12],$V4=[1,13],$V5=[1,23],$V6=[1,24],$V7=[1,25],$V8=[1,26],$V9=[1,27],$Va=[1,19],$Vb=[1,28],$Vc=[1,29],$Vd=[1,20],$Ve=[1,18],$Vf=[1,21],$Vg=[1,22],$Vh=[1,36],$Vi=[1,37],$Vj=[1,38],$Vk=[1,39],$Vl=[1,40],$Vm=[6,8,10,13,15,17,20,21,22,24,26,28,33,34,35,36,37,40,43,44,48,50,51,52,66,67,68,69,70],$Vn=[1,45],$Vo=[1,46],$Vp=[1,55],$Vq=[40,48,50,51,52,71,72],$Vr=[1,66],$Vs=[1,64],$Vt=[1,61],$Vu=[1,65],$Vv=[1,67],$Vw=[6,8,10,13,17,22,24,26,28,33,34,35,36,37,40,41,42,43,44,48,49,50,51,52,66,67,68,69,70],$Vx=[66,67,68,69,70],$Vy=[1,85],$Vz=[1,84],$VA=[1,82],$VB=[1,83],$VC=[6,10,42,47],$VD=[6,10,13,41,42,47,48,49],$VE=[1,93],$VF=[1,92],$VG=[1,91],$VH=[19,58],$VI=[1,102],$VJ=[1,101],$VK=[19,58,61,63];\nvar parser = {trace: function trace () { },\nyy: {},\nsymbols_: {\"error\":2,\"start\":3,\"ER_DIAGRAM\":4,\"document\":5,\"EOF\":6,\"line\":7,\"SPACE\":8,\"statement\":9,\"NEWLINE\":10,\"entityName\":11,\"relSpec\":12,\"COLON\":13,\"role\":14,\"STYLE_SEPARATOR\":15,\"idList\":16,\"BLOCK_START\":17,\"attributes\":18,\"BLOCK_STOP\":19,\"SQS\":20,\"SQE\":21,\"title\":22,\"title_value\":23,\"acc_title\":24,\"acc_title_value\":25,\"acc_descr\":26,\"acc_descr_value\":27,\"acc_descr_multiline_value\":28,\"direction\":29,\"classDefStatement\":30,\"classStatement\":31,\"styleStatement\":32,\"direction_tb\":33,\"direction_bt\":34,\"direction_rl\":35,\"direction_lr\":36,\"CLASSDEF\":37,\"stylesOpt\":38,\"separator\":39,\"UNICODE_TEXT\":40,\"STYLE_TEXT\":41,\"COMMA\":42,\"CLASS\":43,\"STYLE\":44,\"style\":45,\"styleComponent\":46,\"SEMI\":47,\"NUM\":48,\"BRKT\":49,\"ENTITY_NAME\":50,\"DECIMAL_NUM\":51,\"ENTITY_ONE\":52,\"attribute\":53,\"attributeType\":54,\"attributeName\":55,\"attributeKeyTypeList\":56,\"attributeComment\":57,\"ATTRIBUTE_WORD\":58,\"?\":59,\"attributeKeyType\":60,\",\":61,\"ATTRIBUTE_KEY\":62,\"COMMENT\":63,\"cardinality\":64,\"relType\":65,\"ZERO_OR_ONE\":66,\"ZERO_OR_MORE\":67,\"ONE_OR_MORE\":68,\"ONLY_ONE\":69,\"MD_PARENT\":70,\"NON_IDENTIFYING\":71,\"IDENTIFYING\":72,\"WORD\":73,\"$accept\":0,\"$end\":1},\nterminals_: {2:\"error\",4:\"ER_DIAGRAM\",6:\"EOF\",8:\"SPACE\",10:\"NEWLINE\",13:\"COLON\",15:\"STYLE_SEPARATOR\",17:\"BLOCK_START\",19:\"BLOCK_STOP\",20:\"SQS\",21:\"SQE\",22:\"title\",23:\"title_value\",24:\"acc_title\",25:\"acc_title_value\",26:\"acc_descr\",27:\"acc_descr_value\",28:\"acc_descr_multiline_value\",33:\"direction_tb\",34:\"direction_bt\",35:\"direction_rl\",36:\"direction_lr\",37:\"CLASSDEF\",40:\"UNICODE_TEXT\",41:\"STYLE_TEXT\",42:\"COMMA\",43:\"CLASS\",44:\"STYLE\",47:\"SEMI\",48:\"NUM\",49:\"BRKT\",50:\"ENTITY_NAME\",51:\"DECIMAL_NUM\",52:\"ENTITY_ONE\",58:\"ATTRIBUTE_WORD\",59:\"?\",61:\",\",62:\"ATTRIBUTE_KEY\",63:\"COMMENT\",66:\"ZERO_OR_ONE\",67:\"ZERO_OR_MORE\",68:\"ONE_OR_MORE\",69:\"ONLY_ONE\",70:\"MD_PARENT\",71:\"NON_IDENTIFYING\",72:\"IDENTIFYING\",73:\"WORD\"},\nproductions_: [0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,5],[9,9],[9,7],[9,7],[9,4],[9,6],[9,3],[9,5],[9,1],[9,3],[9,7],[9,9],[9,6],[9,8],[9,4],[9,6],[9,2],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[9,1],[29,1],[29,1],[29,1],[29,1],[30,4],[16,1],[16,1],[16,3],[16,3],[31,3],[32,4],[38,1],[38,3],[45,1],[45,2],[39,1],[39,1],[39,1],[46,1],[46,1],[46,1],[46,1],[11,1],[11,1],[11,1],[11,1],[11,1],[18,1],[18,2],[53,2],[53,3],[53,3],[53,4],[54,1],[54,2],[55,1],[56,1],[56,3],[60,1],[57,1],[12,3],[64,1],[64,1],[64,1],[64,1],[64,1],[65,1],[65,1],[14,1],[14,1],[14,1]],\nperformAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {\n/* this == yyval */\n\nvar $0 = $$.length - 1;\nswitch (yystate) {\ncase 1:\n /*console.log('finished parsing');*/ \nbreak;\ncase 2:\n this.$ = [] \nbreak;\ncase 3:\n$$[$0-1].push($$[$0]);this.$ = $$[$0-1]\nbreak;\ncase 4: case 5:\n this.$ = $$[$0] \nbreak;\ncase 6: case 7:\n this.$=[];\nbreak;\ncase 8:\n\n yy.addEntity($$[$0-4]);\n yy.addEntity($$[$0-2]);\n yy.addRelationship($$[$0-4], $$[$0], $$[$0-2], $$[$0-3]);\n \nbreak;\ncase 9:\n\n yy.addEntity($$[$0-8]);\n yy.addEntity($$[$0-4]);\n yy.addRelationship($$[$0-8], $$[$0], $$[$0-4], $$[$0-5]);\n yy.setClass([$$[$0-8]], $$[$0-6]);\n yy.setClass([$$[$0-4]], $$[$0-2]);\n \nbreak;\ncase 10:\n\n yy.addEntity($$[$0-6]);\n yy.addEntity($$[$0-2]);\n yy.addRelationship($$[$0-6], $$[$0], $$[$0-2], $$[$0-3]);\n yy.setClass([$$[$0-6]], $$[$0-4]);\n \nbreak;\ncase 11:\n\n yy.addEntity($$[$0-6]);\n yy.addEntity($$[$0-4]);\n yy.addRelationship($$[$0-6], $$[$0], $$[$0-4], $$[$0-5]);\n yy.setClass([$$[$0-4]], $$[$0-2]);\n \nbreak;\ncase 12:\n\n yy.addEntity($$[$0-3]);\n yy.addAttributes($$[$0-3], $$[$0-1]);\n \nbreak;\ncase 13:\n\n yy.addEntity($$[$0-5]);\n yy.addAttributes($$[$0-5], $$[$0-1]);\n yy.setClass([$$[$0-5]], $$[$0-3]);\n \nbreak;\ncase 14:\n yy.addEntity($$[$0-2]); \nbreak;\ncase 15:\n yy.addEntity($$[$0-4]); yy.setClass([$$[$0-4]], $$[$0-2]); \nbreak;\ncase 16:\n yy.addEntity($$[$0]); \nbreak;\ncase 17:\n yy.addEntity($$[$0-2]); yy.setClass([$$[$0-2]], $$[$0]); \nbreak;\ncase 18:\n\n yy.addEntity($$[$0-6], $$[$0-4]);\n yy.addAttributes($$[$0-6], $$[$0-1]);\n \nbreak;\ncase 19:\n\n yy.addEntity($$[$0-8], $$[$0-6]);\n yy.addAttributes($$[$0-8], $$[$0-1]);\n yy.setClass([$$[$0-8]], $$[$0-3]);\n\n \nbreak;\ncase 20:\n yy.addEntity($$[$0-5], $$[$0-3]); \nbreak;\ncase 21:\n yy.addEntity($$[$0-7], $$[$0-5]); yy.setClass([$$[$0-7]], $$[$0-2]); \nbreak;\ncase 22:\n yy.addEntity($$[$0-3], $$[$0-1]); \nbreak;\ncase 23:\n yy.addEntity($$[$0-5], $$[$0-3]); yy.setClass([$$[$0-5]], $$[$0]); \nbreak;\ncase 24: case 25:\n this.$=$$[$0].trim();yy.setAccTitle(this.$); \nbreak;\ncase 26: case 27:\n this.$=$$[$0].trim();yy.setAccDescription(this.$); \nbreak;\ncase 32:\n yy.setDirection('TB');\nbreak;\ncase 33:\n yy.setDirection('BT');\nbreak;\ncase 34:\n yy.setDirection('RL');\nbreak;\ncase 35:\n yy.setDirection('LR');\nbreak;\ncase 36:\nthis.$ = $$[$0-3];yy.addClass($$[$0-2],$$[$0-1]);\nbreak;\ncase 37: case 38: case 59: case 68:\n this.$ = [$$[$0]]; \nbreak;\ncase 39: case 40:\n this.$ = $$[$0-2].concat([$$[$0]]); \nbreak;\ncase 41:\nthis.$ = $$[$0-2];yy.setClass($$[$0-1], $$[$0]);\nbreak;\ncase 42:\n;this.$ = $$[$0-3];yy.addCssStyles($$[$0-2],$$[$0-1]);\nbreak;\ncase 43:\n this.$ = [$$[$0]] \nbreak;\ncase 44:\n$$[$0-2].push($$[$0]);this.$ = $$[$0-2];\nbreak;\ncase 46:\n this.$ = $$[$0-1] + $$[$0]; \nbreak;\ncase 54: case 80: case 81:\n this.$ = $$[$0].replace(/\"/g, ''); \nbreak;\ncase 55: case 56: case 57: case 58: case 82:\n this.$ = $$[$0]; \nbreak;\ncase 60:\n $$[$0].push($$[$0-1]); this.$=$$[$0]; \nbreak;\ncase 61:\n this.$ = { type: $$[$0-1], name: $$[$0] }; \nbreak;\ncase 62:\n this.$ = { type: $$[$0-2], name: $$[$0-1], keys: $$[$0] }; \nbreak;\ncase 63:\n this.$ = { type: $$[$0-2], name: $$[$0-1], comment: $$[$0] }; \nbreak;\ncase 64:\n this.$ = { type: $$[$0-3], name: $$[$0-2], keys: $$[$0-1], comment: $$[$0] }; \nbreak;\ncase 65: case 67: case 70:\n this.$=$$[$0]; \nbreak;\ncase 66:\n this.$=$$[$0-1] + $$[$0]; \nbreak;\ncase 69:\n $$[$0-2].push($$[$0]); this.$ = $$[$0-2]; \nbreak;\ncase 71:\n this.$=$$[$0].replace(/\"/g, ''); \nbreak;\ncase 72:\n\n this.$ = { cardA: $$[$0], relType: $$[$0-1], cardB: $$[$0-2] };\n /*console.log('relSpec: ' + $$[$0] + $$[$0-1] + $$[$0-2]);*/\n \nbreak;\ncase 73:\n this.$ = yy.Cardinality.ZERO_OR_ONE; \nbreak;\ncase 74:\n this.$ = yy.Cardinality.ZERO_OR_MORE; \nbreak;\ncase 75:\n this.$ = yy.Cardinality.ONE_OR_MORE; \nbreak;\ncase 76:\n this.$ = yy.Cardinality.ONLY_ONE; \nbreak;\ncase 77:\n this.$ = yy.Cardinality.MD_PARENT; \nbreak;\ncase 78:\n this.$ = yy.Identification.NON_IDENTIFYING; \nbreak;\ncase 79:\n this.$ = yy.Identification.IDENTIFYING; \nbreak;\n}\n},\ntable: [{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:9,22:$V1,24:$V2,26:$V3,28:$V4,29:14,30:15,31:16,32:17,33:$V5,34:$V6,35:$V7,36:$V8,37:$V9,40:$Va,43:$Vb,44:$Vc,48:$Vd,50:$Ve,51:$Vf,52:$Vg},o($V0,[2,7],{1:[2,1]}),o($V0,[2,3]),{9:30,11:9,22:$V1,24:$V2,26:$V3,28:$V4,29:14,30:15,31:16,32:17,33:$V5,34:$V6,35:$V7,36:$V8,37:$V9,40:$Va,43:$Vb,44:$Vc,48:$Vd,50:$Ve,51:$Vf,52:$Vg},o($V0,[2,5]),o($V0,[2,6]),o($V0,[2,16],{12:31,64:35,15:[1,32],17:[1,33],20:[1,34],66:$Vh,67:$Vi,68:$Vj,69:$Vk,70:$Vl}),{23:[1,41]},{25:[1,42]},{27:[1,43]},o($V0,[2,27]),o($V0,[2,28]),o($V0,[2,29]),o($V0,[2,30]),o($V0,[2,31]),o($Vm,[2,54]),o($Vm,[2,55]),o($Vm,[2,56]),o($Vm,[2,57]),o($Vm,[2,58]),o($V0,[2,32]),o($V0,[2,33]),o($V0,[2,34]),o($V0,[2,35]),{16:44,40:$Vn,41:$Vo},{16:47,40:$Vn,41:$Vo},{16:48,40:$Vn,41:$Vo},o($V0,[2,4]),{11:49,40:$Va,48:$Vd,50:$Ve,51:$Vf,52:$Vg},{16:50,40:$Vn,41:$Vo},{18:51,19:[1,52],53:53,54:54,58:$Vp},{11:56,40:$Va,48:$Vd,50:$Ve,51:$Vf,52:$Vg},{65:57,71:[1,58],72:[1,59]},o($Vq,[2,73]),o($Vq,[2,74]),o($Vq,[2,75]),o($Vq,[2,76]),o($Vq,[2,77]),o($V0,[2,24]),o($V0,[2,25]),o($V0,[2,26]),{13:$Vr,38:60,41:$Vs,42:$Vt,45:62,46:63,48:$Vu,49:$Vv},o($Vw,[2,37]),o($Vw,[2,38]),{16:68,40:$Vn,41:$Vo,42:$Vt},{13:$Vr,38:69,41:$Vs,42:$Vt,45:62,46:63,48:$Vu,49:$Vv},{13:[1,70],15:[1,71]},o($V0,[2,17],{64:35,12:72,17:[1,73],42:$Vt,66:$Vh,67:$Vi,68:$Vj,69:$Vk,70:$Vl}),{19:[1,74]},o($V0,[2,14]),{18:75,19:[2,59],53:53,54:54,58:$Vp},{55:76,58:[1,77]},{58:[2,65],59:[1,78]},{21:[1,79]},{64:80,66:$Vh,67:$Vi,68:$Vj,69:$Vk,70:$Vl},o($Vx,[2,78]),o($Vx,[2,79]),{6:$Vy,10:$Vz,39:81,42:$VA,47:$VB},{40:[1,86],41:[1,87]},o($VC,[2,43],{46:88,13:$Vr,41:$Vs,48:$Vu,49:$Vv}),o($VD,[2,45]),o($VD,[2,50]),o($VD,[2,51]),o($VD,[2,52]),o($VD,[2,53]),o($V0,[2,41],{42:$Vt}),{6:$Vy,10:$Vz,39:89,42:$VA,47:$VB},{14:90,40:$VE,50:$VF,73:$VG},{16:94,40:$Vn,41:$Vo},{11:95,40:$Va,48:$Vd,50:$Ve,51:$Vf,52:$Vg},{18:96,19:[1,97],53:53,54:54,58:$Vp},o($V0,[2,12]),{19:[2,60]},o($VH,[2,61],{56:98,57:99,60:100,62:$VI,63:$VJ}),o([19,58,62,63],[2,67]),{58:[2,66]},o($V0,[2,22],{15:[1,104],17:[1,103]}),o([40,48,50,51,52],[2,72]),o($V0,[2,36]),{13:$Vr,41:$Vs,45:105,46:63,48:$Vu,49:$Vv},o($V0,[2,47]),o($V0,[2,48]),o($V0,[2,49]),o($Vw,[2,39]),o($Vw,[2,40]),o($VD,[2,46]),o($V0,[2,42]),o($V0,[2,8]),o($V0,[2,80]),o($V0,[2,81]),o($V0,[2,82]),{13:[1,106],42:$Vt},{13:[1,108],15:[1,107]},{19:[1,109]},o($V0,[2,15]),o($VH,[2,62],{57:110,61:[1,111],63:$VJ}),o($VH,[2,63]),o($VK,[2,68]),o($VH,[2,71]),o($VK,[2,70]),{18:112,19:[1,113],53:53,54:54,58:$Vp},{16:114,40:$Vn,41:$Vo},o($VC,[2,44],{46:88,13:$Vr,41:$Vs,48:$Vu,49:$Vv}),{14:115,40:$VE,50:$VF,73:$VG},{16:116,40:$Vn,41:$Vo},{14:117,40:$VE,50:$VF,73:$VG},o($V0,[2,13]),o($VH,[2,64]),{60:118,62:$VI},{19:[1,119]},o($V0,[2,20]),o($V0,[2,23],{17:[1,120],42:$Vt}),o($V0,[2,11]),{13:[1,121],42:$Vt},o($V0,[2,10]),o($VK,[2,69]),o($V0,[2,18]),{18:122,19:[1,123],53:53,54:54,58:$Vp},{14:124,40:$VE,50:$VF,73:$VG},{19:[1,125]},o($V0,[2,21]),o($V0,[2,9]),o($V0,[2,19])],\ndefaultActions: {75:[2,60],78:[2,66]},\nparseError: function parseError (str, hash) {\n if (hash.recoverable) {\n this.trace(str);\n } else {\n var error = new Error(str);\n error.hash = hash;\n throw error;\n }\n},\nparse: function parse(input) {\n var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\n var args = lstack.slice.call(arguments, 1);\n var lexer = Object.create(this.lexer);\n var sharedState = { yy: {} };\n for (var k in this.yy) {\n if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\n sharedState.yy[k] = this.yy[k];\n }\n }\n lexer.setInput(input, sharedState.yy);\n sharedState.yy.lexer = lexer;\n sharedState.yy.parser = this;\n if (typeof lexer.yylloc == 'undefined') {\n lexer.yylloc = {};\n }\n var yyloc = lexer.yylloc;\n lstack.push(yyloc);\n var ranges = lexer.options && lexer.options.ranges;\n if (typeof sharedState.yy.parseError === 'function') {\n this.parseError = sharedState.yy.parseError;\n } else {\n this.parseError = Object.getPrototypeOf(this).parseError;\n }\n function popStack(n) {\n stack.length = stack.length - 2 * n;\n vstack.length = vstack.length - n;\n lstack.length = lstack.length - n;\n }\n function lex() {\n var token;\n token = tstack.pop() || lexer.lex() || EOF;\n if (typeof token !== 'number') {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n token = self.symbols_[token] || token;\n }\n return token;\n }\n var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;\n while (true) {\n state = stack[stack.length - 1];\n if (this.defaultActions[state]) {\n action = this.defaultActions[state];\n } else {\n if (symbol === null || typeof symbol == 'undefined') {\n symbol = lex();\n }\n action = table[state] && table[state][symbol];\n }\n if (typeof action === 'undefined' || !action.length || !action[0]) {\n var errStr = '';\n expected = [];\n for (p in table[state]) {\n if (this.terminals_[p] && p > TERROR) {\n expected.push('\\'' + this.terminals_[p] + '\\'');\n }\n }\n if (lexer.showPosition) {\n errStr = 'Parse error on line ' + (yylineno + 1) + ':\\n' + lexer.showPosition() + '\\nExpecting ' + expected.join(', ') + ', got \\'' + (this.terminals_[symbol] || symbol) + '\\'';\n } else {\n errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\\'' + (this.terminals_[symbol] || symbol) + '\\'');\n }\n this.parseError(errStr, {\n text: lexer.match,\n token: this.terminals_[symbol] || symbol,\n line: lexer.yylineno,\n loc: yyloc,\n expected: expected\n });\n }\n if (action[0] instanceof Array && action.length > 1) {\n throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);\n }\n switch (action[0]) {\n case 1:\n stack.push(symbol);\n vstack.push(lexer.yytext);\n lstack.push(lexer.yylloc);\n stack.push(action[1]);\n symbol = null;\n if (!preErrorSymbol) {\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n if (recovering > 0) {\n recovering--;\n }\n } else {\n symbol = preErrorSymbol;\n preErrorSymbol = null;\n }\n break;\n case 2:\n len = this.productions_[action[1]][1];\n yyval.$ = vstack[vstack.length - len];\n yyval._$ = {\n first_line: lstack[lstack.length - (len || 1)].first_line,\n last_line: lstack[lstack.length - 1].last_line,\n first_column: lstack[lstack.length - (len || 1)].first_column,\n last_column: lstack[lstack.length - 1].last_column\n };\n if (ranges) {\n yyval._$.range = [\n lstack[lstack.length - (len || 1)].range[0],\n lstack[lstack.length - 1].range[1]\n ];\n }\n r = this.performAction.apply(yyval, [\n yytext,\n yyleng,\n yylineno,\n sharedState.yy,\n action[1],\n vstack,\n lstack\n ].concat(args));\n if (typeof r !== 'undefined') {\n return r;\n }\n if (len) {\n stack = stack.slice(0, -1 * len * 2);\n vstack = vstack.slice(0, -1 * len);\n lstack = lstack.slice(0, -1 * len);\n }\n stack.push(this.productions_[action[1]][0]);\n vstack.push(yyval.$);\n lstack.push(yyval._$);\n newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\n stack.push(newState);\n break;\n case 3:\n return true;\n }\n }\n return true;\n}};\n\n/* generated by jison-lex 0.3.4 */\nvar lexer = (function(){\nvar lexer = ({\n\nEOF:1,\n\nparseError:function parseError(str, hash) {\n if (this.yy.parser) {\n this.yy.parser.parseError(str, hash);\n } else {\n throw new Error(str);\n }\n },\n\n// resets the lexer, sets new input\nsetInput:function (input, yy) {\n this.yy = yy || this.yy || {};\n this._input = input;\n this._more = this._backtrack = this.done = false;\n this.yylineno = this.yyleng = 0;\n this.yytext = this.matched = this.match = '';\n this.conditionStack = ['INITIAL'];\n this.yylloc = {\n first_line: 1,\n first_column: 0,\n last_line: 1,\n last_column: 0\n };\n if (this.options.ranges) {\n this.yylloc.range = [0,0];\n }\n this.offset = 0;\n return this;\n },\n\n// consumes and returns one char from the input\ninput:function () {\n var ch = this._input[0];\n this.yytext += ch;\n this.yyleng++;\n this.offset++;\n this.match += ch;\n this.matched += ch;\n var lines = ch.match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno++;\n this.yylloc.last_line++;\n } else {\n this.yylloc.last_column++;\n }\n if (this.options.ranges) {\n this.yylloc.range[1]++;\n }\n\n this._input = this._input.slice(1);\n return ch;\n },\n\n// unshifts one char (or a string) into the input\nunput:function (ch) {\n var len = ch.length;\n var lines = ch.split(/(?:\\r\\n?|\\n)/g);\n\n this._input = ch + this._input;\n this.yytext = this.yytext.substr(0, this.yytext.length - len);\n //this.yyleng -= len;\n this.offset -= len;\n var oldLines = this.match.split(/(?:\\r\\n?|\\n)/g);\n this.match = this.match.substr(0, this.match.length - 1);\n this.matched = this.matched.substr(0, this.matched.length - 1);\n\n if (lines.length - 1) {\n this.yylineno -= lines.length - 1;\n }\n var r = this.yylloc.range;\n\n this.yylloc = {\n first_line: this.yylloc.first_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.first_column,\n last_column: lines ?\n (lines.length === oldLines.length ? this.yylloc.first_column : 0)\n + oldLines[oldLines.length - lines.length].length - lines[0].length :\n this.yylloc.first_column - len\n };\n\n if (this.options.ranges) {\n this.yylloc.range = [r[0], r[0] + this.yyleng - len];\n }\n this.yyleng = this.yytext.length;\n return this;\n },\n\n// When called from action, caches matched text and appends it on next action\nmore:function () {\n this._more = true;\n return this;\n },\n\n// 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.\nreject:function () {\n if (this.options.backtrack_lexer) {\n this._backtrack = true;\n } else {\n 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(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n\n }\n return this;\n },\n\n// retain first n characters of the match\nless:function (n) {\n this.unput(this.match.slice(n));\n },\n\n// displays already matched input, i.e. for error messages\npastInput:function () {\n var past = this.matched.substr(0, this.matched.length - this.match.length);\n return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\\n/g, \"\");\n },\n\n// displays upcoming input, i.e. for error messages\nupcomingInput:function () {\n var next = this.match;\n if (next.length < 20) {\n next += this._input.substr(0, 20-next.length);\n }\n return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\\n/g, \"\");\n },\n\n// displays the character position where the lexing error occurred, i.e. for error messages\nshowPosition:function () {\n var pre = this.pastInput();\n var c = new Array(pre.length + 1).join(\"-\");\n return pre + this.upcomingInput() + \"\\n\" + c + \"^\";\n },\n\n// test the lexed token: return FALSE when not a match, otherwise return token\ntest_match:function(match, indexed_rule) {\n var token,\n lines,\n backup;\n\n if (this.options.backtrack_lexer) {\n // save context\n backup = {\n yylineno: this.yylineno,\n yylloc: {\n first_line: this.yylloc.first_line,\n last_line: this.last_line,\n first_column: this.yylloc.first_column,\n last_column: this.yylloc.last_column\n },\n yytext: this.yytext,\n match: this.match,\n matches: this.matches,\n matched: this.matched,\n yyleng: this.yyleng,\n offset: this.offset,\n _more: this._more,\n _input: this._input,\n yy: this.yy,\n conditionStack: this.conditionStack.slice(0),\n done: this.done\n };\n if (this.options.ranges) {\n backup.yylloc.range = this.yylloc.range.slice(0);\n }\n }\n\n lines = match[0].match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno += lines.length;\n }\n this.yylloc = {\n first_line: this.yylloc.last_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.last_column,\n last_column: lines ?\n lines[lines.length - 1].length - lines[lines.length - 1].match(/\\r?\\n?/)[0].length :\n this.yylloc.last_column + match[0].length\n };\n this.yytext += match[0];\n this.match += match[0];\n this.matches = match;\n this.yyleng = this.yytext.length;\n if (this.options.ranges) {\n this.yylloc.range = [this.offset, this.offset += this.yyleng];\n }\n this._more = false;\n this._backtrack = false;\n this._input = this._input.slice(match[0].length);\n this.matched += match[0];\n token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);\n if (this.done && this._input) {\n this.done = false;\n }\n if (token) {\n return token;\n } else if (this._backtrack) {\n // recover context\n for (var k in backup) {\n this[k] = backup[k];\n }\n return false; // rule action called reject() implying the next rule should be tested instead.\n }\n return false;\n },\n\n// return next match in input\nnext:function () {\n if (this.done) {\n return this.EOF;\n }\n if (!this._input) {\n this.done = true;\n }\n\n var token,\n match,\n tempMatch,\n index;\n if (!this._more) {\n this.yytext = '';\n this.match = '';\n }\n var rules = this._currentRules();\n for (var i = 0; i < rules.length; i++) {\n tempMatch = this._input.match(this.rules[rules[i]]);\n if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {\n match = tempMatch;\n index = i;\n if (this.options.backtrack_lexer) {\n token = this.test_match(tempMatch, rules[i]);\n if (token !== false) {\n return token;\n } else if (this._backtrack) {\n match = false;\n continue; // rule action called reject() implying a rule MISmatch.\n } else {\n // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)\n return false;\n }\n } else if (!this.options.flex) {\n break;\n }\n }\n }\n if (match) {\n token = this.test_match(match, rules[index]);\n if (token !== false) {\n return token;\n }\n // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)\n return false;\n }\n if (this._input === \"\") {\n return this.EOF;\n } else {\n return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\\n' + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n },\n\n// return next match that has a token\nlex:function lex () {\n var r = this.next();\n if (r) {\n return r;\n } else {\n return this.lex();\n }\n },\n\n// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)\nbegin:function begin (condition) {\n this.conditionStack.push(condition);\n },\n\n// pop the previously active lexer condition state off the condition stack\npopState:function popState () {\n var n = this.conditionStack.length - 1;\n if (n > 0) {\n return this.conditionStack.pop();\n } else {\n return this.conditionStack[0];\n }\n },\n\n// produce the lexer rule set which is active for the currently active lexer condition state\n_currentRules:function _currentRules () {\n if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {\n return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;\n } else {\n return this.conditions[\"INITIAL\"].rules;\n }\n },\n\n// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available\ntopState:function topState (n) {\n n = this.conditionStack.length - 1 - Math.abs(n || 0);\n if (n >= 0) {\n return this.conditionStack[n];\n } else {\n return \"INITIAL\";\n }\n },\n\n// alias for begin(condition)\npushState:function pushState (condition) {\n this.begin(condition);\n },\n\n// return the number of states currently on the stack\nstateStackSize:function stateStackSize() {\n return this.conditionStack.length;\n },\noptions: {\"case-insensitive\":true},\nperformAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {\nvar YYSTATE=YY_START;\nswitch($avoiding_name_collisions) {\ncase 0: this.begin(\"acc_title\");return 24; \nbreak;\ncase 1: this.popState(); return \"acc_title_value\"; \nbreak;\ncase 2: this.begin(\"acc_descr\");return 26; \nbreak;\ncase 3: this.popState(); return \"acc_descr_value\"; \nbreak;\ncase 4: this.begin(\"acc_descr_multiline\");\nbreak;\ncase 5: this.popState(); \nbreak;\ncase 6:return \"acc_descr_multiline_value\";\nbreak;\ncase 7:return 33;\nbreak;\ncase 8:return 34;\nbreak;\ncase 9:return 35;\nbreak;\ncase 10:return 36;\nbreak;\ncase 11:return 10;\nbreak;\ncase 12:/* skip whitespace */\nbreak;\ncase 13:return 8;\nbreak;\ncase 14:return 50;\nbreak;\ncase 15:return 73;\nbreak;\ncase 16:return 4;\nbreak;\ncase 17: this.begin(\"block\"); return 17; \nbreak;\ncase 18:return 49;\nbreak;\ncase 19:return 49;\nbreak;\ncase 20:return 42;\nbreak;\ncase 21:return 15;\nbreak;\ncase 22:return 13;\nbreak;\ncase 23:/* skip whitespace in block */\nbreak;\ncase 24:return 62\nbreak;\ncase 25:return 58;\nbreak;\ncase 26:return 58;\nbreak;\ncase 27: this.begin(\"block_bq\"); \nbreak;\ncase 28:return 58;\nbreak;\ncase 29: this.popState(); \nbreak;\ncase 30:return 63;\nbreak;\ncase 31:/* nothing */\nbreak;\ncase 32: this.popState(); return 19; \nbreak;\ncase 33:return yy_.yytext[0];\nbreak;\ncase 34:return 20;\nbreak;\ncase 35:return 21;\nbreak;\ncase 36: this.begin(\"style\"); return 44; \nbreak;\ncase 37: this.popState(); return 10; \nbreak;\ncase 38:/* skip whitespace in block */\nbreak;\ncase 39:return 13;\nbreak;\ncase 40:return 42;\nbreak;\ncase 41:return 49;\nbreak;\ncase 42: this.begin(\"style\"); return 37; \nbreak;\ncase 43:return 43;\nbreak;\ncase 44:return 66;\nbreak;\ncase 45:return 68;\nbreak;\ncase 46:return 68;\nbreak;\ncase 47:return 68;\nbreak;\ncase 48:return 66;\nbreak;\ncase 49:return 66;\nbreak;\ncase 50:return 67;\nbreak;\ncase 51:return 67;\nbreak;\ncase 52:return 67;\nbreak;\ncase 53:return 67;\nbreak;\ncase 54:return 67;\nbreak;\ncase 55:return 68;\nbreak;\ncase 56:return 67;\nbreak;\ncase 57:return 68;\nbreak;\ncase 58:return 69;\nbreak;\ncase 59:return 69;\nbreak;\ncase 60:return 51;\nbreak;\ncase 61:return 69;\nbreak;\ncase 62:return 69;\nbreak;\ncase 63:return 69;\nbreak;\ncase 64:return 52;\nbreak;\ncase 65:return 48;\nbreak;\ncase 66:return 69;\nbreak;\ncase 67:return 66;\nbreak;\ncase 68:return 67;\nbreak;\ncase 69:return 68;\nbreak;\ncase 70:return 70;\nbreak;\ncase 71:return 71;\nbreak;\ncase 72:return 72;\nbreak;\ncase 73:return 72;\nbreak;\ncase 74:return 71;\nbreak;\ncase 75:return 71;\nbreak;\ncase 76:return 71;\nbreak;\ncase 77:return 41;\nbreak;\ncase 78:return 47;\nbreak;\ncase 79:return 40;\nbreak;\ncase 80:return yy_.yytext[0];\nbreak;\ncase 81:return 6;\nbreak;\n}\n},\nrules: [/^(?:accTitle\\s*:\\s*)/i,/^(?:(?!\\n||)*[^\\n]*)/i,/^(?:accDescr\\s*:\\s*)/i,/^(?:(?!\\n||)*[^\\n]*)/i,/^(?:accDescr\\s*\\{\\s*)/i,/^(?:[\\}])/i,/^(?:[^\\}]*)/i,/^(?:.*direction\\s+TB[^\\n]*)/i,/^(?:.*direction\\s+BT[^\\n]*)/i,/^(?:.*direction\\s+RL[^\\n]*)/i,/^(?:.*direction\\s+LR[^\\n]*)/i,/^(?:[\\n]+)/i,/^(?:\\s+)/i,/^(?:[\\s]+)/i,/^(?:\"[^\"%\\r\\n\\v\\b\\\\]+\")/i,/^(?:\"[^\"]*\")/i,/^(?:erDiagram\\b)/i,/^(?:\\{)/i,/^(?:#)/i,/^(?:#)/i,/^(?:,)/i,/^(?::::)/i,/^(?::)/i,/^(?:\\s+)/i,/^(?:\\b((?:PK)|(?:FK)|(?:UK))\\b)/i,/^(?:([^\\s]*)[~].*[~]([^\\s]*))/i,/^(?:([\\*A-Za-z_\\u00C0-\\uFFFF][A-Za-z0-9\\-\\_\\[\\]\\(\\)\\.,\\u00C0-\\uFFFF\\*]*))/i,/^(?:[`])/i,/^(?:[^`]+)/i,/^(?:[`])/i,/^(?:\"[^\"]*\")/i,/^(?:[\\n]+)/i,/^(?:\\})/i,/^(?:.)/i,/^(?:\\[)/i,/^(?:\\])/i,/^(?:style\\b)/i,/^(?:[\\n]+)/i,/^(?:\\s+)/i,/^(?::)/i,/^(?:,)/i,/^(?:#)/i,/^(?:classDef\\b)/i,/^(?:class\\b)/i,/^(?:one or zero\\b)/i,/^(?:one or more\\b)/i,/^(?:one or many\\b)/i,/^(?:1\\+)/i,/^(?:\\|o\\b)/i,/^(?:zero or one\\b)/i,/^(?:zero or more\\b)/i,/^(?:zero or many\\b)/i,/^(?:0\\+)/i,/^(?:\\}o\\b)/i,/^(?:many\\(0\\))/i,/^(?:many\\(1\\))/i,/^(?:many\\b)/i,/^(?:\\}\\|)/i,/^(?:one\\b)/i,/^(?:only one\\b)/i,/^(?:[0-9]+\\.[0-9]+)/i,/^(?:1(?=\\s+[A-Za-z_\"']))/i,/^(?:1(?=\\s+[0-9]))/i,/^(?:1(?=(--|\\.\\.|\\.-|-\\.)))/i,/^(?:1\\b)/i,/^(?:[0-9]+)/i,/^(?:\\|\\|)/i,/^(?:o\\|)/i,/^(?:o\\{)/i,/^(?:\\|\\{)/i,/^(?:u(?=[\\.\\-\\|]))/i,/^(?:\\.\\.)/i,/^(?:--)/i,/^(?:to\\b)/i,/^(?:optionally to\\b)/i,/^(?:\\.-)/i,/^(?:-\\.)/i,/^(?:([^\\x00-\\x7F]|\\w|-|\\*)+)/i,/^(?:;)/i,/^(?:([^\\x00-\\x7F]|\\w|-|\\*|\\.)+)/i,/^(?:.)/i,/^(?:$)/i],\nconditions: {\"style\":{\"rules\":[37,38,39,40,41,77,78],\"inclusive\":false},\"acc_descr_multiline\":{\"rules\":[5,6],\"inclusive\":false},\"acc_descr\":{\"rules\":[3],\"inclusive\":false},\"acc_title\":{\"rules\":[1],\"inclusive\":false},\"block_bq\":{\"rules\":[28,29],\"inclusive\":false},\"block\":{\"rules\":[23,24,25,26,27,30,31,32,33],\"inclusive\":false},\"INITIAL\":{\"rules\":[0,2,4,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,34,35,36,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,71,72,73,74,75,76,79,80,81],\"inclusive\":true}}\n});\nreturn lexer;\n})();\nparser.lexer = lexer;\nfunction Parser () {\n this.yy = {};\n}\nParser.prototype = parser;parser.Parser = Parser;\nreturn new Parser;\n})(); \n\tparser.parser = parser;\n\texport { parser };\n\texport default parser;\n\t", "import { log } from '../../logger.js';\nimport { getConfig } from '../../diagram-api/diagramAPI.js';\nimport type { Edge, Node } from '../../rendering-util/types.js';\nimport type { EntityNode, Attribute, Relationship, EntityClass, RelSpec } from './erTypes.js';\nimport {\n setAccTitle,\n getAccTitle,\n getAccDescription,\n setAccDescription,\n clear as commonClear,\n setDiagramTitle,\n getDiagramTitle,\n} from '../common/commonDb.js';\nimport { getEdgeId } from '../../utils.js';\nimport type { DiagramDB } from '../../diagram-api/types.js';\n\nexport class ErDB implements DiagramDB {\n private entities = new Map<string, EntityNode>();\n private relationships: Relationship[] = [];\n private classes = new Map<string, EntityClass>();\n private direction = 'TB';\n\n private Cardinality = {\n ZERO_OR_ONE: 'ZERO_OR_ONE',\n ZERO_OR_MORE: 'ZERO_OR_MORE',\n ONE_OR_MORE: 'ONE_OR_MORE',\n ONLY_ONE: 'ONLY_ONE',\n MD_PARENT: 'MD_PARENT',\n };\n\n private Identification = {\n NON_IDENTIFYING: 'NON_IDENTIFYING',\n IDENTIFYING: 'IDENTIFYING',\n };\n\n constructor() {\n this.clear();\n this.addEntity = this.addEntity.bind(this);\n this.addAttributes = this.addAttributes.bind(this);\n this.addRelationship = this.addRelationship.bind(this);\n this.setDirection = this.setDirection.bind(this);\n this.addCssStyles = this.addCssStyles.bind(this);\n this.addClass = this.addClass.bind(this);\n this.setClass = this.setClass.bind(this);\n this.setAccTitle = this.setAccTitle.bind(this);\n this.setAccDescription = this.setAccDescription.bind(this);\n }\n\n /**\n * Add entity\n * @param name - The name of the entity\n * @param alias - The alias of the entity\n */\n public addEntity(name: string, alias = ''): EntityNode {\n if (!this.entities.has(name)) {\n this.entities.set(name, {\n id: `entity-${name}-${this.entities.size}`,\n label: name,\n attributes: [],\n alias,\n shape: 'erBox',\n look: getConfig().look ?? 'default',\n cssClasses: 'default',\n cssStyles: [],\n labelType: 'markdown',\n });\n log.info('Added new entity :', name);\n } else if (!this.entities.get(name)?.alias && alias) {\n this.entities.get(name)!.alias = alias;\n log.info(`Add alias '${alias}' to entity '${name}'`);\n }\n\n return this.entities.get(name)!;\n }\n\n public getEntity(name: string) {\n return this.entities.get(name);\n }\n\n public getEntities() {\n return this.entities;\n }\n\n public getClasses() {\n return this.classes;\n }\n\n public addAttributes(entityName: string, attribs: Attribute[]) {\n const entity = this.addEntity(entityName); // May do nothing (if entity has already been added)\n\n // Process attribs in reverse order due to effect of recursive construction (last attribute is first)\n let i;\n for (i = attribs.length - 1; i >= 0; i--) {\n if (!attribs[i].keys) {\n attribs[i].keys = [];\n }\n if (!attribs[i].comment) {\n attribs[i].comment = '';\n }\n entity.attributes.push(attribs[i]);\n log.debug('Added attribute ', attribs[i].name);\n }\n }\n\n /**\n * Add a relationship\n *\n * @param entA - The first entity in the relationship\n * @param rolA - The role played by the first entity in relation to the second\n * @param entB - The second entity in the relationship\n * @param rSpec - The details of the relationship between the two entities\n */\n public addRelationship(entA: string, rolA: string, entB: string, rSpec: RelSpec) {\n const entityA = this.entities.get(entA);\n const entityB = this.entities.get(entB);\n if (!entityA || !entityB) {\n return;\n }\n\n const rel = {\n entityA: entityA.id,\n roleA: rolA,\n entityB: entityB.id,\n relSpec: rSpec,\n };\n\n this.relationships.push(rel);\n log.debug('Added new relationship :', rel);\n }\n\n public getRelationships() {\n return this.relationships;\n }\n\n public getDirection() {\n return this.direction;\n }\n\n public setDirection(dir: string) {\n this.direction = dir;\n }\n\n private getCompiledStyles(classDefs: string[]) {\n let compiledStyles: string[] = [];\n for (const customClass of classDefs) {\n const cssClass = this.classes.get(customClass);\n if (cssClass?.styles) {\n compiledStyles = [...compiledStyles, ...(cssClass.styles ?? [])].map((s) => s.trim());\n }\n if (cssClass?.textStyles) {\n compiledStyles = [...compiledStyles, ...(cssClass.textStyles ?? [])].map((s) => s.trim());\n }\n }\n return compiledStyles;\n }\n\n public addCssStyles(ids: string[], styles: string[]) {\n for (const id of ids) {\n const entity = this.entities.get(id);\n if (!styles || !entity) {\n return;\n }\n for (const style of styles) {\n entity.cssStyles!.push(style);\n }\n }\n }\n\n public addClass(ids: string[], style: string[]) {\n ids.forEach((id) => {\n let classNode = this.classes.get(id);\n if (classNode === undefined) {\n classNode = { id, styles: [], textStyles: [] };\n this.classes.set(id, classNode);\n }\n\n if (style) {\n style.forEach(function (s) {\n if (/color/.exec(s)) {\n const newStyle = s.replace('fill', 'bgFill');\n classNode.textStyles.push(newStyle);\n }\n classNode.styles.push(s);\n });\n }\n });\n }\n\n public setClass(ids: string[], classNames: string[]) {\n for (const id of ids) {\n const entity = this.entities.get(id);\n if (entity) {\n for (const className of classNames) {\n entity.cssClasses += ' ' + className;\n }\n }\n }\n }\n\n public clear() {\n this.entities = new Map();\n this.classes = new Map();\n this.relationships = [];\n commonClear();\n }\n\n public getData() {\n const nodes: Node[] = [];\n const edges: Edge[] = [];\n const config = getConfig();\n\n let colorIndex = 0;\n for (const entityKey of this.entities.keys()) {\n const entityNode = this.entities.get(entityKey);\n if (entityNode) {\n entityNode.cssCompiledStyles = this.getCompiledStyles(entityNode.cssClasses!.split(' '));\n entityNode.colorIndex = colorIndex++;\n nodes.push(entityNode as unknown as Node);\n }\n }\n\n let count = 0;\n for (const relationship of this.relationships) {\n const edge: Edge = {\n id: getEdgeId(relationship.entityA, relationship.entityB, {\n prefix: 'id',\n counter: count++,\n }),\n type: 'normal',\n curve: 'basis',\n start: relationship.entityA,\n end: relationship.entityB,\n label: relationship.roleA,\n labelpos: 'c',\n thickness: 'normal',\n classes: 'relationshipLine',\n arrowTypeStart: relationship.relSpec.cardB.toLowerCase(),\n arrowTypeEnd: relationship.relSpec.cardA.toLowerCase(),\n pattern: relationship.relSpec.relType == 'IDENTIFYING' ? 'solid' : 'dashed',\n look: config.look,\n labelType: 'markdown',\n };\n edges.push(edge);\n }\n return { nodes, edges, other: {}, config, direction: 'TB' };\n }\n\n public setAccTitle = setAccTitle;\n public getAccTitle = getAccTitle;\n public setAccDescription = setAccDescription;\n public getAccDescription = getAccDescription;\n public setDiagramTitle = setDiagramTitle;\n public getDiagramTitle = getDiagramTitle;\n public getConfig = () => getConfig().er;\n}\n", "import { getConfig } from '../../diagram-api/diagramAPI.js';\nimport { log } from '../../logger.js';\nimport { getDiagramElement } from '../../rendering-util/insertElementsForSize.js';\nimport { getRegisteredLayoutAlgorithm, render } from '../../rendering-util/render.js';\nimport { setupViewPortForSVG } from '../../rendering-util/setupViewPortForSVG.js';\nimport type { LayoutData } from '../../rendering-util/types.js';\nimport utils from '../../utils.js';\nimport { select } from 'd3';\n\nexport const draw = async function (text: string, id: string, _version: string, diag: any) {\n log.info('REF0:');\n log.info('Drawing er diagram (unified)', id);\n const { securityLevel, er: conf, layout } = getConfig();\n\n // The getData method provided in all supported diagrams is used to extract the data from the parsed structure\n // into the Layout data format\n const data4Layout = diag.db.getData() as LayoutData;\n\n // Create the root SVG - the element is the div containing the SVG element\n const svg = getDiagramElement(id, securityLevel);\n\n data4Layout.type = diag.type;\n data4Layout.layoutAlgorithm = getRegisteredLayoutAlgorithm(layout);\n\n // Workaround as when rendering and setting up the graph it uses flowchart spacing before data4Layout spacing?\n data4Layout.config.flowchart!.nodeSpacing = conf?.nodeSpacing || 140;\n data4Layout.config.flowchart!.rankSpacing = conf?.rankSpacing || 80;\n data4Layout.direction = diag.db.getDirection();\n const { config } = data4Layout;\n const { look } = config;\n\n if (look === 'neo') {\n data4Layout.markers = [\n 'only_one_neo',\n 'zero_or_one_neo',\n 'one_or_more_neo',\n 'zero_or_more_neo',\n ];\n } else {\n data4Layout.markers = ['only_one', 'zero_or_one', 'one_or_more', 'zero_or_more'];\n }\n data4Layout.diagramId = id;\n await render(data4Layout, svg);\n // Elk layout algorithm displays markers above nodes, so move edges to top so they are \"painted\" over by the nodes.\n if (data4Layout.layoutAlgorithm === 'elk') {\n svg.select('.edges').lower();\n }\n\n // Sets the background nodes to the same position as their original counterparts.\n // Background nodes are created when the look is handDrawn so the ER diagram markers do not show underneath.\n const backgroundNodes = svg.selectAll('[id*=\"-background\"]');\n // eslint-disable-next-line unicorn/prefer-spread\n if (Array.from(backgroundNodes).length > 0) {\n backgroundNodes.each(function (this: SVGElement) {\n const backgroundNode = select(this);\n const backgroundId = backgroundNode.attr('id');\n\n const nonBackgroundId = backgroundId.replace('-background', '');\n const nonBackgroundNode = svg.select(`#${CSS.escape(nonBackgroundId)}`);\n\n if (!nonBackgroundNode.empty()) {\n const transform = nonBackgroundNode.attr('transform');\n backgroundNode.attr('transform', transform);\n }\n });\n }\n\n const padding = 8;\n utils.insertTitle(\n svg,\n 'erDiagramTitleText',\n conf?.titleTopMargin ?? 25,\n diag.db.getDiagramTitle()\n );\n\n setupViewPortForSVG(svg, padding, 'erDiagram', conf?.useMaxWidth ?? true);\n};\n", "import * as khroma from 'khroma';\nimport type { DiagramStylesProvider } from '../../diagram-api/types.js';\n\nconst fade = (color: string, opacity: number) => {\n // @ts-ignore TODO: incorrect types from khroma\n const channel = khroma.channel;\n\n const r = channel(color, 'r');\n const g = channel(color, 'g');\n const b = channel(color, 'b');\n\n // @ts-ignore incorrect types from khroma\n return khroma.rgba(r, g, b, opacity);\n};\nconst COLOR_THEMES = new Set(['redux-color', 'redux-dark-color']);\n\nconst genColor: DiagramStylesProvider = (options) => {\n const { theme, look, bkgColorArray, borderColorArray } = options;\n if (!COLOR_THEMES.has(theme)) {\n return '';\n }\n const hasBkgColors = bkgColorArray?.length > 0;\n let sections = '';\n\n for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) {\n sections += `\n\n [data-look=\"${look}\"][data-color-id=\"color-${i}\"].node path {\n stroke: ${borderColorArray[i]};\n ${hasBkgColors ? `fill: ${bkgColorArray[i]};` : ''}\n }\n\n [data-look=\"${look}\"][data-color-id=\"color-${i}\"].node rect {\n stroke: ${borderColorArray[i]};\n ${hasBkgColors ? `fill: ${bkgColorArray[i]};` : ''}\n }\n `;\n }\n return sections;\n};\n\nconst getStyles: DiagramStylesProvider = (options) => {\n const { look, theme, erEdgeLabelBackground, strokeWidth } = options;\n return `\n ${genColor(options)}\n .entityBox {\n fill: ${options.mainBkg};\n stroke: ${options.nodeBorder};\n }\n\n .relationshipLabelBox {\n fill: ${options.tertiaryColor};\n opacity: 0.7;\n background-color: ${options.tertiaryColor};\n rect {\n opacity: 0.5;\n }\n }\n\n .labelBkg {\n background-color: ${COLOR_THEMES.has(theme) && erEdgeLabelBackground ? erEdgeLabelBackground : fade(options.tertiaryColor, 0.5)};\n }\n\n .edgeLabel {\n background-color: ${COLOR_THEMES.has(theme) && erEdgeLabelBackground ? erEdgeLabelBackground : options.edgeLabelBackground};\n }\n .edgeLabel .label rect {\n fill: ${COLOR_THEMES.has(theme) && erEdgeLabelBackground ? erEdgeLabelBackground : options.edgeLabelBackground};\n }\n .edgeLabel .label text {\n fill: ${options.textColor};\n }\n\n .edgeLabel .label {\n fill: ${options.nodeBorder};\n font-size: 14px;\n }\n\n .label {\n font-family: ${options.fontFamily};\n color: ${options.nodeTextColor || options.textColor};\n }\n\n .edge-pattern-dashed {\n stroke-dasharray: 8,8;\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon\n {\n fill: ${options.mainBkg};\n stroke: ${options.nodeBorder};\n stroke-width: ${look === 'neo' ? strokeWidth : '1px'};\n }\n\n .relationshipLine {\n stroke: ${options.lineColor};\n stroke-width: ${look === 'neo' ? strokeWidth