switched to Typescript

This commit is contained in:
David Mosbach 2023-08-15 04:43:28 +02:00
parent 4c24eab8c7
commit ea3763ffe9
13 changed files with 3937 additions and 1061 deletions

4
.gitignore vendored
View File

@ -2,4 +2,6 @@
CHANGELOG.md
test.json
server.py
/workflows
/workflows
/spaß
/node_modules

View File

@ -2,29 +2,29 @@
<meta charset="utf-8">
<title>Editor</title>
<!-- <script src="//unpkg.com/force-graph"></script> -->
<script src="https://unpkg.com/force-graph@1.43.0/dist/force-graph.min.js"></script>
<!-- <script src="https://unpkg.com/force-graph@1.43.0/dist/force-graph.min.js"></script> <- yo -->
<!-- <script src="./force-graph-master/src/force-graph.js"></script> -->
<!--<script src="../../dist/force-graph.js"></script>-->
<script src="https://cdn.jsdelivr.net/gh/nextapps-de/flexsearch@0.7.31/dist/flexsearch.bundle.js"></script>
<!-- <script src="https://cdn.jsdelivr.net/gh/nextapps-de/flexsearch@0.7.31/dist/flexsearch.bundle.js"></script> <- yo -->
<link rel="STYLESHEET" type="text/css" href="./editor.css">
</head>
<body>
<div id="editor">
<div id="curtain" onclick="closeFileDisplay()"></div> <!--Backdrop behind the file menu-->
<div id="curtain"></div> <!--Backdrop behind the file menu-->
<div id="submenu-backdrop"></div>
<div id="mainmenu" class="menu-lightmode"> <!--Horizontal main menu-->
<div class="menuitem" onclick="openFileMenu(this)">
<div id="file-menu-btn" class="menuitem">
<div class="menubutton">File</div>
<div id="filemenu" class="submenu" onclick="event.stopPropagation()">
<div class="menutop menu-lightmode">New Workflow</div>
<div class="menucenter menu-lightmode" onclick="openFileDisplay()">Open</div>
<div id="open-file" class="menucenter menu-lightmode">Open</div>
<div class="menucenter menu-lightmode">Save</div>
<div class="menucenter menu-lightmode">Save As</div>
<div class="menubottom menu-lightmode">Export</div>
</div>
</div>
<div class="menuitem" onclick="openEditMenu(this)">
<div id="edit-menu-btn" class="menuitem">
<div class="menubutton">Edit</div>
<div id="editmenu" class="submenu" onclick="event.stopPropagation()">
<div class="menutop menu-lightmode">Undo</div>
@ -33,7 +33,7 @@
<div class="menubottom menu-lightmode">Run Linter</div>
</div>
</div>
<div class="menuitem" onclick="openViewMenu(this)">
<div id="view-menu-btn" class="menuitem">
<div class="menubutton">View</div>
<div class="submenu menu-lightmode" onclick="event.stopPropagation()">
<table id="view-table">
@ -42,7 +42,7 @@
<label for="actor">Highlight actor:</label>
</td>
<td>
<select name="actor" id="actor" onchange="selectActor();"></select>
<select name="actor" id="actor"></select>
</td>
</tr>
<tr>
@ -50,13 +50,13 @@
<label for="viewer">Highlight viewer:</label>
</td>
<td>
<select name="viewer" id="viewer" onchange="selectViewer();"></select>
<select name="viewer" id="viewer"></select>
</td>
</tr>
</table>
</div>
</div>
<div class="menuitem" onclick="openSettingsMenu(this)">
<div id="settings-menu-btn" class="menuitem">
<div class="menubutton">Settings</div> <!--Main settings menu-->
<div class="submenu menu-lightmode" onclick="event.stopPropagation()">
<table id="settings-table">
@ -69,7 +69,7 @@
<td>
<label class="toggle" title="Dark Mode">
<input type="checkbox">
<span class="toggle-slider" onclick="toggleTheme()"></span>
<span id="theme-toggle" class="toggle-slider"></span>
</label>
</td>
<td>
@ -121,14 +121,14 @@
</div>
</div>
</div>
<div class="menuitem" onclick="openAboutMenu(this)">
<div id="about-menu-btn" class="menuitem">
<div class="menubutton">About</div>
<div class="submenu menu-lightmode">Visualiser & editor for Uni2work workflows</div>
</div>
<div class="menuitem" onclick="openSearchMenu(this)">
<div id="search-menu-btn" class="menuitem">
<div id="search-container">
<input id="search-input" type="text" placeholder="Search" onclick="showSearchResults()" oninput="search(this.value)">
<span class="search-button" onclick="searchInput.focus()">
<input id="search-input" type="text" placeholder="Search">
<span class="search-button">
<svg id="search-icon" class="search-icon-lightmode" height="18" width="18" xmlns="http://www.w3.org/2000/svg">
<circle cx="11" cy="7" r="6" stroke-width="2" fill="none" />
<polyline points="6,12 2,16" style="fill:none;stroke-width:2" stroke-linecap="round" />
@ -176,7 +176,7 @@
Node
</div>
<h1 id="sideheading">Hello</h1>
<svg class="close" height="15" width="15" xmlns="http://www.w3.org/2000/svg" onclick="deselect()">
<svg id="close-side-panel" class="close" height="15" width="15" xmlns="http://www.w3.org/2000/svg">
<polyline points="1,1 14,14" style="fill:none;stroke:rgb(120, 120, 120);stroke-width:2" stroke-linecap="round" />
<polyline points="14,1 1,14" style="fill:none;stroke:rgb(120, 120, 120);stroke-width:2" stroke-linecap="round" />
X
@ -184,16 +184,16 @@
</div>
<div id="sidecontent"></div>
<div id="sidebuttons">
<button type="submit">Apply</button>
<button type="reset" onclick="deselect()">Cancel</button>
<button type="submit" onclick="focusSelection()">Focus</button>
<button type="submit" onclick="removeSelection()" style="position: absolute; right: 0px;">Delete</button>
<button id="side-panel-apply" type="submit">Apply</button>
<button id="side-panel-cancel" type="reset">Cancel</button>
<button id="side-panel-focus" type="submit">Focus</button>
<button id="side-panel-delete" type="submit" style="position: absolute; right: 0px;">Delete</button>
</div>
</div>
<div id="filepanel" class="menu-lightmode"> <!--Pop-up panel covering the center of the screen for file interactions-->
<div id="fileheader">
<h2 id="fileheading">Hello</h2>
<svg class="close" height="15" width="15" xmlns="http://www.w3.org/2000/svg" onclick="closeFileDisplay()">
<svg id="close-file-panel" class="close" height="15" width="15" xmlns="http://www.w3.org/2000/svg">
<polyline points="1,1 14,14" style="fill:none;stroke:rgb(120, 120, 120);stroke-width:2" stroke-linecap="round" />
<polyline points="14,1 1,14" style="fill:none;stroke:rgb(120, 120, 120);stroke-width:2" stroke-linecap="round" />
X
@ -202,11 +202,11 @@
<div id="filecontent"></div>
<div id="filebuttons">
<!-- <button type="submit">Load</button> -->
<button type="reset" onclick="closeFileDisplay()">Cancel</button>
<button id="file-panel-cancel" type="reset">Cancel</button>
</div>
</div>
<div id="ctmenubg" class="contextmenu"> <!--Context menu displayed after right-clicking the background-->
<div class="menutop menu-lightmode" onclick="addState()">
<div id="add-state" class="menutop menu-lightmode">
<svg height="10" width="10" xmlns="http://www.w3.org/2000/svg">
<circle cx="5" cy="5" r="4" stroke-width="2" fill="none" />
</svg>
@ -220,19 +220,19 @@
</div>
</div>
<div id="ctmenust" class="contextmenu"> <!--Context menu displayed after right-clicking a state-->
<div class="menutop menu-lightmode" onclick="markEdgeFrom()">
<div id="edge-from" class="menutop menu-lightmode">
<svg height="10" width="10" xmlns="http://www.w3.org/2000/svg">
<polyline points="1,1 9,9" style="fill:none;stroke-width:2" stroke-linecap="round" />
</svg>
&nbsp;&nbsp;New Edge from here
</div>
<div class="menucenter menu-lightmode" onclick="markEdgeTo()">
<div id="edge-to" class="menucenter menu-lightmode">
<svg height="10" width="10" xmlns="http://www.w3.org/2000/svg">
<polyline points="1,9 9,1" style="fill:none;stroke-width:2" stroke-linecap="round" />
</svg>
&nbsp;&nbsp;New Edge to here
</div>
<div class="menucenter menu-lightmode" onclick="rightSelect()">
<div class="edit-item menucenter menu-lightmode">
<svg height="10" width="10" xmlns="http://www.w3.org/2000/svg">
<polyline points="1,9 9,1" style="fill:none;stroke-width:4" />
<polyline points="1,9 8,2" style="fill:none;stroke-width:2" stroke-linecap="round" />
@ -247,7 +247,7 @@
</svg>
&nbsp;&nbsp;Duplicate
</div>
<div class="menubottom menu-lightmode" onclick="removeRightSelection()">
<div class="delete-item menubottom menu-lightmode">
<svg height="10" width="10" xmlns="http://www.w3.org/2000/svg">
<polyline points="1,1 9,9" style="fill:none;stroke:rgb(183, 76, 76);stroke-width:2" stroke-linecap="round" />
<polyline points="9,1 1,9" style="fill:none;stroke:rgb(183, 76, 76);stroke-width:2" stroke-linecap="round" />
@ -256,7 +256,7 @@
</div>
</div>
<div id="ctmenued" class="contextmenu"> <!--Context menu displayed after right-clicking an edge-->
<div class="menutop menu-lightmode" onclick="rightSelect()">
<div class="edit-item menutop menu-lightmode">
<svg height="10" width="10" xmlns="http://www.w3.org/2000/svg">
<polyline points="1,9 9,1" style="fill:none;stroke-width:4" />
<polyline points="1,9 8,2" style="fill:none;stroke-width:2" stroke-linecap="round" />
@ -271,7 +271,7 @@
</svg>
&nbsp;&nbsp;Duplicate
</div>
<div class="menubottom menu-lightmode" onclick="removeRightSelection()">
<div class="delete-item menubottom menu-lightmode">
<svg height="10" width="10" xmlns="http://www.w3.org/2000/svg">
<polyline points="1,1 9,9" style="fill:none;stroke:rgb(183, 76, 76);stroke-width:2" stroke-linecap="round" />
<polyline points="9,1 1,9" style="fill:none;stroke:rgb(183, 76, 76);stroke-width:2" stroke-linecap="round" />
@ -282,7 +282,7 @@
<div id="graph"></div> <!--The graph canvas-->
</div>
<script src="./workflow.js"></script>
<script src="./editor.js"></script>
<script src="./keyboard.js"></script>
<!-- <script src="./workflow.ts"></script> -->
<script type="module" src="editor.js"></script>
<!-- <script src="./keyboard.ts"></script> -->
</body>

1867
editor.js

File diff suppressed because it is too large Load Diff

1180
editor.ts Normal file

File diff suppressed because it is too large Load Diff

1
forcegraph.js Normal file
View File

@ -0,0 +1 @@
"use strict";

1
forcegraph.ts Normal file
View File

@ -0,0 +1 @@
declare module 'https://*';

View File

@ -1,25 +1 @@
document.addEventListener('keydown', e => {
console.log(e.ctrlKey, e.key);
if (e.key === 'Escape') {
closeContextMenus(contextMenuEd, contextMenuSt, contextMenuBg);
closeMenuItem();
closeFileDisplay();
deselect();
rightSelection = null;
searchInput.blur();
} else if (!e.ctrlKey) return;
switch (e.key) {
case 'f':
e.preventDefault();
searchInput.focus();
openSearchMenu(searchContainer.parentElement);
break;
case 'o':
e.preventDefault();
openFileDisplay();
default:
break;
}
})
"use strict";

0
keyboard.ts Normal file
View File

969
package-lock.json generated Normal file
View File

@ -0,0 +1,969 @@
{
"name": "workflow-visualiser",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "workflow-visualiser",
"version": "1.0.0",
"license": "AGPL-3.0-or-later",
"dependencies": {
"commonjs": "^0.0.1",
"flexsearch": "^0.7.31",
"typescript": "^5.1.6"
}
},
"node_modules/abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
"dependencies": {
"event-target-shim": "^5.0.0"
},
"engines": {
"node": ">=6.5"
}
},
"node_modules/array-buffer-byte-length": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz",
"integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==",
"dependencies": {
"call-bind": "^1.0.2",
"is-array-buffer": "^3.0.1"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/arraybuffer.prototype.slice": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz",
"integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==",
"dependencies": {
"array-buffer-byte-length": "^1.0.0",
"call-bind": "^1.0.2",
"define-properties": "^1.2.0",
"get-intrinsic": "^1.2.1",
"is-array-buffer": "^3.0.2",
"is-shared-array-buffer": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/available-typed-arrays": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"node_modules/call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"dependencies": {
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.2"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/commonjs": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/commonjs/-/commonjs-0.0.1.tgz",
"integrity": "sha512-hscVSSFaViuW9i3q7G9BYDpcg/vEdzgk570bUD1u54tcrXQwB2pbHgI7placWz9ZQEJ04goyx8W7mPI/EPpxyw==",
"dependencies": {
"system": ">=0.0.1",
"test": ">=0.0.5"
},
"engines": {
"node": ">=0.1.103"
}
},
"node_modules/define-properties": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz",
"integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==",
"dependencies": {
"has-property-descriptors": "^1.0.0",
"object-keys": "^1.1.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/es-abstract": {
"version": "1.22.1",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz",
"integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==",
"dependencies": {
"array-buffer-byte-length": "^1.0.0",
"arraybuffer.prototype.slice": "^1.0.1",
"available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2",
"es-set-tostringtag": "^2.0.1",
"es-to-primitive": "^1.2.1",
"function.prototype.name": "^1.1.5",
"get-intrinsic": "^1.2.1",
"get-symbol-description": "^1.0.0",
"globalthis": "^1.0.3",
"gopd": "^1.0.1",
"has": "^1.0.3",
"has-property-descriptors": "^1.0.0",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"internal-slot": "^1.0.5",
"is-array-buffer": "^3.0.2",
"is-callable": "^1.2.7",
"is-negative-zero": "^2.0.2",
"is-regex": "^1.1.4",
"is-shared-array-buffer": "^1.0.2",
"is-string": "^1.0.7",
"is-typed-array": "^1.1.10",
"is-weakref": "^1.0.2",
"object-inspect": "^1.12.3",
"object-keys": "^1.1.1",
"object.assign": "^4.1.4",
"regexp.prototype.flags": "^1.5.0",
"safe-array-concat": "^1.0.0",
"safe-regex-test": "^1.0.0",
"string.prototype.trim": "^1.2.7",
"string.prototype.trimend": "^1.0.6",
"string.prototype.trimstart": "^1.0.6",
"typed-array-buffer": "^1.0.0",
"typed-array-byte-length": "^1.0.0",
"typed-array-byte-offset": "^1.0.0",
"typed-array-length": "^1.0.4",
"unbox-primitive": "^1.0.2",
"which-typed-array": "^1.1.10"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
"integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
"dependencies": {
"get-intrinsic": "^1.1.3",
"has": "^1.0.3",
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-to-primitive": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
"integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
"dependencies": {
"is-callable": "^1.1.4",
"is-date-object": "^1.0.1",
"is-symbol": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/event-target-shim": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
"engines": {
"node": ">=6"
}
},
"node_modules/events": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
"engines": {
"node": ">=0.8.x"
}
},
"node_modules/flexsearch": {
"version": "0.7.31",
"resolved": "https://registry.npmjs.org/flexsearch/-/flexsearch-0.7.31.tgz",
"integrity": "sha512-XGozTsMPYkm+6b5QL3Z9wQcJjNYxp0CYn3U1gO7dwD6PAqU1SVWZxI9CCg3z+ml3YfqdPnrBehaBrnH2AGKbNA=="
},
"node_modules/for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
"dependencies": {
"is-callable": "^1.1.3"
}
},
"node_modules/function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"node_modules/function.prototype.name": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
"integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3",
"es-abstract": "^1.19.0",
"functions-have-names": "^1.2.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/functions-have-names": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-intrinsic": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
"dependencies": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-symbol-description": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
"integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
"dependencies": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.1.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/globalthis": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
"integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
"dependencies": {
"define-properties": "^1.1.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
"dependencies": {
"get-intrinsic": "^1.1.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dependencies": {
"function-bind": "^1.1.1"
},
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/has-bigints": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
"integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-property-descriptors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
"integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
"dependencies": {
"get-intrinsic": "^1.1.1"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
"dependencies": {
"has-symbols": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/internal-slot": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz",
"integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==",
"dependencies": {
"get-intrinsic": "^1.2.0",
"has": "^1.0.3",
"side-channel": "^1.0.4"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/is-array-buffer": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
"integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==",
"dependencies": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.2.0",
"is-typed-array": "^1.1.10"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-bigint": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
"integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
"dependencies": {
"has-bigints": "^1.0.1"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-boolean-object": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
"integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
"dependencies": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-callable": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-date-object": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
"integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
"dependencies": {
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-negative-zero": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
"integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-number-object": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
"integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
"dependencies": {
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-regex": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
"dependencies": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-shared-array-buffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
"integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
"dependencies": {
"call-bind": "^1.0.2"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-string": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
"integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
"dependencies": {
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-symbol": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
"integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
"dependencies": {
"has-symbols": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-typed-array": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
"integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
"dependencies": {
"which-typed-array": "^1.1.11"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-weakref": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
"integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
"dependencies": {
"call-bind": "^1.0.2"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
},
"node_modules/minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/object-inspect": {
"version": "1.12.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
"integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/object.assign": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
"integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.4",
"has-symbols": "^1.0.3",
"object-keys": "^1.1.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/readable-stream": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz",
"integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==",
"dependencies": {
"abort-controller": "^3.0.0",
"buffer": "^6.0.3",
"events": "^3.3.0",
"process": "^0.11.10",
"string_decoder": "^1.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/regexp.prototype.flags": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz",
"integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==",
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.2.0",
"functions-have-names": "^1.2.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/safe-array-concat": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz",
"integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==",
"dependencies": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.2.0",
"has-symbols": "^1.0.3",
"isarray": "^2.0.5"
},
"engines": {
"node": ">=0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/safe-regex-test": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
"integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
"dependencies": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.1.3",
"is-regex": "^1.1.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"dependencies": {
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
"object-inspect": "^1.9.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"dependencies": {
"safe-buffer": "~5.2.0"
}
},
"node_modules/string.prototype.replaceall": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/string.prototype.replaceall/-/string.prototype.replaceall-1.0.7.tgz",
"integrity": "sha512-xB2WV2GlSCSJT5dMGdhdH1noMPiAB91guiepwTYyWY9/0Vq/TZ7RPmnOSUGAEvry08QIK7EMr28aAii+9jC6kw==",
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.4",
"es-abstract": "^1.20.4",
"get-intrinsic": "^1.1.3",
"has-symbols": "^1.0.3",
"is-regex": "^1.1.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/string.prototype.trim": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz",
"integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==",
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.4",
"es-abstract": "^1.20.4"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/string.prototype.trimend": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz",
"integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==",
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.4",
"es-abstract": "^1.20.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/string.prototype.trimstart": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz",
"integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==",
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.4",
"es-abstract": "^1.20.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/system": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/system/-/system-2.0.1.tgz",
"integrity": "sha512-BwSUSa8LMHZouGadZ34ck3TsrH5s3oMmTKPK+xHdbBnTCZOZMJ38fHGKLAHkBl0PXru1Z4BsymQU4qqvTxWzdQ==",
"bin": {
"jscat": "bundle.js"
}
},
"node_modules/test": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/test/-/test-3.3.0.tgz",
"integrity": "sha512-JKlEohxDIJRjwBH/+BrTcAPHljBALrAHw3Zs99RqZlaC605f6BggqXhxkdqZThbSHgaYPwpNJlf9bTSWkb/1rA==",
"dependencies": {
"minimist": "^1.2.6",
"readable-stream": "^4.3.0",
"string.prototype.replaceall": "^1.0.6"
},
"bin": {
"node--test": "bin/node--test.js",
"node--test-name-pattern": "bin/node--test-name-pattern.js",
"node--test-only": "bin/node--test-only.js",
"test": "bin/node-core-test.js"
}
},
"node_modules/typed-array-buffer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz",
"integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==",
"dependencies": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.2.1",
"is-typed-array": "^1.1.10"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/typed-array-byte-length": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz",
"integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==",
"dependencies": {
"call-bind": "^1.0.2",
"for-each": "^0.3.3",
"has-proto": "^1.0.1",
"is-typed-array": "^1.1.10"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/typed-array-byte-offset": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz",
"integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==",
"dependencies": {
"available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2",
"for-each": "^0.3.3",
"has-proto": "^1.0.1",
"is-typed-array": "^1.1.10"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/typed-array-length": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
"integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
"dependencies": {
"call-bind": "^1.0.2",
"for-each": "^0.3.3",
"is-typed-array": "^1.1.9"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/typescript": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
"integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/unbox-primitive": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
"integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
"dependencies": {
"call-bind": "^1.0.2",
"has-bigints": "^1.0.2",
"has-symbols": "^1.0.3",
"which-boxed-primitive": "^1.0.2"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/which-boxed-primitive": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
"integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
"dependencies": {
"is-bigint": "^1.0.1",
"is-boolean-object": "^1.1.0",
"is-number-object": "^1.0.4",
"is-string": "^1.0.5",
"is-symbol": "^1.0.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/which-typed-array": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz",
"integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==",
"dependencies": {
"available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
}
}
}

21
package.json Normal file
View File

@ -0,0 +1,21 @@
{
"name": "workflow-visualiser",
"version": "1.0.0",
"description": "Visualiser for Uni2work workflows",
"type": "module",
"scripts": {
"start": "start ./editor.html; cd spaß; py ../server.py",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://gitlab.uniworx.de/uni2work/workflows/workflow-visualiser"
},
"author": "David Mosbach",
"license": "AGPL-3.0-or-later",
"dependencies": {
"commonjs": "^0.0.1",
"flexsearch": "^0.7.31",
"typescript": "^5.1.6"
}
}

109
tsconfig.json Normal file
View File

@ -0,0 +1,109 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
//"lib": ["es2022"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "es6", /* Specify what module code is generated. */
// "rootDir": "./", /* Specify the root folder within your source files. */
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
// "outDir": "./", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}

View File

@ -1,92 +1,282 @@
class Role {
constructor(json) {
this.json = json;
if (json.tag == 'payload-reference') {
this.name = json['payload-label'];
} else if (json.authorized) {
this.name = json.authorized['dnf-terms'][0][0].var + ' (auth)';
} else if (json.user) {
this.name = json.user;
} else if (json.tag) {
this.name = json.tag + ' (tag)';
} else {
this.name = JSON.stringify(json);
export class Workflow {
states;
actions;
constructor(json) {
const stateMap = new Map();
this.states = [];
for (const state of json.states) {
var node = new WFNode(state);
this.states.push(node);
stateMap.set(node.id, node);
}
// Resolve ID refs to nodes
var actions = json.actions.map(action => {
function transformRef(ref) {
if (ref instanceof String)
stateMap.has(ref)
&& (ref = stateMap.get(ref))
|| console.error('Ref to unknown state: ' + ref);
return ref;
}
action.source = transformRef(action.source);
action.target = transformRef(action.target);
return action;
});
this.actions = [];
for (const action of actions)
this.actions.push(new WFEdge(action));
}
}
format() {
return [document.createTextNode(this.name)];
}
}
class Message {
constructor(json) {
var content = json.content;
this.fallback = content.fallback;
this.fallbackLang = content['fallback-lang'];
this.translations = content.translations;
this.status = json.status;
this.viewers = [];
json.viewers.forEach(v => this.viewers.push(new Role(v)));
}
format() {
var v = document.createElement('h3');
var viewers = document.createTextNode('Viewers');
v.appendChild(viewers);
var viewerList = document.createElement('ul');
this.viewers.forEach(v => {
var viewer = document.createElement('li');
viewer.appendChild(document.createTextNode(v.name));
viewerList.appendChild(viewer);
});
var h = document.createElement('h3');
var heading = document.createTextNode('Status');
h.appendChild(heading);
var p = document.createElement('p');
var text = document.createTextNode(this.status);
p.appendChild(text);
var result = [v, viewerList, h, p];
h = document.createElement('h3');
heading = document.createTextNode(this.fallbackLang);
h.appendChild(heading);
p = document.createElement('html');
p.setAttribute('lang', this.fallbackLang);
p.innerHTML = this.fallback;
result.push(h, p);
for (var t in this.translations) {
h = document.createElement('h3');
heading = document.createTextNode(t);
h.appendChild(heading);
p = document.createElement('html');
p.setAttribute('lang', this.translations[t]);
p.innerHTML = this.translations[t];
result.push(h, p);
export class WFNode {
stateData;
x;
y;
fx;
fy;
id;
name;
val;
constructor(json) {
this.stateData = new StateData(json.stateData);
this.x = json.x;
this.y = json.y;
this.fx = json.fx;
this.fy = json.fy;
this.id = json.id;
this.name = json.name;
this.val = json.val;
}
return result;
}
}
class Payload {
constructor(json) {
this.fields = [];
if (json === null) return;
for (var f in json) {
this.fields.push(f);
export class StateData {
abbreviation;
messages;
viewers;
payload;
viewerNames;
final;
constructor(json) {
this.abbreviation = json.abbreviation;
this.messages = json.messages ? json.messages.map(message => { return new Message(message); }) : [];
this.viewers = json.viewers ? new Viewers(json.viewers) : Viewers.empty();
this.payload = new Payload(json.payload);
this.viewerNames = [];
this.final = json.final;
}
}
format() {
var fieldList = document.createElement('ul');
this.fields.forEach(f => {
var field = document.createElement('li');
field.appendChild(document.createTextNode(f));
fieldList.appendChild(field);
});
return [fieldList];
}
}
}
export class WFEdge {
actionData;
source;
target;
id;
name;
nodePairId;
curvature;
__controlPoints;
constructor(json) {
this.actionData = new ActionData(json.actionData);
this.source = json.source;
this.target = json.target;
this.id = json.id;
this.name = json.name;
this.nodePairId = json.nodePairId;
this.curvature = 0;
}
}
export class ActionData {
messages;
viewers;
actors;
'actor Viewers';
form;
viewerNames;
actorNames;
mode;
constructor(json) {
this.messages = json.messages ? json.messages.map(message => { return new Message(message); }) : [];
this.viewers = json.viewers ? new Viewers(json.viewers) : Viewers.empty();
this.actors = json.actors ? new Actors(json.actors) : Actors.empty();
this['actor Viewers'] = json['actor Viewers'] ? new Viewers(json['actor Viewers']) : Viewers.empty();
this.form = new Payload(json.form);
this.viewerNames = [];
this.actorNames = [];
this.mode = json.mode ?? undefined;
}
}
export class Role {
json;
name;
constructor(json) {
this.json = json;
if (json.tag == 'payload-reference') {
this.name = json['payload-label'];
}
else if (json.authorized) {
this.name = json.authorized['dnf-terms'][0][0].var + ' (auth)'; //TODO ugly
}
else if (json.user) {
this.name = json.user;
}
else if (json.tag) {
this.name = json.tag + ' (tag)';
}
else {
this.name = JSON.stringify(json);
}
}
format() {
return [document.createTextNode(this.name)];
}
}
export class Roles {
roleName;
anchor;
comment;
roles;
constructor(json, roleName) {
this.roleName = roleName;
this.anchor = json.anchor ? new Anchor(json.anchor) : new Anchor('NoAnchor');
this.roles = [];
for (const role of json[roleName])
this.roles.push(new Role(role));
this.comment = json.comment;
}
length() {
return this.roles.length;
}
format() {
var r = document.createElement('h4');
var roles = document.createTextNode('Roles');
r.appendChild(roles);
var rolesList = document.createElement('ul');
this.roles.forEach(r => {
var role = document.createElement('li');
role.appendChild(document.createTextNode(r.name));
rolesList.appendChild(role);
});
var result = [];
if (this.comment.length > 0) {
var c = document.createElement('h4');
c.innerText = 'Comment';
var comment = document.createElement('p');
comment.innerText = this.comment.join(' ');
result.push(c, comment);
}
if (this.anchor) {
var a = document.createElement('h4');
a.appendChild(this.anchor.format());
result.push(a);
}
else
result.push(r);
result.push(rolesList);
return result;
}
}
export class Viewers extends Roles {
static empty() {
return new Viewers({
viewers: [],
anchor: 'NoAnchor',
comment: []
});
}
constructor(json) {
super(json, 'viewers');
}
}
export class Actors extends Roles {
static empty() {
return new Actors({
actors: [],
anchor: 'NoAnchor',
comment: []
});
}
constructor(json) {
super(json, 'actors');
}
}
export class Anchor {
name;
type;
constructor(json) {
if (!json || json === 'NoAnchor') {
this.name = undefined;
this.type = 'none';
}
else {
this.name = json.name;
this.type = json.type;
}
}
format() {
return document.createTextNode(`${this.type == 'alias' ? '*' : '&'}${this.name}`);
}
}
export class Message {
fallback;
fallbackLang;
translations;
status;
viewers;
constructor(json) {
var content = json.content;
this.fallback = content.fallback;
this.fallbackLang = content['fallback-lang'];
this.translations = content.translations;
this.status = json.status;
this.viewers = new Viewers(json.viewers);
}
format() {
var v = document.createElement('h3');
var viewers = document.createTextNode('Viewers');
v.appendChild(viewers);
var viewerList = this.viewers.format();
var h = document.createElement('h3');
var heading = document.createTextNode('Status');
h.appendChild(heading);
var p = document.createElement('p');
var text = document.createTextNode(this.status);
p.appendChild(text);
var result = [v];
result = result.concat(viewerList);
result.push(h, p);
h = document.createElement('h3');
heading = document.createTextNode(this.fallbackLang);
h.appendChild(heading);
p = document.createElement('html');
p.setAttribute('lang', this.fallbackLang);
p.innerHTML = this.fallback;
result.push(h, p);
for (var t in this.translations) {
h = document.createElement('h3');
heading = document.createTextNode(t);
h.appendChild(heading);
p = document.createElement('html');
p.setAttribute('lang', this.translations[t]);
p.innerHTML = this.translations[t];
result.push(h, p);
}
return result;
}
}
export class Payload {
fields;
constructor(json) {
this.fields = [];
if (json === undefined)
return;
for (var f in json) {
this.fields.push(f);
}
}
format() {
var fieldList = document.createElement('ul');
this.fields.forEach(f => {
var field = document.createElement('li');
field.appendChild(document.createTextNode(f));
fieldList.appendChild(field);
});
return [fieldList];
}
}

392
workflow.ts Normal file
View File

@ -0,0 +1,392 @@
export type WF = {
states : NodeFormat[],
actions : EdgeFormat[]
}
export type NodeFormat = {
stateData: SDFormat,
x: number,
y: number,
fx: number,
fy: number,
id: string,
name: string,
val: number
}
export type SDFormat = {
abbreviation: string,
final: boolean | string,
messages?: MessageFormat[],
viewers?: RolesFormat,
payload?: string[]
}
export type EdgeFormat = {
actionData: ADFormat,
source: WFNode | string,
target: WFNode | string,
id: string,
name: string,
nodePairId : string
}
export type ActionMode = 'initial' | 'manual' | 'automatic';
export type ADFormat = {
messages?: MessageFormat[],
viewers?: RolesFormat,
actors?: RolesFormat,
['actor Viewers']?: RolesFormat,
mode?: ActionMode,
form?: string[]
}
export type RoleFormat = {
tag : string | null,
authorized : JSON | null,
user : string | null,
'payload-label': string | null
}
export type RoleName = 'actors' | 'viewers';
export type RolesFormat = {
[roleName: string]: any,
anchor: AnchorFormat,
comment: string[]
}
export type AnchorFormat = {
name: string,
type: AnchorType
} | 'NoAnchor' | null //TODO either NoAnchor or null in parser
export type AnchorType = 'anchor' | 'alias' | 'none'
export type MessageFormat = {
content: {
fallback: string,
'fallback-lang': string,
translations: JSON
},
status: string,
viewers: RolesFormat
}
export class Workflow {
states: WFNode[];
actions: WFEdge[];
constructor(json: WF) {
const stateMap: Map<string, WFNode> = new Map();
this.states = [];
for (const state of json.states) {
var node = new WFNode(state);
this.states.push(node);
stateMap.set(node.id, node);
}
// Resolve ID refs to nodes
var actions = json.actions.map(action => {
function transformRef(ref: string | WFNode) {
if (ref instanceof String)
stateMap.has(<string>ref)
&& (ref = <WFNode>stateMap.get(<string>ref))
|| console.error('Ref to unknown state: ' + ref);
return ref;
}
action.source = transformRef(action.source);
action.target = transformRef(action.target);
return action;
});
this.actions = [];
for (const action of actions)
this.actions.push(new WFEdge(action));
}
}
export class WFNode {
stateData: StateData;
x: number;
y: number;
fx: number;
fy: number;
id: string;
name: string;
val: number;
constructor(json: NodeFormat) {
this.stateData = new StateData(json.stateData);
this.x = json.x;
this.y = json.y;
this.fx = json.fx;
this.fy = json.fy;
this.id = json.id;
this.name = json.name;
this.val = json.val;
}
}
export class StateData {
abbreviation: string;
messages: Message[];
viewers: Viewers;
payload: Payload;
viewerNames: string[];
final: boolean | string;
constructor(json: SDFormat) {
this.abbreviation = json.abbreviation;
this.messages = json.messages ? json.messages.map(message => { return new Message(message) }) : [];
this.viewers = json.viewers ? new Viewers(json.viewers) : Viewers.empty();
this.payload = new Payload(json.payload);
this.viewerNames = [];
this.final = json.final;
}
}
export class WFEdge {
actionData: ActionData;
source: WFNode;
target: WFNode;
id: string;
name: string;
nodePairId : string;
curvature: number;
__controlPoints?: any;
constructor(json: EdgeFormat) {
this.actionData = new ActionData(json.actionData);
this.source = <WFNode>json.source;
this.target = <WFNode>json.target;
this.id = json.id;
this.name = json.name;
this.nodePairId = json.nodePairId;
this.curvature = 0;
}
}
export class ActionData {
messages: Message[];
viewers: Viewers;
actors: Actors;
'actor Viewers': Viewers;
form: Payload;
viewerNames: string[];
actorNames: string[];
mode: ActionMode | undefined;
constructor(json: ADFormat) {
this.messages = json.messages ? json.messages.map(message => { return new Message(message) }) : [];
this.viewers = json.viewers ? new Viewers(json.viewers) : Viewers.empty();
this.actors = json.actors ? new Actors(json.actors) : Actors.empty();
this['actor Viewers'] = json['actor Viewers'] ? new Viewers(json['actor Viewers']) : Viewers.empty();
this.form = new Payload(json.form);
this.viewerNames = [];
this.actorNames = [];
this.mode = json.mode ?? undefined;
}
}
export class Role {
json: RoleFormat;
name: string;
constructor(json: RoleFormat) {
this.json = json;
if (json.tag == 'payload-reference') {
this.name = <string>json['payload-label' as keyof RoleFormat];
} else if (json.authorized) {
this.name = (<any[]><unknown>json.authorized['dnf-terms' as keyof JSON])[0][0].var + ' (auth)'; //TODO ugly
} else if (json.user) {
this.name = json.user;
} else if (json.tag) {
this.name = json.tag + ' (tag)';
} else {
this.name = JSON.stringify(json);
}
}
format() {
return [document.createTextNode(this.name)];
}
}
export class Roles {
roleName: RoleName;
anchor: Anchor;
comment: string[];
roles: Role[];
constructor(json: RolesFormat, roleName: RoleName) {
this.roleName = roleName
this.anchor = json.anchor ? new Anchor(json.anchor) : new Anchor('NoAnchor');
this.roles = [];
for (const role of json[roleName as keyof RolesFormat])
this.roles.push(new Role(role));
this.comment = json.comment;
}
length() {
return this.roles.length;
}
format() {
var r = document.createElement('h4');
var roles = document.createTextNode('Roles');
r.appendChild(roles);
var rolesList = document.createElement('ul');
this.roles.forEach(r => {
var role = document.createElement('li');
role.appendChild(document.createTextNode(r.name));
rolesList.appendChild(role);
});
var result: HTMLElement[] = [];
if (this.comment.length > 0) {
var c = document.createElement('h4');
c.innerText = 'Comment';
var comment = document.createElement('p');
comment.innerText = this.comment.join(' ');
result.push(c, comment);
}
if (this.anchor) {
var a = document.createElement('h4');
a.appendChild(this.anchor.format());
result.push(a);
} else result.push(r)
result.push(rolesList);
return result;
}
}
export class Viewers extends Roles {
static empty() {
return new Viewers({
viewers: [],
anchor: 'NoAnchor',
comment: []
})
}
constructor(json: RolesFormat) {
super(json, 'viewers');
}
}
export class Actors extends Roles {
static empty() {
return new Actors({
actors: [],
anchor: 'NoAnchor',
comment: []
})
}
constructor(json: RolesFormat) {
super(json, 'actors');
}
}
export class Anchor {
name: string | undefined;
type: AnchorType;
constructor(json: AnchorFormat) {
if (!json || json === 'NoAnchor') {
this.name = undefined;
this.type = 'none';
} else {
this.name = json.name;
this.type = json.type;
}
}
format() {
return document.createTextNode(`${this.type == 'alias' ? '*' : '&'}${this.name}`);
}
}
export class Message {
fallback: string;
fallbackLang: string;
translations: JSON;
status: string;
viewers: Viewers;
constructor(json: MessageFormat) {
var content = json.content;
this.fallback = content.fallback;
this.fallbackLang = content['fallback-lang'];
this.translations = content.translations;
this.status = json.status;
this.viewers = new Viewers(json.viewers);
}
format() {
var v = document.createElement('h3');
var viewers = document.createTextNode('Viewers');
v.appendChild(viewers);
var viewerList = this.viewers.format();
var h = document.createElement('h3');
var heading = document.createTextNode('Status');
h.appendChild(heading);
var p: HTMLElement = document.createElement('p');
var text = document.createTextNode(this.status);
p.appendChild(text);
var result: HTMLElement[] = [v];
result = result.concat(viewerList);
result.push(h, p);
h = document.createElement('h3');
heading = document.createTextNode(this.fallbackLang);
h.appendChild(heading);
p = document.createElement('html');
p.setAttribute('lang', this.fallbackLang);
p.innerHTML = this.fallback;
result.push(h, p);
for (var t in this.translations) {
h = document.createElement('h3');
heading = document.createTextNode(t);
h.appendChild(heading);
p = document.createElement('html');
p.setAttribute('lang', <string>this.translations[t as keyof JSON]);
p.innerHTML = <string>this.translations[t as keyof JSON];
result.push(h, p);
}
return result;
}
}
export class Payload {
fields: string[]
constructor(json: string[] | undefined) {
this.fields = [];
if (json === undefined) return;
for (var f in json) {
this.fields.push(f);
}
}
format() {
var fieldList = document.createElement('ul');
this.fields.forEach(f => {
var field = document.createElement('li');
field.appendChild(document.createTextNode(f));
fieldList.appendChild(field);
});
return [fieldList];
}
}