@spectratools/graphic-designer-cli 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1060,7 +1060,8 @@ var connectionElementSchema = z2.object({
1060
1060
  from: z2.string().min(1).max(120),
1061
1061
  to: z2.string().min(1).max(120),
1062
1062
  style: z2.enum(["solid", "dashed", "dotted"]).default("solid"),
1063
- strokeStyle: z2.enum(["solid", "dashed", "dotted"]).default("solid"),
1063
+ /** @deprecated Use `style` instead. */
1064
+ strokeStyle: z2.enum(["solid", "dashed", "dotted"]).optional(),
1064
1065
  arrow: z2.enum(["end", "start", "both", "none"]).default("end"),
1065
1066
  label: z2.string().min(1).max(200).optional(),
1066
1067
  labelPosition: z2.enum(["start", "middle", "end"]).default("middle"),
@@ -1072,7 +1073,8 @@ var connectionElementSchema = z2.object({
1072
1073
  arrowSize: z2.number().min(4).max(32).optional(),
1073
1074
  arrowPlacement: z2.enum(["endpoint", "boundary"]).default("endpoint"),
1074
1075
  opacity: z2.number().min(0).max(1).default(1),
1075
- routing: z2.enum(["auto", "orthogonal", "curve", "arc"]).default("auto"),
1076
+ routing: z2.enum(["auto", "orthogonal", "curve", "arc", "straight"]).default("auto"),
1077
+ curveMode: z2.enum(["normal", "ellipse"]).default("normal"),
1076
1078
  tension: z2.number().min(0.1).max(0.8).default(0.35),
1077
1079
  fromAnchor: anchorHintSchema.optional(),
1078
1080
  toAnchor: anchorHintSchema.optional()
@@ -1165,7 +1167,11 @@ var autoLayoutConfigSchema = z2.object({
1165
1167
  /** Sort strategy for radial layout node ordering. Only relevant when algorithm is 'radial'. */
1166
1168
  radialSortBy: z2.enum(["id", "connections"]).optional(),
1167
1169
  /** Explicit center used by curve/arc connection routing. */
1168
- diagramCenter: diagramCenterSchema.optional()
1170
+ diagramCenter: diagramCenterSchema.optional(),
1171
+ /** Horizontal radius for shared ellipse used by curveMode: 'ellipse'. */
1172
+ ellipseRx: z2.number().positive().optional(),
1173
+ /** Vertical radius for shared ellipse used by curveMode: 'ellipse'. */
1174
+ ellipseRy: z2.number().positive().optional()
1169
1175
  }).strict();
1170
1176
  var gridLayoutConfigSchema = z2.object({
1171
1177
  mode: z2.literal("grid"),
@@ -1175,7 +1181,11 @@ var gridLayoutConfigSchema = z2.object({
1175
1181
  cardMaxHeight: z2.number().int().min(32).max(4096).optional(),
1176
1182
  equalHeight: z2.boolean().default(false),
1177
1183
  /** Explicit center used by curve/arc connection routing. */
1178
- diagramCenter: diagramCenterSchema.optional()
1184
+ diagramCenter: diagramCenterSchema.optional(),
1185
+ /** Horizontal radius for shared ellipse used by curveMode: 'ellipse'. */
1186
+ ellipseRx: z2.number().positive().optional(),
1187
+ /** Vertical radius for shared ellipse used by curveMode: 'ellipse'. */
1188
+ ellipseRy: z2.number().positive().optional()
1179
1189
  }).strict();
1180
1190
  var stackLayoutConfigSchema = z2.object({
1181
1191
  mode: z2.literal("stack"),
@@ -1183,7 +1193,11 @@ var stackLayoutConfigSchema = z2.object({
1183
1193
  gap: z2.number().int().min(0).max(256).default(24),
1184
1194
  alignment: z2.enum(["start", "center", "end", "stretch"]).default("stretch"),
1185
1195
  /** Explicit center used by curve/arc connection routing. */
1186
- diagramCenter: diagramCenterSchema.optional()
1196
+ diagramCenter: diagramCenterSchema.optional(),
1197
+ /** Horizontal radius for shared ellipse used by curveMode: 'ellipse'. */
1198
+ ellipseRx: z2.number().positive().optional(),
1199
+ /** Vertical radius for shared ellipse used by curveMode: 'ellipse'. */
1200
+ ellipseRy: z2.number().positive().optional()
1187
1201
  }).strict();
1188
1202
  var manualPositionSchema = z2.object({
1189
1203
  x: z2.number().int(),
@@ -1195,7 +1209,11 @@ var manualLayoutConfigSchema = z2.object({
1195
1209
  mode: z2.literal("manual"),
1196
1210
  positions: z2.record(z2.string().min(1), manualPositionSchema).default({}),
1197
1211
  /** Explicit center used by curve/arc connection routing. */
1198
- diagramCenter: diagramCenterSchema.optional()
1212
+ diagramCenter: diagramCenterSchema.optional(),
1213
+ /** Horizontal radius for shared ellipse used by curveMode: 'ellipse'. */
1214
+ ellipseRx: z2.number().positive().optional(),
1215
+ /** Vertical radius for shared ellipse used by curveMode: 'ellipse'. */
1216
+ ellipseRy: z2.number().positive().optional()
1199
1217
  }).strict();
1200
1218
  var layoutConfigSchema = z2.discriminatedUnion("mode", [
1201
1219
  autoLayoutConfigSchema,
@@ -1260,7 +1278,11 @@ var diagramElementSchema = z2.discriminatedUnion("type", [
1260
1278
  var diagramLayoutSchema = z2.object({
1261
1279
  mode: z2.enum(["manual", "auto"]).default("manual"),
1262
1280
  positions: z2.record(z2.string(), diagramPositionSchema).optional(),
1263
- diagramCenter: diagramCenterSchema.optional()
1281
+ diagramCenter: diagramCenterSchema.optional(),
1282
+ /** Horizontal radius for shared ellipse used by curveMode: 'ellipse'. */
1283
+ ellipseRx: z2.number().positive().optional(),
1284
+ /** Vertical radius for shared ellipse used by curveMode: 'ellipse'. */
1285
+ ellipseRy: z2.number().positive().optional()
1264
1286
  }).strict();
1265
1287
  var diagramSpecSchema = z2.object({
1266
1288
  version: z2.literal(1),
@@ -3338,6 +3360,72 @@ function arcRoute(fromBounds, toBounds, diagramCenter, tension, fromAnchor, toAn
3338
3360
  [pMid, cp3, cp4, p3]
3339
3361
  ];
3340
3362
  }
3363
+ function inferEllipseParams(nodeBounds, explicitCenter, explicitRx, explicitRy) {
3364
+ if (nodeBounds.length === 0) {
3365
+ return {
3366
+ cx: explicitCenter?.x ?? 0,
3367
+ cy: explicitCenter?.y ?? 0,
3368
+ rx: explicitRx ?? 1,
3369
+ ry: explicitRy ?? 1
3370
+ };
3371
+ }
3372
+ const centers = nodeBounds.map(rectCenter);
3373
+ const cx = explicitCenter?.x ?? centers.reduce((sum, c) => sum + c.x, 0) / centers.length;
3374
+ const cy = explicitCenter?.y ?? centers.reduce((sum, c) => sum + c.y, 0) / centers.length;
3375
+ const rx = explicitRx ?? Math.max(1, ...centers.map((c) => Math.abs(c.x - cx)));
3376
+ const ry = explicitRy ?? Math.max(1, ...centers.map((c) => Math.abs(c.y - cy)));
3377
+ return { cx, cy, rx, ry };
3378
+ }
3379
+ function ellipseRoute(fromBounds, toBounds, ellipse, fromAnchor, toAnchor) {
3380
+ const fromCenter = rectCenter(fromBounds);
3381
+ const toCenter = rectCenter(toBounds);
3382
+ const p0 = resolveAnchor(fromBounds, fromAnchor, toCenter);
3383
+ const p3 = resolveAnchor(toBounds, toAnchor, fromCenter);
3384
+ const theta1 = Math.atan2(
3385
+ (fromCenter.y - ellipse.cy) / ellipse.ry,
3386
+ (fromCenter.x - ellipse.cx) / ellipse.rx
3387
+ );
3388
+ const theta2 = Math.atan2(
3389
+ (toCenter.y - ellipse.cy) / ellipse.ry,
3390
+ (toCenter.x - ellipse.cx) / ellipse.rx
3391
+ );
3392
+ let angularSpan = theta2 - theta1;
3393
+ while (angularSpan > Math.PI) angularSpan -= 2 * Math.PI;
3394
+ while (angularSpan <= -Math.PI) angularSpan += 2 * Math.PI;
3395
+ const absSpan = Math.abs(angularSpan);
3396
+ const kappa = absSpan < 1e-6 ? 0 : 4 / 3 * Math.tan(absSpan / 4);
3397
+ const tangent1 = {
3398
+ x: -ellipse.rx * Math.sin(theta1),
3399
+ y: ellipse.ry * Math.cos(theta1)
3400
+ };
3401
+ const tangent2 = {
3402
+ x: -ellipse.rx * Math.sin(theta2),
3403
+ y: ellipse.ry * Math.cos(theta2)
3404
+ };
3405
+ const len1 = Math.hypot(tangent1.x, tangent1.y) || 1;
3406
+ const len2 = Math.hypot(tangent2.x, tangent2.y) || 1;
3407
+ const norm1 = { x: tangent1.x / len1, y: tangent1.y / len1 };
3408
+ const norm2 = { x: tangent2.x / len2, y: tangent2.y / len2 };
3409
+ const chordLength = Math.hypot(p3.x - p0.x, p3.y - p0.y);
3410
+ const cpDistance = chordLength * kappa * 0.5;
3411
+ const sign = angularSpan >= 0 ? 1 : -1;
3412
+ const cp1 = {
3413
+ x: p0.x + norm1.x * cpDistance * sign,
3414
+ y: p0.y + norm1.y * cpDistance * sign
3415
+ };
3416
+ const cp2 = {
3417
+ x: p3.x - norm2.x * cpDistance * sign,
3418
+ y: p3.y - norm2.y * cpDistance * sign
3419
+ };
3420
+ return [p0, cp1, cp2, p3];
3421
+ }
3422
+ function straightRoute(fromBounds, toBounds, fromAnchor, toAnchor) {
3423
+ const fromC = rectCenter(fromBounds);
3424
+ const toC = rectCenter(toBounds);
3425
+ const p0 = resolveAnchor(fromBounds, fromAnchor, toC);
3426
+ const p3 = resolveAnchor(toBounds, toAnchor, fromC);
3427
+ return [p0, p3];
3428
+ }
3341
3429
  function orthogonalRoute(fromBounds, toBounds, fromAnchor, toAnchor) {
3342
3430
  const fromC = rectCenter(fromBounds);
3343
3431
  const toC = rectCenter(toBounds);
@@ -3382,15 +3470,6 @@ function findBoundaryIntersection(p0, cp1, cp2, p3, targetRect, searchFromEnd) {
3382
3470
  }
3383
3471
  return void 0;
3384
3472
  }
3385
- function pointAlongArc(route, t) {
3386
- const [first, second] = route;
3387
- if (t <= 0.5) {
3388
- const localT2 = Math.max(0, Math.min(1, t * 2));
3389
- return bezierPointAt(first[0], first[1], first[2], first[3], localT2);
3390
- }
3391
- const localT = Math.max(0, Math.min(1, (t - 0.5) * 2));
3392
- return bezierPointAt(second[0], second[1], second[2], second[3], localT);
3393
- }
3394
3473
  function computeDiagramCenter(nodeBounds, canvasCenter) {
3395
3474
  if (nodeBounds.length === 0) {
3396
3475
  return canvasCenter ?? { x: 0, y: 0 };
@@ -3513,8 +3592,19 @@ function polylineBounds(points) {
3513
3592
  };
3514
3593
  }
3515
3594
  function renderConnection(ctx, conn, fromBounds, toBounds, theme, edgeRoute, options) {
3516
- const routing = conn.routing ?? "auto";
3517
- const strokeStyle = conn.strokeStyle ?? conn.style ?? "solid";
3595
+ let routing = conn.routing ?? "auto";
3596
+ let curveMode = conn.curveMode ?? "normal";
3597
+ if (conn.strokeStyle !== void 0) {
3598
+ console.warn("connection.strokeStyle is deprecated, use style instead");
3599
+ }
3600
+ if (routing === "arc") {
3601
+ console.warn(
3602
+ "connection routing: 'arc' is deprecated. Use routing: 'curve' with curveMode: 'ellipse' instead."
3603
+ );
3604
+ routing = "curve";
3605
+ curveMode = "ellipse";
3606
+ }
3607
+ const strokeStyle = conn.style ?? conn.strokeStyle ?? "solid";
3518
3608
  const strokeWidth = conn.width ?? conn.strokeWidth ?? 2;
3519
3609
  const tension = conn.tension ?? 0.35;
3520
3610
  const dash = dashFromStyle(strokeStyle);
@@ -3536,14 +3626,29 @@ function renderConnection(ctx, conn, fromBounds, toBounds, theme, edgeRoute, opt
3536
3626
  ctx.globalAlpha = conn.opacity;
3537
3627
  const arrowPlacement = conn.arrowPlacement ?? "endpoint";
3538
3628
  if (routing === "curve") {
3539
- const [p0, cp1, cp2, p3] = curveRoute(
3540
- fromBounds,
3541
- toBounds,
3542
- diagramCenter,
3543
- tension,
3544
- conn.fromAnchor,
3545
- conn.toAnchor
3546
- );
3629
+ let p0;
3630
+ let cp1;
3631
+ let cp2;
3632
+ let p3;
3633
+ if (curveMode === "ellipse") {
3634
+ const ellipse = options?.ellipseParams ?? inferEllipseParams([fromBounds, toBounds]);
3635
+ [p0, cp1, cp2, p3] = ellipseRoute(
3636
+ fromBounds,
3637
+ toBounds,
3638
+ ellipse,
3639
+ conn.fromAnchor,
3640
+ conn.toAnchor
3641
+ );
3642
+ } else {
3643
+ [p0, cp1, cp2, p3] = curveRoute(
3644
+ fromBounds,
3645
+ toBounds,
3646
+ diagramCenter,
3647
+ tension,
3648
+ conn.fromAnchor,
3649
+ conn.toAnchor
3650
+ );
3651
+ }
3547
3652
  const stroke = resolveConnectionStroke(ctx, p0, p3, conn.fromColor, style.color, conn.toColor);
3548
3653
  ctx.strokeStyle = stroke;
3549
3654
  ctx.lineWidth = style.width;
@@ -3576,51 +3681,22 @@ function renderConnection(ctx, conn, fromBounds, toBounds, theme, edgeRoute, opt
3576
3681
  }
3577
3682
  }
3578
3683
  }
3579
- } else if (routing === "arc") {
3580
- const [first, second] = arcRoute(
3581
- fromBounds,
3582
- toBounds,
3583
- diagramCenter,
3584
- tension,
3585
- conn.fromAnchor,
3586
- conn.toAnchor
3587
- );
3588
- const [p0, cp1, cp2, pMid] = first;
3589
- const [, cp3, cp4, p3] = second;
3684
+ } else if (routing === "straight") {
3685
+ const [p0, p3] = straightRoute(fromBounds, toBounds, conn.fromAnchor, conn.toAnchor);
3590
3686
  const stroke = resolveConnectionStroke(ctx, p0, p3, conn.fromColor, style.color, conn.toColor);
3591
3687
  ctx.strokeStyle = stroke;
3592
3688
  ctx.lineWidth = style.width;
3593
3689
  ctx.setLineDash(style.dash ?? []);
3594
3690
  ctx.beginPath();
3595
3691
  ctx.moveTo(p0.x, p0.y);
3596
- ctx.bezierCurveTo(cp1.x, cp1.y, cp2.x, cp2.y, pMid.x, pMid.y);
3597
- ctx.bezierCurveTo(cp3.x, cp3.y, cp4.x, cp4.y, p3.x, p3.y);
3692
+ ctx.lineTo(p3.x, p3.y);
3598
3693
  ctx.stroke();
3599
- linePoints = [p0, cp1, cp2, pMid, cp3, cp4, p3];
3694
+ linePoints = [p0, p3];
3600
3695
  startPoint = p0;
3601
3696
  endPoint = p3;
3602
- startAngle = Math.atan2(p0.y - cp1.y, p0.x - cp1.x);
3603
- endAngle = Math.atan2(p3.y - cp4.y, p3.x - cp4.x);
3604
- labelPoint = pointAlongArc([first, second], labelT);
3605
- if (arrowPlacement === "boundary") {
3606
- if (conn.arrow === "end" || conn.arrow === "both") {
3607
- const [, s_cp3, s_cp4, s_p3] = second;
3608
- const tEnd = findBoundaryIntersection(pMid, s_cp3, s_cp4, s_p3, toBounds, true);
3609
- if (tEnd !== void 0) {
3610
- endPoint = bezierPointAt(pMid, s_cp3, s_cp4, s_p3, tEnd);
3611
- const tangent = bezierTangentAt(pMid, s_cp3, s_cp4, s_p3, tEnd);
3612
- endAngle = Math.atan2(tangent.y, tangent.x);
3613
- }
3614
- }
3615
- if (conn.arrow === "start" || conn.arrow === "both") {
3616
- const tStart = findBoundaryIntersection(p0, cp1, cp2, pMid, fromBounds, false);
3617
- if (tStart !== void 0) {
3618
- startPoint = bezierPointAt(p0, cp1, cp2, pMid, tStart);
3619
- const tangent = bezierTangentAt(p0, cp1, cp2, pMid, tStart);
3620
- startAngle = Math.atan2(tangent.y, tangent.x) + Math.PI;
3621
- }
3622
- }
3623
- }
3697
+ startAngle = Math.atan2(p0.y - p3.y, p0.x - p3.x);
3698
+ endAngle = Math.atan2(p3.y - p0.y, p3.x - p0.x);
3699
+ labelPoint = pointAlongPolyline(linePoints, labelT);
3624
3700
  } else {
3625
3701
  const hasAnchorHints = conn.fromAnchor !== void 0 || conn.toAnchor !== void 0;
3626
3702
  const useElkRoute = routing === "auto" && !hasAnchorHints && (edgeRoute?.points.length ?? 0) >= 2;
@@ -5049,10 +5125,19 @@ async function renderDesign(input, options = {}) {
5049
5125
  break;
5050
5126
  }
5051
5127
  }
5052
- const diagramCenter = spec.layout.diagramCenter ?? computeDiagramCenter(
5053
- spec.elements.filter((element) => element.type !== "connection").map((element) => elementRects.get(element.id)).filter((rect) => rect != null),
5054
- { x: spec.canvas.width / 2, y: spec.canvas.height / 2 }
5128
+ const nodeBounds = spec.elements.filter((element) => element.type !== "connection").map((element) => elementRects.get(element.id)).filter((rect) => rect != null);
5129
+ const diagramCenter = spec.layout.diagramCenter ?? computeDiagramCenter(nodeBounds, { x: spec.canvas.width / 2, y: spec.canvas.height / 2 });
5130
+ const layoutEllipseRx = "ellipseRx" in spec.layout ? spec.layout.ellipseRx : void 0;
5131
+ const layoutEllipseRy = "ellipseRy" in spec.layout ? spec.layout.ellipseRy : void 0;
5132
+ const hasEllipseConnections = spec.elements.some(
5133
+ (el) => el.type === "connection" && (el.curveMode === "ellipse" || el.routing === "arc")
5055
5134
  );
5135
+ const ellipseParams = hasEllipseConnections ? inferEllipseParams(
5136
+ nodeBounds,
5137
+ spec.layout.diagramCenter ?? diagramCenter,
5138
+ layoutEllipseRx,
5139
+ layoutEllipseRy
5140
+ ) : void 0;
5056
5141
  for (const element of spec.elements) {
5057
5142
  if (element.type !== "connection") {
5058
5143
  continue;
@@ -5066,7 +5151,15 @@ async function renderDesign(input, options = {}) {
5066
5151
  }
5067
5152
  const edgeRoute = edgeRoutes?.get(`${element.from}-${element.to}`);
5068
5153
  elements.push(
5069
- ...renderConnection(ctx, element, fromRect, toRect, theme, edgeRoute, { diagramCenter })
5154
+ ...renderConnection(
5155
+ ctx,
5156
+ element,
5157
+ fromRect,
5158
+ toRect,
5159
+ theme,
5160
+ edgeRoute,
5161
+ ellipseParams ? { diagramCenter, ellipseParams } : { diagramCenter }
5162
+ )
5070
5163
  );
5071
5164
  }
5072
5165
  if (footerRect && spec.footer) {
@@ -6128,8 +6221,10 @@ export {
6128
6221
  drawRainbowRule,
6129
6222
  drawVignette,
6130
6223
  edgeAnchor,
6224
+ ellipseRoute,
6131
6225
  flowNodeElementSchema,
6132
6226
  highlightCode,
6227
+ inferEllipseParams,
6133
6228
  inferLayout,
6134
6229
  inferSidecarPath,
6135
6230
  initHighlighter,
@@ -6148,6 +6243,7 @@ export {
6148
6243
  resolveShikiTheme,
6149
6244
  resolveTheme,
6150
6245
  runQa,
6246
+ straightRoute,
6151
6247
  themeToShikiMap,
6152
6248
  writeRenderArtifacts
6153
6249
  };
package/dist/qa.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { R as RenderMetadata, D as DesignSpec } from './spec.schema-B6sXTTou.js';
1
+ import { R as RenderMetadata, D as DesignSpec } from './spec.schema-CYlOLxmK.js';
2
2
  import 'zod';
3
3
  import '@napi-rs/canvas';
4
4
 
package/dist/qa.js CHANGED
@@ -793,7 +793,8 @@ var connectionElementSchema = z2.object({
793
793
  from: z2.string().min(1).max(120),
794
794
  to: z2.string().min(1).max(120),
795
795
  style: z2.enum(["solid", "dashed", "dotted"]).default("solid"),
796
- strokeStyle: z2.enum(["solid", "dashed", "dotted"]).default("solid"),
796
+ /** @deprecated Use `style` instead. */
797
+ strokeStyle: z2.enum(["solid", "dashed", "dotted"]).optional(),
797
798
  arrow: z2.enum(["end", "start", "both", "none"]).default("end"),
798
799
  label: z2.string().min(1).max(200).optional(),
799
800
  labelPosition: z2.enum(["start", "middle", "end"]).default("middle"),
@@ -805,7 +806,8 @@ var connectionElementSchema = z2.object({
805
806
  arrowSize: z2.number().min(4).max(32).optional(),
806
807
  arrowPlacement: z2.enum(["endpoint", "boundary"]).default("endpoint"),
807
808
  opacity: z2.number().min(0).max(1).default(1),
808
- routing: z2.enum(["auto", "orthogonal", "curve", "arc"]).default("auto"),
809
+ routing: z2.enum(["auto", "orthogonal", "curve", "arc", "straight"]).default("auto"),
810
+ curveMode: z2.enum(["normal", "ellipse"]).default("normal"),
809
811
  tension: z2.number().min(0.1).max(0.8).default(0.35),
810
812
  fromAnchor: anchorHintSchema.optional(),
811
813
  toAnchor: anchorHintSchema.optional()
@@ -898,7 +900,11 @@ var autoLayoutConfigSchema = z2.object({
898
900
  /** Sort strategy for radial layout node ordering. Only relevant when algorithm is 'radial'. */
899
901
  radialSortBy: z2.enum(["id", "connections"]).optional(),
900
902
  /** Explicit center used by curve/arc connection routing. */
901
- diagramCenter: diagramCenterSchema.optional()
903
+ diagramCenter: diagramCenterSchema.optional(),
904
+ /** Horizontal radius for shared ellipse used by curveMode: 'ellipse'. */
905
+ ellipseRx: z2.number().positive().optional(),
906
+ /** Vertical radius for shared ellipse used by curveMode: 'ellipse'. */
907
+ ellipseRy: z2.number().positive().optional()
902
908
  }).strict();
903
909
  var gridLayoutConfigSchema = z2.object({
904
910
  mode: z2.literal("grid"),
@@ -908,7 +914,11 @@ var gridLayoutConfigSchema = z2.object({
908
914
  cardMaxHeight: z2.number().int().min(32).max(4096).optional(),
909
915
  equalHeight: z2.boolean().default(false),
910
916
  /** Explicit center used by curve/arc connection routing. */
911
- diagramCenter: diagramCenterSchema.optional()
917
+ diagramCenter: diagramCenterSchema.optional(),
918
+ /** Horizontal radius for shared ellipse used by curveMode: 'ellipse'. */
919
+ ellipseRx: z2.number().positive().optional(),
920
+ /** Vertical radius for shared ellipse used by curveMode: 'ellipse'. */
921
+ ellipseRy: z2.number().positive().optional()
912
922
  }).strict();
913
923
  var stackLayoutConfigSchema = z2.object({
914
924
  mode: z2.literal("stack"),
@@ -916,7 +926,11 @@ var stackLayoutConfigSchema = z2.object({
916
926
  gap: z2.number().int().min(0).max(256).default(24),
917
927
  alignment: z2.enum(["start", "center", "end", "stretch"]).default("stretch"),
918
928
  /** Explicit center used by curve/arc connection routing. */
919
- diagramCenter: diagramCenterSchema.optional()
929
+ diagramCenter: diagramCenterSchema.optional(),
930
+ /** Horizontal radius for shared ellipse used by curveMode: 'ellipse'. */
931
+ ellipseRx: z2.number().positive().optional(),
932
+ /** Vertical radius for shared ellipse used by curveMode: 'ellipse'. */
933
+ ellipseRy: z2.number().positive().optional()
920
934
  }).strict();
921
935
  var manualPositionSchema = z2.object({
922
936
  x: z2.number().int(),
@@ -928,7 +942,11 @@ var manualLayoutConfigSchema = z2.object({
928
942
  mode: z2.literal("manual"),
929
943
  positions: z2.record(z2.string().min(1), manualPositionSchema).default({}),
930
944
  /** Explicit center used by curve/arc connection routing. */
931
- diagramCenter: diagramCenterSchema.optional()
945
+ diagramCenter: diagramCenterSchema.optional(),
946
+ /** Horizontal radius for shared ellipse used by curveMode: 'ellipse'. */
947
+ ellipseRx: z2.number().positive().optional(),
948
+ /** Vertical radius for shared ellipse used by curveMode: 'ellipse'. */
949
+ ellipseRy: z2.number().positive().optional()
932
950
  }).strict();
933
951
  var layoutConfigSchema = z2.discriminatedUnion("mode", [
934
952
  autoLayoutConfigSchema,
@@ -993,7 +1011,11 @@ var diagramElementSchema = z2.discriminatedUnion("type", [
993
1011
  var diagramLayoutSchema = z2.object({
994
1012
  mode: z2.enum(["manual", "auto"]).default("manual"),
995
1013
  positions: z2.record(z2.string(), diagramPositionSchema).optional(),
996
- diagramCenter: diagramCenterSchema.optional()
1014
+ diagramCenter: diagramCenterSchema.optional(),
1015
+ /** Horizontal radius for shared ellipse used by curveMode: 'ellipse'. */
1016
+ ellipseRx: z2.number().positive().optional(),
1017
+ /** Vertical radius for shared ellipse used by curveMode: 'ellipse'. */
1018
+ ellipseRy: z2.number().positive().optional()
997
1019
  }).strict();
998
1020
  var diagramSpecSchema = z2.object({
999
1021
  version: z2.literal(1),
@@ -1,3 +1,3 @@
1
- export { i as DEFAULT_GENERATOR_VERSION, S as IterationMeta, V as LayoutSnapshot, a as Rect, Y as RenderDesignOptions, R as RenderMetadata, Z as RenderResult, d as RenderedElement, a4 as WrittenArtifacts, a7 as computeSpecHash, aq as inferSidecarPath, at as renderDesign, av as writeRenderArtifacts } from './spec.schema-B6sXTTou.js';
1
+ export { i as DEFAULT_GENERATOR_VERSION, S as IterationMeta, V as LayoutSnapshot, a as Rect, Y as RenderDesignOptions, R as RenderMetadata, Z as RenderResult, d as RenderedElement, a4 as WrittenArtifacts, a7 as computeSpecHash, aq as inferSidecarPath, at as renderDesign, av as writeRenderArtifacts } from './spec.schema-CYlOLxmK.js';
2
2
  import 'zod';
3
3
  import '@napi-rs/canvas';