libpetri 0.3.5 → 0.4.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/dist/chunk-ZE6RR3R4.js +412 -0
- package/dist/chunk-ZE6RR3R4.js.map +1 -0
- package/dist/debug/index.d.ts +408 -0
- package/dist/debug/index.js +1085 -0
- package/dist/debug/index.js.map +1 -0
- package/dist/event-store-Y8q_wapJ.d.ts +152 -0
- package/dist/export/index.js +11 -398
- package/dist/export/index.js.map +1 -1
- package/dist/index.d.ts +3 -150
- package/dist/index.js +11 -11
- package/package.json +7 -1
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
import {
|
|
2
|
+
earliest,
|
|
3
|
+
hasDeadline,
|
|
4
|
+
latest
|
|
5
|
+
} from "./chunk-FN773SSE.js";
|
|
6
|
+
|
|
7
|
+
// src/export/styles.ts
|
|
8
|
+
var NODE_STYLES = {
|
|
9
|
+
place: { shape: "circle", fill: "#FFFFFF", stroke: "#333333", penwidth: 1.5, width: 0.35 },
|
|
10
|
+
start: { shape: "circle", fill: "#d4edda", stroke: "#28a745", penwidth: 2, width: 0.35 },
|
|
11
|
+
end: { shape: "circle", fill: "#cce5ff", stroke: "#004085", penwidth: 2, width: 0.35 },
|
|
12
|
+
environment: { shape: "circle", fill: "#f8d7da", stroke: "#721c24", penwidth: 2, style: "dashed", width: 0.35 },
|
|
13
|
+
transition: { shape: "box", fill: "#fff3cd", stroke: "#856404", penwidth: 1, height: 0.4, width: 0.8 }
|
|
14
|
+
};
|
|
15
|
+
var EDGE_STYLES = {
|
|
16
|
+
input: { color: "#333333", style: "solid", arrowhead: "normal" },
|
|
17
|
+
output: { color: "#333333", style: "solid", arrowhead: "normal" },
|
|
18
|
+
inhibitor: { color: "#dc3545", style: "solid", arrowhead: "odot" },
|
|
19
|
+
read: { color: "#6c757d", style: "dashed", arrowhead: "normal" },
|
|
20
|
+
reset: { color: "#fd7e14", style: "bold", arrowhead: "normal", penwidth: 2 }
|
|
21
|
+
};
|
|
22
|
+
var FONT = { family: "Helvetica,Arial,sans-serif", nodeSize: 12, edgeSize: 10 };
|
|
23
|
+
var GRAPH = { nodesep: 0.5, ranksep: 0.75 };
|
|
24
|
+
function nodeStyle(category) {
|
|
25
|
+
return NODE_STYLES[category];
|
|
26
|
+
}
|
|
27
|
+
function edgeStyle(arcType) {
|
|
28
|
+
return EDGE_STYLES[arcType];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/export/petri-net-mapper.ts
|
|
32
|
+
var DEFAULT_DOT_CONFIG = {
|
|
33
|
+
direction: "TB",
|
|
34
|
+
showTypes: true,
|
|
35
|
+
showIntervals: true,
|
|
36
|
+
showPriority: true
|
|
37
|
+
};
|
|
38
|
+
function sanitize(name) {
|
|
39
|
+
return name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
40
|
+
}
|
|
41
|
+
function mapToGraph(net, config = DEFAULT_DOT_CONFIG) {
|
|
42
|
+
const places = analyzePlaces(net);
|
|
43
|
+
const envNames = config.environmentPlaces ?? /* @__PURE__ */ new Set();
|
|
44
|
+
const nodes = [];
|
|
45
|
+
const edges = [];
|
|
46
|
+
for (const [name, info] of places) {
|
|
47
|
+
const category = placeCategory(info, envNames.has(name));
|
|
48
|
+
const style = nodeStyle(category);
|
|
49
|
+
nodes.push({
|
|
50
|
+
id: "p_" + sanitize(name),
|
|
51
|
+
label: "",
|
|
52
|
+
shape: style.shape,
|
|
53
|
+
fill: style.fill,
|
|
54
|
+
stroke: style.stroke,
|
|
55
|
+
penwidth: style.penwidth,
|
|
56
|
+
semanticId: name,
|
|
57
|
+
style: style.style,
|
|
58
|
+
width: style.width,
|
|
59
|
+
attrs: { xlabel: name, fixedsize: "true" }
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
for (const t of net.transitions) {
|
|
63
|
+
const style = nodeStyle("transition");
|
|
64
|
+
nodes.push({
|
|
65
|
+
id: "t_" + sanitize(t.name),
|
|
66
|
+
label: transitionLabel(t, config),
|
|
67
|
+
shape: style.shape,
|
|
68
|
+
fill: style.fill,
|
|
69
|
+
stroke: style.stroke,
|
|
70
|
+
penwidth: style.penwidth,
|
|
71
|
+
semanticId: t.name,
|
|
72
|
+
height: style.height,
|
|
73
|
+
width: style.width
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
for (const t of net.transitions) {
|
|
77
|
+
const tid = "t_" + sanitize(t.name);
|
|
78
|
+
for (const spec of t.inputSpecs) {
|
|
79
|
+
const pid = "p_" + sanitize(spec.place.name);
|
|
80
|
+
const inputStyle = edgeStyle("input");
|
|
81
|
+
let label;
|
|
82
|
+
switch (spec.type) {
|
|
83
|
+
case "exactly":
|
|
84
|
+
label = `\xD7${spec.count}`;
|
|
85
|
+
break;
|
|
86
|
+
case "all":
|
|
87
|
+
label = "*";
|
|
88
|
+
break;
|
|
89
|
+
case "at-least":
|
|
90
|
+
label = `\u2265${spec.minimum}`;
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
edges.push({
|
|
94
|
+
from: pid,
|
|
95
|
+
to: tid,
|
|
96
|
+
label,
|
|
97
|
+
color: inputStyle.color,
|
|
98
|
+
style: inputStyle.style,
|
|
99
|
+
arrowhead: inputStyle.arrowhead,
|
|
100
|
+
arcType: "input"
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
if (t.outputSpec !== null) {
|
|
104
|
+
edges.push(...outputEdges(tid, t.outputSpec, null));
|
|
105
|
+
}
|
|
106
|
+
for (const inh of t.inhibitors) {
|
|
107
|
+
const pid = "p_" + sanitize(inh.place.name);
|
|
108
|
+
const inhStyle = edgeStyle("inhibitor");
|
|
109
|
+
edges.push({
|
|
110
|
+
from: pid,
|
|
111
|
+
to: tid,
|
|
112
|
+
color: inhStyle.color,
|
|
113
|
+
style: inhStyle.style,
|
|
114
|
+
arrowhead: inhStyle.arrowhead,
|
|
115
|
+
arcType: "inhibitor"
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
for (const r of t.reads) {
|
|
119
|
+
const pid = "p_" + sanitize(r.place.name);
|
|
120
|
+
const readStyle = edgeStyle("read");
|
|
121
|
+
edges.push({
|
|
122
|
+
from: pid,
|
|
123
|
+
to: tid,
|
|
124
|
+
label: "read",
|
|
125
|
+
color: readStyle.color,
|
|
126
|
+
style: readStyle.style,
|
|
127
|
+
arrowhead: readStyle.arrowhead,
|
|
128
|
+
arcType: "read"
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
const outputPlaceNames = t.outputSpec !== null ? new Set([...t.outputPlaces()].map((p) => p.name)) : /* @__PURE__ */ new Set();
|
|
132
|
+
for (const rst of t.resets) {
|
|
133
|
+
if (!outputPlaceNames.has(rst.place.name)) {
|
|
134
|
+
const pid = "p_" + sanitize(rst.place.name);
|
|
135
|
+
const resetStyle = edgeStyle("reset");
|
|
136
|
+
edges.push({
|
|
137
|
+
from: tid,
|
|
138
|
+
to: pid,
|
|
139
|
+
label: "reset",
|
|
140
|
+
color: resetStyle.color,
|
|
141
|
+
style: resetStyle.style,
|
|
142
|
+
arrowhead: resetStyle.arrowhead,
|
|
143
|
+
penwidth: resetStyle.penwidth,
|
|
144
|
+
arcType: "reset"
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
id: sanitize(net.name),
|
|
151
|
+
rankdir: config.direction,
|
|
152
|
+
nodes,
|
|
153
|
+
edges,
|
|
154
|
+
subgraphs: [],
|
|
155
|
+
graphAttrs: {
|
|
156
|
+
nodesep: String(GRAPH.nodesep),
|
|
157
|
+
ranksep: String(GRAPH.ranksep),
|
|
158
|
+
fontname: FONT.family
|
|
159
|
+
},
|
|
160
|
+
nodeDefaults: {
|
|
161
|
+
fontname: FONT.family,
|
|
162
|
+
fontsize: String(FONT.nodeSize)
|
|
163
|
+
},
|
|
164
|
+
edgeDefaults: {
|
|
165
|
+
fontname: FONT.family,
|
|
166
|
+
fontsize: String(FONT.edgeSize)
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function analyzePlaces(net) {
|
|
171
|
+
const map = /* @__PURE__ */ new Map();
|
|
172
|
+
function ensure(name) {
|
|
173
|
+
let info = map.get(name);
|
|
174
|
+
if (!info) {
|
|
175
|
+
info = { hasIncoming: false, hasOutgoing: false };
|
|
176
|
+
map.set(name, info);
|
|
177
|
+
}
|
|
178
|
+
return info;
|
|
179
|
+
}
|
|
180
|
+
for (const t of net.transitions) {
|
|
181
|
+
for (const spec of t.inputSpecs) {
|
|
182
|
+
ensure(spec.place.name).hasOutgoing = true;
|
|
183
|
+
}
|
|
184
|
+
if (t.outputSpec !== null) {
|
|
185
|
+
for (const p of t.outputPlaces()) {
|
|
186
|
+
ensure(p.name).hasIncoming = true;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
for (const inh of t.inhibitors) {
|
|
190
|
+
ensure(inh.place.name);
|
|
191
|
+
}
|
|
192
|
+
for (const r of t.reads) {
|
|
193
|
+
ensure(r.place.name).hasOutgoing = true;
|
|
194
|
+
}
|
|
195
|
+
for (const rst of t.resets) {
|
|
196
|
+
ensure(rst.place.name);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return map;
|
|
200
|
+
}
|
|
201
|
+
function placeCategory(info, isEnvironment) {
|
|
202
|
+
if (isEnvironment) return "environment";
|
|
203
|
+
if (!info.hasIncoming) return "start";
|
|
204
|
+
if (!info.hasOutgoing) return "end";
|
|
205
|
+
return "place";
|
|
206
|
+
}
|
|
207
|
+
function transitionLabel(t, config) {
|
|
208
|
+
const parts = [t.name];
|
|
209
|
+
if (config.showIntervals) {
|
|
210
|
+
const e = earliest(t.timing);
|
|
211
|
+
const l = latest(t.timing);
|
|
212
|
+
const max = hasDeadline(t.timing) ? String(l) : "\u221E";
|
|
213
|
+
parts.push(`[${e}, ${max}]ms`);
|
|
214
|
+
}
|
|
215
|
+
if (config.showPriority && t.priority !== 0) {
|
|
216
|
+
parts.push(`prio=${t.priority}`);
|
|
217
|
+
}
|
|
218
|
+
return parts.join(" ");
|
|
219
|
+
}
|
|
220
|
+
function outputEdges(transitionId, out, branchLabel) {
|
|
221
|
+
const outStyle = edgeStyle("output");
|
|
222
|
+
switch (out.type) {
|
|
223
|
+
case "place": {
|
|
224
|
+
const pid = "p_" + sanitize(out.place.name);
|
|
225
|
+
return [{
|
|
226
|
+
from: transitionId,
|
|
227
|
+
to: pid,
|
|
228
|
+
label: branchLabel ?? void 0,
|
|
229
|
+
color: outStyle.color,
|
|
230
|
+
style: outStyle.style,
|
|
231
|
+
arrowhead: outStyle.arrowhead,
|
|
232
|
+
arcType: "output"
|
|
233
|
+
}];
|
|
234
|
+
}
|
|
235
|
+
case "forward-input": {
|
|
236
|
+
const pid = "p_" + sanitize(out.to.name);
|
|
237
|
+
const label = (branchLabel ? branchLabel + " " : "") + "\u27F5" + out.from.name;
|
|
238
|
+
return [{
|
|
239
|
+
from: transitionId,
|
|
240
|
+
to: pid,
|
|
241
|
+
label,
|
|
242
|
+
color: outStyle.color,
|
|
243
|
+
style: "dashed",
|
|
244
|
+
arrowhead: outStyle.arrowhead,
|
|
245
|
+
arcType: "output"
|
|
246
|
+
}];
|
|
247
|
+
}
|
|
248
|
+
case "and":
|
|
249
|
+
return out.children.flatMap((c) => outputEdges(transitionId, c, branchLabel));
|
|
250
|
+
case "xor": {
|
|
251
|
+
const edges = [];
|
|
252
|
+
for (const child of out.children) {
|
|
253
|
+
const label = inferBranchLabel(child);
|
|
254
|
+
edges.push(...outputEdges(transitionId, child, label));
|
|
255
|
+
}
|
|
256
|
+
return edges;
|
|
257
|
+
}
|
|
258
|
+
case "timeout":
|
|
259
|
+
return outputEdges(transitionId, out.child, `\u23F1${out.afterMs}ms`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function inferBranchLabel(out) {
|
|
263
|
+
switch (out.type) {
|
|
264
|
+
case "place":
|
|
265
|
+
return out.place.name;
|
|
266
|
+
case "timeout":
|
|
267
|
+
return `\u23F1${out.afterMs}ms`;
|
|
268
|
+
case "forward-input":
|
|
269
|
+
return out.to.name;
|
|
270
|
+
case "and":
|
|
271
|
+
case "xor":
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// src/export/dot-renderer.ts
|
|
277
|
+
function renderDot(graph) {
|
|
278
|
+
const lines = [];
|
|
279
|
+
lines.push(`digraph ${quoteId(graph.id)} {`);
|
|
280
|
+
lines.push(` rankdir=${graph.rankdir};`);
|
|
281
|
+
for (const [key, value] of Object.entries(graph.graphAttrs)) {
|
|
282
|
+
lines.push(` ${key}=${quoteAttr(value)};`);
|
|
283
|
+
}
|
|
284
|
+
if (Object.keys(graph.nodeDefaults).length > 0) {
|
|
285
|
+
lines.push(` node [${formatAttrs(graph.nodeDefaults)}];`);
|
|
286
|
+
}
|
|
287
|
+
if (Object.keys(graph.edgeDefaults).length > 0) {
|
|
288
|
+
lines.push(` edge [${formatAttrs(graph.edgeDefaults)}];`);
|
|
289
|
+
}
|
|
290
|
+
lines.push("");
|
|
291
|
+
for (const sg of graph.subgraphs) {
|
|
292
|
+
lines.push(...renderSubgraph(sg, " "));
|
|
293
|
+
lines.push("");
|
|
294
|
+
}
|
|
295
|
+
for (const node of graph.nodes) {
|
|
296
|
+
lines.push(` ${renderNode(node)}`);
|
|
297
|
+
}
|
|
298
|
+
if (graph.nodes.length > 0) {
|
|
299
|
+
lines.push("");
|
|
300
|
+
}
|
|
301
|
+
for (const edge of graph.edges) {
|
|
302
|
+
lines.push(` ${renderEdge(edge)}`);
|
|
303
|
+
}
|
|
304
|
+
lines.push("}");
|
|
305
|
+
return lines.join("\n");
|
|
306
|
+
}
|
|
307
|
+
function renderNode(node) {
|
|
308
|
+
const attrs = {
|
|
309
|
+
label: node.label,
|
|
310
|
+
shape: node.shape,
|
|
311
|
+
style: node.style ? `"filled,${node.style}"` : "filled",
|
|
312
|
+
fillcolor: node.fill,
|
|
313
|
+
color: node.stroke,
|
|
314
|
+
penwidth: String(node.penwidth)
|
|
315
|
+
};
|
|
316
|
+
if (node.height !== void 0) {
|
|
317
|
+
attrs["height"] = String(node.height);
|
|
318
|
+
}
|
|
319
|
+
if (node.width !== void 0) {
|
|
320
|
+
attrs["width"] = String(node.width);
|
|
321
|
+
}
|
|
322
|
+
if (node.attrs) {
|
|
323
|
+
for (const [key, value] of Object.entries(node.attrs)) {
|
|
324
|
+
attrs[key] = value;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return `${quoteId(node.id)} [${formatNodeAttrs(attrs)}];`;
|
|
328
|
+
}
|
|
329
|
+
function renderEdge(edge) {
|
|
330
|
+
const attrs = {
|
|
331
|
+
color: edge.color,
|
|
332
|
+
style: edge.style,
|
|
333
|
+
arrowhead: edge.arrowhead
|
|
334
|
+
};
|
|
335
|
+
if (edge.label !== void 0) {
|
|
336
|
+
attrs["label"] = edge.label;
|
|
337
|
+
}
|
|
338
|
+
if (edge.penwidth !== void 0) {
|
|
339
|
+
attrs["penwidth"] = String(edge.penwidth);
|
|
340
|
+
}
|
|
341
|
+
if (edge.attrs) {
|
|
342
|
+
for (const [key, value] of Object.entries(edge.attrs)) {
|
|
343
|
+
attrs[key] = value;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return `${quoteId(edge.from)} -> ${quoteId(edge.to)} [${formatNodeAttrs(attrs)}];`;
|
|
347
|
+
}
|
|
348
|
+
function renderSubgraph(sg, indent) {
|
|
349
|
+
const lines = [];
|
|
350
|
+
lines.push(`${indent}subgraph ${quoteId("cluster_" + sg.id)} {`);
|
|
351
|
+
if (sg.label !== void 0) {
|
|
352
|
+
lines.push(`${indent} label=${quoteAttr(sg.label)};`);
|
|
353
|
+
}
|
|
354
|
+
if (sg.attrs) {
|
|
355
|
+
for (const [key, value] of Object.entries(sg.attrs)) {
|
|
356
|
+
lines.push(`${indent} ${key}=${quoteAttr(value)};`);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
for (const node of sg.nodes) {
|
|
360
|
+
lines.push(`${indent} ${renderNode(node)}`);
|
|
361
|
+
}
|
|
362
|
+
lines.push(`${indent}}`);
|
|
363
|
+
return lines;
|
|
364
|
+
}
|
|
365
|
+
function quoteId(id) {
|
|
366
|
+
if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(id) && !isDotKeyword(id)) {
|
|
367
|
+
return id;
|
|
368
|
+
}
|
|
369
|
+
return `"${escapeDot(id)}"`;
|
|
370
|
+
}
|
|
371
|
+
function quoteAttr(value) {
|
|
372
|
+
if (/^-?\d+(\.\d+)?$/.test(value)) {
|
|
373
|
+
return value;
|
|
374
|
+
}
|
|
375
|
+
return `"${escapeDot(value)}"`;
|
|
376
|
+
}
|
|
377
|
+
function escapeDot(s) {
|
|
378
|
+
return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
379
|
+
}
|
|
380
|
+
function formatNodeAttrs(attrs) {
|
|
381
|
+
return Object.entries(attrs).map(([key, value]) => {
|
|
382
|
+
if (value.startsWith('"') && value.endsWith('"')) {
|
|
383
|
+
return `${key}=${value}`;
|
|
384
|
+
}
|
|
385
|
+
return `${key}=${quoteAttr(value)}`;
|
|
386
|
+
}).join(", ");
|
|
387
|
+
}
|
|
388
|
+
function formatAttrs(attrs) {
|
|
389
|
+
return Object.entries(attrs).map(([key, value]) => `${key}=${quoteAttr(value)}`).join(", ");
|
|
390
|
+
}
|
|
391
|
+
function isDotKeyword(id) {
|
|
392
|
+
const lower = id.toLowerCase();
|
|
393
|
+
return lower === "graph" || lower === "digraph" || lower === "subgraph" || lower === "node" || lower === "edge" || lower === "strict";
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// src/export/dot-exporter.ts
|
|
397
|
+
function dotExport(net, config) {
|
|
398
|
+
return renderDot(mapToGraph(net, config));
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
export {
|
|
402
|
+
FONT,
|
|
403
|
+
GRAPH,
|
|
404
|
+
nodeStyle,
|
|
405
|
+
edgeStyle,
|
|
406
|
+
DEFAULT_DOT_CONFIG,
|
|
407
|
+
sanitize,
|
|
408
|
+
mapToGraph,
|
|
409
|
+
renderDot,
|
|
410
|
+
dotExport
|
|
411
|
+
};
|
|
412
|
+
//# sourceMappingURL=chunk-ZE6RR3R4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/export/styles.ts","../src/export/petri-net-mapper.ts","../src/export/dot-renderer.ts","../src/export/dot-exporter.ts"],"sourcesContent":["/**\n * Style loader for Petri net visualization.\n *\n * Reads the shared style definition from `spec/petri-net-styles.json` and\n * exposes typed accessors for node and edge visual properties.\n *\n * @module export/styles\n */\n\nimport type { NodeShape, EdgeLineStyle, ArrowHead } from './graph.js';\n\n// ======================== Style Types ========================\n\nexport interface NodeVisual {\n readonly shape: NodeShape;\n readonly fill: string;\n readonly stroke: string;\n readonly penwidth: number;\n readonly style?: string;\n readonly height?: number;\n readonly width?: number;\n}\n\nexport interface EdgeVisual {\n readonly color: string;\n readonly style: EdgeLineStyle;\n readonly arrowhead: ArrowHead;\n readonly penwidth?: number;\n}\n\nexport interface FontStyle {\n readonly family: string;\n readonly nodeSize: number;\n readonly edgeSize: number;\n}\n\nexport interface GraphStyle {\n readonly nodesep: number;\n readonly ranksep: number;\n}\n\n// ======================== Inline Style Data ========================\n\n// Inlined from spec/petri-net-styles.json to avoid runtime JSON import issues.\n// Keep in sync with the spec file.\n\nconst NODE_STYLES: Record<NodeCategory, NodeVisual> = {\n place: { shape: 'circle', fill: '#FFFFFF', stroke: '#333333', penwidth: 1.5, width: 0.35 },\n start: { shape: 'circle', fill: '#d4edda', stroke: '#28a745', penwidth: 2.0, width: 0.35 },\n end: { shape: 'circle', fill: '#cce5ff', stroke: '#004085', penwidth: 2.0, width: 0.35 },\n environment: { shape: 'circle', fill: '#f8d7da', stroke: '#721c24', penwidth: 2.0, style: 'dashed', width: 0.35 },\n transition: { shape: 'box', fill: '#fff3cd', stroke: '#856404', penwidth: 1.0, height: 0.4, width: 0.8 },\n};\n\nconst EDGE_STYLES: Record<EdgeCategory, EdgeVisual> = {\n input: { color: '#333333', style: 'solid', arrowhead: 'normal' },\n output: { color: '#333333', style: 'solid', arrowhead: 'normal' },\n inhibitor: { color: '#dc3545', style: 'solid', arrowhead: 'odot' },\n read: { color: '#6c757d', style: 'dashed', arrowhead: 'normal' },\n reset: { color: '#fd7e14', style: 'bold', arrowhead: 'normal', penwidth: 2.0 },\n};\n\nexport const FONT: FontStyle = { family: 'Helvetica,Arial,sans-serif', nodeSize: 12, edgeSize: 10 };\n\nexport const GRAPH: GraphStyle = { nodesep: 0.5, ranksep: 0.75 };\n\n// ======================== Public API ========================\n\nexport type NodeCategory = 'place' | 'start' | 'end' | 'environment' | 'transition';\nexport type EdgeCategory = 'input' | 'output' | 'inhibitor' | 'read' | 'reset';\n\n/** Returns the visual style for the given node category. */\nexport function nodeStyle(category: NodeCategory): NodeVisual {\n return NODE_STYLES[category];\n}\n\n/** Returns the visual style for the given edge/arc type. */\nexport function edgeStyle(arcType: EdgeCategory): EdgeVisual {\n return EDGE_STYLES[arcType];\n}\n","/**\n * Maps a PetriNet definition to a format-agnostic Graph.\n *\n * This is where all the Petri net semantics live. The mapper understands\n * places, transitions, arcs, timing, and priority. It produces a Graph\n * that can be rendered to DOT (or any other format) without Petri net knowledge.\n *\n * @module export/petri-net-mapper\n */\n\nimport type { PetriNet } from '../core/petri-net.js';\nimport type { Transition } from '../core/transition.js';\nimport type { Out } from '../core/out.js';\nimport { earliest, latest, hasDeadline } from '../core/timing.js';\nimport type { Graph, GraphNode, GraphEdge, RankDir } from './graph.js';\nimport { nodeStyle, edgeStyle, FONT, GRAPH } from './styles.js';\nimport type { NodeCategory } from './styles.js';\n\n// ======================== Configuration ========================\n\nexport interface DotConfig {\n readonly direction: RankDir;\n readonly showTypes: boolean;\n readonly showIntervals: boolean;\n readonly showPriority: boolean;\n readonly environmentPlaces?: ReadonlySet<string>;\n}\n\nexport const DEFAULT_DOT_CONFIG: DotConfig = {\n direction: 'TB',\n showTypes: true,\n showIntervals: true,\n showPriority: true,\n};\n\n// ======================== Public API ========================\n\n/** Sanitizes a name for use as a graph node ID. */\nexport function sanitize(name: string): string {\n return name.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\n/** Maps a PetriNet to a format-agnostic Graph. */\nexport function mapToGraph(net: PetriNet, config: DotConfig = DEFAULT_DOT_CONFIG): Graph {\n const places = analyzePlaces(net);\n const envNames = config.environmentPlaces ?? new Set<string>();\n\n const nodes: GraphNode[] = [];\n const edges: GraphEdge[] = [];\n\n // Place nodes\n for (const [name, info] of places) {\n const category = placeCategory(info, envNames.has(name));\n const style = nodeStyle(category);\n nodes.push({\n id: 'p_' + sanitize(name),\n label: '',\n shape: style.shape,\n fill: style.fill,\n stroke: style.stroke,\n penwidth: style.penwidth,\n semanticId: name,\n style: style.style,\n width: style.width,\n attrs: { xlabel: name, fixedsize: 'true' },\n });\n }\n\n // Transition nodes\n for (const t of net.transitions) {\n const style = nodeStyle('transition');\n nodes.push({\n id: 't_' + sanitize(t.name),\n label: transitionLabel(t, config),\n shape: style.shape,\n fill: style.fill,\n stroke: style.stroke,\n penwidth: style.penwidth,\n semanticId: t.name,\n height: style.height,\n width: style.width,\n });\n }\n\n // Edges\n for (const t of net.transitions) {\n const tid = 't_' + sanitize(t.name);\n\n // Input arcs from inputSpecs\n for (const spec of t.inputSpecs) {\n const pid = 'p_' + sanitize(spec.place.name);\n const inputStyle = edgeStyle('input');\n let label: string | undefined;\n switch (spec.type) {\n case 'exactly':\n label = `\\u00d7${spec.count}`;\n break;\n case 'all':\n label = '*';\n break;\n case 'at-least':\n label = `\\u2265${spec.minimum}`;\n break;\n }\n edges.push({\n from: pid,\n to: tid,\n label,\n color: inputStyle.color,\n style: inputStyle.style,\n arrowhead: inputStyle.arrowhead,\n arcType: 'input',\n });\n }\n\n // Output arcs from outputSpec\n if (t.outputSpec !== null) {\n edges.push(...outputEdges(tid, t.outputSpec, null));\n }\n\n // Inhibitor arcs\n for (const inh of t.inhibitors) {\n const pid = 'p_' + sanitize(inh.place.name);\n const inhStyle = edgeStyle('inhibitor');\n edges.push({\n from: pid,\n to: tid,\n color: inhStyle.color,\n style: inhStyle.style,\n arrowhead: inhStyle.arrowhead,\n arcType: 'inhibitor',\n });\n }\n\n // Read arcs\n for (const r of t.reads) {\n const pid = 'p_' + sanitize(r.place.name);\n const readStyle = edgeStyle('read');\n edges.push({\n from: pid,\n to: tid,\n label: 'read',\n color: readStyle.color,\n style: readStyle.style,\n arrowhead: readStyle.arrowhead,\n arcType: 'read',\n });\n }\n\n // Reset arcs (only those without matching output)\n const outputPlaceNames = t.outputSpec !== null\n ? new Set([...t.outputPlaces()].map(p => p.name))\n : new Set<string>();\n for (const rst of t.resets) {\n if (!outputPlaceNames.has(rst.place.name)) {\n const pid = 'p_' + sanitize(rst.place.name);\n const resetStyle = edgeStyle('reset');\n edges.push({\n from: tid,\n to: pid,\n label: 'reset',\n color: resetStyle.color,\n style: resetStyle.style,\n arrowhead: resetStyle.arrowhead,\n penwidth: resetStyle.penwidth,\n arcType: 'reset',\n });\n }\n }\n }\n\n return {\n id: sanitize(net.name),\n rankdir: config.direction,\n nodes,\n edges,\n subgraphs: [],\n graphAttrs: {\n nodesep: String(GRAPH.nodesep),\n ranksep: String(GRAPH.ranksep),\n fontname: FONT.family,\n },\n nodeDefaults: {\n fontname: FONT.family,\n fontsize: String(FONT.nodeSize),\n },\n edgeDefaults: {\n fontname: FONT.family,\n fontsize: String(FONT.edgeSize),\n },\n };\n}\n\n// ======================== Place Analysis ========================\n\ninterface PlaceInfo {\n hasIncoming: boolean;\n hasOutgoing: boolean;\n}\n\nfunction analyzePlaces(net: PetriNet): Map<string, PlaceInfo> {\n const map = new Map<string, PlaceInfo>();\n\n function ensure(name: string): PlaceInfo {\n let info = map.get(name);\n if (!info) {\n info = { hasIncoming: false, hasOutgoing: false };\n map.set(name, info);\n }\n return info;\n }\n\n for (const t of net.transitions) {\n for (const spec of t.inputSpecs) {\n ensure(spec.place.name).hasOutgoing = true;\n }\n if (t.outputSpec !== null) {\n for (const p of t.outputPlaces()) {\n ensure(p.name).hasIncoming = true;\n }\n }\n for (const inh of t.inhibitors) {\n ensure(inh.place.name);\n }\n for (const r of t.reads) {\n ensure(r.place.name).hasOutgoing = true;\n }\n for (const rst of t.resets) {\n ensure(rst.place.name);\n }\n }\n\n return map;\n}\n\nfunction placeCategory(info: PlaceInfo, isEnvironment: boolean): NodeCategory {\n if (isEnvironment) return 'environment';\n if (!info.hasIncoming) return 'start';\n if (!info.hasOutgoing) return 'end';\n return 'place';\n}\n\n// ======================== Helpers ========================\n\nfunction transitionLabel(t: Transition, config: DotConfig): string {\n const parts = [t.name];\n\n if (config.showIntervals) {\n const e = earliest(t.timing);\n const l = latest(t.timing);\n const max = hasDeadline(t.timing) ? String(l) : '\\u221e';\n parts.push(`[${e}, ${max}]ms`);\n }\n\n if (config.showPriority && t.priority !== 0) {\n parts.push(`prio=${t.priority}`);\n }\n\n return parts.join(' ');\n}\n\nfunction outputEdges(transitionId: string, out: Out, branchLabel: string | null): GraphEdge[] {\n const outStyle = edgeStyle('output');\n\n switch (out.type) {\n case 'place': {\n const pid = 'p_' + sanitize(out.place.name);\n return [{\n from: transitionId,\n to: pid,\n label: branchLabel ?? undefined,\n color: outStyle.color,\n style: outStyle.style,\n arrowhead: outStyle.arrowhead,\n arcType: 'output',\n }];\n }\n\n case 'forward-input': {\n const pid = 'p_' + sanitize(out.to.name);\n const label = (branchLabel ? branchLabel + ' ' : '') + '\\u27f5' + out.from.name;\n return [{\n from: transitionId,\n to: pid,\n label,\n color: outStyle.color,\n style: 'dashed' as const,\n arrowhead: outStyle.arrowhead,\n arcType: 'output',\n }];\n }\n\n case 'and':\n return out.children.flatMap(c => outputEdges(transitionId, c, branchLabel));\n\n case 'xor': {\n const edges: GraphEdge[] = [];\n for (const child of out.children) {\n const label = inferBranchLabel(child);\n edges.push(...outputEdges(transitionId, child, label));\n }\n return edges;\n }\n\n case 'timeout':\n return outputEdges(transitionId, out.child, `\\u23f1${out.afterMs}ms`);\n }\n}\n\nfunction inferBranchLabel(out: Out): string | null {\n switch (out.type) {\n case 'place': return out.place.name;\n case 'timeout': return `\\u23f1${out.afterMs}ms`;\n case 'forward-input': return out.to.name;\n case 'and':\n case 'xor':\n return null;\n }\n}\n","/**\n * Renders a Graph to DOT (Graphviz) string.\n *\n * Pure function with zero Petri net knowledge. Operates solely on the\n * format-agnostic Graph model.\n *\n * @module export/dot-renderer\n */\n\nimport type { Graph, GraphNode, GraphEdge, Subgraph } from './graph.js';\n\n// ======================== Public API ========================\n\n/** Renders a Graph to a DOT string suitable for Graphviz. */\nexport function renderDot(graph: Graph): string {\n const lines: string[] = [];\n\n lines.push(`digraph ${quoteId(graph.id)} {`);\n\n // Graph attributes\n lines.push(` rankdir=${graph.rankdir};`);\n for (const [key, value] of Object.entries(graph.graphAttrs)) {\n lines.push(` ${key}=${quoteAttr(value)};`);\n }\n\n // Node defaults\n if (Object.keys(graph.nodeDefaults).length > 0) {\n lines.push(` node [${formatAttrs(graph.nodeDefaults)}];`);\n }\n\n // Edge defaults\n if (Object.keys(graph.edgeDefaults).length > 0) {\n lines.push(` edge [${formatAttrs(graph.edgeDefaults)}];`);\n }\n\n lines.push('');\n\n // Subgraphs\n for (const sg of graph.subgraphs) {\n lines.push(...renderSubgraph(sg, ' '));\n lines.push('');\n }\n\n // Nodes\n for (const node of graph.nodes) {\n lines.push(` ${renderNode(node)}`);\n }\n\n if (graph.nodes.length > 0) {\n lines.push('');\n }\n\n // Edges\n for (const edge of graph.edges) {\n lines.push(` ${renderEdge(edge)}`);\n }\n\n lines.push('}');\n\n return lines.join('\\n');\n}\n\n// ======================== Internal Rendering ========================\n\nfunction renderNode(node: GraphNode): string {\n const attrs: Record<string, string> = {\n label: node.label,\n shape: node.shape,\n style: node.style ? `\"filled,${node.style}\"` : 'filled',\n fillcolor: node.fill,\n color: node.stroke,\n penwidth: String(node.penwidth),\n };\n\n if (node.height !== undefined) {\n attrs['height'] = String(node.height);\n }\n if (node.width !== undefined) {\n attrs['width'] = String(node.width);\n }\n\n // Merge extra attrs\n if (node.attrs) {\n for (const [key, value] of Object.entries(node.attrs)) {\n attrs[key] = value;\n }\n }\n\n return `${quoteId(node.id)} [${formatNodeAttrs(attrs)}];`;\n}\n\nfunction renderEdge(edge: GraphEdge): string {\n const attrs: Record<string, string> = {\n color: edge.color,\n style: edge.style,\n arrowhead: edge.arrowhead,\n };\n\n if (edge.label !== undefined) {\n attrs['label'] = edge.label;\n }\n if (edge.penwidth !== undefined) {\n attrs['penwidth'] = String(edge.penwidth);\n }\n\n // Merge extra attrs\n if (edge.attrs) {\n for (const [key, value] of Object.entries(edge.attrs)) {\n attrs[key] = value;\n }\n }\n\n return `${quoteId(edge.from)} -> ${quoteId(edge.to)} [${formatNodeAttrs(attrs)}];`;\n}\n\nfunction renderSubgraph(sg: Subgraph, indent: string): string[] {\n const lines: string[] = [];\n lines.push(`${indent}subgraph ${quoteId('cluster_' + sg.id)} {`);\n\n if (sg.label !== undefined) {\n lines.push(`${indent} label=${quoteAttr(sg.label)};`);\n }\n\n if (sg.attrs) {\n for (const [key, value] of Object.entries(sg.attrs)) {\n lines.push(`${indent} ${key}=${quoteAttr(value)};`);\n }\n }\n\n for (const node of sg.nodes) {\n lines.push(`${indent} ${renderNode(node)}`);\n }\n\n lines.push(`${indent}}`);\n return lines;\n}\n\n// ======================== DOT Quoting ========================\n\n/** Quotes a DOT identifier. Always quotes to be safe with special chars. */\nfunction quoteId(id: string): string {\n // DOT keywords that must be quoted\n if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(id) && !isDotKeyword(id)) {\n return id;\n }\n return `\"${escapeDot(id)}\"`;\n}\n\n/** Quotes a DOT attribute value. */\nfunction quoteAttr(value: string): string {\n // Numbers don't need quoting\n if (/^-?\\d+(\\.\\d+)?$/.test(value)) {\n return value;\n }\n return `\"${escapeDot(value)}\"`;\n}\n\n/** Escapes special characters for DOT strings. */\nfunction escapeDot(s: string): string {\n return s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n\n/**\n * Formats node/edge attributes where certain values (like style with commas)\n * need special handling.\n */\nfunction formatNodeAttrs(attrs: Record<string, string>): string {\n return Object.entries(attrs)\n .map(([key, value]) => {\n // Style values that are already pre-quoted (contain the quote char)\n if (value.startsWith('\"') && value.endsWith('\"')) {\n return `${key}=${value}`;\n }\n return `${key}=${quoteAttr(value)}`;\n })\n .join(', ');\n}\n\n/** Formats simple key=value attributes. */\nfunction formatAttrs(attrs: Readonly<Record<string, string>>): string {\n return Object.entries(attrs)\n .map(([key, value]) => `${key}=${quoteAttr(value)}`)\n .join(', ');\n}\n\n/** DOT language keywords that must be quoted when used as identifiers. */\nfunction isDotKeyword(id: string): boolean {\n const lower = id.toLowerCase();\n return lower === 'graph' || lower === 'digraph' || lower === 'subgraph'\n || lower === 'node' || lower === 'edge' || lower === 'strict';\n}\n","/**\n * Convenience function for exporting a PetriNet to DOT format.\n *\n * @module export/dot-exporter\n */\n\nimport type { PetriNet } from '../core/petri-net.js';\nimport type { DotConfig } from './petri-net-mapper.js';\nimport { mapToGraph } from './petri-net-mapper.js';\nimport { renderDot } from './dot-renderer.js';\n\n/**\n * Exports a PetriNet to DOT (Graphviz) format.\n *\n * @param net the Petri net to export\n * @param config optional export configuration\n * @returns DOT string suitable for rendering with Graphviz\n */\nexport function dotExport(net: PetriNet, config?: DotConfig): string {\n return renderDot(mapToGraph(net, config));\n}\n"],"mappings":"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","names":[]}
|