@diagrammo/dgmo 0.16.0 → 0.17.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.
Files changed (53) hide show
  1. package/dist/advanced.cjs +133 -280
  2. package/dist/advanced.d.cts +9 -2
  3. package/dist/advanced.d.ts +9 -2
  4. package/dist/advanced.js +133 -280
  5. package/dist/auto.cjs +135 -269
  6. package/dist/auto.js +96 -96
  7. package/dist/auto.mjs +135 -269
  8. package/dist/cli.cjs +125 -125
  9. package/dist/index.cjs +132 -266
  10. package/dist/index.js +132 -266
  11. package/dist/internal.cjs +133 -280
  12. package/dist/internal.d.cts +9 -2
  13. package/dist/internal.d.ts +9 -2
  14. package/dist/internal.js +133 -280
  15. package/docs/language-reference.md +14 -18
  16. package/docs/migration-sequence-color-to-tags.md +1 -1
  17. package/gallery/fixtures/sequence-tags-protocols.dgmo +3 -3
  18. package/gallery/fixtures/sequence-tags.dgmo +3 -3
  19. package/gallery/fixtures/sequence.dgmo +4 -4
  20. package/package.json +7 -3
  21. package/src/auto/index.ts +2 -2
  22. package/src/boxes-and-lines/layout.ts +1 -2
  23. package/src/c4/parser.ts +1 -1
  24. package/src/class/parser.ts +1 -1
  25. package/src/cli.ts +2 -2
  26. package/src/completion.ts +1 -14
  27. package/src/cycle/parser.ts +1 -1
  28. package/src/d3.ts +2 -3
  29. package/src/diagnostics.ts +20 -0
  30. package/src/echarts.ts +2 -2
  31. package/src/editor/dgmo.grammar.d.ts +1 -1
  32. package/src/er/parser.ts +1 -1
  33. package/src/graph/flowchart-renderer.ts +3 -0
  34. package/src/infra/renderer.ts +1 -2
  35. package/src/journey-map/parser.ts +1 -1
  36. package/src/kanban/parser.ts +1 -1
  37. package/src/mindmap/parser.ts +2 -3
  38. package/src/org/parser.ts +1 -1
  39. package/src/pert/analyzer.ts +10 -10
  40. package/src/pert/layout.ts +1 -1
  41. package/src/pert/parser.ts +1 -1
  42. package/src/pyramid/parser.ts +1 -1
  43. package/src/raci/parser.ts +2 -2
  44. package/src/ring/parser.ts +1 -1
  45. package/src/sequence/parser.ts +66 -14
  46. package/src/sequence/participant-inference.ts +18 -181
  47. package/src/sequence/renderer.ts +47 -136
  48. package/src/sitemap/parser.ts +1 -1
  49. package/src/tech-radar/parser.ts +2 -2
  50. package/src/utils/extract-alias.ts +1 -1
  51. package/src/utils/inline-markdown.ts +1 -1
  52. package/src/utils/time-ticks.ts +1 -1
  53. package/src/wireframe/parser.ts +1 -1
package/dist/index.js CHANGED
@@ -416,6 +416,9 @@ function nameMergedMessage(args) {
416
416
  function akaRemovedMessage() {
417
417
  return `'aka' is no longer supported \u2014 use the participant name directly`;
418
418
  }
419
+ function participantTypeRemovedMessage(type) {
420
+ return `'${type}' is no longer supported \u2014 drop 'is a ${type}'; the participant renders as the default rectangle`;
421
+ }
419
422
  function tagShorthandRemovedMessage(args) {
420
423
  return `Bare tag shorthand 'tag ${args.name} ${args.alias}' was removed. Use 'tag ${args.name} as ${args.alias}' instead.`;
421
424
  }
@@ -449,7 +452,15 @@ var init_diagnostics = __esm({
449
452
  * participant declaration. Forgiving normalization makes aliasing
450
453
  * unnecessary; the diagnostic directs users to the new syntax.
451
454
  */
452
- AKA_REMOVED: "E_AKA_REMOVED"
455
+ AKA_REMOVED: "E_AKA_REMOVED",
456
+ /**
457
+ * Error: a removed sequence participant-type keyword was used in
458
+ * an `is a X` declaration. The 0.16.0 trim retained only
459
+ * `actor`/`database`/`cache`/`queue`; `service`/`frontend`/
460
+ * `networking`/`gateway`/`external` no longer carry semantic
461
+ * weight and emit this error so users drop the override.
462
+ */
463
+ PARTICIPANT_TYPE_REMOVED: "E_PARTICIPANT_TYPE_REMOVED"
453
464
  };
454
465
  ALIAS_DIAGNOSTIC_CODES = {
455
466
  /** Alias token used before its declaration (strict-ordering rule). */
@@ -3112,81 +3123,7 @@ var init_participant_inference = __esm({
3112
3123
  // Names that would incorrectly match general patterns in later groups
3113
3124
  { pattern: /^KeyDB$/i, type: "cache" },
3114
3125
  // not database (DB$ suffix)
3115
- { pattern: /Webhook/i, type: "external" },
3116
- // not frontend (Web contains)
3117
- { pattern: /^Upstream$/i, type: "external" },
3118
- // not queue (Stream$ suffix)
3119
- { pattern: /^Downstream$/i, type: "external" },
3120
- // not queue (Stream$ suffix)
3121
- // ── 1. Infrastructure overrides ─────────────────────────
3122
- // These names end in -er/-or but are NOT actors
3123
- { pattern: /^.*Router$/i, type: "networking" },
3124
- { pattern: /^.*Scheduler$/i, type: "service" },
3125
- { pattern: /^.*Dispatcher$/i, type: "service" },
3126
- { pattern: /^.*Balancer$/i, type: "networking" },
3127
- { pattern: /^.*Controller$/i, type: "service" },
3128
- { pattern: /^.*Handler$/i, type: "service" },
3129
- { pattern: /^.*Processor$/i, type: "service" },
3130
- { pattern: /^.*Connector$/i, type: "service" },
3131
- { pattern: /^.*Adapter$/i, type: "service" },
3132
- { pattern: /^.*Provider$/i, type: "service" },
3133
- { pattern: /^.*Manager$/i, type: "service" },
3134
- { pattern: /^.*Orchestrator$/i, type: "service" },
3135
- { pattern: /^.*Monitor$/i, type: "service" },
3136
- { pattern: /^.*Resolver$/i, type: "service" },
3137
- { pattern: /^.*Logger$/i, type: "service" },
3138
- { pattern: /^.*Server$/i, type: "service" },
3139
- { pattern: /^.*Broker$/i, type: "queue" },
3140
- { pattern: /^.*Worker$/i, type: "service" },
3141
- { pattern: /^.*Consumer$/i, type: "service" },
3142
- { pattern: /^.*Producer$/i, type: "service" },
3143
- { pattern: /^.*Publisher$/i, type: "service" },
3144
- { pattern: /^.*Subscriber$/i, type: "service" },
3145
- { pattern: /^.*Listener$/i, type: "service" },
3146
- // New -er/-or suffixes that are services, not actors
3147
- { pattern: /^.*Watcher$/i, type: "service" },
3148
- { pattern: /^.*Executor$/i, type: "service" },
3149
- { pattern: /^.*Aggregator$/i, type: "service" },
3150
- { pattern: /^.*Collector$/i, type: "service" },
3151
- { pattern: /^.*Transformer$/i, type: "service" },
3152
- { pattern: /^.*Validator$/i, type: "service" },
3153
- { pattern: /^.*Generator$/i, type: "service" },
3154
- { pattern: /^.*Indexer$/i, type: "service" },
3155
- { pattern: /^.*Crawler$/i, type: "service" },
3156
- { pattern: /^.*Scanner$/i, type: "service" },
3157
- { pattern: /^.*Parser$/i, type: "service" },
3158
- { pattern: /^.*Emitter$/i, type: "service" },
3159
- { pattern: /^.*Exporter$/i, type: "service" },
3160
- { pattern: /^.*Importer$/i, type: "service" },
3161
- { pattern: /^.*Loader$/i, type: "service" },
3162
- { pattern: /^.*Renderer$/i, type: "service" },
3163
- { pattern: /^.*Checker$/i, type: "service" },
3164
- { pattern: /^.*Inspector$/i, type: "service" },
3165
- { pattern: /^.*Encoder$/i, type: "service" },
3166
- { pattern: /^.*Decoder$/i, type: "service" },
3167
- { pattern: /^.*Notifier$/i, type: "service" },
3168
- // ── 2. Networking patterns ──────────────────────────────
3169
- { pattern: /Gateway/i, type: "networking" },
3170
- { pattern: /GW$/i, type: "networking" },
3171
- { pattern: /Proxy/i, type: "networking" },
3172
- { pattern: /LB$/i, type: "networking" },
3173
- { pattern: /LoadBalancer/i, type: "networking" },
3174
- { pattern: /CDN/i, type: "networking" },
3175
- { pattern: /Firewall/i, type: "networking" },
3176
- { pattern: /WAF$/i, type: "networking" },
3177
- { pattern: /DNS/i, type: "networking" },
3178
- { pattern: /Ingress/i, type: "networking" },
3179
- // Named products & patterns
3180
- { pattern: /Nginx/i, type: "networking" },
3181
- { pattern: /Traefik/i, type: "networking" },
3182
- { pattern: /Envoy/i, type: "networking" },
3183
- { pattern: /Istio/i, type: "networking" },
3184
- { pattern: /Kong/i, type: "networking" },
3185
- { pattern: /Akamai/i, type: "networking" },
3186
- { pattern: /Cloudflare/i, type: "networking" },
3187
- { pattern: /Mesh$/i, type: "networking" },
3188
- { pattern: /ServiceMesh/i, type: "networking" },
3189
- // ── 3. Database patterns ────────────────────────────────
3126
+ // ── 1. Database patterns ────────────────────────────────
3190
3127
  { pattern: /DB$/i, type: "database" },
3191
3128
  { pattern: /Database/i, type: "database" },
3192
3129
  { pattern: /Datastore/i, type: "database" },
@@ -3220,16 +3157,15 @@ var init_participant_inference = __esm({
3220
3157
  { pattern: /Milvus/i, type: "database" },
3221
3158
  { pattern: /Presto/i, type: "database" },
3222
3159
  { pattern: /Table$/i, type: "database" },
3223
- // ── 4. Cache patterns ──────────────────────────────────
3160
+ // ── 2. Cache patterns ──────────────────────────────────
3224
3161
  { pattern: /Cache/i, type: "cache" },
3225
3162
  { pattern: /Redis/i, type: "cache" },
3226
3163
  { pattern: /Memcache/i, type: "cache" },
3227
- // CDN already matched by networking above
3228
3164
  // Named products
3229
3165
  { pattern: /Dragonfly/i, type: "cache" },
3230
3166
  { pattern: /Hazelcast/i, type: "cache" },
3231
3167
  { pattern: /Valkey/i, type: "cache" },
3232
- // ── 5. Queue/Messaging patterns ─────────────────────────
3168
+ // ── 3. Queue/Messaging patterns ─────────────────────────
3233
3169
  { pattern: /Queue/i, type: "queue" },
3234
3170
  { pattern: /MQ$/i, type: "queue" },
3235
3171
  { pattern: /SQS/i, type: "queue" },
@@ -3242,6 +3178,7 @@ var init_participant_inference = __esm({
3242
3178
  { pattern: /Stream$/i, type: "queue" },
3243
3179
  { pattern: /SNS/i, type: "queue" },
3244
3180
  { pattern: /PubSub/i, type: "queue" },
3181
+ { pattern: /Broker$/i, type: "queue" },
3245
3182
  // Named products & patterns
3246
3183
  { pattern: /NATS/i, type: "queue" },
3247
3184
  { pattern: /Pulsar/i, type: "queue" },
@@ -3252,7 +3189,7 @@ var init_participant_inference = __esm({
3252
3189
  { pattern: /Sidekiq/i, type: "queue" },
3253
3190
  { pattern: /EventHub/i, type: "queue" },
3254
3191
  { pattern: /Channel$/i, type: "queue" },
3255
- // ── 6. Actor patterns ──────────────────────────────────
3192
+ // ── 4. Actor patterns ──────────────────────────────────
3256
3193
  // Exact matches first
3257
3194
  { pattern: /^Admin$/i, type: "actor" },
3258
3195
  { pattern: /^User$/i, type: "actor" },
@@ -3271,98 +3208,11 @@ var init_participant_inference = __esm({
3271
3208
  { pattern: /^Fan$/i, type: "actor" },
3272
3209
  { pattern: /^Purchaser$/i, type: "actor" },
3273
3210
  { pattern: /^Reviewer$/i, type: "actor" },
3274
- // Suffix rules (after infrastructure overrides filtered above)
3211
+ // Suffix rules
3275
3212
  { pattern: /User$/i, type: "actor" },
3276
3213
  { pattern: /Actor$/i, type: "actor" },
3277
3214
  { pattern: /Analyst$/i, type: "actor" },
3278
- { pattern: /Staff$/i, type: "actor" },
3279
- // ── 7. Frontend patterns ────────────────────────────────
3280
- { pattern: /App$/i, type: "frontend" },
3281
- { pattern: /Application/i, type: "frontend" },
3282
- { pattern: /Mobile/i, type: "frontend" },
3283
- { pattern: /iOS/i, type: "frontend" },
3284
- { pattern: /Android/i, type: "frontend" },
3285
- { pattern: /Web/i, type: "frontend" },
3286
- { pattern: /Browser/i, type: "frontend" },
3287
- { pattern: /Frontend/i, type: "frontend" },
3288
- { pattern: /UI$/i, type: "frontend" },
3289
- { pattern: /Dashboard/i, type: "frontend" },
3290
- { pattern: /CLI$/i, type: "frontend" },
3291
- { pattern: /Terminal/i, type: "frontend" },
3292
- // Frameworks & patterns
3293
- { pattern: /React/i, type: "frontend" },
3294
- { pattern: /^Vue$/i, type: "frontend" },
3295
- { pattern: /Angular/i, type: "frontend" },
3296
- { pattern: /Svelte/i, type: "frontend" },
3297
- { pattern: /NextJS/i, type: "frontend" },
3298
- { pattern: /Nuxt/i, type: "frontend" },
3299
- { pattern: /Remix/i, type: "frontend" },
3300
- { pattern: /Electron/i, type: "frontend" },
3301
- { pattern: /Tauri/i, type: "frontend" },
3302
- { pattern: /Widget$/i, type: "frontend" },
3303
- { pattern: /Portal/i, type: "frontend" },
3304
- { pattern: /Console$/i, type: "frontend" },
3305
- { pattern: /^SPA$/i, type: "frontend" },
3306
- { pattern: /^PWA$/i, type: "frontend" },
3307
- // ── 8. Service patterns ─────────────────────────────────
3308
- { pattern: /Service/i, type: "service" },
3309
- { pattern: /Svc$/i, type: "service" },
3310
- { pattern: /API$/i, type: "service" },
3311
- { pattern: /Lambda/i, type: "service" },
3312
- { pattern: /Function$/i, type: "service" },
3313
- { pattern: /Fn$/i, type: "service" },
3314
- { pattern: /Job$/i, type: "service" },
3315
- { pattern: /Cron/i, type: "service" },
3316
- { pattern: /Microservice/i, type: "service" },
3317
- // Auth
3318
- { pattern: /^Auth$/i, type: "service" },
3319
- { pattern: /^AuthN$/i, type: "service" },
3320
- { pattern: /^AuthZ$/i, type: "service" },
3321
- { pattern: /^SSO$/i, type: "service" },
3322
- { pattern: /OAuth/i, type: "service" },
3323
- { pattern: /^OIDC$/i, type: "service" },
3324
- // SaaS
3325
- { pattern: /Stripe/i, type: "service" },
3326
- { pattern: /Twilio/i, type: "service" },
3327
- { pattern: /SendGrid/i, type: "service" },
3328
- { pattern: /Mailgun/i, type: "service" },
3329
- // Cloud/infra
3330
- { pattern: /^S3$/i, type: "service" },
3331
- { pattern: /^Blob$/i, type: "service" },
3332
- { pattern: /Vercel/i, type: "service" },
3333
- { pattern: /Netlify/i, type: "service" },
3334
- { pattern: /Heroku/i, type: "service" },
3335
- { pattern: /Docker/i, type: "service" },
3336
- { pattern: /Kubernetes/i, type: "service" },
3337
- { pattern: /K8s/i, type: "service" },
3338
- { pattern: /Terraform/i, type: "service" },
3339
- // Security
3340
- { pattern: /Vault/i, type: "service" },
3341
- { pattern: /^HSM$/i, type: "service" },
3342
- { pattern: /KMS/i, type: "service" },
3343
- { pattern: /^IAM$/i, type: "service" },
3344
- // AI/ML
3345
- { pattern: /^LLM$/i, type: "service" },
3346
- { pattern: /GPT/i, type: "service" },
3347
- { pattern: /^Claude$/i, type: "service" },
3348
- { pattern: /Embedding/i, type: "service" },
3349
- { pattern: /Inference/i, type: "service" },
3350
- // Suffixes & patterns
3351
- { pattern: /Pipeline$/i, type: "service" },
3352
- { pattern: /Registry/i, type: "service" },
3353
- { pattern: /Engine$/i, type: "service" },
3354
- { pattern: /Daemon/i, type: "service" },
3355
- // ── 9. External patterns ────────────────────────────────
3356
- { pattern: /External/i, type: "external" },
3357
- { pattern: /Ext$/i, type: "external" },
3358
- { pattern: /ThirdParty/i, type: "external" },
3359
- { pattern: /3P$/i, type: "external" },
3360
- { pattern: /Vendor/i, type: "external" },
3361
- // Named products & patterns
3362
- { pattern: /Callback/i, type: "external" },
3363
- { pattern: /^AWS$/i, type: "external" },
3364
- { pattern: /^GCP$/i, type: "external" },
3365
- { pattern: /Azure/i, type: "external" }
3215
+ { pattern: /Staff$/i, type: "actor" }
3366
3216
  ];
3367
3217
  RULE_COUNT = PARTICIPANT_RULES.length;
3368
3218
  }
@@ -3655,7 +3505,7 @@ function parseSequenceDgmo(content) {
3655
3505
  const pushWarning = (line12, message) => {
3656
3506
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
3657
3507
  };
3658
- if (!content || !content.trim()) {
3508
+ if (!content?.trim()) {
3659
3509
  return fail(0, "Empty content");
3660
3510
  }
3661
3511
  const lines = content.split("\n");
@@ -3666,7 +3516,7 @@ function parseSequenceDgmo(content) {
3666
3516
  const fl = lines[fi].trim();
3667
3517
  if (!fl || fl.startsWith("//")) continue;
3668
3518
  const parsed = parseFirstLine(fl);
3669
- if (parsed && parsed.chartType === "sequence") {
3519
+ if (parsed?.chartType === "sequence") {
3670
3520
  hasExplicitChart = true;
3671
3521
  firstLineIndex = fi;
3672
3522
  if (parsed.title) {
@@ -3981,6 +3831,17 @@ function parseSequenceDgmo(content) {
3981
3831
  const id = isAMatch[1];
3982
3832
  const typeStr = isAMatch[2].toLowerCase();
3983
3833
  let remainder = isAMatch[3]?.trim() || "";
3834
+ if (REMOVED_PARTICIPANT_TYPES.has(typeStr)) {
3835
+ result.diagnostics.push(
3836
+ makeDgmoError(
3837
+ lineNumber,
3838
+ participantTypeRemovedMessage(typeStr),
3839
+ "error",
3840
+ NAME_DIAGNOSTIC_CODES.PARTICIPANT_TYPE_REMOVED
3841
+ )
3842
+ );
3843
+ continue;
3844
+ }
3984
3845
  const participantType = VALID_PARTICIPANT_TYPES.has(
3985
3846
  typeStr
3986
3847
  ) ? typeStr : "default";
@@ -4281,6 +4142,25 @@ function parseSequenceDgmo(content) {
4281
4142
  }
4282
4143
  continue;
4283
4144
  }
4145
+ const elifMatch = trimmed.match(/^elif\b\s*(.*)$/i);
4146
+ if (elifMatch) {
4147
+ const tailRaw = elifMatch[1].trim();
4148
+ const tail = tailRaw ? " " + tailRaw : "";
4149
+ pushError(
4150
+ lineNumber,
4151
+ `'elif' is not a keyword. Did you mean 'else if${tail}'?`
4152
+ );
4153
+ continue;
4154
+ }
4155
+ const elseLabelMatch = trimmed.match(/^else\s+(.+)$/i);
4156
+ if (elseLabelMatch) {
4157
+ const tail = elseLabelMatch[1].trim();
4158
+ pushError(
4159
+ lineNumber,
4160
+ `'else' does not take a label. Did you mean 'else if ${tail}'?`
4161
+ );
4162
+ continue;
4163
+ }
4284
4164
  {
4285
4165
  const noteParsed = parseNoteLine(
4286
4166
  trimmed,
@@ -4404,7 +4284,7 @@ function looksLikeSequence(content) {
4404
4284
  return ARROW_PATTERN.test(trimmed);
4405
4285
  });
4406
4286
  }
4407
- var KNOWN_SEQ_OPTIONS, KNOWN_SEQ_BOOLEANS, VALID_PARTICIPANT_TYPES, IS_A_PATTERN, POSITION_ONLY_PATTERN, COLORED_PARTICIPANT_PATTERN, GROUP_HEADING_PATTERN, GROUP_HEADING_FALLBACK, LEGACY_GROUP_PATTERN, SECTION_PATTERN, ARROW_PATTERN, NOTE_BARE, NOTE_MULTI;
4287
+ var KNOWN_SEQ_OPTIONS, KNOWN_SEQ_BOOLEANS, VALID_PARTICIPANT_TYPES, REMOVED_PARTICIPANT_TYPES, IS_A_PATTERN, POSITION_ONLY_PATTERN, COLORED_PARTICIPANT_PATTERN, GROUP_HEADING_PATTERN, GROUP_HEADING_FALLBACK, LEGACY_GROUP_PATTERN, SECTION_PATTERN, ARROW_PATTERN, NOTE_BARE, NOTE_MULTI;
4408
4288
  var init_parser = __esm({
4409
4289
  "src/sequence/parser.ts"() {
4410
4290
  "use strict";
@@ -4417,15 +4297,17 @@ var init_parser = __esm({
4417
4297
  KNOWN_SEQ_OPTIONS = /* @__PURE__ */ new Set(["active-tag"]);
4418
4298
  KNOWN_SEQ_BOOLEANS = /* @__PURE__ */ new Set(["activations", "solid-fill", "no-title"]);
4419
4299
  VALID_PARTICIPANT_TYPES = /* @__PURE__ */ new Set([
4420
- "service",
4421
4300
  "database",
4422
4301
  "actor",
4423
4302
  "queue",
4424
- "cache",
4425
- "gateway",
4426
- "external",
4303
+ "cache"
4304
+ ]);
4305
+ REMOVED_PARTICIPANT_TYPES = /* @__PURE__ */ new Set([
4306
+ "service",
4307
+ "frontend",
4427
4308
  "networking",
4428
- "frontend"
4309
+ "gateway",
4310
+ "external"
4429
4311
  ]);
4430
4312
  IS_A_PATTERN = /^([^:]+?)\s+is\s+an?\s+(\w+)(?:\s+(.+))?$/i;
4431
4313
  POSITION_ONLY_PATTERN = /^([^:]+?)\s+position\s+(-?\d+)$/i;
@@ -5319,7 +5201,7 @@ function parseClassDiagram(content, palette) {
5319
5201
  if (trimmed.startsWith("//")) continue;
5320
5202
  if (!contentStarted && indent === 0 && i === 0) {
5321
5203
  const firstLine = parseFirstLine(trimmed);
5322
- if (firstLine && firstLine.chartType === "class") {
5204
+ if (firstLine?.chartType === "class") {
5323
5205
  if (firstLine.title) {
5324
5206
  result.title = firstLine.title;
5325
5207
  result.titleLineNumber = lineNumber;
@@ -5720,7 +5602,7 @@ function parseERDiagram(content, palette) {
5720
5602
  if (trimmed.startsWith("//")) continue;
5721
5603
  if (!firstLineParsed && indent === 0) {
5722
5604
  const firstLineResult = parseFirstLine(trimmed);
5723
- if (firstLineResult && firstLineResult.chartType === "er") {
5605
+ if (firstLineResult?.chartType === "er") {
5724
5606
  firstLineParsed = true;
5725
5607
  if (firstLineResult.title) {
5726
5608
  result.title = firstLineResult.title;
@@ -6674,7 +6556,7 @@ function parseExtendedChart(content, palette) {
6674
6556
  ""
6675
6557
  ) : trimmed;
6676
6558
  const dataRow2 = parseDataRowValues(strippedLine);
6677
- if (dataRow2 && dataRow2.values.length === 1) {
6559
+ if (dataRow2?.values.length === 1) {
6678
6560
  const source = sankeyStack.at(-1).name;
6679
6561
  const linkColor = valColorMatch?.[2] ? resolveColorWithDiagnostic(
6680
6562
  valColorMatch[2].trim(),
@@ -6906,7 +6788,7 @@ function parseExtendedChart(content, palette) {
6906
6788
  }
6907
6789
  }
6908
6790
  const dataRow = parseDataRowValues(trimmed);
6909
- if (dataRow && dataRow.values.length === 1) {
6791
+ if (dataRow?.values.length === 1) {
6910
6792
  const { label: rawLabel, color: pointColor } = extractColor(
6911
6793
  dataRow.label,
6912
6794
  palette
@@ -8950,7 +8832,7 @@ function parseOrg(content, palette) {
8950
8832
  const pushWarning = (line12, message) => {
8951
8833
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
8952
8834
  };
8953
- if (!content || !content.trim()) {
8835
+ if (!content?.trim()) {
8954
8836
  return fail(0, "No content provided");
8955
8837
  }
8956
8838
  const lines = content.split("\n");
@@ -9247,7 +9129,7 @@ function parseKanban(content, palette) {
9247
9129
  const warn = (line12, message) => {
9248
9130
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
9249
9131
  };
9250
- if (!content || !content.trim()) {
9132
+ if (!content?.trim()) {
9251
9133
  return fail(0, "No content provided");
9252
9134
  }
9253
9135
  const lines = content.split("\n");
@@ -9636,7 +9518,7 @@ function parseC4(content, palette) {
9636
9518
  result.error = formatDgmoError(diag);
9637
9519
  return result;
9638
9520
  };
9639
- if (!content || !content.trim()) {
9521
+ if (!content?.trim()) {
9640
9522
  return fail(0, "No content provided");
9641
9523
  }
9642
9524
  const lines = content.split("\n");
@@ -10387,7 +10269,7 @@ function parseSitemap(content, palette) {
10387
10269
  const pushWarning = (line12, message) => {
10388
10270
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
10389
10271
  };
10390
- if (!content || !content.trim()) {
10272
+ if (!content?.trim()) {
10391
10273
  return fail(0, "No content provided");
10392
10274
  }
10393
10275
  const lines = content.split("\n");
@@ -13071,7 +12953,7 @@ function parsePert(content, parseOpts = {}) {
13071
12953
  const head = trimmed.slice(0, firstSpace).toLowerCase();
13072
12954
  const value = trimmed.slice(firstSpace + 1).trim();
13073
12955
  const hint = NEAR_DIRECTIVE_HINTS.find((h) => h.stem === head);
13074
- if (hint && hint.matches.test(value)) {
12956
+ if (hint?.matches.test(value)) {
13075
12957
  error(
13076
12958
  lineNumber,
13077
12959
  `Unknown directive '${head}'. Did you mean '${hint.canonical}'?`,
@@ -14378,7 +14260,7 @@ function parseMindmap(content, palette) {
14378
14260
  const pushWarning = (line12, message) => {
14379
14261
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
14380
14262
  };
14381
- if (!content || !content.trim()) {
14263
+ if (!content?.trim()) {
14382
14264
  return fail(0, "No content provided");
14383
14265
  }
14384
14266
  const lines = content.split("\n");
@@ -14549,7 +14431,7 @@ function parseMindmap(content, palette) {
14549
14431
  const diag = makeDgmoError(1, "No nodes found in mindmap");
14550
14432
  result.diagnostics.push(diag);
14551
14433
  result.error = formatDgmoError(diag);
14552
- } else if (titleRoot && titleRoot.children.length === 0 && result.roots.length === 1 && !result.error) {
14434
+ } else if (titleRoot?.children.length === 0 && result.roots.length === 1 && !result.error) {
14553
14435
  }
14554
14436
  return result;
14555
14437
  }
@@ -15008,7 +14890,7 @@ function parseWireframe(content) {
15008
14890
  const indent = measureIndent(line12);
15009
14891
  if (phase === "header") {
15010
14892
  const firstLineResult = parseFirstLine(trimmed);
15011
- if (firstLineResult && firstLineResult.chartType === "wireframe") {
14893
+ if (firstLineResult?.chartType === "wireframe") {
15012
14894
  title = firstLineResult.title || null;
15013
14895
  titleLineNumber = lineNumber;
15014
14896
  continue;
@@ -15303,7 +15185,7 @@ function parseTechRadar(content) {
15303
15185
  const warn = (line12, message) => {
15304
15186
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
15305
15187
  };
15306
- if (!content || !content.trim()) {
15188
+ if (!content?.trim()) {
15307
15189
  return fail(0, "No content provided");
15308
15190
  }
15309
15191
  function isRingName(name) {
@@ -15340,7 +15222,7 @@ function parseTechRadar(content) {
15340
15222
  if (trimmed.startsWith("//")) continue;
15341
15223
  if (!headerParsed) {
15342
15224
  const firstLine = parseFirstLine(trimmed);
15343
- if (firstLine && firstLine.chartType === "tech-radar") {
15225
+ if (firstLine?.chartType === "tech-radar") {
15344
15226
  result.title = firstLine.title ?? "";
15345
15227
  result.titleLineNumber = lineNumber;
15346
15228
  headerParsed = true;
@@ -15632,7 +15514,7 @@ function parseCycle(content) {
15632
15514
  const indent = measureIndent(raw);
15633
15515
  if (!headerParsed) {
15634
15516
  const firstLineResult = parseFirstLine(trimmed);
15635
- if (firstLineResult && firstLineResult.chartType === "cycle") {
15517
+ if (firstLineResult?.chartType === "cycle") {
15636
15518
  result.title = firstLineResult.title ?? "";
15637
15519
  result.titleLineNumber = lineNum;
15638
15520
  headerParsed = true;
@@ -15856,7 +15738,7 @@ function parseJourneyMap(content, palette) {
15856
15738
  const warn = (line12, message) => {
15857
15739
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
15858
15740
  };
15859
- if (!content || !content.trim()) {
15741
+ if (!content?.trim()) {
15860
15742
  return fail(0, "No content provided");
15861
15743
  }
15862
15744
  const lines = content.split("\n");
@@ -16276,7 +16158,7 @@ function parsePyramid(content) {
16276
16158
  const indent = measureIndent(raw);
16277
16159
  if (!headerParsed) {
16278
16160
  const firstLineResult = parseFirstLine(trimmed);
16279
- if (firstLineResult && firstLineResult.chartType === "pyramid") {
16161
+ if (firstLineResult?.chartType === "pyramid") {
16280
16162
  result.title = firstLineResult.title ?? "";
16281
16163
  result.titleLineNumber = lineNum;
16282
16164
  headerParsed = true;
@@ -16410,7 +16292,7 @@ function parseRing(content) {
16410
16292
  const indent = measureIndent(raw);
16411
16293
  if (!headerParsed) {
16412
16294
  const firstLineResult = parseFirstLine(trimmed);
16413
- if (firstLineResult && firstLineResult.chartType === "ring") {
16295
+ if (firstLineResult?.chartType === "ring") {
16414
16296
  result.title = firstLineResult.title ?? "";
16415
16297
  result.titleLineNumber = lineNum;
16416
16298
  headerParsed = true;
@@ -16857,7 +16739,7 @@ function parseRaci(content, palette) {
16857
16739
  const errorAt = (line12, message, code) => {
16858
16740
  result.diagnostics.push(makeDgmoError(line12, message, "error", code));
16859
16741
  };
16860
- if (!content || !content.trim()) {
16742
+ if (!content?.trim()) {
16861
16743
  return fail(0, "No content provided");
16862
16744
  }
16863
16745
  const lines = content.split("\n");
@@ -17178,7 +17060,7 @@ function parseRaci(content, palette) {
17178
17060
  if (roleId === null) continue;
17179
17061
  if (rolesExplicit) {
17180
17062
  const entry = roleStore.get(roleId);
17181
- if (entry && entry.declaredLine === lineNumber) {
17063
+ if (entry?.declaredLine === lineNumber) {
17182
17064
  const candidates = result.roleDisplayNames.filter(
17183
17065
  (n) => n !== entry.displayName
17184
17066
  );
@@ -23460,8 +23342,7 @@ async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
23460
23342
  const edge = parsed.edges[i];
23461
23343
  if (edgeParallelCounts[i] === 0) continue;
23462
23344
  const elkEdge = edgeById.get(`e${i}`);
23463
- if (!elkEdge || !elkEdge.sections || elkEdge.sections.length === 0)
23464
- continue;
23345
+ if (!elkEdge?.sections || elkEdge.sections.length === 0) continue;
23465
23346
  const container = elkEdge.container ?? "root";
23466
23347
  const off = containerAbs.get(container) ?? { x: 0, y: 0 };
23467
23348
  const s = elkEdge.sections[0];
@@ -28388,6 +28269,8 @@ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, sol
28388
28269
  case "document":
28389
28270
  renderDocument(g, node, palette, isDark, colorOff, solid);
28390
28271
  break;
28272
+ default:
28273
+ break;
28391
28274
  }
28392
28275
  }
28393
28276
  function renderFlowchart(container, graph, layout, palette, isDark, onClickItem, exportDims) {
@@ -30958,7 +30841,7 @@ function renderNodes(svg, nodes, palette, isDark, animate, expandedNodeIds, acti
30958
30841
  const badgeText = `${node.computedInstances}x`;
30959
30842
  g.append("text").attr("x", x + node.width - 6).attr("y", y + NODE_HEADER_HEIGHT2 / 2 + META_FONT_SIZE4 * 0.35).attr("text-anchor", "end").attr("font-family", FONT_FAMILY).attr("font-size", META_FONT_SIZE4).attr("fill", textFill).attr("data-instance-node", node.id).style("cursor", "pointer").text(badgeText);
30960
30843
  }
30961
- const showDots = activeGroup != null && activeGroup.toLowerCase() === "capabilities";
30844
+ const showDots = activeGroup?.toLowerCase() === "capabilities";
30962
30845
  const roles = showDots && !node.isEdge ? inferRoles(node.properties) : [];
30963
30846
  if (roles.length > 0) {
30964
30847
  const dotY = isCollapsedGroup ? y + node.height - COLLAPSE_BAR_HEIGHT6 - NODE_PAD_BOTTOM2 / 2 : y + node.height - NODE_PAD_BOTTOM2 / 2;
@@ -31755,7 +31638,7 @@ function analyzePert(parsed) {
31755
31638
  for (const e of edges) {
31756
31639
  if (!e.lag || e.lag.amount >= 0) continue;
31757
31640
  const src = activities.find((a) => a.id === e.source);
31758
- if (!src || !src.duration) continue;
31641
+ if (!src?.duration) continue;
31759
31642
  const leadDays = -toDays(e.lag, sprintDays);
31760
31643
  const srcDurDays = toDays(src.duration.m, sprintDays);
31761
31644
  if (e.type === "FS" && leadDays > srcDurDays) {
@@ -32261,7 +32144,7 @@ function buildSummary(input) {
32261
32144
  const anchor = input.anchor ?? null;
32262
32145
  if (parsedActivities.length === 0) return null;
32263
32146
  if (projectMu === null) {
32264
- if (anchor && anchor.kind === "backward") {
32147
+ if (anchor?.kind === "backward") {
32265
32148
  return [
32266
32149
  { text: "Expected duration: ?", level: 0 },
32267
32150
  { text: "P50 latest-safe start: ?", level: 0 },
@@ -32284,13 +32167,13 @@ function buildSummary(input) {
32284
32167
  const sigmaPositive = projectSigma !== null && projectSigma > 0;
32285
32168
  const showMcDetail = mc && sigmaPositive;
32286
32169
  const sigmaParen = showMcDetail ? ` (\xB1 ${roundForCaption(projectSigma)} ${pluralizeUnit(projectSigma, unit)})` : "";
32287
- if (anchor && anchor.kind === "forward") {
32170
+ if (anchor?.kind === "forward") {
32288
32171
  const projectMuDays = projectMu * unitToDays(unit);
32289
32172
  rows.push({
32290
32173
  text: `Expected finish: ${addCalendarDays(anchor.date, projectMuDays)}${sigmaParen}.`,
32291
32174
  level: 0
32292
32175
  });
32293
- } else if (anchor && anchor.kind === "backward") {
32176
+ } else if (anchor?.kind === "backward") {
32294
32177
  const projectMuDays = projectMu * unitToDays(unit);
32295
32178
  rows.push({
32296
32179
  text: `Expected start: ${addCalendarDays(anchor.date, -projectMuDays)}${sigmaParen}.`,
@@ -32309,13 +32192,13 @@ function buildSummary(input) {
32309
32192
  { pct: 80, days: monteCarloResult.p80 },
32310
32193
  { pct: 95, days: monteCarloResult.p95 }
32311
32194
  ];
32312
- if (anchor && anchor.kind === "forward") {
32195
+ if (anchor?.kind === "forward") {
32313
32196
  for (const { pct, days } of percentiles) {
32314
32197
  const offsetDays = roundConservative(days, "forward");
32315
32198
  const date = addCalendarDays(anchor.date, offsetDays);
32316
32199
  rows.push({ text: `P${pct} finish: ${date}.`, level: 1 });
32317
32200
  }
32318
- } else if (anchor && anchor.kind === "backward") {
32201
+ } else if (anchor?.kind === "backward") {
32319
32202
  for (const { pct, days } of percentiles) {
32320
32203
  const offsetDays = roundConservative(days, "backward");
32321
32204
  const date = addCalendarDays(anchor.date, -offsetDays);
@@ -32359,20 +32242,20 @@ function buildProjectSubtitle(input) {
32359
32242
  const sigmaPositive = projectSigma !== null && projectSigma > 0;
32360
32243
  const sigmaParen = sigmaPositive ? ` (\xB1 ${roundForCaption(projectSigma)})` : "";
32361
32244
  if (projectMu === null) {
32362
- if (anchor && anchor.kind === "forward") {
32245
+ if (anchor?.kind === "forward") {
32363
32246
  return `Expected finish: ? \xB7 \u2248 ? ${pluralizeUnit(2, unit)} of work`;
32364
32247
  }
32365
- if (anchor && anchor.kind === "backward") {
32248
+ if (anchor?.kind === "backward") {
32366
32249
  return `Expected start: ? \xB7 \u2248 ? ${pluralizeUnit(2, unit)} lead time`;
32367
32250
  }
32368
32251
  return `\u2248 ? ${pluralizeUnit(2, unit)}`;
32369
32252
  }
32370
32253
  const muStr = `${roundForCaption(projectMu)} ${pluralizeUnit(projectMu, unit)}`;
32371
- if (anchor && anchor.kind === "forward") {
32254
+ if (anchor?.kind === "forward") {
32372
32255
  const projectMuDays = projectMu * unitToDays(unit);
32373
32256
  return `Expected finish: ${addCalendarDays(anchor.date, projectMuDays)} \xB7 \u2248 ${muStr} of work${sigmaParen}`;
32374
32257
  }
32375
- if (anchor && anchor.kind === "backward") {
32258
+ if (anchor?.kind === "backward") {
32376
32259
  const projectMuDays = projectMu * unitToDays(unit);
32377
32260
  return `Expected start: ${addCalendarDays(anchor.date, -projectMuDays)} \xB7 \u2248 ${muStr} lead time${sigmaParen}`;
32378
32261
  }
@@ -32563,7 +32446,7 @@ function computeNodeSizing(resolved) {
32563
32446
  return { activityWidth, milestoneWidth, outerColW, midColW };
32564
32447
  }
32565
32448
  function nodeDimensions(resolved, id, sizing, overrides) {
32566
- if (overrides && overrides[id]) {
32449
+ if (overrides?.[id]) {
32567
32450
  return { width: overrides[id].width, height: overrides[id].height };
32568
32451
  }
32569
32452
  const r = resolved.activities.find((a) => a.activity.id === id);
@@ -42949,9 +42832,6 @@ function wrapLabelWords(words) {
42949
42832
  function renderRectParticipant(g, palette, isDark, color, solid) {
42950
42833
  g.append("rect").attr("x", -W / 2).attr("y", 0).attr("width", W).attr("height", H).attr("rx", 2).attr("ry", 2).attr("fill", fill(palette, isDark, color, solid)).attr("stroke", stroke(palette, color)).attr("stroke-width", SW);
42951
42834
  }
42952
- function renderServiceParticipant(g, palette, isDark, color, solid) {
42953
- g.append("rect").attr("x", -W / 2).attr("y", 0).attr("width", W).attr("height", H).attr("rx", SERVICE_BORDER_RADIUS).attr("ry", SERVICE_BORDER_RADIUS).attr("fill", fill(palette, isDark, color, solid)).attr("stroke", stroke(palette, color)).attr("stroke-width", SW);
42954
- }
42955
42835
  function renderActorParticipant(g, palette, color) {
42956
42836
  const headR = 8;
42957
42837
  const cx = 0;
@@ -43006,31 +42886,6 @@ function renderCacheParticipant(g, palette, isDark, color, solid) {
43006
42886
  g.append("line").attr("x1", W / 2).attr("y1", topY).attr("x2", W / 2).attr("y2", topY + bodyH).attr("stroke", s).attr("stroke-width", SW).attr("stroke-dasharray", dash);
43007
42887
  g.append("ellipse").attr("cx", 0).attr("cy", topY).attr("rx", W / 2).attr("ry", ry).attr("fill", f).attr("stroke", s).attr("stroke-width", SW).attr("stroke-dasharray", dash);
43008
42888
  }
43009
- function renderNetworkingParticipant(g, palette, isDark, color, solid) {
43010
- const inset = 16;
43011
- const points = [
43012
- `${-W / 2 + inset},0`,
43013
- `${W / 2 - inset},0`,
43014
- `${W / 2},${H / 2}`,
43015
- `${W / 2 - inset},${H}`,
43016
- `${-W / 2 + inset},${H}`,
43017
- `${-W / 2},${H / 2}`
43018
- ].join(" ");
43019
- g.append("polygon").attr("points", points).attr("fill", fill(palette, isDark, color, solid)).attr("stroke", stroke(palette, color)).attr("stroke-width", SW);
43020
- }
43021
- function renderFrontendParticipant(g, palette, isDark, color, solid) {
43022
- const screenH = H - 10;
43023
- const s = stroke(palette, color);
43024
- g.append("rect").attr("x", -W / 2).attr("y", 0).attr("width", W).attr("height", screenH).attr("rx", 3).attr("ry", 3).attr("fill", fill(palette, isDark, color, solid)).attr("stroke", s).attr("stroke-width", SW);
43025
- g.append("line").attr("x1", 0).attr("y1", screenH).attr("x2", 0).attr("y2", H - 2).attr("stroke", s).attr("stroke-width", SW);
43026
- g.append("line").attr("x1", -14).attr("y1", H - 2).attr("x2", 14).attr("y2", H - 2).attr("stroke", s).attr("stroke-width", SW);
43027
- }
43028
- function renderExternalParticipant(g, palette, isDark, color, solid) {
43029
- g.append("rect").attr("x", -W / 2).attr("y", 0).attr("width", W).attr("height", H).attr("rx", 2).attr("ry", 2).attr("fill", fill(palette, isDark, color, solid)).attr("stroke", stroke(palette, color)).attr("stroke-width", SW).attr("stroke-dasharray", "6 3");
43030
- }
43031
- function renderGatewayParticipant(g, palette, isDark, color, _solid) {
43032
- renderRectParticipant(g, palette, isDark, color);
43033
- }
43034
42889
  function groupMessagesBySection(elements, messages) {
43035
42890
  const groups = [];
43036
42891
  let currentGroup = null;
@@ -43669,7 +43524,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
43669
43524
  }
43670
43525
  }
43671
43526
  const lastStep = renderSteps[renderSteps.length - 1];
43672
- const lastIsSelfCall = lastStep && lastStep.type === "call" && lastStep.from === lastStep.to;
43527
+ const lastIsSelfCall = lastStep?.type === "call" && lastStep.from === lastStep.to;
43673
43528
  const lastStepTrailing = lastIsSelfCall ? SELF_CALL_HEIGHT + 25 : stepSpacing;
43674
43529
  let contentBottomY = renderSteps.length > 0 ? Math.max(
43675
43530
  stepYPositions[stepYPositions.length - 1] + lastStepTrailing,
@@ -43843,6 +43698,9 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
43843
43698
  const FRAME_PADDING_X = 30;
43844
43699
  const FRAME_PADDING_BOTTOM = 15;
43845
43700
  const FRAME_LABEL_HEIGHT = 18;
43701
+ const SELF_ARROW_PROJECTION = ACTIVATION_WIDTH / 2 + SELF_CALL_WIDTH;
43702
+ const SELF_ARROW_FRAME_PAD = 10;
43703
+ const frameRightmostX = Math.max(...Array.from(participantX.values()));
43846
43704
  const collectMsgIndices = (els) => {
43847
43705
  const indices = [];
43848
43706
  for (const el of els) {
@@ -43909,16 +43767,40 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
43909
43767
  maxPX = Math.max(maxPX, px);
43910
43768
  }
43911
43769
  }
43912
- const frameX = minPX - FRAME_PADDING_X;
43770
+ let extraLeft = 0;
43771
+ let extraRight = 0;
43772
+ let maxStepIsSelfCall = false;
43773
+ for (const mi of allIndices) {
43774
+ const m = messages[mi];
43775
+ if (m.from === m.to) {
43776
+ const px = participantX.get(m.from);
43777
+ if (px !== void 0) {
43778
+ const flipLeft = px === frameRightmostX;
43779
+ if (flipLeft) {
43780
+ const loopMin = px - SELF_ARROW_PROJECTION;
43781
+ const need = minPX - FRAME_PADDING_X - loopMin + SELF_ARROW_FRAME_PAD;
43782
+ if (need > 0) extraLeft = Math.max(extraLeft, need);
43783
+ } else {
43784
+ const loopMax = px + SELF_ARROW_PROJECTION;
43785
+ const need = loopMax - (maxPX + FRAME_PADDING_X) + SELF_ARROW_FRAME_PAD;
43786
+ if (need > 0) extraRight = Math.max(extraRight, need);
43787
+ }
43788
+ }
43789
+ if (msgToLastStep.get(mi) === maxStep) {
43790
+ maxStepIsSelfCall = true;
43791
+ }
43792
+ }
43793
+ }
43794
+ const frameX = minPX - FRAME_PADDING_X - extraLeft;
43913
43795
  const frameY = stepY(minStep) - FRAME_PADDING_TOP;
43914
- const frameW = maxPX - minPX + FRAME_PADDING_X * 2;
43915
- const frameH = stepY(maxStep) - stepY(minStep) + FRAME_PADDING_TOP + FRAME_PADDING_BOTTOM;
43796
+ const frameW = maxPX - minPX + FRAME_PADDING_X * 2 + extraLeft + extraRight;
43797
+ const frameH = stepY(maxStep) - stepY(minStep) + FRAME_PADDING_TOP + FRAME_PADDING_BOTTOM + (maxStepIsSelfCall ? SELF_CALL_HEIGHT : 0);
43916
43798
  svg.append("rect").attr("x", frameX).attr("y", frameY).attr("width", frameW).attr("height", frameH).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 1).attr("stroke-dasharray", "2 3").attr("rx", 3).attr("ry", 3).attr("class", "block-frame").attr("data-block-line", String(el.lineNumber));
43917
43799
  deferredLabels.push({
43918
43800
  x: frameX + 6,
43919
43801
  y: frameY + FRAME_LABEL_HEIGHT - 4,
43920
43802
  text: `${el.type} ${el.label}`,
43921
- bold: true,
43803
+ bold: false,
43922
43804
  italic: false,
43923
43805
  blockLine: el.lineNumber
43924
43806
  });
@@ -43944,7 +43826,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
43944
43826
  y: dividerY + 14,
43945
43827
  text: `else if ${branchData.label}`,
43946
43828
  bold: false,
43947
- italic: true,
43829
+ italic: false,
43948
43830
  blockLine: branchData.lineNumber
43949
43831
  });
43950
43832
  }
@@ -43971,7 +43853,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
43971
43853
  y: dividerY + 14,
43972
43854
  text: "else",
43973
43855
  bold: false,
43974
- italic: true,
43856
+ italic: false,
43975
43857
  blockLine: el.elseLineNumber
43976
43858
  });
43977
43859
  }
@@ -44041,7 +43923,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
44041
43923
  return side === "right" ? px + ACTIVATION_WIDTH / 2 + offset : px - ACTIVATION_WIDTH / 2 + offset;
44042
43924
  };
44043
43925
  const leftmostX = Math.min(...Array.from(participantX.values()));
44044
- const rightmostX = Math.max(...Array.from(participantX.values()));
43926
+ const rightmostX = frameRightmostX;
44045
43927
  const sectionLineX1 = leftmostX - PARTICIPANT_BOX_WIDTH / 2 - 10;
44046
43928
  const sectionLineX2 = rightmostX + PARTICIPANT_BOX_WIDTH / 2 + 10;
44047
43929
  for (const region of sectionRegions) {
@@ -44300,27 +44182,12 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
44300
44182
  case "database":
44301
44183
  renderDatabaseParticipant(g, palette, isDark, color, solid);
44302
44184
  break;
44303
- case "service":
44304
- renderServiceParticipant(g, palette, isDark, color, solid);
44305
- break;
44306
44185
  case "queue":
44307
44186
  renderQueueParticipant(g, palette, isDark, color, solid);
44308
44187
  break;
44309
44188
  case "cache":
44310
44189
  renderCacheParticipant(g, palette, isDark, color, solid);
44311
44190
  break;
44312
- case "networking":
44313
- renderNetworkingParticipant(g, palette, isDark, color, solid);
44314
- break;
44315
- case "frontend":
44316
- renderFrontendParticipant(g, palette, isDark, color, solid);
44317
- break;
44318
- case "external":
44319
- renderExternalParticipant(g, palette, isDark, color, solid);
44320
- break;
44321
- case "gateway":
44322
- renderGatewayParticipant(g, palette, isDark, color, solid);
44323
- break;
44324
44191
  default:
44325
44192
  renderRectParticipant(g, palette, isDark, color, solid);
44326
44193
  break;
@@ -44348,7 +44215,7 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
44348
44215
  });
44349
44216
  }
44350
44217
  }
44351
- var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, SERVICE_BORDER_RADIUS, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, NOTE_LANE_MAX, LABEL_CHAR_WIDTH, LABEL_MAX_CHARS, fill, stroke, SW, W, H;
44218
+ var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, NOTE_LANE_MAX, LABEL_CHAR_WIDTH, LABEL_MAX_CHARS, fill, stroke, SW, W, H;
44352
44219
  var init_renderer19 = __esm({
44353
44220
  "src/sequence/renderer.ts"() {
44354
44221
  "use strict";
@@ -44369,7 +44236,6 @@ var init_renderer19 = __esm({
44369
44236
  TOP_MARGIN = 20;
44370
44237
  TITLE_HEIGHT8 = 30;
44371
44238
  PARTICIPANT_Y_OFFSET = 10;
44372
- SERVICE_BORDER_RADIUS = 10;
44373
44239
  MESSAGE_START_OFFSET = 30;
44374
44240
  LIFELINE_TAIL = 30;
44375
44241
  ARROWHEAD_SIZE = 8;
@@ -44566,7 +44432,7 @@ function parseVisualization(content, palette) {
44566
44432
  const warn = (line12, message) => {
44567
44433
  result.diagnostics.push(makeDgmoError(line12, message, "warning"));
44568
44434
  };
44569
- if (!content || !content.trim()) {
44435
+ if (!content?.trim()) {
44570
44436
  return fail(0, "Empty content");
44571
44437
  }
44572
44438
  const lines = content.split("\n");
@@ -46606,7 +46472,7 @@ function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setu
46606
46472
  const groupKey = groupName.toLowerCase();
46607
46473
  groupEl.attr("data-tag-group", groupKey);
46608
46474
  if (isActive && !viewMode) {
46609
- const isSwimActive = currentSwimlaneGroup != null && currentSwimlaneGroup.toLowerCase() === groupKey;
46475
+ const isSwimActive = currentSwimlaneGroup?.toLowerCase() === groupKey;
46610
46476
  const pillWidth3 = measureLegendText(groupName, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
46611
46477
  const pillXOff = LG_CAPSULE_PAD;
46612
46478
  const iconX = pillXOff + pillWidth3 + 5;