mermaid
Version:
Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.
1,462 lines • 67.5 kB
JavaScript
import { sanitizeUrl } from "@braintree/sanitize-url";
import dayjs from "dayjs";
import dayjsIsoWeek from "dayjs/plugin/isoWeek.js";
import dayjsCustomParseFormat from "dayjs/plugin/customParseFormat.js";
import dayjsAdvancedFormat from "dayjs/plugin/advancedFormat.js";
import { c as getConfig, s as setAccTitle, g as getAccTitle, r as setDiagramTitle, t as getDiagramTitle, b as setAccDescription, a as getAccDescription, m as mermaidAPI, v as clear$1, u as utils, l as log, i as configureSvgSize, e as common } from "./mermaid-768dc893.js";
import { select, scaleTime, min, max, scaleLinear, interpolateHcl, axisBottom, timeFormat, timeMonth, timeDay, timeHour, timeMinute, axisTop, timeMonday, timeTuesday, timeWednesday, timeThursday, timeFriday, timeSaturday, timeSunday } from "d3";
import "ts-dedent";
import "dompurify";
import "khroma";
import "lodash-es/memoize.js";
import "lodash-es/merge.js";
import "stylis";
import "lodash-es/isEmpty.js";
var parser = function() {
var o = function(k, v, o2, l) {
for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v)
;
return o2;
}, $V0 = [1, 3], $V1 = [1, 5], $V2 = [7, 9, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 31, 33, 34, 36, 43, 48], $V3 = [1, 32], $V4 = [1, 33], $V5 = [1, 34], $V6 = [1, 35], $V7 = [1, 36], $V8 = [1, 37], $V9 = [1, 38], $Va = [1, 15], $Vb = [1, 16], $Vc = [1, 17], $Vd = [1, 18], $Ve = [1, 19], $Vf = [1, 20], $Vg = [1, 21], $Vh = [1, 22], $Vi = [1, 24], $Vj = [1, 25], $Vk = [1, 26], $Vl = [1, 27], $Vm = [1, 28], $Vn = [1, 30], $Vo = [1, 39], $Vp = [1, 42], $Vq = [5, 7, 9, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 31, 33, 34, 36, 43, 48];
var parser2 = {
trace: function trace() {
},
yy: {},
symbols_: { "error": 2, "start": 3, "directive": 4, "gantt": 5, "document": 6, "EOF": 7, "line": 8, "SPACE": 9, "statement": 10, "NL": 11, "weekday": 12, "weekday_monday": 13, "weekday_tuesday": 14, "weekday_wednesday": 15, "weekday_thursday": 16, "weekday_friday": 17, "weekday_saturday": 18, "weekday_sunday": 19, "dateFormat": 20, "inclusiveEndDates": 21, "topAxis": 22, "axisFormat": 23, "tickInterval": 24, "excludes": 25, "includes": 26, "todayMarker": 27, "title": 28, "acc_title": 29, "acc_title_value": 30, "acc_descr": 31, "acc_descr_value": 32, "acc_descr_multiline_value": 33, "section": 34, "clickStatement": 35, "taskTxt": 36, "taskData": 37, "openDirective": 38, "typeDirective": 39, "closeDirective": 40, ":": 41, "argDirective": 42, "click": 43, "callbackname": 44, "callbackargs": 45, "href": 46, "clickStatementDebug": 47, "open_directive": 48, "type_directive": 49, "arg_directive": 50, "close_directive": 51, "$accept": 0, "$end": 1 },
terminals_: { 2: "error", 5: "gantt", 7: "EOF", 9: "SPACE", 11: "NL", 13: "weekday_monday", 14: "weekday_tuesday", 15: "weekday_wednesday", 16: "weekday_thursday", 17: "weekday_friday", 18: "weekday_saturday", 19: "weekday_sunday", 20: "dateFormat", 21: "inclusiveEndDates", 22: "topAxis", 23: "axisFormat", 24: "tickInterval", 25: "excludes", 26: "includes", 27: "todayMarker", 28: "title", 29: "acc_title", 30: "acc_title_value", 31: "acc_descr", 32: "acc_descr_value", 33: "acc_descr_multiline_value", 34: "section", 36: "taskTxt", 37: "taskData", 41: ":", 43: "click", 44: "callbackname", 45: "callbackargs", 46: "href", 48: "open_directive", 49: "type_directive", 50: "arg_directive", 51: "close_directive" },
productions_: [0, [3, 2], [3, 3], [6, 0], [6, 2], [8, 2], [8, 1], [8, 1], [8, 1], [12, 1], [12, 1], [12, 1], [12, 1], [12, 1], [12, 1], [12, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 2], [10, 2], [10, 1], [10, 1], [10, 1], [10, 2], [10, 1], [4, 4], [4, 6], [35, 2], [35, 3], [35, 3], [35, 4], [35, 3], [35, 4], [35, 2], [47, 2], [47, 3], [47, 3], [47, 4], [47, 3], [47, 4], [47, 2], [38, 1], [39, 1], [42, 1], [40, 1]],
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {
var $0 = $$.length - 1;
switch (yystate) {
case 2:
return $$[$0 - 1];
case 3:
this.$ = [];
break;
case 4:
$$[$0 - 1].push($$[$0]);
this.$ = $$[$0 - 1];
break;
case 5:
case 6:
this.$ = $$[$0];
break;
case 7:
case 8:
this.$ = [];
break;
case 9:
yy.setWeekday("monday");
break;
case 10:
yy.setWeekday("tuesday");
break;
case 11:
yy.setWeekday("wednesday");
break;
case 12:
yy.setWeekday("thursday");
break;
case 13:
yy.setWeekday("friday");
break;
case 14:
yy.setWeekday("saturday");
break;
case 15:
yy.setWeekday("sunday");
break;
case 16:
yy.setDateFormat($$[$0].substr(11));
this.$ = $$[$0].substr(11);
break;
case 17:
yy.enableInclusiveEndDates();
this.$ = $$[$0].substr(18);
break;
case 18:
yy.TopAxis();
this.$ = $$[$0].substr(8);
break;
case 19:
yy.setAxisFormat($$[$0].substr(11));
this.$ = $$[$0].substr(11);
break;
case 20:
yy.setTickInterval($$[$0].substr(13));
this.$ = $$[$0].substr(13);
break;
case 21:
yy.setExcludes($$[$0].substr(9));
this.$ = $$[$0].substr(9);
break;
case 22:
yy.setIncludes($$[$0].substr(9));
this.$ = $$[$0].substr(9);
break;
case 23:
yy.setTodayMarker($$[$0].substr(12));
this.$ = $$[$0].substr(12);
break;
case 25:
yy.setDiagramTitle($$[$0].substr(6));
this.$ = $$[$0].substr(6);
break;
case 26:
this.$ = $$[$0].trim();
yy.setAccTitle(this.$);
break;
case 27:
case 28:
this.$ = $$[$0].trim();
yy.setAccDescription(this.$);
break;
case 29:
yy.addSection($$[$0].substr(8));
this.$ = $$[$0].substr(8);
break;
case 31:
yy.addTask($$[$0 - 1], $$[$0]);
this.$ = "task";
break;
case 35:
this.$ = $$[$0 - 1];
yy.setClickEvent($$[$0 - 1], $$[$0], null);
break;
case 36:
this.$ = $$[$0 - 2];
yy.setClickEvent($$[$0 - 2], $$[$0 - 1], $$[$0]);
break;
case 37:
this.$ = $$[$0 - 2];
yy.setClickEvent($$[$0 - 2], $$[$0 - 1], null);
yy.setLink($$[$0 - 2], $$[$0]);
break;
case 38:
this.$ = $$[$0 - 3];
yy.setClickEvent($$[$0 - 3], $$[$0 - 2], $$[$0 - 1]);
yy.setLink($$[$0 - 3], $$[$0]);
break;
case 39:
this.$ = $$[$0 - 2];
yy.setClickEvent($$[$0 - 2], $$[$0], null);
yy.setLink($$[$0 - 2], $$[$0 - 1]);
break;
case 40:
this.$ = $$[$0 - 3];
yy.setClickEvent($$[$0 - 3], $$[$0 - 1], $$[$0]);
yy.setLink($$[$0 - 3], $$[$0 - 2]);
break;
case 41:
this.$ = $$[$0 - 1];
yy.setLink($$[$0 - 1], $$[$0]);
break;
case 42:
case 48:
this.$ = $$[$0 - 1] + " " + $$[$0];
break;
case 43:
case 44:
case 46:
this.$ = $$[$0 - 2] + " " + $$[$0 - 1] + " " + $$[$0];
break;
case 45:
case 47:
this.$ = $$[$0 - 3] + " " + $$[$0 - 2] + " " + $$[$0 - 1] + " " + $$[$0];
break;
case 49:
yy.parseDirective("%%{", "open_directive");
break;
case 50:
yy.parseDirective($$[$0], "type_directive");
break;
case 51:
$$[$0] = $$[$0].trim().replace(/'/g, '"');
yy.parseDirective($$[$0], "arg_directive");
break;
case 52:
yy.parseDirective("}%%", "close_directive", "gantt");
break;
}
},
table: [{ 3: 1, 4: 2, 5: $V0, 38: 4, 48: $V1 }, { 1: [3] }, { 3: 6, 4: 2, 5: $V0, 38: 4, 48: $V1 }, o($V2, [2, 3], { 6: 7 }), { 39: 8, 49: [1, 9] }, { 49: [2, 49] }, { 1: [2, 1] }, { 4: 31, 7: [1, 10], 8: 11, 9: [1, 12], 10: 13, 11: [1, 14], 12: 23, 13: $V3, 14: $V4, 15: $V5, 16: $V6, 17: $V7, 18: $V8, 19: $V9, 20: $Va, 21: $Vb, 22: $Vc, 23: $Vd, 24: $Ve, 25: $Vf, 26: $Vg, 27: $Vh, 28: $Vi, 29: $Vj, 31: $Vk, 33: $Vl, 34: $Vm, 35: 29, 36: $Vn, 38: 4, 43: $Vo, 48: $V1 }, { 40: 40, 41: [1, 41], 51: $Vp }, o([41, 51], [2, 50]), o($V2, [2, 8], { 1: [2, 2] }), o($V2, [2, 4]), { 4: 31, 10: 43, 12: 23, 13: $V3, 14: $V4, 15: $V5, 16: $V6, 17: $V7, 18: $V8, 19: $V9, 20: $Va, 21: $Vb, 22: $Vc, 23: $Vd, 24: $Ve, 25: $Vf, 26: $Vg, 27: $Vh, 28: $Vi, 29: $Vj, 31: $Vk, 33: $Vl, 34: $Vm, 35: 29, 36: $Vn, 38: 4, 43: $Vo, 48: $V1 }, o($V2, [2, 6]), o($V2, [2, 7]), o($V2, [2, 16]), o($V2, [2, 17]), o($V2, [2, 18]), o($V2, [2, 19]), o($V2, [2, 20]), o($V2, [2, 21]), o($V2, [2, 22]), o($V2, [2, 23]), o($V2, [2, 24]), o($V2, [2, 25]), { 30: [1, 44] }, { 32: [1, 45] }, o($V2, [2, 28]), o($V2, [2, 29]), o($V2, [2, 30]), { 37: [1, 46] }, o($V2, [2, 32]), o($V2, [2, 9]), o($V2, [2, 10]), o($V2, [2, 11]), o($V2, [2, 12]), o($V2, [2, 13]), o($V2, [2, 14]), o($V2, [2, 15]), { 44: [1, 47], 46: [1, 48] }, { 11: [1, 49] }, { 42: 50, 50: [1, 51] }, { 11: [2, 52] }, o($V2, [2, 5]), o($V2, [2, 26]), o($V2, [2, 27]), o($V2, [2, 31]), o($V2, [2, 35], { 45: [1, 52], 46: [1, 53] }), o($V2, [2, 41], { 44: [1, 54] }), o($Vq, [2, 33]), { 40: 55, 51: $Vp }, { 51: [2, 51] }, o($V2, [2, 36], { 46: [1, 56] }), o($V2, [2, 37]), o($V2, [2, 39], { 45: [1, 57] }), { 11: [1, 58] }, o($V2, [2, 38]), o($V2, [2, 40]), o($Vq, [2, 34])],
defaultActions: { 5: [2, 49], 6: [2, 1], 42: [2, 52], 51: [2, 51] },
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, TERROR = 2, EOF = 1;
var args = lstack.slice.call(arguments, 1);
var lexer2 = 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];
}
}
lexer2.setInput(input, sharedState.yy);
sharedState.yy.lexer = lexer2;
sharedState.yy.parser = this;
if (typeof lexer2.yylloc == "undefined") {
lexer2.yylloc = {};
}
var yyloc = lexer2.yylloc;
lstack.push(yyloc);
var ranges = lexer2.options && lexer2.options.ranges;
if (typeof sharedState.yy.parseError === "function") {
this.parseError = sharedState.yy.parseError;
} else {
this.parseError = Object.getPrototypeOf(this).parseError;
}
function lex() {
var token;
token = tstack.pop() || lexer2.lex() || EOF;
if (typeof token !== "number") {
if (token instanceof Array) {
tstack = token;
token = tstack.pop();
}
token = self.symbols_[token] || token;
}
return token;
}
var symbol, state, action, 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 (lexer2.showPosition) {
errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.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: lexer2.match,
token: this.terminals_[symbol] || symbol,
line: lexer2.yylineno,
loc: yyloc,
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(lexer2.yytext);
lstack.push(lexer2.yylloc);
stack.push(action[1]);
symbol = null;
{
yyleng = lexer2.yyleng;
yytext = lexer2.yytext;
yylineno = lexer2.yylineno;
yyloc = lexer2.yylloc;
}
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;
}
};
var lexer = function() {
var lexer2 = {
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.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) {
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) {
for (var k in backup) {
this[k] = backup[k];
}
return false;
}
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;
} else {
return false;
}
} else if (!this.options.flex) {
break;
}
}
}
if (match) {
token = this.test_match(match, rules[index]);
if (token !== false) {
return token;
}
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) {
switch ($avoiding_name_collisions) {
case 0:
this.begin("open_directive");
return 48;
case 1:
this.begin("type_directive");
return 49;
case 2:
this.popState();
this.begin("arg_directive");
return 41;
case 3:
this.popState();
this.popState();
return 51;
case 4:
return 50;
case 5:
this.begin("acc_title");
return 29;
case 6:
this.popState();
return "acc_title_value";
case 7:
this.begin("acc_descr");
return 31;
case 8:
this.popState();
return "acc_descr_value";
case 9:
this.begin("acc_descr_multiline");
break;
case 10:
this.popState();
break;
case 11:
return "acc_descr_multiline_value";
case 12:
break;
case 13:
break;
case 14:
break;
case 15:
return 11;
case 16:
break;
case 17:
break;
case 18:
break;
case 19:
this.begin("href");
break;
case 20:
this.popState();
break;
case 21:
return 46;
case 22:
this.begin("callbackname");
break;
case 23:
this.popState();
break;
case 24:
this.popState();
this.begin("callbackargs");
break;
case 25:
return 44;
case 26:
this.popState();
break;
case 27:
return 45;
case 28:
this.begin("click");
break;
case 29:
this.popState();
break;
case 30:
return 43;
case 31:
return 5;
case 32:
return 20;
case 33:
return 21;
case 34:
return 22;
case 35:
return 23;
case 36:
return 24;
case 37:
return 26;
case 38:
return 25;
case 39:
return 27;
case 40:
return 13;
case 41:
return 14;
case 42:
return 15;
case 43:
return 16;
case 44:
return 17;
case 45:
return 18;
case 46:
return 19;
case 47:
return "date";
case 48:
return 28;
case 49:
return "accDescription";
case 50:
return 34;
case 51:
return 36;
case 52:
return 37;
case 53:
return 41;
case 54:
return 7;
case 55:
return "INVALID";
}
},
rules: [/^(?:%%\{)/i, /^(?:((?:(?!\}%%)[^:.])*))/i, /^(?::)/i, /^(?:\}%%)/i, /^(?:((?:(?!\}%%).|\n)*))/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:%%(?!\{)*[^\n]*)/i, /^(?:[^\}]%%*[^\n]*)/i, /^(?:%%*[^\n]*[\n]*)/i, /^(?:[\n]+)/i, /^(?:\s+)/i, /^(?:#[^\n]*)/i, /^(?:%[^\n]*)/i, /^(?:href[\s]+["])/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:call[\s]+)/i, /^(?:\([\s]*\))/i, /^(?:\()/i, /^(?:[^(]*)/i, /^(?:\))/i, /^(?:[^)]*)/i, /^(?:click[\s]+)/i, /^(?:[\s\n])/i, /^(?:[^\s\n]*)/i, /^(?:gantt\b)/i, /^(?:dateFormat\s[^#\n;]+)/i, /^(?:inclusiveEndDates\b)/i, /^(?:topAxis\b)/i, /^(?:axisFormat\s[^#\n;]+)/i, /^(?:tickInterval\s[^#\n;]+)/i, /^(?:includes\s[^#\n;]+)/i, /^(?:excludes\s[^#\n;]+)/i, /^(?:todayMarker\s[^\n;]+)/i, /^(?:weekday\s+monday\b)/i, /^(?:weekday\s+tuesday\b)/i, /^(?:weekday\s+wednesday\b)/i, /^(?:weekday\s+thursday\b)/i, /^(?:weekday\s+friday\b)/i, /^(?:weekday\s+saturday\b)/i, /^(?:weekday\s+sunday\b)/i, /^(?:\d\d\d\d-\d\d-\d\d\b)/i, /^(?:title\s[^#\n;]+)/i, /^(?:accDescription\s[^#\n;]+)/i, /^(?:section\s[^#:\n;]+)/i, /^(?:[^#:\n;]+)/i, /^(?::[^#\n;]+)/i, /^(?::)/i, /^(?:$)/i, /^(?:.)/i],
conditions: { "acc_descr_multiline": { "rules": [10, 11], "inclusive": false }, "acc_descr": { "rules": [8], "inclusive": false }, "acc_title": { "rules": [6], "inclusive": false }, "close_directive": { "rules": [], "inclusive": false }, "arg_directive": { "rules": [3, 4], "inclusive": false }, "type_directive": { "rules": [2, 3], "inclusive": false }, "open_directive": { "rules": [1], "inclusive": false }, "callbackargs": { "rules": [26, 27], "inclusive": false }, "callbackname": { "rules": [23, 24, 25], "inclusive": false }, "href": { "rules": [20, 21], "inclusive": false }, "click": { "rules": [29, 30], "inclusive": false }, "INITIAL": { "rules": [0, 5, 7, 9, 12, 13, 14, 15, 16, 17, 18, 19, 22, 28, 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], "inclusive": true } }
};
return lexer2;
}();
parser2.lexer = lexer;
function Parser() {
this.yy = {};
}
Parser.prototype = parser2;
parser2.Parser = Parser;
return new Parser();
}();
parser.parser = parser;
const ganttParser = parser;
dayjs.extend(dayjsIsoWeek);
dayjs.extend(dayjsCustomParseFormat);
dayjs.extend(dayjsAdvancedFormat);
let dateFormat = "";
let axisFormat = "";
let tickInterval = void 0;
let todayMarker = "";
let includes = [];
let excludes = [];
let links = {};
let sections = [];
let tasks = [];
let currentSection = "";
let displayMode = "";
const tags = ["active", "done", "crit", "milestone"];
let funs = [];
let inclusiveEndDates = false;
let topAxis = false;
let weekday = "sunday";
let lastOrder = 0;
const parseDirective = function(statement, context, type) {
mermaidAPI.parseDirective(this, statement, context, type);
};
const clear = function() {
sections = [];
tasks = [];
currentSection = "";
funs = [];
taskCnt = 0;
lastTask = void 0;
lastTaskID = void 0;
rawTasks = [];
dateFormat = "";
axisFormat = "";
displayMode = "";
tickInterval = void 0;
todayMarker = "";
includes = [];
excludes = [];
inclusiveEndDates = false;
topAxis = false;
lastOrder = 0;
links = {};
clear$1();
weekday = "sunday";
};
const setAxisFormat = function(txt) {
axisFormat = txt;
};
const getAxisFormat = function() {
return axisFormat;
};
const setTickInterval = function(txt) {
tickInterval = txt;
};
const getTickInterval = function() {
return tickInterval;
};
const setTodayMarker = function(txt) {
todayMarker = txt;
};
const getTodayMarker = function() {
return todayMarker;
};
const setDateFormat = function(txt) {
dateFormat = txt;
};
const enableInclusiveEndDates = function() {
inclusiveEndDates = true;
};
const endDatesAreInclusive = function() {
return inclusiveEndDates;
};
const enableTopAxis = function() {
topAxis = true;
};
const topAxisEnabled = function() {
return topAxis;
};
const setDisplayMode = function(txt) {
displayMode = txt;
};
const getDisplayMode = function() {
return displayMode;
};
const getDateFormat = function() {
return dateFormat;
};
const setIncludes = function(txt) {
includes = txt.toLowerCase().split(/[\s,]+/);
};
const getIncludes = function() {
return includes;
};
const setExcludes = function(txt) {
excludes = txt.toLowerCase().split(/[\s,]+/);
};
const getExcludes = function() {
return excludes;
};
const getLinks = function() {
return links;
};
const addSection = function(txt) {
currentSection = txt;
sections.push(txt);
};
const getSections = function() {
return sections;
};
const getTasks = function() {
let allItemsProcessed = compileTasks();
const maxDepth = 10;
let iterationCount = 0;
while (!allItemsProcessed && iterationCount < maxDepth) {
allItemsProcessed = compileTasks();
iterationCount++;
}
tasks = rawTasks;
return tasks;
};
const isInvalidDate = function(date, dateFormat2, excludes2, includes2) {
if (includes2.includes(date.format(dateFormat2.trim()))) {
return false;
}
if (date.isoWeekday() >= 6 && excludes2.includes("weekends")) {
return true;
}
if (excludes2.includes(date.format("dddd").toLowerCase())) {
return true;
}
return excludes2.includes(date.format(dateFormat2.trim()));
};
const setWeekday = function(txt) {
weekday = txt;
};
const getWeekday = function() {
return weekday;
};
const checkTaskDates = function(task, dateFormat2, excludes2, includes2) {
if (!excludes2.length || task.manualEndTime) {
return;
}
let startTime;
if (task.startTime instanceof Date) {
startTime = dayjs(task.startTime);
} else {
startTime = dayjs(task.startTime, dateFormat2, true);
}
startTime = startTime.add(1, "d");
let originalEndTime;
if (task.endTime instanceof Date) {
originalEndTime = dayjs(task.endTime);
} else {
originalEndTime = dayjs(task.endTime, dateFormat2, true);
}
const [fixedEndTime, renderEndTime] = fixTaskDates(
startTime,
originalEndTime,
dateFormat2,
excludes2,
includes2
);
task.endTime = fixedEndTime.toDate();
task.renderEndTime = renderEndTime;
};
const fixTaskDates = function(startTime, endTime, dateFormat2, excludes2, includes2) {
let invalid = false;
let renderEndTime = null;
while (startTime <= endTime) {
if (!invalid) {
renderEndTime = endTime.toDate();
}
invalid = isInvalidDate(startTime, dateFormat2, excludes2, includes2);
if (invalid) {
endTime = endTime.add(1, "d");
}
startTime = startTime.add(1, "d");
}
return [endTime, renderEndTime];
};
const getStartDate = function(prevTime, dateFormat2, str) {
str = str.trim();
const re = /^after\s+([\d\w- ]+)/;
const afterStatement = re.exec(str.trim());
if (afterStatement !== null) {
let latestEndingTask = null;
afterStatement[1].split(" ").forEach(function(id) {
let task = findTaskById(id);
if (task !== void 0) {
if (!latestEndingTask) {
latestEndingTask = task;
} else {
if (task.endTime > latestEndingTask.endTime) {
latestEndingTask = task;
}
}
}
});
if (!latestEndingTask) {
const dt = /* @__PURE__ */ new Date();
dt.setHours(0, 0, 0, 0);
return dt;
} else {
return latestEndingTask.endTime;
}
}
let mDate = dayjs(str, dateFormat2.trim(), true);
if (mDate.isValid()) {
return mDate.toDate();
} else {
log.debug("Invalid date:" + str);
log.debug("With date format:" + dateFormat2.trim());
const d = new Date(str);
if (d === void 0 || isNaN(d.getTime()) || // WebKit browsers can mis-parse invalid dates to be ridiculously
// huge numbers, e.g. new Date('202304') gets parsed as January 1, 202304.
// This can cause virtually infinite loops while rendering, so for the
// purposes of Gantt charts we'll just treat any date beyond 10,000 AD/BC as
// invalid.
d.getFullYear() < -1e4 || d.getFullYear() > 1e4) {
throw new Error("Invalid date:" + str);
}
return d;
}
};
const parseDuration = function(str) {
const statement = /^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(str.trim());
if (statement !== null) {
return [Number.parseFloat(statement[1]), statement[2]];
}
return [NaN, "ms"];
};
const getEndDate = function(prevTime, dateFormat2, str, inclusive = false) {
str = str.trim();
let mDate = dayjs(str, dateFormat2.trim(), true);
if (mDate.isValid()) {
if (inclusive) {
mDate = mDate.add(1, "d");
}
return mDate.toDate();
}
let endTime = dayjs(prevTime);
const [durationValue, durationUnit] = parseDuration(str);
if (!Number.isNaN(durationValue)) {
const newEndTime = endTime.add(durationValue, durationUnit);
if (newEndTime.isValid()) {
endTime = newEndTime;
}
}
return endTime.toDate();
};
let taskCnt = 0;
const parseId = function(idStr) {
if (idStr === void 0) {
taskCnt = taskCnt + 1;
return "task" + taskCnt;
}
return idStr;
};
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 = {};
getTaskTags(data, task, tags);
for (let i = 0; i < data.length; i++) {
data[i] = data[i].trim();
}
let endTimeData = "";
switch (data.length) {
case 1:
task.id = parseId();
task.startTime = prevTask.endTime;
endTimeData = data[0];
break;
case 2:
task.id = parseId();
task.startTime = getStartDate(void 0, dateFormat, data[0]);
endTimeData = data[1];
break;
case 3:
task.id = parseId(data[0]);
task.startTime = getStartDate(void 0, dateFormat, data[1]);
endTimeData = data[2];
break;
}
if (endTimeData) {
task.endTime = getEndDate(task.startTime, dateFormat, endTimeData, inclusiveEndDates);
task.manualEndTime = dayjs(endTimeData, "YYYY-MM-DD", true).isValid();
checkTaskDates(task, dateFormat, excludes, includes);
}
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 = {};
getTaskTags(data, task, tags);
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;
}
return task;
};
let lastTask;
let lastTaskID;
let rawTasks = [];
const taskDb = {};
const addTask = function(descr, data) {
const rawTask = {
section: currentSection,
type: currentSection,
processed: false,
manualEndTime: false,
renderEndTime: null,
raw: { data },
task: descr,
classes: []
};
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;
rawTask.milestone = taskInfo.milestone;
rawTask.order = lastOrder;
lastOrder++;
const pos = rawTasks.push(rawTask);
lastTaskID = rawTask.id;
taskDb[rawTask.id] = pos - 1;
};
const findTaskById = function(id) {
const pos = taskDb[id];
return rawTasks[pos];
};
const addTaskOrg = function(descr, data) {
const newTask = {
section: currentSection,
type: currentSection,
description: descr,
task: descr,
classes: []
};
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;
newTask.milestone = taskInfo.milestone;
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(void 0, 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,
inclusiveEndDates
);
if (rawTasks[pos].endTime) {
rawTasks[pos].processed = true;
rawTasks[pos].manualEndTime = dayjs(
rawTasks[pos].raw.endTime.data,
"YYYY-MM-DD",
true
).isValid();
checkTaskDates(rawTasks[pos], dateFormat, excludes, includes);
}
}
return rawTasks[pos].processed;
};
let allProcessed = true;
for (const [i, rawTask] of rawTasks.entries()) {
compileTask(i);
allProcessed = allProcessed && rawTask.processed;
}
return allProcessed;
};
const setLink = function(ids, _linkStr) {
let linkStr = _linkStr;
if (getConfig().securityLevel !== "loose") {
linkStr = sanitizeUrl(_linkStr);
}
ids.split(",").forEach(function(id) {
let rawTask = findTaskById(id);
if (rawTask !== void 0) {
pushFun(id, () => {
window.open(linkStr, "_self");
});
links[id] = linkStr;
}
});
setClass(ids, "clickable");
};
const setClass = function(ids, className) {
ids.split(",").forEach(function(id) {
let rawTask = findTaskById(id);
if (rawTask !== void 0) {
rawTask.classes.push(className);
}
});
};
const setClickFun = function(id, functionName, functionArgs) {
if (getConfig().securityLevel !== "loose") {
return;
}
if (functionName === void 0) {
return;
}
let argList = [];
if (typeof functionArgs === "string") {
argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);
for (let i = 0; i < argList.length; i++) {
let item = argList[i].trim();
if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') {
item = item.substr(1, item.length - 2);
}
argList[i] = item;
}
}
if (argList.length === 0) {
argList.push(id);
}
let rawTask = findTaskById(id);
if (rawTask !== void 0) {
pushFun(id, () => {
utils.runFunc(functionName, ...argList);
});
}
};
const pushFun = function(id, callbackFunction) {
funs.push(
function() {
const elem = document.querySelector(`[id="${id}"]`);
if (elem !== null) {
elem.addEventListener("click", function() {
callbackFunction();
});
}
},
function() {
const elem = document.querySelector(`[id="${id}-text"]`);
if (elem !== null) {
elem.addEventListener("click", function() {
callbackFunction();
});
}
}
);
};
const setClickEvent = function(ids, functionName, functionArgs) {
ids.split(",").forEach(function(id) {
setClickFun(id, functionName, functionArgs);
});
setClass(ids, "clickable");
};
const bindFunctions = function(element) {
funs.forEach(function(fun) {
fun(element);
});
};
const ganttDb = {
parseDirective,
getConfig: () => getConfig().gantt,
clear,
setDateFormat,
getDateFormat,
enableInclusiveEndDates,
endDatesAreInclusive,
enableTopAxis,
topAxisEnabled,
setAxisFormat,
getAxisFormat,
setTickInterval,
getTickInterval,
setTodayMarker,
getTodayMarker,
setAccTitle,
getAccTitle,
setDiagramTitle,
getDiagramTitle,
setDisplayMode,
getDisplayMode,
setAccDescription,
getAccDescription,
addSection,
getSections,
getTasks,
addTask,
findTaskById,
addTaskOrg,
setIncludes,
getIncludes,
setExcludes,
getExcludes,
setClickEvent,
setLink,
getLinks,
bindFunctions,
parseDuration,
isInvalidDate,
setWeekday,
getWeekday
};
function getTaskTags(data, task, tags2) {
let matchFound = true;
while (matchFound) {
matchFound = false;
tags2.forEach(function(t) {
const pattern = "^\\s*" + t + "\\s*$";
const regex = new RegExp(pattern);
if (data[0].match(regex)) {
task[t] = true;
data.shift(1);
matchFound = true;
}
});
}
}
const setConf = function() {
log.debug("Something is calling, setConf, remove the call");
};
const mapWeekdayToTimeFunction = {
monday: timeMonday,
tuesday: timeTuesday,
wednesday: timeWednesday,
thursday: timeThursday,
friday: timeFriday,
saturday: timeSaturday,
sunday: timeSunday
};
const getMaxIntersections = (tasks2, orderOffset) => {
let timeline = [...tasks2].map(() => -Infinity);
let sorted = [...tasks2].sort((a, b) => a.startTime - b.startTime || a.order - b.order);
let maxIntersections = 0;
for (const element of sorted) {
for (let j = 0; j < timeline.length; j++) {
if (element.startTime >= timeline[j]) {
timeline[j] = element.endTime;
element.order = j + orderOffset;
if (j > maxIntersections) {
maxIntersections = j;
}
break;
}
}
}
return maxIntersections;
};
let w;
const draw = function(text, id, version, diagObj) {
const conf = getConfig().gantt;
const securityLevel = getConfig().securityLevel;
let sandboxElement;
if (securityLevel === "sandbox") {
sandboxElement = select("#i" + id);
}
const root = securityLevel === "sandbox" ? select(sandboxElement.nodes()[0].contentDocument.body) : select("body");
const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document;
const elem = doc.getElementById(id);
w = elem.parentElement.offsetWidth;
if (w === void 0) {
w = 1200;
}
if (conf.useWidth !== void 0) {
w = conf.useWidth;
}
const taskArray = diagObj.db.getTasks();
let categories = [];
for (const element of taskArray) {
categories.push(element.type);
}
categories = checkUnique(categories);
const categoryHeights = {};
let h = 2 * conf.topPadding;
if (diagObj.db.getDisplayMode() === "compact" || conf.displayMode === "compact") {
const categoryElements = {};
for (const element of taskArray) {
if (categoryElements[element.section] === void 0) {
categoryElements[element.section] = [element];
} else {
categoryElements[element.section].push(element);
}
}
let intersections = 0;
for (const category of Object.keys(categoryElements)) {
const categoryHeight = getMaxIntersections(categoryElements[category], intersections) + 1;
intersections += categoryHeight;
h += categoryHeight * (conf.barHeight + conf.barGap);
categoryHeights[category] = categoryHeight;
}
} else {
h += taskArray.length * (conf.barHeight + conf.barGap);
for (const category of categories) {
categoryHeights[category] = taskArray.filter((task) => task.type === category).length;
}
}
elem.setAttribute("viewBox", "0 0 " + w + " " + h);
const svg = root.select(`[id="${id}"]`);
const timeScale = scaleTime().domain([
min(taskArray, function(d) {
return d.startTime;
}),
max(taskArray, function(d) {
return d.endTime;
})
]).rangeRound([0, w - conf.leftPadding - conf.rightPadding]);
function taskCompare(a, b) {
const taskA = a.startTime;
const taskB = b.startTime;
let result = 0;
if (taskA > taskB) {
result = 1;
} else if (taskA < taskB) {
result = -1;
}
return result;
}
taskArray.sort(taskCompare);
makeGant(taskArray, w, h);
configureSvgSize(svg, h, w, conf.useMaxWidth);
svg.append("text").text(diagObj.db.getDiagramTitle()).attr("x", w / 2).attr("y", conf.titleTopMargin).attr("class", "titleText");
function makeGant(tasks2, pageWidth, pageHeight) {
const barHeight = conf.barHeight;
const gap = barHeight + conf.barGap;
const topPadding = conf.topPadding;
const leftPadding = conf.leftPadding;
const colorScale = scaleLinear().domain([0, categories.length]).range(["#00B9FA", "#F95002"]).interpolate(interpolateHcl);
drawExcludeDays(
gap,
topPadding,
leftPadding,
pageWidth,
pageHeight,
tasks2,
diagObj.db.getExcludes(),
diagObj.db.getIncludes()
);
makeGrid(leftPadding, topPadding, pageWidth, pageHeight);
drawRects(tasks2, gap, topPadding, leftPadding, barHeight, colorScale, pageWidth);
vertLabels(gap, topPadding);
drawToday(leftPadding, topPadding, pageWidth, pageHeight);
}
function drawRects(theArray, theGap, theTopPad, theSidePad, theBarHeight, theColorScale, w2) {
const uniqueTaskOrderIds = [...new Set(theArray.map((item) => item.order))];
const uniqueTasks