libpetri 2.7.0 → 2.8.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.
@@ -1,5 +1,5 @@
1
1
  import { Application } from 'typedoc';
2
- import { P as PetriNet, S as SubnetDef, o as Instance } from '../petri-net-D73-PO6d.js';
2
+ import { P as PetriNet, S as SubnetDef, o as Instance } from '../petri-net-B4wQwsUj.js';
3
3
 
4
4
  /**
5
5
  * TypeDoc plugin for `@petrinet` and `@subnet` tags — auto-generates
@@ -3,7 +3,8 @@ import {
3
3
  dotExport,
4
4
  nodeStyle,
5
5
  sanitize
6
- } from "../chunk-ULX3OG6H.js";
6
+ } from "../chunk-JVI5HFRX.js";
7
+ import "../chunk-E3ZWB645.js";
7
8
  import "../chunk-ATT7U5H5.js";
8
9
 
9
10
  // src/doclet/petri-net-plugin.ts
@@ -446,7 +447,7 @@ function escapeLabel(s) {
446
447
 
447
448
  // src/doclet/petri-net-plugin.ts
448
449
  async function getDotExport() {
449
- const mod = await import("../dot-exporter-TYC6FUAD.js");
450
+ const mod = await import("../dot-exporter-SHBYMMJ3.js");
450
451
  return mod.dotExport;
451
452
  }
452
453
  var TAG_PETRINET = "@petrinet";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/doclet/petri-net-plugin.ts","../../src/doclet/net-resolver.ts","../../src/doclet/diagram-renderer.ts","../../src/doclet/subnet-header.ts","../../src/doclet/subnet-dot-export.ts","../../src/doclet/svg-renderer.ts"],"sourcesContent":["/**\n * TypeDoc plugin for `@petrinet` and `@subnet` tags — auto-generates\n * interactive SVG diagrams from PetriNet / SubnetDef / Instance definitions\n * and embeds them in TypeDoc output.\n *\n * Mirrors: `org.libpetri.doclet.PetriNetTaglet` + `SubnetTaglet`\n *\n * Plugin lifecycle (TypeDoc hooks):\n * 1. `bootstrapEnd` → register `@petrinet` and `@subnet` as known block tags.\n * 2. `preRenderAsyncJobs` → walk reflections, resolve references, generate\n * SVGs, cache HTML.\n * 3. `comment.beforeTags` → inject cached HTML via `JSX.Raw`, skip default\n * rendering for the recognised tags.\n *\n * @module doclet/petri-net-plugin\n */\n\nimport {\n type Application,\n type CommentTag,\n type DeclarationReflection,\n type ProjectReflection,\n type Reflection,\n JSX,\n} from 'typedoc';\nimport { resolveNet, type ResolvedNet } from './net-resolver.js';\nimport { renderSvg, renderSubnetSvg, escapeHtml } from './diagram-renderer.js';\nimport { forSubnetDef, forInstance } from './subnet-header.js';\nimport { fullBody as subnetFullBody, interfaceOnly as subnetInterfaceOnly } from './subnet-dot-export.js';\n\n// Lazy import to avoid requiring libpetri/export at module level.\nasync function getDotExport(): Promise<typeof import('../export/dot-exporter.js').dotExport> {\n const mod = await import('../export/dot-exporter.js');\n return mod.dotExport;\n}\n\n/** Block tag for full body diagrams — resolves PetriNet / SubnetDef / Instance. */\nconst TAG_PETRINET = '@petrinet' as `@${string}`;\n/** Block tag for interface-only subnet diagrams. */\nconst TAG_SUBNET = '@subnet' as `@${string}`;\n\n/** Cache: reflection ID → rendered HTML string */\nconst htmlCache = new Map<number, string>();\n\n/**\n * Loads the petri-net plugin into the TypeDoc application.\n *\n * @param app - the TypeDoc Application instance\n */\nexport function load(app: Application): void {\n // 1. Register both tags as known block tags at bootstrap time.\n app.on('bootstrapEnd', () => {\n const blockTags = app.options.getValue('blockTags') as string[];\n const additions: string[] = [];\n if (!blockTags.includes(TAG_PETRINET)) additions.push(TAG_PETRINET);\n if (!blockTags.includes(TAG_SUBNET)) additions.push(TAG_SUBNET);\n if (additions.length > 0) {\n app.options.setValue('blockTags', [...blockTags, ...additions]);\n }\n });\n\n // 2. Resolve references and generate SVG during pre-render async phase.\n app.renderer.preRenderAsyncJobs.push(async (output) => {\n htmlCache.clear();\n await processProject(app, output.project);\n });\n\n // 3. Inject cached HTML into comment output, suppress default tag rendering.\n app.renderer.hooks.on('comment.beforeTags', (_context, comment, reflection) => {\n const cached = htmlCache.get(reflection.id);\n if (!cached) return JSX.createElement(JSX.Raw, { html: '' });\n\n // Mark our tags as skip so TypeDoc doesn't render them as plain text.\n for (const tag of comment.blockTags) {\n if (tag.tag === TAG_PETRINET || tag.tag === TAG_SUBNET) {\n tag.skipRendering = true;\n }\n }\n\n return JSX.createElement(JSX.Raw, { html: cached });\n });\n}\n\n/**\n * Walks all reflections in the project and processes `@petrinet` / `@subnet`\n * tags. Per-reflection HTML accumulates in {@link htmlCache} so multiple tags\n * on one symbol render in declaration order.\n */\nasync function processProject(app: Application, project: ProjectReflection): Promise<void> {\n const reflections = Object.values(project.reflections);\n\n for (const reflection of reflections) {\n const comment = reflection.comment;\n if (!comment) continue;\n\n for (const tag of comment.blockTags) {\n const isPetrinet = tag.tag === TAG_PETRINET;\n const isSubnet = tag.tag === TAG_SUBNET;\n if (!isPetrinet && !isSubnet) continue;\n\n const reference = tagContent(tag);\n try {\n const html = isSubnet\n ? await generateInterfaceOnly(reference, reflection)\n : await generateDiagram(reference, reflection);\n const existing = htmlCache.get(reflection.id) ?? '';\n htmlCache.set(reflection.id, existing + html);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n const tagName = isSubnet ? '@subnet' : '@petrinet';\n app.logger.warn(`${tagName} error for ${reflection.getFriendlyFullName()}: ${msg}`);\n const html = errorHtml(`Error generating diagram for '${reference}': ${msg}`);\n const existing = htmlCache.get(reflection.id) ?? '';\n htmlCache.set(reflection.id, existing + html);\n }\n }\n }\n}\n\n/**\n * Generates a diagram HTML string for a single `@petrinet` reference. Resolves\n * the reference to one of {@link ResolvedNet} variants and dispatches to the\n * matching renderer.\n */\nasync function generateDiagram(\n reference: string,\n reflection: Reflection,\n): Promise<string> {\n const trimmed = reference.trim();\n if (!trimmed) {\n return errorHtml(`Empty @petrinet reference on ${reflection.getFriendlyFullName()}`);\n }\n\n const sourceFile = getSourceFilePath(reflection);\n if (!sourceFile) {\n return errorHtml(`Cannot determine source file for ${reflection.getFriendlyFullName()}`);\n }\n\n const resolved = await resolveNet(trimmed, sourceFile);\n if (!resolved) {\n return errorHtml(`Cannot resolve PetriNet/SubnetDef/Instance: ${trimmed}`);\n }\n\n return await renderResolved(resolved, /* interfaceOnly */ false);\n}\n\n/**\n * Generates an interface-only diagram for a `@subnet` reference. When the\n * resolved reference is not a {@link import('../core/subnet-def.js').SubnetDef},\n * falls back to the regular diagram so the tag still produces useful output.\n */\nasync function generateInterfaceOnly(\n reference: string,\n reflection: Reflection,\n): Promise<string> {\n const trimmed = reference.trim();\n if (!trimmed) {\n return errorHtml(`Empty @subnet reference on ${reflection.getFriendlyFullName()}`);\n }\n\n const sourceFile = getSourceFilePath(reflection);\n if (!sourceFile) {\n return errorHtml(`Cannot determine source file for ${reflection.getFriendlyFullName()}`);\n }\n\n const resolved = await resolveNet(trimmed, sourceFile);\n if (!resolved) {\n return errorHtml(`Cannot resolve SubnetDef: ${trimmed}`);\n }\n\n return await renderResolved(resolved, /* interfaceOnly */ true);\n}\n\n/**\n * Dispatches a {@link ResolvedNet} to the matching renderer. The\n * `interfaceOnly` flag is honoured only when the resolved kind is `subnet` —\n * for `net` and `instance` it is ignored (the body is the whole point of\n * those references).\n */\nasync function renderResolved(\n resolved: ResolvedNet,\n interfaceOnly: boolean,\n): Promise<string> {\n switch (resolved.kind) {\n case 'net': {\n const dotExport = await getDotExport();\n const dot = dotExport(resolved.value);\n return renderDiagramHtml(resolved.title, dot, /* header */ null);\n }\n case 'subnet': {\n const dot = interfaceOnly\n ? subnetInterfaceOnly(resolved.value)\n : subnetFullBody(resolved.value);\n const header = forSubnetDef(resolved.value, interfaceOnly);\n const title = resolved.value.name + (interfaceOnly ? ' (interface)' : '');\n return renderDiagramHtml(title, dot, header);\n }\n case 'instance': {\n const dotExport = await getDotExport();\n const dot = dotExport(resolved.value.renamedBody);\n const header = forInstance(resolved.value);\n return renderDiagramHtml(resolved.title, dot, header);\n }\n }\n}\n\n/**\n * Emits the diagram HTML. The canonical viewer renders DOT to SVG\n * client-side via Graphviz-WASM, so no server-side SVG rendering happens\n * here. Routes through the subnet-aware renderer when `header` is non-null,\n * the plain renderer otherwise.\n */\nfunction renderDiagramHtml(\n title: string,\n dot: string,\n header: string | null,\n): string {\n if (header !== null) {\n return renderSubnetSvg(title, header, dot);\n }\n return renderSvg(title, dot);\n}\n\n/**\n * Extracts text content from a CommentTag.\n */\nfunction tagContent(tag: CommentTag): string {\n return tag.content\n .map((part) => part.text)\n .join('')\n .trim();\n}\n\n/**\n * Gets the source file path from a reflection. Walks parents because\n * comment-bearing reflections sometimes lack their own `sources` (e.g.\n * inherited members).\n */\nfunction getSourceFilePath(reflection: Reflection): string | null {\n const decl = reflection as DeclarationReflection;\n if (decl.sources && decl.sources.length > 0) {\n return decl.sources[0]!.fullFileName;\n }\n if (reflection.parent) {\n return getSourceFilePath(reflection.parent);\n }\n return null;\n}\n\n/**\n * Renders an error message as styled HTML.\n */\nfunction errorHtml(message: string): string {\n return `<div class=\"petrinet-error\" style=\"color: #dc3545; border: 1px solid #dc3545; padding: 10px; border-radius: 4px;\">\n<strong>@petrinet Error:</strong> ${escapeHtml(message)}\n</div>`;\n}\n","/**\n * Dynamic import-based resolver for `@petrinet` / `@subnet` references.\n *\n * Resolves three kinds of static exports per Java's `PetriNetTaglet` design:\n * 1. `PetriNet` — full body diagram (existing behaviour).\n * 2. `SubnetDef<?>` — body diagram with interface ports highlighted, plus a\n * subnet header with port/channel badges.\n * 3. `Instance<?>` — renamed body diagram (already prefix-clustered by the\n * DOT exporter), plus an instance header with prefix, def name, and\n * params summary.\n *\n * TypeScript cannot use reflection like Java — modules must be importable at\n * doc time (typically from `dist/` after `npm run build`).\n *\n * Tag format:\n * ```\n * @petrinet ./path/to/module#exportName — access a static export\n * @petrinet ./path/to/module#functionName() — call a function returning one\n * @petrinet #localExport — resolve from same file\n * ```\n *\n * Mirrors: `org.libpetri.doclet.PetriNetTaglet.resolveReference`\n *\n * @module doclet/net-resolver\n */\n\nimport { resolve, dirname } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { PetriNet } from '../core/petri-net.js';\nimport type { SubnetDef } from '../core/subnet-def.js';\nimport type { Instance } from '../core/instance.js';\n\n/**\n * Discriminated-union result from {@link resolveNet}. Each variant carries\n * the resolved value plus a display title.\n */\nexport type ResolvedNet =\n | { readonly kind: 'net'; readonly value: PetriNet; readonly title: string }\n | { readonly kind: 'subnet'; readonly value: SubnetDef<unknown>; readonly title: string }\n | { readonly kind: 'instance'; readonly value: Instance<unknown>; readonly title: string };\n\n/**\n * Parses a `@petrinet` / `@subnet` reference and resolves it via dynamic\n * import. Returns `null` when the reference cannot be parsed or imported, or\n * when the resolved value is none of the three supported kinds.\n *\n * @param reference - the tag content, e.g. `./definition#buildDebugNet()`\n * @param sourceFilePath - absolute path to the source file containing the tag\n */\nexport async function resolveNet(\n reference: string,\n sourceFilePath: string,\n): Promise<ResolvedNet | null> {\n const trimmed = reference.trim().split(/\\s+/)[0] ?? '';\n if (!trimmed) return null;\n\n const hashIndex = trimmed.indexOf('#');\n if (hashIndex === -1) return null;\n\n const modulePath = trimmed.substring(0, hashIndex);\n const exportRef = trimmed.substring(hashIndex + 1);\n if (!exportRef) return null;\n\n const isCall = exportRef.endsWith('()');\n const exportName = isCall ? exportRef.slice(0, -2) : exportRef;\n\n // Resolve module path relative to the source file.\n let absolutePath: string;\n if (modulePath) {\n absolutePath = resolve(dirname(sourceFilePath), modulePath);\n } else {\n // `#localExport` — resolve from same file's compiled output.\n absolutePath = sourceFilePath;\n }\n\n // Try `.js` extension for compiled output, then `.ts` for ts-node scenarios.\n const candidates = [\n absolutePath,\n absolutePath + '.js',\n absolutePath + '.ts',\n absolutePath.replace(/\\.ts$/, '.js'),\n ];\n\n let mod: Record<string, unknown> | undefined;\n for (const candidate of candidates) {\n try {\n mod = await import(pathToFileURL(candidate).href) as Record<string, unknown>;\n break;\n } catch {\n // Try next candidate.\n }\n }\n\n if (!mod) return null;\n\n const exported = mod[exportName];\n if (exported == null) return null;\n\n let value: unknown;\n if (isCall) {\n if (typeof exported !== 'function') return null;\n const result = (exported as (...args: unknown[]) => unknown)();\n // Support functions that return `{ net: PetriNet, ... }` for legacy\n // callers; otherwise pass the result through directly.\n if (\n result !== null && typeof result === 'object' && 'net' in result &&\n isPetriNetLike((result as { net: unknown }).net)\n ) {\n value = (result as { net: unknown }).net;\n } else {\n value = result;\n }\n } else {\n value = exported;\n }\n\n return classify(value);\n}\n\n/**\n * Wraps the resolved value into a {@link ResolvedNet} variant by structural\n * shape — checks {@link Instance} before {@link SubnetDef} before\n * {@link PetriNet} so the most specific match wins (Instance has both `def`\n * and `renamedBody`; SubnetDef has `iface` and `body`; PetriNet has only\n * `transitions` + `name`).\n *\n * Returns `null` when the value matches none of the supported shapes.\n */\nfunction classify(value: unknown): ResolvedNet | null {\n if (value === null || typeof value !== 'object') return null;\n\n if (isInstanceLike(value)) {\n const inst = value as Instance<unknown>;\n return { kind: 'instance', value: inst, title: `${inst.def.name} :: ${inst.prefix}` };\n }\n if (isSubnetDefLike(value)) {\n const def = value as SubnetDef<unknown>;\n return { kind: 'subnet', value: def, title: def.name };\n }\n if (isPetriNetLike(value)) {\n const net = value as PetriNet;\n return { kind: 'net', value: net, title: net.name };\n }\n return null;\n}\n\n/**\n * Structural test for {@link PetriNet}: has a string `name` and a `transitions`\n * Set. Avoids `instanceof` because the imported module may have re-bound the\n * class identity (TypeDoc's bundled output vs `dist/` import path).\n */\nfunction isPetriNetLike(value: unknown): value is PetriNet {\n if (value === null || typeof value !== 'object') return false;\n const candidate = value as { name?: unknown; transitions?: unknown };\n return typeof candidate.name === 'string' && candidate.transitions instanceof Set;\n}\n\n/**\n * Structural test for {@link SubnetDef}: has a string `name`, a {@link\n * PetriNet}-shaped `body`, and an `iface` carrying `ports` + `channels` maps.\n */\nfunction isSubnetDefLike(value: unknown): value is SubnetDef<unknown> {\n if (value === null || typeof value !== 'object') return false;\n const candidate = value as { name?: unknown; body?: unknown; iface?: unknown };\n if (typeof candidate.name !== 'string') return false;\n if (!isPetriNetLike(candidate.body)) return false;\n const iface = candidate.iface as { ports?: unknown; channels?: unknown } | undefined;\n return iface !== undefined && iface !== null\n && iface.ports instanceof Map && iface.channels instanceof Map;\n}\n\n/**\n * Structural test for {@link Instance}: has a string `prefix`, a {@link\n * SubnetDef}-shaped `def`, and a {@link PetriNet}-shaped `renamedBody`.\n */\nfunction isInstanceLike(value: unknown): value is Instance<unknown> {\n if (value === null || typeof value !== 'object') return false;\n const candidate = value as { prefix?: unknown; def?: unknown; renamedBody?: unknown };\n return typeof candidate.prefix === 'string'\n && isSubnetDefLike(candidate.def)\n && isPetriNetLike(candidate.renamedBody);\n}\n","/**\n * Shared HTML renderer for Petri Net diagrams in TypeDoc.\n *\n * Generates consistent HTML markup that mounts the canonical\n * {@link https://libpetri.org | libpetri} viewer client-side. The viewer IIFE\n * bundle (Graphviz WASM inlined, offline-safe) is inlined into the generated\n * HTML, making the plugin fully self-contained with no external file\n * dependencies.\n *\n * Each diagram container carries its DOT source as a `data-dot` attribute. An\n * init snippet reads the attribute and calls\n * `window.LibpetriViewer.mount(dot, container, { chrome: true })` to render the\n * SVG and wire pan/zoom + cluster legend/filter chrome.\n *\n * Mirrors: `org.libpetri.doclet.DiagramRenderer`\n *\n * @module doclet/diagram-renderer\n */\n\nimport { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nfunction loadResource(filename: string): string {\n return readFileSync(join(__dirname, 'resources', filename), 'utf-8');\n}\n\nlet inlineCss: string | undefined;\nlet inlineJs: string | undefined;\n\nfunction css(): string {\n return (inlineCss ??= loadResource('petrinet-diagrams.css'));\n}\n\nfunction js(): string {\n return (inlineJs ??= loadResource('petrinet-diagrams.js'));\n}\n\n/**\n * Escapes HTML special characters for safe embedding as text content.\n */\nexport function escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\n/**\n * Escapes a string for safe inclusion in an HTML attribute value enclosed in\n * double quotes. Identical to {@link escapeHtml} plus single-quote escaping\n * (defence-in-depth even though we always emit double-quoted attributes).\n */\nfunction escapeAttr(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\n/**\n * Renders a diagram from a DOT source string. The viewer renders the SVG\n * client-side via Graphviz-WASM; no server-side SVG is emitted on the\n * embedded path.\n *\n * Inlines CSS and the viewer IIFE from bundled resources. The IIFE is guarded\n * by an idempotency check (`window._libpetriViewerInit`) so it only executes\n * once per page even when multiple `@petrinet` tags appear.\n *\n * @param title - optional title (null/undefined for no title)\n * @param dotSource - the DOT source code; embedded as `data-dot` and shown in\n * the collapsible \"View DOT Source\" block\n * @returns HTML markup with diagram controls\n */\nexport function renderSvg(\n title: string | null | undefined,\n dotSource: string,\n): string {\n return renderInternal(title ?? null, /* headerHtml */ null, dotSource);\n}\n\n/**\n * Renders a subnet- or instance-aware diagram. Identical to {@link renderSvg}\n * apart from an extra {@code headerHtml} block (the port/channel/params\n * badge bar) prepended above the diagram, and the CSS class\n * {@code subnet-diagram} on the wrapper.\n *\n * @param title diagram title (e.g. \"BoundedBuffer :: b1\")\n * @param headerHtml the HTML produced by {@link import('./subnet-header.js')}\n * @param dotSource the DOT source code\n * @returns HTML markup\n */\nexport function renderSubnetSvg(\n title: string | null | undefined,\n headerHtml: string,\n dotSource: string,\n): string {\n return renderInternal(title ?? null, headerHtml, dotSource);\n}\n\nlet diagramIdCounter = 0;\n\nfunction renderInternal(\n title: string | null,\n headerHtml: string | null,\n dotSource: string,\n): string {\n const titleHtml = title !== null ? `<h4>${escapeHtml(title)}</h4>\\n` : '';\n const summaryText = title !== null ? 'View DOT Source' : 'View Source';\n const diagramClass = headerHtml !== null ? 'petrinet-diagram subnet-diagram' : 'petrinet-diagram';\n const headerBlock = headerHtml !== null ? headerHtml : '';\n const dotAttr = escapeAttr(dotSource);\n const containerId = `libpetri-diagram-${++diagramIdCounter}`;\n\n return `<style>${css()}</style>\n<script>if(!window._libpetriViewerInit){window._libpetriViewerInit=true;\n${js()}\n}</script>\n<div class=\"${diagramClass}\">\n${titleHtml}${headerBlock}<div class=\"diagram-container\" id=\"${containerId}\" data-libpetri-diagram=\"true\" data-dot=\"${dotAttr}\"></div>\n<details>\n<summary>${summaryText}</summary>\n<pre><code>${escapeHtml(dotSource)}</code></pre>\n</details>\n</div>\n<script>(function(){function mount(){var el=document.getElementById(${JSON.stringify(containerId)});if(!el)return;if(el.dataset.libpetriMounted)return;if(!window.LibpetriViewer||typeof window.LibpetriViewer.mount!=='function'){return setTimeout(mount,30);}el.dataset.libpetriMounted='1';try{window.LibpetriViewer.mount(el.dataset.dot,el,{chrome:true});}catch(e){console.error('[libpetri] mount failed',e);}}if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',mount);}else{mount();}})();</script>`;\n}\n","/**\n * HTML-fragment generator for the small \"subnet header\" badge bar that the\n * {@link import('./diagram-renderer.js')} layers above subnet diagrams.\n *\n * For a {@link import('../core/subnet-def.js').SubnetDef} the header lists\n * the subnet name, the parameter type (best-effort — TypeScript erases\n * generics at runtime so the slot is shown as a placeholder), and one badge\n * per port and channel — colour-coded by direction\n * (`interface-port-input` / `-output` / `-inout` CSS classes, plus\n * `interface-channel` for sync channels).\n *\n * For an {@link import('../core/instance.js').Instance} the header lists the\n * instance prefix, the originating definition's name, and the {@link\n * import('../core/instance.js').Instance#params} summary.\n *\n * Mirrors: `org.libpetri.doclet.SubnetHeader`\n *\n * @module doclet/subnet-header\n */\n\nimport type { Instance } from '../core/instance.js';\nimport type { Interface, Port } from '../core/interface.js';\nimport type { SubnetDef } from '../core/subnet-def.js';\nimport { escapeHtml } from './diagram-renderer.js';\n\n/**\n * Builds the header HTML for a {@link SubnetDef} field.\n *\n * @param def the subnet definition\n * @param interfaceOnly when `true`, the header carries the \"(interface only)\"\n * badge so the reader knows the body is intentionally\n * omitted\n */\nexport function forSubnetDef(def: SubnetDef<unknown>, interfaceOnly: boolean): string {\n const sb: string[] = [];\n sb.push(`<div class=\"subnet-header\">\\n`);\n sb.push(` <div class=\"subnet-header-row\">\\n`);\n sb.push(` <span class=\"subnet-header-label\">subnet</span>\\n`);\n sb.push(` <span class=\"subnet-header-name\">${escapeHtml(def.name)}</span>\\n`);\n // TypeScript erases generics at runtime, so the parameter-type slot is\n // populated with a placeholder (\"?\"). Java emits the simple class name —\n // the structural HTML is otherwise byte-equivalent.\n sb.push(` <span class=\"subnet-header-param\">&lt;?&gt;</span>\\n`);\n if (interfaceOnly) {\n sb.push(` <span class=\"subnet-header-badge subnet-header-badge-interface\">interface only</span>\\n`);\n }\n sb.push(` </div>\\n`);\n sb.push(renderPortChannelBadges(def.iface));\n sb.push(`</div>\\n`);\n return sb.join('');\n}\n\n/**\n * Builds the header HTML for an {@link Instance} field.\n */\nexport function forInstance(instance: Instance<unknown>): string {\n const def = instance.def;\n const sb: string[] = [];\n sb.push(`<div class=\"subnet-header\">\\n`);\n sb.push(` <div class=\"subnet-header-row\">\\n`);\n sb.push(` <span class=\"subnet-header-label\">instance</span>\\n`);\n sb.push(` <span class=\"subnet-header-name\">${escapeHtml(instance.prefix)}</span>\\n`);\n sb.push(` <span class=\"subnet-header-of\">of</span>\\n`);\n sb.push(` <span class=\"subnet-header-name\">${escapeHtml(def.name)}</span>\\n`);\n const params = instance.params;\n if (params !== null && params !== undefined) {\n sb.push(` <span class=\"subnet-header-params\">params=${escapeHtml(String(params))}</span>\\n`);\n }\n sb.push(` </div>\\n`);\n sb.push(renderPortChannelBadges(def.iface));\n sb.push(`</div>\\n`);\n return sb.join('');\n}\n\n/**\n * Renders the per-port and per-channel badge row. Each badge carries a CSS\n * class identifying its kind so the stylesheet can colour-code by direction.\n */\nfunction renderPortChannelBadges(iface: Interface): string {\n if (iface.ports.size === 0 && iface.channels.size === 0) {\n return '';\n }\n const sb: string[] = [];\n sb.push(` <div class=\"subnet-header-badges\">\\n`);\n for (const port of iface.ports.values()) {\n const kind = portKind(port);\n sb.push(` <span class=\"interface-port-badge interface-port-badge-${kind}\">`);\n sb.push(`<span class=\"badge-direction\">${kind}</span>`);\n sb.push(`<span class=\"badge-name\">${escapeHtml(port.name)}</span>`);\n // TypeScript erases generics so we can't print the runtime token type;\n // omit the type-name span rather than emit a bogus value.\n sb.push(`</span>\\n`);\n }\n for (const channel of iface.channels.values()) {\n sb.push(` <span class=\"interface-channel-badge\">`);\n sb.push(`<span class=\"badge-direction\">channel</span>`);\n sb.push(`<span class=\"badge-name\">${escapeHtml(channel.name)}</span>`);\n sb.push(`</span>\\n`);\n }\n sb.push(` </div>\\n`);\n return sb.join('');\n}\n\nfunction portKind(port: Port<unknown>): 'input' | 'output' | 'inout' {\n return port.direction;\n}\n","/**\n * DOT generators for the subnet-aware diagrams the {@link\n * import('./petri-net-plugin.js')} plugin draws.\n *\n * Two flavours:\n * - {@link fullBody} — the subnet's complete body, but with its interface-port\n * places restyled with the `interface-port` category from\n * `petri-net-styles.json` so they read as boundary elements at a glance. A\n * small `subgraph cluster_iface_*` with label `\"interface\"` surrounds the\n * port places and channel transitions to advertise the subnet boundary\n * visually.\n * - {@link interfaceOnly} — a tiny diagram of just the port places, the\n * channel transitions, and a single stub node indicating the body is\n * omitted. Used by the `@subnet` block tag.\n *\n * This module stays in the doclet directory (rather than living in\n * `export/`) because it is a doclet-presentation concern — the production\n * export pipeline never adds the `interface` cluster.\n *\n * Mirrors: `org.libpetri.doclet.SubnetDotExport`\n *\n * @module doclet/subnet-dot-export\n */\n\nimport type { SubnetDef } from '../core/subnet-def.js';\nimport type { Interface, Port, Channel } from '../core/interface.js';\nimport { dotExport } from '../export/dot-exporter.js';\nimport { sanitize } from '../export/petri-net-mapper.js';\nimport { nodeStyle, FONT } from '../export/styles.js';\n\n/**\n * Renders the full body of a {@link SubnetDef} with the interface ports\n * restyled. The output is a post-processed version of {@link dotExport}: the\n * port-place node attribute lines are rewritten so the post-processor swaps in\n * the {@code interface-port} category, channel-transition lines swap in\n * {@code sync-channel}, and an extra {@code subgraph cluster_iface_<name>}\n * block is appended that lists the port nodes by id — overriding their\n * cluster membership without re-emitting them (DOT semantics: a node\n * referenced inside a subgraph block by id alone is treated as a member of\n * that cluster).\n */\nexport function fullBody(def: SubnetDef<unknown>): string {\n let dot = dotExport(def.body);\n const portIds = portNodeIds(def.iface);\n const channelIds = channelNodeIds(def.iface);\n\n // Restyle: rewrite the matched node lines so the post-processor swaps in\n // the interface-port and sync-channel categories. The renderer emits each\n // node as one line ending with `];` so a per-id rewrite is sufficient and\n // deterministic.\n for (const portId of portIds) {\n dot = restyleNode(dot, portId, nodeStyle('interface-port'));\n }\n for (const chId of channelIds) {\n dot = restyleNode(dot, chId, nodeStyle('sync-channel'));\n }\n\n // Wrap the port and channel ids in a header cluster so the doclet's viewer\n // can render the boundary distinctly. Done by injecting an extra subgraph\n // block before the closing `}` of the digraph.\n if (portIds.size > 0 || channelIds.size > 0) {\n let iface = '';\n iface += ` subgraph cluster_iface_${sanitize(def.name)} {\\n`;\n iface += ` label=\"interface\";\\n`;\n iface += ` style=\"rounded,dashed\";\\n`;\n iface += ` bgcolor=\"#F0F6FF\";\\n`;\n iface += ` penwidth=2;\\n`;\n for (const id of portIds) {\n iface += ` ${id};\\n`;\n }\n for (const id of channelIds) {\n iface += ` ${id};\\n`;\n }\n iface += ` }\\n`;\n\n const lastBrace = dot.lastIndexOf('}');\n if (lastBrace > 0) {\n dot = dot.substring(0, lastBrace) + iface + dot.substring(lastBrace);\n }\n }\n return dot;\n}\n\n/**\n * Renders an interface-only diagram: just the port places + channel\n * transitions + a single stub node labelled \"(internals omitted)\" so the\n * reader knows the body has not been drawn.\n */\nexport function interfaceOnly(def: SubnetDef<unknown>): string {\n const sb: string[] = [];\n sb.push(`digraph ${sanitize(def.name)} {\\n`);\n sb.push(` rankdir=LR;\\n`);\n sb.push(` nodesep=0.5;\\n`);\n sb.push(` ranksep=0.6;\\n`);\n sb.push(` fontname=\"${FONT.family}\";\\n`);\n sb.push(` node [fontname=\"${FONT.family}\", fontsize=12];\\n`);\n sb.push(` edge [fontname=\"${FONT.family}\", fontsize=10];\\n`);\n sb.push('\\n');\n\n const stubId = 'stub_' + sanitize(def.name);\n\n // Group ports by direction: inputs on the left, outputs on the right,\n // inouts above. This keeps the interface diagram visually structured even\n // when the body internals are absent.\n const inputs: Port<unknown>[] = [];\n const outputs: Port<unknown>[] = [];\n const inouts: Port<unknown>[] = [];\n for (const port of def.iface.ports.values()) {\n switch (port.direction) {\n case 'input': inputs.push(port); break;\n case 'output': outputs.push(port); break;\n case 'inout': inouts.push(port); break;\n }\n }\n\n // Emit port nodes.\n for (const port of inputs) emitPortNode(sb, port, 'input');\n for (const port of outputs) emitPortNode(sb, port, 'output');\n for (const port of inouts) emitPortNode(sb, port, 'inout');\n\n // Emit channel nodes.\n const syncStyle = nodeStyle('sync-channel');\n for (const ch of def.iface.channels.values()) {\n sb.push(` ${channelNodeId(ch)} [`);\n sb.push(`label=\"⇄ ${escapeLabel(ch.name)}\", `);\n sb.push(`shape=${syncStyle.shape}, `);\n sb.push(`style=\"filled\", `);\n sb.push(`fillcolor=\"${syncStyle.fill}\", `);\n sb.push(`color=\"${syncStyle.stroke}\", `);\n sb.push(`penwidth=${trimNumber(syncStyle.penwidth)}`);\n sb.push(`];\\n`);\n }\n\n // Emit stub node.\n sb.push(` ${stubId} [`);\n sb.push(`label=\"${escapeLabel(def.name)}\\\\n(internals omitted)\", `);\n sb.push(`shape=box, style=\"filled,dashed,rounded\", `);\n sb.push(`fillcolor=\"#FFFFFF\", color=\"#666666\", penwidth=1, `);\n sb.push(`fontsize=11`);\n sb.push(`];\\n`);\n sb.push('\\n');\n\n // Connect inputs -> stub -> outputs; inouts and channels link both ways.\n for (const port of inputs) {\n sb.push(` ${portNodeId(port)} -> ${stubId} [color=\"#1d4ed8\", arrowhead=normal];\\n`);\n }\n for (const port of outputs) {\n sb.push(` ${stubId} -> ${portNodeId(port)} [color=\"#1d4ed8\", arrowhead=normal];\\n`);\n }\n for (const port of inouts) {\n sb.push(` ${portNodeId(port)} -> ${stubId} [color=\"#1d4ed8\", arrowhead=normalnormal, dir=both];\\n`);\n }\n for (const ch of def.iface.channels.values()) {\n sb.push(` ${channelNodeId(ch)} -> ${stubId} [color=\"#6d28d9\", arrowhead=normal, style=dashed];\\n`);\n }\n\n sb.push(`}\\n`);\n return sb.join('');\n}\n\n// ============================================================\n// Helpers\n// ============================================================\n\nfunction emitPortNode(sb: string[], port: Port<unknown>, direction: string): void {\n const style = nodeStyle('interface-port');\n // Token type isn't carried at runtime in TypeScript (generics erased), so\n // the xlabel is the direction marker only — Java additionally appends the\n // port's tokenType simple name. The structural content is otherwise\n // identical.\n sb.push(` ${portNodeId(port)} [`);\n sb.push(`label=\"${escapeLabel(port.name)}\", `);\n sb.push(`xlabel=\"${escapeLabel(direction)}\", `);\n sb.push(`shape=${style.shape}, `);\n sb.push(`style=\"filled,${style.style ?? 'solid'}\", `);\n sb.push(`fillcolor=\"${style.fill}\", `);\n sb.push(`color=\"${style.stroke}\", `);\n sb.push(`penwidth=${trimNumber(style.penwidth)}`);\n if (style.width !== undefined) {\n sb.push(`, width=${trimNumber(style.width)}, fixedsize=true`);\n }\n sb.push(`];\\n`);\n}\n\nfunction portNodeId(port: Port<unknown>): string {\n return 'p_' + sanitize(port.place.name);\n}\n\nfunction channelNodeId(ch: Channel): string {\n return 't_' + sanitize(ch.transition.name);\n}\n\nfunction portNodeIds(iface: Interface): Set<string> {\n const ids = new Set<string>();\n for (const port of iface.ports.values()) ids.add(portNodeId(port));\n return ids;\n}\n\nfunction channelNodeIds(iface: Interface): Set<string> {\n const ids = new Set<string>();\n for (const ch of iface.channels.values()) ids.add(channelNodeId(ch));\n return ids;\n}\n\n/**\n * Rewrites the {@code fillcolor=}, {@code color=}, {@code style=}, and\n * {@code penwidth=} attributes of the line declaring the given node id so\n * the supplied style takes precedence. Operates as a plain text rewrite:\n * the {@link import('../export/dot-renderer.js').renderDot} output formats\n * each node line deterministically, so a per-attribute regex is reliable.\n */\nfunction restyleNode(\n dot: string,\n nodeId: string,\n style: ReturnType<typeof nodeStyle>,\n): string {\n // The node line begins with: <id> [\n // and ends with: ];\n // Find the line, then surgically swap fillcolor / color / style / penwidth.\n const marker = nodeId + ' [';\n let start = dot.indexOf('\\n ' + marker);\n if (start < 0) start = dot.indexOf(' ' + marker);\n if (start < 0) return dot;\n // Skip the leading newline if present so we operate on the line proper.\n if (dot.charAt(start) === '\\n') start += 1;\n const lineEnd = dot.indexOf('];', start);\n if (lineEnd < 0) return dot;\n let line = dot.substring(start, lineEnd + 2);\n\n // Order matters: keep `fillcolor` before `color` so the substring search\n // for `color=\"` doesn't accidentally hit `fillcolor=\"`.\n line = replaceAttr(line, 'fillcolor', style.fill);\n line = replaceAttr(line, 'color', style.stroke);\n line = replaceAttr(line, 'penwidth', trimNumber(style.penwidth));\n if (style.style !== undefined) {\n // Compose with `filled` because the renderer already includes that.\n line = replaceAttr(line, 'style', `\"filled,${style.style}\"`);\n }\n\n return dot.substring(0, start) + line + dot.substring(lineEnd + 2);\n}\n\n/**\n * Replaces the value of a {@code key=value} pair within a single DOT\n * attribute list. Quotes the value when the existing form was quoted, leaves\n * the value unquoted when the existing form was unquoted (numeric).\n */\nfunction replaceAttr(line: string, key: string, value: string): string {\n // Match key=\"...\" (quoted) — the key must be preceded by a non-word char\n // (start, comma, or space) so `color=` doesn't match inside `fillcolor=`.\n const quotedPat = key + '=\"';\n const qStart = findAttrStart(line, quotedPat);\n if (qStart >= 0) {\n const valStart = qStart + quotedPat.length;\n const valEnd = line.indexOf('\"', valStart);\n if (valEnd < 0) return line;\n let v = value;\n if (v.startsWith('\"') && v.endsWith('\"') && v.length >= 2) {\n v = v.substring(1, v.length - 1);\n }\n return line.substring(0, valStart) + v + line.substring(valEnd);\n }\n // Match key=NN (numeric, ends at ',' or ']').\n const unquoted = key + '=';\n const uStart = findAttrStart(line, unquoted);\n if (uStart < 0) return line;\n const valStart = uStart + unquoted.length;\n let valEnd = valStart;\n while (valEnd < line.length) {\n const c = line.charAt(valEnd);\n if (c === ',' || c === ']') break;\n valEnd++;\n }\n return line.substring(0, valStart) + value + line.substring(valEnd);\n}\n\n/**\n * Finds the start of a `key=` attribute pattern in `line`, ensuring the\n * match is not a suffix of another attribute name (e.g. `color=` must not\n * match inside `fillcolor=`). Returns -1 when no boundary-respecting match\n * exists.\n */\nfunction findAttrStart(line: string, pattern: string): number {\n let from = 0;\n while (from < line.length) {\n const idx = line.indexOf(pattern, from);\n if (idx < 0) return -1;\n if (idx === 0) return idx;\n const prev = line.charAt(idx - 1);\n // Word-boundary check: previous char must not be alphanumeric/underscore.\n if (!/[A-Za-z0-9_]/.test(prev)) return idx;\n from = idx + 1;\n }\n return -1;\n}\n\nfunction trimNumber(d: number): string {\n if (Number.isInteger(d)) return String(d);\n return String(d);\n}\n\nfunction escapeLabel(s: string): string {\n return s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n","/**\n * SVG renderer using `@viz-js/viz` (Graphviz WASM).\n *\n * Pure WASM — zero external dependencies. No system `dot` binary required.\n *\n * Mirrors: Java's `PetriNetTaglet.dotToSvg()` (which uses `dot -Tsvg` subprocess)\n *\n * @module doclet/svg-renderer\n */\n\n/**\n * Renders a DOT string to SVG using the `@viz-js/viz` WASM engine.\n *\n * Strips the XML prolog/DOCTYPE and explicit width/height attributes so the SVG\n * scales via viewBox + CSS instead of overriding with fixed pt sizes.\n *\n * @param dot - the DOT source string\n * @returns SVG markup string\n * @throws if `@viz-js/viz` is not installed or DOT parsing fails\n */\nexport async function dotToSvg(dot: string): Promise<string> {\n // Dynamic import — @viz-js/viz is an optional peer dependency\n const { instance } = await import('@viz-js/viz');\n const viz = await instance();\n let svg = viz.renderString(dot, { format: 'svg', engine: 'dot' });\n\n // Strip XML prolog and DOCTYPE — invalid inside HTML5\n const svgStart = svg.indexOf('<svg');\n if (svgStart > 0) svg = svg.substring(svgStart);\n\n // Strip explicit width/height attributes (e.g. \"1942pt\") so the SVG\n // scales via viewBox + CSS instead of overriding with fixed pt sizes\n svg = svg.replace(/\\s+(?:width|height)=\"[^\"]*\"/g, '');\n\n return svg;\n}\n"],"mappings":"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","names":["dirname","interfaceOnly","valStart","valEnd","interfaceOnly","dotExport"]}
1
+ {"version":3,"sources":["../../src/doclet/petri-net-plugin.ts","../../src/doclet/net-resolver.ts","../../src/doclet/diagram-renderer.ts","../../src/doclet/subnet-header.ts","../../src/doclet/subnet-dot-export.ts","../../src/doclet/svg-renderer.ts"],"sourcesContent":["/**\n * TypeDoc plugin for `@petrinet` and `@subnet` tags — auto-generates\n * interactive SVG diagrams from PetriNet / SubnetDef / Instance definitions\n * and embeds them in TypeDoc output.\n *\n * Mirrors: `org.libpetri.doclet.PetriNetTaglet` + `SubnetTaglet`\n *\n * Plugin lifecycle (TypeDoc hooks):\n * 1. `bootstrapEnd` → register `@petrinet` and `@subnet` as known block tags.\n * 2. `preRenderAsyncJobs` → walk reflections, resolve references, generate\n * SVGs, cache HTML.\n * 3. `comment.beforeTags` → inject cached HTML via `JSX.Raw`, skip default\n * rendering for the recognised tags.\n *\n * @module doclet/petri-net-plugin\n */\n\nimport {\n type Application,\n type CommentTag,\n type DeclarationReflection,\n type ProjectReflection,\n type Reflection,\n JSX,\n} from 'typedoc';\nimport { resolveNet, type ResolvedNet } from './net-resolver.js';\nimport { renderSvg, renderSubnetSvg, escapeHtml } from './diagram-renderer.js';\nimport { forSubnetDef, forInstance } from './subnet-header.js';\nimport { fullBody as subnetFullBody, interfaceOnly as subnetInterfaceOnly } from './subnet-dot-export.js';\n\n// Lazy import to avoid requiring libpetri/export at module level.\nasync function getDotExport(): Promise<typeof import('../export/dot-exporter.js').dotExport> {\n const mod = await import('../export/dot-exporter.js');\n return mod.dotExport;\n}\n\n/** Block tag for full body diagrams — resolves PetriNet / SubnetDef / Instance. */\nconst TAG_PETRINET = '@petrinet' as `@${string}`;\n/** Block tag for interface-only subnet diagrams. */\nconst TAG_SUBNET = '@subnet' as `@${string}`;\n\n/** Cache: reflection ID → rendered HTML string */\nconst htmlCache = new Map<number, string>();\n\n/**\n * Loads the petri-net plugin into the TypeDoc application.\n *\n * @param app - the TypeDoc Application instance\n */\nexport function load(app: Application): void {\n // 1. Register both tags as known block tags at bootstrap time.\n app.on('bootstrapEnd', () => {\n const blockTags = app.options.getValue('blockTags') as string[];\n const additions: string[] = [];\n if (!blockTags.includes(TAG_PETRINET)) additions.push(TAG_PETRINET);\n if (!blockTags.includes(TAG_SUBNET)) additions.push(TAG_SUBNET);\n if (additions.length > 0) {\n app.options.setValue('blockTags', [...blockTags, ...additions]);\n }\n });\n\n // 2. Resolve references and generate SVG during pre-render async phase.\n app.renderer.preRenderAsyncJobs.push(async (output) => {\n htmlCache.clear();\n await processProject(app, output.project);\n });\n\n // 3. Inject cached HTML into comment output, suppress default tag rendering.\n app.renderer.hooks.on('comment.beforeTags', (_context, comment, reflection) => {\n const cached = htmlCache.get(reflection.id);\n if (!cached) return JSX.createElement(JSX.Raw, { html: '' });\n\n // Mark our tags as skip so TypeDoc doesn't render them as plain text.\n for (const tag of comment.blockTags) {\n if (tag.tag === TAG_PETRINET || tag.tag === TAG_SUBNET) {\n tag.skipRendering = true;\n }\n }\n\n return JSX.createElement(JSX.Raw, { html: cached });\n });\n}\n\n/**\n * Walks all reflections in the project and processes `@petrinet` / `@subnet`\n * tags. Per-reflection HTML accumulates in {@link htmlCache} so multiple tags\n * on one symbol render in declaration order.\n */\nasync function processProject(app: Application, project: ProjectReflection): Promise<void> {\n const reflections = Object.values(project.reflections);\n\n for (const reflection of reflections) {\n const comment = reflection.comment;\n if (!comment) continue;\n\n for (const tag of comment.blockTags) {\n const isPetrinet = tag.tag === TAG_PETRINET;\n const isSubnet = tag.tag === TAG_SUBNET;\n if (!isPetrinet && !isSubnet) continue;\n\n const reference = tagContent(tag);\n try {\n const html = isSubnet\n ? await generateInterfaceOnly(reference, reflection)\n : await generateDiagram(reference, reflection);\n const existing = htmlCache.get(reflection.id) ?? '';\n htmlCache.set(reflection.id, existing + html);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n const tagName = isSubnet ? '@subnet' : '@petrinet';\n app.logger.warn(`${tagName} error for ${reflection.getFriendlyFullName()}: ${msg}`);\n const html = errorHtml(`Error generating diagram for '${reference}': ${msg}`);\n const existing = htmlCache.get(reflection.id) ?? '';\n htmlCache.set(reflection.id, existing + html);\n }\n }\n }\n}\n\n/**\n * Generates a diagram HTML string for a single `@petrinet` reference. Resolves\n * the reference to one of {@link ResolvedNet} variants and dispatches to the\n * matching renderer.\n */\nasync function generateDiagram(\n reference: string,\n reflection: Reflection,\n): Promise<string> {\n const trimmed = reference.trim();\n if (!trimmed) {\n return errorHtml(`Empty @petrinet reference on ${reflection.getFriendlyFullName()}`);\n }\n\n const sourceFile = getSourceFilePath(reflection);\n if (!sourceFile) {\n return errorHtml(`Cannot determine source file for ${reflection.getFriendlyFullName()}`);\n }\n\n const resolved = await resolveNet(trimmed, sourceFile);\n if (!resolved) {\n return errorHtml(`Cannot resolve PetriNet/SubnetDef/Instance: ${trimmed}`);\n }\n\n return await renderResolved(resolved, /* interfaceOnly */ false);\n}\n\n/**\n * Generates an interface-only diagram for a `@subnet` reference. When the\n * resolved reference is not a {@link import('../core/subnet-def.js').SubnetDef},\n * falls back to the regular diagram so the tag still produces useful output.\n */\nasync function generateInterfaceOnly(\n reference: string,\n reflection: Reflection,\n): Promise<string> {\n const trimmed = reference.trim();\n if (!trimmed) {\n return errorHtml(`Empty @subnet reference on ${reflection.getFriendlyFullName()}`);\n }\n\n const sourceFile = getSourceFilePath(reflection);\n if (!sourceFile) {\n return errorHtml(`Cannot determine source file for ${reflection.getFriendlyFullName()}`);\n }\n\n const resolved = await resolveNet(trimmed, sourceFile);\n if (!resolved) {\n return errorHtml(`Cannot resolve SubnetDef: ${trimmed}`);\n }\n\n return await renderResolved(resolved, /* interfaceOnly */ true);\n}\n\n/**\n * Dispatches a {@link ResolvedNet} to the matching renderer. The\n * `interfaceOnly` flag is honoured only when the resolved kind is `subnet` —\n * for `net` and `instance` it is ignored (the body is the whole point of\n * those references).\n */\nasync function renderResolved(\n resolved: ResolvedNet,\n interfaceOnly: boolean,\n): Promise<string> {\n switch (resolved.kind) {\n case 'net': {\n const dotExport = await getDotExport();\n const dot = dotExport(resolved.value);\n return renderDiagramHtml(resolved.title, dot, /* header */ null);\n }\n case 'subnet': {\n const dot = interfaceOnly\n ? subnetInterfaceOnly(resolved.value)\n : subnetFullBody(resolved.value);\n const header = forSubnetDef(resolved.value, interfaceOnly);\n const title = resolved.value.name + (interfaceOnly ? ' (interface)' : '');\n return renderDiagramHtml(title, dot, header);\n }\n case 'instance': {\n const dotExport = await getDotExport();\n const dot = dotExport(resolved.value.renamedBody);\n const header = forInstance(resolved.value);\n return renderDiagramHtml(resolved.title, dot, header);\n }\n }\n}\n\n/**\n * Emits the diagram HTML. The canonical viewer renders DOT to SVG\n * client-side via Graphviz-WASM, so no server-side SVG rendering happens\n * here. Routes through the subnet-aware renderer when `header` is non-null,\n * the plain renderer otherwise.\n */\nfunction renderDiagramHtml(\n title: string,\n dot: string,\n header: string | null,\n): string {\n if (header !== null) {\n return renderSubnetSvg(title, header, dot);\n }\n return renderSvg(title, dot);\n}\n\n/**\n * Extracts text content from a CommentTag.\n */\nfunction tagContent(tag: CommentTag): string {\n return tag.content\n .map((part) => part.text)\n .join('')\n .trim();\n}\n\n/**\n * Gets the source file path from a reflection. Walks parents because\n * comment-bearing reflections sometimes lack their own `sources` (e.g.\n * inherited members).\n */\nfunction getSourceFilePath(reflection: Reflection): string | null {\n const decl = reflection as DeclarationReflection;\n if (decl.sources && decl.sources.length > 0) {\n return decl.sources[0]!.fullFileName;\n }\n if (reflection.parent) {\n return getSourceFilePath(reflection.parent);\n }\n return null;\n}\n\n/**\n * Renders an error message as styled HTML.\n */\nfunction errorHtml(message: string): string {\n return `<div class=\"petrinet-error\" style=\"color: #dc3545; border: 1px solid #dc3545; padding: 10px; border-radius: 4px;\">\n<strong>@petrinet Error:</strong> ${escapeHtml(message)}\n</div>`;\n}\n","/**\n * Dynamic import-based resolver for `@petrinet` / `@subnet` references.\n *\n * Resolves three kinds of static exports per Java's `PetriNetTaglet` design:\n * 1. `PetriNet` — full body diagram (existing behaviour).\n * 2. `SubnetDef<?>` — body diagram with interface ports highlighted, plus a\n * subnet header with port/channel badges.\n * 3. `Instance<?>` — renamed body diagram (already prefix-clustered by the\n * DOT exporter), plus an instance header with prefix, def name, and\n * params summary.\n *\n * TypeScript cannot use reflection like Java — modules must be importable at\n * doc time (typically from `dist/` after `npm run build`).\n *\n * Tag format:\n * ```\n * @petrinet ./path/to/module#exportName — access a static export\n * @petrinet ./path/to/module#functionName() — call a function returning one\n * @petrinet #localExport — resolve from same file\n * ```\n *\n * Mirrors: `org.libpetri.doclet.PetriNetTaglet.resolveReference`\n *\n * @module doclet/net-resolver\n */\n\nimport { resolve, dirname } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { PetriNet } from '../core/petri-net.js';\nimport type { SubnetDef } from '../core/subnet-def.js';\nimport type { Instance } from '../core/instance.js';\n\n/**\n * Discriminated-union result from {@link resolveNet}. Each variant carries\n * the resolved value plus a display title.\n */\nexport type ResolvedNet =\n | { readonly kind: 'net'; readonly value: PetriNet; readonly title: string }\n | { readonly kind: 'subnet'; readonly value: SubnetDef<unknown>; readonly title: string }\n | { readonly kind: 'instance'; readonly value: Instance<unknown>; readonly title: string };\n\n/**\n * Parses a `@petrinet` / `@subnet` reference and resolves it via dynamic\n * import. Returns `null` when the reference cannot be parsed or imported, or\n * when the resolved value is none of the three supported kinds.\n *\n * @param reference - the tag content, e.g. `./definition#buildDebugNet()`\n * @param sourceFilePath - absolute path to the source file containing the tag\n */\nexport async function resolveNet(\n reference: string,\n sourceFilePath: string,\n): Promise<ResolvedNet | null> {\n const trimmed = reference.trim().split(/\\s+/)[0] ?? '';\n if (!trimmed) return null;\n\n const hashIndex = trimmed.indexOf('#');\n if (hashIndex === -1) return null;\n\n const modulePath = trimmed.substring(0, hashIndex);\n const exportRef = trimmed.substring(hashIndex + 1);\n if (!exportRef) return null;\n\n const isCall = exportRef.endsWith('()');\n const exportName = isCall ? exportRef.slice(0, -2) : exportRef;\n\n // Resolve module path relative to the source file.\n let absolutePath: string;\n if (modulePath) {\n absolutePath = resolve(dirname(sourceFilePath), modulePath);\n } else {\n // `#localExport` — resolve from same file's compiled output.\n absolutePath = sourceFilePath;\n }\n\n // Try `.js` extension for compiled output, then `.ts` for ts-node scenarios.\n const candidates = [\n absolutePath,\n absolutePath + '.js',\n absolutePath + '.ts',\n absolutePath.replace(/\\.ts$/, '.js'),\n ];\n\n let mod: Record<string, unknown> | undefined;\n for (const candidate of candidates) {\n try {\n mod = await import(pathToFileURL(candidate).href) as Record<string, unknown>;\n break;\n } catch {\n // Try next candidate.\n }\n }\n\n if (!mod) return null;\n\n const exported = mod[exportName];\n if (exported == null) return null;\n\n let value: unknown;\n if (isCall) {\n if (typeof exported !== 'function') return null;\n const result = (exported as (...args: unknown[]) => unknown)();\n // Support functions that return `{ net: PetriNet, ... }` for legacy\n // callers; otherwise pass the result through directly.\n if (\n result !== null && typeof result === 'object' && 'net' in result &&\n isPetriNetLike((result as { net: unknown }).net)\n ) {\n value = (result as { net: unknown }).net;\n } else {\n value = result;\n }\n } else {\n value = exported;\n }\n\n return classify(value);\n}\n\n/**\n * Wraps the resolved value into a {@link ResolvedNet} variant by structural\n * shape — checks {@link Instance} before {@link SubnetDef} before\n * {@link PetriNet} so the most specific match wins (Instance has both `def`\n * and `renamedBody`; SubnetDef has `iface` and `body`; PetriNet has only\n * `transitions` + `name`).\n *\n * Returns `null` when the value matches none of the supported shapes.\n */\nfunction classify(value: unknown): ResolvedNet | null {\n if (value === null || typeof value !== 'object') return null;\n\n if (isInstanceLike(value)) {\n const inst = value as Instance<unknown>;\n return { kind: 'instance', value: inst, title: `${inst.def.name} :: ${inst.prefix}` };\n }\n if (isSubnetDefLike(value)) {\n const def = value as SubnetDef<unknown>;\n return { kind: 'subnet', value: def, title: def.name };\n }\n if (isPetriNetLike(value)) {\n const net = value as PetriNet;\n return { kind: 'net', value: net, title: net.name };\n }\n return null;\n}\n\n/**\n * Structural test for {@link PetriNet}: has a string `name` and a `transitions`\n * Set. Avoids `instanceof` because the imported module may have re-bound the\n * class identity (TypeDoc's bundled output vs `dist/` import path).\n */\nfunction isPetriNetLike(value: unknown): value is PetriNet {\n if (value === null || typeof value !== 'object') return false;\n const candidate = value as { name?: unknown; transitions?: unknown };\n return typeof candidate.name === 'string' && candidate.transitions instanceof Set;\n}\n\n/**\n * Structural test for {@link SubnetDef}: has a string `name`, a {@link\n * PetriNet}-shaped `body`, and an `iface` carrying `ports` + `channels` maps.\n */\nfunction isSubnetDefLike(value: unknown): value is SubnetDef<unknown> {\n if (value === null || typeof value !== 'object') return false;\n const candidate = value as { name?: unknown; body?: unknown; iface?: unknown };\n if (typeof candidate.name !== 'string') return false;\n if (!isPetriNetLike(candidate.body)) return false;\n const iface = candidate.iface as { ports?: unknown; channels?: unknown } | undefined;\n return iface !== undefined && iface !== null\n && iface.ports instanceof Map && iface.channels instanceof Map;\n}\n\n/**\n * Structural test for {@link Instance}: has a string `prefix`, a {@link\n * SubnetDef}-shaped `def`, and a {@link PetriNet}-shaped `renamedBody`.\n */\nfunction isInstanceLike(value: unknown): value is Instance<unknown> {\n if (value === null || typeof value !== 'object') return false;\n const candidate = value as { prefix?: unknown; def?: unknown; renamedBody?: unknown };\n return typeof candidate.prefix === 'string'\n && isSubnetDefLike(candidate.def)\n && isPetriNetLike(candidate.renamedBody);\n}\n","/**\n * Shared HTML renderer for Petri Net diagrams in TypeDoc.\n *\n * Generates consistent HTML markup that mounts the canonical\n * {@link https://libpetri.org | libpetri} viewer client-side. The viewer IIFE\n * bundle (Graphviz WASM inlined, offline-safe) is inlined into the generated\n * HTML, making the plugin fully self-contained with no external file\n * dependencies.\n *\n * Each diagram container carries its DOT source as a `data-dot` attribute. An\n * init snippet reads the attribute and calls\n * `window.LibpetriViewer.mount(dot, container, { chrome: true })` to render the\n * SVG and wire pan/zoom + cluster legend/filter chrome.\n *\n * Mirrors: `org.libpetri.doclet.DiagramRenderer`\n *\n * @module doclet/diagram-renderer\n */\n\nimport { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nfunction loadResource(filename: string): string {\n return readFileSync(join(__dirname, 'resources', filename), 'utf-8');\n}\n\nlet inlineCss: string | undefined;\nlet inlineJs: string | undefined;\n\nfunction css(): string {\n return (inlineCss ??= loadResource('petrinet-diagrams.css'));\n}\n\nfunction js(): string {\n return (inlineJs ??= loadResource('petrinet-diagrams.js'));\n}\n\n/**\n * Escapes HTML special characters for safe embedding as text content.\n */\nexport function escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\n/**\n * Escapes a string for safe inclusion in an HTML attribute value enclosed in\n * double quotes. Identical to {@link escapeHtml} plus single-quote escaping\n * (defence-in-depth even though we always emit double-quoted attributes).\n */\nfunction escapeAttr(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\n/**\n * Renders a diagram from a DOT source string. The viewer renders the SVG\n * client-side via Graphviz-WASM; no server-side SVG is emitted on the\n * embedded path.\n *\n * Inlines CSS and the viewer IIFE from bundled resources. The IIFE is guarded\n * by an idempotency check (`window._libpetriViewerInit`) so it only executes\n * once per page even when multiple `@petrinet` tags appear.\n *\n * @param title - optional title (null/undefined for no title)\n * @param dotSource - the DOT source code; embedded as `data-dot` and shown in\n * the collapsible \"View DOT Source\" block\n * @returns HTML markup with diagram controls\n */\nexport function renderSvg(\n title: string | null | undefined,\n dotSource: string,\n): string {\n return renderInternal(title ?? null, /* headerHtml */ null, dotSource);\n}\n\n/**\n * Renders a subnet- or instance-aware diagram. Identical to {@link renderSvg}\n * apart from an extra {@code headerHtml} block (the port/channel/params\n * badge bar) prepended above the diagram, and the CSS class\n * {@code subnet-diagram} on the wrapper.\n *\n * @param title diagram title (e.g. \"BoundedBuffer :: b1\")\n * @param headerHtml the HTML produced by {@link import('./subnet-header.js')}\n * @param dotSource the DOT source code\n * @returns HTML markup\n */\nexport function renderSubnetSvg(\n title: string | null | undefined,\n headerHtml: string,\n dotSource: string,\n): string {\n return renderInternal(title ?? null, headerHtml, dotSource);\n}\n\nlet diagramIdCounter = 0;\n\nfunction renderInternal(\n title: string | null,\n headerHtml: string | null,\n dotSource: string,\n): string {\n const titleHtml = title !== null ? `<h4>${escapeHtml(title)}</h4>\\n` : '';\n const summaryText = title !== null ? 'View DOT Source' : 'View Source';\n const diagramClass = headerHtml !== null ? 'petrinet-diagram subnet-diagram' : 'petrinet-diagram';\n const headerBlock = headerHtml !== null ? headerHtml : '';\n const dotAttr = escapeAttr(dotSource);\n const containerId = `libpetri-diagram-${++diagramIdCounter}`;\n\n return `<style>${css()}</style>\n<script>if(!window._libpetriViewerInit){window._libpetriViewerInit=true;\n${js()}\n}</script>\n<div class=\"${diagramClass}\">\n${titleHtml}${headerBlock}<div class=\"diagram-container\" id=\"${containerId}\" data-libpetri-diagram=\"true\" data-dot=\"${dotAttr}\"></div>\n<details>\n<summary>${summaryText}</summary>\n<pre><code>${escapeHtml(dotSource)}</code></pre>\n</details>\n</div>\n<script>(function(){function mount(){var el=document.getElementById(${JSON.stringify(containerId)});if(!el)return;if(el.dataset.libpetriMounted)return;if(!window.LibpetriViewer||typeof window.LibpetriViewer.mount!=='function'){return setTimeout(mount,30);}el.dataset.libpetriMounted='1';try{window.LibpetriViewer.mount(el.dataset.dot,el,{chrome:true});}catch(e){console.error('[libpetri] mount failed',e);}}if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',mount);}else{mount();}})();</script>`;\n}\n","/**\n * HTML-fragment generator for the small \"subnet header\" badge bar that the\n * {@link import('./diagram-renderer.js')} layers above subnet diagrams.\n *\n * For a {@link import('../core/subnet-def.js').SubnetDef} the header lists\n * the subnet name, the parameter type (best-effort — TypeScript erases\n * generics at runtime so the slot is shown as a placeholder), and one badge\n * per port and channel — colour-coded by direction\n * (`interface-port-input` / `-output` / `-inout` CSS classes, plus\n * `interface-channel` for sync channels).\n *\n * For an {@link import('../core/instance.js').Instance} the header lists the\n * instance prefix, the originating definition's name, and the {@link\n * import('../core/instance.js').Instance#params} summary.\n *\n * Mirrors: `org.libpetri.doclet.SubnetHeader`\n *\n * @module doclet/subnet-header\n */\n\nimport type { Instance } from '../core/instance.js';\nimport type { Interface, Port } from '../core/interface.js';\nimport type { SubnetDef } from '../core/subnet-def.js';\nimport { escapeHtml } from './diagram-renderer.js';\n\n/**\n * Builds the header HTML for a {@link SubnetDef} field.\n *\n * @param def the subnet definition\n * @param interfaceOnly when `true`, the header carries the \"(interface only)\"\n * badge so the reader knows the body is intentionally\n * omitted\n */\nexport function forSubnetDef(def: SubnetDef<unknown>, interfaceOnly: boolean): string {\n const sb: string[] = [];\n sb.push(`<div class=\"subnet-header\">\\n`);\n sb.push(` <div class=\"subnet-header-row\">\\n`);\n sb.push(` <span class=\"subnet-header-label\">subnet</span>\\n`);\n sb.push(` <span class=\"subnet-header-name\">${escapeHtml(def.name)}</span>\\n`);\n // TypeScript erases generics at runtime, so the parameter-type slot is\n // populated with a placeholder (\"?\"). Java emits the simple class name —\n // the structural HTML is otherwise byte-equivalent.\n sb.push(` <span class=\"subnet-header-param\">&lt;?&gt;</span>\\n`);\n if (interfaceOnly) {\n sb.push(` <span class=\"subnet-header-badge subnet-header-badge-interface\">interface only</span>\\n`);\n }\n sb.push(` </div>\\n`);\n sb.push(renderPortChannelBadges(def.iface));\n sb.push(`</div>\\n`);\n return sb.join('');\n}\n\n/**\n * Builds the header HTML for an {@link Instance} field.\n */\nexport function forInstance(instance: Instance<unknown>): string {\n const def = instance.def;\n const sb: string[] = [];\n sb.push(`<div class=\"subnet-header\">\\n`);\n sb.push(` <div class=\"subnet-header-row\">\\n`);\n sb.push(` <span class=\"subnet-header-label\">instance</span>\\n`);\n sb.push(` <span class=\"subnet-header-name\">${escapeHtml(instance.prefix)}</span>\\n`);\n sb.push(` <span class=\"subnet-header-of\">of</span>\\n`);\n sb.push(` <span class=\"subnet-header-name\">${escapeHtml(def.name)}</span>\\n`);\n const params = instance.params;\n if (params !== null && params !== undefined) {\n sb.push(` <span class=\"subnet-header-params\">params=${escapeHtml(String(params))}</span>\\n`);\n }\n sb.push(` </div>\\n`);\n sb.push(renderPortChannelBadges(def.iface));\n sb.push(`</div>\\n`);\n return sb.join('');\n}\n\n/**\n * Renders the per-port and per-channel badge row. Each badge carries a CSS\n * class identifying its kind so the stylesheet can colour-code by direction.\n */\nfunction renderPortChannelBadges(iface: Interface): string {\n if (iface.ports.size === 0 && iface.channels.size === 0) {\n return '';\n }\n const sb: string[] = [];\n sb.push(` <div class=\"subnet-header-badges\">\\n`);\n for (const port of iface.ports.values()) {\n const kind = portKind(port);\n sb.push(` <span class=\"interface-port-badge interface-port-badge-${kind}\">`);\n sb.push(`<span class=\"badge-direction\">${kind}</span>`);\n sb.push(`<span class=\"badge-name\">${escapeHtml(port.name)}</span>`);\n // TypeScript erases generics so we can't print the runtime token type;\n // omit the type-name span rather than emit a bogus value.\n sb.push(`</span>\\n`);\n }\n for (const channel of iface.channels.values()) {\n sb.push(` <span class=\"interface-channel-badge\">`);\n sb.push(`<span class=\"badge-direction\">channel</span>`);\n sb.push(`<span class=\"badge-name\">${escapeHtml(channel.name)}</span>`);\n sb.push(`</span>\\n`);\n }\n sb.push(` </div>\\n`);\n return sb.join('');\n}\n\nfunction portKind(port: Port<unknown>): 'input' | 'output' | 'inout' {\n return port.direction;\n}\n","/**\n * DOT generators for the subnet-aware diagrams the {@link\n * import('./petri-net-plugin.js')} plugin draws.\n *\n * Two flavours:\n * - {@link fullBody} — the subnet's complete body, but with its interface-port\n * places restyled with the `interface-port` category from\n * `petri-net-styles.json` so they read as boundary elements at a glance. A\n * small `subgraph cluster_iface_*` with label `\"interface\"` surrounds the\n * port places and channel transitions to advertise the subnet boundary\n * visually.\n * - {@link interfaceOnly} — a tiny diagram of just the port places, the\n * channel transitions, and a single stub node indicating the body is\n * omitted. Used by the `@subnet` block tag.\n *\n * This module stays in the doclet directory (rather than living in\n * `export/`) because it is a doclet-presentation concern — the production\n * export pipeline never adds the `interface` cluster.\n *\n * Mirrors: `org.libpetri.doclet.SubnetDotExport`\n *\n * @module doclet/subnet-dot-export\n */\n\nimport type { SubnetDef } from '../core/subnet-def.js';\nimport type { Interface, Port, Channel } from '../core/interface.js';\nimport { dotExport } from '../export/dot-exporter.js';\nimport { sanitize } from '../export/petri-net-mapper.js';\nimport { nodeStyle, FONT } from '../export/styles.js';\n\n/**\n * Renders the full body of a {@link SubnetDef} with the interface ports\n * restyled. The output is a post-processed version of {@link dotExport}: the\n * port-place node attribute lines are rewritten so the post-processor swaps in\n * the {@code interface-port} category, channel-transition lines swap in\n * {@code sync-channel}, and an extra {@code subgraph cluster_iface_<name>}\n * block is appended that lists the port nodes by id — overriding their\n * cluster membership without re-emitting them (DOT semantics: a node\n * referenced inside a subgraph block by id alone is treated as a member of\n * that cluster).\n */\nexport function fullBody(def: SubnetDef<unknown>): string {\n let dot = dotExport(def.body);\n const portIds = portNodeIds(def.iface);\n const channelIds = channelNodeIds(def.iface);\n\n // Restyle: rewrite the matched node lines so the post-processor swaps in\n // the interface-port and sync-channel categories. The renderer emits each\n // node as one line ending with `];` so a per-id rewrite is sufficient and\n // deterministic.\n for (const portId of portIds) {\n dot = restyleNode(dot, portId, nodeStyle('interface-port'));\n }\n for (const chId of channelIds) {\n dot = restyleNode(dot, chId, nodeStyle('sync-channel'));\n }\n\n // Wrap the port and channel ids in a header cluster so the doclet's viewer\n // can render the boundary distinctly. Done by injecting an extra subgraph\n // block before the closing `}` of the digraph.\n if (portIds.size > 0 || channelIds.size > 0) {\n let iface = '';\n iface += ` subgraph cluster_iface_${sanitize(def.name)} {\\n`;\n iface += ` label=\"interface\";\\n`;\n iface += ` style=\"rounded,dashed\";\\n`;\n iface += ` bgcolor=\"#F0F6FF\";\\n`;\n iface += ` penwidth=2;\\n`;\n for (const id of portIds) {\n iface += ` ${id};\\n`;\n }\n for (const id of channelIds) {\n iface += ` ${id};\\n`;\n }\n iface += ` }\\n`;\n\n const lastBrace = dot.lastIndexOf('}');\n if (lastBrace > 0) {\n dot = dot.substring(0, lastBrace) + iface + dot.substring(lastBrace);\n }\n }\n return dot;\n}\n\n/**\n * Renders an interface-only diagram: just the port places + channel\n * transitions + a single stub node labelled \"(internals omitted)\" so the\n * reader knows the body has not been drawn.\n */\nexport function interfaceOnly(def: SubnetDef<unknown>): string {\n const sb: string[] = [];\n sb.push(`digraph ${sanitize(def.name)} {\\n`);\n sb.push(` rankdir=LR;\\n`);\n sb.push(` nodesep=0.5;\\n`);\n sb.push(` ranksep=0.6;\\n`);\n sb.push(` fontname=\"${FONT.family}\";\\n`);\n sb.push(` node [fontname=\"${FONT.family}\", fontsize=12];\\n`);\n sb.push(` edge [fontname=\"${FONT.family}\", fontsize=10];\\n`);\n sb.push('\\n');\n\n const stubId = 'stub_' + sanitize(def.name);\n\n // Group ports by direction: inputs on the left, outputs on the right,\n // inouts above. This keeps the interface diagram visually structured even\n // when the body internals are absent.\n const inputs: Port<unknown>[] = [];\n const outputs: Port<unknown>[] = [];\n const inouts: Port<unknown>[] = [];\n for (const port of def.iface.ports.values()) {\n switch (port.direction) {\n case 'input': inputs.push(port); break;\n case 'output': outputs.push(port); break;\n case 'inout': inouts.push(port); break;\n }\n }\n\n // Emit port nodes.\n for (const port of inputs) emitPortNode(sb, port, 'input');\n for (const port of outputs) emitPortNode(sb, port, 'output');\n for (const port of inouts) emitPortNode(sb, port, 'inout');\n\n // Emit channel nodes.\n const syncStyle = nodeStyle('sync-channel');\n for (const ch of def.iface.channels.values()) {\n sb.push(` ${channelNodeId(ch)} [`);\n sb.push(`label=\"⇄ ${escapeLabel(ch.name)}\", `);\n sb.push(`shape=${syncStyle.shape}, `);\n sb.push(`style=\"filled\", `);\n sb.push(`fillcolor=\"${syncStyle.fill}\", `);\n sb.push(`color=\"${syncStyle.stroke}\", `);\n sb.push(`penwidth=${trimNumber(syncStyle.penwidth)}`);\n sb.push(`];\\n`);\n }\n\n // Emit stub node.\n sb.push(` ${stubId} [`);\n sb.push(`label=\"${escapeLabel(def.name)}\\\\n(internals omitted)\", `);\n sb.push(`shape=box, style=\"filled,dashed,rounded\", `);\n sb.push(`fillcolor=\"#FFFFFF\", color=\"#666666\", penwidth=1, `);\n sb.push(`fontsize=11`);\n sb.push(`];\\n`);\n sb.push('\\n');\n\n // Connect inputs -> stub -> outputs; inouts and channels link both ways.\n for (const port of inputs) {\n sb.push(` ${portNodeId(port)} -> ${stubId} [color=\"#1d4ed8\", arrowhead=normal];\\n`);\n }\n for (const port of outputs) {\n sb.push(` ${stubId} -> ${portNodeId(port)} [color=\"#1d4ed8\", arrowhead=normal];\\n`);\n }\n for (const port of inouts) {\n sb.push(` ${portNodeId(port)} -> ${stubId} [color=\"#1d4ed8\", arrowhead=normalnormal, dir=both];\\n`);\n }\n for (const ch of def.iface.channels.values()) {\n sb.push(` ${channelNodeId(ch)} -> ${stubId} [color=\"#6d28d9\", arrowhead=normal, style=dashed];\\n`);\n }\n\n sb.push(`}\\n`);\n return sb.join('');\n}\n\n// ============================================================\n// Helpers\n// ============================================================\n\nfunction emitPortNode(sb: string[], port: Port<unknown>, direction: string): void {\n const style = nodeStyle('interface-port');\n // Token type isn't carried at runtime in TypeScript (generics erased), so\n // the xlabel is the direction marker only — Java additionally appends the\n // port's tokenType simple name. The structural content is otherwise\n // identical.\n sb.push(` ${portNodeId(port)} [`);\n sb.push(`label=\"${escapeLabel(port.name)}\", `);\n sb.push(`xlabel=\"${escapeLabel(direction)}\", `);\n sb.push(`shape=${style.shape}, `);\n sb.push(`style=\"filled,${style.style ?? 'solid'}\", `);\n sb.push(`fillcolor=\"${style.fill}\", `);\n sb.push(`color=\"${style.stroke}\", `);\n sb.push(`penwidth=${trimNumber(style.penwidth)}`);\n if (style.width !== undefined) {\n sb.push(`, width=${trimNumber(style.width)}, fixedsize=true`);\n }\n sb.push(`];\\n`);\n}\n\nfunction portNodeId(port: Port<unknown>): string {\n return 'p_' + sanitize(port.place.name);\n}\n\nfunction channelNodeId(ch: Channel): string {\n return 't_' + sanitize(ch.transition.name);\n}\n\nfunction portNodeIds(iface: Interface): Set<string> {\n const ids = new Set<string>();\n for (const port of iface.ports.values()) ids.add(portNodeId(port));\n return ids;\n}\n\nfunction channelNodeIds(iface: Interface): Set<string> {\n const ids = new Set<string>();\n for (const ch of iface.channels.values()) ids.add(channelNodeId(ch));\n return ids;\n}\n\n/**\n * Rewrites the {@code fillcolor=}, {@code color=}, {@code style=}, and\n * {@code penwidth=} attributes of the line declaring the given node id so\n * the supplied style takes precedence. Operates as a plain text rewrite:\n * the {@link import('../export/dot-renderer.js').renderDot} output formats\n * each node line deterministically, so a per-attribute regex is reliable.\n */\nfunction restyleNode(\n dot: string,\n nodeId: string,\n style: ReturnType<typeof nodeStyle>,\n): string {\n // The node line begins with: <id> [\n // and ends with: ];\n // Find the line, then surgically swap fillcolor / color / style / penwidth.\n const marker = nodeId + ' [';\n let start = dot.indexOf('\\n ' + marker);\n if (start < 0) start = dot.indexOf(' ' + marker);\n if (start < 0) return dot;\n // Skip the leading newline if present so we operate on the line proper.\n if (dot.charAt(start) === '\\n') start += 1;\n const lineEnd = dot.indexOf('];', start);\n if (lineEnd < 0) return dot;\n let line = dot.substring(start, lineEnd + 2);\n\n // Order matters: keep `fillcolor` before `color` so the substring search\n // for `color=\"` doesn't accidentally hit `fillcolor=\"`.\n line = replaceAttr(line, 'fillcolor', style.fill);\n line = replaceAttr(line, 'color', style.stroke);\n line = replaceAttr(line, 'penwidth', trimNumber(style.penwidth));\n if (style.style !== undefined) {\n // Compose with `filled` because the renderer already includes that.\n line = replaceAttr(line, 'style', `\"filled,${style.style}\"`);\n }\n\n return dot.substring(0, start) + line + dot.substring(lineEnd + 2);\n}\n\n/**\n * Replaces the value of a {@code key=value} pair within a single DOT\n * attribute list. Quotes the value when the existing form was quoted, leaves\n * the value unquoted when the existing form was unquoted (numeric).\n */\nfunction replaceAttr(line: string, key: string, value: string): string {\n // Match key=\"...\" (quoted) — the key must be preceded by a non-word char\n // (start, comma, or space) so `color=` doesn't match inside `fillcolor=`.\n const quotedPat = key + '=\"';\n const qStart = findAttrStart(line, quotedPat);\n if (qStart >= 0) {\n const valStart = qStart + quotedPat.length;\n const valEnd = line.indexOf('\"', valStart);\n if (valEnd < 0) return line;\n let v = value;\n if (v.startsWith('\"') && v.endsWith('\"') && v.length >= 2) {\n v = v.substring(1, v.length - 1);\n }\n return line.substring(0, valStart) + v + line.substring(valEnd);\n }\n // Match key=NN (numeric, ends at ',' or ']').\n const unquoted = key + '=';\n const uStart = findAttrStart(line, unquoted);\n if (uStart < 0) return line;\n const valStart = uStart + unquoted.length;\n let valEnd = valStart;\n while (valEnd < line.length) {\n const c = line.charAt(valEnd);\n if (c === ',' || c === ']') break;\n valEnd++;\n }\n return line.substring(0, valStart) + value + line.substring(valEnd);\n}\n\n/**\n * Finds the start of a `key=` attribute pattern in `line`, ensuring the\n * match is not a suffix of another attribute name (e.g. `color=` must not\n * match inside `fillcolor=`). Returns -1 when no boundary-respecting match\n * exists.\n */\nfunction findAttrStart(line: string, pattern: string): number {\n let from = 0;\n while (from < line.length) {\n const idx = line.indexOf(pattern, from);\n if (idx < 0) return -1;\n if (idx === 0) return idx;\n const prev = line.charAt(idx - 1);\n // Word-boundary check: previous char must not be alphanumeric/underscore.\n if (!/[A-Za-z0-9_]/.test(prev)) return idx;\n from = idx + 1;\n }\n return -1;\n}\n\nfunction trimNumber(d: number): string {\n if (Number.isInteger(d)) return String(d);\n return String(d);\n}\n\nfunction escapeLabel(s: string): string {\n return s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n","/**\n * SVG renderer using `@viz-js/viz` (Graphviz WASM).\n *\n * Pure WASM — zero external dependencies. No system `dot` binary required.\n *\n * Mirrors: Java's `PetriNetTaglet.dotToSvg()` (which uses `dot -Tsvg` subprocess)\n *\n * @module doclet/svg-renderer\n */\n\n/**\n * Renders a DOT string to SVG using the `@viz-js/viz` WASM engine.\n *\n * Strips the XML prolog/DOCTYPE and explicit width/height attributes so the SVG\n * scales via viewBox + CSS instead of overriding with fixed pt sizes.\n *\n * @param dot - the DOT source string\n * @returns SVG markup string\n * @throws if `@viz-js/viz` is not installed or DOT parsing fails\n */\nexport async function dotToSvg(dot: string): Promise<string> {\n // Dynamic import — @viz-js/viz is an optional peer dependency\n const { instance } = await import('@viz-js/viz');\n const viz = await instance();\n let svg = viz.renderString(dot, { format: 'svg', engine: 'dot' });\n\n // Strip XML prolog and DOCTYPE — invalid inside HTML5\n const svgStart = svg.indexOf('<svg');\n if (svgStart > 0) svg = svg.substring(svgStart);\n\n // Strip explicit width/height attributes (e.g. \"1942pt\") so the SVG\n // scales via viewBox + CSS instead of overriding with fixed pt sizes\n svg = svg.replace(/\\s+(?:width|height)=\"[^\"]*\"/g, '');\n\n return svg;\n}\n"],"mappings":"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","names":["dirname","interfaceOnly","valStart","valEnd","interfaceOnly","dotExport"]}
@@ -0,0 +1,9 @@
1
+ import {
2
+ dotExport
3
+ } from "./chunk-JVI5HFRX.js";
4
+ import "./chunk-E3ZWB645.js";
5
+ import "./chunk-ATT7U5H5.js";
6
+ export {
7
+ dotExport
8
+ };
9
+ //# sourceMappingURL=dot-exporter-SHBYMMJ3.js.map
@@ -1,4 +1,4 @@
1
- import { T as Token } from './petri-net-D73-PO6d.js';
1
+ import { T as Token } from './petri-net-B4wQwsUj.js';
2
2
 
3
3
  /**
4
4
  * Events emitted during Petri Net execution.
@@ -1,4 +1,4 @@
1
- import { P as PetriNet } from '../petri-net-D73-PO6d.js';
1
+ import { P as PetriNet } from '../petri-net-B4wQwsUj.js';
2
2
 
3
3
  /**
4
4
  * Format-agnostic typed graph model.
@@ -8,7 +8,8 @@ import {
8
8
  nodeStyle,
9
9
  renderDot,
10
10
  sanitize
11
- } from "../chunk-ULX3OG6H.js";
11
+ } from "../chunk-JVI5HFRX.js";
12
+ import "../chunk-E3ZWB645.js";
12
13
  import "../chunk-ATT7U5H5.js";
13
14
  export {
14
15
  DEFAULT_DOT_CONFIG,
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { P as PetriNet, S as SubnetDef, a as Place, T as Token, b as Transition, E as EnvironmentPlace, c as TransitionContext, O as Out } from './petri-net-D73-PO6d.js';
2
- export { A as Arc, d as ArcInhibitor, e as ArcInput, f as ArcOutput, g as ArcRead, h as ArcReset, C as Channel, i as ComposeBindings, F as FusionSet, j as FusionSetBuilder, I as In, k as InAll, l as InAtLeast, m as InExactly, n as InOne, o as Instance, p as Interface, q as InterfaceBuilder, L as LogFn, M as MAX_DURATION_MS, r as OutAnd, s as OutForwardInput, t as OutPlace, u as OutTimeout, v as OutXor, w as OutputEntry, x as PetriNetBuilder, y as Port, z as PortDirection, B as SubnetDefBuilder, D as SubnetInstance, G as Timing, H as TimingDeadline, J as TimingDelayed, K as TimingExact, N as TimingImmediate, Q as TimingWindow, R as TokenInput, U as TokenOutput, V as TransitionAction, W as TransitionBuilder, X as VerificationHarness, Y as VerificationResult, Z as all, _ as allPlaces, $ as and, a0 as andPlaces, a1 as arcPlace, a2 as atLeast, a3 as consumptionCount, a4 as deadline, a5 as delayed, a6 as earliest, a7 as enumerateBranches, a8 as environmentPlace, a9 as exact, aa as exactly, ab as fork, ac as forwardInput, ad as hasDeadline, ae as hasGuard, af as immediate, ag as inhibitorArc, ah as inputArc, ai as isUnit, aj as latest, ak as matchesGuard, al as one, am as outPlace, an as outputArc, ao as passthrough, ap as place, aq as produce, ar as readArc, as as requiredCount, at as resetArc, au as timeout, av as timeoutPlace, aw as tokenAt, ax as tokenOf, ay as transform, az as transformAsync, aA as transformFrom, aB as unitToken, aC as window, aD as withTimeout, aE as xor, aF as xorPlaces } from './petri-net-D73-PO6d.js';
3
- import { E as EventStore } from './event-store-8XkpYUeU.js';
4
- export { A as ActionTimedOut, a as ExecutionCompleted, b as ExecutionStarted, I as InMemoryEventStore, L as LogMessage, M as MarkingSnapshot, N as NetEvent, T as TokenAdded, c as TokenRemoved, d as TransitionClockRestarted, e as TransitionCompleted, f as TransitionEnabled, g as TransitionFailed, h as TransitionStarted, i as TransitionTimedOut, j as eventTransitionName, k as eventsOfType, l as failures, m as filterEvents, n as inMemoryEventStore, o as isFailureEvent, p as noopEventStore, t as transitionEvents } from './event-store-8XkpYUeU.js';
1
+ import { P as PetriNet, S as SubnetDef, a as Place, T as Token, b as Transition, E as EnvironmentPlace, c as TransitionContext, O as Out } from './petri-net-B4wQwsUj.js';
2
+ export { A as Arc, d as ArcInhibitor, e as ArcInput, f as ArcOutput, g as ArcRead, h as ArcReset, C as Channel, i as ComposeBindings, F as FusionSet, j as FusionSetBuilder, I as In, k as InAll, l as InAtLeast, m as InExactly, n as InOne, o as Instance, p as Interface, q as InterfaceBuilder, K as KeyFn, L as LogFn, M as MAX_DURATION_MS, r as MatchKey, s as MatchSpec, N as NameId, t as OutAnd, u as OutForwardInput, v as OutPlace, w as OutTimeout, x as OutXor, y as OutputEntry, z as PetriNetBuilder, B as Port, D as PortDirection, G as SubnetDefBuilder, H as SubnetInstance, J as Timing, Q as TimingDeadline, R as TimingDelayed, U as TimingExact, V as TimingImmediate, W as TimingWindow, X as TokenInput, Y as TokenOutput, Z as TransitionAction, _ as TransitionBuilder, $ as VerificationHarness, a0 as VerificationResult, a1 as all, a2 as allPlaces, a3 as and, a4 as andPlaces, a5 as arcPlace, a6 as atLeast, a7 as consumptionCount, a8 as deadline, a9 as delayed, aa as earliest, ab as enumerateBranches, ac as environmentPlace, ad as exact, ae as exactly, af as fork, ag as forwardInput, ah as hasDeadline, ai as hasGuard, aj as immediate, ak as inhibitorArc, al as inputArc, am as isUnit, an as keyForPlace, ao as latest, ap as matchCorrelates, aq as matchKey, ar as matchSpec, as as matchesGuard, at as nameId, au as one, av as outPlace, aw as outputArc, ax as passthrough, ay as place, az as produce, aA as readArc, aB as requiredCount, aC as resetArc, aD as timeout, aE as timeoutPlace, aF as tokenAt, aG as tokenOf, aH as transform, aI as transformAsync, aJ as transformFrom, aK as unitToken, aL as window, aM as withTimeout, aN as xor, aO as xorPlaces } from './petri-net-B4wQwsUj.js';
3
+ import { E as EventStore } from './event-store-CAkN_ayv.js';
4
+ export { A as ActionTimedOut, a as ExecutionCompleted, b as ExecutionStarted, I as InMemoryEventStore, L as LogMessage, M as MarkingSnapshot, N as NetEvent, T as TokenAdded, c as TokenRemoved, d as TransitionClockRestarted, e as TransitionCompleted, f as TransitionEnabled, g as TransitionFailed, h as TransitionStarted, i as TransitionTimedOut, j as eventTransitionName, k as eventsOfType, l as failures, m as filterEvents, n as inMemoryEventStore, o as isFailureEvent, p as noopEventStore, t as transitionEvents } from './event-store-CAkN_ayv.js';
5
5
 
6
6
  /**
7
7
  * Discriminated sum-type abstraction over Petri nets, distinguishing **closed**
@@ -148,6 +148,7 @@ declare class CompiledNet {
148
148
  private readonly _consumptionPlaceIds;
149
149
  private readonly _cardinalityChecks;
150
150
  private readonly _hasGuards;
151
+ private readonly _hasMatch;
151
152
  private constructor();
152
153
  static compile(net: PetriNet): CompiledNet;
153
154
  place(pid: number): Place<any>;
@@ -158,6 +159,7 @@ declare class CompiledNet {
158
159
  consumptionPlaceIds(tid: number): readonly number[];
159
160
  cardinalityCheck(tid: number): CardinalityCheck | null;
160
161
  hasGuards(tid: number): boolean;
162
+ hasMatch(tid: number): boolean;
161
163
  /**
162
164
  * Two-phase bitmap enablement check for a transition:
163
165
  * 1. **Presence check**: verifies all required places (inputs + reads) have tokens
@@ -250,6 +252,8 @@ interface BitmapNetExecutorOptions {
250
252
  declare class BitmapNetExecutor implements PetriNetExecutor {
251
253
  private readonly compiled;
252
254
  private readonly marking;
255
+ /** Monotonic source for ν-name minting (ctx.freshName(), NU-010). */
256
+ private freshNameCounter;
253
257
  private readonly eventStore;
254
258
  private readonly environmentPlaces;
255
259
  private readonly hasEnvironmentPlaces;
@@ -423,6 +427,7 @@ declare class PrecompiledNet {
423
427
  readonly consumptionPlaceIds: readonly (readonly number[])[];
424
428
  readonly cardinalityChecks: readonly (CardinalityCheck | null)[];
425
429
  readonly hasGuards: readonly boolean[];
430
+ readonly hasMatch: readonly boolean[];
426
431
  readonly allImmediate: boolean;
427
432
  readonly allSamePriority: boolean;
428
433
  readonly anyDeadlines: boolean;
@@ -499,6 +504,17 @@ declare class PrecompiledNetExecutor implements PetriNetExecutor {
499
504
  private readonly eventStoreEnabled;
500
505
  /** Per-place token arrays, indexed by pid. */
501
506
  private readonly tokenQueues;
507
+ /** Monotonic source for ν-name minting (ctx.freshName(), NU-010). */
508
+ private freshNameCounter;
509
+ /**
510
+ * Per-transition ν-name minter cache, indexed by tid (built lazily). Each
511
+ * supplier is created once and reused across firings, so installing it on a
512
+ * per-fire context is a field assignment rather than a per-fire closure
513
+ * allocation — keeping the fire path lean for non-ν transitions. Every
514
+ * transition gets one (forks mint but carry no MatchSpec, so gating on
515
+ * `hasMatch` would wrongly starve them).
516
+ */
517
+ private readonly freshNameSuppliers;
502
518
  private readonly markingBitmap;
503
519
  private readonly dirtyBitmap;
504
520
  private readonly dirtyScanBuffer;
@@ -554,6 +570,13 @@ declare class PrecompiledNetExecutor implements PetriNetExecutor {
554
570
  private fireReadyImmediate;
555
571
  private fireReadyGeneral;
556
572
  private fireTransition;
573
+ /**
574
+ * Consumes the name-matched tokens for a ν-net join (NU-020): correlated
575
+ * inputs take tokens whose projected name equals the chosen binding (guard
576
+ * first, then name equality — NU-021); other inputs consume FIFO. Reset arcs
577
+ * are honoured as on the opcode path. Mirrors {@link fireTransitionGuarded}.
578
+ */
579
+ private fireTransitionMatched;
557
580
  private fireTransitionGuarded;
558
581
  private updateBitmapAfterConsumption;
559
582
  private processCompletedTransitions;