@mica-js/core 0.0.1 → 0.1.1
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/LICENSE +21 -21
- package/README.md +431 -10
- package/dist/canvas/index.d.ts +38 -147
- package/dist/canvas/index.js +196 -153
- package/dist/canvas/index.js.map +1 -1
- package/dist/index.d.ts +445 -4
- package/dist/index.js +2432 -4
- package/dist/index.js.map +1 -1
- package/dist/schematic/index.d.ts +11 -10
- package/dist/schematic/index.js +3 -3
- package/dist/schematic/index.js.map +1 -1
- package/dist/{validate-COqYIMQg.js → validate-DuALfDe0.js} +5 -5
- package/dist/validate-DuALfDe0.js.map +1 -0
- package/package.json +9 -1
- package/dist/validate-COqYIMQg.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["samePoint"],"sources":["../../src/schematic/format/types.ts","../../src/schematic/device/reference.ts","../../src/schematic/format/parse-schematic.ts","../../src/schematic/format/serialize.ts","../../src/schematic/geometry/point.ts","../../src/schematic/geometry/transform.ts","../../src/schematic/topology/derive.ts","../../src/schematic/load/load.ts","../../src/schematic/device/properties.ts","../../src/schematic/edit/ids.ts","../../src/schematic/edit/commands.ts","../../src/schematic/edit/editor.ts","../../src/schematic/device/symbol.ts","../../src/schematic/edit/query.ts","../../src/schematic/edit/segment-drag.ts","../../src/schematic/edit/junctions.ts","../../src/schematic/edit/wires.ts","../../src/schematic/geometry/reroute.ts","../../src/schematic/edit/preview.ts","../../src/schematic/device/synthesis.ts","../../src/schematic/device/registry.ts","../../src/schematic/device/designator.ts"],"sourcesContent":["/**\n * Schema version of the `.sch` contract (see x-botlab/mica-js#6).\n *\n * 2D placement lives in the separate `.cnv` canvas contract (see x-botlab/mica-js#67 and\n * `@mica-js/core/canvas`).\n */\nexport const SCHEMATIC_VERSION = 1;\n\nexport type SchematicVersion = typeof SCHEMATIC_VERSION;\n\nexport interface Point {\n readonly x: number;\n readonly y: number;\n}\n\nexport interface Rect {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n}\n\nexport interface Placement {\n readonly x: number;\n readonly y: number;\n readonly rotation: number;\n}\n\n/** Where an image / binary property value lives (#7). */\nexport type AssetMode = 'file' | 'inline' | 'store';\n\n/**\n * Reference to a project asset instead of inline bytes (#7): `file` is a project-root relative\n * POSIX path, `inline` is base64 text and `store` is a host resource identifier.\n */\nexport interface AssetReference {\n readonly src: string;\n readonly mode: AssetMode;\n}\n\n/**\n * Instance property value stored in `symbol.properties` (see #6 / #7): a scalar, a resource\n * reference for `image` / `binary` properties, or `null` for an explicitly cleared nullable one.\n */\nexport type PropertyValue = string | number | boolean | AssetReference | null;\n\nexport interface SchematicSymbol extends Placement {\n /** Stable identity used by selections, undo and `.view` layout keys. */\n readonly id: string;\n readonly device: string;\n /** Instance property overrides; absent means \"use device defaults\". */\n readonly properties?: Readonly<Record<string, PropertyValue>>;\n /**\n * Reference designator of a component (`U1`, `R2`); defaults to {@link id}.\n * Only components carry one — the format rejects it elsewhere.\n */\n readonly designator?: string;\n /**\n * Net name of a net label, power or ground symbol (`VCC`, `N1`). It is the text drawn next to\n * the anchor and the key same-named ports merge on. Only net-naming symbols carry one.\n */\n readonly net?: string;\n /**\n * Reference designator anchor in symbol-local coordinates (unrotated, unplaced).\n * Absent means the default position at the body's top-left corner.\n */\n readonly reference?: Point;\n}\n\nexport interface SchematicWire {\n readonly id: string;\n readonly points: readonly Point[];\n}\n\nexport interface SchematicJunction {\n readonly id: string;\n readonly x: number;\n readonly y: number;\n readonly wires: readonly string[];\n}\n\nexport interface SchematicSheet {\n readonly symbols: readonly SchematicSymbol[];\n readonly wires: readonly SchematicWire[];\n readonly junctions: readonly SchematicJunction[];\n}\n\n/** Root of a `.sch` file; the file name is the schematic's identity. */\nexport interface SchematicDocument {\n readonly version: SchematicVersion;\n readonly sheet: SchematicSheet;\n}\n","export const LABEL_DEVICE = 'builtin:label';\nexport const POWER_DEVICE = 'builtin:power';\nexport const GROUND_DEVICE = 'builtin:ground';\n/** Free-standing annotation; it is not a connection point and never joins a net. */\nexport const TEXT_DEVICE = 'builtin:text';\nexport const RESERVED_PACKAGE_NAMESPACE = 'builtin';\n\n/** Builtin symbols recognised by the loader instead of the device registry. */\nexport type BuiltinSymbolKind = 'label' | 'power' | 'ground';\n\nconst BUILTIN_DEVICES: Readonly<Record<string, BuiltinSymbolKind>> = {\n [LABEL_DEVICE]: 'label',\n [POWER_DEVICE]: 'power',\n [GROUND_DEVICE]: 'ground',\n};\n\nexport const DEFAULT_POWER_LABEL = 'VCC';\nexport const DEFAULT_GROUND_LABEL = 'GND';\nexport const DEFAULT_TEXT_CONTENT = '文本';\n\nexport interface DeviceReference {\n readonly raw: string;\n readonly packageId: string;\n readonly deviceId: string;\n}\n\nconst PACKAGE_NAMESPACE_PATTERN = /^@[A-Za-z0-9][A-Za-z0-9._+-]*$/;\nconst PACKAGE_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]*$/;\nconst DEVICE_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]*$/;\n\n/**\n * Splits `<packageId>:<deviceId>`. Package ids follow npm conventions and may be scoped\n * (`@scope/name`); the device id uses a conservative identifier charset until #3 / #11 finalize it.\n */\nexport function parseDeviceReference(raw: string): DeviceReference | undefined {\n const separator = raw.indexOf(':');\n if (separator <= 0 || separator === raw.length - 1) {\n return undefined;\n }\n if (raw.indexOf(':', separator + 1) !== -1) {\n return undefined;\n }\n const packageId = raw.slice(0, separator);\n const deviceId = raw.slice(separator + 1);\n if (!isValidPackageId(packageId) || !DEVICE_ID_PATTERN.test(deviceId)) {\n return undefined;\n }\n return { raw, packageId, deviceId };\n}\n\nexport function isValidPackageId(packageId: string): boolean {\n if (packageId.startsWith('@')) {\n const parts = packageId.split('/');\n if (parts.length !== 2) {\n return false;\n }\n const [scope, name] = parts;\n return (\n scope !== undefined &&\n name !== undefined &&\n PACKAGE_NAMESPACE_PATTERN.test(scope) &&\n PACKAGE_NAME_PATTERN.test(name)\n );\n }\n return PACKAGE_NAME_PATTERN.test(packageId);\n}\n\n/** `builtin` is reserved for loader-provided symbols such as `builtin:label`. */\nexport function isReservedPackageId(packageId: string): boolean {\n return (\n packageId === RESERVED_PACKAGE_NAMESPACE ||\n packageId.startsWith(`${RESERVED_PACKAGE_NAMESPACE}/`)\n );\n}\n\nexport function isLabelDevice(raw: string): boolean {\n return raw === LABEL_DEVICE;\n}\n\n/** True for the free-standing text annotation (`builtin:text`). */\nexport function isTextDevice(raw: string): boolean {\n return raw === TEXT_DEVICE;\n}\n\n/** Text of a `builtin:text` symbol, falling back to a placeholder. */\nexport function textDeviceContent(symbol: {\n readonly properties?: Readonly<Record<string, unknown>>;\n}): string {\n const text = symbol.properties?.['text'];\n return typeof text === 'string' && text.length > 0 ? text : DEFAULT_TEXT_CONTENT;\n}\n\n/** Returns the builtin kind for `builtin:label` / `builtin:power` / `builtin:ground`. */\nexport function builtinSymbolKind(raw: string): BuiltinSymbolKind | undefined {\n return BUILTIN_DEVICES[raw];\n}\n\nexport function isBuiltinDevice(raw: string): boolean {\n return builtinSymbolKind(raw) !== undefined;\n}\n\n/** What a placed symbol is for: the single question the rest of the code asks about it. */\nexport type SymbolRole = 'component' | 'net-label' | 'power' | 'ground' | 'text';\n\n/** Role of a symbol, derived from its device reference; unknown devices are components. */\nexport function symbolRole(device: string): SymbolRole {\n switch (builtinSymbolKind(device)) {\n case 'label':\n return 'net-label';\n case 'power':\n return 'power';\n case 'ground':\n return 'ground';\n default:\n return isTextDevice(device) ? 'text' : 'component';\n }\n}\n\n/** Only components are annotated with a reference designator. */\nexport function hasDesignator(role: SymbolRole): boolean {\n return role === 'component';\n}\n\n/** Net labels, power and ground ports name the net they attach to. */\nexport function namesNet(role: SymbolRole): boolean {\n return role === 'net-label' || role === 'power' || role === 'ground';\n}\n\n/** Reference designator of a component; `undefined` for symbols that have none. */\nexport function designatorOf(symbol: {\n readonly id: string;\n readonly device: string;\n readonly designator?: string;\n}): string | undefined {\n return hasDesignator(symbolRole(symbol.device)) ? (symbol.designator ?? symbol.id) : undefined;\n}\n\n/** Net name of a label / power / ground symbol; `undefined` when the symbol names no net. */\nexport function netNameOf(symbol: {\n readonly device: string;\n readonly net?: string;\n}): string | undefined {\n switch (symbolRole(symbol.device)) {\n case 'power':\n return symbol.net ?? DEFAULT_POWER_LABEL;\n case 'ground':\n return symbol.net ?? DEFAULT_GROUND_LABEL;\n case 'net-label':\n return symbol.net;\n default:\n return undefined;\n }\n}\n\n/** Net name a freshly placed symbol of `role` gets when none is given. */\nexport function defaultNetName(role: SymbolRole): string | undefined {\n switch (role) {\n case 'power':\n return DEFAULT_POWER_LABEL;\n case 'ground':\n return DEFAULT_GROUND_LABEL;\n default:\n return undefined;\n }\n}\n\nexport function formatDeviceReference(packageId: string, deviceId: string): string {\n return `${packageId}:${deviceId}`;\n}\n","import type { Diagnostic } from './diagnostics';\nimport { SchematicError } from './errors';\nimport { parseInput } from './input';\nimport type {\n Point,\n SchematicDocument,\n SchematicJunction,\n SchematicSheet,\n SchematicSymbol,\n SchematicWire,\n} from './types';\nimport { SCHEMATIC_VERSION } from './types';\nimport {\n designatorOf,\n hasDesignator,\n namesNet,\n symbolRole,\n type SymbolRole,\n} from '../device/reference';\nimport {\n checkDuplicateIds,\n forbidUnknownFields,\n hasErrors,\n isRecord,\n readArrayField,\n readIntegerField,\n readNumberField,\n readObjectField,\n readPoint,\n readProperties,\n readStringField,\n report,\n type IdentifiedEntry,\n} from './validate';\n\n/** @throws {SchematicError} when the input does not match the `.sch` contract. */\nexport function parseSchematic(input: string | unknown): SchematicDocument {\n const diagnostics: Diagnostic[] = [];\n const parsed = parseInput(input, diagnostics);\n if (!parsed.ok) {\n throw new SchematicError(diagnostics);\n }\n const value = readDocument(parsed.value, diagnostics);\n if (value === undefined || hasErrors(diagnostics)) {\n throw new SchematicError(diagnostics);\n }\n return value;\n}\n\nfunction readDocument(value: unknown, diagnostics: Diagnostic[]): SchematicDocument | undefined {\n if (!isRecord(value)) {\n report(diagnostics, 'json/not-object', 'Schematic must be a JSON object.', []);\n return undefined;\n }\n forbidUnknownFields(value, ['version', 'sheet'], [], diagnostics);\n const version = readVersion(value, diagnostics);\n const sheet = readSheet(readObjectField(value, 'sheet', [], diagnostics), diagnostics);\n if (version === undefined || sheet === undefined) {\n return undefined;\n }\n return { version, sheet };\n}\n\nfunction readVersion(\n value: Record<string, unknown>,\n diagnostics: Diagnostic[],\n): typeof SCHEMATIC_VERSION | undefined {\n const version = readIntegerField(value, 'version', [], diagnostics);\n if (version === undefined) {\n return undefined;\n }\n if (version !== SCHEMATIC_VERSION) {\n report(\n diagnostics,\n 'schema/unsupported-version',\n `Unsupported version ${version}; expected ${SCHEMATIC_VERSION}.`,\n ['version'],\n );\n return undefined;\n }\n return SCHEMATIC_VERSION;\n}\n\nfunction readSheet(\n value: Record<string, unknown> | undefined,\n diagnostics: Diagnostic[],\n): SchematicSheet | undefined {\n if (value === undefined) {\n return undefined;\n }\n forbidUnknownFields(value, ['symbols', 'wires', 'junctions'], ['sheet'], diagnostics);\n const rawSymbols = readArrayField(value, 'symbols', ['sheet'], diagnostics) ?? [];\n const rawWires = readArrayField(value, 'wires', ['sheet'], diagnostics) ?? [];\n const rawJunctions = readArrayField(value, 'junctions', ['sheet'], diagnostics) ?? [];\n\n const symbols: SchematicSymbol[] = [];\n const symbolIds: IdentifiedEntry[] = [];\n rawSymbols.forEach((item, index) => {\n const path = ['sheet', 'symbols', String(index)];\n const symbol = readSymbol(item, path, diagnostics);\n if (symbol !== undefined) {\n symbols.push(symbol);\n symbolIds.push({ id: symbol.id, path: [...path, 'id'] });\n }\n });\n\n const wires: SchematicWire[] = [];\n const wireIds: IdentifiedEntry[] = [];\n rawWires.forEach((item, index) => {\n const path = ['sheet', 'wires', String(index)];\n const wire = readWire(item, path, diagnostics);\n if (wire !== undefined) {\n wires.push(wire);\n wireIds.push({ id: wire.id, path: [...path, 'id'] });\n }\n });\n\n const knownWireIds = new Set(wires.map((wire) => wire.id));\n const junctions: SchematicJunction[] = [];\n const junctionIds: IdentifiedEntry[] = [];\n rawJunctions.forEach((item, index) => {\n const path = ['sheet', 'junctions', String(index)];\n const junction = readJunction(item, path, diagnostics);\n if (junction === undefined) {\n return;\n }\n const seenWireIds = new Set<string>();\n junction.wires.forEach((wireId, wireIndex) => {\n const wirePath = [...path, 'wires', String(wireIndex)];\n if (seenWireIds.has(wireId)) {\n report(\n diagnostics,\n 'junction/duplicate-wire',\n `Junction \"${junction.id}\" references wire \"${wireId}\" more than once.`,\n wirePath,\n { kind: 'junction', id: junction.id },\n );\n } else {\n seenWireIds.add(wireId);\n }\n if (!knownWireIds.has(wireId)) {\n report(\n diagnostics,\n 'junction/unknown-wire',\n `Junction \"${junction.id}\" references unknown wire \"${wireId}\".`,\n wirePath,\n { kind: 'junction', id: junction.id },\n );\n }\n });\n junctions.push(junction);\n junctionIds.push({ id: junction.id, path: [...path, 'id'] });\n });\n\n checkDuplicateIds(symbolIds, 'symbol', diagnostics);\n checkDuplicateDesignators(symbols, diagnostics);\n checkDuplicateIds(wireIds, 'wire', diagnostics);\n checkDuplicateIds(junctionIds, 'junction', diagnostics);\n\n return { symbols, wires, junctions };\n}\n\n/** Two components must not share a reference designator. */\nfunction checkDuplicateDesignators(\n symbols: readonly SchematicSymbol[],\n diagnostics: Diagnostic[],\n): void {\n const seen = new Set<string>();\n symbols.forEach((symbol, index) => {\n const designator = designatorOf(symbol);\n if (designator === undefined) {\n return;\n }\n if (seen.has(designator)) {\n report(\n diagnostics,\n 'symbol/designator-duplicate',\n `Reference designator ${JSON.stringify(designator)} is used more than once.`,\n ['sheet', 'symbols', String(index), 'designator'],\n { kind: 'symbol', id: symbol.id },\n );\n return;\n }\n seen.add(designator);\n });\n}\n\nfunction readSymbol(\n value: unknown,\n path: readonly string[],\n diagnostics: Diagnostic[],\n): SchematicSymbol | undefined {\n if (!isRecord(value)) {\n report(diagnostics, 'schema/invalid-type', 'Symbol must be an object.', path);\n return undefined;\n }\n forbidUnknownFields(\n value,\n ['id', 'device', 'x', 'y', 'rotation', 'properties', 'designator', 'net', 'reference'],\n path,\n diagnostics,\n );\n const id = readStringField(value, 'id', path, diagnostics, { nonEmpty: true });\n const device = readStringField(value, 'device', path, diagnostics, { nonEmpty: true });\n const x = readNumberField(value, 'x', path, diagnostics);\n const y = readNumberField(value, 'y', path, diagnostics);\n const rotation = readNumberField(value, 'rotation', path, diagnostics);\n const properties =\n value['properties'] === undefined\n ? undefined\n : readProperties(value['properties'], [...path, 'properties'], diagnostics);\n const reference =\n value['reference'] === undefined\n ? undefined\n : readPoint(value['reference'], [...path, 'reference'], diagnostics);\n const designator = readRoleField(value, 'designator', device, path, diagnostics, hasDesignator);\n const net = readRoleField(value, 'net', device, path, diagnostics, namesNet);\n if (device !== undefined) {\n const role = symbolRole(device);\n if (namesNet(role) && net === undefined && value['net'] === undefined) {\n report(\n diagnostics,\n 'symbol/missing-net',\n `Symbols of role \"${role}\" must name the net they attach to.`,\n [...path, 'net'],\n );\n }\n if (!hasDesignator(role) && value['reference'] !== undefined) {\n report(\n diagnostics,\n 'symbol/unsupported-field',\n `Symbols of role \"${role}\" carry no reference designator.`,\n [...path, 'reference'],\n );\n }\n }\n if (\n id === undefined ||\n device === undefined ||\n x === undefined ||\n y === undefined ||\n rotation === undefined ||\n (value['reference'] !== undefined && reference === undefined)\n ) {\n return undefined;\n }\n return {\n id,\n device,\n x,\n y,\n rotation,\n ...(properties === undefined ? {} : { properties }),\n ...(designator === undefined ? {} : { designator }),\n ...(net === undefined ? {} : { net }),\n ...(reference === undefined ? {} : { reference }),\n };\n}\n\n/**\n * Reads a field that only some symbol roles may carry, so the format cannot describe a power\n * symbol with a reference designator or a resistor with a net name.\n */\nfunction readRoleField(\n value: Record<string, unknown>,\n field: 'designator' | 'net',\n device: string | undefined,\n path: readonly string[],\n diagnostics: Diagnostic[],\n allowed: (role: SymbolRole) => boolean,\n): string | undefined {\n const raw = value[field];\n if (raw === undefined || device === undefined) {\n return undefined;\n }\n const role = symbolRole(device);\n if (!allowed(role)) {\n report(\n diagnostics,\n 'symbol/unsupported-field',\n `Symbols of role \"${role}\" must not declare \"${field}\".`,\n [...path, field],\n );\n return undefined;\n }\n return readStringField(value, field, path, diagnostics, { nonEmpty: true });\n}\n\nfunction readWire(\n value: unknown,\n path: readonly string[],\n diagnostics: Diagnostic[],\n): SchematicWire | undefined {\n if (!isRecord(value)) {\n report(diagnostics, 'schema/invalid-type', 'Wire must be an object.', path);\n return undefined;\n }\n forbidUnknownFields(value, ['id', 'points'], path, diagnostics);\n const id = readStringField(value, 'id', path, diagnostics, { nonEmpty: true });\n const rawPoints = readArrayField(value, 'points', path, diagnostics);\n const points: Point[] = [];\n if (rawPoints !== undefined) {\n if (rawPoints.length < 2) {\n report(diagnostics, 'wire/invalid-points', 'Wire must contain at least two points.', [\n ...path,\n 'points',\n ]);\n }\n rawPoints.forEach((item, index) => {\n const point = readPoint(item, [...path, 'points', String(index)], diagnostics);\n if (point !== undefined) {\n points.push(point);\n }\n });\n }\n if (id === undefined || rawPoints === undefined) {\n return undefined;\n }\n for (let index = 1; index < points.length; index += 1) {\n const previous = points[index - 1];\n const current = points[index];\n if (previous === undefined || current === undefined) {\n continue;\n }\n if (previous.x !== current.x && previous.y !== current.y) {\n report(diagnostics, 'wire/not-orthogonal', 'Wire segments must be horizontal or vertical.', [\n ...path,\n 'points',\n String(index),\n ]);\n return undefined;\n }\n }\n return { id, points };\n}\n\nfunction readJunction(\n value: unknown,\n path: readonly string[],\n diagnostics: Diagnostic[],\n): SchematicJunction | undefined {\n if (!isRecord(value)) {\n report(diagnostics, 'schema/invalid-type', 'Junction must be an object.', path);\n return undefined;\n }\n forbidUnknownFields(value, ['id', 'x', 'y', 'wires'], path, diagnostics);\n const id = readStringField(value, 'id', path, diagnostics, { nonEmpty: true });\n const x = readNumberField(value, 'x', path, diagnostics);\n const y = readNumberField(value, 'y', path, diagnostics);\n const rawWires = readArrayField(value, 'wires', path, diagnostics);\n const wires: string[] = [];\n if (rawWires !== undefined) {\n if (rawWires.length < 2) {\n report(diagnostics, 'schema/invalid-value', 'Junction must reference at least two wires.', [\n ...path,\n 'wires',\n ]);\n }\n rawWires.forEach((item, index) => {\n const wirePath = [...path, 'wires', String(index)];\n if (typeof item !== 'string') {\n report(\n diagnostics,\n 'schema/invalid-type',\n 'Junction wire reference must be a string.',\n wirePath,\n );\n return;\n }\n if (item.length === 0) {\n report(\n diagnostics,\n 'schema/invalid-value',\n 'Junction wire reference must not be empty.',\n wirePath,\n );\n return;\n }\n wires.push(item);\n });\n }\n if (id === undefined || x === undefined || y === undefined || rawWires === undefined) {\n return undefined;\n }\n return { id, x, y, wires };\n}\n","import type { PropertyValue, SchematicDocument } from './types';\n\n/** Serializes with a fixed field order and 2-space indentation, matching the examples in #6. */\nexport function serializeSchematic(document: SchematicDocument): string {\n const serializable = {\n version: document.version,\n sheet: {\n symbols: document.sheet.symbols.map((symbol) => {\n const serialized: Record<string, unknown> = {\n id: symbol.id,\n device: symbol.device,\n x: symbol.x,\n y: symbol.y,\n rotation: symbol.rotation,\n };\n if (symbol.properties !== undefined && Object.keys(symbol.properties).length > 0) {\n serialized['properties'] = sortProperties(symbol.properties);\n }\n // Role-scoped fields are written explicitly so the file states what the symbol is for.\n if (symbol.designator !== undefined) {\n serialized['designator'] = symbol.designator;\n }\n if (symbol.net !== undefined) {\n serialized['net'] = symbol.net;\n }\n if (symbol.reference !== undefined) {\n serialized['reference'] = { x: symbol.reference.x, y: symbol.reference.y };\n }\n return serialized;\n }),\n wires: document.sheet.wires.map((wire) => ({\n id: wire.id,\n points: wire.points.map((point) => ({ x: point.x, y: point.y })),\n })),\n junctions: document.sheet.junctions.map((junction) => ({\n id: junction.id,\n x: junction.x,\n y: junction.y,\n wires: [...junction.wires],\n })),\n },\n };\n return `${JSON.stringify(serializable, null, 2)}\\n`;\n}\n\nfunction sortProperties(\n properties: Readonly<Record<string, PropertyValue>>,\n): Record<string, PropertyValue> {\n const sorted: Record<string, PropertyValue> = Object.create(null);\n for (const key of Object.keys(properties).sort()) {\n const value = properties[key];\n if (value !== undefined) {\n sorted[key] = value;\n }\n }\n return sorted;\n}\n","import type { Point, Rect } from '../format/types';\n\n/** Default comparison tolerance, in page units. */\nexport const DEFAULT_TOLERANCE = 0;\n\nexport function distance(a: Point, b: Point): number {\n return Math.hypot(b.x - a.x, b.y - a.y);\n}\n\nexport function samePoint(a: Point, b: Point): boolean {\n return a.x === b.x && a.y === b.y;\n}\n\nexport function pointsEqual(a: Point, b: Point, tolerance = DEFAULT_TOLERANCE): boolean {\n return distance(a, b) <= tolerance;\n}\n\n/** Closest point on the closed segment `a`–`b`, plus its position `t` in `[0, 1]`. */\nexport function projectOnSegment(\n point: Point,\n a: Point,\n b: Point,\n): { readonly x: number; readonly y: number; readonly t: number } {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const lengthSquared = dx * dx + dy * dy;\n if (lengthSquared === 0) {\n return { x: a.x, y: a.y, t: 0 };\n }\n const raw = ((point.x - a.x) * dx + (point.y - a.y) * dy) / lengthSquared;\n const t = raw < 0 ? 0 : raw > 1 ? 1 : raw;\n return { x: a.x + dx * t, y: a.y + dy * t, t };\n}\n\nexport interface SegmentProjection {\n /** Closest point of the polyline. */\n readonly point: Point;\n /** Index of the segment that holds the closest point. */\n readonly segment: number;\n /** Position along that segment, in `[0, 1]`. */\n readonly t: number;\n readonly distance: number;\n}\n\n/** Closest point on a polyline, with the segment it belongs to; `undefined` when empty. */\nexport function nearestPointOnPolyline(\n points: readonly Point[],\n point: Point,\n): SegmentProjection | undefined {\n let best: SegmentProjection | undefined;\n for (let index = 1; index < points.length; index += 1) {\n const a = points[index - 1];\n const b = points[index];\n if (a === undefined || b === undefined) {\n continue;\n }\n const projected = projectOnSegment(point, a, b);\n const candidate: SegmentProjection = {\n point: { x: projected.x, y: projected.y },\n segment: index - 1,\n t: projected.t,\n distance: distance(point, projected),\n };\n if (best === undefined || candidate.distance < best.distance) {\n best = candidate;\n }\n }\n const only = points[0];\n if (best === undefined && only !== undefined) {\n return { point: only, segment: 0, t: 0, distance: distance(point, only) };\n }\n return best;\n}\n\n/** Point at position `t` along segment `segment` of a polyline. */\nexport function pointOnPolylineAt(\n points: readonly Point[],\n segment: number,\n t: number,\n): Point | undefined {\n const a = points[segment];\n if (a === undefined) {\n return undefined;\n }\n const b = points[segment + 1] ?? a;\n return { x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t };\n}\n\n/** True when `point` lies on the closed segment `a`–`b`, within `tolerance`. */\nexport function pointOnSegment(\n point: Point,\n a: Point,\n b: Point,\n tolerance = DEFAULT_TOLERANCE,\n): boolean {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const length = Math.hypot(dx, dy);\n if (length === 0) {\n return pointsEqual(point, a, tolerance);\n }\n const area = (point.x - a.x) * dy - (point.y - a.y) * dx;\n if (Math.abs(area) / length > tolerance) {\n return false;\n }\n const projection = ((point.x - a.x) * dx + (point.y - a.y) * dy) / (length * length);\n const overhang = tolerance / length;\n if (projection < -overhang || projection > 1 + overhang) {\n return false;\n }\n return distanceToSegment(point, a, b) <= tolerance;\n}\n\nexport function distanceToSegment(point: Point, a: Point, b: Point): number {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const lengthSquared = dx * dx + dy * dy;\n if (lengthSquared === 0) {\n return distance(point, a);\n }\n const t = ((point.x - a.x) * dx + (point.y - a.y) * dy) / lengthSquared;\n const clamped = t < 0 ? 0 : t > 1 ? 1 : t;\n return distance(point, { x: a.x + clamped * dx, y: a.y + clamped * dy });\n}\n\n/** True when `point` lies on any segment of the polyline, endpoints included. */\nexport function pointOnPolyline(\n points: readonly Point[],\n point: Point,\n tolerance = DEFAULT_TOLERANCE,\n): boolean {\n if (points.length === 1) {\n const [only] = points;\n return only !== undefined && pointsEqual(only, point, tolerance);\n }\n for (let index = 1; index < points.length; index += 1) {\n const previous = points[index - 1];\n const current = points[index];\n if (\n previous !== undefined &&\n current !== undefined &&\n pointOnSegment(point, previous, current, tolerance)\n ) {\n return true;\n }\n }\n return false;\n}\n\nexport function boundsOfPoints(points: readonly Point[]): Rect | undefined {\n const [first, ...rest] = points;\n if (first === undefined) {\n return undefined;\n }\n let minX = first.x;\n let minY = first.y;\n let maxX = first.x;\n let maxY = first.y;\n for (const point of rest) {\n minX = Math.min(minX, point.x);\n minY = Math.min(minY, point.y);\n maxX = Math.max(maxX, point.x);\n maxY = Math.max(maxY, point.y);\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\nexport function unionBounds(a: Rect | undefined, b: Rect | undefined): Rect | undefined {\n if (a === undefined) {\n return b;\n }\n if (b === undefined) {\n return a;\n }\n const minX = Math.min(a.x, b.x);\n const minY = Math.min(a.y, b.y);\n const maxX = Math.max(a.x + a.width, b.x + b.width);\n const maxY = Math.max(a.y + a.height, b.y + b.height);\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n","import type { Placement, Point, Rect } from '../format/types';\nimport type { PinAnchor } from '../device/symbol';\nimport { boundsOfPoints } from './point';\n\n/** Rotates counter-clockwise around the origin. Rotation is expressed in degrees. */\nexport function rotatePoint(point: Point, degrees: number): Point {\n const radians = (degrees * Math.PI) / 180;\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n return {\n x: point.x * cos - point.y * sin,\n y: point.x * sin + point.y * cos,\n };\n}\n\n/** Applies a symbol placement to a pre-placement anchor. */\nexport function symbolPinPosition(placement: Placement, anchor: PinAnchor): Point {\n const rotated = rotatePoint(anchor, placement.rotation);\n return { x: placement.x + rotated.x, y: placement.y + rotated.y };\n}\n\n/** Distance between the reference default anchor and the body's top-left corner. */\nexport const REFERENCE_DEFAULT_OFFSET = 4;\n\n/**\n * Local anchor of a symbol's reference designator: the explicit override, else the body's\n * top-left corner lifted by {@link REFERENCE_DEFAULT_OFFSET}.\n */\nexport function referenceAnchor(outline: Rect | undefined, override?: Point): Point {\n if (override !== undefined) {\n return { x: override.x, y: override.y };\n }\n if (outline === undefined) {\n return { x: 0, y: -REFERENCE_DEFAULT_OFFSET };\n }\n return { x: outline.x, y: outline.y - REFERENCE_DEFAULT_OFFSET };\n}\n\n/** World position of a symbol's reference designator anchor. */\nexport function referencePosition(\n placement: Placement,\n outline: Rect | undefined,\n override?: Point,\n): Point {\n return symbolPinPosition(placement, referenceAnchor(outline, override));\n}\n\n/** Bounding box of a symbol: its transformed outline, else its pins, else its origin. */\nexport function symbolBounds(\n placement: Placement,\n outline: Rect | undefined,\n pins: Readonly<Record<string, PinAnchor>>,\n): Rect | undefined {\n if (outline !== undefined) {\n const corners: Point[] = [\n { x: outline.x, y: outline.y },\n { x: outline.x + outline.width, y: outline.y },\n { x: outline.x, y: outline.y + outline.height },\n { x: outline.x + outline.width, y: outline.y + outline.height },\n ];\n return boundsOfPoints(corners.map((corner) => symbolPinPosition(placement, corner)));\n }\n const anchors = Object.values(pins).map((anchor) => symbolPinPosition(placement, anchor));\n if (anchors.length > 0) {\n return boundsOfPoints(anchors);\n }\n return { x: placement.x, y: placement.y, width: 0, height: 0 };\n}\n","import type { Diagnostic } from '../format/diagnostics';\nimport { throwIfErrors } from '../format/errors';\nimport type { Point, Rect, SchematicDocument } from '../format/types';\nimport { builtinSymbolKind, netNameOf, parseDeviceReference } from '../device/reference';\nimport type { DeviceSymbolProvider } from '../device/symbol';\nimport {\n boundsOfPoints,\n pointOnPolyline,\n pointsEqual,\n unionBounds,\n DEFAULT_TOLERANCE,\n} from '../geometry/point';\nimport { symbolBounds, symbolPinPosition } from '../geometry/transform';\n\nexport interface SchematicPinInstance {\n readonly symbolId: string;\n readonly pinId: string;\n readonly position: Point;\n /** True when the pin is not connected to any wire, label or other pin. */\n readonly open: boolean;\n /** Name of the net the pin belongs to; `null` for anonymous nets. */\n readonly netName: string | null;\n}\n\nexport type SchematicNetMember =\n | { readonly kind: 'pin'; readonly symbolId: string; readonly pinId: string }\n | { readonly kind: 'label'; readonly symbolId: string }\n | { readonly kind: 'power'; readonly symbolId: string }\n | { readonly kind: 'ground'; readonly symbolId: string };\n\nexport interface SchematicNet {\n /** Name contributed by the single naming connection point; `null` when anonymous. */\n readonly name: string | null;\n readonly wireIds: readonly string[];\n readonly members: readonly SchematicNetMember[];\n}\n\nexport interface DanglingWireEnd {\n readonly wireId: string;\n readonly end: 'start' | 'end';\n readonly point: Point;\n}\n\nexport interface TopologyOptions {\n readonly devices?: DeviceSymbolProvider;\n /** Coordinate comparison tolerance in page units; defaults to exact matching. */\n readonly tolerance?: number;\n}\n\nexport interface SchematicTopology {\n readonly nets: readonly SchematicNet[];\n readonly pins: readonly SchematicPinInstance[];\n readonly danglingWireEnds: readonly DanglingWireEnd[];\n /** Bounding box of all wires, pins and symbol outlines. */\n readonly bounds: Rect | undefined;\n}\n\ntype Connection =\n | {\n readonly kind: 'pin';\n readonly symbolId: string;\n readonly pinId: string;\n readonly point: Point;\n }\n | {\n readonly kind: 'label' | 'power' | 'ground';\n readonly symbolId: string;\n readonly point: Point;\n /** Net name contributed by this connection point. */\n readonly name: string;\n };\n\n/**\n * Derives nets from wires, explicit junctions and symbol connection points (#6).\n *\n * @throws {SchematicError} when a device cannot be resolved or a net has conflicting labels.\n */\nexport function deriveSchematicTopology(\n document: SchematicDocument,\n options: TopologyOptions = {},\n): SchematicTopology {\n const diagnostics: Diagnostic[] = [];\n const tolerance = options.tolerance ?? DEFAULT_TOLERANCE;\n const { devices } = options;\n const { symbols, wires, junctions } = document.sheet;\n\n const connections: Connection[] = [];\n let bounds: Rect | undefined;\n\n for (const symbol of symbols) {\n bounds = unionBounds(bounds, { x: symbol.x, y: symbol.y, width: 0, height: 0 });\n const builtin = builtinSymbolKind(symbol.device);\n if (builtin !== undefined) {\n const net = netNameOf(symbol);\n if (net !== undefined) {\n connections.push({\n kind: builtin,\n symbolId: symbol.id,\n point: { x: symbol.x, y: symbol.y },\n name: net,\n });\n }\n continue;\n }\n\n const reference = parseDeviceReference(symbol.device);\n if (reference === undefined) {\n if (devices !== undefined) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-reference',\n message: `Symbol \"${symbol.id}\" has an invalid device reference ${JSON.stringify(symbol.device)}.`,\n entity: { kind: 'symbol', id: symbol.id },\n });\n }\n continue;\n }\n if (devices === undefined) {\n continue;\n }\n\n const definition = devices.getDeviceSymbol(reference);\n const name = devices.getDeviceName(reference);\n if (name === undefined) {\n diagnostics.push({\n severity: 'error',\n code: 'device/unresolved',\n message: `Symbol \"${symbol.id}\" references unresolved device ${JSON.stringify(symbol.device)}.`,\n entity: { kind: 'symbol', id: symbol.id },\n });\n continue;\n }\n if (definition === undefined) {\n continue;\n }\n\n bounds = unionBounds(bounds, symbolBounds(symbol, definition.bounds, definition.pins));\n for (const [pinId, anchor] of Object.entries(definition.pins)) {\n const position = symbolPinPosition(symbol, anchor);\n connections.push({ kind: 'pin', symbolId: symbol.id, pinId, point: position });\n bounds = unionBounds(bounds, { x: position.x, y: position.y, width: 0, height: 0 });\n }\n }\n\n for (const wire of wires) {\n bounds = unionBounds(bounds, boundsOfPoints(wire.points));\n }\n\n const wireIndex = new Map<string, number>();\n wires.forEach((wire, index) => wireIndex.set(wire.id, index));\n const wireCount = wires.length;\n const parent = new Array<number>(wireCount + connections.length);\n for (let index = 0; index < parent.length; index += 1) {\n parent[index] = index;\n }\n\n const find = (node: number): number => {\n let root = node;\n while (parent[root] !== root) {\n const next = parent[root] as number;\n parent[root] = parent[next] as number;\n root = next;\n }\n return root;\n };\n\n const union = (a: number, b: number): void => {\n const rootA = find(a);\n const rootB = find(b);\n if (rootA !== rootB) {\n parent[rootB] = rootA;\n }\n };\n\n for (const junction of junctions) {\n const targets = junction.wires\n .map((wireId) => wireIndex.get(wireId))\n .filter((index): index is number => index !== undefined);\n const [first, ...rest] = targets;\n if (first === undefined) {\n continue;\n }\n for (const target of rest) {\n union(first, target);\n }\n }\n\n /** Wire index → connection indexes attached to it. */\n const wireAttachments = new Map<number, number[]>();\n connections.forEach((connection, connectionIndex) => {\n wires.forEach((wire, index) => {\n if (!pointOnPolyline(wire.points, connection.point, tolerance)) {\n return;\n }\n union(index, wireCount + connectionIndex);\n const attached = wireAttachments.get(index);\n if (attached === undefined) {\n wireAttachments.set(index, [connectionIndex]);\n } else {\n attached.push(connectionIndex);\n }\n });\n });\n\n const groups = new Map<number, { wires: number[]; connections: number[] }>();\n const groupOf = (root: number): { wires: number[]; connections: number[] } => {\n const existing = groups.get(root);\n if (existing !== undefined) {\n return existing;\n }\n const created = { wires: [], connections: [] };\n groups.set(root, created);\n return created;\n };\n wires.forEach((_, index) => {\n groupOf(find(index)).wires.push(index);\n });\n connections.forEach((_, connectionIndex) => {\n groupOf(find(wireCount + connectionIndex)).connections.push(connectionIndex);\n });\n\n const netOfConnection = new Map<number, SchematicNet>();\n const nets: SchematicNet[] = [];\n for (const group of mergeGroupsByName(groups, connections, diagnostics)) {\n const connected = group.wires.length > 0 || group.connections.length >= 2;\n if (group.connections.length === 0 || !connected) {\n continue;\n }\n const name = group.name;\n\n const members: SchematicNetMember[] = group.connections\n .map((index) => connections[index])\n .map((connection): SchematicNetMember | undefined => {\n if (connection === undefined) {\n return undefined;\n }\n return connection.kind === 'pin'\n ? { kind: 'pin', symbolId: connection.symbolId, pinId: connection.pinId }\n : { kind: connection.kind, symbolId: connection.symbolId };\n })\n .filter((member): member is SchematicNetMember => member !== undefined)\n .sort(compareMembers);\n\n const net: SchematicNet = {\n name,\n wireIds: group.wires\n .map((index) => wires[index]?.id)\n .filter((id): id is string => id !== undefined)\n .sort(),\n members,\n };\n nets.push(net);\n for (const index of group.connections) {\n netOfConnection.set(index, net);\n }\n }\n\n const pins: SchematicPinInstance[] = [];\n connections.forEach((connection, index) => {\n if (connection.kind !== 'pin') {\n return;\n }\n const net = netOfConnection.get(index);\n pins.push({\n symbolId: connection.symbolId,\n pinId: connection.pinId,\n position: connection.point,\n open: net === undefined,\n netName: net?.name ?? null,\n });\n });\n pins.sort((a, b) => a.symbolId.localeCompare(b.symbolId) || a.pinId.localeCompare(b.pinId));\n\n const danglingWireEnds: DanglingWireEnd[] = [];\n wires.forEach((wire, index) => {\n const endpoints: readonly { end: 'start' | 'end'; point: Point | undefined }[] = [\n { end: 'start', point: wire.points[0] },\n { end: 'end', point: wire.points[wire.points.length - 1] },\n ];\n for (const { end, point } of endpoints) {\n if (point === undefined) {\n continue;\n }\n const attached = (wireAttachments.get(index) ?? []).some((connectionIndex) => {\n const connection = connections[connectionIndex];\n return connection !== undefined && pointsEqual(connection.point, point, tolerance);\n });\n const junctioned = junctions.some(\n (junction) =>\n junction.wires.includes(wire.id) &&\n pointsEqual({ x: junction.x, y: junction.y }, point, tolerance),\n );\n if (!attached && !junctioned) {\n danglingWireEnds.push({ wireId: wire.id, end, point });\n }\n }\n });\n danglingWireEnds.sort((a, b) => a.wireId.localeCompare(b.wireId) || a.end.localeCompare(b.end));\n\n throwIfErrors(diagnostics);\n\n return {\n nets: nets.sort(\n (a, b) => compareNetNames(a.name, b.name) || compareMembers(a.members[0], b.members[0]),\n ),\n pins,\n danglingWireEnds,\n bounds,\n };\n}\n\n/** A connected group of wires and connection points, named by the labels attached to it. */\ninterface NetGroup {\n readonly wires: number[];\n readonly connections: number[];\n readonly name: string | null;\n}\n\n/**\n * Folds groups that carry the same net name into one group: net names are the merge key, so two\n * `VCC` ports on separate wires are the same net (KiCad-style name-based connectivity).\n * A group that declares two different names is an error.\n */\nfunction mergeGroupsByName(\n groups: ReadonlyMap<number, { wires: number[]; connections: number[] }>,\n connections: readonly Connection[],\n diagnostics: Diagnostic[],\n): readonly NetGroup[] {\n const byName = new Map<string, { wires: number[]; connections: number[] }>();\n const merged: NetGroup[] = [];\n for (const group of groups.values()) {\n const names = group.connections\n .map((index) => connections[index])\n .filter(\n (connection): connection is Extract<Connection, { kind: 'label' | 'power' | 'ground' }> =>\n connection !== undefined && connection.kind !== 'pin',\n )\n .map((connection) => connection.name)\n .sort();\n if (names.length > 1) {\n diagnostics.push({\n severity: 'error',\n code: 'net/naming-conflict',\n message: `Net has conflicting names: ${names.map((item) => JSON.stringify(item)).join(', ')}.`,\n });\n }\n const name = names.length === 1 ? (names[0] as string) : null;\n // Only groups that already connect something are folded together: merging is about joining\n // nets, not about giving free-floating labels a net of their own.\n if (name === null || (group.wires.length === 0 && group.connections.length < 2)) {\n merged.push({ wires: group.wires, connections: group.connections, name });\n continue;\n }\n const existing = byName.get(name);\n if (existing === undefined) {\n const created = { wires: [...group.wires], connections: [...group.connections] };\n byName.set(name, created);\n merged.push({ ...created, name });\n continue;\n }\n existing.wires.push(...group.wires);\n existing.connections.push(...group.connections);\n }\n return merged;\n}\n\nconst KIND_ORDER: readonly SchematicNetMember['kind'][] = ['label', 'power', 'ground', 'pin'];\n\nfunction compareMembers(\n a: SchematicNetMember | undefined,\n b: SchematicNetMember | undefined,\n): number {\n if (a === undefined || b === undefined) {\n return a === undefined ? (b === undefined ? 0 : 1) : -1;\n }\n if (a.kind !== b.kind) {\n return KIND_ORDER.indexOf(a.kind) - KIND_ORDER.indexOf(b.kind);\n }\n const bySymbol = a.symbolId.localeCompare(b.symbolId);\n if (bySymbol !== 0) {\n return bySymbol;\n }\n const pinA = a.kind === 'pin' ? a.pinId : '';\n const pinB = b.kind === 'pin' ? b.pinId : '';\n return pinA.localeCompare(pinB);\n}\n\nfunction compareNetNames(a: string | null, b: string | null): number {\n if (a === null || b === null) {\n return a === null ? (b === null ? 0 : 1) : -1;\n }\n return a.localeCompare(b);\n}\n","import { parseSchematic } from '../format/parse-schematic';\nimport type { SchematicDocument } from '../format/types';\nimport {\n deriveSchematicTopology,\n type SchematicTopology,\n type TopologyOptions,\n} from '../topology/derive';\n\nexport type LoadSchematicOptions = TopologyOptions;\n\nexport interface LoadedSchematic {\n readonly document: SchematicDocument;\n readonly topology: SchematicTopology;\n}\n\n/** Parses a schematic and derives its topology. @throws {SchematicError} on any contract violation. */\nexport function loadSchematic(\n source: string | SchematicDocument,\n options: LoadSchematicOptions = {},\n): LoadedSchematic {\n const document = parseSchematic(source);\n return { document, topology: deriveSchematicTopology(document, options) };\n}\n","import { isAssetReference } from '../format/asset';\nimport type { PropertyValue } from '../format/types';\nimport { isRecord } from '../format/validate';\n\n/** Property value types a device may declare (#7). */\nexport const PROPERTY_TYPES = [\n 'string',\n 'integer',\n 'number',\n 'boolean',\n 'color',\n 'enum',\n 'image',\n 'binary',\n] as const;\n\nexport type PropertyType = (typeof PROPERTY_TYPES)[number];\n\nexport interface PropertyOption {\n readonly value: string;\n readonly label: string;\n}\n\n/**\n * Descriptor of one device property (#7). `default` is the declared default, `title` falls back to\n * the key, and the remaining fields carry the constraints of the type.\n */\nexport interface PropertyDescriptor {\n readonly key: string;\n readonly type: PropertyType;\n readonly title?: string;\n readonly description?: string;\n /** Declared default; absent when the description omits it or it breaks its own constraints. */\n readonly default?: PropertyValue;\n /** When true an explicit `null` is a valid instance value. */\n readonly nullable?: boolean;\n /** `string`: maximum length in Unicode code points. */\n readonly maxLength?: number;\n /** `integer` / `number`: closed lower bound. */\n readonly min?: number;\n /** `integer` / `number`: closed upper bound. */\n readonly max?: number;\n /** `number`: open lower bound; mutually exclusive with `min`. */\n readonly exclusiveMin?: number;\n /** `integer` / `number`: editing step, always greater than zero. */\n readonly step?: number;\n /** `number`: display unit of the stored value. */\n readonly unit?: string;\n /** `color`: whether `#RRGGBBAA` values are accepted. */\n readonly alpha?: boolean;\n /** `enum`: non-empty option list. */\n readonly options?: readonly PropertyOption[];\n /** `image` / `binary`: host-side payload limit in bytes. */\n readonly maxBytes?: number;\n /** `image`: host-side pixel limit. */\n readonly maxPixels?: number;\n}\n\nexport interface PropertyValueProblem {\n readonly code: 'schema/invalid-type' | 'schema/invalid-value';\n readonly message: string;\n}\n\nconst COLOR_PATTERN = /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;\n\nexport function isPropertyType(value: unknown): value is PropertyType {\n return typeof value === 'string' && (PROPERTY_TYPES as readonly string[]).includes(value);\n}\n\n/** Uppercases a `#RRGGBB` / `#RRGGBBAA` color; `undefined` when the text is not a color. */\nexport function normalizeColor(value: string): string | undefined {\n return COLOR_PATTERN.test(value) ? value.toUpperCase() : undefined;\n}\n\n/** Parses one declared property; `undefined` when the type is unknown or the descriptor unusable. */\nexport function parsePropertyDescriptor(key: string, raw: unknown): PropertyDescriptor | undefined {\n if (!isRecord(raw)) {\n return undefined;\n }\n const type = raw['type'];\n if (!isPropertyType(type)) {\n return undefined;\n }\n const draft: {\n -readonly [K in keyof PropertyDescriptor]: PropertyDescriptor[K];\n } = { key, type };\n\n const title = readText(raw['title']);\n if (title !== undefined) {\n draft.title = title;\n }\n const description = readText(raw['description']);\n if (description !== undefined) {\n draft.description = description;\n }\n if (raw['nullable'] === true) {\n draft.nullable = true;\n }\n\n if (type === 'string') {\n const maxLength = readCount(raw['maxLength']);\n if (maxLength !== undefined) {\n draft.maxLength = maxLength;\n }\n }\n if (type === 'integer' || type === 'number') {\n const min = readFinite(raw['min']);\n if (min !== undefined) {\n draft.min = min;\n }\n const max = readFinite(raw['max']);\n if (max !== undefined) {\n draft.max = max;\n }\n const step = readFinite(raw['step']);\n if (step !== undefined && step > 0) {\n draft.step = step;\n }\n if (type === 'number') {\n const exclusiveMin = readFinite(raw['exclusiveMin']);\n if (exclusiveMin !== undefined) {\n draft.exclusiveMin = exclusiveMin;\n }\n const unit = readText(raw['unit']);\n if (unit !== undefined) {\n draft.unit = unit;\n }\n }\n }\n if (type === 'color' && raw['alpha'] === true) {\n draft.alpha = true;\n }\n if (type === 'enum') {\n const options = readOptions(raw['options']);\n if (options === undefined) {\n return undefined;\n }\n draft.options = options;\n }\n if (type === 'image' || type === 'binary') {\n const maxBytes = readCount(raw['maxBytes']);\n if (maxBytes !== undefined) {\n draft.maxBytes = maxBytes;\n }\n if (type === 'image') {\n const maxPixels = readCount(raw['maxPixels']);\n if (maxPixels !== undefined) {\n draft.maxPixels = maxPixels;\n }\n }\n }\n\n const defaultValue = raw['default'];\n if (defaultValue !== undefined && propertyValueProblem(draft, defaultValue) === undefined) {\n draft.default = defaultValue as PropertyValue;\n }\n return draft;\n}\n\n/** Parses the `properties` object of a device description, skipping unusable declarations. */\nexport function readPropertyDescriptors(raw: unknown): ReadonlyMap<string, PropertyDescriptor> {\n const descriptors = new Map<string, PropertyDescriptor>();\n if (!isRecord(raw)) {\n return descriptors;\n }\n for (const [key, value] of Object.entries(raw)) {\n if (key.length === 0) {\n continue;\n }\n const descriptor = parsePropertyDescriptor(key, value);\n if (descriptor !== undefined) {\n descriptors.set(key, descriptor);\n }\n }\n return descriptors;\n}\n\n/** Constraint violation of `value` for `descriptor`; `undefined` when the value is acceptable. */\nexport function propertyValueProblem(\n descriptor: PropertyDescriptor,\n value: unknown,\n): PropertyValueProblem | undefined {\n const key = descriptor.key;\n if (value === null) {\n return descriptor.nullable === true\n ? undefined\n : { code: 'schema/invalid-value', message: `Property \"${key}\" is not nullable.` };\n }\n switch (descriptor.type) {\n case 'string': {\n if (typeof value !== 'string') {\n return { code: 'schema/invalid-type', message: `Property \"${key}\" must be a string.` };\n }\n const maxLength = descriptor.maxLength;\n if (maxLength !== undefined && [...value].length > maxLength) {\n return {\n code: 'schema/invalid-value',\n message: `Property \"${key}\" must be at most ${String(maxLength)} characters.`,\n };\n }\n return undefined;\n }\n case 'integer': {\n if (typeof value !== 'number' || !Number.isSafeInteger(value)) {\n return {\n code: 'schema/invalid-type',\n message: `Property \"${key}\" must be a safe integer.`,\n };\n }\n return boundProblem(descriptor, value);\n }\n case 'number': {\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n return {\n code: 'schema/invalid-type',\n message: `Property \"${key}\" must be a finite number.`,\n };\n }\n if (descriptor.exclusiveMin !== undefined && value <= descriptor.exclusiveMin) {\n return {\n code: 'schema/invalid-value',\n message: `Property \"${key}\" must be greater than ${String(descriptor.exclusiveMin)}.`,\n };\n }\n return boundProblem(descriptor, value);\n }\n case 'boolean':\n return typeof value === 'boolean'\n ? undefined\n : { code: 'schema/invalid-type', message: `Property \"${key}\" must be a boolean.` };\n case 'color': {\n if (typeof value !== 'string') {\n return { code: 'schema/invalid-type', message: `Property \"${key}\" must be a string.` };\n }\n const normalized = normalizeColor(value);\n if (normalized === undefined) {\n return {\n code: 'schema/invalid-value',\n message: `Property \"${key}\" must be a \"#RRGGBB\" color.`,\n };\n }\n if (descriptor.alpha !== true && normalized.length === 9) {\n return {\n code: 'schema/invalid-value',\n message: `Property \"${key}\" does not accept alpha; use \"#RRGGBB\".`,\n };\n }\n return undefined;\n }\n case 'enum': {\n if (typeof value !== 'string') {\n return { code: 'schema/invalid-type', message: `Property \"${key}\" must be a string.` };\n }\n const allowed = (descriptor.options ?? []).map((option) => option.value);\n return allowed.includes(value)\n ? undefined\n : {\n code: 'schema/invalid-value',\n message: `Property \"${key}\" must be one of ${allowed.map((entry) => JSON.stringify(entry)).join(', ')}.`,\n };\n }\n case 'image':\n case 'binary':\n return isAssetReference(value)\n ? undefined\n : {\n code: 'schema/invalid-type',\n message: `Property \"${key}\" must be a resource reference { \"src\", \"mode\" }.`,\n };\n }\n}\n\n/** Canonical stored value: colors are uppercased, everything else is stored as given. */\nexport function normalizePropertyValue(\n descriptor: PropertyDescriptor,\n value: PropertyValue,\n): PropertyValue {\n if (descriptor.type === 'color' && typeof value === 'string') {\n return normalizeColor(value) ?? value;\n }\n return value;\n}\n\nfunction boundProblem(\n descriptor: PropertyDescriptor,\n value: number,\n): PropertyValueProblem | undefined {\n const key = descriptor.key;\n if (descriptor.min !== undefined && value < descriptor.min) {\n return {\n code: 'schema/invalid-value',\n message: `Property \"${key}\" must be at least ${String(descriptor.min)}.`,\n };\n }\n if (descriptor.max !== undefined && value > descriptor.max) {\n return {\n code: 'schema/invalid-value',\n message: `Property \"${key}\" must be at most ${String(descriptor.max)}.`,\n };\n }\n return undefined;\n}\n\nfunction readText(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nfunction readFinite(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\nfunction readCount(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 ? value : undefined;\n}\n\nfunction readOptions(value: unknown): readonly PropertyOption[] | undefined {\n if (!Array.isArray(value) || value.length === 0) {\n return undefined;\n }\n const options: PropertyOption[] = [];\n const seen = new Set<string>();\n for (const entry of value) {\n if (!isRecord(entry)) {\n return undefined;\n }\n const optionValue = entry['value'];\n const label = entry['label'];\n if (\n typeof optionValue !== 'string' ||\n optionValue.length === 0 ||\n typeof label !== 'string' ||\n label.length === 0 ||\n seen.has(optionValue)\n ) {\n return undefined;\n }\n seen.add(optionValue);\n options.push({ value: optionValue, label });\n }\n return options;\n}\n","import type { SchematicDocument } from '../format/types';\n\nexport type ElementKind = 'symbol' | 'wire' | 'junction';\n\nexport type ElementIdFactory = (kind: ElementKind, document: SchematicDocument) => string;\n\nfunction usedIds(document: SchematicDocument, kind: ElementKind): ReadonlySet<string> {\n const ids =\n kind === 'symbol'\n ? document.sheet.symbols.map((symbol) => symbol.id)\n : kind === 'wire'\n ? document.sheet.wires.map((wire) => wire.id)\n : document.sheet.junctions.map((junction) => junction.id);\n return new Set(ids);\n}\n\n/**\n * Random UUID v4, falling back to `getRandomValues` (or `Math.random` in ancient runtimes).\n * Ids are opaque identity: they never collide with the designators and net names users edit.\n */\nexport function createUuid(): string {\n const source = randomSource();\n if (typeof source?.randomUUID === 'function') {\n return source.randomUUID();\n }\n const bytes = new Uint8Array(16);\n if (typeof source?.getRandomValues === 'function') {\n source.getRandomValues(bytes);\n } else {\n for (let index = 0; index < bytes.length; index += 1) {\n bytes[index] = Math.floor(Math.random() * 256);\n }\n }\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;\n const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('');\n return [\n hex.slice(0, 8),\n hex.slice(8, 12),\n hex.slice(12, 16),\n hex.slice(16, 20),\n hex.slice(20),\n ].join('-');\n}\n\n/** Web Crypto as available in browsers and Node; core does not depend on either's typings. */\ninterface RandomSource {\n randomUUID?: () => string;\n getRandomValues?: (array: Uint8Array) => Uint8Array;\n}\n\nfunction randomSource(): RandomSource | undefined {\n return (globalThis as { crypto?: RandomSource }).crypto;\n}\n\n/** Fresh UUID v4 that no element of `kind` uses yet. */\nexport const defaultElementIdFactory: ElementIdFactory = (kind, document) => {\n const used = usedIds(document, kind);\n let id = createUuid();\n while (used.has(id)) {\n id = createUuid();\n }\n return id;\n};\n","import { isAssetReference } from '../format/asset';\nimport type { Diagnostic } from '../format/diagnostics';\nimport { throwIfErrors } from '../format/errors';\nimport { parseSchematic } from '../format/parse-schematic';\nimport type {\n Point,\n PropertyValue,\n SchematicDocument,\n SchematicJunction,\n SchematicSymbol,\n SchematicWire,\n} from '../format/types';\nimport { toPointer } from '../format/validate';\nimport {\n normalizePropertyValue,\n propertyValueProblem,\n type PropertyDescriptor,\n} from '../device/properties';\nimport { parseDeviceReference } from '../device/reference';\nimport { defaultNetName, hasDesignator, namesNet, symbolRole } from '../device/reference';\nimport type { SymbolRole } from '../device/reference';\nimport type { TopologyOptions } from '../topology/derive';\nimport { DEFAULT_TOLERANCE, pointOnPolyline } from '../geometry/point';\nimport { defaultElementIdFactory, type ElementIdFactory } from './ids';\n\nexport type SchematicCommand =\n | {\n readonly type: 'add-symbol';\n readonly id?: string;\n readonly device: string;\n readonly x: number;\n readonly y: number;\n readonly rotation?: number;\n readonly properties?: Readonly<Record<string, PropertyValue>>;\n /** Component reference designator; defaults to the new symbol's id. */\n readonly designator?: string;\n /** Net name for labels / power / ground; power and ground fall back to VCC / GND. */\n readonly net?: string;\n /** Reference designator anchor in symbol-local coordinates; `null` clears it. */\n readonly reference?: Point | null;\n }\n | {\n readonly type: 'update-symbol';\n readonly id: string;\n readonly device?: string;\n readonly x?: number;\n readonly y?: number;\n readonly rotation?: number;\n /** Replaces the whole property map when provided. */\n readonly properties?: Readonly<Record<string, PropertyValue>>;\n /** Reference designator; `null` clears the override, `undefined` keeps it. */\n readonly designator?: string | null;\n /** Net name; `null` clears it, `undefined` keeps it. */\n readonly net?: string | null;\n /** Reference designator anchor; `null` clears it, `undefined` keeps it. */\n readonly reference?: Point | null;\n }\n | { readonly type: 'remove-symbol'; readonly id: string }\n | {\n readonly type: 'set-symbol-property';\n readonly id: string;\n readonly key: string;\n readonly value: PropertyValue;\n }\n | { readonly type: 'remove-symbol-property'; readonly id: string; readonly key: string }\n | { readonly type: 'add-wire'; readonly id?: string; readonly points: readonly Point[] }\n | { readonly type: 'set-wire-points'; readonly id: string; readonly points: readonly Point[] }\n | { readonly type: 'remove-wire'; readonly id: string }\n | {\n readonly type: 'add-junction';\n readonly id?: string;\n readonly x: number;\n readonly y: number;\n readonly wires: readonly string[];\n }\n | {\n readonly type: 'update-junction';\n readonly id: string;\n readonly x?: number;\n readonly y?: number;\n readonly wires?: readonly string[];\n }\n | { readonly type: 'remove-junction'; readonly id: string };\n\nexport interface EditEffect {\n readonly kind: 'junction-removed';\n readonly id: string;\n readonly reason: 'wire-removed' | 'junction-detached';\n}\n\nexport interface SchematicEditOptions extends TopologyOptions {\n readonly createId?: ElementIdFactory;\n /** How to handle junctions that stop lying on a wire after its geometry changes. */\n readonly onJunctionConflict?: 'reject' | 'remove';\n /** Receives cascaded removals such as junctions dropped with their wire. */\n readonly onEffect?: (effect: EditEffect) => void;\n}\n\n/**\n * Applies an edit command to a copy of `document`.\n *\n * @throws {SchematicError} when the command is invalid; the input document is never mutated.\n */\nexport function applySchematicCommand(\n document: SchematicDocument,\n command: SchematicCommand,\n options: SchematicEditOptions = {},\n): SchematicDocument {\n const symbols = [...document.sheet.symbols];\n const wires = [...document.sheet.wires];\n const junctions = [...document.sheet.junctions];\n const diagnostics: Diagnostic[] = [];\n const effects: EditEffect[] = [];\n const createId = options.createId ?? defaultElementIdFactory;\n const draft = (): SchematicDocument => ({ ...document, sheet: { symbols, wires, junctions } });\n\n switch (command.type) {\n case 'add-symbol': {\n const device = requireDevice(command.device, diagnostics);\n const id = command.id ?? createId('symbol', draft());\n const properties = normalizeProperties(\n command.properties,\n deviceDescriptors(device, options),\n diagnostics,\n );\n const reference = resolveReference(\n command.reference,\n undefined,\n ['sheet', 'symbols'],\n diagnostics,\n );\n if (device !== undefined) {\n const role = symbolRole(device);\n const designator = resolveDesignator(command.designator, role, id, diagnostics);\n const net = resolveNet(command.net, role, diagnostics);\n symbols.push(\n withProperties(\n {\n id,\n device,\n x: command.x,\n y: command.y,\n rotation: command.rotation ?? 0,\n ...(designator === undefined ? {} : { designator }),\n ...(net === undefined ? {} : { net }),\n ...(hasDesignator(role) && reference !== undefined ? { reference } : {}),\n },\n properties,\n ),\n );\n }\n break;\n }\n case 'update-symbol': {\n const index = findIndex(symbols, command.id, 'symbol', diagnostics);\n const current = index === -1 ? undefined : symbols[index];\n if (current !== undefined) {\n const device =\n command.device === undefined\n ? current.device\n : requireDevice(command.device, diagnostics);\n const properties =\n command.properties === undefined\n ? current.properties\n : normalizeProperties(\n command.properties,\n deviceDescriptors(device, options),\n diagnostics,\n );\n const reference = resolveReference(\n command.reference,\n current.reference,\n ['sheet', 'symbols', String(index)],\n diagnostics,\n );\n if (device !== undefined) {\n const role = symbolRole(device);\n const designator = resolveOptionalText(\n command.designator,\n current.designator,\n hasDesignator(role),\n 'designator',\n diagnostics,\n );\n const net = resolveOptionalText(\n command.net,\n current.net,\n namesNet(role),\n 'net',\n diagnostics,\n );\n symbols[index] = withProperties(\n {\n id: current.id,\n device,\n x: command.x ?? current.x,\n y: command.y ?? current.y,\n rotation: command.rotation ?? current.rotation,\n ...(designator === undefined ? {} : { designator }),\n ...(net === undefined ? {} : { net }),\n ...(hasDesignator(role) && reference !== undefined ? { reference } : {}),\n },\n properties,\n );\n }\n }\n break;\n }\n case 'remove-symbol': {\n const index = findIndex(symbols, command.id, 'symbol', diagnostics);\n if (index !== -1) {\n symbols.splice(index, 1);\n }\n break;\n }\n case 'set-symbol-property': {\n const index = findIndex(symbols, command.id, 'symbol', diagnostics);\n const current = index === -1 ? undefined : symbols[index];\n if (current !== undefined) {\n const value = checkPropertyValue(\n command.key,\n command.value,\n deviceDescriptors(current.device, options)?.get(command.key),\n diagnostics,\n );\n if (value !== undefined) {\n symbols[index] = withProperties(baseOf(current), {\n ...(current.properties ?? {}),\n [command.key]: value,\n });\n }\n }\n break;\n }\n case 'remove-symbol-property': {\n const index = findIndex(symbols, command.id, 'symbol', diagnostics);\n const current = index === -1 ? undefined : symbols[index];\n if (current !== undefined) {\n const properties = { ...(current.properties ?? {}) };\n if (!Object.prototype.hasOwnProperty.call(properties, command.key)) {\n diagnostics.push({\n severity: 'error',\n code: 'edit/unknown-entity',\n message: `Symbol \"${current.id}\" has no property ${JSON.stringify(command.key)}.`,\n entity: { kind: 'symbol', id: current.id },\n });\n } else {\n delete properties[command.key];\n symbols[index] = withProperties(baseOf(current), properties);\n }\n }\n break;\n }\n case 'add-wire': {\n const id = command.id ?? createId('wire', draft());\n const wire = makeWire(id, command.points, diagnostics);\n if (wire !== undefined) {\n wires.push(wire);\n }\n break;\n }\n case 'set-wire-points': {\n const index = findIndex(wires, command.id, 'wire', diagnostics);\n if (index !== -1) {\n const wire = makeWire(command.id, command.points, diagnostics);\n if (wire !== undefined) {\n wires[index] = wire;\n }\n }\n break;\n }\n case 'remove-wire': {\n const index = findIndex(wires, command.id, 'wire', diagnostics);\n if (index !== -1) {\n wires.splice(index, 1);\n for (let junctionIndex = junctions.length - 1; junctionIndex >= 0; junctionIndex -= 1) {\n const junction = junctions[junctionIndex];\n if (junction === undefined || !junction.wires.includes(command.id)) {\n continue;\n }\n effects.push({ kind: 'junction-removed', id: junction.id, reason: 'wire-removed' });\n junctions.splice(junctionIndex, 1);\n }\n }\n break;\n }\n case 'add-junction': {\n const id = command.id ?? createId('junction', draft());\n const junction = makeJunction(id, command.x, command.y, command.wires, diagnostics);\n if (junction !== undefined) {\n junctions.push(junction);\n }\n break;\n }\n case 'update-junction': {\n const index = findIndex(junctions, command.id, 'junction', diagnostics);\n const current = index === -1 ? undefined : junctions[index];\n if (current !== undefined) {\n const junction = makeJunction(\n current.id,\n command.x ?? current.x,\n command.y ?? current.y,\n command.wires ?? current.wires,\n diagnostics,\n );\n if (junction !== undefined) {\n junctions[index] = junction;\n }\n }\n break;\n }\n case 'remove-junction': {\n const index = findIndex(junctions, command.id, 'junction', diagnostics);\n if (index !== -1) {\n junctions.splice(index, 1);\n }\n break;\n }\n default: {\n diagnostics.push({\n severity: 'error',\n code: 'edit/invalid-command',\n message: `Unsupported command ${JSON.stringify((command as { type?: unknown }).type)}.`,\n });\n }\n }\n\n throwIfErrors(diagnostics);\n\n const result = validateSheet(draft(), options, diagnostics, effects);\n throwIfErrors(diagnostics);\n\n for (const effect of effects) {\n options.onEffect?.(effect);\n }\n return result;\n}\n\nfunction validateSheet(\n candidate: SchematicDocument,\n options: SchematicEditOptions,\n diagnostics: Diagnostic[],\n effects: EditEffect[],\n): SchematicDocument {\n // Structural re-validation: ids, required fields, wire point counts, junction references.\n const parsed = parseSchematic(candidate);\n const tolerance = options.tolerance ?? DEFAULT_TOLERANCE;\n const wireById = new Map(parsed.sheet.wires.map((wire) => [wire.id, wire]));\n const survivingJunctions: SchematicJunction[] = [];\n let cascaded = false;\n\n for (const junction of parsed.sheet.junctions) {\n const detached = junction.wires.some((wireId) => {\n const wire = wireById.get(wireId);\n return (\n wire === undefined ||\n !pointOnPolyline(wire.points, { x: junction.x, y: junction.y }, tolerance)\n );\n });\n if (!detached) {\n survivingJunctions.push(junction);\n continue;\n }\n if (options.onJunctionConflict === 'remove') {\n cascaded = true;\n effects.push({ kind: 'junction-removed', id: junction.id, reason: 'junction-detached' });\n continue;\n }\n diagnostics.push({\n severity: 'error',\n code: 'junction/off-wire',\n message: `Junction \"${junction.id}\" no longer lies on every referenced wire.`,\n pointer: toPointer(['sheet', 'junctions']),\n entity: { kind: 'junction', id: junction.id },\n });\n }\n\n if (!cascaded) {\n return parsed;\n }\n return { ...parsed, sheet: { ...parsed.sheet, junctions: survivingJunctions } };\n}\n\nfunction makeWire(\n id: string,\n points: readonly Point[],\n diagnostics: Diagnostic[],\n): SchematicWire | undefined {\n if (points.length < 2) {\n diagnostics.push({\n severity: 'error',\n code: 'wire/invalid-points',\n message: `Wire \"${id}\" must contain at least two points.`,\n entity: { kind: 'wire', id },\n });\n return undefined;\n }\n return { id, points: points.map((point) => ({ x: point.x, y: point.y })) };\n}\n\nfunction makeJunction(\n id: string,\n x: number,\n y: number,\n wires: readonly string[],\n diagnostics: Diagnostic[],\n): SchematicJunction | undefined {\n if (wires.length < 2) {\n diagnostics.push({\n severity: 'error',\n code: 'schema/invalid-value',\n message: `Junction \"${id}\" must reference at least two wires.`,\n entity: { kind: 'junction', id },\n });\n return undefined;\n }\n return { id, x, y, wires: [...wires] };\n}\n\nfunction requireDevice(device: string, diagnostics: Diagnostic[]): string | undefined {\n if (parseDeviceReference(device) === undefined) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-reference',\n message: `Invalid device reference ${JSON.stringify(device)}.`,\n });\n return undefined;\n }\n return device;\n}\n\nfunction baseOf(symbol: SchematicSymbol): Omit<SchematicSymbol, 'properties' | 'reference'> {\n return {\n id: symbol.id,\n device: symbol.device,\n x: symbol.x,\n y: symbol.y,\n rotation: symbol.rotation,\n ...(symbol.designator === undefined ? {} : { designator: symbol.designator }),\n ...(symbol.net === undefined ? {} : { net: symbol.net }),\n };\n}\n\n/**\n * Reference designator for a new symbol: components keep `undefined` (the id doubles as the\n * default designator), everything else must not have one.\n */\nfunction resolveDesignator(\n value: string | undefined,\n role: SymbolRole,\n id: string,\n diagnostics: Diagnostic[],\n): string | undefined {\n if (!hasDesignator(role)) {\n if (value !== undefined) {\n diagnostics.push({\n severity: 'error',\n code: 'symbol/unsupported-field',\n message: `Symbols of role \"${role}\" carry no reference designator.`,\n });\n }\n return undefined;\n }\n const trimmed = value?.trim();\n return trimmed === undefined || trimmed.length === 0 || trimmed === id ? undefined : trimmed;\n}\n\n/** Net name for a new symbol; labels need one, power and ground fall back to their default. */\nfunction resolveNet(\n value: string | undefined,\n role: SymbolRole,\n diagnostics: Diagnostic[],\n): string | undefined {\n if (!namesNet(role)) {\n if (value !== undefined) {\n diagnostics.push({\n severity: 'error',\n code: 'symbol/unsupported-field',\n message: `Symbols of role \"${role}\" name no net.`,\n });\n }\n return undefined;\n }\n const trimmed = value?.trim();\n if (trimmed !== undefined && trimmed.length > 0) {\n return trimmed;\n }\n const fallback = defaultNetName(role);\n if (fallback === undefined) {\n diagnostics.push({\n severity: 'error',\n code: 'symbol/missing-net',\n message: `Symbols of role \"${role}\" must name the net they attach to.`,\n });\n }\n return fallback;\n}\n\n/** `null` clears the field, `undefined` keeps it, and unsupported roles cannot set it. */\nfunction resolveOptionalText(\n value: string | null | undefined,\n current: string | undefined,\n supported: boolean,\n field: 'designator' | 'net',\n diagnostics: Diagnostic[],\n): string | undefined {\n if (value === undefined) {\n return current;\n }\n if (!supported) {\n diagnostics.push({\n severity: 'error',\n code: 'symbol/unsupported-field',\n message: `This symbol must not declare \"${field}\".`,\n });\n return undefined;\n }\n if (value === null) {\n return undefined;\n }\n const trimmed = value.trim();\n if (trimmed.length === 0) {\n diagnostics.push({\n severity: 'error',\n code: 'schema/invalid-value',\n message: `${field === 'net' ? 'Net name' : 'Reference designator'} must not be empty.`,\n });\n return undefined;\n }\n return trimmed;\n}\n\nfunction withProperties(\n symbol: Omit<SchematicSymbol, 'properties'>,\n properties: Readonly<Record<string, PropertyValue>> | undefined,\n): SchematicSymbol {\n if (properties === undefined || Object.keys(properties).length === 0) {\n return symbol;\n }\n return { ...symbol, properties };\n}\n\n/** `reference: null` clears the override and falls back to the default anchor. */\nfunction resolveReference(\n value: Point | null | undefined,\n current: Point | undefined,\n path: readonly string[],\n diagnostics: Diagnostic[],\n): Point | undefined {\n if (value === undefined) {\n return current;\n }\n if (value === null) {\n return undefined;\n }\n if (typeof value !== 'object' || !Number.isFinite(value.x) || !Number.isFinite(value.y)) {\n diagnostics.push({\n severity: 'error',\n code: 'schema/invalid-value',\n message: 'Symbol reference must contain finite x and y numbers.',\n pointer: toPointer([...path, 'reference']),\n });\n return undefined;\n }\n return { x: value.x, y: value.y };\n}\n\n/** Property descriptors of `device`, when the caller supplied a device registry (#7). */\nfunction deviceDescriptors(\n device: string | undefined,\n options: SchematicEditOptions,\n): ReadonlyMap<string, PropertyDescriptor> | undefined {\n const reference = device === undefined ? undefined : parseDeviceReference(device);\n return reference === undefined\n ? undefined\n : options.devices?.getDevicePropertyDescriptors?.(reference);\n}\n\nfunction normalizeProperties(\n properties: Readonly<Record<string, PropertyValue>> | undefined,\n descriptors: ReadonlyMap<string, PropertyDescriptor> | undefined,\n diagnostics: Diagnostic[],\n): Readonly<Record<string, PropertyValue>> | undefined {\n if (properties === undefined) {\n return undefined;\n }\n const normalized: Record<string, PropertyValue> = {};\n for (const [key, value] of Object.entries(properties)) {\n if (key.length === 0) {\n diagnostics.push({\n severity: 'error',\n code: 'schema/invalid-value',\n message: 'Property keys must not be empty.',\n });\n continue;\n }\n const checked = checkPropertyValue(key, value, descriptors?.get(key), diagnostics);\n if (checked !== undefined) {\n normalized[key] = checked;\n }\n }\n return normalized;\n}\n\nfunction checkPropertyValue(\n key: string,\n value: PropertyValue,\n descriptor: PropertyDescriptor | undefined,\n diagnostics: Diagnostic[],\n): PropertyValue | undefined {\n if (key.length === 0) {\n diagnostics.push({\n severity: 'error',\n code: 'schema/invalid-value',\n message: 'Property keys must not be empty.',\n });\n return undefined;\n }\n if (descriptor !== undefined) {\n const problem = propertyValueProblem(descriptor, value);\n if (problem !== undefined) {\n diagnostics.push({ severity: 'error', code: problem.code, message: problem.message });\n return undefined;\n }\n return normalizePropertyValue(descriptor, value);\n }\n if (typeof value === 'string' || typeof value === 'boolean' || value === null) {\n return value;\n }\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) {\n diagnostics.push({\n severity: 'error',\n code: 'schema/invalid-value',\n message: `Property \"${key}\" must be a finite number.`,\n });\n return undefined;\n }\n return value;\n }\n if (isAssetReference(value)) {\n return value;\n }\n diagnostics.push({\n severity: 'error',\n code: 'schema/invalid-value',\n message: `Property \"${key}\" must be a string, finite number, boolean, resource reference or null.`,\n });\n return undefined;\n}\n\nfunction findIndex<T extends { readonly id: string }>(\n items: readonly T[],\n id: string,\n kind: 'symbol' | 'wire' | 'junction',\n diagnostics: Diagnostic[],\n): number {\n const index = items.findIndex((item) => item.id === id);\n if (index === -1) {\n diagnostics.push({\n severity: 'error',\n code: 'edit/unknown-entity',\n message: `Unknown ${kind} \"${id}\".`,\n entity: { kind, id },\n });\n }\n return index;\n}\n","import type { SchematicDocument } from '../format/types';\nimport { parseSchematic } from '../format/parse-schematic';\nimport { pointOnPolyline } from '../geometry/point';\nimport { serializeSchematic } from '../format/serialize';\nimport { deriveSchematicTopology, type SchematicTopology } from '../topology/derive';\nimport {\n applySchematicCommand,\n type SchematicCommand,\n type SchematicEditOptions,\n} from './commands';\n\nexport interface SchematicEditorOptions extends SchematicEditOptions {\n /** Maximum number of undo steps kept; defaults to 200. */\n readonly historyLimit?: number;\n}\n\nconst DEFAULT_HISTORY_LIMIT = 200;\n\n/**\n * Stateful editor over a schematic document with undo/redo.\n * Every mutation goes through {@link applySchematicCommand}; failures leave the state untouched.\n */\nexport class SchematicEditor {\n readonly #options: SchematicEditorOptions;\n readonly #historyLimit: number;\n #past: SchematicDocument[] = [];\n #future: SchematicDocument[] = [];\n #document: SchematicDocument;\n #depth = 0;\n\n constructor(document: SchematicDocument, options: SchematicEditorOptions = {}) {\n this.#document = document;\n this.#options = options;\n this.#historyLimit = options.historyLimit ?? DEFAULT_HISTORY_LIMIT;\n }\n\n get document(): SchematicDocument {\n return this.#document;\n }\n\n get canUndo(): boolean {\n return this.#past.length > 0;\n }\n\n get canRedo(): boolean {\n return this.#future.length > 0;\n }\n\n /** @throws {SchematicError} leaving the current document and history untouched. */\n dispatch(command: SchematicCommand): void {\n const next = applySchematicCommand(this.#document, command, this.#options);\n this.#record(next);\n }\n\n /**\n * Records an already-derived document (for example a wire split) as one history step.\n * Junctions that no longer lie on their wires are dropped, keeping the document consistent.\n *\n * @throws {SchematicError} when the document is invalid; the state stays untouched.\n */\n replace(document: SchematicDocument): void {\n const parsed = parseSchematic(document);\n const tolerance = this.#options.tolerance ?? 0;\n const wireById = new Map(parsed.sheet.wires.map((wire) => [wire.id, wire]));\n const junctions = parsed.sheet.junctions.filter((junction) =>\n junction.wires.every((wireId) => {\n const wire = wireById.get(wireId);\n return (\n wire !== undefined &&\n pointOnPolyline(wire.points, { x: junction.x, y: junction.y }, tolerance)\n );\n }),\n );\n this.#record(\n junctions.length === parsed.sheet.junctions.length\n ? parsed\n : { ...parsed, sheet: { ...parsed.sheet, junctions } },\n );\n }\n\n /** Applies several edits atomically; a failure rolls back every command in the block. */\n transaction(edit: (editor: SchematicEditor) => void): void {\n if (this.#depth > 0) {\n edit(this);\n return;\n }\n const document = this.#document;\n const future = this.#future;\n this.#past.push(document);\n this.#future = [];\n this.#depth = 1;\n try {\n edit(this);\n } catch (error) {\n this.#document = document;\n this.#past.pop();\n this.#future = future;\n throw error;\n } finally {\n this.#depth = 0;\n }\n if (this.#document === document) {\n this.#past.pop();\n this.#future = future;\n return;\n }\n this.#trimHistory();\n }\n\n undo(): void {\n const previous = this.#past.pop();\n if (previous === undefined) {\n return;\n }\n if (this.#depth === 0) {\n this.#future.push(this.#document);\n }\n this.#document = previous;\n }\n\n redo(): void {\n const next = this.#future.pop();\n if (next === undefined) {\n return;\n }\n if (this.#depth === 0) {\n this.#past.push(this.#document);\n }\n this.#document = next;\n }\n\n topology(): SchematicTopology {\n return deriveSchematicTopology(this.#document, this.#options);\n }\n\n toJSON(): string {\n return serializeSchematic(this.#document);\n }\n\n #record(next: SchematicDocument): void {\n const previous = this.#document;\n this.#document = next;\n if (this.#depth > 0) {\n return;\n }\n this.#past.push(previous);\n this.#future = [];\n this.#trimHistory();\n }\n\n #trimHistory(): void {\n if (this.#past.length > this.#historyLimit) {\n this.#past.shift();\n }\n }\n}\n","import type { Rect } from '../format/types';\nimport type { PropertyDescriptor } from './properties';\nimport type { DeviceReference } from './reference';\n\n/** Side of the symbol body a pin is drawn on; controls stub direction and label placement. */\nexport type PinSide = 'left' | 'right' | 'top' | 'bottom';\n\nexport interface PinAnchor {\n /** Connection point (outer end of the pin stub) in symbol space. */\n readonly x: number;\n readonly y: number;\n /** Side the pin is displayed on; inferred from the position when omitted. */\n readonly side?: PinSide;\n}\n\nexport interface DeviceSymbolDefinition {\n /** Name rendered at the centre of the symbol. */\n readonly name: string;\n /** Pin id to pre-placement anchor coordinate in symbol space. */\n readonly pins: Readonly<Record<string, PinAnchor>>;\n /** Optional outline used by the editor to draw the symbol body. */\n readonly bounds?: Rect;\n}\n\nexport interface DeviceSymbolGeometry {\n /** Placement-independent geometry, as provided by the device description. */\n readonly name?: string;\n readonly pins: Readonly<Record<string, PinAnchor>>;\n readonly bounds?: Rect;\n}\n\nexport interface DeviceSymbolProvider {\n /** Symbol geometry; `undefined` when the device is unknown or has no geometry. */\n getDeviceSymbol(reference: DeviceReference): DeviceSymbolDefinition | undefined;\n /** Name rendered on the symbol: the symbol name, else the display name. `undefined` when unknown. */\n getDeviceName(reference: DeviceReference): string | undefined;\n /**\n * Reference-designator prefix the device declares (`U`, `R`, `DS`, …); `undefined` when the\n * provider does not describe one, in which case placement falls back to the global default.\n */\n getDeviceDesignatorPrefix?(reference: DeviceReference): string | undefined;\n /**\n * Property descriptors the device declares (#7); `undefined` when the provider does not describe\n * them, in which case property editing is restricted to structural validation only.\n */\n getDevicePropertyDescriptors?(\n reference: DeviceReference,\n ): ReadonlyMap<string, PropertyDescriptor> | undefined;\n}\n\n/** Bounding box of a device's pins; `undefined` when it declares none. */\nexport function pinsBounds(pins: Readonly<Record<string, PinAnchor>>): Rect | undefined {\n const points = Object.values(pins);\n if (points.length === 0) {\n return undefined;\n }\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n for (const point of points) {\n minX = Math.min(minX, point.x);\n minY = Math.min(minY, point.y);\n maxX = Math.max(maxX, point.x);\n maxY = Math.max(maxY, point.y);\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\n/** Side a pin is drawn on: its declared side, else the closest edge of the body outline. */\nexport function pinSide(pin: PinAnchor, outline: Rect | undefined): PinSide | undefined {\n if (pin.side !== undefined) {\n return pin.side;\n }\n if (outline === undefined) {\n return undefined;\n }\n const dx = (pin.x - (outline.x + outline.width / 2)) / Math.max(outline.width / 2, 1e-6);\n const dy = (pin.y - (outline.y + outline.height / 2)) / Math.max(outline.height / 2, 1e-6);\n if (Math.abs(dx) >= Math.abs(dy)) {\n return dx >= 0 ? 'right' : 'left';\n }\n return dy >= 0 ? 'bottom' : 'top';\n}\n\n/**\n * Inner end of a pin stub, where it meets the body outline. Together with the anchor it forms the\n * grabbable pin: rendering draws that line and hit testing accepts clicks anywhere along it.\n */\nexport function pinStubEnd(\n body: Rect,\n anchor: { readonly x: number; readonly y: number },\n side: PinSide,\n): { readonly x: number; readonly y: number } {\n switch (side) {\n case 'left':\n return { x: body.x, y: anchor.y };\n case 'right':\n return { x: body.x + body.width, y: anchor.y };\n case 'top':\n return { x: anchor.x, y: body.y };\n case 'bottom':\n return { x: anchor.x, y: body.y + body.height };\n }\n}\n","import type { Point, Rect, SchematicDocument } from '../format/types';\nimport {\n GROUND_DEVICE,\n POWER_DEVICE,\n designatorOf,\n hasDesignator,\n isLabelDevice,\n isTextDevice,\n netNameOf,\n parseDeviceReference,\n symbolRole,\n textDeviceContent,\n} from '../device/reference';\nimport type { DeviceSymbolProvider } from '../device/symbol';\nimport { pinSide, pinStubEnd, pinsBounds } from '../device/symbol';\nimport {\n DEFAULT_TOLERANCE,\n distanceToSegment,\n pointOnPolyline,\n pointsEqual,\n} from '../geometry/point';\nimport {\n referencePosition,\n rotatePoint,\n symbolBounds,\n symbolPinPosition,\n} from '../geometry/transform';\n\nexport interface HitTestOptions {\n readonly devices?: DeviceSymbolProvider;\n /** Coordinate comparison tolerance in page units; defaults to exact matching. */\n readonly tolerance?: number;\n /** Include symbol bodies in the hit search; defaults to true. */\n readonly includeSymbols?: boolean;\n}\n\nexport type SchematicHit =\n | { readonly kind: 'reference'; readonly symbolId: string }\n | { readonly kind: 'junction'; readonly id: string }\n | { readonly kind: 'pin'; readonly symbolId: string; readonly pinId: string }\n | { readonly kind: 'wire'; readonly id: string; readonly segment: number }\n | { readonly kind: 'symbol'; readonly id: string };\n\n/**\n * Returns the topmost element at `point`: reference labels, junctions, pins, wires, then\n * symbol bodies.\n */\nexport function hitTestSchematic(\n document: SchematicDocument,\n point: Point,\n options: HitTestOptions = {},\n): SchematicHit | undefined {\n const tolerance = options.tolerance ?? DEFAULT_TOLERANCE;\n const includeSymbols = options.includeSymbols ?? true;\n\n const reference = referenceHit(document, point, options, tolerance);\n if (reference !== undefined) {\n return reference;\n }\n\n const junctions = [...document.sheet.junctions].sort((a, b) => a.id.localeCompare(b.id));\n for (const junction of junctions) {\n if (pointsEqual({ x: junction.x, y: junction.y }, point, tolerance)) {\n return { kind: 'junction', id: junction.id };\n }\n }\n\n if (options.devices !== undefined) {\n const symbols = [...document.sheet.symbols]\n .filter((symbol) => !isLabelDevice(symbol.device))\n .sort((a, b) => a.id.localeCompare(b.id));\n for (const symbol of symbols) {\n const reference = parseDeviceReference(symbol.device);\n const definition =\n reference === undefined ? undefined : options.devices.getDeviceSymbol(reference);\n if (definition === undefined) {\n continue;\n }\n const body = definition.bounds ??\n pinsBounds(definition.pins) ?? { x: -12, y: -12, width: 24, height: 24 };\n const pinIds = Object.keys(definition.pins).sort();\n for (const pinId of pinIds) {\n const anchor = definition.pins[pinId];\n if (anchor === undefined) {\n continue;\n }\n const end = symbolPinPosition(symbol, anchor);\n if (pointsEqual(end, point, tolerance)) {\n return { kind: 'pin', symbolId: symbol.id, pinId };\n }\n // The whole pin stub is grabbable, so clicking the drawn pin starts a wire at its end.\n const side = pinSide(anchor, body);\n if (side === undefined) {\n continue;\n }\n const start = symbolPinPosition(symbol, pinStubEnd(body, anchor, side));\n if (distanceToSegment(point, start, end) <= tolerance) {\n return { kind: 'pin', symbolId: symbol.id, pinId };\n }\n }\n }\n }\n\n const wires = [...document.sheet.wires].sort((a, b) => a.id.localeCompare(b.id));\n for (const wire of wires) {\n for (let index = 1; index < wire.points.length; index += 1) {\n const previous = wire.points[index - 1];\n const current = wire.points[index];\n if (\n previous !== undefined &&\n current !== undefined &&\n distanceToSegment(point, previous, current) <= tolerance\n ) {\n return { kind: 'wire', id: wire.id, segment: index - 1 };\n }\n }\n }\n\n if (!includeSymbols) {\n return undefined;\n }\n\n const symbols = [...document.sheet.symbols].sort((a, b) => a.id.localeCompare(b.id));\n for (const symbol of symbols) {\n const reference = parseDeviceReference(symbol.device);\n const definition =\n reference === undefined ? undefined : options.devices?.getDeviceSymbol(reference);\n const bounds =\n definition === undefined\n ? annotationBounds(symbol)\n : symbolBounds(symbol, definition.bounds, definition.pins);\n if (bounds === undefined) {\n continue;\n }\n const inside =\n point.x >= bounds.x - tolerance &&\n point.x <= bounds.x + bounds.width + tolerance &&\n point.y >= bounds.y - tolerance &&\n point.y <= bounds.y + bounds.height + tolerance;\n if (inside) {\n return { kind: 'symbol', id: symbol.id };\n }\n }\n\n return undefined;\n}\n\n/** Approximate clickable box for symbols without device geometry (labels, text annotations). */\nfunction annotationBounds(symbol: {\n readonly id: string;\n readonly device: string;\n readonly x: number;\n readonly y: number;\n readonly rotation: number;\n readonly net?: string;\n readonly properties?: Readonly<Record<string, unknown>>;\n}): Rect {\n const device = symbol.device;\n if (device === POWER_DEVICE) {\n // Stem, bar and the label above them.\n return rotatedBounds(symbol, {\n x: -POWER_HALF_WIDTH,\n y: -POWER_HEIGHT,\n width: POWER_HALF_WIDTH * 2,\n height: POWER_HEIGHT + ANNOTATION_HEIGHT / 2,\n });\n }\n if (device === GROUND_DEVICE) {\n // Stem, the three bars and the label below them.\n return rotatedBounds(symbol, {\n x: -POWER_HALF_WIDTH,\n y: -ANNOTATION_HEIGHT / 2,\n width: POWER_HALF_WIDTH * 2,\n height: GROUND_HEIGHT,\n });\n }\n const content = isTextDevice(device)\n ? textDeviceContent(symbol)\n : isLabelDevice(device)\n ? (netNameOf(symbol) ?? '')\n : '';\n if (content.length === 0) {\n return { x: symbol.x, y: symbol.y, width: 0, height: 0 };\n }\n const height = ANNOTATION_HEIGHT;\n // Labels anchor at their connection point (left edge); text is drawn from its origin too.\n return rotatedBounds(symbol, {\n x: 0,\n y: -height / 2,\n width: content.length * ANNOTATION_CHAR_WIDTH,\n height,\n });\n}\n\n/** Axis-aligned box of a symbol-local rectangle after applying the symbol's rotation. */\nfunction rotatedBounds(\n symbol: { readonly x: number; readonly y: number; readonly rotation: number },\n local: Rect,\n): Rect {\n if (symbol.rotation % 360 === 0) {\n return {\n x: symbol.x + local.x,\n y: symbol.y + local.y,\n width: local.width,\n height: local.height,\n };\n }\n const corners = [\n { x: local.x, y: local.y },\n { x: local.x + local.width, y: local.y },\n { x: local.x, y: local.y + local.height },\n { x: local.x + local.width, y: local.y + local.height },\n ].map((corner) => {\n const rotated = rotatePoint(corner, symbol.rotation);\n return { x: symbol.x + rotated.x, y: symbol.y + rotated.y };\n });\n const xs = corners.map((corner) => corner.x);\n const ys = corners.map((corner) => corner.y);\n const minX = Math.min(...xs);\n const minY = Math.min(...ys);\n return { x: minX, y: minY, width: Math.max(...xs) - minX, height: Math.max(...ys) - minY };\n}\n\nconst ANNOTATION_CHAR_WIDTH = 6;\nconst ANNOTATION_HEIGHT = 12;\n/** Half width of the power/ground glyph box. */\nconst POWER_HALF_WIDTH = 10;\n/** How far the power symbol (stem + bar + label) reaches above its anchor. */\nconst POWER_HEIGHT = 24;\n/** How far the ground symbol (stem + bars + label) reaches below its anchor. */\nconst GROUND_HEIGHT = 30;\n\n/** Hit box of a reference designator, positioned like the renderer draws it. */\nfunction referenceHit(\n document: SchematicDocument,\n point: Point,\n options: HitTestOptions,\n tolerance: number,\n): SchematicHit | undefined {\n const symbols = [...document.sheet.symbols]\n .filter((symbol) => hasDesignator(symbolRole(symbol.device)))\n .sort((a, b) => a.id.localeCompare(b.id));\n for (const symbol of symbols) {\n const reference = parseDeviceReference(symbol.device);\n const definition =\n reference === undefined ? undefined : options.devices?.getDeviceSymbol(reference);\n if (definition === undefined) {\n continue;\n }\n const designator = designatorOf(symbol) ?? symbol.id;\n const anchor = referencePosition(symbol, definition.bounds, symbol.reference);\n const width = designator.length * ANNOTATION_CHAR_WIDTH;\n const box: Rect = {\n x: anchor.x,\n y: anchor.y - ANNOTATION_HEIGHT,\n width,\n height: ANNOTATION_HEIGHT,\n };\n const inside =\n point.x >= box.x - tolerance &&\n point.x <= box.x + box.width + tolerance &&\n point.y >= box.y - tolerance &&\n point.y <= box.y + box.height + tolerance;\n if (inside) {\n return { kind: 'reference', symbolId: symbol.id };\n }\n }\n return undefined;\n}\n\nexport interface JunctionCandidate {\n readonly point: Point;\n readonly wireIds: readonly string[];\n}\nexport interface JunctionCandidateOptions {\n readonly tolerance?: number;\n}\n\n/**\n * Finds positions where wires touch or cross without an explicit junction (#6 requires junctions\n * to be created by the user). Existing junctions are excluded.\n */\nexport function findJunctionCandidates(\n document: SchematicDocument,\n options: JunctionCandidateOptions = {},\n): readonly JunctionCandidate[] {\n const tolerance = options.tolerance ?? DEFAULT_TOLERANCE;\n const wires = [...document.sheet.wires].sort((a, b) => a.id.localeCompare(b.id));\n const existing = document.sheet.junctions;\n const candidates: { point: Point; wireIds: Set<string> }[] = [];\n\n const add = (point: Point, wireId: string): void => {\n // Points within tolerance describe the same junction handle, so they are merged.\n const entry = candidates.find((candidate) => pointsEqual(candidate.point, point, tolerance));\n if (entry === undefined) {\n candidates.push({ point: { x: point.x, y: point.y }, wireIds: new Set([wireId]) });\n return;\n }\n entry.wireIds.add(wireId);\n };\n\n for (let left = 0; left < wires.length; left += 1) {\n const first = wires[left];\n if (first === undefined) {\n continue;\n }\n for (let right = left + 1; right < wires.length; right += 1) {\n const second = wires[right];\n if (second === undefined) {\n continue;\n }\n const points: Point[] = [...intersections(first.points, second.points, tolerance)];\n const firstPoints = [...first.points];\n const secondPoints = [...second.points];\n for (const point of firstPoints) {\n if (pointOnPolyline(secondPoints, point, tolerance)) {\n points.push(point);\n }\n }\n for (const point of secondPoints) {\n if (pointOnPolyline(firstPoints, point, tolerance)) {\n points.push(point);\n }\n }\n for (const point of points) {\n add(point, first.id);\n add(point, second.id);\n }\n }\n }\n\n const result: JunctionCandidate[] = [];\n for (const candidate of candidates) {\n if (candidate.wireIds.size < 2) {\n continue;\n }\n const wireIds = [...candidate.wireIds].sort();\n const covered = existing.some(\n (junction) =>\n pointsEqual({ x: junction.x, y: junction.y }, candidate.point, tolerance) &&\n wireIds.every((wireId) => junction.wires.includes(wireId)),\n );\n if (!covered) {\n result.push({ point: candidate.point, wireIds });\n }\n }\n\n return result.sort(\n (a, b) =>\n a.point.x - b.point.x ||\n a.point.y - b.point.y ||\n a.wireIds.join(',').localeCompare(b.wireIds.join(',')),\n );\n}\n\n/** Segment–segment intersection points in the closed-segment sense, within `tolerance`. */\nfunction* intersections(\n first: readonly Point[],\n second: readonly Point[],\n tolerance: number,\n): Generator<Point> {\n for (let a = 1; a < first.length; a += 1) {\n const a1 = first[a - 1];\n const a2 = first[a];\n if (a1 === undefined || a2 === undefined) {\n continue;\n }\n for (let b = 1; b < second.length; b += 1) {\n const b1 = second[b - 1];\n const b2 = second[b];\n if (b1 === undefined || b2 === undefined) {\n continue;\n }\n const point = segmentIntersection(a1, a2, b1, b2, tolerance);\n if (point !== undefined) {\n yield point;\n }\n }\n }\n}\n\nfunction segmentIntersection(\n a1: Point,\n a2: Point,\n b1: Point,\n b2: Point,\n tolerance: number,\n): Point | undefined {\n const r = { x: a2.x - a1.x, y: a2.y - a1.y };\n const s = { x: b2.x - b1.x, y: b2.y - b1.y };\n const denominator = r.x * s.y - r.y * s.x;\n const qp = { x: b1.x - a1.x, y: b1.y - a1.y };\n if (Math.abs(denominator) < Number.EPSILON) {\n // Parallel or collinear: overlap points are covered by the endpoint checks in the caller.\n return undefined;\n }\n const t = (qp.x * s.y - qp.y * s.x) / denominator;\n const u = (qp.x * r.y - qp.y * r.x) / denominator;\n const slackT = tolerance === 0 ? 0 : tolerance / Math.hypot(r.x, r.y);\n const slackU = tolerance === 0 ? 0 : tolerance / Math.hypot(s.x, s.y);\n if (t < -slackT || t > 1 + slackT || u < -slackU || u > 1 + slackU) {\n return undefined;\n }\n return { x: a1.x + t * r.x, y: a1.y + t * r.y };\n}\n","import { parseDeviceReference, symbolRole } from '../device/reference';\nimport type { DeviceSymbolProvider } from '../device/symbol';\nimport type { Point, SchematicDocument, SchematicWire } from '../format/types';\nimport { symbolPinPosition } from '../geometry/transform';\n\nexport interface SegmentDragOptions {\n readonly devices?: DeviceSymbolProvider;\n}\n\n/**\n * Wire points produced by sliding one segment by `delta` along its normal.\n *\n * The whole run of segments parallel to the dragged one moves along, so no neighbour is left\n * diagonal. Where that run ends at a pin, an anchor, a junction or another wire, the vertex stays\n * put and the wire gains a dogleg. Pure geometry: the caller decides how to apply it.\n */\nexport function planSegmentDrag(\n document: SchematicDocument,\n wireId: string,\n segment: number,\n delta: Point,\n options: SegmentDragOptions = {},\n): readonly Point[] | undefined {\n const wire = document.sheet.wires.find((candidate) => candidate.id === wireId);\n return wire === undefined\n ? undefined\n : planWireSegmentDrag(document, wire, segment, delta, options);\n}\n\nfunction planWireSegmentDrag(\n document: SchematicDocument,\n wire: SchematicWire,\n segment: number,\n delta: Point,\n options: SegmentDragOptions,\n): readonly Point[] | undefined {\n const points = wire.points;\n const start = points[segment];\n const end = points[segment + 1];\n if (start === undefined || end === undefined || (delta.x === 0 && delta.y === 0)) {\n return undefined;\n }\n if (start.x === end.x && start.y === end.y) {\n return undefined;\n }\n // Dragging a horizontal segment moves its run vertically; the run only breaks at a segment\n // pointing the other way (it just stretches) or at a connected vertex (it needs a dogleg).\n const horizontal = start.y === end.y;\n const isParallel = (from: Point, to: Point): boolean =>\n horizontal ? from.y === to.y : from.x === to.x;\n const connected = (point: Point): boolean => isConnectedVertex(document, point, wire.id, options);\n\n let first = segment;\n while (first > 0) {\n const previous = points[first - 1];\n const current = points[first];\n if (\n previous === undefined ||\n current === undefined ||\n !isParallel(previous, current) ||\n connected(current)\n ) {\n break;\n }\n first -= 1;\n }\n let last = segment + 1;\n while (last < points.length - 1) {\n const current = points[last];\n const next = points[last + 1];\n if (\n current === undefined ||\n next === undefined ||\n !isParallel(current, next) ||\n connected(current)\n ) {\n break;\n }\n last += 1;\n }\n\n const firstPoint = points[first];\n const lastPoint = points[last];\n if (firstPoint === undefined || lastPoint === undefined) {\n return undefined;\n }\n const shift = (point: Point): Point => ({ x: point.x + delta.x, y: point.y + delta.y });\n const moved: Point[] = [];\n for (let index = first; index <= last; index += 1) {\n const point = points[index];\n if (point !== undefined) {\n moved.push(shift(point));\n }\n }\n if (connected(firstPoint)) {\n moved.unshift(firstPoint);\n }\n if (connected(lastPoint)) {\n moved.push(lastPoint);\n }\n return [...points.slice(0, first), ...moved, ...points.slice(last + 1)];\n}\n\n/** True when something other than the wire itself is attached at `point`. */\nexport function isConnectedVertex(\n document: SchematicDocument,\n point: Point,\n wireId: string,\n options: SegmentDragOptions = {},\n): boolean {\n const same = (candidate: Point): boolean => candidate.x === point.x && candidate.y === point.y;\n for (const junction of document.sheet.junctions) {\n if (same(junction)) {\n return true;\n }\n }\n for (const wire of document.sheet.wires) {\n if (wire.id !== wireId && wire.points.some(same)) {\n return true;\n }\n }\n for (const symbol of document.sheet.symbols) {\n const role = symbolRole(symbol.device);\n if (role !== 'component') {\n if (same({ x: symbol.x, y: symbol.y })) {\n return true;\n }\n continue;\n }\n const reference = parseDeviceReference(symbol.device);\n const definition =\n reference === undefined ? undefined : options.devices?.getDeviceSymbol(reference);\n if (definition === undefined) {\n continue;\n }\n for (const anchor of Object.values(definition.pins)) {\n if (same(symbolPinPosition(symbol, anchor))) {\n return true;\n }\n }\n }\n return false;\n}\n","import type { Point, SchematicDocument } from '../format/types';\nimport { pointOnPolyline } from '../geometry/point';\n\nexport interface JunctionReleaseOptions {\n readonly tolerance?: number;\n}\n\nexport interface JunctionRelease {\n readonly id: string;\n /** Remaining participating wires; `undefined` means the junction has to be removed. */\n readonly wires: readonly string[] | undefined;\n}\n\n/**\n * Junctions that must let go of `wireId`: its new geometry no longer passes through them.\n *\n * A junction left with fewer than two wires is dropped instead of being kept dangling. Pure\n * geometry: the caller applies the resulting commands.\n */\nexport function planJunctionRelease(\n document: SchematicDocument,\n wireId: string,\n points: readonly Point[],\n options: JunctionReleaseOptions = {},\n): readonly JunctionRelease[] {\n const tolerance = options.tolerance ?? 0;\n const releases: JunctionRelease[] = [];\n for (const junction of document.sheet.junctions) {\n if (!junction.wires.includes(wireId)) {\n continue;\n }\n if (pointOnPolyline(points, { x: junction.x, y: junction.y }, tolerance)) {\n continue;\n }\n const remaining = junction.wires.filter((id) => id !== wireId);\n releases.push({ id: junction.id, wires: remaining.length < 2 ? undefined : remaining });\n }\n return releases;\n}\n\nexport interface JunctionJoin {\n readonly id: string;\n readonly wires: readonly string[];\n}\n\n/**\n * The junction sitting exactly at `point`, extended with `wireId`, so a wire that ends on an\n * existing junction actually joins it. `undefined` when there is nothing to join.\n */\nexport function joinJunctionAt(\n document: SchematicDocument,\n wireId: string,\n point: Point,\n): JunctionJoin | undefined {\n const junction = document.sheet.junctions.find(\n (candidate) => candidate.x === point.x && candidate.y === point.y,\n );\n if (junction === undefined || junction.wires.includes(wireId)) {\n return undefined;\n }\n return { id: junction.id, wires: [...junction.wires, wireId] };\n}\n","import { SchematicError } from '../format/errors';\nimport { parseSchematic } from '../format/parse-schematic';\nimport type { Point, SchematicDocument, SchematicJunction, SchematicWire } from '../format/types';\nimport { DEFAULT_TOLERANCE, pointOnPolyline, pointsEqual } from '../geometry/point';\nimport { defaultElementIdFactory, type ElementIdFactory } from './ids';\n\nexport interface WireEditOptions {\n readonly tolerance?: number;\n readonly createId?: ElementIdFactory;\n}\n\nexport interface SplitWireResult {\n readonly document: SchematicDocument;\n /** Wire that keeps the original id (the part before `point`). */\n readonly firstWireId: string;\n readonly secondWireId: string;\n}\n\nexport interface MergeWiresResult {\n readonly document: SchematicDocument;\n /** Wire that kept its id and absorbed the other one. */\n readonly wireId: string;\n readonly removedWireId: string;\n readonly removedJunctionId: string;\n}\n\n/**\n * Splits `wireId` at `point`, which must lie strictly inside the polyline.\n * Junctions that only touch the second half are re-pointed to the new wire.\n *\n * @throws {SchematicError} when the wire is unknown or `point` is not an interior point.\n */\nexport function splitWireAt(\n document: SchematicDocument,\n wireId: string,\n point: Point,\n options: WireEditOptions = {},\n): SplitWireResult {\n const tolerance = options.tolerance ?? DEFAULT_TOLERANCE;\n const wire = document.sheet.wires.find((candidate) => candidate.id === wireId);\n if (wire === undefined) {\n throw new SchematicError([\n {\n severity: 'error',\n code: 'edit/unknown-entity',\n message: `Unknown wire \"${wireId}\".`,\n entity: { kind: 'wire', id: wireId },\n },\n ]);\n }\n\n const split = splitPoints(wire.points, point, tolerance);\n if (split === undefined) {\n throw new SchematicError([\n {\n severity: 'error',\n code: 'wire/invalid-points',\n message: `Point (${point.x}, ${point.y}) is not an interior point of wire \"${wireId}\".`,\n entity: { kind: 'wire', id: wireId },\n },\n ]);\n }\n\n const firstWireId = wireId;\n const secondWireId =\n options.createId?.('wire', document) ?? defaultElementIdFactory('wire', document);\n if (secondWireId === firstWireId) {\n throw new SchematicError([\n {\n severity: 'error',\n code: 'edit/invalid-command',\n message: `Generated wire id \"${secondWireId}\" collides with the split wire.`,\n entity: { kind: 'wire', id: wireId },\n },\n ]);\n }\n\n const [firstPoints, secondPoints] = split;\n const wires: SchematicWire[] = [];\n for (const candidate of document.sheet.wires) {\n if (candidate.id !== wireId) {\n wires.push(candidate);\n continue;\n }\n wires.push({ id: firstWireId, points: firstPoints });\n wires.push({ id: secondWireId, points: secondPoints });\n }\n\n const junctions = document.sheet.junctions.map((junction) =>\n remapJunction(\n junction,\n wireId,\n firstWireId,\n secondWireId,\n firstPoints,\n secondPoints,\n point,\n tolerance,\n ),\n );\n\n return {\n document: validate({ ...document, sheet: { ...document.sheet, wires, junctions } }),\n firstWireId,\n secondWireId,\n };\n}\n\n/**\n * Merges the two collinear wires meeting at `junctionId` into one wire and removes the junction.\n * Returns `undefined` when the junction does not describe such a splice.\n *\n * @throws {SchematicError} when the junction is unknown.\n */\nexport function mergeWiresAtJunction(\n document: SchematicDocument,\n junctionId: string,\n options: WireEditOptions = {},\n): MergeWiresResult | undefined {\n const tolerance = options.tolerance ?? DEFAULT_TOLERANCE;\n const junction = document.sheet.junctions.find((candidate) => candidate.id === junctionId);\n if (junction === undefined) {\n throw new SchematicError([\n {\n severity: 'error',\n code: 'edit/unknown-entity',\n message: `Unknown junction \"${junctionId}\".`,\n entity: { kind: 'junction', id: junctionId },\n },\n ]);\n }\n if (junction.wires.length !== 2) {\n return undefined;\n }\n\n const [firstId, secondId] = junction.wires as [string, string];\n const first = document.sheet.wires.find((wire) => wire.id === firstId);\n const second = document.sheet.wires.find((wire) => wire.id === secondId);\n if (first === undefined || second === undefined) {\n return undefined;\n }\n\n const merged = mergePoints(first.points, second.points, junction, tolerance);\n if (merged === undefined) {\n return undefined;\n }\n\n const wires: SchematicWire[] = [];\n for (const candidate of document.sheet.wires) {\n if (candidate.id === secondId) {\n continue;\n }\n wires.push(candidate.id === firstId ? { id: firstId, points: merged } : candidate);\n }\n\n const junctions = document.sheet.junctions\n .filter((candidate) => candidate.id !== junctionId)\n .map((candidate) =>\n candidate.wires.includes(secondId)\n ? { ...candidate, wires: candidate.wires.map((id) => (id === secondId ? firstId : id)) }\n : candidate,\n );\n\n return {\n document: validate({ ...document, sheet: { ...document.sheet, wires, junctions } }),\n wireId: firstId,\n removedWireId: secondId,\n removedJunctionId: junctionId,\n };\n}\n\nfunction validate(document: SchematicDocument): SchematicDocument {\n return parseSchematic(document);\n}\n\nfunction splitPoints(\n points: readonly Point[],\n point: Point,\n tolerance: number,\n): readonly [readonly Point[], readonly Point[]] | undefined {\n const first = points[0];\n const last = points[points.length - 1];\n if (first === undefined || last === undefined) {\n return undefined;\n }\n if (pointsEqual(first, point, tolerance) || pointsEqual(last, point, tolerance)) {\n return undefined;\n }\n if (!pointOnPolyline(points, point, tolerance)) {\n return undefined;\n }\n for (let index = 1; index < points.length; index += 1) {\n const previous = points[index - 1];\n const current = points[index];\n if (previous === undefined || current === undefined) {\n continue;\n }\n if (!pointOnPolyline([previous, current], point, tolerance)) {\n continue;\n }\n const firstPoints = [...points.slice(0, index), { x: point.x, y: point.y }];\n const secondPoints = [{ x: point.x, y: point.y }, ...points.slice(index)];\n return [firstPoints, secondPoints];\n }\n return undefined;\n}\n\nfunction remapJunction(\n junction: SchematicJunction,\n wireId: string,\n firstWireId: string,\n secondWireId: string,\n firstPoints: readonly Point[],\n secondPoints: readonly Point[],\n splitPoint: Point,\n tolerance: number,\n): SchematicJunction {\n if (!junction.wires.includes(wireId)) {\n return junction;\n }\n const point = { x: junction.x, y: junction.y };\n if (pointsEqual(point, splitPoint, tolerance)) {\n const others = junction.wires.filter((id) => id !== wireId);\n return { ...junction, wires: [firstWireId, secondWireId, ...others] };\n }\n const onFirst = pointOnPolyline(firstPoints, point, tolerance);\n const onSecond = pointOnPolyline(secondPoints, point, tolerance);\n if (onFirst && !onSecond) {\n return junction;\n }\n if (onSecond && !onFirst) {\n return { ...junction, wires: junction.wires.map((id) => (id === wireId ? secondWireId : id)) };\n }\n return junction;\n}\n\nfunction mergePoints(\n first: readonly Point[],\n second: readonly Point[],\n junction: SchematicJunction,\n tolerance: number,\n): readonly Point[] | undefined {\n const at = { x: junction.x, y: junction.y };\n const firstStart = first[0];\n const firstEnd = first[first.length - 1];\n const secondStart = second[0];\n const secondEnd = second[second.length - 1];\n if (\n firstStart === undefined ||\n firstEnd === undefined ||\n secondStart === undefined ||\n secondEnd === undefined\n ) {\n return undefined;\n }\n\n const firstStartsAt = pointsEqual(firstStart, at, tolerance);\n const firstEndsAt = pointsEqual(firstEnd, at, tolerance);\n const secondStartsAt = pointsEqual(secondStart, at, tolerance);\n const secondEndsAt = pointsEqual(secondEnd, at, tolerance);\n\n let head: readonly Point[] | undefined;\n let tail: readonly Point[] | undefined;\n if (firstEndsAt && secondStartsAt) {\n head = first;\n tail = second;\n } else if (secondEndsAt && firstStartsAt) {\n head = second;\n tail = first;\n } else if (firstEndsAt && secondEndsAt) {\n head = first;\n tail = [...second].reverse();\n } else if (firstStartsAt && secondStartsAt) {\n head = [...first].reverse();\n tail = second;\n }\n if (head === undefined || tail === undefined || !isContinuous(head, tail)) {\n return undefined;\n }\n return [...head, ...tail.slice(1)];\n}\n\n/** True when the last segment of `a` and the first segment of `b` are collinear. */\nfunction isContinuous(a: readonly Point[], b: readonly Point[]): boolean {\n const a1 = a[a.length - 2];\n const a2 = a[a.length - 1];\n const b1 = b[0];\n const b2 = b[1];\n if (a1 === undefined || a2 === undefined || b1 === undefined || b2 === undefined) {\n return false;\n }\n const ax = a2.x - a1.x;\n const ay = a2.y - a1.y;\n const bx = b2.x - b1.x;\n const by = b2.y - b1.y;\n const cross = ax * by - ay * bx;\n const scale = Math.hypot(ax, ay) * Math.hypot(bx, by);\n if (scale === 0) {\n return false;\n }\n return Math.abs(cross) / scale <= 1e-9 && ax * bx + ay * by > 0;\n}\n","import type { Point, SchematicWire } from '../format/types';\n\nexport interface PointMove {\n readonly from: Point;\n readonly to: Point;\n}\n\nexport interface ReroutedWire {\n readonly points: readonly Point[];\n /** Every point that changed, so junctions and anchors can follow. */\n readonly moves: readonly PointMove[];\n}\n\n/**\n * Moves a wire endpoint to `to` while keeping every segment horizontal or vertical.\n *\n * The displacement is absorbed segment by segment (the classic orthogonal drag): the point after\n * the moved end is shifted just enough to restore the original orientation, and the correction is\n * passed on until a segment can take it. No extra points are inserted, so the wire never doubles\n * back on itself.\n */\nexport function rerouteWireEndpoint(\n wire: SchematicWire,\n from: Point,\n to: Point,\n): ReroutedWire | undefined {\n const points = wire.points;\n const first = points[0];\n const last = points[points.length - 1];\n if (first === undefined || last === undefined) {\n return undefined;\n }\n if (samePoint(first, from)) {\n return rerouteFrom(points, to, 'start');\n }\n if (samePoint(last, from)) {\n return rerouteFrom(points, to, 'end');\n }\n return undefined;\n}\n\nfunction rerouteFrom(points: readonly Point[], target: Point, end: 'start' | 'end'): ReroutedWire {\n const next = points.map((point) => ({ x: point.x, y: point.y }));\n const first = next[0];\n const last = next[next.length - 1];\n if (first === undefined || last === undefined) {\n return { points: next, moves: [] };\n }\n\n if (end === 'start') {\n next[0] = { x: target.x, y: target.y };\n for (let index = 0; index < next.length - 1; index += 1) {\n const a = next[index];\n const b = next[index + 1];\n if (a === undefined || b === undefined || a.x === b.x || a.y === b.y) {\n break;\n }\n const horizontal = points[index]?.y === points[index + 1]?.y;\n next[index + 1] = horizontal ? { x: b.x, y: a.y } : { x: a.x, y: b.y };\n }\n } else {\n next[next.length - 1] = { x: target.x, y: target.y };\n for (let index = next.length - 1; index > 0; index -= 1) {\n const a = next[index - 1];\n const b = next[index];\n if (a === undefined || b === undefined || a.x === b.x || a.y === b.y) {\n break;\n }\n const horizontal = points[index - 1]?.y === points[index]?.y;\n next[index - 1] = horizontal ? { x: a.x, y: b.y } : { x: b.x, y: a.y };\n }\n }\n\n const moves: PointMove[] = [];\n for (let index = 0; index < points.length; index += 1) {\n const before = points[index];\n const after = next[index];\n if (before !== undefined && after !== undefined && !samePoint(before, after)) {\n moves.push({ from: before, to: after });\n }\n }\n return { points: dropRepeatedPoints(next), moves };\n}\n\nfunction dropRepeatedPoints(points: readonly Point[]): readonly Point[] {\n const result: Point[] = [];\n for (const point of points) {\n const previous = result[result.length - 1];\n if (previous === undefined || !samePoint(previous, point)) {\n result.push(point);\n }\n }\n return result.length >= 2 ? result : points;\n}\n\n/**\n * Moves a wire endpoint to `to` by stretching or bending it, leaving the original run in place.\n *\n * Unlike {@link rerouteWireEndpoint}, which absorbs the move by shifting the neighbouring points,\n * this keeps every existing point: a move along the attached segment only changes its length, and a\n * perpendicular move appends an orthogonal fold at the moved end. That is the behaviour net labels\n * and power ports need while being dragged — the wire follows them instead of sliding away.\n */\nexport function stretchWireEndpoint(\n wire: SchematicWire,\n from: Point,\n to: Point,\n): ReroutedWire | undefined {\n const points = wire.points;\n const first = points[0];\n const last = points[points.length - 1];\n if (first === undefined || last === undefined) {\n return undefined;\n }\n if (samePoint(first, from)) {\n return stretchAt(points, to, 'start');\n }\n if (samePoint(last, from)) {\n return stretchAt(points, to, 'end');\n }\n return undefined;\n}\n\nfunction stretchAt(points: readonly Point[], target: Point, end: 'start' | 'end'): ReroutedWire {\n const anchor = end === 'start' ? points[0] : points[points.length - 1];\n const neighbor = end === 'start' ? points[1] : points[points.length - 2];\n if (anchor === undefined) {\n return { points, moves: [] };\n }\n if (neighbor === undefined) {\n const next = points.map((point) => ({ x: point.x, y: point.y }));\n if (end === 'start') {\n next[0] = { x: target.x, y: target.y };\n } else {\n next[next.length - 1] = { x: target.x, y: target.y };\n }\n return { points: next, moves: [{ from: anchor, to: target }] };\n }\n\n const horizontal = neighbor.y === anchor.y;\n const perpendicular = horizontal ? target.y !== anchor.y : target.x !== anchor.x;\n if (!perpendicular) {\n const next = points.map((point) => ({ x: point.x, y: point.y }));\n if (end === 'start') {\n next[0] = { x: target.x, y: target.y };\n } else {\n next[next.length - 1] = { x: target.x, y: target.y };\n }\n return { points: dropRepeatedPoints(next), moves: [{ from: anchor, to: target }] };\n }\n\n // Turn at the anchor first, then run perpendicular; a pure perpendicular move adds one segment.\n const elbow = horizontal ? { x: anchor.x, y: target.y } : { x: target.x, y: anchor.y };\n const turn = samePoint(elbow, target) ? [] : [elbow];\n const next = end === 'start' ? [target, ...turn, ...points] : [...points, ...turn, target];\n return { points: dropRepeatedPoints(next), moves: [] };\n}\n\nfunction samePoint(left: Point, right: Point): boolean {\n return left.x === right.x && left.y === right.y;\n}\n","import { namesNet, symbolRole } from '../device/reference';\nimport type { DeviceSymbolProvider } from '../device/symbol';\nimport type { Placement, Point, SchematicDocument } from '../format/types';\nimport { symbolPinPosition } from '../geometry/transform';\nimport {\n nearestPointOnPolyline,\n pointOnPolyline,\n pointOnPolylineAt,\n samePoint,\n} from '../geometry/point';\nimport { rerouteWireEndpoint, stretchWireEndpoint } from '../geometry/reroute';\n\nexport interface SymbolDragPreview {\n /** New point lists for wires whose endpoint is attached to a moving pin. */\n readonly wires: ReadonlyMap<string, readonly Point[]>;\n /** New positions for junctions sitting on a moving pin. */\n readonly junctions: ReadonlyMap<string, Point>;\n /** New positions for anchors (power / ground / label) attached to a moving pin. */\n readonly symbols: ReadonlyMap<string, Point>;\n}\n\n/**\n * Geometry of a symbol being dragged or rotated: which wires, junctions and anchors follow.\n * Shared by the editor controller (commit) and the renderer (live preview).\n */\nexport function previewSymbolDrag(\n document: SchematicDocument,\n devices: DeviceSymbolProvider | undefined,\n symbolId: string,\n next: Placement,\n): SymbolDragPreview | undefined {\n const symbol = document.sheet.symbols.find((candidate) => candidate.id === symbolId);\n if (symbol === undefined) {\n return undefined;\n }\n\n // Net labels and ports stretch their wire; component pins keep the run attached to the pin.\n const stretches = isNetAnchor(symbol.device);\n const definition = connectionAnchors(devices, symbol.device);\n const moves: { readonly from: Point; readonly to: Point }[] = [];\n for (const anchor of Object.values(definition)) {\n const from = symbolPinPosition(symbol, anchor);\n const to = symbolPinPosition(next, anchor);\n if (from.x !== to.x || from.y !== to.y) {\n moves.push({ from, to });\n }\n }\n\n const wires = new Map<string, readonly Point[]>();\n const junctions = new Map<string, Point>();\n const symbols = new Map<string, Point>();\n if (moves.length === 0) {\n return { wires, junctions, symbols };\n }\n\n const pointMoves = [...moves];\n for (const wire of document.sheet.wires) {\n for (const move of moves) {\n const rerouted = stretches\n ? stretchWireEndpoint(wire, move.from, move.to)\n : rerouteWireEndpoint(wire, move.from, move.to);\n if (rerouted === undefined) {\n continue;\n }\n wires.set(wire.id, rerouted.points);\n for (const extra of rerouted.moves) {\n if (!pointMoves.some((candidate) => samePoint(candidate.from, extra.from))) {\n pointMoves.push(extra);\n }\n }\n break;\n }\n }\n\n // Junctions that still lie on their (rerouted) wires stay put; only detached ones are re-placed.\n for (const junction of document.sheet.junctions) {\n const point = { x: junction.x, y: junction.y };\n const attached = junction.wires.every((wireId) => {\n const points = wires.get(wireId) ?? document.sheet.wires.find((w) => w.id === wireId)?.points;\n return points !== undefined && pointOnPolyline(points, point, ON_WIRE_EPSILON);\n });\n if (attached) {\n continue;\n }\n for (const wireId of junction.wires) {\n const before = document.sheet.wires.find((candidate) => candidate.id === wireId);\n const after = wires.get(wireId);\n if (before === undefined || after === undefined) {\n continue;\n }\n const projected = nearestPointOnPolyline(before.points, point);\n const moved =\n projected === undefined\n ? undefined\n : pointOnPolylineAt(after, projected.segment, projected.t);\n if (moved === undefined) {\n continue;\n }\n junctions.set(junction.id, moved);\n break;\n }\n }\n\n for (const move of pointMoves) {\n for (const junction of document.sheet.junctions) {\n if (samePoint({ x: junction.x, y: junction.y }, move.from)) {\n junctions.set(junction.id, move.to);\n }\n }\n for (const other of document.sheet.symbols) {\n if (other.id !== symbolId && samePoint({ x: other.x, y: other.y }, move.from)) {\n symbols.set(other.id, move.to);\n }\n }\n }\n\n return { wires, junctions, symbols };\n}\n\n/** True for the builtin anchors that name a net: net labels, power and ground. */\nfunction isNetAnchor(device: string): boolean {\n return namesNet(symbolRole(device));\n}\n\n/**\n * Connection points of a device in symbol-local space. Net labels, power and ground symbols connect\n * at their own anchor, so they report one at the origin and drag their wire end like a pin does.\n */\nfunction connectionAnchors(\n devices: DeviceSymbolProvider | undefined,\n device: string,\n): Readonly<Record<string, Point>> {\n if (isNetAnchor(device)) {\n return { net: { x: 0, y: 0 } };\n }\n if (symbolRole(device) !== 'component') {\n // Text symbols connect nowhere.\n return {};\n }\n const separator = device.indexOf(':');\n if (separator <= 0 || devices === undefined) {\n return {};\n }\n const packageId = device.slice(0, separator);\n const deviceId = device.slice(separator + 1);\n return devices.getDeviceSymbol({ raw: device, packageId, deviceId })?.pins ?? {};\n}\n\nconst ON_WIRE_EPSILON = 1e-6;\n","import type { Rect } from '../format/types';\nimport type { DeviceSymbolDefinition, PinAnchor, PinSide } from './symbol';\n\n/** Pin declaration subset used for symbol synthesis (see #11 / #12). */\nexport interface DevicePinDeclaration {\n /** Display side; pins without a side are drawn on the left. */\n readonly side?: PinSide;\n}\n\nexport interface SymbolSynthesisOptions {\n /** Distance between pin rows, in page units. Defaults to 10. */\n readonly pinPitch?: number;\n /** Stub length outside the body. Defaults to 10. */\n readonly stubLength?: number;\n /** Minimum body width. Defaults to 60. */\n readonly minWidth?: number;\n /** Minimum body height. Defaults to 40. */\n readonly minHeight?: number;\n /** Horizontal padding between the body edge and pin labels. Defaults to 10. */\n readonly horizontalPadding?: number;\n /** Vertical padding above the first and below the last pin row. Defaults to 10. */\n readonly verticalPadding?: number;\n /** Approximate glyph width of the device name. Defaults to 5.5. */\n readonly characterWidth?: number;\n /** Approximate glyph width of a pin name. Defaults to 4.5. */\n readonly labelCharacterWidth?: number;\n /** Gap between the device name and the side pin labels. Defaults to 12. */\n readonly nameGap?: number;\n /** Inset of a top/bottom pin label from the body edge. Defaults to 10. */\n readonly labelInset?: number;\n}\n\nexport interface SymbolSynthesisInput {\n readonly name: string;\n readonly pins: Readonly<Record<string, DevicePinDeclaration>>;\n}\n\nconst DEFAULT_PIN_SIDE: PinSide = 'left';\n\n/** Half height of a centred glyph box, in `characterWidth` units. */\nconst NAME_HALF_EXTENT = 1;\n\n/**\n * Derives symbol geometry from pin declarations: no coordinates or body size are authored.\n * Pins keep their declaration order within a side and snap to `pinPitch`.\n */\nexport function synthesizeDeviceSymbol(\n input: SymbolSynthesisInput,\n options: SymbolSynthesisOptions = {},\n): DeviceSymbolDefinition {\n const pinPitch = options.pinPitch ?? 10;\n const stubLength = options.stubLength ?? 10;\n const minWidth = options.minWidth ?? 60;\n const minHeight = options.minHeight ?? 40;\n const horizontalPadding = options.horizontalPadding ?? 10;\n const verticalPadding = options.verticalPadding ?? 10;\n const characterWidth = options.characterWidth ?? 5.5;\n const labelCharacterWidth = options.labelCharacterWidth ?? 4.5;\n const nameGap = options.nameGap ?? 12;\n const labelInset = options.labelInset ?? 10;\n\n const sides: Record<PinSide, string[]> = { left: [], right: [], top: [], bottom: [] };\n for (const [pinId, declaration] of Object.entries(input.pins)) {\n sides[declaration.side ?? DEFAULT_PIN_SIDE].push(pinId);\n }\n\n const rows = Math.max(sides.left.length, sides.right.length);\n const columns = Math.max(sides.top.length, sides.bottom.length);\n const height = Math.max(\n minHeight,\n verticalPadding * 2 + Math.max(rows - 1, 0) * pinPitch + pinPitch,\n // Rotated top/bottom labels must clear the centred device name.\n 2 *\n (NAME_HALF_EXTENT * characterWidth +\n pinPitch / 2 +\n labelInset +\n rotatedHalf(sides, labelCharacterWidth)),\n );\n const width = Math.max(\n minWidth,\n horizontalPadding * 2 + Math.max(columns - 1, 0) * pinPitch + pinPitch,\n );\n\n const leftText = longest(sides.left);\n const rightText = longest(sides.right);\n const contentWidth =\n (leftText + rightText) * labelCharacterWidth +\n input.name.length * characterWidth +\n horizontalPadding * 2 +\n nameGap * 2;\n const bodyWidth = Math.ceil(Math.max(width, contentWidth) / pinPitch) * pinPitch;\n const bodyHeight = Math.ceil(height / pinPitch) * pinPitch;\n\n const body: Rect = {\n x: -bodyWidth / 2,\n y: -bodyHeight / 2,\n width: bodyWidth,\n height: bodyHeight,\n };\n\n const pins: Record<string, PinAnchor> = Object.create(null);\n\n const placeVertical = (pinIds: readonly string[], side: 'left' | 'right'): void => {\n const start = -((pinIds.length - 1) * pinPitch) / 2;\n pinIds.forEach((pinId, index) => {\n const y = start + index * pinPitch;\n const x = side === 'left' ? body.x - stubLength : body.x + body.width + stubLength;\n pins[pinId] = { x, y, side };\n });\n };\n placeVertical(sides.left, 'left');\n placeVertical(sides.right, 'right');\n\n const placeHorizontal = (pinIds: readonly string[], side: 'top' | 'bottom'): void => {\n const start = -((pinIds.length - 1) * pinPitch) / 2;\n pinIds.forEach((pinId, index) => {\n const x = start + index * pinPitch;\n const y = side === 'top' ? body.y - stubLength : body.y + body.height + stubLength;\n pins[pinId] = { x, y, side };\n });\n };\n placeHorizontal(sides.top, 'top');\n placeHorizontal(sides.bottom, 'bottom');\n\n return { name: input.name, pins, bounds: body };\n}\n\nfunction longest(pinIds: readonly string[]): number {\n return pinIds.reduce((max, pinId) => Math.max(max, pinId.length), 0);\n}\n\nfunction rotatedHalf(\n sides: Readonly<Record<PinSide, readonly string[]>>,\n characterWidth: number,\n): number {\n return (Math.max(longest(sides.top), longest(sides.bottom)) * characterWidth) / 2;\n}\n","import type { Diagnostic } from '../format/diagnostics';\nimport { SchematicError, throwIfErrors } from '../format/errors';\nimport type { Rect } from '../format/types';\nimport { isRecord } from '../format/validate';\nimport {\n formatDeviceReference,\n isReservedPackageId,\n isValidPackageId,\n parseDeviceReference,\n type DeviceReference,\n} from './reference';\nimport type {\n DeviceSymbolDefinition,\n DeviceSymbolGeometry,\n DeviceSymbolProvider,\n PinAnchor,\n PinSide,\n} from './symbol';\nimport { readPropertyDescriptors, type PropertyDescriptor } from './properties';\nimport { synthesizeDeviceSymbol, type DevicePinDeclaration } from './synthesis';\n\nconst PIN_SIDES: readonly PinSide[] = ['left', 'right', 'top', 'bottom'];\n\nexport interface DeviceRegistrationEntry {\n /** Device id, unique within the package. */\n readonly id: string;\n /** Display name; defaults to the device id. */\n readonly displayName?: string;\n readonly description?: string;\n /**\n * Reference-designator prefix used when the device is placed (`U1`, `R3`, `DS2`, …).\n * Falls back to `raw.designatorPrefix`, then to the global default `U`.\n */\n readonly designatorPrefix?: string;\n /** Schematic symbol; omitted when the device has no geometry yet. */\n readonly symbol?: DeviceSymbolGeometry;\n /** Remaining device description fields (#5 pins, #7 properties, #10 ports, ...), kept as-is. */\n readonly raw?: Readonly<Record<string, unknown>>;\n}\n\n/** Package data prepared by the host from the #11 `devices` index and device descriptions. */\nexport interface DevicePackageRegistration {\n readonly packageId: string;\n readonly devices: readonly DeviceRegistrationEntry[];\n}\n\nexport interface ResolvedDevice {\n readonly reference: DeviceReference;\n readonly packageId: string;\n readonly deviceId: string;\n readonly displayName: string;\n readonly description: string | undefined;\n /** Designator prefix declared by the device description; `undefined` when it declares none. */\n readonly designatorPrefix: string | undefined;\n /** Property descriptors declared by `properties` (#7), keyed by property key. */\n readonly propertyDescriptors: ReadonlyMap<string, PropertyDescriptor>;\n readonly symbol: DeviceSymbolDefinition | undefined;\n readonly raw: Readonly<Record<string, unknown>>;\n}\n\nexport interface DeviceRegisterOptions {\n readonly replace?: boolean;\n}\n\nexport interface DeviceRegistry extends DeviceSymbolProvider {\n /** @throws {SchematicError} when the package data is invalid; nothing is registered then. */\n registerPackage(registration: DevicePackageRegistration, options?: DeviceRegisterOptions): void;\n resolve(reference: DeviceReference | string): ResolvedDevice | undefined;\n listDevices(packageId?: string): readonly ResolvedDevice[];\n /** Non-fatal diagnostics collected while registering packages (currently `device/no-symbol`). */\n readonly diagnostics: readonly Diagnostic[];\n}\n\ninterface StoredPackage {\n readonly packageId: string;\n readonly devices: ReadonlyMap<string, ResolvedDevice>;\n}\n\nexport function createDeviceRegistry(\n packages: readonly DevicePackageRegistration[] = [],\n): DeviceRegistry {\n const stored = new Map<string, StoredPackage>();\n const registrationDiagnostics: Diagnostic[] = [];\n\n const getDeviceName = (reference: DeviceReference): string | undefined => {\n const device = lookup(reference);\n // `symbol.name` already resolves to displayName or device id when the description omits it.\n return device?.symbol?.name ?? device?.displayName;\n };\n\n const lookup = (reference: DeviceReference): ResolvedDevice | undefined => {\n const pkg = stored.get(reference.packageId);\n return pkg?.devices.get(reference.deviceId);\n };\n\n const registry: DeviceRegistry = {\n registerPackage(registration, options) {\n const diagnostics: Diagnostic[] = [];\n const packageId = registration.packageId;\n if (!isValidPackageId(packageId)) {\n throw new SchematicError([\n {\n severity: 'error',\n code: 'device/invalid-package',\n message: `Invalid package id ${JSON.stringify(packageId)}.`,\n },\n ]);\n }\n if (isReservedPackageId(packageId)) {\n throw new SchematicError([\n {\n severity: 'error',\n code: 'device/reserved-namespace',\n message: `Package id ${JSON.stringify(packageId)} uses the reserved \"builtin\" namespace.`,\n },\n ]);\n }\n if (stored.has(packageId) && options?.replace !== true) {\n throw new SchematicError([\n {\n severity: 'error',\n code: 'device/duplicate-package',\n message: `Package ${JSON.stringify(packageId)} is already registered.`,\n },\n ]);\n }\n\n const devices = new Map<string, ResolvedDevice>();\n const reportedUnknownPins = new Set<string>();\n for (const entry of registration.devices) {\n const deviceId = typeof entry.id === 'string' ? entry.id : '';\n if (deviceId.length === 0) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-description',\n message: `Package ${JSON.stringify(packageId)} contains a device without an id.`,\n });\n continue;\n }\n const devicePath = `${packageId}:${deviceId}`;\n if (devices.has(deviceId)) {\n diagnostics.push({\n severity: 'error',\n code: 'device/duplicate-device',\n message: `Device ${JSON.stringify(devicePath)} is declared more than once.`,\n });\n continue;\n }\n\n const raw = isRecord(entry.raw) ? entry.raw : Object.create(null);\n const displayName =\n typeof entry.displayName === 'string' && entry.displayName.length > 0\n ? entry.displayName\n : deviceId;\n const symbol = readSymbolGeometry(entry, raw, devicePath, diagnostics, reportedUnknownPins);\n const designatorPrefix = readDesignatorPrefix(entry, raw);\n\n devices.set(deviceId, {\n reference: {\n raw: formatDeviceReference(packageId, deviceId),\n packageId,\n deviceId,\n },\n packageId,\n deviceId,\n displayName,\n description: typeof entry.description === 'string' ? entry.description : undefined,\n designatorPrefix,\n propertyDescriptors: readPropertyDescriptors(raw['properties']),\n symbol,\n raw,\n });\n }\n\n registrationDiagnostics.push(...diagnostics);\n throwIfErrors(diagnostics);\n stored.set(packageId, { packageId, devices });\n },\n\n resolve(reference) {\n const parsed = typeof reference === 'string' ? parseDeviceReference(reference) : reference;\n if (parsed === undefined) {\n return undefined;\n }\n return lookup(parsed);\n },\n\n listDevices(packageId) {\n const packages = packageId === undefined ? [...stored.values()] : [stored.get(packageId)];\n const devices: ResolvedDevice[] = [];\n for (const pkg of packages) {\n if (pkg === undefined) {\n continue;\n }\n devices.push(...pkg.devices.values());\n }\n return devices.sort(\n (a, b) => a.packageId.localeCompare(b.packageId) || a.deviceId.localeCompare(b.deviceId),\n );\n },\n\n getDeviceSymbol(reference) {\n return lookup(reference)?.symbol;\n },\n\n getDeviceName,\n\n getDeviceDesignatorPrefix(reference) {\n return lookup(reference)?.designatorPrefix;\n },\n\n getDevicePropertyDescriptors(reference) {\n return lookup(reference)?.propertyDescriptors;\n },\n\n get diagnostics() {\n return registrationDiagnostics;\n },\n };\n\n for (const registration of packages) {\n registry.registerPackage(registration);\n }\n\n return registry;\n}\n\n/** Designator prefix declared on the entry, else inside `raw`, else `undefined` (caller defaults). */\nfunction readDesignatorPrefix(\n entry: DeviceRegistrationEntry,\n raw: Readonly<Record<string, unknown>>,\n): string | undefined {\n const declared = entry.designatorPrefix ?? raw['designatorPrefix'];\n if (typeof declared !== 'string') {\n return undefined;\n }\n const trimmed = declared.trim();\n return trimmed.length === 0 ? undefined : trimmed;\n}\n\nfunction readSymbolGeometry(\n entry: DeviceRegistrationEntry,\n raw: Readonly<Record<string, unknown>>,\n devicePath: string,\n diagnostics: Diagnostic[],\n reportedUnknownPins: Set<string>,\n): DeviceSymbolDefinition | undefined {\n const displayName =\n typeof entry.displayName === 'string' && entry.displayName.length > 0\n ? entry.displayName\n : entry.id;\n const symbol = entry.symbol;\n\n if (symbol === undefined) {\n // No explicit geometry: derive it from the #5 / #11 pin declaration.\n const declarations = readPinDeclarations(raw['pins']);\n if (declarations === undefined) {\n diagnostics.push({\n severity: 'warning',\n code: 'device/no-symbol',\n message: `Device ${JSON.stringify(devicePath)} has neither symbol geometry nor pin declarations.`,\n });\n return undefined;\n }\n const synthesized = synthesizeDeviceSymbol({ name: displayName, pins: declarations });\n return synthesized;\n }\n\n if (!isRecord(symbol)) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-description',\n message: `Device ${JSON.stringify(devicePath)} has an invalid symbol definition.`,\n });\n return undefined;\n }\n\n const pins = readPins(symbol.pins, devicePath, diagnostics);\n if (pins === undefined) {\n return undefined;\n }\n\n const declaredPins = readDeclaredPinIds(raw.pins);\n if (declaredPins !== undefined) {\n for (const pinId of Object.keys(pins)) {\n if (!declaredPins.has(pinId) && !reportedUnknownPins.has(`${devicePath}\\u0000${pinId}`)) {\n reportedUnknownPins.add(`${devicePath}\\u0000${pinId}`);\n diagnostics.push({\n severity: 'error',\n code: 'device/unknown-pin',\n message: `Device ${JSON.stringify(devicePath)} symbol declares pin ${JSON.stringify(pinId)} which is absent from the pin declaration.`,\n });\n }\n }\n }\n\n const bounds = readBounds(symbol.bounds, devicePath, diagnostics);\n const declaredName =\n typeof symbol.name === 'string' && symbol.name.length > 0 ? symbol.name : undefined;\n const name = declaredName ?? displayName;\n\n return bounds === undefined ? { name, pins } : { name, pins, bounds };\n}\n\nfunction readPinDeclarations(value: unknown): Record<string, DevicePinDeclaration> | undefined {\n if (!isRecord(value) || Object.keys(value).length === 0) {\n return undefined;\n }\n const declarations: Record<string, DevicePinDeclaration> = Object.create(null);\n for (const [pinId, pin] of Object.entries(value)) {\n if (pinId.length === 0 || !isRecord(pin)) {\n return undefined;\n }\n const declaration: {\n -readonly [K in keyof DevicePinDeclaration]: DevicePinDeclaration[K];\n } = {};\n if (PIN_SIDES.includes(pin.side as PinSide)) {\n declaration.side = pin.side as PinSide;\n }\n declarations[pinId] = declaration;\n }\n return declarations;\n}\n\nfunction readPins(\n value: unknown,\n devicePath: string,\n diagnostics: Diagnostic[],\n): Record<string, PinAnchor> | undefined {\n if (!isRecord(value)) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-description',\n message: `Device ${JSON.stringify(devicePath)} symbol must declare a pins object.`,\n });\n return undefined;\n }\n const pins: Record<string, PinAnchor> = Object.create(null);\n let failed = false;\n for (const [pinId, anchor] of Object.entries(value)) {\n if (pinId.length === 0) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-description',\n message: `Device ${JSON.stringify(devicePath)} symbol declares an empty pin id.`,\n });\n failed = true;\n continue;\n }\n if (!isRecord(anchor) || !Number.isFinite(anchor.x) || !Number.isFinite(anchor.y)) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-description',\n message: `Device ${JSON.stringify(devicePath)} pin ${JSON.stringify(pinId)} must have finite x and y anchors.`,\n });\n failed = true;\n continue;\n }\n const side = anchor.side;\n if (side !== undefined && !PIN_SIDES.includes(side as PinSide)) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-description',\n message: `Device ${JSON.stringify(devicePath)} pin ${JSON.stringify(pinId)} has invalid side ${JSON.stringify(side)}.`,\n });\n failed = true;\n continue;\n }\n pins[pinId] =\n side === undefined\n ? { x: anchor.x as number, y: anchor.y as number }\n : { x: anchor.x as number, y: anchor.y as number, side: side as PinSide };\n }\n return failed ? undefined : pins;\n}\n\nfunction readBounds(\n value: unknown,\n devicePath: string,\n diagnostics: Diagnostic[],\n): Rect | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (\n !isRecord(value) ||\n !Number.isFinite(value.x) ||\n !Number.isFinite(value.y) ||\n !Number.isFinite(value.width) ||\n !Number.isFinite(value.height)\n ) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-description',\n message: `Device ${JSON.stringify(devicePath)} symbol bounds must have finite x, y, width and height.`,\n });\n return undefined;\n }\n return {\n x: value.x as number,\n y: value.y as number,\n width: value.width as number,\n height: value.height as number,\n };\n}\n\nfunction readDeclaredPinIds(value: unknown): Set<string> | undefined {\n if (!isRecord(value)) {\n return undefined;\n }\n return new Set(Object.keys(value));\n}\n","import type { SchematicDocument } from '../format/types';\nimport { designatorOf, parseDeviceReference } from './reference';\nimport type { DeviceSymbolProvider } from './symbol';\n\n/** Prefix used when neither the host nor the device description provides one. */\nexport const DEFAULT_DESIGNATOR_PREFIX = 'U';\n\n/**\n * Picks the reference designator of a newly placed component. Hosts replace this when their\n * naming rules go beyond the device's own prefix.\n */\nexport type DesignatorFactory = (device: string, document: SchematicDocument) => string;\n\n/** Smallest unused `<prefix><n>` designator. */\nexport function nextDesignator(\n document: SchematicDocument,\n prefix: string = DEFAULT_DESIGNATOR_PREFIX,\n): string {\n const used = new Set(\n document.sheet.symbols\n .map((symbol) => designatorOf(symbol))\n .filter((designator): designator is string => designator !== undefined),\n );\n for (let index = 1; index < Number.MAX_SAFE_INTEGER; index += 1) {\n const candidate = `${prefix}${index}`;\n if (!used.has(candidate)) {\n return candidate;\n }\n }\n return prefix;\n}\n\n/**\n * Designator policy derived from the device descriptions: `<device prefix><n>`, falling back to\n * `U` for devices that declare none.\n */\nexport function createDesignatorFactory(\n devices: DeviceSymbolProvider | undefined,\n): DesignatorFactory {\n return (device, document) => nextDesignator(document, designatorPrefixOf(devices, device));\n}\n\n/** Prefix the device declares, else {@link DEFAULT_DESIGNATOR_PREFIX}. */\nexport function designatorPrefixOf(\n devices: DeviceSymbolProvider | undefined,\n device: string,\n): string {\n const reference = parseDeviceReference(device);\n const declared =\n reference === undefined ? undefined : devices?.getDeviceDesignatorPrefix?.(reference);\n return declared ?? DEFAULT_DESIGNATOR_PREFIX;\n}\n\n/** Default policy for providers without device data: `U1`, `U2`, … */\nexport const defaultDesignatorFactory: DesignatorFactory = (device, document) =>\n nextDesignator(document);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["samePoint"],"sources":["../../src/format/types.ts","../../src/schematic/device/reference.ts","../../src/schematic/format/parse-schematic.ts","../../src/schematic/format/serialize.ts","../../src/schematic/geometry/point.ts","../../src/schematic/geometry/transform.ts","../../src/schematic/netlist/derive.ts","../../src/schematic/load/load.ts","../../src/schematic/device/properties.ts","../../src/schematic/edit/ids.ts","../../src/schematic/edit/commands.ts","../../src/schematic/edit/editor.ts","../../src/schematic/device/symbol.ts","../../src/schematic/edit/query.ts","../../src/schematic/edit/segment-drag.ts","../../src/schematic/edit/junctions.ts","../../src/schematic/edit/wires.ts","../../src/schematic/geometry/reroute.ts","../../src/schematic/edit/preview.ts","../../src/schematic/device/synthesis.ts","../../src/schematic/device/registry.ts","../../src/schematic/device/designator.ts"],"sourcesContent":["import type { Point, PropertyValue } from './value';\n\n/**\n * Schema version of the `.sch` contract (see x-botlab/mica-js#6).\n *\n * 2D placement lives in the separate `.cnv` canvas contract (see x-botlab/mica-js#67 and\n * `@mica-js/core/canvas`).\n */\nexport const SCHEMATIC_VERSION = 1;\n\nexport type SchematicVersion = typeof SCHEMATIC_VERSION;\n\nexport interface Rect {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n}\n\nexport interface Placement {\n readonly x: number;\n readonly y: number;\n readonly rotation: number;\n}\n\nexport interface SchematicSymbol extends Placement {\n /** Stable identity used by selections, undo and `.view` layout keys. */\n readonly id: string;\n readonly device: string;\n /** Instance property overrides; absent means \"use device defaults\". */\n readonly properties?: Readonly<Record<string, PropertyValue>>;\n /**\n * Reference designator of a component (`U1`, `R2`); defaults to {@link id}.\n * Only components carry one — the format rejects it elsewhere.\n */\n readonly designator?: string;\n /**\n * Net name of a net label, power or ground symbol (`VCC`, `N1`). It is the text drawn next to\n * the anchor and the key same-named ports merge on. Only net-naming symbols carry one.\n */\n readonly net?: string;\n /**\n * Reference designator anchor in symbol-local coordinates (unrotated, unplaced).\n * Absent means the default position at the body's top-left corner.\n */\n readonly reference?: Point;\n}\n\nexport interface SchematicWire {\n readonly id: string;\n readonly points: readonly Point[];\n}\n\nexport interface SchematicJunction {\n readonly id: string;\n readonly x: number;\n readonly y: number;\n readonly wires: readonly string[];\n}\n\nexport interface SchematicSheet {\n readonly symbols: readonly SchematicSymbol[];\n readonly wires: readonly SchematicWire[];\n readonly junctions: readonly SchematicJunction[];\n}\n\n/** Root of a `.sch` file; the file name is the schematic's identity. */\nexport interface SchematicDocument {\n readonly version: SchematicVersion;\n readonly sheet: SchematicSheet;\n}\n","export const LABEL_DEVICE = 'builtin:label';\nexport const POWER_DEVICE = 'builtin:power';\nexport const GROUND_DEVICE = 'builtin:ground';\n/** Free-standing annotation; it is not a connection point and never joins a net. */\nexport const TEXT_DEVICE = 'builtin:text';\nexport const RESERVED_PACKAGE_NAMESPACE = 'builtin';\n\n/** Builtin symbols recognised by the loader instead of the device registry. */\nexport type BuiltinSymbolKind = 'label' | 'power' | 'ground';\n\nconst BUILTIN_DEVICES: Readonly<Record<string, BuiltinSymbolKind>> = {\n [LABEL_DEVICE]: 'label',\n [POWER_DEVICE]: 'power',\n [GROUND_DEVICE]: 'ground',\n};\n\nexport const DEFAULT_POWER_LABEL = 'VCC';\nexport const DEFAULT_GROUND_LABEL = 'GND';\nexport const DEFAULT_TEXT_CONTENT = '文本';\n\nexport interface DeviceReference {\n readonly raw: string;\n readonly packageId: string;\n readonly deviceId: string;\n}\n\nconst PACKAGE_NAMESPACE_PATTERN = /^@[A-Za-z0-9][A-Za-z0-9._+-]*$/;\nconst PACKAGE_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]*$/;\nconst DEVICE_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]*$/;\n\n/**\n * Splits `<packageId>:<deviceId>`. Package ids follow npm conventions and may be scoped\n * (`@scope/name`); the device id uses a conservative identifier charset until #3 / #11 finalize it.\n */\nexport function parseDeviceReference(raw: string): DeviceReference | undefined {\n const separator = raw.indexOf(':');\n if (separator <= 0 || separator === raw.length - 1) {\n return undefined;\n }\n if (raw.indexOf(':', separator + 1) !== -1) {\n return undefined;\n }\n const packageId = raw.slice(0, separator);\n const deviceId = raw.slice(separator + 1);\n if (!isValidPackageId(packageId) || !DEVICE_ID_PATTERN.test(deviceId)) {\n return undefined;\n }\n return { raw, packageId, deviceId };\n}\n\nexport function isValidPackageId(packageId: string): boolean {\n if (packageId.startsWith('@')) {\n const parts = packageId.split('/');\n if (parts.length !== 2) {\n return false;\n }\n const [scope, name] = parts;\n return (\n scope !== undefined &&\n name !== undefined &&\n PACKAGE_NAMESPACE_PATTERN.test(scope) &&\n PACKAGE_NAME_PATTERN.test(name)\n );\n }\n return PACKAGE_NAME_PATTERN.test(packageId);\n}\n\n/** `builtin` is reserved for loader-provided symbols such as `builtin:label`. */\nexport function isReservedPackageId(packageId: string): boolean {\n return (\n packageId === RESERVED_PACKAGE_NAMESPACE ||\n packageId.startsWith(`${RESERVED_PACKAGE_NAMESPACE}/`)\n );\n}\n\nexport function isLabelDevice(raw: string): boolean {\n return raw === LABEL_DEVICE;\n}\n\n/** True for the free-standing text annotation (`builtin:text`). */\nexport function isTextDevice(raw: string): boolean {\n return raw === TEXT_DEVICE;\n}\n\n/** Text of a `builtin:text` symbol, falling back to a placeholder. */\nexport function textDeviceContent(symbol: {\n readonly properties?: Readonly<Record<string, unknown>>;\n}): string {\n const text = symbol.properties?.['text'];\n return typeof text === 'string' && text.length > 0 ? text : DEFAULT_TEXT_CONTENT;\n}\n\n/** Returns the builtin kind for `builtin:label` / `builtin:power` / `builtin:ground`. */\nexport function builtinSymbolKind(raw: string): BuiltinSymbolKind | undefined {\n return BUILTIN_DEVICES[raw];\n}\n\nexport function isBuiltinDevice(raw: string): boolean {\n return builtinSymbolKind(raw) !== undefined;\n}\n\n/** What a placed symbol is for: the single question the rest of the code asks about it. */\nexport type SymbolRole = 'component' | 'net-label' | 'power' | 'ground' | 'text';\n\n/** Role of a symbol, derived from its device reference; unknown devices are components. */\nexport function symbolRole(device: string): SymbolRole {\n switch (builtinSymbolKind(device)) {\n case 'label':\n return 'net-label';\n case 'power':\n return 'power';\n case 'ground':\n return 'ground';\n default:\n return isTextDevice(device) ? 'text' : 'component';\n }\n}\n\n/** Only components are annotated with a reference designator. */\nexport function hasDesignator(role: SymbolRole): boolean {\n return role === 'component';\n}\n\n/** Net labels, power and ground ports name the net they attach to. */\nexport function namesNet(role: SymbolRole): boolean {\n return role === 'net-label' || role === 'power' || role === 'ground';\n}\n\n/** Reference designator of a component; `undefined` for symbols that have none. */\nexport function designatorOf(symbol: {\n readonly id: string;\n readonly device: string;\n readonly designator?: string;\n}): string | undefined {\n return hasDesignator(symbolRole(symbol.device)) ? (symbol.designator ?? symbol.id) : undefined;\n}\n\n/** Net name of a label / power / ground symbol; `undefined` when the symbol names no net. */\nexport function netNameOf(symbol: {\n readonly device: string;\n readonly net?: string;\n}): string | undefined {\n switch (symbolRole(symbol.device)) {\n case 'power':\n return symbol.net ?? DEFAULT_POWER_LABEL;\n case 'ground':\n return symbol.net ?? DEFAULT_GROUND_LABEL;\n case 'net-label':\n return symbol.net;\n default:\n return undefined;\n }\n}\n\n/** Net name a freshly placed symbol of `role` gets when none is given. */\nexport function defaultNetName(role: SymbolRole): string | undefined {\n switch (role) {\n case 'power':\n return DEFAULT_POWER_LABEL;\n case 'ground':\n return DEFAULT_GROUND_LABEL;\n default:\n return undefined;\n }\n}\n\nexport function formatDeviceReference(packageId: string, deviceId: string): string {\n return `${packageId}:${deviceId}`;\n}\n","import type { Diagnostic } from '../../format/diagnostics';\nimport { SchematicError } from '../../format/errors';\nimport { parseInput } from '../../format/input';\nimport type {\n SchematicDocument,\n SchematicJunction,\n SchematicSheet,\n SchematicSymbol,\n SchematicWire,\n} from '../../format/types';\nimport { SCHEMATIC_VERSION } from '../../format/types';\nimport type { Point } from '../../format/value';\nimport {\n designatorOf,\n hasDesignator,\n namesNet,\n symbolRole,\n type SymbolRole,\n} from '../device/reference';\nimport {\n checkDuplicateIds,\n forbidUnknownFields,\n hasErrors,\n isRecord,\n readArrayField,\n readIntegerField,\n readNumberField,\n readObjectField,\n readPoint,\n readProperties,\n readStringField,\n report,\n type IdentifiedEntry,\n} from '../../format/validate';\n\n/** @throws {SchematicError} when the input does not match the `.sch` contract. */\nexport function parseSchematic(input: string | unknown): SchematicDocument {\n const diagnostics: Diagnostic[] = [];\n const parsed = parseInput(input, diagnostics);\n if (!parsed.ok) {\n throw new SchematicError(diagnostics);\n }\n const value = readDocument(parsed.value, diagnostics);\n if (value === undefined || hasErrors(diagnostics)) {\n throw new SchematicError(diagnostics);\n }\n return value;\n}\n\nfunction readDocument(value: unknown, diagnostics: Diagnostic[]): SchematicDocument | undefined {\n if (!isRecord(value)) {\n report(diagnostics, 'json/not-object', 'Schematic must be a JSON object.', []);\n return undefined;\n }\n forbidUnknownFields(value, ['version', 'sheet'], [], diagnostics);\n const version = readVersion(value, diagnostics);\n const sheet = readSheet(readObjectField(value, 'sheet', [], diagnostics), diagnostics);\n if (version === undefined || sheet === undefined) {\n return undefined;\n }\n return { version, sheet };\n}\n\nfunction readVersion(\n value: Record<string, unknown>,\n diagnostics: Diagnostic[],\n): typeof SCHEMATIC_VERSION | undefined {\n const version = readIntegerField(value, 'version', [], diagnostics);\n if (version === undefined) {\n return undefined;\n }\n if (version !== SCHEMATIC_VERSION) {\n report(\n diagnostics,\n 'schema/unsupported-version',\n `Unsupported version ${version}; expected ${SCHEMATIC_VERSION}.`,\n ['version'],\n );\n return undefined;\n }\n return SCHEMATIC_VERSION;\n}\n\nfunction readSheet(\n value: Record<string, unknown> | undefined,\n diagnostics: Diagnostic[],\n): SchematicSheet | undefined {\n if (value === undefined) {\n return undefined;\n }\n forbidUnknownFields(value, ['symbols', 'wires', 'junctions'], ['sheet'], diagnostics);\n const rawSymbols = readArrayField(value, 'symbols', ['sheet'], diagnostics) ?? [];\n const rawWires = readArrayField(value, 'wires', ['sheet'], diagnostics) ?? [];\n const rawJunctions = readArrayField(value, 'junctions', ['sheet'], diagnostics) ?? [];\n\n const symbols: SchematicSymbol[] = [];\n const symbolIds: IdentifiedEntry[] = [];\n rawSymbols.forEach((item, index) => {\n const path = ['sheet', 'symbols', String(index)];\n const symbol = readSymbol(item, path, diagnostics);\n if (symbol !== undefined) {\n symbols.push(symbol);\n symbolIds.push({ id: symbol.id, path: [...path, 'id'] });\n }\n });\n\n const wires: SchematicWire[] = [];\n const wireIds: IdentifiedEntry[] = [];\n rawWires.forEach((item, index) => {\n const path = ['sheet', 'wires', String(index)];\n const wire = readWire(item, path, diagnostics);\n if (wire !== undefined) {\n wires.push(wire);\n wireIds.push({ id: wire.id, path: [...path, 'id'] });\n }\n });\n\n const knownWireIds = new Set(wires.map((wire) => wire.id));\n const junctions: SchematicJunction[] = [];\n const junctionIds: IdentifiedEntry[] = [];\n rawJunctions.forEach((item, index) => {\n const path = ['sheet', 'junctions', String(index)];\n const junction = readJunction(item, path, diagnostics);\n if (junction === undefined) {\n return;\n }\n const seenWireIds = new Set<string>();\n junction.wires.forEach((wireId, wireIndex) => {\n const wirePath = [...path, 'wires', String(wireIndex)];\n if (seenWireIds.has(wireId)) {\n report(\n diagnostics,\n 'junction/duplicate-wire',\n `Junction \"${junction.id}\" references wire \"${wireId}\" more than once.`,\n wirePath,\n { kind: 'junction', id: junction.id },\n );\n } else {\n seenWireIds.add(wireId);\n }\n if (!knownWireIds.has(wireId)) {\n report(\n diagnostics,\n 'junction/unknown-wire',\n `Junction \"${junction.id}\" references unknown wire \"${wireId}\".`,\n wirePath,\n { kind: 'junction', id: junction.id },\n );\n }\n });\n junctions.push(junction);\n junctionIds.push({ id: junction.id, path: [...path, 'id'] });\n });\n\n checkDuplicateIds(symbolIds, 'symbol', diagnostics);\n checkDuplicateDesignators(symbols, diagnostics);\n checkDuplicateIds(wireIds, 'wire', diagnostics);\n checkDuplicateIds(junctionIds, 'junction', diagnostics);\n\n return { symbols, wires, junctions };\n}\n\n/** Two components must not share a reference designator. */\nfunction checkDuplicateDesignators(\n symbols: readonly SchematicSymbol[],\n diagnostics: Diagnostic[],\n): void {\n const seen = new Set<string>();\n symbols.forEach((symbol, index) => {\n const designator = designatorOf(symbol);\n if (designator === undefined) {\n return;\n }\n if (seen.has(designator)) {\n report(\n diagnostics,\n 'symbol/designator-duplicate',\n `Reference designator ${JSON.stringify(designator)} is used more than once.`,\n ['sheet', 'symbols', String(index), 'designator'],\n { kind: 'symbol', id: symbol.id },\n );\n return;\n }\n seen.add(designator);\n });\n}\n\nfunction readSymbol(\n value: unknown,\n path: readonly string[],\n diagnostics: Diagnostic[],\n): SchematicSymbol | undefined {\n if (!isRecord(value)) {\n report(diagnostics, 'schema/invalid-type', 'Symbol must be an object.', path);\n return undefined;\n }\n forbidUnknownFields(\n value,\n ['id', 'device', 'x', 'y', 'rotation', 'properties', 'designator', 'net', 'reference'],\n path,\n diagnostics,\n );\n const id = readStringField(value, 'id', path, diagnostics, { nonEmpty: true });\n const device = readStringField(value, 'device', path, diagnostics, { nonEmpty: true });\n const x = readNumberField(value, 'x', path, diagnostics);\n const y = readNumberField(value, 'y', path, diagnostics);\n const rotation = readNumberField(value, 'rotation', path, diagnostics);\n const properties =\n value['properties'] === undefined\n ? undefined\n : readProperties(value['properties'], [...path, 'properties'], diagnostics);\n const reference =\n value['reference'] === undefined\n ? undefined\n : readPoint(value['reference'], [...path, 'reference'], diagnostics);\n const designator = readRoleField(value, 'designator', device, path, diagnostics, hasDesignator);\n const net = readRoleField(value, 'net', device, path, diagnostics, namesNet);\n if (device !== undefined) {\n const role = symbolRole(device);\n if (namesNet(role) && net === undefined && value['net'] === undefined) {\n report(\n diagnostics,\n 'symbol/missing-net',\n `Symbols of role \"${role}\" must name the net they attach to.`,\n [...path, 'net'],\n );\n }\n if (!hasDesignator(role) && value['reference'] !== undefined) {\n report(\n diagnostics,\n 'symbol/unsupported-field',\n `Symbols of role \"${role}\" carry no reference designator.`,\n [...path, 'reference'],\n );\n }\n }\n if (\n id === undefined ||\n device === undefined ||\n x === undefined ||\n y === undefined ||\n rotation === undefined ||\n (value['reference'] !== undefined && reference === undefined)\n ) {\n return undefined;\n }\n return {\n id,\n device,\n x,\n y,\n rotation,\n ...(properties === undefined ? {} : { properties }),\n ...(designator === undefined ? {} : { designator }),\n ...(net === undefined ? {} : { net }),\n ...(reference === undefined ? {} : { reference }),\n };\n}\n\n/**\n * Reads a field that only some symbol roles may carry, so the format cannot describe a power\n * symbol with a reference designator or a resistor with a net name.\n */\nfunction readRoleField(\n value: Record<string, unknown>,\n field: 'designator' | 'net',\n device: string | undefined,\n path: readonly string[],\n diagnostics: Diagnostic[],\n allowed: (role: SymbolRole) => boolean,\n): string | undefined {\n const raw = value[field];\n if (raw === undefined || device === undefined) {\n return undefined;\n }\n const role = symbolRole(device);\n if (!allowed(role)) {\n report(\n diagnostics,\n 'symbol/unsupported-field',\n `Symbols of role \"${role}\" must not declare \"${field}\".`,\n [...path, field],\n );\n return undefined;\n }\n return readStringField(value, field, path, diagnostics, { nonEmpty: true });\n}\n\nfunction readWire(\n value: unknown,\n path: readonly string[],\n diagnostics: Diagnostic[],\n): SchematicWire | undefined {\n if (!isRecord(value)) {\n report(diagnostics, 'schema/invalid-type', 'Wire must be an object.', path);\n return undefined;\n }\n forbidUnknownFields(value, ['id', 'points'], path, diagnostics);\n const id = readStringField(value, 'id', path, diagnostics, { nonEmpty: true });\n const rawPoints = readArrayField(value, 'points', path, diagnostics);\n const points: Point[] = [];\n if (rawPoints !== undefined) {\n if (rawPoints.length < 2) {\n report(diagnostics, 'wire/invalid-points', 'Wire must contain at least two points.', [\n ...path,\n 'points',\n ]);\n }\n rawPoints.forEach((item, index) => {\n const point = readPoint(item, [...path, 'points', String(index)], diagnostics);\n if (point !== undefined) {\n points.push(point);\n }\n });\n }\n if (id === undefined || rawPoints === undefined) {\n return undefined;\n }\n for (let index = 1; index < points.length; index += 1) {\n const previous = points[index - 1];\n const current = points[index];\n if (previous === undefined || current === undefined) {\n continue;\n }\n if (previous.x !== current.x && previous.y !== current.y) {\n report(diagnostics, 'wire/not-orthogonal', 'Wire segments must be horizontal or vertical.', [\n ...path,\n 'points',\n String(index),\n ]);\n return undefined;\n }\n }\n return { id, points };\n}\n\nfunction readJunction(\n value: unknown,\n path: readonly string[],\n diagnostics: Diagnostic[],\n): SchematicJunction | undefined {\n if (!isRecord(value)) {\n report(diagnostics, 'schema/invalid-type', 'Junction must be an object.', path);\n return undefined;\n }\n forbidUnknownFields(value, ['id', 'x', 'y', 'wires'], path, diagnostics);\n const id = readStringField(value, 'id', path, diagnostics, { nonEmpty: true });\n const x = readNumberField(value, 'x', path, diagnostics);\n const y = readNumberField(value, 'y', path, diagnostics);\n const rawWires = readArrayField(value, 'wires', path, diagnostics);\n const wires: string[] = [];\n if (rawWires !== undefined) {\n if (rawWires.length < 2) {\n report(diagnostics, 'schema/invalid-value', 'Junction must reference at least two wires.', [\n ...path,\n 'wires',\n ]);\n }\n rawWires.forEach((item, index) => {\n const wirePath = [...path, 'wires', String(index)];\n if (typeof item !== 'string') {\n report(\n diagnostics,\n 'schema/invalid-type',\n 'Junction wire reference must be a string.',\n wirePath,\n );\n return;\n }\n if (item.length === 0) {\n report(\n diagnostics,\n 'schema/invalid-value',\n 'Junction wire reference must not be empty.',\n wirePath,\n );\n return;\n }\n wires.push(item);\n });\n }\n if (id === undefined || x === undefined || y === undefined || rawWires === undefined) {\n return undefined;\n }\n return { id, x, y, wires };\n}\n","import type { SchematicDocument } from '../../format/types';\nimport type { PropertyValue } from '../../format/value';\n\n/** Serializes with a fixed field order and 2-space indentation, matching the examples in #6. */\nexport function serializeSchematic(document: SchematicDocument): string {\n const serializable = {\n version: document.version,\n sheet: {\n symbols: document.sheet.symbols.map((symbol) => {\n const serialized: Record<string, unknown> = {\n id: symbol.id,\n device: symbol.device,\n x: symbol.x,\n y: symbol.y,\n rotation: symbol.rotation,\n };\n if (symbol.properties !== undefined && Object.keys(symbol.properties).length > 0) {\n serialized['properties'] = sortProperties(symbol.properties);\n }\n // Role-scoped fields are written explicitly so the file states what the symbol is for.\n if (symbol.designator !== undefined) {\n serialized['designator'] = symbol.designator;\n }\n if (symbol.net !== undefined) {\n serialized['net'] = symbol.net;\n }\n if (symbol.reference !== undefined) {\n serialized['reference'] = { x: symbol.reference.x, y: symbol.reference.y };\n }\n return serialized;\n }),\n wires: document.sheet.wires.map((wire) => ({\n id: wire.id,\n points: wire.points.map((point) => ({ x: point.x, y: point.y })),\n })),\n junctions: document.sheet.junctions.map((junction) => ({\n id: junction.id,\n x: junction.x,\n y: junction.y,\n wires: [...junction.wires],\n })),\n },\n };\n return `${JSON.stringify(serializable, null, 2)}\\n`;\n}\n\nfunction sortProperties(\n properties: Readonly<Record<string, PropertyValue>>,\n): Record<string, PropertyValue> {\n const sorted: Record<string, PropertyValue> = Object.create(null);\n for (const key of Object.keys(properties).sort()) {\n const value = properties[key];\n if (value !== undefined) {\n sorted[key] = value;\n }\n }\n return sorted;\n}\n","import type { Rect } from '../../format/types';\nimport type { Point } from '../../format/value';\n\n/** Default comparison tolerance, in page units. */\nexport const DEFAULT_TOLERANCE = 0;\n\nexport function distance(a: Point, b: Point): number {\n return Math.hypot(b.x - a.x, b.y - a.y);\n}\n\nexport function samePoint(a: Point, b: Point): boolean {\n return a.x === b.x && a.y === b.y;\n}\n\nexport function pointsEqual(a: Point, b: Point, tolerance = DEFAULT_TOLERANCE): boolean {\n return distance(a, b) <= tolerance;\n}\n\n/** Closest point on the closed segment `a`–`b`, plus its position `t` in `[0, 1]`. */\nexport function projectOnSegment(\n point: Point,\n a: Point,\n b: Point,\n): { readonly x: number; readonly y: number; readonly t: number } {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const lengthSquared = dx * dx + dy * dy;\n if (lengthSquared === 0) {\n return { x: a.x, y: a.y, t: 0 };\n }\n const raw = ((point.x - a.x) * dx + (point.y - a.y) * dy) / lengthSquared;\n const t = raw < 0 ? 0 : raw > 1 ? 1 : raw;\n return { x: a.x + dx * t, y: a.y + dy * t, t };\n}\n\nexport interface SegmentProjection {\n /** Closest point of the polyline. */\n readonly point: Point;\n /** Index of the segment that holds the closest point. */\n readonly segment: number;\n /** Position along that segment, in `[0, 1]`. */\n readonly t: number;\n readonly distance: number;\n}\n\n/** Closest point on a polyline, with the segment it belongs to; `undefined` when empty. */\nexport function nearestPointOnPolyline(\n points: readonly Point[],\n point: Point,\n): SegmentProjection | undefined {\n let best: SegmentProjection | undefined;\n for (let index = 1; index < points.length; index += 1) {\n const a = points[index - 1];\n const b = points[index];\n if (a === undefined || b === undefined) {\n continue;\n }\n const projected = projectOnSegment(point, a, b);\n const candidate: SegmentProjection = {\n point: { x: projected.x, y: projected.y },\n segment: index - 1,\n t: projected.t,\n distance: distance(point, projected),\n };\n if (best === undefined || candidate.distance < best.distance) {\n best = candidate;\n }\n }\n const only = points[0];\n if (best === undefined && only !== undefined) {\n return { point: only, segment: 0, t: 0, distance: distance(point, only) };\n }\n return best;\n}\n\n/** Point at position `t` along segment `segment` of a polyline. */\nexport function pointOnPolylineAt(\n points: readonly Point[],\n segment: number,\n t: number,\n): Point | undefined {\n const a = points[segment];\n if (a === undefined) {\n return undefined;\n }\n const b = points[segment + 1] ?? a;\n return { x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t };\n}\n\n/** True when `point` lies on the closed segment `a`–`b`, within `tolerance`. */\nexport function pointOnSegment(\n point: Point,\n a: Point,\n b: Point,\n tolerance = DEFAULT_TOLERANCE,\n): boolean {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const length = Math.hypot(dx, dy);\n if (length === 0) {\n return pointsEqual(point, a, tolerance);\n }\n const area = (point.x - a.x) * dy - (point.y - a.y) * dx;\n if (Math.abs(area) / length > tolerance) {\n return false;\n }\n const projection = ((point.x - a.x) * dx + (point.y - a.y) * dy) / (length * length);\n const overhang = tolerance / length;\n if (projection < -overhang || projection > 1 + overhang) {\n return false;\n }\n return distanceToSegment(point, a, b) <= tolerance;\n}\n\nexport function distanceToSegment(point: Point, a: Point, b: Point): number {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const lengthSquared = dx * dx + dy * dy;\n if (lengthSquared === 0) {\n return distance(point, a);\n }\n const t = ((point.x - a.x) * dx + (point.y - a.y) * dy) / lengthSquared;\n const clamped = t < 0 ? 0 : t > 1 ? 1 : t;\n return distance(point, { x: a.x + clamped * dx, y: a.y + clamped * dy });\n}\n\n/** True when `point` lies on any segment of the polyline, endpoints included. */\nexport function pointOnPolyline(\n points: readonly Point[],\n point: Point,\n tolerance = DEFAULT_TOLERANCE,\n): boolean {\n if (points.length === 1) {\n const [only] = points;\n return only !== undefined && pointsEqual(only, point, tolerance);\n }\n for (let index = 1; index < points.length; index += 1) {\n const previous = points[index - 1];\n const current = points[index];\n if (\n previous !== undefined &&\n current !== undefined &&\n pointOnSegment(point, previous, current, tolerance)\n ) {\n return true;\n }\n }\n return false;\n}\n\nexport function boundsOfPoints(points: readonly Point[]): Rect | undefined {\n const [first, ...rest] = points;\n if (first === undefined) {\n return undefined;\n }\n let minX = first.x;\n let minY = first.y;\n let maxX = first.x;\n let maxY = first.y;\n for (const point of rest) {\n minX = Math.min(minX, point.x);\n minY = Math.min(minY, point.y);\n maxX = Math.max(maxX, point.x);\n maxY = Math.max(maxY, point.y);\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\nexport function unionBounds(a: Rect | undefined, b: Rect | undefined): Rect | undefined {\n if (a === undefined) {\n return b;\n }\n if (b === undefined) {\n return a;\n }\n const minX = Math.min(a.x, b.x);\n const minY = Math.min(a.y, b.y);\n const maxX = Math.max(a.x + a.width, b.x + b.width);\n const maxY = Math.max(a.y + a.height, b.y + b.height);\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n","import type { Placement, Rect } from '../../format/types';\nimport type { Point } from '../../format/value';\nimport type { PinAnchor } from '../device/symbol';\nimport { boundsOfPoints } from './point';\n\n/** Rotates counter-clockwise around the origin. Rotation is expressed in degrees. */\nexport function rotatePoint(point: Point, degrees: number): Point {\n const radians = (degrees * Math.PI) / 180;\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n return {\n x: point.x * cos - point.y * sin,\n y: point.x * sin + point.y * cos,\n };\n}\n\n/** Applies a symbol placement to a pre-placement anchor. */\nexport function symbolPinPosition(placement: Placement, anchor: PinAnchor): Point {\n const rotated = rotatePoint(anchor, placement.rotation);\n return { x: placement.x + rotated.x, y: placement.y + rotated.y };\n}\n\n/** Distance between the reference default anchor and the body's top-left corner. */\nexport const REFERENCE_DEFAULT_OFFSET = 4;\n\n/**\n * Local anchor of a symbol's reference designator: the explicit override, else the body's\n * top-left corner lifted by {@link REFERENCE_DEFAULT_OFFSET}.\n */\nexport function referenceAnchor(outline: Rect | undefined, override?: Point): Point {\n if (override !== undefined) {\n return { x: override.x, y: override.y };\n }\n if (outline === undefined) {\n return { x: 0, y: -REFERENCE_DEFAULT_OFFSET };\n }\n return { x: outline.x, y: outline.y - REFERENCE_DEFAULT_OFFSET };\n}\n\n/** World position of a symbol's reference designator anchor. */\nexport function referencePosition(\n placement: Placement,\n outline: Rect | undefined,\n override?: Point,\n): Point {\n return symbolPinPosition(placement, referenceAnchor(outline, override));\n}\n\n/** Bounding box of a symbol: its transformed outline, else its pins, else its origin. */\nexport function symbolBounds(\n placement: Placement,\n outline: Rect | undefined,\n pins: Readonly<Record<string, PinAnchor>>,\n): Rect | undefined {\n if (outline !== undefined) {\n const corners: Point[] = [\n { x: outline.x, y: outline.y },\n { x: outline.x + outline.width, y: outline.y },\n { x: outline.x, y: outline.y + outline.height },\n { x: outline.x + outline.width, y: outline.y + outline.height },\n ];\n return boundsOfPoints(corners.map((corner) => symbolPinPosition(placement, corner)));\n }\n const anchors = Object.values(pins).map((anchor) => symbolPinPosition(placement, anchor));\n if (anchors.length > 0) {\n return boundsOfPoints(anchors);\n }\n return { x: placement.x, y: placement.y, width: 0, height: 0 };\n}\n","import type { Diagnostic } from '../../format/diagnostics';\nimport { throwIfErrors } from '../../format/errors';\nimport type { Rect, SchematicDocument } from '../../format/types';\nimport type { Point } from '../../format/value';\nimport { builtinSymbolKind, netNameOf, parseDeviceReference } from '../device/reference';\nimport type { DeviceSymbolProvider } from '../device/symbol';\nimport {\n boundsOfPoints,\n pointOnPolyline,\n pointsEqual,\n unionBounds,\n DEFAULT_TOLERANCE,\n} from '../geometry/point';\nimport { symbolBounds, symbolPinPosition } from '../geometry/transform';\n\nexport interface SchematicPinInstance {\n readonly symbolId: string;\n readonly pinId: string;\n readonly position: Point;\n /** True when the pin is not connected to any wire, label or other pin. */\n readonly open: boolean;\n /** Name of the net the pin belongs to; `null` for anonymous nets. */\n readonly netName: string | null;\n}\n\nexport type SchematicNetMember =\n | { readonly kind: 'pin'; readonly symbolId: string; readonly pinId: string }\n | { readonly kind: 'label'; readonly symbolId: string }\n | { readonly kind: 'power'; readonly symbolId: string }\n | { readonly kind: 'ground'; readonly symbolId: string };\n\nexport interface SchematicNet {\n /** Name contributed by the single naming connection point; `null` when anonymous. */\n readonly name: string | null;\n readonly wireIds: readonly string[];\n readonly members: readonly SchematicNetMember[];\n}\n\nexport interface DanglingWireEnd {\n readonly wireId: string;\n readonly end: 'start' | 'end';\n readonly point: Point;\n}\n\nexport interface SchematicTopologyOptions {\n readonly devices?: DeviceSymbolProvider;\n /** Coordinate comparison tolerance in page units; defaults to exact matching. */\n readonly tolerance?: number;\n}\n\nexport interface SchematicTopology {\n readonly nets: readonly SchematicNet[];\n readonly pins: readonly SchematicPinInstance[];\n readonly danglingWireEnds: readonly DanglingWireEnd[];\n /** Bounding box of all wires, pins and symbol outlines. */\n readonly bounds: Rect | undefined;\n}\n\ntype Connection =\n | {\n readonly kind: 'pin';\n readonly symbolId: string;\n readonly pinId: string;\n readonly point: Point;\n }\n | {\n readonly kind: 'label' | 'power' | 'ground';\n readonly symbolId: string;\n readonly point: Point;\n /** Net name contributed by this connection point. */\n readonly name: string;\n };\n\n/**\n * Derives nets from wires, explicit junctions and symbol connection points (#6).\n *\n * @throws {SchematicError} when a device cannot be resolved or a net has conflicting labels.\n */\nexport function deriveSchematicTopology(\n document: SchematicDocument,\n options: SchematicTopologyOptions = {},\n): SchematicTopology {\n const diagnostics: Diagnostic[] = [];\n const tolerance = options.tolerance ?? DEFAULT_TOLERANCE;\n const { devices } = options;\n const { symbols, wires, junctions } = document.sheet;\n\n const connections: Connection[] = [];\n let bounds: Rect | undefined;\n\n for (const symbol of symbols) {\n bounds = unionBounds(bounds, { x: symbol.x, y: symbol.y, width: 0, height: 0 });\n const builtin = builtinSymbolKind(symbol.device);\n if (builtin !== undefined) {\n const net = netNameOf(symbol);\n if (net !== undefined) {\n connections.push({\n kind: builtin,\n symbolId: symbol.id,\n point: { x: symbol.x, y: symbol.y },\n name: net,\n });\n }\n continue;\n }\n\n const reference = parseDeviceReference(symbol.device);\n if (reference === undefined) {\n if (devices !== undefined) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-reference',\n message: `Symbol \"${symbol.id}\" has an invalid device reference ${JSON.stringify(symbol.device)}.`,\n entity: { kind: 'symbol', id: symbol.id },\n });\n }\n continue;\n }\n if (devices === undefined) {\n continue;\n }\n\n const definition = devices.getDeviceSymbol(reference);\n const name = devices.getDeviceName(reference);\n if (name === undefined) {\n diagnostics.push({\n severity: 'error',\n code: 'device/unresolved',\n message: `Symbol \"${symbol.id}\" references unresolved device ${JSON.stringify(symbol.device)}.`,\n entity: { kind: 'symbol', id: symbol.id },\n });\n continue;\n }\n if (definition === undefined) {\n continue;\n }\n\n bounds = unionBounds(bounds, symbolBounds(symbol, definition.bounds, definition.pins));\n for (const [pinId, anchor] of Object.entries(definition.pins)) {\n const position = symbolPinPosition(symbol, anchor);\n connections.push({ kind: 'pin', symbolId: symbol.id, pinId, point: position });\n bounds = unionBounds(bounds, { x: position.x, y: position.y, width: 0, height: 0 });\n }\n }\n\n for (const wire of wires) {\n bounds = unionBounds(bounds, boundsOfPoints(wire.points));\n }\n\n const wireIndex = new Map<string, number>();\n wires.forEach((wire, index) => wireIndex.set(wire.id, index));\n const wireCount = wires.length;\n const parent = new Array<number>(wireCount + connections.length);\n for (let index = 0; index < parent.length; index += 1) {\n parent[index] = index;\n }\n\n const find = (node: number): number => {\n let root = node;\n while (parent[root] !== root) {\n const next = parent[root] as number;\n parent[root] = parent[next] as number;\n root = next;\n }\n return root;\n };\n\n const union = (a: number, b: number): void => {\n const rootA = find(a);\n const rootB = find(b);\n if (rootA !== rootB) {\n parent[rootB] = rootA;\n }\n };\n\n for (const junction of junctions) {\n const targets = junction.wires\n .map((wireId) => wireIndex.get(wireId))\n .filter((index): index is number => index !== undefined);\n const [first, ...rest] = targets;\n if (first === undefined) {\n continue;\n }\n for (const target of rest) {\n union(first, target);\n }\n }\n\n /** Wire index → connection indexes attached to it. */\n const wireAttachments = new Map<number, number[]>();\n connections.forEach((connection, connectionIndex) => {\n wires.forEach((wire, index) => {\n if (!pointOnPolyline(wire.points, connection.point, tolerance)) {\n return;\n }\n union(index, wireCount + connectionIndex);\n const attached = wireAttachments.get(index);\n if (attached === undefined) {\n wireAttachments.set(index, [connectionIndex]);\n } else {\n attached.push(connectionIndex);\n }\n });\n });\n\n const groups = new Map<number, { wires: number[]; connections: number[] }>();\n const groupOf = (root: number): { wires: number[]; connections: number[] } => {\n const existing = groups.get(root);\n if (existing !== undefined) {\n return existing;\n }\n const created = { wires: [], connections: [] };\n groups.set(root, created);\n return created;\n };\n wires.forEach((_, index) => {\n groupOf(find(index)).wires.push(index);\n });\n connections.forEach((_, connectionIndex) => {\n groupOf(find(wireCount + connectionIndex)).connections.push(connectionIndex);\n });\n\n const netOfConnection = new Map<number, SchematicNet>();\n const nets: SchematicNet[] = [];\n for (const group of mergeGroupsByName(groups, connections, diagnostics)) {\n const connected = group.wires.length > 0 || group.connections.length >= 2;\n if (group.connections.length === 0 || !connected) {\n continue;\n }\n const name = group.name;\n\n const members: SchematicNetMember[] = group.connections\n .map((index) => connections[index])\n .map((connection): SchematicNetMember | undefined => {\n if (connection === undefined) {\n return undefined;\n }\n return connection.kind === 'pin'\n ? { kind: 'pin', symbolId: connection.symbolId, pinId: connection.pinId }\n : { kind: connection.kind, symbolId: connection.symbolId };\n })\n .filter((member): member is SchematicNetMember => member !== undefined)\n .sort(compareMembers);\n\n const net: SchematicNet = {\n name,\n wireIds: group.wires\n .map((index) => wires[index]?.id)\n .filter((id): id is string => id !== undefined)\n .sort(),\n members,\n };\n nets.push(net);\n for (const index of group.connections) {\n netOfConnection.set(index, net);\n }\n }\n\n const pins: SchematicPinInstance[] = [];\n connections.forEach((connection, index) => {\n if (connection.kind !== 'pin') {\n return;\n }\n const net = netOfConnection.get(index);\n pins.push({\n symbolId: connection.symbolId,\n pinId: connection.pinId,\n position: connection.point,\n open: net === undefined,\n netName: net?.name ?? null,\n });\n });\n pins.sort((a, b) => a.symbolId.localeCompare(b.symbolId) || a.pinId.localeCompare(b.pinId));\n\n const danglingWireEnds: DanglingWireEnd[] = [];\n wires.forEach((wire, index) => {\n const endpoints: readonly { end: 'start' | 'end'; point: Point | undefined }[] = [\n { end: 'start', point: wire.points[0] },\n { end: 'end', point: wire.points[wire.points.length - 1] },\n ];\n for (const { end, point } of endpoints) {\n if (point === undefined) {\n continue;\n }\n const attached = (wireAttachments.get(index) ?? []).some((connectionIndex) => {\n const connection = connections[connectionIndex];\n return connection !== undefined && pointsEqual(connection.point, point, tolerance);\n });\n const junctioned = junctions.some(\n (junction) =>\n junction.wires.includes(wire.id) &&\n pointsEqual({ x: junction.x, y: junction.y }, point, tolerance),\n );\n if (!attached && !junctioned) {\n danglingWireEnds.push({ wireId: wire.id, end, point });\n }\n }\n });\n danglingWireEnds.sort((a, b) => a.wireId.localeCompare(b.wireId) || a.end.localeCompare(b.end));\n\n throwIfErrors(diagnostics);\n\n return {\n nets: nets.sort(\n (a, b) => compareNetNames(a.name, b.name) || compareMembers(a.members[0], b.members[0]),\n ),\n pins,\n danglingWireEnds,\n bounds,\n };\n}\n\n/** A connected group of wires and connection points, named by the labels attached to it. */\ninterface NetGroup {\n readonly wires: number[];\n readonly connections: number[];\n readonly name: string | null;\n}\n\n/**\n * Folds groups that carry the same net name into one group: net names are the merge key, so two\n * `VCC` ports on separate wires are the same net (KiCad-style name-based connectivity).\n * A group that declares two different names is an error.\n */\nfunction mergeGroupsByName(\n groups: ReadonlyMap<number, { wires: number[]; connections: number[] }>,\n connections: readonly Connection[],\n diagnostics: Diagnostic[],\n): readonly NetGroup[] {\n const byName = new Map<string, { wires: number[]; connections: number[] }>();\n const merged: NetGroup[] = [];\n for (const group of groups.values()) {\n const names = group.connections\n .map((index) => connections[index])\n .filter(\n (connection): connection is Extract<Connection, { kind: 'label' | 'power' | 'ground' }> =>\n connection !== undefined && connection.kind !== 'pin',\n )\n .map((connection) => connection.name)\n .sort();\n if (names.length > 1) {\n diagnostics.push({\n severity: 'error',\n code: 'net/naming-conflict',\n message: `Net has conflicting names: ${names.map((item) => JSON.stringify(item)).join(', ')}.`,\n });\n }\n const name = names.length === 1 ? (names[0] as string) : null;\n // Only groups that already connect something are folded together: merging is about joining\n // nets, not about giving free-floating labels a net of their own.\n if (name === null || (group.wires.length === 0 && group.connections.length < 2)) {\n merged.push({ wires: group.wires, connections: group.connections, name });\n continue;\n }\n const existing = byName.get(name);\n if (existing === undefined) {\n const created = { wires: [...group.wires], connections: [...group.connections] };\n byName.set(name, created);\n merged.push({ ...created, name });\n continue;\n }\n existing.wires.push(...group.wires);\n existing.connections.push(...group.connections);\n }\n return merged;\n}\n\nconst KIND_ORDER: readonly SchematicNetMember['kind'][] = ['label', 'power', 'ground', 'pin'];\n\nfunction compareMembers(\n a: SchematicNetMember | undefined,\n b: SchematicNetMember | undefined,\n): number {\n if (a === undefined || b === undefined) {\n return a === undefined ? (b === undefined ? 0 : 1) : -1;\n }\n if (a.kind !== b.kind) {\n return KIND_ORDER.indexOf(a.kind) - KIND_ORDER.indexOf(b.kind);\n }\n const bySymbol = a.symbolId.localeCompare(b.symbolId);\n if (bySymbol !== 0) {\n return bySymbol;\n }\n const pinA = a.kind === 'pin' ? a.pinId : '';\n const pinB = b.kind === 'pin' ? b.pinId : '';\n return pinA.localeCompare(pinB);\n}\n\nfunction compareNetNames(a: string | null, b: string | null): number {\n if (a === null || b === null) {\n return a === null ? (b === null ? 0 : 1) : -1;\n }\n return a.localeCompare(b);\n}\n","import { parseSchematic } from '../format/parse-schematic';\nimport type { SchematicDocument } from '../../format/types';\nimport {\n deriveSchematicTopology,\n type SchematicTopology,\n type SchematicTopologyOptions,\n} from '../netlist/derive';\n\nexport type LoadSchematicOptions = SchematicTopologyOptions;\n\nexport interface LoadedSchematic {\n readonly document: SchematicDocument;\n readonly topology: SchematicTopology;\n}\n\n/** Parses a schematic and derives its topology. @throws {SchematicError} on any contract violation. */\nexport function loadSchematic(\n source: string | SchematicDocument,\n options: LoadSchematicOptions = {},\n): LoadedSchematic {\n const document = parseSchematic(source);\n return { document, topology: deriveSchematicTopology(document, options) };\n}\n","import { isAssetReference } from '../../format/value';\nimport type { PropertyValue } from '../../format/value';\nimport { isRecord } from '../../format/validate';\n\n/** Property value types a device may declare (#7). */\nexport const PROPERTY_TYPES = [\n 'string',\n 'integer',\n 'number',\n 'boolean',\n 'color',\n 'enum',\n 'image',\n 'binary',\n] as const;\n\nexport type PropertyType = (typeof PROPERTY_TYPES)[number];\n\nexport interface PropertyOption {\n readonly value: string;\n readonly label: string;\n}\n\n/**\n * Descriptor of one device property (#7). `default` is the declared default, `title` falls back to\n * the key, and the remaining fields carry the constraints of the type.\n */\nexport interface PropertyDescriptor {\n readonly key: string;\n readonly type: PropertyType;\n readonly title?: string;\n readonly description?: string;\n /** Declared default; absent when the description omits it or it breaks its own constraints. */\n readonly default?: PropertyValue;\n /** When true an explicit `null` is a valid instance value. */\n readonly nullable?: boolean;\n /** `string`: maximum length in Unicode code points. */\n readonly maxLength?: number;\n /** `integer` / `number`: closed lower bound. */\n readonly min?: number;\n /** `integer` / `number`: closed upper bound. */\n readonly max?: number;\n /** `number`: open lower bound; mutually exclusive with `min`. */\n readonly exclusiveMin?: number;\n /** `integer` / `number`: editing step, always greater than zero. */\n readonly step?: number;\n /** `number`: display unit of the stored value. */\n readonly unit?: string;\n /** `color`: whether `#RRGGBBAA` values are accepted. */\n readonly alpha?: boolean;\n /** `enum`: non-empty option list. */\n readonly options?: readonly PropertyOption[];\n /** `image` / `binary`: host-side payload limit in bytes. */\n readonly maxBytes?: number;\n /** `image`: host-side pixel limit. */\n readonly maxPixels?: number;\n}\n\nexport interface PropertyValueProblem {\n readonly code: 'schema/invalid-type' | 'schema/invalid-value';\n readonly message: string;\n}\n\nconst COLOR_PATTERN = /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;\n\nexport function isPropertyType(value: unknown): value is PropertyType {\n return typeof value === 'string' && (PROPERTY_TYPES as readonly string[]).includes(value);\n}\n\n/** Uppercases a `#RRGGBB` / `#RRGGBBAA` color; `undefined` when the text is not a color. */\nexport function normalizeColor(value: string): string | undefined {\n return COLOR_PATTERN.test(value) ? value.toUpperCase() : undefined;\n}\n\n/** Parses one declared property; `undefined` when the type is unknown or the descriptor unusable. */\nexport function parsePropertyDescriptor(key: string, raw: unknown): PropertyDescriptor | undefined {\n if (!isRecord(raw)) {\n return undefined;\n }\n const type = raw['type'];\n if (!isPropertyType(type)) {\n return undefined;\n }\n const draft: {\n -readonly [K in keyof PropertyDescriptor]: PropertyDescriptor[K];\n } = { key, type };\n\n const title = readText(raw['title']);\n if (title !== undefined) {\n draft.title = title;\n }\n const description = readText(raw['description']);\n if (description !== undefined) {\n draft.description = description;\n }\n if (raw['nullable'] === true) {\n draft.nullable = true;\n }\n\n if (type === 'string') {\n const maxLength = readCount(raw['maxLength']);\n if (maxLength !== undefined) {\n draft.maxLength = maxLength;\n }\n }\n if (type === 'integer' || type === 'number') {\n const min = readFinite(raw['min']);\n if (min !== undefined) {\n draft.min = min;\n }\n const max = readFinite(raw['max']);\n if (max !== undefined) {\n draft.max = max;\n }\n const step = readFinite(raw['step']);\n if (step !== undefined && step > 0) {\n draft.step = step;\n }\n if (type === 'number') {\n const exclusiveMin = readFinite(raw['exclusiveMin']);\n if (exclusiveMin !== undefined) {\n draft.exclusiveMin = exclusiveMin;\n }\n const unit = readText(raw['unit']);\n if (unit !== undefined) {\n draft.unit = unit;\n }\n }\n }\n if (type === 'color' && raw['alpha'] === true) {\n draft.alpha = true;\n }\n if (type === 'enum') {\n const options = readOptions(raw['options']);\n if (options === undefined) {\n return undefined;\n }\n draft.options = options;\n }\n if (type === 'image' || type === 'binary') {\n const maxBytes = readCount(raw['maxBytes']);\n if (maxBytes !== undefined) {\n draft.maxBytes = maxBytes;\n }\n if (type === 'image') {\n const maxPixels = readCount(raw['maxPixels']);\n if (maxPixels !== undefined) {\n draft.maxPixels = maxPixels;\n }\n }\n }\n\n const defaultValue = raw['default'];\n if (defaultValue !== undefined && propertyValueProblem(draft, defaultValue) === undefined) {\n draft.default = defaultValue as PropertyValue;\n }\n return draft;\n}\n\n/** Parses the `properties` object of a device description, skipping unusable declarations. */\nexport function readPropertyDescriptors(raw: unknown): ReadonlyMap<string, PropertyDescriptor> {\n const descriptors = new Map<string, PropertyDescriptor>();\n if (!isRecord(raw)) {\n return descriptors;\n }\n for (const [key, value] of Object.entries(raw)) {\n if (key.length === 0) {\n continue;\n }\n const descriptor = parsePropertyDescriptor(key, value);\n if (descriptor !== undefined) {\n descriptors.set(key, descriptor);\n }\n }\n return descriptors;\n}\n\n/** Constraint violation of `value` for `descriptor`; `undefined` when the value is acceptable. */\nexport function propertyValueProblem(\n descriptor: PropertyDescriptor,\n value: unknown,\n): PropertyValueProblem | undefined {\n const key = descriptor.key;\n if (value === null) {\n return descriptor.nullable === true\n ? undefined\n : { code: 'schema/invalid-value', message: `Property \"${key}\" is not nullable.` };\n }\n switch (descriptor.type) {\n case 'string': {\n if (typeof value !== 'string') {\n return { code: 'schema/invalid-type', message: `Property \"${key}\" must be a string.` };\n }\n const maxLength = descriptor.maxLength;\n if (maxLength !== undefined && [...value].length > maxLength) {\n return {\n code: 'schema/invalid-value',\n message: `Property \"${key}\" must be at most ${String(maxLength)} characters.`,\n };\n }\n return undefined;\n }\n case 'integer': {\n if (typeof value !== 'number' || !Number.isSafeInteger(value)) {\n return {\n code: 'schema/invalid-type',\n message: `Property \"${key}\" must be a safe integer.`,\n };\n }\n return boundProblem(descriptor, value);\n }\n case 'number': {\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n return {\n code: 'schema/invalid-type',\n message: `Property \"${key}\" must be a finite number.`,\n };\n }\n if (descriptor.exclusiveMin !== undefined && value <= descriptor.exclusiveMin) {\n return {\n code: 'schema/invalid-value',\n message: `Property \"${key}\" must be greater than ${String(descriptor.exclusiveMin)}.`,\n };\n }\n return boundProblem(descriptor, value);\n }\n case 'boolean':\n return typeof value === 'boolean'\n ? undefined\n : { code: 'schema/invalid-type', message: `Property \"${key}\" must be a boolean.` };\n case 'color': {\n if (typeof value !== 'string') {\n return { code: 'schema/invalid-type', message: `Property \"${key}\" must be a string.` };\n }\n const normalized = normalizeColor(value);\n if (normalized === undefined) {\n return {\n code: 'schema/invalid-value',\n message: `Property \"${key}\" must be a \"#RRGGBB\" color.`,\n };\n }\n if (descriptor.alpha !== true && normalized.length === 9) {\n return {\n code: 'schema/invalid-value',\n message: `Property \"${key}\" does not accept alpha; use \"#RRGGBB\".`,\n };\n }\n return undefined;\n }\n case 'enum': {\n if (typeof value !== 'string') {\n return { code: 'schema/invalid-type', message: `Property \"${key}\" must be a string.` };\n }\n const allowed = (descriptor.options ?? []).map((option) => option.value);\n return allowed.includes(value)\n ? undefined\n : {\n code: 'schema/invalid-value',\n message: `Property \"${key}\" must be one of ${allowed.map((entry) => JSON.stringify(entry)).join(', ')}.`,\n };\n }\n case 'image':\n case 'binary':\n return isAssetReference(value)\n ? undefined\n : {\n code: 'schema/invalid-type',\n message: `Property \"${key}\" must be a resource reference { \"src\", \"mode\" }.`,\n };\n }\n}\n\n/** Canonical stored value: colors are uppercased, everything else is stored as given. */\nexport function normalizePropertyValue(\n descriptor: PropertyDescriptor,\n value: PropertyValue,\n): PropertyValue {\n if (descriptor.type === 'color' && typeof value === 'string') {\n return normalizeColor(value) ?? value;\n }\n return value;\n}\n\nfunction boundProblem(\n descriptor: PropertyDescriptor,\n value: number,\n): PropertyValueProblem | undefined {\n const key = descriptor.key;\n if (descriptor.min !== undefined && value < descriptor.min) {\n return {\n code: 'schema/invalid-value',\n message: `Property \"${key}\" must be at least ${String(descriptor.min)}.`,\n };\n }\n if (descriptor.max !== undefined && value > descriptor.max) {\n return {\n code: 'schema/invalid-value',\n message: `Property \"${key}\" must be at most ${String(descriptor.max)}.`,\n };\n }\n return undefined;\n}\n\nfunction readText(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nfunction readFinite(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\nfunction readCount(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 ? value : undefined;\n}\n\nfunction readOptions(value: unknown): readonly PropertyOption[] | undefined {\n if (!Array.isArray(value) || value.length === 0) {\n return undefined;\n }\n const options: PropertyOption[] = [];\n const seen = new Set<string>();\n for (const entry of value) {\n if (!isRecord(entry)) {\n return undefined;\n }\n const optionValue = entry['value'];\n const label = entry['label'];\n if (\n typeof optionValue !== 'string' ||\n optionValue.length === 0 ||\n typeof label !== 'string' ||\n label.length === 0 ||\n seen.has(optionValue)\n ) {\n return undefined;\n }\n seen.add(optionValue);\n options.push({ value: optionValue, label });\n }\n return options;\n}\n","import type { SchematicDocument } from '../../format/types';\n\nexport type ElementKind = 'symbol' | 'wire' | 'junction';\n\nexport type ElementIdFactory = (kind: ElementKind, document: SchematicDocument) => string;\n\nfunction usedIds(document: SchematicDocument, kind: ElementKind): ReadonlySet<string> {\n const ids =\n kind === 'symbol'\n ? document.sheet.symbols.map((symbol) => symbol.id)\n : kind === 'wire'\n ? document.sheet.wires.map((wire) => wire.id)\n : document.sheet.junctions.map((junction) => junction.id);\n return new Set(ids);\n}\n\n/**\n * Random UUID v4, falling back to `getRandomValues` (or `Math.random` in ancient runtimes).\n * Ids are opaque identity: they never collide with the designators and net names users edit.\n */\nexport function createUuid(): string {\n const source = randomSource();\n if (typeof source?.randomUUID === 'function') {\n return source.randomUUID();\n }\n const bytes = new Uint8Array(16);\n if (typeof source?.getRandomValues === 'function') {\n source.getRandomValues(bytes);\n } else {\n for (let index = 0; index < bytes.length; index += 1) {\n bytes[index] = Math.floor(Math.random() * 256);\n }\n }\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;\n const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('');\n return [\n hex.slice(0, 8),\n hex.slice(8, 12),\n hex.slice(12, 16),\n hex.slice(16, 20),\n hex.slice(20),\n ].join('-');\n}\n\n/** Web Crypto as available in browsers and Node; core does not depend on either's typings. */\ninterface RandomSource {\n randomUUID?: () => string;\n getRandomValues?: (array: Uint8Array) => Uint8Array;\n}\n\nfunction randomSource(): RandomSource | undefined {\n return (globalThis as { crypto?: RandomSource }).crypto;\n}\n\n/** Fresh UUID v4 that no element of `kind` uses yet. */\nexport const defaultElementIdFactory: ElementIdFactory = (kind, document) => {\n const used = usedIds(document, kind);\n let id = createUuid();\n while (used.has(id)) {\n id = createUuid();\n }\n return id;\n};\n","import { isAssetReference } from '../../format/value';\nimport type { Diagnostic } from '../../format/diagnostics';\nimport { throwIfErrors } from '../../format/errors';\nimport { parseSchematic } from '../format/parse-schematic';\nimport type { Point, PropertyValue } from '../../format/value';\nimport type {\n SchematicDocument,\n SchematicJunction,\n SchematicSymbol,\n SchematicWire,\n} from '../../format/types';\nimport { toPointer } from '../../format/validate';\nimport {\n normalizePropertyValue,\n propertyValueProblem,\n type PropertyDescriptor,\n} from '../device/properties';\nimport { parseDeviceReference } from '../device/reference';\nimport { defaultNetName, hasDesignator, namesNet, symbolRole } from '../device/reference';\nimport type { SymbolRole } from '../device/reference';\nimport type { SchematicTopologyOptions } from '../netlist/derive';\nimport { DEFAULT_TOLERANCE, pointOnPolyline } from '../geometry/point';\nimport { defaultElementIdFactory, type ElementIdFactory } from './ids';\n\nexport type SchematicCommand =\n | {\n readonly type: 'add-symbol';\n readonly id?: string;\n readonly device: string;\n readonly x: number;\n readonly y: number;\n readonly rotation?: number;\n readonly properties?: Readonly<Record<string, PropertyValue>>;\n /** Component reference designator; defaults to the new symbol's id. */\n readonly designator?: string;\n /** Net name for labels / power / ground; power and ground fall back to VCC / GND. */\n readonly net?: string;\n /** Reference designator anchor in symbol-local coordinates; `null` clears it. */\n readonly reference?: Point | null;\n }\n | {\n readonly type: 'update-symbol';\n readonly id: string;\n readonly device?: string;\n readonly x?: number;\n readonly y?: number;\n readonly rotation?: number;\n /** Replaces the whole property map when provided. */\n readonly properties?: Readonly<Record<string, PropertyValue>>;\n /** Reference designator; `null` clears the override, `undefined` keeps it. */\n readonly designator?: string | null;\n /** Net name; `null` clears it, `undefined` keeps it. */\n readonly net?: string | null;\n /** Reference designator anchor; `null` clears it, `undefined` keeps it. */\n readonly reference?: Point | null;\n }\n | { readonly type: 'remove-symbol'; readonly id: string }\n | {\n readonly type: 'set-symbol-property';\n readonly id: string;\n readonly key: string;\n readonly value: PropertyValue;\n }\n | { readonly type: 'remove-symbol-property'; readonly id: string; readonly key: string }\n | { readonly type: 'add-wire'; readonly id?: string; readonly points: readonly Point[] }\n | { readonly type: 'set-wire-points'; readonly id: string; readonly points: readonly Point[] }\n | { readonly type: 'remove-wire'; readonly id: string }\n | {\n readonly type: 'add-junction';\n readonly id?: string;\n readonly x: number;\n readonly y: number;\n readonly wires: readonly string[];\n }\n | {\n readonly type: 'update-junction';\n readonly id: string;\n readonly x?: number;\n readonly y?: number;\n readonly wires?: readonly string[];\n }\n | { readonly type: 'remove-junction'; readonly id: string };\n\nexport interface EditEffect {\n readonly kind: 'junction-removed';\n readonly id: string;\n readonly reason: 'wire-removed' | 'junction-detached';\n}\n\nexport interface SchematicEditOptions extends SchematicTopologyOptions {\n readonly createId?: ElementIdFactory;\n /** How to handle junctions that stop lying on a wire after its geometry changes. */\n readonly onJunctionConflict?: 'reject' | 'remove';\n /** Receives cascaded removals such as junctions dropped with their wire. */\n readonly onEffect?: (effect: EditEffect) => void;\n}\n\n/**\n * Applies an edit command to a copy of `document`.\n *\n * @throws {SchematicError} when the command is invalid; the input document is never mutated.\n */\nexport function applySchematicCommand(\n document: SchematicDocument,\n command: SchematicCommand,\n options: SchematicEditOptions = {},\n): SchematicDocument {\n const symbols = [...document.sheet.symbols];\n const wires = [...document.sheet.wires];\n const junctions = [...document.sheet.junctions];\n const diagnostics: Diagnostic[] = [];\n const effects: EditEffect[] = [];\n const createId = options.createId ?? defaultElementIdFactory;\n const draft = (): SchematicDocument => ({ ...document, sheet: { symbols, wires, junctions } });\n\n switch (command.type) {\n case 'add-symbol': {\n const device = requireDevice(command.device, diagnostics);\n const id = command.id ?? createId('symbol', draft());\n const properties = normalizeProperties(\n command.properties,\n deviceDescriptors(device, options),\n diagnostics,\n );\n const reference = resolveReference(\n command.reference,\n undefined,\n ['sheet', 'symbols'],\n diagnostics,\n );\n if (device !== undefined) {\n const role = symbolRole(device);\n const designator = resolveDesignator(command.designator, role, id, diagnostics);\n const net = resolveNet(command.net, role, diagnostics);\n symbols.push(\n withProperties(\n {\n id,\n device,\n x: command.x,\n y: command.y,\n rotation: command.rotation ?? 0,\n ...(designator === undefined ? {} : { designator }),\n ...(net === undefined ? {} : { net }),\n ...(hasDesignator(role) && reference !== undefined ? { reference } : {}),\n },\n properties,\n ),\n );\n }\n break;\n }\n case 'update-symbol': {\n const index = findIndex(symbols, command.id, 'symbol', diagnostics);\n const current = index === -1 ? undefined : symbols[index];\n if (current !== undefined) {\n const device =\n command.device === undefined\n ? current.device\n : requireDevice(command.device, diagnostics);\n const properties =\n command.properties === undefined\n ? current.properties\n : normalizeProperties(\n command.properties,\n deviceDescriptors(device, options),\n diagnostics,\n );\n const reference = resolveReference(\n command.reference,\n current.reference,\n ['sheet', 'symbols', String(index)],\n diagnostics,\n );\n if (device !== undefined) {\n const role = symbolRole(device);\n const designator = resolveOptionalText(\n command.designator,\n current.designator,\n hasDesignator(role),\n 'designator',\n diagnostics,\n );\n const net = resolveOptionalText(\n command.net,\n current.net,\n namesNet(role),\n 'net',\n diagnostics,\n );\n symbols[index] = withProperties(\n {\n id: current.id,\n device,\n x: command.x ?? current.x,\n y: command.y ?? current.y,\n rotation: command.rotation ?? current.rotation,\n ...(designator === undefined ? {} : { designator }),\n ...(net === undefined ? {} : { net }),\n ...(hasDesignator(role) && reference !== undefined ? { reference } : {}),\n },\n properties,\n );\n }\n }\n break;\n }\n case 'remove-symbol': {\n const index = findIndex(symbols, command.id, 'symbol', diagnostics);\n if (index !== -1) {\n symbols.splice(index, 1);\n }\n break;\n }\n case 'set-symbol-property': {\n const index = findIndex(symbols, command.id, 'symbol', diagnostics);\n const current = index === -1 ? undefined : symbols[index];\n if (current !== undefined) {\n const value = checkPropertyValue(\n command.key,\n command.value,\n deviceDescriptors(current.device, options)?.get(command.key),\n diagnostics,\n );\n if (value !== undefined) {\n symbols[index] = withProperties(baseOf(current), {\n ...(current.properties ?? {}),\n [command.key]: value,\n });\n }\n }\n break;\n }\n case 'remove-symbol-property': {\n const index = findIndex(symbols, command.id, 'symbol', diagnostics);\n const current = index === -1 ? undefined : symbols[index];\n if (current !== undefined) {\n const properties = { ...(current.properties ?? {}) };\n if (!Object.prototype.hasOwnProperty.call(properties, command.key)) {\n diagnostics.push({\n severity: 'error',\n code: 'edit/unknown-entity',\n message: `Symbol \"${current.id}\" has no property ${JSON.stringify(command.key)}.`,\n entity: { kind: 'symbol', id: current.id },\n });\n } else {\n delete properties[command.key];\n symbols[index] = withProperties(baseOf(current), properties);\n }\n }\n break;\n }\n case 'add-wire': {\n const id = command.id ?? createId('wire', draft());\n const wire = makeWire(id, command.points, diagnostics);\n if (wire !== undefined) {\n wires.push(wire);\n }\n break;\n }\n case 'set-wire-points': {\n const index = findIndex(wires, command.id, 'wire', diagnostics);\n if (index !== -1) {\n const wire = makeWire(command.id, command.points, diagnostics);\n if (wire !== undefined) {\n wires[index] = wire;\n }\n }\n break;\n }\n case 'remove-wire': {\n const index = findIndex(wires, command.id, 'wire', diagnostics);\n if (index !== -1) {\n wires.splice(index, 1);\n for (let junctionIndex = junctions.length - 1; junctionIndex >= 0; junctionIndex -= 1) {\n const junction = junctions[junctionIndex];\n if (junction === undefined || !junction.wires.includes(command.id)) {\n continue;\n }\n effects.push({ kind: 'junction-removed', id: junction.id, reason: 'wire-removed' });\n junctions.splice(junctionIndex, 1);\n }\n }\n break;\n }\n case 'add-junction': {\n const id = command.id ?? createId('junction', draft());\n const junction = makeJunction(id, command.x, command.y, command.wires, diagnostics);\n if (junction !== undefined) {\n junctions.push(junction);\n }\n break;\n }\n case 'update-junction': {\n const index = findIndex(junctions, command.id, 'junction', diagnostics);\n const current = index === -1 ? undefined : junctions[index];\n if (current !== undefined) {\n const junction = makeJunction(\n current.id,\n command.x ?? current.x,\n command.y ?? current.y,\n command.wires ?? current.wires,\n diagnostics,\n );\n if (junction !== undefined) {\n junctions[index] = junction;\n }\n }\n break;\n }\n case 'remove-junction': {\n const index = findIndex(junctions, command.id, 'junction', diagnostics);\n if (index !== -1) {\n junctions.splice(index, 1);\n }\n break;\n }\n default: {\n diagnostics.push({\n severity: 'error',\n code: 'edit/invalid-command',\n message: `Unsupported command ${JSON.stringify((command as { type?: unknown }).type)}.`,\n });\n }\n }\n\n throwIfErrors(diagnostics);\n\n const result = validateSheet(draft(), options, diagnostics, effects);\n throwIfErrors(diagnostics);\n\n for (const effect of effects) {\n options.onEffect?.(effect);\n }\n return result;\n}\n\nfunction validateSheet(\n candidate: SchematicDocument,\n options: SchematicEditOptions,\n diagnostics: Diagnostic[],\n effects: EditEffect[],\n): SchematicDocument {\n // Structural re-validation: ids, required fields, wire point counts, junction references.\n const parsed = parseSchematic(candidate);\n const tolerance = options.tolerance ?? DEFAULT_TOLERANCE;\n const wireById = new Map(parsed.sheet.wires.map((wire) => [wire.id, wire]));\n const survivingJunctions: SchematicJunction[] = [];\n let cascaded = false;\n\n for (const junction of parsed.sheet.junctions) {\n const detached = junction.wires.some((wireId) => {\n const wire = wireById.get(wireId);\n return (\n wire === undefined ||\n !pointOnPolyline(wire.points, { x: junction.x, y: junction.y }, tolerance)\n );\n });\n if (!detached) {\n survivingJunctions.push(junction);\n continue;\n }\n if (options.onJunctionConflict === 'remove') {\n cascaded = true;\n effects.push({ kind: 'junction-removed', id: junction.id, reason: 'junction-detached' });\n continue;\n }\n diagnostics.push({\n severity: 'error',\n code: 'junction/off-wire',\n message: `Junction \"${junction.id}\" no longer lies on every referenced wire.`,\n pointer: toPointer(['sheet', 'junctions']),\n entity: { kind: 'junction', id: junction.id },\n });\n }\n\n if (!cascaded) {\n return parsed;\n }\n return { ...parsed, sheet: { ...parsed.sheet, junctions: survivingJunctions } };\n}\n\nfunction makeWire(\n id: string,\n points: readonly Point[],\n diagnostics: Diagnostic[],\n): SchematicWire | undefined {\n if (points.length < 2) {\n diagnostics.push({\n severity: 'error',\n code: 'wire/invalid-points',\n message: `Wire \"${id}\" must contain at least two points.`,\n entity: { kind: 'wire', id },\n });\n return undefined;\n }\n return { id, points: points.map((point) => ({ x: point.x, y: point.y })) };\n}\n\nfunction makeJunction(\n id: string,\n x: number,\n y: number,\n wires: readonly string[],\n diagnostics: Diagnostic[],\n): SchematicJunction | undefined {\n if (wires.length < 2) {\n diagnostics.push({\n severity: 'error',\n code: 'schema/invalid-value',\n message: `Junction \"${id}\" must reference at least two wires.`,\n entity: { kind: 'junction', id },\n });\n return undefined;\n }\n return { id, x, y, wires: [...wires] };\n}\n\nfunction requireDevice(device: string, diagnostics: Diagnostic[]): string | undefined {\n if (parseDeviceReference(device) === undefined) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-reference',\n message: `Invalid device reference ${JSON.stringify(device)}.`,\n });\n return undefined;\n }\n return device;\n}\n\nfunction baseOf(symbol: SchematicSymbol): Omit<SchematicSymbol, 'properties' | 'reference'> {\n return {\n id: symbol.id,\n device: symbol.device,\n x: symbol.x,\n y: symbol.y,\n rotation: symbol.rotation,\n ...(symbol.designator === undefined ? {} : { designator: symbol.designator }),\n ...(symbol.net === undefined ? {} : { net: symbol.net }),\n };\n}\n\n/**\n * Reference designator for a new symbol: components keep `undefined` (the id doubles as the\n * default designator), everything else must not have one.\n */\nfunction resolveDesignator(\n value: string | undefined,\n role: SymbolRole,\n id: string,\n diagnostics: Diagnostic[],\n): string | undefined {\n if (!hasDesignator(role)) {\n if (value !== undefined) {\n diagnostics.push({\n severity: 'error',\n code: 'symbol/unsupported-field',\n message: `Symbols of role \"${role}\" carry no reference designator.`,\n });\n }\n return undefined;\n }\n const trimmed = value?.trim();\n return trimmed === undefined || trimmed.length === 0 || trimmed === id ? undefined : trimmed;\n}\n\n/** Net name for a new symbol; labels need one, power and ground fall back to their default. */\nfunction resolveNet(\n value: string | undefined,\n role: SymbolRole,\n diagnostics: Diagnostic[],\n): string | undefined {\n if (!namesNet(role)) {\n if (value !== undefined) {\n diagnostics.push({\n severity: 'error',\n code: 'symbol/unsupported-field',\n message: `Symbols of role \"${role}\" name no net.`,\n });\n }\n return undefined;\n }\n const trimmed = value?.trim();\n if (trimmed !== undefined && trimmed.length > 0) {\n return trimmed;\n }\n const fallback = defaultNetName(role);\n if (fallback === undefined) {\n diagnostics.push({\n severity: 'error',\n code: 'symbol/missing-net',\n message: `Symbols of role \"${role}\" must name the net they attach to.`,\n });\n }\n return fallback;\n}\n\n/** `null` clears the field, `undefined` keeps it, and unsupported roles cannot set it. */\nfunction resolveOptionalText(\n value: string | null | undefined,\n current: string | undefined,\n supported: boolean,\n field: 'designator' | 'net',\n diagnostics: Diagnostic[],\n): string | undefined {\n if (value === undefined) {\n return current;\n }\n if (!supported) {\n diagnostics.push({\n severity: 'error',\n code: 'symbol/unsupported-field',\n message: `This symbol must not declare \"${field}\".`,\n });\n return undefined;\n }\n if (value === null) {\n return undefined;\n }\n const trimmed = value.trim();\n if (trimmed.length === 0) {\n diagnostics.push({\n severity: 'error',\n code: 'schema/invalid-value',\n message: `${field === 'net' ? 'Net name' : 'Reference designator'} must not be empty.`,\n });\n return undefined;\n }\n return trimmed;\n}\n\nfunction withProperties(\n symbol: Omit<SchematicSymbol, 'properties'>,\n properties: Readonly<Record<string, PropertyValue>> | undefined,\n): SchematicSymbol {\n if (properties === undefined || Object.keys(properties).length === 0) {\n return symbol;\n }\n return { ...symbol, properties };\n}\n\n/** `reference: null` clears the override and falls back to the default anchor. */\nfunction resolveReference(\n value: Point | null | undefined,\n current: Point | undefined,\n path: readonly string[],\n diagnostics: Diagnostic[],\n): Point | undefined {\n if (value === undefined) {\n return current;\n }\n if (value === null) {\n return undefined;\n }\n if (typeof value !== 'object' || !Number.isFinite(value.x) || !Number.isFinite(value.y)) {\n diagnostics.push({\n severity: 'error',\n code: 'schema/invalid-value',\n message: 'Symbol reference must contain finite x and y numbers.',\n pointer: toPointer([...path, 'reference']),\n });\n return undefined;\n }\n return { x: value.x, y: value.y };\n}\n\n/** Property descriptors of `device`, when the caller supplied a device registry (#7). */\nfunction deviceDescriptors(\n device: string | undefined,\n options: SchematicEditOptions,\n): ReadonlyMap<string, PropertyDescriptor> | undefined {\n const reference = device === undefined ? undefined : parseDeviceReference(device);\n return reference === undefined\n ? undefined\n : options.devices?.getDevicePropertyDescriptors?.(reference);\n}\n\nfunction normalizeProperties(\n properties: Readonly<Record<string, PropertyValue>> | undefined,\n descriptors: ReadonlyMap<string, PropertyDescriptor> | undefined,\n diagnostics: Diagnostic[],\n): Readonly<Record<string, PropertyValue>> | undefined {\n if (properties === undefined) {\n return undefined;\n }\n const normalized: Record<string, PropertyValue> = {};\n for (const [key, value] of Object.entries(properties)) {\n if (key.length === 0) {\n diagnostics.push({\n severity: 'error',\n code: 'schema/invalid-value',\n message: 'Property keys must not be empty.',\n });\n continue;\n }\n const checked = checkPropertyValue(key, value, descriptors?.get(key), diagnostics);\n if (checked !== undefined) {\n normalized[key] = checked;\n }\n }\n return normalized;\n}\n\nfunction checkPropertyValue(\n key: string,\n value: PropertyValue,\n descriptor: PropertyDescriptor | undefined,\n diagnostics: Diagnostic[],\n): PropertyValue | undefined {\n if (key.length === 0) {\n diagnostics.push({\n severity: 'error',\n code: 'schema/invalid-value',\n message: 'Property keys must not be empty.',\n });\n return undefined;\n }\n if (descriptor !== undefined) {\n const problem = propertyValueProblem(descriptor, value);\n if (problem !== undefined) {\n diagnostics.push({ severity: 'error', code: problem.code, message: problem.message });\n return undefined;\n }\n return normalizePropertyValue(descriptor, value);\n }\n if (typeof value === 'string' || typeof value === 'boolean' || value === null) {\n return value;\n }\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) {\n diagnostics.push({\n severity: 'error',\n code: 'schema/invalid-value',\n message: `Property \"${key}\" must be a finite number.`,\n });\n return undefined;\n }\n return value;\n }\n if (isAssetReference(value)) {\n return value;\n }\n diagnostics.push({\n severity: 'error',\n code: 'schema/invalid-value',\n message: `Property \"${key}\" must be a string, finite number, boolean, resource reference or null.`,\n });\n return undefined;\n}\n\nfunction findIndex<T extends { readonly id: string }>(\n items: readonly T[],\n id: string,\n kind: 'symbol' | 'wire' | 'junction',\n diagnostics: Diagnostic[],\n): number {\n const index = items.findIndex((item) => item.id === id);\n if (index === -1) {\n diagnostics.push({\n severity: 'error',\n code: 'edit/unknown-entity',\n message: `Unknown ${kind} \"${id}\".`,\n entity: { kind, id },\n });\n }\n return index;\n}\n","import type { SchematicDocument } from '../../format/types';\nimport { parseSchematic } from '../format/parse-schematic';\nimport { pointOnPolyline } from '../geometry/point';\nimport { serializeSchematic } from '../format/serialize';\nimport { deriveSchematicTopology, type SchematicTopology } from '../netlist/derive';\nimport {\n applySchematicCommand,\n type SchematicCommand,\n type SchematicEditOptions,\n} from './commands';\n\nexport interface SchematicEditorOptions extends SchematicEditOptions {\n /** Maximum number of undo steps kept; defaults to 200. */\n readonly historyLimit?: number;\n}\n\nconst DEFAULT_HISTORY_LIMIT = 200;\n\n/**\n * Stateful editor over a schematic document with undo/redo.\n * Every mutation goes through {@link applySchematicCommand}; failures leave the state untouched.\n */\nexport class SchematicEditor {\n readonly #options: SchematicEditorOptions;\n readonly #historyLimit: number;\n #past: SchematicDocument[] = [];\n #future: SchematicDocument[] = [];\n #document: SchematicDocument;\n #depth = 0;\n\n constructor(document: SchematicDocument, options: SchematicEditorOptions = {}) {\n this.#document = document;\n this.#options = options;\n this.#historyLimit = options.historyLimit ?? DEFAULT_HISTORY_LIMIT;\n }\n\n get document(): SchematicDocument {\n return this.#document;\n }\n\n get canUndo(): boolean {\n return this.#past.length > 0;\n }\n\n get canRedo(): boolean {\n return this.#future.length > 0;\n }\n\n /** @throws {SchematicError} leaving the current document and history untouched. */\n dispatch(command: SchematicCommand): void {\n const next = applySchematicCommand(this.#document, command, this.#options);\n this.#record(next);\n }\n\n /**\n * Records an already-derived document (for example a wire split) as one history step.\n * Junctions that no longer lie on their wires are dropped, keeping the document consistent.\n *\n * @throws {SchematicError} when the document is invalid; the state stays untouched.\n */\n replace(document: SchematicDocument): void {\n const parsed = parseSchematic(document);\n const tolerance = this.#options.tolerance ?? 0;\n const wireById = new Map(parsed.sheet.wires.map((wire) => [wire.id, wire]));\n const junctions = parsed.sheet.junctions.filter((junction) =>\n junction.wires.every((wireId) => {\n const wire = wireById.get(wireId);\n return (\n wire !== undefined &&\n pointOnPolyline(wire.points, { x: junction.x, y: junction.y }, tolerance)\n );\n }),\n );\n this.#record(\n junctions.length === parsed.sheet.junctions.length\n ? parsed\n : { ...parsed, sheet: { ...parsed.sheet, junctions } },\n );\n }\n\n /** Applies several edits atomically; a failure rolls back every command in the block. */\n transaction(edit: (editor: SchematicEditor) => void): void {\n if (this.#depth > 0) {\n edit(this);\n return;\n }\n const document = this.#document;\n const future = this.#future;\n this.#past.push(document);\n this.#future = [];\n this.#depth = 1;\n try {\n edit(this);\n } catch (error) {\n this.#document = document;\n this.#past.pop();\n this.#future = future;\n throw error;\n } finally {\n this.#depth = 0;\n }\n if (this.#document === document) {\n this.#past.pop();\n this.#future = future;\n return;\n }\n this.#trimHistory();\n }\n\n undo(): void {\n const previous = this.#past.pop();\n if (previous === undefined) {\n return;\n }\n if (this.#depth === 0) {\n this.#future.push(this.#document);\n }\n this.#document = previous;\n }\n\n redo(): void {\n const next = this.#future.pop();\n if (next === undefined) {\n return;\n }\n if (this.#depth === 0) {\n this.#past.push(this.#document);\n }\n this.#document = next;\n }\n\n topology(): SchematicTopology {\n return deriveSchematicTopology(this.#document, this.#options);\n }\n\n toJSON(): string {\n return serializeSchematic(this.#document);\n }\n\n #record(next: SchematicDocument): void {\n const previous = this.#document;\n this.#document = next;\n if (this.#depth > 0) {\n return;\n }\n this.#past.push(previous);\n this.#future = [];\n this.#trimHistory();\n }\n\n #trimHistory(): void {\n if (this.#past.length > this.#historyLimit) {\n this.#past.shift();\n }\n }\n}\n","import type { Rect } from '../../format/types';\nimport type { PropertyDescriptor } from './properties';\nimport type { DeviceReference } from './reference';\n\n/** Side of the symbol body a pin is drawn on; controls stub direction and label placement. */\nexport type PinSide = 'left' | 'right' | 'top' | 'bottom';\n\nexport interface PinAnchor {\n /** Connection point (outer end of the pin stub) in symbol space. */\n readonly x: number;\n readonly y: number;\n /** Side the pin is displayed on; inferred from the position when omitted. */\n readonly side?: PinSide;\n}\n\nexport interface DeviceSymbolDefinition {\n /** Name rendered at the centre of the symbol. */\n readonly name: string;\n /** Pin id to pre-placement anchor coordinate in symbol space. */\n readonly pins: Readonly<Record<string, PinAnchor>>;\n /** Optional outline used by the editor to draw the symbol body. */\n readonly bounds?: Rect;\n}\n\nexport interface DeviceSymbolGeometry {\n /** Placement-independent geometry, as provided by the device description. */\n readonly name?: string;\n readonly pins: Readonly<Record<string, PinAnchor>>;\n readonly bounds?: Rect;\n}\n\nexport interface DeviceSymbolProvider {\n /** Symbol geometry; `undefined` when the device is unknown or has no geometry. */\n getDeviceSymbol(reference: DeviceReference): DeviceSymbolDefinition | undefined;\n /** Name rendered on the symbol: the symbol name, else the display name. `undefined` when unknown. */\n getDeviceName(reference: DeviceReference): string | undefined;\n /**\n * Reference-designator prefix the device declares (`U`, `R`, `DS`, …); `undefined` when the\n * provider does not describe one, in which case placement falls back to the global default.\n */\n getDeviceDesignatorPrefix?(reference: DeviceReference): string | undefined;\n /**\n * Property descriptors the device declares (#7); `undefined` when the provider does not describe\n * them, in which case property editing is restricted to structural validation only.\n */\n getDevicePropertyDescriptors?(\n reference: DeviceReference,\n ): ReadonlyMap<string, PropertyDescriptor> | undefined;\n}\n\n/** Bounding box of a device's pins; `undefined` when it declares none. */\nexport function pinsBounds(pins: Readonly<Record<string, PinAnchor>>): Rect | undefined {\n const points = Object.values(pins);\n if (points.length === 0) {\n return undefined;\n }\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n for (const point of points) {\n minX = Math.min(minX, point.x);\n minY = Math.min(minY, point.y);\n maxX = Math.max(maxX, point.x);\n maxY = Math.max(maxY, point.y);\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\n/** Side a pin is drawn on: its declared side, else the closest edge of the body outline. */\nexport function pinSide(pin: PinAnchor, outline: Rect | undefined): PinSide | undefined {\n if (pin.side !== undefined) {\n return pin.side;\n }\n if (outline === undefined) {\n return undefined;\n }\n const dx = (pin.x - (outline.x + outline.width / 2)) / Math.max(outline.width / 2, 1e-6);\n const dy = (pin.y - (outline.y + outline.height / 2)) / Math.max(outline.height / 2, 1e-6);\n if (Math.abs(dx) >= Math.abs(dy)) {\n return dx >= 0 ? 'right' : 'left';\n }\n return dy >= 0 ? 'bottom' : 'top';\n}\n\n/**\n * Inner end of a pin stub, where it meets the body outline. Together with the anchor it forms the\n * grabbable pin: rendering draws that line and hit testing accepts clicks anywhere along it.\n */\nexport function pinStubEnd(\n body: Rect,\n anchor: { readonly x: number; readonly y: number },\n side: PinSide,\n): { readonly x: number; readonly y: number } {\n switch (side) {\n case 'left':\n return { x: body.x, y: anchor.y };\n case 'right':\n return { x: body.x + body.width, y: anchor.y };\n case 'top':\n return { x: anchor.x, y: body.y };\n case 'bottom':\n return { x: anchor.x, y: body.y + body.height };\n }\n}\n","import type { Rect, SchematicDocument } from '../../format/types';\nimport type { Point } from '../../format/value';\nimport {\n GROUND_DEVICE,\n POWER_DEVICE,\n designatorOf,\n hasDesignator,\n isLabelDevice,\n isTextDevice,\n netNameOf,\n parseDeviceReference,\n symbolRole,\n textDeviceContent,\n} from '../device/reference';\nimport type { DeviceSymbolProvider } from '../device/symbol';\nimport { pinSide, pinStubEnd, pinsBounds } from '../device/symbol';\nimport {\n DEFAULT_TOLERANCE,\n distanceToSegment,\n pointOnPolyline,\n pointsEqual,\n} from '../geometry/point';\nimport {\n referencePosition,\n rotatePoint,\n symbolBounds,\n symbolPinPosition,\n} from '../geometry/transform';\n\nexport interface HitTestOptions {\n readonly devices?: DeviceSymbolProvider;\n /** Coordinate comparison tolerance in page units; defaults to exact matching. */\n readonly tolerance?: number;\n /** Include symbol bodies in the hit search; defaults to true. */\n readonly includeSymbols?: boolean;\n}\n\nexport type SchematicHit =\n | { readonly kind: 'reference'; readonly symbolId: string }\n | { readonly kind: 'junction'; readonly id: string }\n | { readonly kind: 'pin'; readonly symbolId: string; readonly pinId: string }\n | { readonly kind: 'wire'; readonly id: string; readonly segment: number }\n | { readonly kind: 'symbol'; readonly id: string };\n\n/**\n * Returns the topmost element at `point`: reference labels, junctions, pins, wires, then\n * symbol bodies.\n */\nexport function hitTestSchematic(\n document: SchematicDocument,\n point: Point,\n options: HitTestOptions = {},\n): SchematicHit | undefined {\n const tolerance = options.tolerance ?? DEFAULT_TOLERANCE;\n const includeSymbols = options.includeSymbols ?? true;\n\n const reference = referenceHit(document, point, options, tolerance);\n if (reference !== undefined) {\n return reference;\n }\n\n const junctions = [...document.sheet.junctions].sort((a, b) => a.id.localeCompare(b.id));\n for (const junction of junctions) {\n if (pointsEqual({ x: junction.x, y: junction.y }, point, tolerance)) {\n return { kind: 'junction', id: junction.id };\n }\n }\n\n if (options.devices !== undefined) {\n const symbols = [...document.sheet.symbols]\n .filter((symbol) => !isLabelDevice(symbol.device))\n .sort((a, b) => a.id.localeCompare(b.id));\n for (const symbol of symbols) {\n const reference = parseDeviceReference(symbol.device);\n const definition =\n reference === undefined ? undefined : options.devices.getDeviceSymbol(reference);\n if (definition === undefined) {\n continue;\n }\n const body = definition.bounds ??\n pinsBounds(definition.pins) ?? { x: -12, y: -12, width: 24, height: 24 };\n const pinIds = Object.keys(definition.pins).sort();\n for (const pinId of pinIds) {\n const anchor = definition.pins[pinId];\n if (anchor === undefined) {\n continue;\n }\n const end = symbolPinPosition(symbol, anchor);\n if (pointsEqual(end, point, tolerance)) {\n return { kind: 'pin', symbolId: symbol.id, pinId };\n }\n // The whole pin stub is grabbable, so clicking the drawn pin starts a wire at its end.\n const side = pinSide(anchor, body);\n if (side === undefined) {\n continue;\n }\n const start = symbolPinPosition(symbol, pinStubEnd(body, anchor, side));\n if (distanceToSegment(point, start, end) <= tolerance) {\n return { kind: 'pin', symbolId: symbol.id, pinId };\n }\n }\n }\n }\n\n const wires = [...document.sheet.wires].sort((a, b) => a.id.localeCompare(b.id));\n for (const wire of wires) {\n for (let index = 1; index < wire.points.length; index += 1) {\n const previous = wire.points[index - 1];\n const current = wire.points[index];\n if (\n previous !== undefined &&\n current !== undefined &&\n distanceToSegment(point, previous, current) <= tolerance\n ) {\n return { kind: 'wire', id: wire.id, segment: index - 1 };\n }\n }\n }\n\n if (!includeSymbols) {\n return undefined;\n }\n\n const symbols = [...document.sheet.symbols].sort((a, b) => a.id.localeCompare(b.id));\n for (const symbol of symbols) {\n const reference = parseDeviceReference(symbol.device);\n const definition =\n reference === undefined ? undefined : options.devices?.getDeviceSymbol(reference);\n const bounds =\n definition === undefined\n ? annotationBounds(symbol)\n : symbolBounds(symbol, definition.bounds, definition.pins);\n if (bounds === undefined) {\n continue;\n }\n const inside =\n point.x >= bounds.x - tolerance &&\n point.x <= bounds.x + bounds.width + tolerance &&\n point.y >= bounds.y - tolerance &&\n point.y <= bounds.y + bounds.height + tolerance;\n if (inside) {\n return { kind: 'symbol', id: symbol.id };\n }\n }\n\n return undefined;\n}\n\n/** Approximate clickable box for symbols without device geometry (labels, text annotations). */\nfunction annotationBounds(symbol: {\n readonly id: string;\n readonly device: string;\n readonly x: number;\n readonly y: number;\n readonly rotation: number;\n readonly net?: string;\n readonly properties?: Readonly<Record<string, unknown>>;\n}): Rect {\n const device = symbol.device;\n if (device === POWER_DEVICE) {\n // Stem, bar and the label above them.\n return rotatedBounds(symbol, {\n x: -POWER_HALF_WIDTH,\n y: -POWER_HEIGHT,\n width: POWER_HALF_WIDTH * 2,\n height: POWER_HEIGHT + ANNOTATION_HEIGHT / 2,\n });\n }\n if (device === GROUND_DEVICE) {\n // Stem, the three bars and the label below them.\n return rotatedBounds(symbol, {\n x: -POWER_HALF_WIDTH,\n y: -ANNOTATION_HEIGHT / 2,\n width: POWER_HALF_WIDTH * 2,\n height: GROUND_HEIGHT,\n });\n }\n const content = isTextDevice(device)\n ? textDeviceContent(symbol)\n : isLabelDevice(device)\n ? (netNameOf(symbol) ?? '')\n : '';\n if (content.length === 0) {\n return { x: symbol.x, y: symbol.y, width: 0, height: 0 };\n }\n const height = ANNOTATION_HEIGHT;\n // Labels anchor at their connection point (left edge); text is drawn from its origin too.\n return rotatedBounds(symbol, {\n x: 0,\n y: -height / 2,\n width: content.length * ANNOTATION_CHAR_WIDTH,\n height,\n });\n}\n\n/** Axis-aligned box of a symbol-local rectangle after applying the symbol's rotation. */\nfunction rotatedBounds(\n symbol: { readonly x: number; readonly y: number; readonly rotation: number },\n local: Rect,\n): Rect {\n if (symbol.rotation % 360 === 0) {\n return {\n x: symbol.x + local.x,\n y: symbol.y + local.y,\n width: local.width,\n height: local.height,\n };\n }\n const corners = [\n { x: local.x, y: local.y },\n { x: local.x + local.width, y: local.y },\n { x: local.x, y: local.y + local.height },\n { x: local.x + local.width, y: local.y + local.height },\n ].map((corner) => {\n const rotated = rotatePoint(corner, symbol.rotation);\n return { x: symbol.x + rotated.x, y: symbol.y + rotated.y };\n });\n const xs = corners.map((corner) => corner.x);\n const ys = corners.map((corner) => corner.y);\n const minX = Math.min(...xs);\n const minY = Math.min(...ys);\n return { x: minX, y: minY, width: Math.max(...xs) - minX, height: Math.max(...ys) - minY };\n}\n\nconst ANNOTATION_CHAR_WIDTH = 6;\nconst ANNOTATION_HEIGHT = 12;\n/** Half width of the power/ground glyph box. */\nconst POWER_HALF_WIDTH = 10;\n/** How far the power symbol (stem + bar + label) reaches above its anchor. */\nconst POWER_HEIGHT = 24;\n/** How far the ground symbol (stem + bars + label) reaches below its anchor. */\nconst GROUND_HEIGHT = 30;\n\n/** Hit box of a reference designator, positioned like the renderer draws it. */\nfunction referenceHit(\n document: SchematicDocument,\n point: Point,\n options: HitTestOptions,\n tolerance: number,\n): SchematicHit | undefined {\n const symbols = [...document.sheet.symbols]\n .filter((symbol) => hasDesignator(symbolRole(symbol.device)))\n .sort((a, b) => a.id.localeCompare(b.id));\n for (const symbol of symbols) {\n const reference = parseDeviceReference(symbol.device);\n const definition =\n reference === undefined ? undefined : options.devices?.getDeviceSymbol(reference);\n if (definition === undefined) {\n continue;\n }\n const designator = designatorOf(symbol) ?? symbol.id;\n const anchor = referencePosition(symbol, definition.bounds, symbol.reference);\n const width = designator.length * ANNOTATION_CHAR_WIDTH;\n const box: Rect = {\n x: anchor.x,\n y: anchor.y - ANNOTATION_HEIGHT,\n width,\n height: ANNOTATION_HEIGHT,\n };\n const inside =\n point.x >= box.x - tolerance &&\n point.x <= box.x + box.width + tolerance &&\n point.y >= box.y - tolerance &&\n point.y <= box.y + box.height + tolerance;\n if (inside) {\n return { kind: 'reference', symbolId: symbol.id };\n }\n }\n return undefined;\n}\n\nexport interface JunctionCandidate {\n readonly point: Point;\n readonly wireIds: readonly string[];\n}\nexport interface JunctionCandidateOptions {\n readonly tolerance?: number;\n}\n\n/**\n * Finds positions where wires touch or cross without an explicit junction (#6 requires junctions\n * to be created by the user). Existing junctions are excluded.\n */\nexport function findJunctionCandidates(\n document: SchematicDocument,\n options: JunctionCandidateOptions = {},\n): readonly JunctionCandidate[] {\n const tolerance = options.tolerance ?? DEFAULT_TOLERANCE;\n const wires = [...document.sheet.wires].sort((a, b) => a.id.localeCompare(b.id));\n const existing = document.sheet.junctions;\n const candidates: { point: Point; wireIds: Set<string> }[] = [];\n\n const add = (point: Point, wireId: string): void => {\n // Points within tolerance describe the same junction handle, so they are merged.\n const entry = candidates.find((candidate) => pointsEqual(candidate.point, point, tolerance));\n if (entry === undefined) {\n candidates.push({ point: { x: point.x, y: point.y }, wireIds: new Set([wireId]) });\n return;\n }\n entry.wireIds.add(wireId);\n };\n\n for (let left = 0; left < wires.length; left += 1) {\n const first = wires[left];\n if (first === undefined) {\n continue;\n }\n for (let right = left + 1; right < wires.length; right += 1) {\n const second = wires[right];\n if (second === undefined) {\n continue;\n }\n const points: Point[] = [...intersections(first.points, second.points, tolerance)];\n const firstPoints = [...first.points];\n const secondPoints = [...second.points];\n for (const point of firstPoints) {\n if (pointOnPolyline(secondPoints, point, tolerance)) {\n points.push(point);\n }\n }\n for (const point of secondPoints) {\n if (pointOnPolyline(firstPoints, point, tolerance)) {\n points.push(point);\n }\n }\n for (const point of points) {\n add(point, first.id);\n add(point, second.id);\n }\n }\n }\n\n const result: JunctionCandidate[] = [];\n for (const candidate of candidates) {\n if (candidate.wireIds.size < 2) {\n continue;\n }\n const wireIds = [...candidate.wireIds].sort();\n const covered = existing.some(\n (junction) =>\n pointsEqual({ x: junction.x, y: junction.y }, candidate.point, tolerance) &&\n wireIds.every((wireId) => junction.wires.includes(wireId)),\n );\n if (!covered) {\n result.push({ point: candidate.point, wireIds });\n }\n }\n\n return result.sort(\n (a, b) =>\n a.point.x - b.point.x ||\n a.point.y - b.point.y ||\n a.wireIds.join(',').localeCompare(b.wireIds.join(',')),\n );\n}\n\n/** Segment–segment intersection points in the closed-segment sense, within `tolerance`. */\nfunction* intersections(\n first: readonly Point[],\n second: readonly Point[],\n tolerance: number,\n): Generator<Point> {\n for (let a = 1; a < first.length; a += 1) {\n const a1 = first[a - 1];\n const a2 = first[a];\n if (a1 === undefined || a2 === undefined) {\n continue;\n }\n for (let b = 1; b < second.length; b += 1) {\n const b1 = second[b - 1];\n const b2 = second[b];\n if (b1 === undefined || b2 === undefined) {\n continue;\n }\n const point = segmentIntersection(a1, a2, b1, b2, tolerance);\n if (point !== undefined) {\n yield point;\n }\n }\n }\n}\n\nfunction segmentIntersection(\n a1: Point,\n a2: Point,\n b1: Point,\n b2: Point,\n tolerance: number,\n): Point | undefined {\n const r = { x: a2.x - a1.x, y: a2.y - a1.y };\n const s = { x: b2.x - b1.x, y: b2.y - b1.y };\n const denominator = r.x * s.y - r.y * s.x;\n const qp = { x: b1.x - a1.x, y: b1.y - a1.y };\n if (Math.abs(denominator) < Number.EPSILON) {\n // Parallel or collinear: overlap points are covered by the endpoint checks in the caller.\n return undefined;\n }\n const t = (qp.x * s.y - qp.y * s.x) / denominator;\n const u = (qp.x * r.y - qp.y * r.x) / denominator;\n const slackT = tolerance === 0 ? 0 : tolerance / Math.hypot(r.x, r.y);\n const slackU = tolerance === 0 ? 0 : tolerance / Math.hypot(s.x, s.y);\n if (t < -slackT || t > 1 + slackT || u < -slackU || u > 1 + slackU) {\n return undefined;\n }\n return { x: a1.x + t * r.x, y: a1.y + t * r.y };\n}\n","import { parseDeviceReference, symbolRole } from '../device/reference';\nimport type { DeviceSymbolProvider } from '../device/symbol';\nimport type { SchematicDocument, SchematicWire } from '../../format/types';\nimport type { Point } from '../../format/value';\nimport { symbolPinPosition } from '../geometry/transform';\n\nexport interface SegmentDragOptions {\n readonly devices?: DeviceSymbolProvider;\n}\n\n/**\n * Wire points produced by sliding one segment by `delta` along its normal.\n *\n * The whole run of segments parallel to the dragged one moves along, so no neighbour is left\n * diagonal. Where that run ends at a pin, an anchor, a junction or another wire, the vertex stays\n * put and the wire gains a dogleg. Pure geometry: the caller decides how to apply it.\n */\nexport function planSegmentDrag(\n document: SchematicDocument,\n wireId: string,\n segment: number,\n delta: Point,\n options: SegmentDragOptions = {},\n): readonly Point[] | undefined {\n const wire = document.sheet.wires.find((candidate) => candidate.id === wireId);\n return wire === undefined\n ? undefined\n : planWireSegmentDrag(document, wire, segment, delta, options);\n}\n\nfunction planWireSegmentDrag(\n document: SchematicDocument,\n wire: SchematicWire,\n segment: number,\n delta: Point,\n options: SegmentDragOptions,\n): readonly Point[] | undefined {\n const points = wire.points;\n const start = points[segment];\n const end = points[segment + 1];\n if (start === undefined || end === undefined || (delta.x === 0 && delta.y === 0)) {\n return undefined;\n }\n if (start.x === end.x && start.y === end.y) {\n return undefined;\n }\n // Dragging a horizontal segment moves its run vertically; the run only breaks at a segment\n // pointing the other way (it just stretches) or at a connected vertex (it needs a dogleg).\n const horizontal = start.y === end.y;\n const isParallel = (from: Point, to: Point): boolean =>\n horizontal ? from.y === to.y : from.x === to.x;\n const connected = (point: Point): boolean => isConnectedVertex(document, point, wire.id, options);\n\n let first = segment;\n while (first > 0) {\n const previous = points[first - 1];\n const current = points[first];\n if (\n previous === undefined ||\n current === undefined ||\n !isParallel(previous, current) ||\n connected(current)\n ) {\n break;\n }\n first -= 1;\n }\n let last = segment + 1;\n while (last < points.length - 1) {\n const current = points[last];\n const next = points[last + 1];\n if (\n current === undefined ||\n next === undefined ||\n !isParallel(current, next) ||\n connected(current)\n ) {\n break;\n }\n last += 1;\n }\n\n const firstPoint = points[first];\n const lastPoint = points[last];\n if (firstPoint === undefined || lastPoint === undefined) {\n return undefined;\n }\n const shift = (point: Point): Point => ({ x: point.x + delta.x, y: point.y + delta.y });\n const moved: Point[] = [];\n for (let index = first; index <= last; index += 1) {\n const point = points[index];\n if (point !== undefined) {\n moved.push(shift(point));\n }\n }\n if (connected(firstPoint)) {\n moved.unshift(firstPoint);\n }\n if (connected(lastPoint)) {\n moved.push(lastPoint);\n }\n return [...points.slice(0, first), ...moved, ...points.slice(last + 1)];\n}\n\n/** True when something other than the wire itself is attached at `point`. */\nexport function isConnectedVertex(\n document: SchematicDocument,\n point: Point,\n wireId: string,\n options: SegmentDragOptions = {},\n): boolean {\n const same = (candidate: Point): boolean => candidate.x === point.x && candidate.y === point.y;\n for (const junction of document.sheet.junctions) {\n if (same(junction)) {\n return true;\n }\n }\n for (const wire of document.sheet.wires) {\n if (wire.id !== wireId && wire.points.some(same)) {\n return true;\n }\n }\n for (const symbol of document.sheet.symbols) {\n const role = symbolRole(symbol.device);\n if (role !== 'component') {\n if (same({ x: symbol.x, y: symbol.y })) {\n return true;\n }\n continue;\n }\n const reference = parseDeviceReference(symbol.device);\n const definition =\n reference === undefined ? undefined : options.devices?.getDeviceSymbol(reference);\n if (definition === undefined) {\n continue;\n }\n for (const anchor of Object.values(definition.pins)) {\n if (same(symbolPinPosition(symbol, anchor))) {\n return true;\n }\n }\n }\n return false;\n}\n","import type { SchematicDocument } from '../../format/types';\nimport type { Point } from '../../format/value';\nimport { pointOnPolyline } from '../geometry/point';\n\nexport interface JunctionReleaseOptions {\n readonly tolerance?: number;\n}\n\nexport interface JunctionRelease {\n readonly id: string;\n /** Remaining participating wires; `undefined` means the junction has to be removed. */\n readonly wires: readonly string[] | undefined;\n}\n\n/**\n * Junctions that must let go of `wireId`: its new geometry no longer passes through them.\n *\n * A junction left with fewer than two wires is dropped instead of being kept dangling. Pure\n * geometry: the caller applies the resulting commands.\n */\nexport function planJunctionRelease(\n document: SchematicDocument,\n wireId: string,\n points: readonly Point[],\n options: JunctionReleaseOptions = {},\n): readonly JunctionRelease[] {\n const tolerance = options.tolerance ?? 0;\n const releases: JunctionRelease[] = [];\n for (const junction of document.sheet.junctions) {\n if (!junction.wires.includes(wireId)) {\n continue;\n }\n if (pointOnPolyline(points, { x: junction.x, y: junction.y }, tolerance)) {\n continue;\n }\n const remaining = junction.wires.filter((id) => id !== wireId);\n releases.push({ id: junction.id, wires: remaining.length < 2 ? undefined : remaining });\n }\n return releases;\n}\n\nexport interface JunctionJoin {\n readonly id: string;\n readonly wires: readonly string[];\n}\n\n/**\n * The junction sitting exactly at `point`, extended with `wireId`, so a wire that ends on an\n * existing junction actually joins it. `undefined` when there is nothing to join.\n */\nexport function joinJunctionAt(\n document: SchematicDocument,\n wireId: string,\n point: Point,\n): JunctionJoin | undefined {\n const junction = document.sheet.junctions.find(\n (candidate) => candidate.x === point.x && candidate.y === point.y,\n );\n if (junction === undefined || junction.wires.includes(wireId)) {\n return undefined;\n }\n return { id: junction.id, wires: [...junction.wires, wireId] };\n}\n","import { SchematicError } from '../../format/errors';\nimport { parseSchematic } from '../format/parse-schematic';\nimport type { SchematicDocument, SchematicJunction, SchematicWire } from '../../format/types';\nimport type { Point } from '../../format/value';\nimport { DEFAULT_TOLERANCE, pointOnPolyline, pointsEqual } from '../geometry/point';\nimport { defaultElementIdFactory, type ElementIdFactory } from './ids';\n\nexport interface WireEditOptions {\n readonly tolerance?: number;\n readonly createId?: ElementIdFactory;\n}\n\nexport interface SplitWireResult {\n readonly document: SchematicDocument;\n /** Wire that keeps the original id (the part before `point`). */\n readonly firstWireId: string;\n readonly secondWireId: string;\n}\n\nexport interface MergeWiresResult {\n readonly document: SchematicDocument;\n /** Wire that kept its id and absorbed the other one. */\n readonly wireId: string;\n readonly removedWireId: string;\n readonly removedJunctionId: string;\n}\n\n/**\n * Splits `wireId` at `point`, which must lie strictly inside the polyline.\n * Junctions that only touch the second half are re-pointed to the new wire.\n *\n * @throws {SchematicError} when the wire is unknown or `point` is not an interior point.\n */\nexport function splitWireAt(\n document: SchematicDocument,\n wireId: string,\n point: Point,\n options: WireEditOptions = {},\n): SplitWireResult {\n const tolerance = options.tolerance ?? DEFAULT_TOLERANCE;\n const wire = document.sheet.wires.find((candidate) => candidate.id === wireId);\n if (wire === undefined) {\n throw new SchematicError([\n {\n severity: 'error',\n code: 'edit/unknown-entity',\n message: `Unknown wire \"${wireId}\".`,\n entity: { kind: 'wire', id: wireId },\n },\n ]);\n }\n\n const split = splitPoints(wire.points, point, tolerance);\n if (split === undefined) {\n throw new SchematicError([\n {\n severity: 'error',\n code: 'wire/invalid-points',\n message: `Point (${point.x}, ${point.y}) is not an interior point of wire \"${wireId}\".`,\n entity: { kind: 'wire', id: wireId },\n },\n ]);\n }\n\n const firstWireId = wireId;\n const secondWireId =\n options.createId?.('wire', document) ?? defaultElementIdFactory('wire', document);\n if (secondWireId === firstWireId) {\n throw new SchematicError([\n {\n severity: 'error',\n code: 'edit/invalid-command',\n message: `Generated wire id \"${secondWireId}\" collides with the split wire.`,\n entity: { kind: 'wire', id: wireId },\n },\n ]);\n }\n\n const [firstPoints, secondPoints] = split;\n const wires: SchematicWire[] = [];\n for (const candidate of document.sheet.wires) {\n if (candidate.id !== wireId) {\n wires.push(candidate);\n continue;\n }\n wires.push({ id: firstWireId, points: firstPoints });\n wires.push({ id: secondWireId, points: secondPoints });\n }\n\n const junctions = document.sheet.junctions.map((junction) =>\n remapJunction(\n junction,\n wireId,\n firstWireId,\n secondWireId,\n firstPoints,\n secondPoints,\n point,\n tolerance,\n ),\n );\n\n return {\n document: validate({ ...document, sheet: { ...document.sheet, wires, junctions } }),\n firstWireId,\n secondWireId,\n };\n}\n\n/**\n * Merges the two collinear wires meeting at `junctionId` into one wire and removes the junction.\n * Returns `undefined` when the junction does not describe such a splice.\n *\n * @throws {SchematicError} when the junction is unknown.\n */\nexport function mergeWiresAtJunction(\n document: SchematicDocument,\n junctionId: string,\n options: WireEditOptions = {},\n): MergeWiresResult | undefined {\n const tolerance = options.tolerance ?? DEFAULT_TOLERANCE;\n const junction = document.sheet.junctions.find((candidate) => candidate.id === junctionId);\n if (junction === undefined) {\n throw new SchematicError([\n {\n severity: 'error',\n code: 'edit/unknown-entity',\n message: `Unknown junction \"${junctionId}\".`,\n entity: { kind: 'junction', id: junctionId },\n },\n ]);\n }\n if (junction.wires.length !== 2) {\n return undefined;\n }\n\n const [firstId, secondId] = junction.wires as [string, string];\n const first = document.sheet.wires.find((wire) => wire.id === firstId);\n const second = document.sheet.wires.find((wire) => wire.id === secondId);\n if (first === undefined || second === undefined) {\n return undefined;\n }\n\n const merged = mergePoints(first.points, second.points, junction, tolerance);\n if (merged === undefined) {\n return undefined;\n }\n\n const wires: SchematicWire[] = [];\n for (const candidate of document.sheet.wires) {\n if (candidate.id === secondId) {\n continue;\n }\n wires.push(candidate.id === firstId ? { id: firstId, points: merged } : candidate);\n }\n\n const junctions = document.sheet.junctions\n .filter((candidate) => candidate.id !== junctionId)\n .map((candidate) =>\n candidate.wires.includes(secondId)\n ? { ...candidate, wires: candidate.wires.map((id) => (id === secondId ? firstId : id)) }\n : candidate,\n );\n\n return {\n document: validate({ ...document, sheet: { ...document.sheet, wires, junctions } }),\n wireId: firstId,\n removedWireId: secondId,\n removedJunctionId: junctionId,\n };\n}\n\nfunction validate(document: SchematicDocument): SchematicDocument {\n return parseSchematic(document);\n}\n\nfunction splitPoints(\n points: readonly Point[],\n point: Point,\n tolerance: number,\n): readonly [readonly Point[], readonly Point[]] | undefined {\n const first = points[0];\n const last = points[points.length - 1];\n if (first === undefined || last === undefined) {\n return undefined;\n }\n if (pointsEqual(first, point, tolerance) || pointsEqual(last, point, tolerance)) {\n return undefined;\n }\n if (!pointOnPolyline(points, point, tolerance)) {\n return undefined;\n }\n for (let index = 1; index < points.length; index += 1) {\n const previous = points[index - 1];\n const current = points[index];\n if (previous === undefined || current === undefined) {\n continue;\n }\n if (!pointOnPolyline([previous, current], point, tolerance)) {\n continue;\n }\n const firstPoints = [...points.slice(0, index), { x: point.x, y: point.y }];\n const secondPoints = [{ x: point.x, y: point.y }, ...points.slice(index)];\n return [firstPoints, secondPoints];\n }\n return undefined;\n}\n\nfunction remapJunction(\n junction: SchematicJunction,\n wireId: string,\n firstWireId: string,\n secondWireId: string,\n firstPoints: readonly Point[],\n secondPoints: readonly Point[],\n splitPoint: Point,\n tolerance: number,\n): SchematicJunction {\n if (!junction.wires.includes(wireId)) {\n return junction;\n }\n const point = { x: junction.x, y: junction.y };\n if (pointsEqual(point, splitPoint, tolerance)) {\n const others = junction.wires.filter((id) => id !== wireId);\n return { ...junction, wires: [firstWireId, secondWireId, ...others] };\n }\n const onFirst = pointOnPolyline(firstPoints, point, tolerance);\n const onSecond = pointOnPolyline(secondPoints, point, tolerance);\n if (onFirst && !onSecond) {\n return junction;\n }\n if (onSecond && !onFirst) {\n return { ...junction, wires: junction.wires.map((id) => (id === wireId ? secondWireId : id)) };\n }\n return junction;\n}\n\nfunction mergePoints(\n first: readonly Point[],\n second: readonly Point[],\n junction: SchematicJunction,\n tolerance: number,\n): readonly Point[] | undefined {\n const at = { x: junction.x, y: junction.y };\n const firstStart = first[0];\n const firstEnd = first[first.length - 1];\n const secondStart = second[0];\n const secondEnd = second[second.length - 1];\n if (\n firstStart === undefined ||\n firstEnd === undefined ||\n secondStart === undefined ||\n secondEnd === undefined\n ) {\n return undefined;\n }\n\n const firstStartsAt = pointsEqual(firstStart, at, tolerance);\n const firstEndsAt = pointsEqual(firstEnd, at, tolerance);\n const secondStartsAt = pointsEqual(secondStart, at, tolerance);\n const secondEndsAt = pointsEqual(secondEnd, at, tolerance);\n\n let head: readonly Point[] | undefined;\n let tail: readonly Point[] | undefined;\n if (firstEndsAt && secondStartsAt) {\n head = first;\n tail = second;\n } else if (secondEndsAt && firstStartsAt) {\n head = second;\n tail = first;\n } else if (firstEndsAt && secondEndsAt) {\n head = first;\n tail = [...second].reverse();\n } else if (firstStartsAt && secondStartsAt) {\n head = [...first].reverse();\n tail = second;\n }\n if (head === undefined || tail === undefined || !isContinuous(head, tail)) {\n return undefined;\n }\n return [...head, ...tail.slice(1)];\n}\n\n/** True when the last segment of `a` and the first segment of `b` are collinear. */\nfunction isContinuous(a: readonly Point[], b: readonly Point[]): boolean {\n const a1 = a[a.length - 2];\n const a2 = a[a.length - 1];\n const b1 = b[0];\n const b2 = b[1];\n if (a1 === undefined || a2 === undefined || b1 === undefined || b2 === undefined) {\n return false;\n }\n const ax = a2.x - a1.x;\n const ay = a2.y - a1.y;\n const bx = b2.x - b1.x;\n const by = b2.y - b1.y;\n const cross = ax * by - ay * bx;\n const scale = Math.hypot(ax, ay) * Math.hypot(bx, by);\n if (scale === 0) {\n return false;\n }\n return Math.abs(cross) / scale <= 1e-9 && ax * bx + ay * by > 0;\n}\n","import type { SchematicWire } from '../../format/types';\nimport type { Point } from '../../format/value';\n\nexport interface PointMove {\n readonly from: Point;\n readonly to: Point;\n}\n\nexport interface ReroutedWire {\n readonly points: readonly Point[];\n /** Every point that changed, so junctions and anchors can follow. */\n readonly moves: readonly PointMove[];\n}\n\n/**\n * Moves a wire endpoint to `to` while keeping every segment horizontal or vertical.\n *\n * The displacement is absorbed segment by segment (the classic orthogonal drag): the point after\n * the moved end is shifted just enough to restore the original orientation, and the correction is\n * passed on until a segment can take it. No extra points are inserted, so the wire never doubles\n * back on itself.\n */\nexport function rerouteWireEndpoint(\n wire: SchematicWire,\n from: Point,\n to: Point,\n): ReroutedWire | undefined {\n const points = wire.points;\n const first = points[0];\n const last = points[points.length - 1];\n if (first === undefined || last === undefined) {\n return undefined;\n }\n if (samePoint(first, from)) {\n return rerouteFrom(points, to, 'start');\n }\n if (samePoint(last, from)) {\n return rerouteFrom(points, to, 'end');\n }\n return undefined;\n}\n\nfunction rerouteFrom(points: readonly Point[], target: Point, end: 'start' | 'end'): ReroutedWire {\n const next = points.map((point) => ({ x: point.x, y: point.y }));\n const first = next[0];\n const last = next[next.length - 1];\n if (first === undefined || last === undefined) {\n return { points: next, moves: [] };\n }\n\n if (end === 'start') {\n next[0] = { x: target.x, y: target.y };\n for (let index = 0; index < next.length - 1; index += 1) {\n const a = next[index];\n const b = next[index + 1];\n if (a === undefined || b === undefined || a.x === b.x || a.y === b.y) {\n break;\n }\n const horizontal = points[index]?.y === points[index + 1]?.y;\n next[index + 1] = horizontal ? { x: b.x, y: a.y } : { x: a.x, y: b.y };\n }\n } else {\n next[next.length - 1] = { x: target.x, y: target.y };\n for (let index = next.length - 1; index > 0; index -= 1) {\n const a = next[index - 1];\n const b = next[index];\n if (a === undefined || b === undefined || a.x === b.x || a.y === b.y) {\n break;\n }\n const horizontal = points[index - 1]?.y === points[index]?.y;\n next[index - 1] = horizontal ? { x: a.x, y: b.y } : { x: b.x, y: a.y };\n }\n }\n\n const moves: PointMove[] = [];\n for (let index = 0; index < points.length; index += 1) {\n const before = points[index];\n const after = next[index];\n if (before !== undefined && after !== undefined && !samePoint(before, after)) {\n moves.push({ from: before, to: after });\n }\n }\n return { points: dropRepeatedPoints(next), moves };\n}\n\nfunction dropRepeatedPoints(points: readonly Point[]): readonly Point[] {\n const result: Point[] = [];\n for (const point of points) {\n const previous = result[result.length - 1];\n if (previous === undefined || !samePoint(previous, point)) {\n result.push(point);\n }\n }\n return result.length >= 2 ? result : points;\n}\n\n/**\n * Moves a wire endpoint to `to` by stretching or bending it, leaving the original run in place.\n *\n * Unlike {@link rerouteWireEndpoint}, which absorbs the move by shifting the neighbouring points,\n * this keeps every existing point: a move along the attached segment only changes its length, and a\n * perpendicular move appends an orthogonal fold at the moved end. That is the behaviour net labels\n * and power ports need while being dragged — the wire follows them instead of sliding away.\n */\nexport function stretchWireEndpoint(\n wire: SchematicWire,\n from: Point,\n to: Point,\n): ReroutedWire | undefined {\n const points = wire.points;\n const first = points[0];\n const last = points[points.length - 1];\n if (first === undefined || last === undefined) {\n return undefined;\n }\n if (samePoint(first, from)) {\n return stretchAt(points, to, 'start');\n }\n if (samePoint(last, from)) {\n return stretchAt(points, to, 'end');\n }\n return undefined;\n}\n\nfunction stretchAt(points: readonly Point[], target: Point, end: 'start' | 'end'): ReroutedWire {\n const anchor = end === 'start' ? points[0] : points[points.length - 1];\n const neighbor = end === 'start' ? points[1] : points[points.length - 2];\n if (anchor === undefined) {\n return { points, moves: [] };\n }\n if (neighbor === undefined) {\n const next = points.map((point) => ({ x: point.x, y: point.y }));\n if (end === 'start') {\n next[0] = { x: target.x, y: target.y };\n } else {\n next[next.length - 1] = { x: target.x, y: target.y };\n }\n return { points: next, moves: [{ from: anchor, to: target }] };\n }\n\n const horizontal = neighbor.y === anchor.y;\n const perpendicular = horizontal ? target.y !== anchor.y : target.x !== anchor.x;\n if (!perpendicular) {\n const next = points.map((point) => ({ x: point.x, y: point.y }));\n if (end === 'start') {\n next[0] = { x: target.x, y: target.y };\n } else {\n next[next.length - 1] = { x: target.x, y: target.y };\n }\n return { points: dropRepeatedPoints(next), moves: [{ from: anchor, to: target }] };\n }\n\n // Turn at the anchor first, then run perpendicular; a pure perpendicular move adds one segment.\n const elbow = horizontal ? { x: anchor.x, y: target.y } : { x: target.x, y: anchor.y };\n const turn = samePoint(elbow, target) ? [] : [elbow];\n const next = end === 'start' ? [target, ...turn, ...points] : [...points, ...turn, target];\n return { points: dropRepeatedPoints(next), moves: [] };\n}\n\nfunction samePoint(left: Point, right: Point): boolean {\n return left.x === right.x && left.y === right.y;\n}\n","import { namesNet, symbolRole } from '../device/reference';\nimport type { DeviceSymbolProvider } from '../device/symbol';\nimport type { Placement, SchematicDocument } from '../../format/types';\nimport type { Point } from '../../format/value';\nimport { symbolPinPosition } from '../geometry/transform';\nimport {\n nearestPointOnPolyline,\n pointOnPolyline,\n pointOnPolylineAt,\n samePoint,\n} from '../geometry/point';\nimport { rerouteWireEndpoint, stretchWireEndpoint } from '../geometry/reroute';\n\nexport interface SymbolDragPreview {\n /** New point lists for wires whose endpoint is attached to a moving pin. */\n readonly wires: ReadonlyMap<string, readonly Point[]>;\n /** New positions for junctions sitting on a moving pin. */\n readonly junctions: ReadonlyMap<string, Point>;\n /** New positions for anchors (power / ground / label) attached to a moving pin. */\n readonly symbols: ReadonlyMap<string, Point>;\n}\n\n/**\n * Geometry of a symbol being dragged or rotated: which wires, junctions and anchors follow.\n * Shared by the editor controller (commit) and the renderer (live preview).\n */\nexport function previewSymbolDrag(\n document: SchematicDocument,\n devices: DeviceSymbolProvider | undefined,\n symbolId: string,\n next: Placement,\n): SymbolDragPreview | undefined {\n const symbol = document.sheet.symbols.find((candidate) => candidate.id === symbolId);\n if (symbol === undefined) {\n return undefined;\n }\n\n // Net labels and ports stretch their wire; component pins keep the run attached to the pin.\n const stretches = isNetAnchor(symbol.device);\n const definition = connectionAnchors(devices, symbol.device);\n const moves: { readonly from: Point; readonly to: Point }[] = [];\n for (const anchor of Object.values(definition)) {\n const from = symbolPinPosition(symbol, anchor);\n const to = symbolPinPosition(next, anchor);\n if (from.x !== to.x || from.y !== to.y) {\n moves.push({ from, to });\n }\n }\n\n const wires = new Map<string, readonly Point[]>();\n const junctions = new Map<string, Point>();\n const symbols = new Map<string, Point>();\n if (moves.length === 0) {\n return { wires, junctions, symbols };\n }\n\n const pointMoves = [...moves];\n for (const wire of document.sheet.wires) {\n for (const move of moves) {\n const rerouted = stretches\n ? stretchWireEndpoint(wire, move.from, move.to)\n : rerouteWireEndpoint(wire, move.from, move.to);\n if (rerouted === undefined) {\n continue;\n }\n wires.set(wire.id, rerouted.points);\n for (const extra of rerouted.moves) {\n if (!pointMoves.some((candidate) => samePoint(candidate.from, extra.from))) {\n pointMoves.push(extra);\n }\n }\n break;\n }\n }\n\n // Junctions that still lie on their (rerouted) wires stay put; only detached ones are re-placed.\n for (const junction of document.sheet.junctions) {\n const point = { x: junction.x, y: junction.y };\n const attached = junction.wires.every((wireId) => {\n const points = wires.get(wireId) ?? document.sheet.wires.find((w) => w.id === wireId)?.points;\n return points !== undefined && pointOnPolyline(points, point, ON_WIRE_EPSILON);\n });\n if (attached) {\n continue;\n }\n for (const wireId of junction.wires) {\n const before = document.sheet.wires.find((candidate) => candidate.id === wireId);\n const after = wires.get(wireId);\n if (before === undefined || after === undefined) {\n continue;\n }\n const projected = nearestPointOnPolyline(before.points, point);\n const moved =\n projected === undefined\n ? undefined\n : pointOnPolylineAt(after, projected.segment, projected.t);\n if (moved === undefined) {\n continue;\n }\n junctions.set(junction.id, moved);\n break;\n }\n }\n\n for (const move of pointMoves) {\n for (const junction of document.sheet.junctions) {\n if (samePoint({ x: junction.x, y: junction.y }, move.from)) {\n junctions.set(junction.id, move.to);\n }\n }\n for (const other of document.sheet.symbols) {\n if (other.id !== symbolId && samePoint({ x: other.x, y: other.y }, move.from)) {\n symbols.set(other.id, move.to);\n }\n }\n }\n\n return { wires, junctions, symbols };\n}\n\n/** True for the builtin anchors that name a net: net labels, power and ground. */\nfunction isNetAnchor(device: string): boolean {\n return namesNet(symbolRole(device));\n}\n\n/**\n * Connection points of a device in symbol-local space. Net labels, power and ground symbols connect\n * at their own anchor, so they report one at the origin and drag their wire end like a pin does.\n */\nfunction connectionAnchors(\n devices: DeviceSymbolProvider | undefined,\n device: string,\n): Readonly<Record<string, Point>> {\n if (isNetAnchor(device)) {\n return { net: { x: 0, y: 0 } };\n }\n if (symbolRole(device) !== 'component') {\n // Text symbols connect nowhere.\n return {};\n }\n const separator = device.indexOf(':');\n if (separator <= 0 || devices === undefined) {\n return {};\n }\n const packageId = device.slice(0, separator);\n const deviceId = device.slice(separator + 1);\n return devices.getDeviceSymbol({ raw: device, packageId, deviceId })?.pins ?? {};\n}\n\nconst ON_WIRE_EPSILON = 1e-6;\n","import type { Rect } from '../../format/types';\nimport type { DeviceSymbolDefinition, PinAnchor, PinSide } from './symbol';\n\n/** Pin declaration subset used for symbol synthesis (see #11 / #12). */\nexport interface DevicePinDeclaration {\n /** Display side; pins without a side are drawn on the left. */\n readonly side?: PinSide;\n}\n\nexport interface SymbolSynthesisOptions {\n /** Distance between pin rows, in page units. Defaults to 10. */\n readonly pinPitch?: number;\n /** Stub length outside the body. Defaults to 10. */\n readonly stubLength?: number;\n /** Minimum body width. Defaults to 60. */\n readonly minWidth?: number;\n /** Minimum body height. Defaults to 40. */\n readonly minHeight?: number;\n /** Horizontal padding between the body edge and pin labels. Defaults to 10. */\n readonly horizontalPadding?: number;\n /** Vertical padding above the first and below the last pin row. Defaults to 10. */\n readonly verticalPadding?: number;\n /** Approximate glyph width of the device name. Defaults to 5.5. */\n readonly characterWidth?: number;\n /** Approximate glyph width of a pin name. Defaults to 4.5. */\n readonly labelCharacterWidth?: number;\n /** Gap between the device name and the side pin labels. Defaults to 12. */\n readonly nameGap?: number;\n /** Inset of a top/bottom pin label from the body edge. Defaults to 10. */\n readonly labelInset?: number;\n}\n\nexport interface SymbolSynthesisInput {\n readonly name: string;\n readonly pins: Readonly<Record<string, DevicePinDeclaration>>;\n}\n\nconst DEFAULT_PIN_SIDE: PinSide = 'left';\n\n/** Half height of a centred glyph box, in `characterWidth` units. */\nconst NAME_HALF_EXTENT = 1;\n\n/**\n * Derives symbol geometry from pin declarations: no coordinates or body size are authored.\n * Pins keep their declaration order within a side and snap to `pinPitch`.\n */\nexport function synthesizeDeviceSymbol(\n input: SymbolSynthesisInput,\n options: SymbolSynthesisOptions = {},\n): DeviceSymbolDefinition {\n const pinPitch = options.pinPitch ?? 10;\n const stubLength = options.stubLength ?? 10;\n const minWidth = options.minWidth ?? 60;\n const minHeight = options.minHeight ?? 40;\n const horizontalPadding = options.horizontalPadding ?? 10;\n const verticalPadding = options.verticalPadding ?? 10;\n const characterWidth = options.characterWidth ?? 5.5;\n const labelCharacterWidth = options.labelCharacterWidth ?? 4.5;\n const nameGap = options.nameGap ?? 12;\n const labelInset = options.labelInset ?? 10;\n\n const sides: Record<PinSide, string[]> = { left: [], right: [], top: [], bottom: [] };\n for (const [pinId, declaration] of Object.entries(input.pins)) {\n sides[declaration.side ?? DEFAULT_PIN_SIDE].push(pinId);\n }\n\n const rows = Math.max(sides.left.length, sides.right.length);\n const columns = Math.max(sides.top.length, sides.bottom.length);\n const height = Math.max(\n minHeight,\n verticalPadding * 2 + Math.max(rows - 1, 0) * pinPitch + pinPitch,\n // Rotated top/bottom labels must clear the centred device name.\n 2 *\n (NAME_HALF_EXTENT * characterWidth +\n pinPitch / 2 +\n labelInset +\n rotatedHalf(sides, labelCharacterWidth)),\n );\n const width = Math.max(\n minWidth,\n horizontalPadding * 2 + Math.max(columns - 1, 0) * pinPitch + pinPitch,\n );\n\n const leftText = longest(sides.left);\n const rightText = longest(sides.right);\n const contentWidth =\n (leftText + rightText) * labelCharacterWidth +\n input.name.length * characterWidth +\n horizontalPadding * 2 +\n nameGap * 2;\n const bodyWidth = Math.ceil(Math.max(width, contentWidth) / pinPitch) * pinPitch;\n const bodyHeight = Math.ceil(height / pinPitch) * pinPitch;\n\n const body: Rect = {\n x: -bodyWidth / 2,\n y: -bodyHeight / 2,\n width: bodyWidth,\n height: bodyHeight,\n };\n\n const pins: Record<string, PinAnchor> = Object.create(null);\n\n const placeVertical = (pinIds: readonly string[], side: 'left' | 'right'): void => {\n const start = -((pinIds.length - 1) * pinPitch) / 2;\n pinIds.forEach((pinId, index) => {\n const y = start + index * pinPitch;\n const x = side === 'left' ? body.x - stubLength : body.x + body.width + stubLength;\n pins[pinId] = { x, y, side };\n });\n };\n placeVertical(sides.left, 'left');\n placeVertical(sides.right, 'right');\n\n const placeHorizontal = (pinIds: readonly string[], side: 'top' | 'bottom'): void => {\n const start = -((pinIds.length - 1) * pinPitch) / 2;\n pinIds.forEach((pinId, index) => {\n const x = start + index * pinPitch;\n const y = side === 'top' ? body.y - stubLength : body.y + body.height + stubLength;\n pins[pinId] = { x, y, side };\n });\n };\n placeHorizontal(sides.top, 'top');\n placeHorizontal(sides.bottom, 'bottom');\n\n return { name: input.name, pins, bounds: body };\n}\n\nfunction longest(pinIds: readonly string[]): number {\n return pinIds.reduce((max, pinId) => Math.max(max, pinId.length), 0);\n}\n\nfunction rotatedHalf(\n sides: Readonly<Record<PinSide, readonly string[]>>,\n characterWidth: number,\n): number {\n return (Math.max(longest(sides.top), longest(sides.bottom)) * characterWidth) / 2;\n}\n","import type { Diagnostic } from '../../format/diagnostics';\nimport { SchematicError, throwIfErrors } from '../../format/errors';\nimport type { Rect } from '../../format/types';\nimport { isRecord } from '../../format/validate';\nimport {\n formatDeviceReference,\n isReservedPackageId,\n isValidPackageId,\n parseDeviceReference,\n type DeviceReference,\n} from './reference';\nimport type {\n DeviceSymbolDefinition,\n DeviceSymbolGeometry,\n DeviceSymbolProvider,\n PinAnchor,\n PinSide,\n} from './symbol';\nimport { readPropertyDescriptors, type PropertyDescriptor } from './properties';\nimport { synthesizeDeviceSymbol, type DevicePinDeclaration } from './synthesis';\n\nconst PIN_SIDES: readonly PinSide[] = ['left', 'right', 'top', 'bottom'];\n\nexport interface DeviceRegistrationEntry {\n /** Device id, unique within the package. */\n readonly id: string;\n /** Display name; defaults to the device id. */\n readonly displayName?: string;\n readonly description?: string;\n /**\n * Reference-designator prefix used when the device is placed (`U1`, `R3`, `DS2`, …).\n * Falls back to `raw.designatorPrefix`, then to the global default `U`.\n */\n readonly designatorPrefix?: string;\n /** Schematic symbol; omitted when the device has no geometry yet. */\n readonly symbol?: DeviceSymbolGeometry;\n /** Remaining device description fields (#5 pins, #7 properties, #10 ports, ...), kept as-is. */\n readonly raw?: Readonly<Record<string, unknown>>;\n}\n\n/** Package data prepared by the host from the #11 `devices` index and device descriptions. */\nexport interface DevicePackageRegistration {\n readonly packageId: string;\n readonly devices: readonly DeviceRegistrationEntry[];\n}\n\nexport interface ResolvedDevice {\n readonly reference: DeviceReference;\n readonly packageId: string;\n readonly deviceId: string;\n readonly displayName: string;\n readonly description: string | undefined;\n /** Designator prefix declared by the device description; `undefined` when it declares none. */\n readonly designatorPrefix: string | undefined;\n /** Property descriptors declared by `properties` (#7), keyed by property key. */\n readonly propertyDescriptors: ReadonlyMap<string, PropertyDescriptor>;\n readonly symbol: DeviceSymbolDefinition | undefined;\n readonly raw: Readonly<Record<string, unknown>>;\n}\n\nexport interface DeviceRegisterOptions {\n readonly replace?: boolean;\n}\n\nexport interface DeviceRegistry extends DeviceSymbolProvider {\n /** @throws {SchematicError} when the package data is invalid; nothing is registered then. */\n registerPackage(registration: DevicePackageRegistration, options?: DeviceRegisterOptions): void;\n resolve(reference: DeviceReference | string): ResolvedDevice | undefined;\n listDevices(packageId?: string): readonly ResolvedDevice[];\n /** Non-fatal diagnostics collected while registering packages (currently `device/no-symbol`). */\n readonly diagnostics: readonly Diagnostic[];\n}\n\ninterface StoredPackage {\n readonly packageId: string;\n readonly devices: ReadonlyMap<string, ResolvedDevice>;\n}\n\nexport function createDeviceRegistry(\n packages: readonly DevicePackageRegistration[] = [],\n): DeviceRegistry {\n const stored = new Map<string, StoredPackage>();\n const registrationDiagnostics: Diagnostic[] = [];\n\n const getDeviceName = (reference: DeviceReference): string | undefined => {\n const device = lookup(reference);\n // `symbol.name` already resolves to displayName or device id when the description omits it.\n return device?.symbol?.name ?? device?.displayName;\n };\n\n const lookup = (reference: DeviceReference): ResolvedDevice | undefined => {\n const pkg = stored.get(reference.packageId);\n return pkg?.devices.get(reference.deviceId);\n };\n\n const registry: DeviceRegistry = {\n registerPackage(registration, options) {\n const diagnostics: Diagnostic[] = [];\n const packageId = registration.packageId;\n if (!isValidPackageId(packageId)) {\n throw new SchematicError([\n {\n severity: 'error',\n code: 'device/invalid-package',\n message: `Invalid package id ${JSON.stringify(packageId)}.`,\n },\n ]);\n }\n if (isReservedPackageId(packageId)) {\n throw new SchematicError([\n {\n severity: 'error',\n code: 'device/reserved-namespace',\n message: `Package id ${JSON.stringify(packageId)} uses the reserved \"builtin\" namespace.`,\n },\n ]);\n }\n if (stored.has(packageId) && options?.replace !== true) {\n throw new SchematicError([\n {\n severity: 'error',\n code: 'device/duplicate-package',\n message: `Package ${JSON.stringify(packageId)} is already registered.`,\n },\n ]);\n }\n\n const devices = new Map<string, ResolvedDevice>();\n const reportedUnknownPins = new Set<string>();\n for (const entry of registration.devices) {\n const deviceId = typeof entry.id === 'string' ? entry.id : '';\n if (deviceId.length === 0) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-description',\n message: `Package ${JSON.stringify(packageId)} contains a device without an id.`,\n });\n continue;\n }\n const devicePath = `${packageId}:${deviceId}`;\n if (devices.has(deviceId)) {\n diagnostics.push({\n severity: 'error',\n code: 'device/duplicate-device',\n message: `Device ${JSON.stringify(devicePath)} is declared more than once.`,\n });\n continue;\n }\n\n const raw = isRecord(entry.raw) ? entry.raw : Object.create(null);\n const displayName =\n typeof entry.displayName === 'string' && entry.displayName.length > 0\n ? entry.displayName\n : deviceId;\n const symbol = readSymbolGeometry(entry, raw, devicePath, diagnostics, reportedUnknownPins);\n const designatorPrefix = readDesignatorPrefix(entry, raw);\n\n devices.set(deviceId, {\n reference: {\n raw: formatDeviceReference(packageId, deviceId),\n packageId,\n deviceId,\n },\n packageId,\n deviceId,\n displayName,\n description: typeof entry.description === 'string' ? entry.description : undefined,\n designatorPrefix,\n propertyDescriptors: readPropertyDescriptors(raw['properties']),\n symbol,\n raw,\n });\n }\n\n registrationDiagnostics.push(...diagnostics);\n throwIfErrors(diagnostics);\n stored.set(packageId, { packageId, devices });\n },\n\n resolve(reference) {\n const parsed = typeof reference === 'string' ? parseDeviceReference(reference) : reference;\n if (parsed === undefined) {\n return undefined;\n }\n return lookup(parsed);\n },\n\n listDevices(packageId) {\n const packages = packageId === undefined ? [...stored.values()] : [stored.get(packageId)];\n const devices: ResolvedDevice[] = [];\n for (const pkg of packages) {\n if (pkg === undefined) {\n continue;\n }\n devices.push(...pkg.devices.values());\n }\n return devices.sort(\n (a, b) => a.packageId.localeCompare(b.packageId) || a.deviceId.localeCompare(b.deviceId),\n );\n },\n\n getDeviceSymbol(reference) {\n return lookup(reference)?.symbol;\n },\n\n getDeviceName,\n\n getDeviceDesignatorPrefix(reference) {\n return lookup(reference)?.designatorPrefix;\n },\n\n getDevicePropertyDescriptors(reference) {\n return lookup(reference)?.propertyDescriptors;\n },\n\n get diagnostics() {\n return registrationDiagnostics;\n },\n };\n\n for (const registration of packages) {\n registry.registerPackage(registration);\n }\n\n return registry;\n}\n\n/** Designator prefix declared on the entry, else inside `raw`, else `undefined` (caller defaults). */\nfunction readDesignatorPrefix(\n entry: DeviceRegistrationEntry,\n raw: Readonly<Record<string, unknown>>,\n): string | undefined {\n const declared = entry.designatorPrefix ?? raw['designatorPrefix'];\n if (typeof declared !== 'string') {\n return undefined;\n }\n const trimmed = declared.trim();\n return trimmed.length === 0 ? undefined : trimmed;\n}\n\nfunction readSymbolGeometry(\n entry: DeviceRegistrationEntry,\n raw: Readonly<Record<string, unknown>>,\n devicePath: string,\n diagnostics: Diagnostic[],\n reportedUnknownPins: Set<string>,\n): DeviceSymbolDefinition | undefined {\n const displayName =\n typeof entry.displayName === 'string' && entry.displayName.length > 0\n ? entry.displayName\n : entry.id;\n const symbol = entry.symbol;\n\n if (symbol === undefined) {\n // No explicit geometry: derive it from the #5 / #11 pin declaration.\n const declarations = readPinDeclarations(raw['pins']);\n if (declarations === undefined) {\n diagnostics.push({\n severity: 'warning',\n code: 'device/no-symbol',\n message: `Device ${JSON.stringify(devicePath)} has neither symbol geometry nor pin declarations.`,\n });\n return undefined;\n }\n const synthesized = synthesizeDeviceSymbol({ name: displayName, pins: declarations });\n return synthesized;\n }\n\n if (!isRecord(symbol)) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-description',\n message: `Device ${JSON.stringify(devicePath)} has an invalid symbol definition.`,\n });\n return undefined;\n }\n\n const pins = readPins(symbol.pins, devicePath, diagnostics);\n if (pins === undefined) {\n return undefined;\n }\n\n const declaredPins = readDeclaredPinIds(raw.pins);\n if (declaredPins !== undefined) {\n for (const pinId of Object.keys(pins)) {\n if (!declaredPins.has(pinId) && !reportedUnknownPins.has(`${devicePath}\\u0000${pinId}`)) {\n reportedUnknownPins.add(`${devicePath}\\u0000${pinId}`);\n diagnostics.push({\n severity: 'error',\n code: 'device/unknown-pin',\n message: `Device ${JSON.stringify(devicePath)} symbol declares pin ${JSON.stringify(pinId)} which is absent from the pin declaration.`,\n });\n }\n }\n }\n\n const bounds = readBounds(symbol.bounds, devicePath, diagnostics);\n const declaredName =\n typeof symbol.name === 'string' && symbol.name.length > 0 ? symbol.name : undefined;\n const name = declaredName ?? displayName;\n\n return bounds === undefined ? { name, pins } : { name, pins, bounds };\n}\n\nfunction readPinDeclarations(value: unknown): Record<string, DevicePinDeclaration> | undefined {\n if (!isRecord(value) || Object.keys(value).length === 0) {\n return undefined;\n }\n const declarations: Record<string, DevicePinDeclaration> = Object.create(null);\n for (const [pinId, pin] of Object.entries(value)) {\n if (pinId.length === 0 || !isRecord(pin)) {\n return undefined;\n }\n const declaration: {\n -readonly [K in keyof DevicePinDeclaration]: DevicePinDeclaration[K];\n } = {};\n if (PIN_SIDES.includes(pin.side as PinSide)) {\n declaration.side = pin.side as PinSide;\n }\n declarations[pinId] = declaration;\n }\n return declarations;\n}\n\nfunction readPins(\n value: unknown,\n devicePath: string,\n diagnostics: Diagnostic[],\n): Record<string, PinAnchor> | undefined {\n if (!isRecord(value)) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-description',\n message: `Device ${JSON.stringify(devicePath)} symbol must declare a pins object.`,\n });\n return undefined;\n }\n const pins: Record<string, PinAnchor> = Object.create(null);\n let failed = false;\n for (const [pinId, anchor] of Object.entries(value)) {\n if (pinId.length === 0) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-description',\n message: `Device ${JSON.stringify(devicePath)} symbol declares an empty pin id.`,\n });\n failed = true;\n continue;\n }\n if (!isRecord(anchor) || !Number.isFinite(anchor.x) || !Number.isFinite(anchor.y)) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-description',\n message: `Device ${JSON.stringify(devicePath)} pin ${JSON.stringify(pinId)} must have finite x and y anchors.`,\n });\n failed = true;\n continue;\n }\n const side = anchor.side;\n if (side !== undefined && !PIN_SIDES.includes(side as PinSide)) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-description',\n message: `Device ${JSON.stringify(devicePath)} pin ${JSON.stringify(pinId)} has invalid side ${JSON.stringify(side)}.`,\n });\n failed = true;\n continue;\n }\n pins[pinId] =\n side === undefined\n ? { x: anchor.x as number, y: anchor.y as number }\n : { x: anchor.x as number, y: anchor.y as number, side: side as PinSide };\n }\n return failed ? undefined : pins;\n}\n\nfunction readBounds(\n value: unknown,\n devicePath: string,\n diagnostics: Diagnostic[],\n): Rect | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (\n !isRecord(value) ||\n !Number.isFinite(value.x) ||\n !Number.isFinite(value.y) ||\n !Number.isFinite(value.width) ||\n !Number.isFinite(value.height)\n ) {\n diagnostics.push({\n severity: 'error',\n code: 'device/invalid-description',\n message: `Device ${JSON.stringify(devicePath)} symbol bounds must have finite x, y, width and height.`,\n });\n return undefined;\n }\n return {\n x: value.x as number,\n y: value.y as number,\n width: value.width as number,\n height: value.height as number,\n };\n}\n\nfunction readDeclaredPinIds(value: unknown): Set<string> | undefined {\n if (!isRecord(value)) {\n return undefined;\n }\n return new Set(Object.keys(value));\n}\n","import type { SchematicDocument } from '../../format/types';\nimport { designatorOf, parseDeviceReference } from './reference';\nimport type { DeviceSymbolProvider } from './symbol';\n\n/** Prefix used when neither the host nor the device description provides one. */\nexport const DEFAULT_DESIGNATOR_PREFIX = 'U';\n\n/**\n * Picks the reference designator of a newly placed component. Hosts replace this when their\n * naming rules go beyond the device's own prefix.\n */\nexport type DesignatorFactory = (device: string, document: SchematicDocument) => string;\n\n/** Smallest unused `<prefix><n>` designator. */\nexport function nextDesignator(\n document: SchematicDocument,\n prefix: string = DEFAULT_DESIGNATOR_PREFIX,\n): string {\n const used = new Set(\n document.sheet.symbols\n .map((symbol) => designatorOf(symbol))\n .filter((designator): designator is string => designator !== undefined),\n );\n for (let index = 1; index < Number.MAX_SAFE_INTEGER; index += 1) {\n const candidate = `${prefix}${index}`;\n if (!used.has(candidate)) {\n return candidate;\n }\n }\n return prefix;\n}\n\n/**\n * Designator policy derived from the device descriptions: `<device prefix><n>`, falling back to\n * `U` for devices that declare none.\n */\nexport function createDesignatorFactory(\n devices: DeviceSymbolProvider | undefined,\n): DesignatorFactory {\n return (device, document) => nextDesignator(document, designatorPrefixOf(devices, device));\n}\n\n/** Prefix the device declares, else {@link DEFAULT_DESIGNATOR_PREFIX}. */\nexport function designatorPrefixOf(\n devices: DeviceSymbolProvider | undefined,\n device: string,\n): string {\n const reference = parseDeviceReference(device);\n const declared =\n reference === undefined ? undefined : devices?.getDeviceDesignatorPrefix?.(reference);\n return declared ?? DEFAULT_DESIGNATOR_PREFIX;\n}\n\n/** Default policy for providers without device data: `U1`, `U2`, … */\nexport const defaultDesignatorFactory: DesignatorFactory = (device, document) =>\n nextDesignator(document);\n"],"mappings":"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"}
|