@bpmnkit/core 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -1
- package/dist/bpmn/bpmn-builder.d.ts +209 -3
- package/dist/bpmn/bpmn-builder.js +456 -16
- package/dist/bpmn/bpmn-model.d.ts +110 -0
- package/dist/bpmn/bpmn-parser.js +1413 -528
- package/dist/bpmn/bpmn-serializer.js +101 -19
- package/dist/bpmn/compact.d.ts +17 -2
- package/dist/bpmn/compact.js +3 -3
- package/dist/bpmn/full-operations.d.ts +89 -0
- package/dist/bpmn/full-operations.js +478 -0
- package/dist/bpmn/index.d.ts +19 -0
- package/dist/bpmn/index.js +21 -0
- package/dist/bpmn/optimize/feel.js +2 -2
- package/dist/bpmn/optimize/patterns.js +23 -16
- package/dist/bpmn/optimize/tasks.js +30 -7
- package/dist/bpmn/optimize/utils.js +2 -4
- package/dist/bpmn/optimize/variable-flow.js +58 -67
- package/dist/bpmn/semantic-hash.d.ts +93 -0
- package/dist/bpmn/semantic-hash.js +155 -0
- package/dist/bpmn/sha256.d.ts +17 -0
- package/dist/bpmn/sha256.js +95 -0
- package/dist/bpmn/zeebe-extensions.d.ts +56 -0
- package/dist/bpmn/zeebe-extensions.js +79 -0
- package/dist/bpmn/zeebe-placement.d.ts +12 -0
- package/dist/bpmn/zeebe-placement.js +140 -0
- package/dist/errors.d.ts +40 -1
- package/dist/errors.js +41 -0
- package/dist/index.d.ts +10 -4
- package/dist/index.js +7 -3
- package/dist/layout/semantic/graph.d.ts +9 -1
- package/dist/layout/semantic/graph.js +42 -17
- package/dist/layout/semantic/route.js +102 -42
- package/dist/node/index.d.ts +10 -0
- package/dist/node/index.js +9 -0
- package/dist/node/write.d.ts +81 -0
- package/dist/node/write.js +167 -0
- package/dist/types/id-generator.js +11 -3
- package/dist/xml/index.d.ts +3 -1
- package/dist/xml/index.js +2 -1
- package/dist/xml/xml-parser.d.ts +32 -0
- package/dist/xml/xml-parser.js +394 -143
- package/package.json +8 -1
package/dist/bpmn/bpmn-parser.js
CHANGED
|
@@ -1,40 +1,34 @@
|
|
|
1
1
|
import { ParseError } from "../errors.js";
|
|
2
|
-
import {
|
|
3
|
-
// ---------------------------------------------------------------------------
|
|
4
|
-
// Helpers
|
|
5
|
-
// ---------------------------------------------------------------------------
|
|
2
|
+
import { Visit, scanXml } from "../xml/xml-parser.js";
|
|
6
3
|
function localName(name) {
|
|
7
4
|
const idx = name.indexOf(":");
|
|
8
5
|
return idx >= 0 ? name.slice(idx + 1) : name;
|
|
9
6
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
/** True when `qname` is `local` or `<prefix>:<local>` — without slicing a new string. */
|
|
8
|
+
function hasLocalName(qname, local) {
|
|
9
|
+
const idx = qname.indexOf(":");
|
|
10
|
+
if (idx < 0)
|
|
11
|
+
return qname === local;
|
|
12
|
+
return qname.length - idx - 1 === local.length && qname.endsWith(local);
|
|
15
13
|
}
|
|
16
|
-
function attr(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
function attr(attributes, name) {
|
|
15
|
+
const direct = attributes[name];
|
|
16
|
+
if (direct !== undefined)
|
|
17
|
+
return direct;
|
|
18
|
+
// Fall back to a namespace-qualified spelling of the same attribute.
|
|
19
|
+
for (const key in attributes) {
|
|
20
|
+
if (key.length > name.length && hasLocalName(key, name))
|
|
21
|
+
return attributes[key];
|
|
22
22
|
}
|
|
23
23
|
return undefined;
|
|
24
24
|
}
|
|
25
|
-
function requiredAttr(
|
|
26
|
-
const value = attr(
|
|
25
|
+
function requiredAttr(attributes, name, elementName) {
|
|
26
|
+
const value = attr(attributes, name);
|
|
27
27
|
if (value === undefined) {
|
|
28
|
-
throw new ParseError(`Missing required attribute "${name}" on <${
|
|
28
|
+
throw new ParseError(`Missing required attribute "${name}" on <${elementName}>`);
|
|
29
29
|
}
|
|
30
30
|
return value;
|
|
31
31
|
}
|
|
32
|
-
/** Collect text from child <bpmn:incoming> / <bpmn:outgoing> elements. */
|
|
33
|
-
function collectFlowRefs(element, tag) {
|
|
34
|
-
return findChildren(element, tag)
|
|
35
|
-
.map((c) => c.text?.trim())
|
|
36
|
-
.filter((t) => !!t);
|
|
37
|
-
}
|
|
38
32
|
/** Known attribute names on flow nodes — everything else goes to unknownAttributes. */
|
|
39
33
|
const KNOWN_ATTRS = new Set([
|
|
40
34
|
"id",
|
|
@@ -59,22 +53,23 @@ const KNOWN_ATTRS = new Set([
|
|
|
59
53
|
"exporter",
|
|
60
54
|
"exporterVersion",
|
|
61
55
|
"processRef",
|
|
56
|
+
"messageRef",
|
|
62
57
|
"dataObjectRef",
|
|
63
58
|
"dataStoreRef",
|
|
64
59
|
"isCollection",
|
|
65
60
|
"categoryValueRef",
|
|
66
61
|
]);
|
|
67
62
|
/** Extract unknown (namespace-qualified) attributes from an element. */
|
|
68
|
-
function unknownAttrs(
|
|
63
|
+
function unknownAttrs(attributes) {
|
|
69
64
|
const result = {};
|
|
70
|
-
for (const
|
|
71
|
-
if (key.startsWith("xmlns:") || key === "xmlns")
|
|
72
|
-
continue;
|
|
65
|
+
for (const key in attributes) {
|
|
73
66
|
if (KNOWN_ATTRS.has(key))
|
|
74
67
|
continue;
|
|
75
|
-
if (
|
|
68
|
+
if (key.startsWith("xmlns:") || key === "xmlns")
|
|
69
|
+
continue;
|
|
70
|
+
if (key.includes(":") && KNOWN_ATTRS.has(localName(key)))
|
|
76
71
|
continue;
|
|
77
|
-
result[key] =
|
|
72
|
+
result[key] = attributes[key];
|
|
78
73
|
}
|
|
79
74
|
return result;
|
|
80
75
|
}
|
|
@@ -129,114 +124,298 @@ const KNOWN_PROCESS_CHILDREN = new Set([
|
|
|
129
124
|
"extensionElements",
|
|
130
125
|
]);
|
|
131
126
|
// ---------------------------------------------------------------------------
|
|
132
|
-
//
|
|
127
|
+
// Streaming model builder
|
|
128
|
+
//
|
|
129
|
+
// The document is scanned once. Each known element gets a small frame that
|
|
130
|
+
// keeps only what the model needs and builds the model object at the end tag,
|
|
131
|
+
// in the same field order the former tree walk produced. Unknown children are
|
|
132
|
+
// skipped by the scanner without any allocation; only the content of
|
|
133
|
+
// <extensionElements> is still materialised as XmlElement trees, because the
|
|
134
|
+
// model keeps it verbatim.
|
|
133
135
|
// ---------------------------------------------------------------------------
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
/** One element's handler while the scanner is inside it. */
|
|
137
|
+
class Frame {
|
|
138
|
+
/** Whether this frame reads character data; the scanner skips it otherwise. */
|
|
139
|
+
wantsText = false;
|
|
140
|
+
/** A child start tag: the frame for it, or null to skip its whole subtree. */
|
|
141
|
+
child(_local, _name, _attrs) {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
/** Character data directly inside this element. */
|
|
145
|
+
text(_text) { }
|
|
137
146
|
}
|
|
138
|
-
//
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
147
|
+
// Which text-bearing child a TextFrame reports back to its owner.
|
|
148
|
+
const SLOT_INCOMING = 0;
|
|
149
|
+
const SLOT_OUTGOING = 1;
|
|
150
|
+
const SLOT_DOCUMENTATION = 2;
|
|
151
|
+
const SLOT_FLOW_NODE_REF = 3;
|
|
152
|
+
const SLOT_TEXT = 4;
|
|
153
|
+
const SLOT_CONDITION_EXPRESSION = 5;
|
|
154
|
+
const SLOT_COMPLETION_CONDITION = 6;
|
|
155
|
+
const SLOT_TIME_DURATION = 7;
|
|
156
|
+
const SLOT_TIME_DATE = 8;
|
|
157
|
+
const SLOT_TIME_CYCLE = 9;
|
|
158
|
+
const SLOT_CONDITION = 10;
|
|
159
|
+
const SLOT_LOOP_CARDINALITY = 13;
|
|
160
|
+
/** Collects the direct character data of a leaf element; its children are skipped. */
|
|
161
|
+
class TextFrame extends Frame {
|
|
162
|
+
owner;
|
|
163
|
+
slot;
|
|
164
|
+
attrs;
|
|
165
|
+
wantsText = true;
|
|
166
|
+
value;
|
|
167
|
+
constructor(owner, slot, attrs) {
|
|
168
|
+
super();
|
|
169
|
+
this.owner = owner;
|
|
170
|
+
this.slot = slot;
|
|
171
|
+
this.attrs = attrs;
|
|
172
|
+
}
|
|
173
|
+
text(text) {
|
|
174
|
+
this.value = this.value === undefined ? text : this.value + text;
|
|
175
|
+
}
|
|
176
|
+
finish() {
|
|
177
|
+
this.owner.setText(this.slot, this.value, this.attrs);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/** Materialises the children of an <extensionElements> as XmlElement trees. */
|
|
181
|
+
class TreeFrame extends Frame {
|
|
182
|
+
target;
|
|
183
|
+
owner;
|
|
184
|
+
wantsText = true;
|
|
185
|
+
stack = [];
|
|
186
|
+
/**
|
|
187
|
+
* @param target - Where top-level children are appended.
|
|
188
|
+
* @param owner - Element receiving character data directly inside it, when
|
|
189
|
+
* the frame stands for an element rather than a bare child list.
|
|
190
|
+
*/
|
|
191
|
+
constructor(target, owner) {
|
|
192
|
+
super();
|
|
193
|
+
this.target = target;
|
|
194
|
+
this.owner = owner;
|
|
195
|
+
}
|
|
196
|
+
child(_local, name, attrs) {
|
|
197
|
+
const el = { name, attributes: attrs, children: [] };
|
|
198
|
+
const parent = this.stack[this.stack.length - 1];
|
|
199
|
+
if (parent)
|
|
200
|
+
parent.children.push(el);
|
|
201
|
+
else
|
|
202
|
+
this.target.push(el);
|
|
203
|
+
this.stack.push(el);
|
|
204
|
+
return this;
|
|
205
|
+
}
|
|
206
|
+
text(text) {
|
|
207
|
+
const el = this.stack[this.stack.length - 1] ?? this.owner;
|
|
208
|
+
if (el)
|
|
209
|
+
el.text = el.text === undefined ? text : el.text + text;
|
|
210
|
+
}
|
|
211
|
+
finish() {
|
|
212
|
+
dropLayoutWhitespace(this.stack.pop() ?? this.owner);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Clears an element's text when it is only the indentation between its child
|
|
217
|
+
* elements. Without this, re-serialising a nested extension or captured subtree
|
|
218
|
+
* re-emits that indentation as content and it grows on every round trip.
|
|
219
|
+
*/
|
|
220
|
+
function dropLayoutWhitespace(element) {
|
|
221
|
+
if (element === undefined)
|
|
222
|
+
return;
|
|
223
|
+
if (element.children.length > 0 && element.text !== undefined && element.text.trim() === "") {
|
|
224
|
+
element.text = undefined;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Shared handling of the two children every BPMN base element may have.
|
|
229
|
+
*
|
|
230
|
+
* Subclasses call {@link baseChild} first and fall through to their own cases,
|
|
231
|
+
* and read {@link baseFields} when building their model object. Frames that
|
|
232
|
+
* also collect text children override {@link baseText}.
|
|
233
|
+
*/
|
|
234
|
+
class BaseElementFrame extends Frame {
|
|
235
|
+
documentation;
|
|
236
|
+
documentationSeen = false;
|
|
237
|
+
extensions = null;
|
|
238
|
+
/** A base child's frame, or `undefined` when `local` is not one. */
|
|
239
|
+
baseChild(local, attrs) {
|
|
240
|
+
switch (local) {
|
|
241
|
+
case "documentation":
|
|
242
|
+
if (this.documentationSeen)
|
|
243
|
+
return null;
|
|
244
|
+
this.documentationSeen = true;
|
|
245
|
+
return new TextFrame(this, SLOT_DOCUMENTATION, attrs);
|
|
246
|
+
case "extensionElements":
|
|
247
|
+
if (this.extensions !== null)
|
|
248
|
+
return null;
|
|
249
|
+
this.extensions = [];
|
|
250
|
+
return new TreeFrame(this.extensions);
|
|
251
|
+
default:
|
|
252
|
+
return undefined;
|
|
217
253
|
}
|
|
218
|
-
|
|
219
|
-
|
|
254
|
+
}
|
|
255
|
+
/** Only defined keys, so model objects keep the shape they had before. */
|
|
256
|
+
baseFields() {
|
|
257
|
+
const fields = {};
|
|
258
|
+
if (this.documentation !== undefined)
|
|
259
|
+
fields.documentation = this.documentation;
|
|
260
|
+
if (this.extensions !== null && this.extensions.length > 0) {
|
|
261
|
+
fields.extensionElements = this.extensions;
|
|
220
262
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
263
|
+
return fields;
|
|
264
|
+
}
|
|
265
|
+
setText(slot, text, attrs) {
|
|
266
|
+
if (slot === SLOT_DOCUMENTATION) {
|
|
267
|
+
this.documentation = text;
|
|
268
|
+
return;
|
|
227
269
|
}
|
|
270
|
+
this.baseText(slot, text, attrs);
|
|
271
|
+
}
|
|
272
|
+
/** Text children other than `documentation`. */
|
|
273
|
+
baseText(_slot, _text, _attrs) { }
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Captures an unrecognised child subtree verbatim so a round trip does not
|
|
277
|
+
* discard it.
|
|
278
|
+
*
|
|
279
|
+
* Only ever called from a frame's `default:` branch — the path that means "this
|
|
280
|
+
* element is not part of the model". Children a frame recognises but chooses
|
|
281
|
+
* not to store (a second `documentation`, a loop on a type that cannot loop)
|
|
282
|
+
* keep returning `null`, so nothing is captured twice.
|
|
283
|
+
*/
|
|
284
|
+
function captureUnknown(target, name, attrs) {
|
|
285
|
+
const element = { name, attributes: attrs, children: [] };
|
|
286
|
+
target.push(element);
|
|
287
|
+
return new TreeFrame(element.children, element);
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* A frame for an element whose only children are `documentation` and
|
|
291
|
+
* `extensionElements`; everything else it needs comes from its attributes.
|
|
292
|
+
*/
|
|
293
|
+
class BaseOnlyFrame extends BaseElementFrame {
|
|
294
|
+
attrs;
|
|
295
|
+
build;
|
|
296
|
+
target;
|
|
297
|
+
constructor(attrs, build, target) {
|
|
298
|
+
super();
|
|
299
|
+
this.attrs = attrs;
|
|
300
|
+
this.build = build;
|
|
301
|
+
this.target = target;
|
|
302
|
+
}
|
|
303
|
+
child(local, _name, attrs) {
|
|
304
|
+
return this.baseChild(local, attrs) ?? null;
|
|
305
|
+
}
|
|
306
|
+
finish() {
|
|
307
|
+
this.target.push(this.build(this.attrs, this.baseFields()));
|
|
228
308
|
}
|
|
229
|
-
return defs;
|
|
230
309
|
}
|
|
231
310
|
// ---------------------------------------------------------------------------
|
|
232
|
-
//
|
|
311
|
+
// Attribute-only elements
|
|
233
312
|
// ---------------------------------------------------------------------------
|
|
234
|
-
function
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
313
|
+
function parseAssociation(name, attrs, base = {}) {
|
|
314
|
+
return {
|
|
315
|
+
id: requiredAttr(attrs, "id", name),
|
|
316
|
+
sourceRef: requiredAttr(attrs, "sourceRef", name),
|
|
317
|
+
targetRef: requiredAttr(attrs, "targetRef", name),
|
|
318
|
+
associationDirection: attr(attrs, "associationDirection"),
|
|
319
|
+
...base,
|
|
320
|
+
unknownAttributes: unknownAttrs(attrs),
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
function parseGroup(name, attrs, base = {}) {
|
|
324
|
+
return {
|
|
325
|
+
id: requiredAttr(attrs, "id", name),
|
|
326
|
+
categoryValueRef: attr(attrs, "categoryValueRef"),
|
|
327
|
+
...base,
|
|
328
|
+
unknownAttributes: unknownAttrs(attrs),
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
function parseParticipant(name, attrs, base = {}) {
|
|
332
|
+
return {
|
|
333
|
+
id: requiredAttr(attrs, "id", name),
|
|
334
|
+
name: attr(attrs, "name"),
|
|
335
|
+
processRef: attr(attrs, "processRef"),
|
|
336
|
+
...base,
|
|
337
|
+
unknownAttributes: unknownAttrs(attrs),
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
function parseMessageFlow(name, attrs, base = {}) {
|
|
341
|
+
return {
|
|
342
|
+
id: requiredAttr(attrs, "id", name),
|
|
343
|
+
name: attr(attrs, "name"),
|
|
344
|
+
sourceRef: requiredAttr(attrs, "sourceRef", name),
|
|
345
|
+
targetRef: requiredAttr(attrs, "targetRef", name),
|
|
346
|
+
messageRef: attr(attrs, "messageRef"),
|
|
347
|
+
...base,
|
|
348
|
+
unknownAttributes: unknownAttrs(attrs),
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
function parseError(name, attrs, base = {}) {
|
|
352
|
+
return {
|
|
353
|
+
id: requiredAttr(attrs, "id", name),
|
|
354
|
+
name: attr(attrs, "name"),
|
|
355
|
+
errorCode: attr(attrs, "errorCode"),
|
|
356
|
+
...base,
|
|
357
|
+
unknownAttributes: unknownAttrs(attrs),
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
function parseEscalation(name, attrs, base = {}) {
|
|
361
|
+
return {
|
|
362
|
+
id: requiredAttr(attrs, "id", name),
|
|
363
|
+
name: attr(attrs, "name"),
|
|
364
|
+
escalationCode: attr(attrs, "escalationCode"),
|
|
365
|
+
...base,
|
|
366
|
+
unknownAttributes: unknownAttrs(attrs),
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
function parseMessage(name, attrs, base = {}) {
|
|
370
|
+
return {
|
|
371
|
+
id: requiredAttr(attrs, "id", name),
|
|
372
|
+
name: attr(attrs, "name"),
|
|
373
|
+
...base,
|
|
374
|
+
unknownAttributes: unknownAttrs(attrs),
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
function parseSignal(name, attrs, base = {}) {
|
|
378
|
+
return {
|
|
379
|
+
id: requiredAttr(attrs, "id", name),
|
|
380
|
+
name: attr(attrs, "name"),
|
|
381
|
+
...base,
|
|
382
|
+
unknownAttributes: unknownAttrs(attrs),
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
function parseBounds(attrs) {
|
|
386
|
+
return {
|
|
387
|
+
x: Number(attr(attrs, "x") ?? "0"),
|
|
388
|
+
y: Number(attr(attrs, "y") ?? "0"),
|
|
389
|
+
width: Number(attr(attrs, "width") ?? "0"),
|
|
390
|
+
height: Number(attr(attrs, "height") ?? "0"),
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
function newContents() {
|
|
394
|
+
return { flowElements: [], sequenceFlows: [], textAnnotations: [], associations: [], groups: [] };
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* A frame for a child of a flow-element container.
|
|
398
|
+
*
|
|
399
|
+
* Returns `null` when the child is recognised but needs no frame, and
|
|
400
|
+
* `undefined` when it is not part of the model — the caller keeps the latter
|
|
401
|
+
* verbatim, so the two cases must stay distinct.
|
|
402
|
+
*/
|
|
403
|
+
function contentsChild(contents, local, name, attrs) {
|
|
404
|
+
if (FLOW_ELEMENT_TYPES.has(local)) {
|
|
405
|
+
return new FlowNodeFrame(local, name, attrs, contents);
|
|
406
|
+
}
|
|
407
|
+
switch (local) {
|
|
408
|
+
case "sequenceFlow":
|
|
409
|
+
return new SequenceFlowFrame(name, attrs, contents);
|
|
410
|
+
case "textAnnotation":
|
|
411
|
+
return new TextAnnotationFrame(name, attrs, contents.textAnnotations);
|
|
412
|
+
case "association":
|
|
413
|
+
return new BaseOnlyFrame(attrs, (a, base) => parseAssociation(name, a, base), contents.associations);
|
|
414
|
+
case "group":
|
|
415
|
+
return new BaseOnlyFrame(attrs, (a, base) => parseGroup(name, a, base), contents.groups);
|
|
416
|
+
default:
|
|
417
|
+
return undefined;
|
|
418
|
+
}
|
|
240
419
|
}
|
|
241
420
|
// ---------------------------------------------------------------------------
|
|
242
421
|
// Flow elements
|
|
@@ -269,452 +448,1158 @@ const FLOW_ELEMENT_TYPES = new Set([
|
|
|
269
448
|
"dataObjectReference",
|
|
270
449
|
"dataStoreReference",
|
|
271
450
|
]);
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
451
|
+
const EVENT_TYPES = new Set([
|
|
452
|
+
"startEvent",
|
|
453
|
+
"endEvent",
|
|
454
|
+
"intermediateCatchEvent",
|
|
455
|
+
"intermediateThrowEvent",
|
|
456
|
+
"boundaryEvent",
|
|
457
|
+
]);
|
|
458
|
+
/** Types whose <multiInstanceLoopCharacteristics> child is read. */
|
|
459
|
+
const LOOP_TYPES = new Set([
|
|
460
|
+
"task",
|
|
461
|
+
"serviceTask",
|
|
462
|
+
"scriptTask",
|
|
463
|
+
"userTask",
|
|
464
|
+
"businessRuleTask",
|
|
465
|
+
"manualTask",
|
|
466
|
+
"callActivity",
|
|
467
|
+
"sendTask",
|
|
468
|
+
"receiveTask",
|
|
469
|
+
"adHocSubProcess",
|
|
470
|
+
"subProcess",
|
|
471
|
+
"transaction",
|
|
472
|
+
]);
|
|
473
|
+
const CONTAINER_TYPES = new Set([
|
|
474
|
+
"adHocSubProcess",
|
|
475
|
+
"subProcess",
|
|
476
|
+
"eventSubProcess",
|
|
477
|
+
"transaction",
|
|
478
|
+
]);
|
|
479
|
+
const EVENT_DEFINITION_TYPES = new Set([
|
|
480
|
+
"timerEventDefinition",
|
|
481
|
+
"errorEventDefinition",
|
|
482
|
+
"escalationEventDefinition",
|
|
483
|
+
"messageEventDefinition",
|
|
484
|
+
"signalEventDefinition",
|
|
485
|
+
"conditionalEventDefinition",
|
|
486
|
+
"linkEventDefinition",
|
|
487
|
+
"cancelEventDefinition",
|
|
488
|
+
"terminateEventDefinition",
|
|
489
|
+
"compensateEventDefinition",
|
|
490
|
+
]);
|
|
491
|
+
class FlowNodeFrame extends Frame {
|
|
492
|
+
type;
|
|
493
|
+
name;
|
|
494
|
+
attrs;
|
|
495
|
+
target;
|
|
496
|
+
id;
|
|
497
|
+
incoming = [];
|
|
498
|
+
outgoing = [];
|
|
499
|
+
documentation;
|
|
500
|
+
documentationSeen = false;
|
|
501
|
+
extensionElements = null;
|
|
502
|
+
eventDefinitions;
|
|
503
|
+
loopCharacteristics;
|
|
504
|
+
loopSeen = false;
|
|
505
|
+
completionCondition;
|
|
506
|
+
completionSeen = false;
|
|
507
|
+
unknownChildren = [];
|
|
508
|
+
properties = [];
|
|
509
|
+
dataInputAssociations = [];
|
|
510
|
+
dataOutputAssociations = [];
|
|
511
|
+
contents;
|
|
512
|
+
constructor(type, name, attrs, target) {
|
|
513
|
+
super();
|
|
514
|
+
this.type = type;
|
|
515
|
+
this.name = name;
|
|
516
|
+
this.attrs = attrs;
|
|
517
|
+
this.target = target;
|
|
518
|
+
this.id = requiredAttr(attrs, "id", name);
|
|
519
|
+
this.eventDefinitions = EVENT_TYPES.has(type) ? [] : null;
|
|
520
|
+
this.contents = CONTAINER_TYPES.has(type) ? newContents() : null;
|
|
521
|
+
}
|
|
522
|
+
child(local, name, attrs) {
|
|
523
|
+
switch (local) {
|
|
524
|
+
case "incoming":
|
|
525
|
+
return new TextFrame(this, SLOT_INCOMING, attrs);
|
|
526
|
+
case "outgoing":
|
|
527
|
+
return new TextFrame(this, SLOT_OUTGOING, attrs);
|
|
528
|
+
case "documentation":
|
|
529
|
+
if (this.documentationSeen)
|
|
530
|
+
return null;
|
|
531
|
+
this.documentationSeen = true;
|
|
532
|
+
return new TextFrame(this, SLOT_DOCUMENTATION, attrs);
|
|
533
|
+
case "extensionElements":
|
|
534
|
+
if (this.extensionElements !== null)
|
|
535
|
+
return null;
|
|
536
|
+
this.extensionElements = [];
|
|
537
|
+
return new TreeFrame(this.extensionElements);
|
|
538
|
+
case "multiInstanceLoopCharacteristics":
|
|
539
|
+
if (!LOOP_TYPES.has(this.type) || this.loopSeen)
|
|
540
|
+
return null;
|
|
541
|
+
this.loopSeen = true;
|
|
542
|
+
return new LoopFrame(attrs, this);
|
|
543
|
+
case "completionCondition":
|
|
544
|
+
if (this.type !== "adHocSubProcess" || this.completionSeen)
|
|
545
|
+
return null;
|
|
546
|
+
this.completionSeen = true;
|
|
547
|
+
return new TextFrame(this, SLOT_COMPLETION_CONDITION, attrs);
|
|
548
|
+
case "property":
|
|
549
|
+
this.properties.push({
|
|
550
|
+
id: attr(attrs, "id"),
|
|
551
|
+
name: attr(attrs, "name"),
|
|
552
|
+
itemSubjectRef: attr(attrs, "itemSubjectRef"),
|
|
553
|
+
unknownAttributes: unknownAttrs(attrs),
|
|
554
|
+
});
|
|
555
|
+
return null;
|
|
556
|
+
case "dataInputAssociation":
|
|
557
|
+
return new DataAssociationFrame(attrs, this.dataInputAssociations);
|
|
558
|
+
case "dataOutputAssociation":
|
|
559
|
+
return new DataAssociationFrame(attrs, this.dataOutputAssociations);
|
|
560
|
+
default:
|
|
561
|
+
break;
|
|
294
562
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
case "intermediateThrowEvent":
|
|
298
|
-
return { ...base, type: ln, eventDefinitions: parseEventDefinitions(element) };
|
|
299
|
-
case "boundaryEvent":
|
|
300
|
-
return {
|
|
301
|
-
...base,
|
|
302
|
-
type: "boundaryEvent",
|
|
303
|
-
attachedToRef: requiredAttr(element, "attachedToRef"),
|
|
304
|
-
cancelActivity: attr(element, "cancelActivity") !== undefined
|
|
305
|
-
? attr(element, "cancelActivity") === "true"
|
|
306
|
-
: undefined,
|
|
307
|
-
eventDefinitions: parseEventDefinitions(element),
|
|
308
|
-
};
|
|
309
|
-
case "task":
|
|
310
|
-
case "serviceTask":
|
|
311
|
-
case "scriptTask":
|
|
312
|
-
case "userTask":
|
|
313
|
-
case "businessRuleTask":
|
|
314
|
-
case "manualTask":
|
|
315
|
-
case "callActivity":
|
|
316
|
-
return {
|
|
317
|
-
...base,
|
|
318
|
-
type: ln,
|
|
319
|
-
loopCharacteristics: parseLoopCharacteristics(element),
|
|
320
|
-
isForCompensation: attr(element, "isForCompensation") === "true" ? true : undefined,
|
|
321
|
-
};
|
|
322
|
-
case "sendTask":
|
|
323
|
-
case "receiveTask":
|
|
324
|
-
return {
|
|
325
|
-
...base,
|
|
326
|
-
type: ln,
|
|
327
|
-
messageRef: attr(element, "messageRef"),
|
|
328
|
-
loopCharacteristics: parseLoopCharacteristics(element),
|
|
329
|
-
isForCompensation: attr(element, "isForCompensation") === "true" ? true : undefined,
|
|
330
|
-
};
|
|
331
|
-
case "adHocSubProcess": {
|
|
332
|
-
const completionEl = findChild(element, "completionCondition");
|
|
333
|
-
return {
|
|
334
|
-
...base,
|
|
335
|
-
type: "adHocSubProcess",
|
|
336
|
-
loopCharacteristics: parseLoopCharacteristics(element),
|
|
337
|
-
completionCondition: completionEl
|
|
338
|
-
? { text: completionEl.text ?? "", attributes: { ...completionEl.attributes } }
|
|
339
|
-
: undefined,
|
|
340
|
-
cancelRemainingInstances: attr(element, "cancelRemainingInstances") !== undefined
|
|
341
|
-
? attr(element, "cancelRemainingInstances") === "true"
|
|
342
|
-
: undefined,
|
|
343
|
-
...parseProcessContents(element),
|
|
344
|
-
};
|
|
563
|
+
if (this.eventDefinitions !== null && EVENT_DEFINITION_TYPES.has(local)) {
|
|
564
|
+
return eventDefinitionFrame(local, attrs, this.eventDefinitions);
|
|
345
565
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
: undefined,
|
|
353
|
-
loopCharacteristics: parseLoopCharacteristics(element),
|
|
354
|
-
...parseProcessContents(element),
|
|
355
|
-
};
|
|
356
|
-
case "eventSubProcess":
|
|
357
|
-
return {
|
|
358
|
-
...base,
|
|
359
|
-
type: "eventSubProcess",
|
|
360
|
-
...parseProcessContents(element),
|
|
361
|
-
};
|
|
362
|
-
case "transaction":
|
|
363
|
-
return {
|
|
364
|
-
...base,
|
|
365
|
-
type: "transaction",
|
|
366
|
-
loopCharacteristics: parseLoopCharacteristics(element),
|
|
367
|
-
...parseProcessContents(element),
|
|
368
|
-
};
|
|
369
|
-
case "exclusiveGateway":
|
|
370
|
-
return { ...base, type: "exclusiveGateway", default: attr(element, "default") };
|
|
371
|
-
case "parallelGateway":
|
|
372
|
-
return { ...base, type: "parallelGateway" };
|
|
373
|
-
case "inclusiveGateway":
|
|
374
|
-
return { ...base, type: "inclusiveGateway", default: attr(element, "default") };
|
|
375
|
-
case "eventBasedGateway":
|
|
376
|
-
return { ...base, type: "eventBasedGateway" };
|
|
377
|
-
case "complexGateway":
|
|
378
|
-
return { ...base, type: "complexGateway", default: attr(element, "default") };
|
|
379
|
-
case "dataObject":
|
|
380
|
-
return {
|
|
381
|
-
...base,
|
|
382
|
-
type: "dataObject",
|
|
383
|
-
...(attr(element, "isCollection") === "true" ? { isCollection: true } : {}),
|
|
384
|
-
};
|
|
385
|
-
case "dataObjectReference":
|
|
386
|
-
return {
|
|
387
|
-
...base,
|
|
388
|
-
type: "dataObjectReference",
|
|
389
|
-
dataObjectRef: attr(element, "dataObjectRef"),
|
|
390
|
-
...(attr(element, "isCollection") === "true" ? { isCollection: true } : {}),
|
|
391
|
-
};
|
|
392
|
-
case "dataStoreReference":
|
|
393
|
-
return {
|
|
394
|
-
...base,
|
|
395
|
-
type: "dataStoreReference",
|
|
396
|
-
dataStoreRef: attr(element, "dataStoreRef"),
|
|
397
|
-
};
|
|
398
|
-
default:
|
|
399
|
-
return undefined;
|
|
566
|
+
if (this.contents !== null) {
|
|
567
|
+
const child = contentsChild(this.contents, local, name, attrs);
|
|
568
|
+
if (child !== undefined)
|
|
569
|
+
return child;
|
|
570
|
+
}
|
|
571
|
+
return captureUnknown(this.unknownChildren, name, attrs);
|
|
400
572
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
573
|
+
setText(slot, text, attrs) {
|
|
574
|
+
switch (slot) {
|
|
575
|
+
case SLOT_INCOMING: {
|
|
576
|
+
const ref = text?.trim();
|
|
577
|
+
if (ref)
|
|
578
|
+
this.incoming.push(ref);
|
|
579
|
+
break;
|
|
580
|
+
}
|
|
581
|
+
case SLOT_OUTGOING: {
|
|
582
|
+
const ref = text?.trim();
|
|
583
|
+
if (ref)
|
|
584
|
+
this.outgoing.push(ref);
|
|
585
|
+
break;
|
|
586
|
+
}
|
|
587
|
+
case SLOT_DOCUMENTATION:
|
|
588
|
+
this.documentation = text;
|
|
589
|
+
break;
|
|
590
|
+
case SLOT_COMPLETION_CONDITION:
|
|
591
|
+
this.completionCondition = { text: text ?? "", attributes: { ...attrs } };
|
|
592
|
+
break;
|
|
593
|
+
default:
|
|
594
|
+
break;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
setLoopCharacteristics(loop) {
|
|
598
|
+
this.loopCharacteristics = loop;
|
|
599
|
+
}
|
|
600
|
+
finish() {
|
|
601
|
+
const attrs = this.attrs;
|
|
602
|
+
const base = {
|
|
603
|
+
id: this.id,
|
|
604
|
+
...(this.properties.length > 0 ? { properties: this.properties } : {}),
|
|
605
|
+
...(this.dataInputAssociations.length > 0
|
|
606
|
+
? { dataInputAssociations: this.dataInputAssociations }
|
|
607
|
+
: {}),
|
|
608
|
+
...(this.dataOutputAssociations.length > 0
|
|
609
|
+
? { dataOutputAssociations: this.dataOutputAssociations }
|
|
610
|
+
: {}),
|
|
611
|
+
...(this.unknownChildren.length > 0 ? { unknownChildren: this.unknownChildren } : {}),
|
|
612
|
+
name: attr(attrs, "name"),
|
|
613
|
+
incoming: this.incoming,
|
|
614
|
+
outgoing: this.outgoing,
|
|
615
|
+
documentation: this.documentation,
|
|
616
|
+
extensionElements: this.extensionElements ?? [],
|
|
617
|
+
unknownAttributes: unknownAttrs(attrs),
|
|
412
618
|
};
|
|
619
|
+
const eventDefinitions = this.eventDefinitions ?? [];
|
|
620
|
+
const contents = this.contents ?? newContents();
|
|
621
|
+
const type = this.type;
|
|
622
|
+
let el;
|
|
623
|
+
switch (type) {
|
|
624
|
+
case "startEvent": {
|
|
625
|
+
const isInterruptingAttr = attr(attrs, "isInterrupting");
|
|
626
|
+
el = {
|
|
627
|
+
...base,
|
|
628
|
+
type: "startEvent",
|
|
629
|
+
eventDefinitions,
|
|
630
|
+
...(isInterruptingAttr === "false" ? { isInterrupting: false } : {}),
|
|
631
|
+
};
|
|
632
|
+
break;
|
|
633
|
+
}
|
|
634
|
+
case "endEvent":
|
|
635
|
+
case "intermediateCatchEvent":
|
|
636
|
+
case "intermediateThrowEvent":
|
|
637
|
+
el = { ...base, type, eventDefinitions };
|
|
638
|
+
break;
|
|
639
|
+
case "boundaryEvent":
|
|
640
|
+
el = {
|
|
641
|
+
...base,
|
|
642
|
+
type: "boundaryEvent",
|
|
643
|
+
attachedToRef: requiredAttr(attrs, "attachedToRef", this.name),
|
|
644
|
+
cancelActivity: attr(attrs, "cancelActivity") !== undefined
|
|
645
|
+
? attr(attrs, "cancelActivity") === "true"
|
|
646
|
+
: undefined,
|
|
647
|
+
eventDefinitions,
|
|
648
|
+
};
|
|
649
|
+
break;
|
|
650
|
+
case "task":
|
|
651
|
+
case "serviceTask":
|
|
652
|
+
case "scriptTask":
|
|
653
|
+
case "userTask":
|
|
654
|
+
case "businessRuleTask":
|
|
655
|
+
case "manualTask":
|
|
656
|
+
case "callActivity":
|
|
657
|
+
el = {
|
|
658
|
+
...base,
|
|
659
|
+
type,
|
|
660
|
+
loopCharacteristics: this.loopCharacteristics,
|
|
661
|
+
isForCompensation: attr(attrs, "isForCompensation") === "true" ? true : undefined,
|
|
662
|
+
};
|
|
663
|
+
break;
|
|
664
|
+
case "sendTask":
|
|
665
|
+
case "receiveTask":
|
|
666
|
+
el = {
|
|
667
|
+
...base,
|
|
668
|
+
type,
|
|
669
|
+
messageRef: attr(attrs, "messageRef"),
|
|
670
|
+
loopCharacteristics: this.loopCharacteristics,
|
|
671
|
+
isForCompensation: attr(attrs, "isForCompensation") === "true" ? true : undefined,
|
|
672
|
+
};
|
|
673
|
+
break;
|
|
674
|
+
case "adHocSubProcess":
|
|
675
|
+
el = {
|
|
676
|
+
...base,
|
|
677
|
+
type: "adHocSubProcess",
|
|
678
|
+
loopCharacteristics: this.loopCharacteristics,
|
|
679
|
+
completionCondition: this.completionCondition,
|
|
680
|
+
cancelRemainingInstances: attr(attrs, "cancelRemainingInstances") !== undefined
|
|
681
|
+
? attr(attrs, "cancelRemainingInstances") === "true"
|
|
682
|
+
: undefined,
|
|
683
|
+
...contents,
|
|
684
|
+
};
|
|
685
|
+
break;
|
|
686
|
+
case "subProcess":
|
|
687
|
+
el = {
|
|
688
|
+
...base,
|
|
689
|
+
type: "subProcess",
|
|
690
|
+
triggeredByEvent: attr(attrs, "triggeredByEvent") !== undefined
|
|
691
|
+
? attr(attrs, "triggeredByEvent") === "true"
|
|
692
|
+
: undefined,
|
|
693
|
+
loopCharacteristics: this.loopCharacteristics,
|
|
694
|
+
...contents,
|
|
695
|
+
};
|
|
696
|
+
break;
|
|
697
|
+
case "eventSubProcess":
|
|
698
|
+
el = { ...base, type: "eventSubProcess", ...contents };
|
|
699
|
+
break;
|
|
700
|
+
case "transaction":
|
|
701
|
+
el = {
|
|
702
|
+
...base,
|
|
703
|
+
type: "transaction",
|
|
704
|
+
loopCharacteristics: this.loopCharacteristics,
|
|
705
|
+
...contents,
|
|
706
|
+
};
|
|
707
|
+
break;
|
|
708
|
+
case "exclusiveGateway":
|
|
709
|
+
el = { ...base, type: "exclusiveGateway", default: attr(attrs, "default") };
|
|
710
|
+
break;
|
|
711
|
+
case "parallelGateway":
|
|
712
|
+
el = { ...base, type: "parallelGateway" };
|
|
713
|
+
break;
|
|
714
|
+
case "inclusiveGateway":
|
|
715
|
+
el = { ...base, type: "inclusiveGateway", default: attr(attrs, "default") };
|
|
716
|
+
break;
|
|
717
|
+
case "eventBasedGateway":
|
|
718
|
+
el = { ...base, type: "eventBasedGateway" };
|
|
719
|
+
break;
|
|
720
|
+
case "complexGateway":
|
|
721
|
+
el = { ...base, type: "complexGateway", default: attr(attrs, "default") };
|
|
722
|
+
break;
|
|
723
|
+
case "dataObject":
|
|
724
|
+
el = {
|
|
725
|
+
...base,
|
|
726
|
+
type: "dataObject",
|
|
727
|
+
...(attr(attrs, "isCollection") === "true" ? { isCollection: true } : {}),
|
|
728
|
+
};
|
|
729
|
+
break;
|
|
730
|
+
case "dataObjectReference":
|
|
731
|
+
el = {
|
|
732
|
+
...base,
|
|
733
|
+
type: "dataObjectReference",
|
|
734
|
+
dataObjectRef: attr(attrs, "dataObjectRef"),
|
|
735
|
+
...(attr(attrs, "isCollection") === "true" ? { isCollection: true } : {}),
|
|
736
|
+
};
|
|
737
|
+
break;
|
|
738
|
+
case "dataStoreReference":
|
|
739
|
+
el = {
|
|
740
|
+
...base,
|
|
741
|
+
type: "dataStoreReference",
|
|
742
|
+
dataStoreRef: attr(attrs, "dataStoreRef"),
|
|
743
|
+
};
|
|
744
|
+
break;
|
|
745
|
+
default:
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
this.target.flowElements.push(el);
|
|
413
749
|
}
|
|
414
|
-
return {
|
|
415
|
-
id: requiredAttr(element, "id"),
|
|
416
|
-
name: attr(element, "name"),
|
|
417
|
-
sourceRef: requiredAttr(element, "sourceRef"),
|
|
418
|
-
targetRef: requiredAttr(element, "targetRef"),
|
|
419
|
-
conditionExpression,
|
|
420
|
-
extensionElements: parseExtensionElements(element),
|
|
421
|
-
unknownAttributes: unknownAttrs(element),
|
|
422
|
-
};
|
|
423
750
|
}
|
|
424
751
|
// ---------------------------------------------------------------------------
|
|
425
|
-
//
|
|
752
|
+
// Event definitions
|
|
426
753
|
// ---------------------------------------------------------------------------
|
|
427
|
-
function
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
754
|
+
function eventDefinitionFrame(local, attrs, target) {
|
|
755
|
+
switch (local) {
|
|
756
|
+
case "timerEventDefinition":
|
|
757
|
+
return new TimerDefinitionFrame(attrs, target);
|
|
758
|
+
case "conditionalEventDefinition":
|
|
759
|
+
return new ConditionalDefinitionFrame(attrs, target);
|
|
760
|
+
case "errorEventDefinition":
|
|
761
|
+
target.push({ type: "error", id: attr(attrs, "id"), errorRef: attr(attrs, "errorRef") });
|
|
762
|
+
return null;
|
|
763
|
+
case "escalationEventDefinition":
|
|
764
|
+
target.push({
|
|
765
|
+
type: "escalation",
|
|
766
|
+
id: attr(attrs, "id"),
|
|
767
|
+
escalationRef: attr(attrs, "escalationRef"),
|
|
768
|
+
});
|
|
769
|
+
return null;
|
|
770
|
+
case "messageEventDefinition":
|
|
771
|
+
target.push({ type: "message", id: attr(attrs, "id"), messageRef: attr(attrs, "messageRef") });
|
|
772
|
+
return null;
|
|
773
|
+
case "signalEventDefinition":
|
|
774
|
+
target.push({ type: "signal", id: attr(attrs, "id"), signalRef: attr(attrs, "signalRef") });
|
|
775
|
+
return null;
|
|
776
|
+
case "linkEventDefinition":
|
|
777
|
+
target.push({ type: "link", id: attr(attrs, "id"), name: attr(attrs, "name") });
|
|
778
|
+
return null;
|
|
779
|
+
case "cancelEventDefinition":
|
|
780
|
+
target.push({ type: "cancel", id: attr(attrs, "id") });
|
|
781
|
+
return null;
|
|
782
|
+
case "terminateEventDefinition":
|
|
783
|
+
target.push({ type: "terminate", id: attr(attrs, "id") });
|
|
784
|
+
return null;
|
|
785
|
+
case "compensateEventDefinition":
|
|
786
|
+
target.push({
|
|
787
|
+
type: "compensate",
|
|
788
|
+
id: attr(attrs, "id"),
|
|
789
|
+
activityRef: attr(attrs, "activityRef"),
|
|
790
|
+
});
|
|
791
|
+
return null;
|
|
792
|
+
default:
|
|
793
|
+
return null;
|
|
794
|
+
}
|
|
434
795
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
796
|
+
class TimerDefinitionFrame extends Frame {
|
|
797
|
+
attrs;
|
|
798
|
+
target;
|
|
799
|
+
duration;
|
|
800
|
+
date;
|
|
801
|
+
cycle;
|
|
802
|
+
constructor(attrs, target) {
|
|
803
|
+
super();
|
|
804
|
+
this.attrs = attrs;
|
|
805
|
+
this.target = target;
|
|
806
|
+
}
|
|
807
|
+
child(local, _name, attrs) {
|
|
808
|
+
switch (local) {
|
|
809
|
+
case "timeDuration":
|
|
810
|
+
if (this.duration)
|
|
811
|
+
return null;
|
|
812
|
+
this.duration = { text: undefined, attrs };
|
|
813
|
+
return new TextFrame(this, SLOT_TIME_DURATION, attrs);
|
|
814
|
+
case "timeDate":
|
|
815
|
+
if (this.date)
|
|
816
|
+
return null;
|
|
817
|
+
this.date = { text: undefined, attrs };
|
|
818
|
+
return new TextFrame(this, SLOT_TIME_DATE, attrs);
|
|
819
|
+
case "timeCycle":
|
|
820
|
+
if (this.cycle)
|
|
821
|
+
return null;
|
|
822
|
+
this.cycle = { text: undefined, attrs };
|
|
823
|
+
return new TextFrame(this, SLOT_TIME_CYCLE, attrs);
|
|
824
|
+
default:
|
|
825
|
+
return null;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
setText(slot, text) {
|
|
829
|
+
if (slot === SLOT_TIME_DURATION && this.duration)
|
|
830
|
+
this.duration.text = text;
|
|
831
|
+
else if (slot === SLOT_TIME_DATE && this.date)
|
|
832
|
+
this.date.text = text;
|
|
833
|
+
else if (slot === SLOT_TIME_CYCLE && this.cycle)
|
|
834
|
+
this.cycle.text = text;
|
|
835
|
+
}
|
|
836
|
+
finish() {
|
|
837
|
+
this.target.push({
|
|
838
|
+
type: "timer",
|
|
839
|
+
id: attr(this.attrs, "id"),
|
|
840
|
+
timeDuration: this.duration?.text?.trim(),
|
|
841
|
+
timeDurationAttributes: partAttributes(this.duration),
|
|
842
|
+
timeDate: this.date?.text?.trim(),
|
|
843
|
+
timeDateAttributes: partAttributes(this.date),
|
|
844
|
+
timeCycle: this.cycle?.text?.trim(),
|
|
845
|
+
timeCycleAttributes: partAttributes(this.cycle),
|
|
846
|
+
});
|
|
847
|
+
}
|
|
443
848
|
}
|
|
444
|
-
function
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
849
|
+
function partAttributes(part) {
|
|
850
|
+
if (!part)
|
|
851
|
+
return undefined;
|
|
852
|
+
return Object.keys(part.attrs).length > 0 ? { ...part.attrs } : undefined;
|
|
853
|
+
}
|
|
854
|
+
class ConditionalDefinitionFrame extends Frame {
|
|
855
|
+
attrs;
|
|
856
|
+
target;
|
|
857
|
+
conditionSeen = false;
|
|
858
|
+
condition;
|
|
859
|
+
constructor(attrs, target) {
|
|
860
|
+
super();
|
|
861
|
+
this.attrs = attrs;
|
|
862
|
+
this.target = target;
|
|
863
|
+
}
|
|
864
|
+
child(local, _name, attrs) {
|
|
865
|
+
if (local !== "condition" || this.conditionSeen)
|
|
866
|
+
return null;
|
|
867
|
+
this.conditionSeen = true;
|
|
868
|
+
return new TextFrame(this, SLOT_CONDITION, attrs);
|
|
869
|
+
}
|
|
870
|
+
setText(_slot, text) {
|
|
871
|
+
this.condition = text;
|
|
872
|
+
}
|
|
873
|
+
finish() {
|
|
874
|
+
this.target.push({
|
|
875
|
+
type: "conditional",
|
|
876
|
+
id: attr(this.attrs, "id"),
|
|
877
|
+
condition: this.condition?.trim(),
|
|
878
|
+
});
|
|
879
|
+
}
|
|
450
880
|
}
|
|
451
881
|
// ---------------------------------------------------------------------------
|
|
452
|
-
//
|
|
882
|
+
// Multi-instance loop
|
|
453
883
|
// ---------------------------------------------------------------------------
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
884
|
+
class LoopFrame extends Frame {
|
|
885
|
+
attrs;
|
|
886
|
+
owner;
|
|
887
|
+
unknownChildren = [];
|
|
888
|
+
extensionElements = null;
|
|
889
|
+
loopCardinality;
|
|
890
|
+
cardinalitySeen = false;
|
|
891
|
+
completionCondition;
|
|
892
|
+
completionSeen = false;
|
|
893
|
+
constructor(attrs, owner) {
|
|
894
|
+
super();
|
|
895
|
+
this.attrs = attrs;
|
|
896
|
+
this.owner = owner;
|
|
897
|
+
}
|
|
898
|
+
child(local, _name, attrs) {
|
|
899
|
+
switch (local) {
|
|
900
|
+
case "extensionElements":
|
|
901
|
+
if (this.extensionElements !== null)
|
|
902
|
+
return null;
|
|
903
|
+
this.extensionElements = [];
|
|
904
|
+
return new TreeFrame(this.extensionElements);
|
|
905
|
+
case "loopCardinality":
|
|
906
|
+
if (this.cardinalitySeen)
|
|
907
|
+
return null;
|
|
908
|
+
this.cardinalitySeen = true;
|
|
909
|
+
return new TextFrame(this, SLOT_LOOP_CARDINALITY, attrs);
|
|
910
|
+
case "completionCondition":
|
|
911
|
+
if (this.completionSeen)
|
|
912
|
+
return null;
|
|
913
|
+
this.completionSeen = true;
|
|
914
|
+
return new TextFrame(this, SLOT_COMPLETION_CONDITION, attrs);
|
|
915
|
+
default:
|
|
916
|
+
return captureUnknown(this.unknownChildren, _name, attrs);
|
|
478
917
|
}
|
|
479
918
|
}
|
|
480
|
-
|
|
919
|
+
setText(slot, text, attrs) {
|
|
920
|
+
const expression = { text: text ?? "", attributes: { ...attrs } };
|
|
921
|
+
if (slot === SLOT_LOOP_CARDINALITY)
|
|
922
|
+
this.loopCardinality = expression;
|
|
923
|
+
else if (slot === SLOT_COMPLETION_CONDITION)
|
|
924
|
+
this.completionCondition = expression;
|
|
925
|
+
}
|
|
926
|
+
finish() {
|
|
927
|
+
this.owner.setLoopCharacteristics({
|
|
928
|
+
isSequential: this.attrs.isSequential === "true" ? true : undefined,
|
|
929
|
+
loopCardinality: this.loopCardinality,
|
|
930
|
+
completionCondition: this.completionCondition,
|
|
931
|
+
extensionElements: this.extensionElements ?? [],
|
|
932
|
+
...(this.unknownChildren.length > 0 ? { unknownChildren: this.unknownChildren } : {}),
|
|
933
|
+
});
|
|
934
|
+
}
|
|
481
935
|
}
|
|
482
936
|
// ---------------------------------------------------------------------------
|
|
483
|
-
//
|
|
937
|
+
// Sequence flows and annotations
|
|
484
938
|
// ---------------------------------------------------------------------------
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
939
|
+
class SequenceFlowFrame extends Frame {
|
|
940
|
+
attrs;
|
|
941
|
+
target;
|
|
942
|
+
id;
|
|
943
|
+
sourceRef;
|
|
944
|
+
targetRef;
|
|
945
|
+
conditionExpression;
|
|
946
|
+
conditionSeen = false;
|
|
947
|
+
extensionElements = null;
|
|
948
|
+
constructor(name, attrs, target) {
|
|
949
|
+
super();
|
|
950
|
+
this.attrs = attrs;
|
|
951
|
+
this.target = target;
|
|
952
|
+
this.id = requiredAttr(attrs, "id", name);
|
|
953
|
+
this.sourceRef = requiredAttr(attrs, "sourceRef", name);
|
|
954
|
+
this.targetRef = requiredAttr(attrs, "targetRef", name);
|
|
955
|
+
}
|
|
956
|
+
child(local, _name, attrs) {
|
|
957
|
+
switch (local) {
|
|
958
|
+
case "conditionExpression":
|
|
959
|
+
if (this.conditionSeen)
|
|
960
|
+
return null;
|
|
961
|
+
this.conditionSeen = true;
|
|
962
|
+
return new TextFrame(this, SLOT_CONDITION_EXPRESSION, attrs);
|
|
963
|
+
case "extensionElements":
|
|
964
|
+
if (this.extensionElements !== null)
|
|
965
|
+
return null;
|
|
966
|
+
this.extensionElements = [];
|
|
967
|
+
return new TreeFrame(this.extensionElements);
|
|
968
|
+
default:
|
|
969
|
+
return null;
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
setText(_slot, text, attrs) {
|
|
973
|
+
this.conditionExpression = { text: text ?? "", attributes: { ...attrs } };
|
|
974
|
+
}
|
|
975
|
+
finish() {
|
|
976
|
+
this.target.sequenceFlows.push({
|
|
977
|
+
id: this.id,
|
|
978
|
+
name: attr(this.attrs, "name"),
|
|
979
|
+
sourceRef: this.sourceRef,
|
|
980
|
+
targetRef: this.targetRef,
|
|
981
|
+
conditionExpression: this.conditionExpression,
|
|
982
|
+
extensionElements: this.extensionElements ?? [],
|
|
983
|
+
unknownAttributes: unknownAttrs(this.attrs),
|
|
984
|
+
});
|
|
985
|
+
}
|
|
497
986
|
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
987
|
+
class TextAnnotationFrame extends BaseElementFrame {
|
|
988
|
+
name;
|
|
989
|
+
attrs;
|
|
990
|
+
target;
|
|
991
|
+
textSeen = false;
|
|
992
|
+
value;
|
|
993
|
+
constructor(name, attrs, target) {
|
|
994
|
+
super();
|
|
995
|
+
this.name = name;
|
|
996
|
+
this.attrs = attrs;
|
|
997
|
+
this.target = target;
|
|
998
|
+
}
|
|
999
|
+
child(local, _name, attrs) {
|
|
1000
|
+
const base = this.baseChild(local, attrs);
|
|
1001
|
+
if (base !== undefined)
|
|
1002
|
+
return base;
|
|
1003
|
+
if (local !== "text" || this.textSeen)
|
|
1004
|
+
return null;
|
|
1005
|
+
this.textSeen = true;
|
|
1006
|
+
return new TextFrame(this, SLOT_TEXT, attrs);
|
|
1007
|
+
}
|
|
1008
|
+
baseText(_slot, text) {
|
|
1009
|
+
this.value = text;
|
|
1010
|
+
}
|
|
1011
|
+
finish() {
|
|
1012
|
+
this.target.push({
|
|
1013
|
+
id: requiredAttr(this.attrs, "id", this.name),
|
|
1014
|
+
text: this.value,
|
|
1015
|
+
...this.baseFields(),
|
|
1016
|
+
unknownAttributes: unknownAttrs(this.attrs),
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
503
1019
|
}
|
|
504
1020
|
// ---------------------------------------------------------------------------
|
|
505
|
-
//
|
|
1021
|
+
// Categories
|
|
506
1022
|
// ---------------------------------------------------------------------------
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
1023
|
+
/** A root `bpmn:category`; its values supply the labels groups point at. */
|
|
1024
|
+
class CategoryFrame extends BaseElementFrame {
|
|
1025
|
+
attrs;
|
|
1026
|
+
target;
|
|
1027
|
+
categoryValues = [];
|
|
1028
|
+
constructor(attrs, target) {
|
|
1029
|
+
super();
|
|
1030
|
+
this.attrs = attrs;
|
|
1031
|
+
this.target = target;
|
|
1032
|
+
}
|
|
1033
|
+
child(local, _name, attrs) {
|
|
1034
|
+
const base = this.baseChild(local, attrs);
|
|
1035
|
+
if (base !== undefined)
|
|
1036
|
+
return base;
|
|
1037
|
+
if (local === "categoryValue") {
|
|
1038
|
+
const id = attr(attrs, "id");
|
|
1039
|
+
if (id !== undefined) {
|
|
1040
|
+
this.categoryValues.push({
|
|
1041
|
+
id,
|
|
1042
|
+
value: attr(attrs, "value"),
|
|
1043
|
+
unknownAttributes: unknownAttrs(attrs),
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
return null;
|
|
1048
|
+
}
|
|
1049
|
+
finish() {
|
|
1050
|
+
this.target.push({
|
|
1051
|
+
id: attr(this.attrs, "id"),
|
|
1052
|
+
name: attr(this.attrs, "name"),
|
|
1053
|
+
categoryValues: this.categoryValues,
|
|
1054
|
+
unknownAttributes: unknownAttrs(this.attrs),
|
|
1055
|
+
});
|
|
1056
|
+
}
|
|
518
1057
|
}
|
|
519
1058
|
// ---------------------------------------------------------------------------
|
|
520
|
-
//
|
|
1059
|
+
// Data associations
|
|
521
1060
|
// ---------------------------------------------------------------------------
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
1061
|
+
const SLOT_SOURCE_REF = 11;
|
|
1062
|
+
const SLOT_TARGET_REF = 12;
|
|
1063
|
+
/** A `dataInputAssociation` or `dataOutputAssociation` and its ref children. */
|
|
1064
|
+
class DataAssociationFrame extends BaseElementFrame {
|
|
1065
|
+
attrs;
|
|
1066
|
+
target;
|
|
1067
|
+
sourceRefs = [];
|
|
1068
|
+
unknownChildren = [];
|
|
1069
|
+
targetRef;
|
|
1070
|
+
constructor(attrs, target) {
|
|
1071
|
+
super();
|
|
1072
|
+
this.attrs = attrs;
|
|
1073
|
+
this.target = target;
|
|
1074
|
+
}
|
|
1075
|
+
child(local, name, attrs) {
|
|
1076
|
+
const base = this.baseChild(local, attrs);
|
|
1077
|
+
if (base !== undefined)
|
|
1078
|
+
return base;
|
|
1079
|
+
if (local === "sourceRef")
|
|
1080
|
+
return new TextFrame(this, SLOT_SOURCE_REF, attrs);
|
|
1081
|
+
if (local === "targetRef")
|
|
1082
|
+
return new TextFrame(this, SLOT_TARGET_REF, attrs);
|
|
1083
|
+
return captureUnknown(this.unknownChildren, name, attrs);
|
|
1084
|
+
}
|
|
1085
|
+
baseText(slot, text) {
|
|
1086
|
+
const ref = text?.trim();
|
|
1087
|
+
if (!ref)
|
|
1088
|
+
return;
|
|
1089
|
+
if (slot === SLOT_SOURCE_REF)
|
|
1090
|
+
this.sourceRefs.push(ref);
|
|
1091
|
+
else if (slot === SLOT_TARGET_REF)
|
|
1092
|
+
this.targetRef = ref;
|
|
1093
|
+
}
|
|
1094
|
+
finish() {
|
|
1095
|
+
this.target.push({
|
|
1096
|
+
id: attr(this.attrs, "id"),
|
|
1097
|
+
sourceRefs: this.sourceRefs,
|
|
1098
|
+
targetRef: this.targetRef,
|
|
1099
|
+
unknownAttributes: unknownAttrs(this.attrs),
|
|
1100
|
+
...(this.unknownChildren.length > 0 ? { unknownChildren: this.unknownChildren } : {}),
|
|
1101
|
+
});
|
|
1102
|
+
}
|
|
529
1103
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
1104
|
+
class LaneSetFrame extends Frame {
|
|
1105
|
+
attrs;
|
|
1106
|
+
owner;
|
|
1107
|
+
lanes = [];
|
|
1108
|
+
constructor(attrs, owner) {
|
|
1109
|
+
super();
|
|
1110
|
+
this.attrs = attrs;
|
|
1111
|
+
this.owner = owner;
|
|
1112
|
+
}
|
|
1113
|
+
child(local, name, attrs) {
|
|
1114
|
+
return local === "lane" ? new LaneFrame(name, attrs, this.lanes) : null;
|
|
1115
|
+
}
|
|
1116
|
+
finish() {
|
|
1117
|
+
this.owner.setLaneSet({
|
|
1118
|
+
id: attr(this.attrs, "id"),
|
|
1119
|
+
name: attr(this.attrs, "name"),
|
|
1120
|
+
lanes: this.lanes,
|
|
1121
|
+
unknownAttributes: unknownAttrs(this.attrs),
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
538
1124
|
}
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
1125
|
+
class LaneFrame extends BaseElementFrame {
|
|
1126
|
+
name;
|
|
1127
|
+
attrs;
|
|
1128
|
+
target;
|
|
1129
|
+
flowNodeRefs = [];
|
|
1130
|
+
childLaneSet;
|
|
1131
|
+
childLaneSetSeen = false;
|
|
1132
|
+
constructor(name, attrs, target) {
|
|
1133
|
+
super();
|
|
1134
|
+
this.name = name;
|
|
1135
|
+
this.attrs = attrs;
|
|
1136
|
+
this.target = target;
|
|
1137
|
+
}
|
|
1138
|
+
child(local, _name, attrs) {
|
|
1139
|
+
const base = this.baseChild(local, attrs);
|
|
1140
|
+
if (base !== undefined)
|
|
1141
|
+
return base;
|
|
1142
|
+
switch (local) {
|
|
1143
|
+
case "flowNodeRef":
|
|
1144
|
+
return new TextFrame(this, SLOT_FLOW_NODE_REF, attrs);
|
|
1145
|
+
case "childLaneSet":
|
|
1146
|
+
if (this.childLaneSetSeen)
|
|
1147
|
+
return null;
|
|
1148
|
+
this.childLaneSetSeen = true;
|
|
1149
|
+
return new LaneSetFrame(attrs, this);
|
|
1150
|
+
default:
|
|
1151
|
+
return null;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
baseText(_slot, text) {
|
|
1155
|
+
const ref = text?.trim();
|
|
1156
|
+
if (ref)
|
|
1157
|
+
this.flowNodeRefs.push(ref);
|
|
1158
|
+
}
|
|
1159
|
+
setLaneSet(laneSet) {
|
|
1160
|
+
this.childLaneSet = laneSet;
|
|
1161
|
+
}
|
|
1162
|
+
finish() {
|
|
1163
|
+
this.target.push({
|
|
1164
|
+
id: requiredAttr(this.attrs, "id", this.name),
|
|
1165
|
+
name: attr(this.attrs, "name"),
|
|
1166
|
+
flowNodeRefs: this.flowNodeRefs,
|
|
1167
|
+
childLaneSet: this.childLaneSet,
|
|
1168
|
+
...this.baseFields(),
|
|
1169
|
+
unknownAttributes: unknownAttrs(this.attrs),
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
550
1172
|
}
|
|
551
1173
|
// ---------------------------------------------------------------------------
|
|
552
|
-
//
|
|
1174
|
+
// Process
|
|
553
1175
|
// ---------------------------------------------------------------------------
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
1176
|
+
class ProcessFrame extends Frame {
|
|
1177
|
+
attrs;
|
|
1178
|
+
target;
|
|
1179
|
+
id;
|
|
1180
|
+
unknownChildren = [];
|
|
1181
|
+
documentation;
|
|
1182
|
+
documentationSeen = false;
|
|
1183
|
+
extensionElements = null;
|
|
1184
|
+
laneSet;
|
|
1185
|
+
laneSetSeen = false;
|
|
1186
|
+
contents = newContents();
|
|
1187
|
+
constructor(name, attrs, target) {
|
|
1188
|
+
super();
|
|
1189
|
+
this.attrs = attrs;
|
|
1190
|
+
this.target = target;
|
|
1191
|
+
this.id = requiredAttr(attrs, "id", name);
|
|
1192
|
+
}
|
|
1193
|
+
child(local, name, attrs) {
|
|
1194
|
+
switch (local) {
|
|
1195
|
+
case "documentation":
|
|
1196
|
+
if (this.documentationSeen)
|
|
1197
|
+
return null;
|
|
1198
|
+
this.documentationSeen = true;
|
|
1199
|
+
return new TextFrame(this, SLOT_DOCUMENTATION, attrs);
|
|
1200
|
+
case "extensionElements":
|
|
1201
|
+
if (this.extensionElements !== null)
|
|
1202
|
+
return null;
|
|
1203
|
+
this.extensionElements = [];
|
|
1204
|
+
return new TreeFrame(this.extensionElements);
|
|
1205
|
+
case "laneSet":
|
|
1206
|
+
if (this.laneSetSeen)
|
|
1207
|
+
return null;
|
|
1208
|
+
this.laneSetSeen = true;
|
|
1209
|
+
return new LaneSetFrame(attrs, this);
|
|
1210
|
+
default: {
|
|
1211
|
+
const child = contentsChild(this.contents, local, name, attrs);
|
|
1212
|
+
return child === undefined ? captureUnknown(this.unknownChildren, name, attrs) : child;
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
setText(slot, text) {
|
|
1217
|
+
if (slot === SLOT_DOCUMENTATION)
|
|
1218
|
+
this.documentation = text;
|
|
1219
|
+
}
|
|
1220
|
+
setLaneSet(laneSet) {
|
|
1221
|
+
this.laneSet = laneSet;
|
|
1222
|
+
}
|
|
1223
|
+
finish() {
|
|
1224
|
+
const attrs = this.attrs;
|
|
1225
|
+
this.target.push({
|
|
1226
|
+
id: this.id,
|
|
1227
|
+
name: attr(attrs, "name"),
|
|
1228
|
+
isExecutable: attr(attrs, "isExecutable") === "true" ? true : undefined,
|
|
1229
|
+
...(this.documentation !== undefined ? { documentation: this.documentation } : {}),
|
|
1230
|
+
extensionElements: this.extensionElements ?? [],
|
|
1231
|
+
unknownAttributes: unknownAttrs(attrs),
|
|
1232
|
+
laneSet: this.laneSet,
|
|
1233
|
+
...(this.unknownChildren.length > 0 ? { unknownChildren: this.unknownChildren } : {}),
|
|
1234
|
+
...this.contents,
|
|
1235
|
+
});
|
|
1236
|
+
}
|
|
580
1237
|
}
|
|
581
1238
|
// ---------------------------------------------------------------------------
|
|
582
|
-
//
|
|
1239
|
+
// Collaboration
|
|
583
1240
|
// ---------------------------------------------------------------------------
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
1241
|
+
class CollaborationFrame extends Frame {
|
|
1242
|
+
attrs;
|
|
1243
|
+
target;
|
|
1244
|
+
id;
|
|
1245
|
+
participants = [];
|
|
1246
|
+
messageFlows = [];
|
|
1247
|
+
textAnnotations = [];
|
|
1248
|
+
associations = [];
|
|
1249
|
+
groups = [];
|
|
1250
|
+
unknownChildren = [];
|
|
1251
|
+
extensionElements = null;
|
|
1252
|
+
constructor(name, attrs, target) {
|
|
1253
|
+
super();
|
|
1254
|
+
this.attrs = attrs;
|
|
1255
|
+
this.target = target;
|
|
1256
|
+
this.id = requiredAttr(attrs, "id", name);
|
|
1257
|
+
}
|
|
1258
|
+
child(local, name, attrs) {
|
|
1259
|
+
switch (local) {
|
|
1260
|
+
case "participant":
|
|
1261
|
+
return new BaseOnlyFrame(attrs, (a, base) => parseParticipant(name, a, base), this.participants);
|
|
1262
|
+
case "messageFlow":
|
|
1263
|
+
return new BaseOnlyFrame(attrs, (a, base) => parseMessageFlow(name, a, base), this.messageFlows);
|
|
1264
|
+
case "textAnnotation":
|
|
1265
|
+
return new TextAnnotationFrame(name, attrs, this.textAnnotations);
|
|
1266
|
+
case "association":
|
|
1267
|
+
return new BaseOnlyFrame(attrs, (a, base) => parseAssociation(name, a, base), this.associations);
|
|
1268
|
+
case "group":
|
|
1269
|
+
return new BaseOnlyFrame(attrs, (a, base) => parseGroup(name, a, base), this.groups);
|
|
1270
|
+
case "extensionElements":
|
|
1271
|
+
if (this.extensionElements !== null)
|
|
1272
|
+
return null;
|
|
1273
|
+
this.extensionElements = [];
|
|
1274
|
+
return new TreeFrame(this.extensionElements);
|
|
1275
|
+
default:
|
|
1276
|
+
return captureUnknown(this.unknownChildren, name, attrs);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
finish() {
|
|
1280
|
+
this.target.push({
|
|
1281
|
+
id: this.id,
|
|
1282
|
+
participants: this.participants,
|
|
1283
|
+
messageFlows: this.messageFlows,
|
|
1284
|
+
textAnnotations: this.textAnnotations,
|
|
1285
|
+
associations: this.associations,
|
|
1286
|
+
groups: this.groups,
|
|
1287
|
+
extensionElements: this.extensionElements ?? [],
|
|
1288
|
+
unknownAttributes: unknownAttrs(this.attrs),
|
|
1289
|
+
...(this.unknownChildren.length > 0 ? { unknownChildren: this.unknownChildren } : {}),
|
|
1290
|
+
});
|
|
1291
|
+
}
|
|
591
1292
|
}
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
1293
|
+
class LabelFrame extends Frame {
|
|
1294
|
+
owner;
|
|
1295
|
+
bounds;
|
|
1296
|
+
boundsSeen = false;
|
|
1297
|
+
constructor(owner) {
|
|
1298
|
+
super();
|
|
1299
|
+
this.owner = owner;
|
|
1300
|
+
}
|
|
1301
|
+
child(local, _name, attrs) {
|
|
1302
|
+
if (local === "Bounds" && !this.boundsSeen) {
|
|
1303
|
+
this.boundsSeen = true;
|
|
1304
|
+
this.bounds = parseBounds(attrs);
|
|
1305
|
+
}
|
|
1306
|
+
return null;
|
|
1307
|
+
}
|
|
1308
|
+
finish() {
|
|
1309
|
+
this.owner.setLabel({ bounds: this.bounds });
|
|
1310
|
+
}
|
|
598
1311
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
:
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
1312
|
+
class ShapeFrame extends Frame {
|
|
1313
|
+
name;
|
|
1314
|
+
attrs;
|
|
1315
|
+
target;
|
|
1316
|
+
bounds;
|
|
1317
|
+
label;
|
|
1318
|
+
labelSeen = false;
|
|
1319
|
+
constructor(name, attrs, target) {
|
|
1320
|
+
super();
|
|
1321
|
+
this.name = name;
|
|
1322
|
+
this.attrs = attrs;
|
|
1323
|
+
this.target = target;
|
|
1324
|
+
}
|
|
1325
|
+
child(local, _name, attrs) {
|
|
1326
|
+
switch (local) {
|
|
1327
|
+
case "Bounds":
|
|
1328
|
+
if (this.bounds === undefined)
|
|
1329
|
+
this.bounds = parseBounds(attrs);
|
|
1330
|
+
return null;
|
|
1331
|
+
case "BPMNLabel":
|
|
1332
|
+
if (this.labelSeen)
|
|
1333
|
+
return null;
|
|
1334
|
+
this.labelSeen = true;
|
|
1335
|
+
return new LabelFrame(this);
|
|
1336
|
+
default:
|
|
1337
|
+
return null;
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
setLabel(label) {
|
|
1341
|
+
this.label = label;
|
|
1342
|
+
}
|
|
1343
|
+
finish() {
|
|
1344
|
+
const attrs = this.attrs;
|
|
1345
|
+
if (!this.bounds)
|
|
1346
|
+
throw new Error(`Missing <dc:Bounds> in shape "${attr(attrs, "id")}"`);
|
|
1347
|
+
this.target.push({
|
|
1348
|
+
id: requiredAttr(attrs, "id", this.name),
|
|
1349
|
+
bpmnElement: requiredAttr(attrs, "bpmnElement", this.name),
|
|
1350
|
+
isMarkerVisible: attr(attrs, "isMarkerVisible") !== undefined
|
|
1351
|
+
? attr(attrs, "isMarkerVisible") === "true"
|
|
1352
|
+
: undefined,
|
|
1353
|
+
isExpanded: attr(attrs, "isExpanded") !== undefined ? attr(attrs, "isExpanded") === "true" : undefined,
|
|
1354
|
+
isHorizontal: attr(attrs, "isHorizontal") !== undefined
|
|
1355
|
+
? attr(attrs, "isHorizontal") === "true"
|
|
1356
|
+
: undefined,
|
|
1357
|
+
bounds: this.bounds,
|
|
1358
|
+
label: this.label,
|
|
1359
|
+
unknownAttributes: unknownAttrs(attrs),
|
|
1360
|
+
});
|
|
1361
|
+
}
|
|
619
1362
|
}
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
1363
|
+
class EdgeFrame extends Frame {
|
|
1364
|
+
name;
|
|
1365
|
+
attrs;
|
|
1366
|
+
target;
|
|
1367
|
+
waypoints = [];
|
|
1368
|
+
label;
|
|
1369
|
+
labelSeen = false;
|
|
1370
|
+
constructor(name, attrs, target) {
|
|
1371
|
+
super();
|
|
1372
|
+
this.name = name;
|
|
1373
|
+
this.attrs = attrs;
|
|
1374
|
+
this.target = target;
|
|
1375
|
+
}
|
|
1376
|
+
child(local, _name, attrs) {
|
|
1377
|
+
switch (local) {
|
|
1378
|
+
case "waypoint":
|
|
1379
|
+
this.waypoints.push({
|
|
1380
|
+
x: Number(attr(attrs, "x") ?? "0"),
|
|
1381
|
+
y: Number(attr(attrs, "y") ?? "0"),
|
|
1382
|
+
});
|
|
1383
|
+
return null;
|
|
1384
|
+
case "BPMNLabel":
|
|
1385
|
+
if (this.labelSeen)
|
|
1386
|
+
return null;
|
|
1387
|
+
this.labelSeen = true;
|
|
1388
|
+
return new LabelFrame(this);
|
|
1389
|
+
default:
|
|
1390
|
+
return null;
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
setLabel(label) {
|
|
1394
|
+
this.label = label;
|
|
1395
|
+
}
|
|
1396
|
+
finish() {
|
|
1397
|
+
const attrs = this.attrs;
|
|
1398
|
+
this.target.push({
|
|
1399
|
+
id: requiredAttr(attrs, "id", this.name),
|
|
1400
|
+
bpmnElement: requiredAttr(attrs, "bpmnElement", this.name),
|
|
1401
|
+
waypoints: this.waypoints,
|
|
1402
|
+
label: this.label,
|
|
1403
|
+
unknownAttributes: unknownAttrs(attrs),
|
|
1404
|
+
});
|
|
1405
|
+
}
|
|
632
1406
|
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
1407
|
+
class PlaneFrame extends Frame {
|
|
1408
|
+
name;
|
|
1409
|
+
attrs;
|
|
1410
|
+
owner;
|
|
1411
|
+
shapes = [];
|
|
1412
|
+
edges = [];
|
|
1413
|
+
constructor(name, attrs, owner) {
|
|
1414
|
+
super();
|
|
1415
|
+
this.name = name;
|
|
1416
|
+
this.attrs = attrs;
|
|
1417
|
+
this.owner = owner;
|
|
1418
|
+
}
|
|
1419
|
+
child(local, name, attrs) {
|
|
1420
|
+
if (local === "BPMNShape")
|
|
1421
|
+
return new ShapeFrame(name, attrs, this.shapes);
|
|
1422
|
+
if (local === "BPMNEdge")
|
|
1423
|
+
return new EdgeFrame(name, attrs, this.edges);
|
|
1424
|
+
return null;
|
|
1425
|
+
}
|
|
1426
|
+
finish() {
|
|
1427
|
+
this.owner.setPlane(this);
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
class DiagramFrame extends Frame {
|
|
1431
|
+
name;
|
|
1432
|
+
attrs;
|
|
1433
|
+
target;
|
|
1434
|
+
plane;
|
|
1435
|
+
planeSeen = false;
|
|
1436
|
+
constructor(name, attrs, target) {
|
|
1437
|
+
super();
|
|
1438
|
+
this.name = name;
|
|
1439
|
+
this.attrs = attrs;
|
|
1440
|
+
this.target = target;
|
|
1441
|
+
}
|
|
1442
|
+
child(local, name, attrs) {
|
|
1443
|
+
if (local !== "BPMNPlane" || this.planeSeen)
|
|
1444
|
+
return null;
|
|
1445
|
+
this.planeSeen = true;
|
|
1446
|
+
return new PlaneFrame(name, attrs, this);
|
|
1447
|
+
}
|
|
1448
|
+
setPlane(plane) {
|
|
1449
|
+
this.plane = plane;
|
|
1450
|
+
}
|
|
1451
|
+
finish() {
|
|
1452
|
+
const plane = this.plane;
|
|
1453
|
+
if (!plane)
|
|
1454
|
+
throw new Error("Missing <bpmndi:BPMNPlane> in diagram");
|
|
1455
|
+
this.target.push({
|
|
1456
|
+
id: requiredAttr(this.attrs, "id", this.name),
|
|
1457
|
+
plane: {
|
|
1458
|
+
id: requiredAttr(plane.attrs, "id", plane.name),
|
|
1459
|
+
bpmnElement: requiredAttr(plane.attrs, "bpmnElement", plane.name),
|
|
1460
|
+
shapes: plane.shapes,
|
|
1461
|
+
edges: plane.edges,
|
|
1462
|
+
},
|
|
1463
|
+
});
|
|
645
1464
|
}
|
|
646
|
-
return {
|
|
647
|
-
id: requiredAttr(element, "id"),
|
|
648
|
-
plane: {
|
|
649
|
-
id: requiredAttr(planeEl, "id"),
|
|
650
|
-
bpmnElement: requiredAttr(planeEl, "bpmnElement"),
|
|
651
|
-
shapes,
|
|
652
|
-
edges,
|
|
653
|
-
},
|
|
654
|
-
};
|
|
655
1465
|
}
|
|
656
1466
|
// ---------------------------------------------------------------------------
|
|
657
|
-
//
|
|
1467
|
+
// Definitions (document root)
|
|
658
1468
|
// ---------------------------------------------------------------------------
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
1469
|
+
class DefinitionsFrame extends Frame {
|
|
1470
|
+
name;
|
|
1471
|
+
attrs;
|
|
1472
|
+
sink;
|
|
1473
|
+
categories = [];
|
|
1474
|
+
documentation;
|
|
1475
|
+
documentationSeen = false;
|
|
1476
|
+
errors = [];
|
|
1477
|
+
escalations = [];
|
|
1478
|
+
messages = [];
|
|
1479
|
+
signals = [];
|
|
1480
|
+
collaborations = [];
|
|
1481
|
+
processes = [];
|
|
1482
|
+
diagrams = [];
|
|
1483
|
+
unknownChildren = [];
|
|
1484
|
+
constructor(name, attrs, sink) {
|
|
1485
|
+
super();
|
|
1486
|
+
this.name = name;
|
|
1487
|
+
this.attrs = attrs;
|
|
1488
|
+
this.sink = sink;
|
|
1489
|
+
}
|
|
1490
|
+
child(local, name, attrs) {
|
|
1491
|
+
switch (local) {
|
|
1492
|
+
case "documentation":
|
|
1493
|
+
if (this.documentationSeen)
|
|
1494
|
+
return null;
|
|
1495
|
+
this.documentationSeen = true;
|
|
1496
|
+
return new TextFrame(this, SLOT_DOCUMENTATION, attrs);
|
|
1497
|
+
case "error":
|
|
1498
|
+
return new BaseOnlyFrame(attrs, (a, base) => parseError(name, a, base), this.errors);
|
|
1499
|
+
case "escalation":
|
|
1500
|
+
return new BaseOnlyFrame(attrs, (a, base) => parseEscalation(name, a, base), this.escalations);
|
|
1501
|
+
case "message":
|
|
1502
|
+
return new BaseOnlyFrame(attrs, (a, base) => parseMessage(name, a, base), this.messages);
|
|
1503
|
+
case "signal":
|
|
1504
|
+
return new BaseOnlyFrame(attrs, (a, base) => parseSignal(name, a, base), this.signals);
|
|
1505
|
+
case "category":
|
|
1506
|
+
return new CategoryFrame(attrs, this.categories);
|
|
1507
|
+
case "collaboration":
|
|
1508
|
+
return new CollaborationFrame(name, attrs, this.collaborations);
|
|
1509
|
+
case "process":
|
|
1510
|
+
return new ProcessFrame(name, attrs, this.processes);
|
|
1511
|
+
case "BPMNDiagram":
|
|
1512
|
+
return new DiagramFrame(name, attrs, this.diagrams);
|
|
1513
|
+
default:
|
|
1514
|
+
return captureUnknown(this.unknownChildren, name, attrs);
|
|
670
1515
|
}
|
|
671
|
-
|
|
672
|
-
|
|
1516
|
+
}
|
|
1517
|
+
setText(slot, text) {
|
|
1518
|
+
if (slot === SLOT_DOCUMENTATION)
|
|
1519
|
+
this.documentation = text;
|
|
1520
|
+
}
|
|
1521
|
+
finish() {
|
|
1522
|
+
const attrs = this.attrs;
|
|
1523
|
+
const namespaces = {};
|
|
1524
|
+
const unknownAttributes = {};
|
|
1525
|
+
for (const key in attrs) {
|
|
1526
|
+
const value = attrs[key];
|
|
1527
|
+
if (key.startsWith("xmlns:")) {
|
|
1528
|
+
namespaces[key.slice(6)] = value;
|
|
1529
|
+
}
|
|
1530
|
+
else if (key === "xmlns") {
|
|
1531
|
+
namespaces[""] = value;
|
|
1532
|
+
}
|
|
1533
|
+
else if (KNOWN_ATTRS.has(key)) {
|
|
1534
|
+
}
|
|
1535
|
+
else {
|
|
1536
|
+
unknownAttributes[key] = value;
|
|
1537
|
+
}
|
|
673
1538
|
}
|
|
674
|
-
|
|
1539
|
+
this.sink.result = {
|
|
1540
|
+
id: requiredAttr(attrs, "id", this.name),
|
|
1541
|
+
targetNamespace: requiredAttr(attrs, "targetNamespace", this.name),
|
|
1542
|
+
exporter: attr(attrs, "exporter"),
|
|
1543
|
+
exporterVersion: attr(attrs, "exporterVersion"),
|
|
1544
|
+
namespaces,
|
|
1545
|
+
unknownAttributes,
|
|
1546
|
+
...(this.documentation !== undefined ? { documentation: this.documentation } : {}),
|
|
1547
|
+
...(this.categories.length > 0 ? { categories: this.categories } : {}),
|
|
1548
|
+
errors: this.errors,
|
|
1549
|
+
escalations: this.escalations,
|
|
1550
|
+
messages: this.messages,
|
|
1551
|
+
signals: this.signals,
|
|
1552
|
+
collaborations: this.collaborations,
|
|
1553
|
+
processes: this.processes,
|
|
1554
|
+
diagrams: this.diagrams,
|
|
1555
|
+
...(this.unknownChildren.length > 0 ? { unknownChildren: this.unknownChildren } : {}),
|
|
1556
|
+
};
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
/** Routes scanner events to the frame stack. */
|
|
1560
|
+
class BpmnSink {
|
|
1561
|
+
result;
|
|
1562
|
+
/** Set when the root element is not <definitions>; reported once scanning is done. */
|
|
1563
|
+
rootName;
|
|
1564
|
+
stack = [];
|
|
1565
|
+
start(name, local, attrs) {
|
|
1566
|
+
const top = this.stack[this.stack.length - 1];
|
|
1567
|
+
let next;
|
|
1568
|
+
if (top === undefined) {
|
|
1569
|
+
if (local !== "definitions") {
|
|
1570
|
+
this.rootName = name;
|
|
1571
|
+
return Visit.Skip;
|
|
1572
|
+
}
|
|
1573
|
+
next = new DefinitionsFrame(name, attrs, this);
|
|
675
1574
|
}
|
|
676
1575
|
else {
|
|
677
|
-
|
|
1576
|
+
next = top.child(local, name, attrs);
|
|
678
1577
|
}
|
|
1578
|
+
if (next === null)
|
|
1579
|
+
return Visit.Skip;
|
|
1580
|
+
this.stack.push(next);
|
|
1581
|
+
return next.wantsText ? Visit.All : Visit.ElementsOnly;
|
|
679
1582
|
}
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
const signals = [];
|
|
684
|
-
const collaborations = [];
|
|
685
|
-
const processes = [];
|
|
686
|
-
const diagrams = [];
|
|
687
|
-
for (const child of root.children) {
|
|
688
|
-
const ln = localName(child.name);
|
|
689
|
-
if (ln === "error")
|
|
690
|
-
errors.push(parseError(child));
|
|
691
|
-
else if (ln === "escalation")
|
|
692
|
-
escalations.push(parseEscalation(child));
|
|
693
|
-
else if (ln === "message")
|
|
694
|
-
messages.push(parseMessage(child));
|
|
695
|
-
else if (ln === "signal")
|
|
696
|
-
signals.push(parseSignal(child));
|
|
697
|
-
else if (ln === "collaboration")
|
|
698
|
-
collaborations.push(parseCollaboration(child));
|
|
699
|
-
else if (ln === "process")
|
|
700
|
-
processes.push(parseProcess(child));
|
|
701
|
-
else if (ln === "BPMNDiagram")
|
|
702
|
-
diagrams.push(parseDiagram(child));
|
|
1583
|
+
text(text) {
|
|
1584
|
+
;
|
|
1585
|
+
this.stack[this.stack.length - 1].text(text);
|
|
703
1586
|
}
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
1587
|
+
end() {
|
|
1588
|
+
;
|
|
1589
|
+
this.stack.pop().finish();
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
// ---------------------------------------------------------------------------
|
|
1593
|
+
// Public API
|
|
1594
|
+
// ---------------------------------------------------------------------------
|
|
1595
|
+
/** Parse a BPMN XML string into a typed BpmnDefinitions model. */
|
|
1596
|
+
export function parseBpmn(xml) {
|
|
1597
|
+
const sink = new BpmnSink();
|
|
1598
|
+
if (!scanXml(xml, sink))
|
|
1599
|
+
throw new Error("Failed to parse XML: no root element found");
|
|
1600
|
+
if (sink.rootName !== undefined) {
|
|
1601
|
+
throw new Error(`Expected <definitions> root element, got <${sink.rootName}>`);
|
|
1602
|
+
}
|
|
1603
|
+
return sink.result;
|
|
719
1604
|
}
|
|
720
1605
|
//# sourceMappingURL=bpmn-parser.js.map
|