# Interfaces O–S

Import these from `@grafloria/renderer`.

## Interfaces

### `OptimizerLabel`

A label awaiting placement.

```ts
interface OptimizerLabel
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `id` | `string` |  |  |
| `anchor` | `Point` |  | On-path anchor the label hangs off (world). |
| `offset` | `Point` |  | The offset the AUTHOR asked for — the preferred placement, and the fallback. |
| `width` | `number` |  | Box size used for collision tests. |
| `height` | `number` |  |  |
| `autoOffset` | `boolean` |  | Opt-in to the collision search. Off ⇒ `offset` is returned verbatim. |
| `normal` | `Point` |  | Unit normal of the path at `anchor` — the axis the search pushes along. |

### `OptimizerLink`

```ts
interface OptimizerLink
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `id` | `string` |  |  |
| `points` | `Point[]` |  | The ROUTED polyline for this frame (post parallel-separation / self-loop). |
| `jumps?` | `{ mode: DetectionMode; threshold: number; }` |  | Jump config, if this link draws jumps at all. |
| `labels` | `OptimizerLabel[]` |  |  |

### `OptimizerNode`

A node, as far as the optimizer cares: an obstacle with an id.

```ts
interface OptimizerNode
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `id` | `string` |  |  |
| `rect` | `OptimizerRect` |  |  |

### `OptimizerRect`

```ts
interface OptimizerRect
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `x` | `number` |  |  |
| `y` | `number` |  |  |
| `width` | `number` |  |  |
| `height` | `number` |  |  |

### `OptimizerStats`

Per-frame work counters — the incrementality is only real if these are 0 on a quiet frame.

```ts
interface OptimizerStats
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `dirtyLinks` | `number` |  | Links whose geometry changed this frame. |
| `jumpsRecomputed` | `number` |  | Links whose jump set was recomputed (dirty ones + their grid neighbours). |
| `jumpsReused` | `number` |  | Links that served their jump set from cache. |
| `labelsPlaced` | `number` |  | Labels whose placement was searched. |
| `labelsReused` | `number` |  | Labels served from cache. |
| `segmentTests` | `number` |  | Segment-pair intersection tests actually performed. |

### `OutlineSpec`

An SVG element type plus the geometry props for one outline instance.

```ts
interface OutlineSpec
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `el` | `VNodeType` |  |  |
| `geom` | `Record<string, number \| string>` |  |  |
| `verts?` | `ShapePoint[]` |  | Polygon shapes expose their vertices so boundaryPoint can reuse them. |

### `OutlineTransform`

Transform applied to a shape outline. The same primitive drives every render
site: body = {}, selection = { grow: padding }, shadow = { dx, dy }.

```ts
interface OutlineTransform
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `grow?` | `number` |  | Expand the outline outward by this many px (selection highlight padding). |
| `dx?` | `number` |  | Translate the outline (drop-shadow offset). |
| `dy?` | `number` |  |  |
| `radius?` | `number` |  | Corner radius for rect (rx). Emitted only when truthy unless `radiusAlways`. |
| `radiusY?` | `boolean` |  | Also emit ry (= radius). Selection/body want rx+ry; shadow wants rx only. |
| `radiusAlways?` | `boolean` |  | Emit rx even when `radius` is 0 (shadow keeps rx: borderRadius ?? 4). |

### `PagedSvgResult`

```ts
interface PagedSvgResult
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `pages` | `Array<Page & { svg: string }>` |  |  |
| `columns` | `number` |  |  |
| `rows` | `number` |  |  |
| `warnings` | `string[]` |  |  |

### `PanelBadge`

A count / status badge pinned to a corner.

```ts
interface PanelBadge
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `text` | `string` |  |  |
| `corner?` | `PanelCorner` |  |  |
| `fill?` | `string` |  |  |
| `textColor?` | `string` |  |  |

### `PanelHeader`

A header band across the top of the node (ERD/UML title row).

```ts
interface PanelHeader
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `text?` | `string` |  |  |
| `lines?` | `string[]` |  | STACKED header lines — the UML classifier convention of a «stereotype» over the name. Wins over `text` when present; the band grows to hold every line, and each line is fitted to the band width (shrunk, never clipped: «enumeration» over a 120px card used to paint "umeration» Enumera" cut off at both edges). |
| `height?` | `number` |  | Band height in px. Default 22, or 16/line + 4 when `lines` stack. |
| `fill?` | `string` |  |  |
| `textColor?` | `string` |  |  |

### `PanelIcon`

A small icon — a raster href, an emoji/text glyph, or a built-in line icon — pinned to a corner.

```ts
interface PanelIcon
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `href?` | `string` |  |  |
| `glyph?` | `string` |  | Emoji or short glyph, used when `href` is absent. |
| `name?` | `string` |  | A built-in line icon, used when there is no href or glyph: one of {@link BUILTIN_ICONS} (`cloud`, `database`, `disk`, `internet`, `server` — Mermaid architecture-beta's own). Drawn as our paths in the node's ink; an unknown name draws nothing. |
| `size?` | `number` |  | Box size in px. Default 18. |
| `corner?` | `PanelCorner` |  | Corner to pin to. Default 'tl'. |

### `PanelImage`

A raster image slot below the header (data: URI strongly preferred).

```ts
interface PanelImage
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `href` | `string` |  |  |
| `height?` | `number` |  | Slot height in px. Default 48. |

### `PanelRenderContext`

Style inputs the host renderer supplies (theme-derived, CSS-mode aware).

```ts
interface PanelRenderContext
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `nodeId` | `string` |  | Node id — used for stable child keys. |
| `fontSize` | `number` |  |  |
| `headerFill` | `string` |  |  |
| `headerTextColor` | `string` |  |  |
| `bodyTextColor` | `string` |  |  |
| `badgeFill` | `string` |  |  |
| `badgeTextColor` | `string` |  |  |

### `PanelRow`

A stacked body text row (ERD field / UML member).

```ts
interface PanelRow
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `text` | `string` |  |  |
| `align?` | `'start' \| 'middle' \| 'end'` |  |  |

### `PanelSpec`

The composite-panel spec stored at `node.metadata.panel`.

```ts
interface PanelSpec
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `header?` | `PanelHeader` |  |  |
| `image?` | `PanelImage` |  |  |
| `icon?` | `PanelIcon` |  |  |
| `badges?` | `PanelBadge[]` |  |  |
| `rows?` | `PanelRow[]` |  |  |
| `rowHeight?` | `number` |  | Per-row height in px. Default 18. |

### `PathShapeOptions`

Options for {@link registerPathShape}.

By default the boundary point (smart-connection attachment) and the port
anchors are DERIVED from the path outline by sampling — so a custom silhouette
attaches links to its real edge, not its bounding box. Supply `portAnchor` /
`boundaryPoint` to override the sampled geometry with exact analytic anchors
(the same override seam the built-in triangle uses for its apex/base points).

```ts
interface PathShapeOptions
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `viewBox?` | `PathViewBox` |  | Reference box for a STATIC path string (default `0 0 1 1` — unit box). |
| `portAnchor?` | `ShapeDefinition['portAnchor']` |  | Exact port anchors, bypassing outline sampling. |
| `boundaryPoint?` | `ShapeDefinition['boundaryPoint']` |  | Exact smart-connection boundary, bypassing outline sampling. |
| `innerRect?` | `ShapeDefinition['innerRect']` |  | Label box; defaults to the padded bounding box. |
| `sampleSteps?` | `number` |  | Curve subdivision when sampling the outline (default 24). |

### `PathViewBox`

The author's declared reference box for a STATIC path string.

```ts
interface PathViewBox
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `x` | `number` |  |  |
| `y` | `number` |  |  |
| `w` | `number` |  |  |
| `h` | `number` |  |  |

### `PortGlyphInput`

```ts
interface PortGlyphInput
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `x` | `number` |  | Node-local anchor: the port's position. The glyph is CENTRED on it. |
| `y` | `number` |  |  |
| `shape?` | `PortShapeSpec` |  | Resolved glyph spec. Undefined → a circle of `radius` (the legacy glyph). |
| `radius` | `number` |  | The circle radius the interaction config asks for, and the size fallback. |
| `props` | `Record<string, unknown>` |  | Presentation attributes (fill/stroke/…) already merged from theme+group+port. |

### `PortLabelGeometry`

```ts
interface PortLabelGeometry
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `x` | `number` |  |  |
| `y` | `number` |  |  |
| `rotation` | `number` |  | Total rotation in degrees (0 when the label is horizontal). |
| `align` | `'start' \| 'middle' \| 'end'` |  |  |
| `valign` | `'top' \| 'middle' \| 'bottom'` |  |  |

### `PortLabelInput`

```ts
interface PortLabelInput
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `spec` | `PortLabelSpec` |  |  |
| `x` | `number` |  | Node-local anchor of the port's glyph. |
| `y` | `number` |  |  |
| `hw` | `number` |  | Half-extents of the glyph box — the label clears the glyph, not its centre. |
| `hh` | `number` |  |  |
| `side` | `'left' \| 'right' \| 'top' \| 'bottom'` |  | The port's side: the outward normal. |
| `width` | `number` |  | Node box, for the `radial` layout's centre and for `inside` clamping. |
| `height` | `number` |  |  |
| `nudge?` | `number` |  | Vertical nudge applied by collision resolution (see `nudgePortLabels`). |
| `fontSize` | `number` |  |  |
| `fontFamily?` | `string` |  |  |
| `color?` | `string` |  |  |
| `className?` | `string` |  |  |

### `PortLayoutInput`

```ts
interface PortLayoutInput
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `width` | `number` |  | Node-local box the ports live in. |
| `height` | `number` |  |  |
| `side` | `'left' \| 'right' \| 'top' \| 'bottom'` |  | The port's side (after group inheritance). |
| `rank` | `number` |  | This port's rank among the ports sharing its LAYOUT SCOPE, and the scope size. |
| `count` | `number` |  |  |
| `shapeType` | `string` |  | The node's shape type — the `shape` strategy needs it. |
| `rotation?` | `number` |  | The node's rotation in degrees (for `compensateRotation`). |

### `Rect`

```ts
interface Rect
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `x` | `number` |  |  |
| `y` | `number` |  |  |
| `width` | `number` |  |  |
| `height` | `number` |  |  |

### `RouteMemoStats`

```ts
interface RouteMemoStats
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `routed` | `number` |  | links whose route had to be computed this frame |
| `reused` | `number` |  | links served from the previous frame's route |

### `RouteSolverBridgeOptions`

```ts
interface RouteSolverBridgeOptions
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `port?` | `SolverPort` |  | A real Worker (or anything satisfying SolverPort). Omit to run the solver INLINE — same protocol, same code, same answers, just on this thread. The bridge does not construct a Worker itself: that would bake one bundler's URL scheme into the renderer, which is the mistake the old LayoutWorkerPool made. |
| `solver?` | `SolverOptions` |  |  |
| `onRoutesReady?` | `() => void` |  | "I have better routes than the ones you painted." Ask for a re-render. |

### `RouteSolverStats`

```ts
interface RouteSolverStats
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `submitted` | `number` |  |  |
| `applied` | `number` |  |  |
| `discarded` | `number` |  | answers thrown away because the world had moved on under them |
| `superseded` | `number` |  |  |

### `SelfLoopSpec`

```ts
interface SelfLoopSpec
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `rect` | `FanoutRect` |  | World rect of the node both ends live on. |
| `start` | `FanoutPoint` |  | Source attachment point (world, on the node outline). |
| `end` | `FanoutPoint` |  | Target attachment point (world, on the node outline). |
| `sourceSide` | `FanoutSide` |  |  |
| `targetSide` | `FanoutSide` |  |  |
| `size` | `number` |  | How far the loop bulges away from the node body (px). |
| `width` | `number` |  | Lateral span used when the two ends coincide (or nearly do). |

### `ShapePoint`

```ts
interface ShapePoint
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `x` | `number` |  |  |
| `y` | `number` |  |  |

### `ShapeRect`

Node bounding box in WORLD coordinates (used by boundaryPoint).

```ts
interface ShapeRect
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `x` | `number` |  |  |
| `y` | `number` |  |  |
| `w` | `number` |  |  |
| `h` | `number` |  |  |

### `SpotInput`

```ts
interface SpotInput
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `x` | `number` |  | World position of the port's anchor (its glyph centre). |
| `y` | `number` |  |  |
| `hw` | `number` |  | Glyph half-extents — a spot names a corner/edge of THIS box. |
| `hh` | `number` |  |  |
| `side` | `Side` |  | The port's side: the default direction, and the default spot. |
