@tscircuit/core 0.0.985 → 0.0.987
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +123 -109
- package/dist/index.js +214 -145
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -16,115 +16,6 @@ import { CopperPourPipelineSolver } from '@tscircuit/copper-pour-solver';
|
|
|
16
16
|
import { ConnectivityMap } from 'circuit-json-to-connectivity-map';
|
|
17
17
|
import { GraphicsObject } from 'graphics-debug';
|
|
18
18
|
|
|
19
|
-
declare const orderedRenderPhases: readonly ["ReactSubtreesRender", "InflateSubcircuitCircuitJson", "SourceNameDuplicateComponentRemoval", "PcbFootprintStringRender", "InitializePortsFromChildren", "CreateNetsFromProps", "AssignFallbackProps", "CreateTracesFromProps", "CreateTracesFromNetLabels", "CreateTraceHintsFromProps", "SourceGroupRender", "AssignNameToUnnamedComponents", "SourceRender", "SourceParentAttachment", "PortMatching", "OptimizeSelectorCache", "SourceTraceRender", "SourceAddConnectivityMapKey", "SourceDesignRuleChecks", "SimulationRender", "SchematicComponentRender", "SchematicPortRender", "SchematicPrimitiveRender", "SchematicComponentSizeCalculation", "SchematicLayout", "SchematicTraceRender", "SchematicReplaceNetLabelsWithSymbols", "PanelBoardLayout", "PcbComponentRender", "PcbPrimitiveRender", "PcbFootprintLayout", "PcbPortRender", "PcbPortAttachment", "PcbComponentSizeCalculation", "PcbComponentAnchorAlignment", "PcbLayout", "PcbBoardAutoSize", "PanelLayout", "PcbTraceHintRender", "PcbManualTraceRender", "PcbTraceRender", "PcbRouteNetIslands", "PcbCopperPourRender", "PcbDesignRuleChecks", "SilkscreenOverlapAdjustment", "CadModelRender", "PartsEngineRender", "SimulationSpiceEngineRender"];
|
|
20
|
-
type RenderPhase = (typeof orderedRenderPhases)[number];
|
|
21
|
-
declare const renderPhaseIndexMap: Map<"ReactSubtreesRender" | "InflateSubcircuitCircuitJson" | "SourceNameDuplicateComponentRemoval" | "PcbFootprintStringRender" | "InitializePortsFromChildren" | "CreateNetsFromProps" | "AssignFallbackProps" | "CreateTracesFromProps" | "CreateTracesFromNetLabels" | "CreateTraceHintsFromProps" | "SourceGroupRender" | "AssignNameToUnnamedComponents" | "SourceRender" | "SourceParentAttachment" | "PortMatching" | "OptimizeSelectorCache" | "SourceTraceRender" | "SourceAddConnectivityMapKey" | "SourceDesignRuleChecks" | "SimulationRender" | "SchematicComponentRender" | "SchematicPortRender" | "SchematicPrimitiveRender" | "SchematicComponentSizeCalculation" | "SchematicLayout" | "SchematicTraceRender" | "SchematicReplaceNetLabelsWithSymbols" | "PanelBoardLayout" | "PcbComponentRender" | "PcbPrimitiveRender" | "PcbFootprintLayout" | "PcbPortRender" | "PcbPortAttachment" | "PcbComponentSizeCalculation" | "PcbComponentAnchorAlignment" | "PcbLayout" | "PcbBoardAutoSize" | "PanelLayout" | "PcbTraceHintRender" | "PcbManualTraceRender" | "PcbTraceRender" | "PcbRouteNetIslands" | "PcbCopperPourRender" | "PcbDesignRuleChecks" | "SilkscreenOverlapAdjustment" | "CadModelRender" | "PartsEngineRender" | "SimulationSpiceEngineRender", number>;
|
|
22
|
-
type RenderPhaseFn<K extends RenderPhase = RenderPhase> = `doInitial${K}` | `update${K}` | `remove${K}`;
|
|
23
|
-
type RenderPhaseStates = Record<RenderPhase, {
|
|
24
|
-
initialized: boolean;
|
|
25
|
-
dirty: boolean;
|
|
26
|
-
}>;
|
|
27
|
-
type AsyncEffect = {
|
|
28
|
-
effectName: string;
|
|
29
|
-
promise: Promise<void>;
|
|
30
|
-
phase: RenderPhase;
|
|
31
|
-
complete: boolean;
|
|
32
|
-
};
|
|
33
|
-
type RenderPhaseFunctions = {
|
|
34
|
-
[T in RenderPhaseFn]?: () => void;
|
|
35
|
-
};
|
|
36
|
-
type IRenderable = RenderPhaseFunctions & {
|
|
37
|
-
renderPhaseStates: RenderPhaseStates;
|
|
38
|
-
runRenderPhase(phase: RenderPhase): void;
|
|
39
|
-
runRenderPhaseForChildren(phase: RenderPhase): void;
|
|
40
|
-
shouldBeRemoved: boolean;
|
|
41
|
-
children: IRenderable[];
|
|
42
|
-
runRenderCycle(): void;
|
|
43
|
-
};
|
|
44
|
-
declare abstract class Renderable implements IRenderable {
|
|
45
|
-
renderPhaseStates: RenderPhaseStates;
|
|
46
|
-
shouldBeRemoved: boolean;
|
|
47
|
-
children: IRenderable[];
|
|
48
|
-
/** PCB-only SMTPads, PlatedHoles, Holes, Silkscreen elements etc. */
|
|
49
|
-
isPcbPrimitive: boolean;
|
|
50
|
-
/** Schematic-only, lines, boxes, indicators etc. */
|
|
51
|
-
isSchematicPrimitive: boolean;
|
|
52
|
-
_renderId: string;
|
|
53
|
-
_currentRenderPhase: RenderPhase | null;
|
|
54
|
-
private _asyncEffects;
|
|
55
|
-
parent: Renderable | null;
|
|
56
|
-
constructor(props: any);
|
|
57
|
-
_markDirty(phase: RenderPhase): void;
|
|
58
|
-
_queueAsyncEffect(effectName: string, effect: () => Promise<void>): void;
|
|
59
|
-
protected _emitRenderLifecycleEvent(phase: RenderPhase, startOrEnd: "start" | "end"): void;
|
|
60
|
-
getString(): string;
|
|
61
|
-
_hasIncompleteAsyncEffects(): boolean;
|
|
62
|
-
_hasIncompleteAsyncEffectsInSubtreeForPhase(phase: RenderPhase): boolean;
|
|
63
|
-
getCurrentRenderPhase(): RenderPhase | null;
|
|
64
|
-
getRenderGraph(): Record<string, any>;
|
|
65
|
-
getTopLevelRenderable(): Renderable;
|
|
66
|
-
runRenderCycle(): void;
|
|
67
|
-
/**
|
|
68
|
-
* This runs all the render methods for a given phase, calling one of:
|
|
69
|
-
* - doInitial*
|
|
70
|
-
* - update*
|
|
71
|
-
* -remove*
|
|
72
|
-
* ...depending on the current state of the component.
|
|
73
|
-
*/
|
|
74
|
-
runRenderPhase(phase: RenderPhase): void;
|
|
75
|
-
runRenderPhaseForChildren(phase: RenderPhase): void;
|
|
76
|
-
renderError(message: string | Omit<PcbTraceError, "pcb_error_id"> | Omit<PcbPlacementError, "pcb_error_id"> | Omit<PcbManualEditConflictWarning, "pcb_error_id"> | Omit<PcbViaClearanceError, "pcb_error_id">): void;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* This is how we render in React. This can be a confusing part of the codebase,
|
|
81
|
-
* but here are some helpful reference implementations:
|
|
82
|
-
*
|
|
83
|
-
* https://github.com/diegomura/react-pdf/blob/fabecc56727dfb6d590a3fa1e11f50250ecbbea1/packages/reconciler/src/reconciler-31.js
|
|
84
|
-
* https://github.com/pmndrs/react-three-fiber/blob/ec4f00bb61cc4f6e28b3a12b1dca9daa5594f10e/packages/fiber/src/core/renderer.ts
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*/
|
|
88
|
-
|
|
89
|
-
type ReactSubtree = {
|
|
90
|
-
element: ReactElement;
|
|
91
|
-
component: NormalComponent;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
type SchematicBoxPortPositionWithMetadata = {
|
|
95
|
-
trueIndex: number;
|
|
96
|
-
pinNumber: number;
|
|
97
|
-
side: "left" | "right" | "top" | "bottom";
|
|
98
|
-
distanceFromOrthogonalEdge: number;
|
|
99
|
-
x: number;
|
|
100
|
-
y: number;
|
|
101
|
-
};
|
|
102
|
-
interface SchematicBoxDimensions {
|
|
103
|
-
pinCount: number;
|
|
104
|
-
getPortPositionByPinNumber(pinNumber: number): SchematicBoxPortPositionWithMetadata | null;
|
|
105
|
-
getSize(): {
|
|
106
|
-
width: number;
|
|
107
|
-
height: number;
|
|
108
|
-
};
|
|
109
|
-
getSizeIncludingPins(): {
|
|
110
|
-
width: number;
|
|
111
|
-
height: number;
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
interface SchematicBoxComponentDimensions {
|
|
115
|
-
schWidth: number;
|
|
116
|
-
schHeight: number;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
interface BoardI {
|
|
120
|
-
componentName: string;
|
|
121
|
-
boardThickness: number;
|
|
122
|
-
_connectedSchematicPortPairs: Set<string>;
|
|
123
|
-
allLayers: ReadonlyArray<LayerRef>;
|
|
124
|
-
_getBoardCalcVariables(): Record<string, number>;
|
|
125
|
-
pcb_board_id?: string | null;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
19
|
declare const SOLVERS: {
|
|
129
20
|
PackSolver2: typeof PackSolver2;
|
|
130
21
|
AutoroutingPipelineSolver: typeof AutoroutingPipelineSolver;
|
|
@@ -271,6 +162,124 @@ interface DebugLogOutputEvent {
|
|
|
271
162
|
content: any;
|
|
272
163
|
}
|
|
273
164
|
|
|
165
|
+
interface IRootCircuit {
|
|
166
|
+
emit(event: RootCircuitEventName, ...args: any[]): void;
|
|
167
|
+
on(event: RootCircuitEventName, listener: (...args: any[]) => void): void;
|
|
168
|
+
_hasIncompleteAsyncEffectsForPhase(phase: RenderPhase): boolean;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
declare const orderedRenderPhases: readonly ["ReactSubtreesRender", "InflateSubcircuitCircuitJson", "SourceNameDuplicateComponentRemoval", "PcbFootprintStringRender", "InitializePortsFromChildren", "CreateNetsFromProps", "AssignFallbackProps", "CreateTracesFromProps", "CreateTracesFromNetLabels", "CreateTraceHintsFromProps", "SourceGroupRender", "AssignNameToUnnamedComponents", "SourceRender", "SourceParentAttachment", "PortMatching", "OptimizeSelectorCache", "SourceTraceRender", "SourceAddConnectivityMapKey", "SourceDesignRuleChecks", "SimulationRender", "SchematicComponentRender", "SchematicPortRender", "SchematicPrimitiveRender", "SchematicComponentSizeCalculation", "SchematicLayout", "SchematicTraceRender", "SchematicReplaceNetLabelsWithSymbols", "PanelBoardLayout", "PcbComponentRender", "PcbPrimitiveRender", "PcbFootprintLayout", "PcbPortRender", "PcbPortAttachment", "PcbComponentSizeCalculation", "PcbComponentAnchorAlignment", "PcbLayout", "PcbBoardAutoSize", "PanelLayout", "PcbTraceHintRender", "PcbManualTraceRender", "PcbTraceRender", "PcbRouteNetIslands", "PcbCopperPourRender", "PcbDesignRuleChecks", "SilkscreenOverlapAdjustment", "CadModelRender", "PartsEngineRender", "SimulationSpiceEngineRender"];
|
|
172
|
+
type RenderPhase = (typeof orderedRenderPhases)[number];
|
|
173
|
+
declare const renderPhaseIndexMap: Map<"ReactSubtreesRender" | "InflateSubcircuitCircuitJson" | "SourceNameDuplicateComponentRemoval" | "PcbFootprintStringRender" | "InitializePortsFromChildren" | "CreateNetsFromProps" | "AssignFallbackProps" | "CreateTracesFromProps" | "CreateTracesFromNetLabels" | "CreateTraceHintsFromProps" | "SourceGroupRender" | "AssignNameToUnnamedComponents" | "SourceRender" | "SourceParentAttachment" | "PortMatching" | "OptimizeSelectorCache" | "SourceTraceRender" | "SourceAddConnectivityMapKey" | "SourceDesignRuleChecks" | "SimulationRender" | "SchematicComponentRender" | "SchematicPortRender" | "SchematicPrimitiveRender" | "SchematicComponentSizeCalculation" | "SchematicLayout" | "SchematicTraceRender" | "SchematicReplaceNetLabelsWithSymbols" | "PanelBoardLayout" | "PcbComponentRender" | "PcbPrimitiveRender" | "PcbFootprintLayout" | "PcbPortRender" | "PcbPortAttachment" | "PcbComponentSizeCalculation" | "PcbComponentAnchorAlignment" | "PcbLayout" | "PcbBoardAutoSize" | "PanelLayout" | "PcbTraceHintRender" | "PcbManualTraceRender" | "PcbTraceRender" | "PcbRouteNetIslands" | "PcbCopperPourRender" | "PcbDesignRuleChecks" | "SilkscreenOverlapAdjustment" | "CadModelRender" | "PartsEngineRender" | "SimulationSpiceEngineRender", number>;
|
|
174
|
+
type RenderPhaseFn<K extends RenderPhase = RenderPhase> = `doInitial${K}` | `update${K}` | `remove${K}`;
|
|
175
|
+
type RenderPhaseStates = Record<RenderPhase, {
|
|
176
|
+
initialized: boolean;
|
|
177
|
+
dirty: boolean;
|
|
178
|
+
}>;
|
|
179
|
+
type AsyncEffect = {
|
|
180
|
+
asyncEffectId: string;
|
|
181
|
+
effectName: string;
|
|
182
|
+
promise: Promise<void>;
|
|
183
|
+
phase: RenderPhase;
|
|
184
|
+
complete: boolean;
|
|
185
|
+
};
|
|
186
|
+
type RenderPhaseFunctions = {
|
|
187
|
+
[T in RenderPhaseFn]?: () => void;
|
|
188
|
+
};
|
|
189
|
+
type IRenderable = RenderPhaseFunctions & {
|
|
190
|
+
renderPhaseStates: RenderPhaseStates;
|
|
191
|
+
runRenderPhase(phase: RenderPhase): void;
|
|
192
|
+
runRenderPhaseForChildren(phase: RenderPhase): void;
|
|
193
|
+
shouldBeRemoved: boolean;
|
|
194
|
+
children: IRenderable[];
|
|
195
|
+
runRenderCycle(): void;
|
|
196
|
+
};
|
|
197
|
+
declare abstract class Renderable implements IRenderable {
|
|
198
|
+
renderPhaseStates: RenderPhaseStates;
|
|
199
|
+
shouldBeRemoved: boolean;
|
|
200
|
+
children: IRenderable[];
|
|
201
|
+
/** PCB-only SMTPads, PlatedHoles, Holes, Silkscreen elements etc. */
|
|
202
|
+
isPcbPrimitive: boolean;
|
|
203
|
+
/** Schematic-only, lines, boxes, indicators etc. */
|
|
204
|
+
isSchematicPrimitive: boolean;
|
|
205
|
+
_renderId: string;
|
|
206
|
+
_currentRenderPhase: RenderPhase | null;
|
|
207
|
+
private _asyncEffects;
|
|
208
|
+
parent: Renderable | null;
|
|
209
|
+
constructor(props: any);
|
|
210
|
+
_markDirty(phase: RenderPhase): void;
|
|
211
|
+
_queueAsyncEffect(effectName: string, effect: () => Promise<void>): void;
|
|
212
|
+
protected _emitRenderLifecycleEvent(phase: RenderPhase, startOrEnd: "start" | "end"): void;
|
|
213
|
+
getString(): string;
|
|
214
|
+
_hasIncompleteAsyncEffects(): boolean;
|
|
215
|
+
_hasIncompleteAsyncEffectsInSubtreeForPhase(phase: RenderPhase): boolean;
|
|
216
|
+
_hasIncompleteAsyncEffectsForPhase(phase: RenderPhase): boolean;
|
|
217
|
+
getCurrentRenderPhase(): RenderPhase | null;
|
|
218
|
+
getRenderGraph(): Record<string, any>;
|
|
219
|
+
getTopLevelRenderable(): Renderable;
|
|
220
|
+
runRenderCycle(): void;
|
|
221
|
+
/**
|
|
222
|
+
* This runs all the render methods for a given phase, calling one of:
|
|
223
|
+
* - doInitial*
|
|
224
|
+
* - update*
|
|
225
|
+
* -remove*
|
|
226
|
+
* ...depending on the current state of the component.
|
|
227
|
+
*/
|
|
228
|
+
runRenderPhase(phase: RenderPhase): void;
|
|
229
|
+
runRenderPhaseForChildren(phase: RenderPhase): void;
|
|
230
|
+
protected _getRootCircuit(): IRootCircuit | null;
|
|
231
|
+
renderError(message: string | Omit<PcbTraceError, "pcb_error_id"> | Omit<PcbPlacementError, "pcb_error_id"> | Omit<PcbManualEditConflictWarning, "pcb_error_id"> | Omit<PcbViaClearanceError, "pcb_error_id">): void;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* This is how we render in React. This can be a confusing part of the codebase,
|
|
236
|
+
* but here are some helpful reference implementations:
|
|
237
|
+
*
|
|
238
|
+
* https://github.com/diegomura/react-pdf/blob/fabecc56727dfb6d590a3fa1e11f50250ecbbea1/packages/reconciler/src/reconciler-31.js
|
|
239
|
+
* https://github.com/pmndrs/react-three-fiber/blob/ec4f00bb61cc4f6e28b3a12b1dca9daa5594f10e/packages/fiber/src/core/renderer.ts
|
|
240
|
+
*
|
|
241
|
+
*
|
|
242
|
+
*/
|
|
243
|
+
|
|
244
|
+
type ReactSubtree = {
|
|
245
|
+
element: ReactElement;
|
|
246
|
+
component: NormalComponent;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
type SchematicBoxPortPositionWithMetadata = {
|
|
250
|
+
trueIndex: number;
|
|
251
|
+
pinNumber: number;
|
|
252
|
+
side: "left" | "right" | "top" | "bottom";
|
|
253
|
+
distanceFromOrthogonalEdge: number;
|
|
254
|
+
x: number;
|
|
255
|
+
y: number;
|
|
256
|
+
};
|
|
257
|
+
interface SchematicBoxDimensions {
|
|
258
|
+
pinCount: number;
|
|
259
|
+
getPortPositionByPinNumber(pinNumber: number): SchematicBoxPortPositionWithMetadata | null;
|
|
260
|
+
getSize(): {
|
|
261
|
+
width: number;
|
|
262
|
+
height: number;
|
|
263
|
+
};
|
|
264
|
+
getSizeIncludingPins(): {
|
|
265
|
+
width: number;
|
|
266
|
+
height: number;
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
interface SchematicBoxComponentDimensions {
|
|
270
|
+
schWidth: number;
|
|
271
|
+
schHeight: number;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
interface BoardI {
|
|
275
|
+
componentName: string;
|
|
276
|
+
boardThickness: number;
|
|
277
|
+
_connectedSchematicPortPairs: Set<string>;
|
|
278
|
+
allLayers: ReadonlyArray<LayerRef>;
|
|
279
|
+
_getBoardCalcVariables(): Record<string, number>;
|
|
280
|
+
pcb_board_id?: string | null;
|
|
281
|
+
}
|
|
282
|
+
|
|
274
283
|
declare function resolveStaticFileImport(path: string, platform?: PlatformConfig): Promise<string>;
|
|
275
284
|
|
|
276
285
|
declare class RootCircuit {
|
|
@@ -299,6 +308,8 @@ declare class RootCircuit {
|
|
|
299
308
|
*/
|
|
300
309
|
projectUrl?: string;
|
|
301
310
|
_hasRenderedAtleastOnce: boolean;
|
|
311
|
+
private _asyncEffectIdsByPhase;
|
|
312
|
+
private _asyncEffectPhaseById;
|
|
302
313
|
constructor({ platform, projectUrl, }?: {
|
|
303
314
|
platform?: PlatformConfig;
|
|
304
315
|
projectUrl?: string;
|
|
@@ -313,6 +324,7 @@ declare class RootCircuit {
|
|
|
313
324
|
render(): void;
|
|
314
325
|
renderUntilSettled(): Promise<void>;
|
|
315
326
|
private _hasIncompleteAsyncEffects;
|
|
327
|
+
_hasIncompleteAsyncEffectsForPhase(phase: RenderPhase): boolean;
|
|
316
328
|
getCircuitJson(): AnyCircuitElement[];
|
|
317
329
|
toJson(): AnyCircuitElement[];
|
|
318
330
|
getSvg(options: {
|
|
@@ -336,6 +348,8 @@ declare class RootCircuit {
|
|
|
336
348
|
removeListener(event: RootCircuitEventName, listener: (...args: any[]) => void): void;
|
|
337
349
|
enableDebug(debug: string | null | false): void;
|
|
338
350
|
getClientOrigin(): string;
|
|
351
|
+
private _registerAsyncEffectStart;
|
|
352
|
+
private _registerAsyncEffectEnd;
|
|
339
353
|
}
|
|
340
354
|
/**
|
|
341
355
|
* @deprecated
|
package/dist/index.js
CHANGED
|
@@ -185,6 +185,7 @@ var asyncPhaseDependencies = {
|
|
|
185
185
|
PcbComponentAnchorAlignment: ["PcbFootprintStringRender"]
|
|
186
186
|
};
|
|
187
187
|
var globalRenderCounter = 0;
|
|
188
|
+
var globalAsyncEffectCounter = 0;
|
|
188
189
|
var Renderable = class _Renderable {
|
|
189
190
|
renderPhaseStates;
|
|
190
191
|
shouldBeRemoved = false;
|
|
@@ -219,7 +220,9 @@ var Renderable = class _Renderable {
|
|
|
219
220
|
}
|
|
220
221
|
}
|
|
221
222
|
_queueAsyncEffect(effectName, effect) {
|
|
223
|
+
const asyncEffectId = `${this._renderId}:${globalAsyncEffectCounter++}`;
|
|
222
224
|
const asyncEffect = {
|
|
225
|
+
asyncEffectId,
|
|
223
226
|
promise: effect(),
|
|
224
227
|
// TODO don't start effects until end of render cycle
|
|
225
228
|
phase: this._currentRenderPhase,
|
|
@@ -227,9 +230,10 @@ var Renderable = class _Renderable {
|
|
|
227
230
|
complete: false
|
|
228
231
|
};
|
|
229
232
|
this._asyncEffects.push(asyncEffect);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
+
const root = this._getRootCircuit();
|
|
234
|
+
if (root) {
|
|
235
|
+
root.emit("asyncEffect:start", {
|
|
236
|
+
asyncEffectId,
|
|
233
237
|
effectName,
|
|
234
238
|
componentDisplayName: this.getString(),
|
|
235
239
|
phase: asyncEffect.phase
|
|
@@ -237,9 +241,10 @@ var Renderable = class _Renderable {
|
|
|
237
241
|
}
|
|
238
242
|
asyncEffect.promise.then(() => {
|
|
239
243
|
asyncEffect.complete = true;
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
244
|
+
const root2 = this._getRootCircuit();
|
|
245
|
+
if (root2) {
|
|
246
|
+
root2.emit("asyncEffect:end", {
|
|
247
|
+
asyncEffectId,
|
|
243
248
|
effectName,
|
|
244
249
|
componentDisplayName: this.getString(),
|
|
245
250
|
phase: asyncEffect.phase
|
|
@@ -251,9 +256,10 @@ var Renderable = class _Renderable {
|
|
|
251
256
|
${error.stack}`
|
|
252
257
|
);
|
|
253
258
|
asyncEffect.complete = true;
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
259
|
+
const root2 = this._getRootCircuit();
|
|
260
|
+
if (root2) {
|
|
261
|
+
root2.emit("asyncEffect:end", {
|
|
262
|
+
asyncEffectId,
|
|
257
263
|
effectName,
|
|
258
264
|
componentDisplayName: this.getString(),
|
|
259
265
|
phase: asyncEffect.phase,
|
|
@@ -270,10 +276,10 @@ ${error.stack}`
|
|
|
270
276
|
componentDisplayName: this.getString(),
|
|
271
277
|
type: granular_event_type
|
|
272
278
|
};
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
279
|
+
const root = this._getRootCircuit();
|
|
280
|
+
if (root) {
|
|
281
|
+
root.emit(granular_event_type, eventPayload);
|
|
282
|
+
root.emit("renderable:renderLifecycle:anyEvent", {
|
|
277
283
|
...eventPayload,
|
|
278
284
|
type: granular_event_type
|
|
279
285
|
});
|
|
@@ -299,6 +305,13 @@ ${error.stack}`
|
|
|
299
305
|
}
|
|
300
306
|
return false;
|
|
301
307
|
}
|
|
308
|
+
_hasIncompleteAsyncEffectsForPhase(phase) {
|
|
309
|
+
const root = this._getRootCircuit();
|
|
310
|
+
if (root?._hasIncompleteAsyncEffectsForPhase) {
|
|
311
|
+
return root._hasIncompleteAsyncEffectsForPhase(phase);
|
|
312
|
+
}
|
|
313
|
+
return this._hasIncompleteAsyncEffectsInSubtreeForPhase(phase);
|
|
314
|
+
}
|
|
302
315
|
getCurrentRenderPhase() {
|
|
303
316
|
return this._currentRenderPhase;
|
|
304
317
|
}
|
|
@@ -355,9 +368,8 @@ ${error.stack}`
|
|
|
355
368
|
}
|
|
356
369
|
const deps = asyncPhaseDependencies[phase] || [];
|
|
357
370
|
if (deps.length > 0) {
|
|
358
|
-
const root = this.getTopLevelRenderable();
|
|
359
371
|
for (const depPhase of deps) {
|
|
360
|
-
if (
|
|
372
|
+
if (this._hasIncompleteAsyncEffectsForPhase(depPhase)) {
|
|
361
373
|
return;
|
|
362
374
|
}
|
|
363
375
|
}
|
|
@@ -383,6 +395,12 @@ ${error.stack}`
|
|
|
383
395
|
child.runRenderPhase(phase);
|
|
384
396
|
}
|
|
385
397
|
}
|
|
398
|
+
_getRootCircuit() {
|
|
399
|
+
if ("root" in this) {
|
|
400
|
+
return this.root ?? null;
|
|
401
|
+
}
|
|
402
|
+
return null;
|
|
403
|
+
}
|
|
386
404
|
renderError(message) {
|
|
387
405
|
if (typeof message === "string") {
|
|
388
406
|
throw new Error(message);
|
|
@@ -2358,10 +2376,10 @@ var SmtPad = class extends PrimitiveComponent2 {
|
|
|
2358
2376
|
pcb_group_id: this.getGroup()?.pcb_group_id ?? void 0
|
|
2359
2377
|
});
|
|
2360
2378
|
} else if (props.shape === "polygon") {
|
|
2361
|
-
const transformedPoints = props.points.map((
|
|
2379
|
+
const transformedPoints = props.points.map((point6) => {
|
|
2362
2380
|
const transformed = applyToPoint2(globalTransform, {
|
|
2363
|
-
x: distance.parse(
|
|
2364
|
-
y: distance.parse(
|
|
2381
|
+
x: distance.parse(point6.x),
|
|
2382
|
+
y: distance.parse(point6.y)
|
|
2365
2383
|
});
|
|
2366
2384
|
return {
|
|
2367
2385
|
x: transformed.x,
|
|
@@ -2593,18 +2611,18 @@ var SilkscreenPath = class extends PrimitiveComponent2 {
|
|
|
2593
2611
|
if (!currentPath) return;
|
|
2594
2612
|
let currentCenterX = 0;
|
|
2595
2613
|
let currentCenterY = 0;
|
|
2596
|
-
for (const
|
|
2597
|
-
currentCenterX +=
|
|
2598
|
-
currentCenterY +=
|
|
2614
|
+
for (const point6 of currentPath.route) {
|
|
2615
|
+
currentCenterX += point6.x;
|
|
2616
|
+
currentCenterY += point6.y;
|
|
2599
2617
|
}
|
|
2600
2618
|
currentCenterX /= currentPath.route.length;
|
|
2601
2619
|
currentCenterY /= currentPath.route.length;
|
|
2602
2620
|
const offsetX = newCenter.x - currentCenterX;
|
|
2603
2621
|
const offsetY = newCenter.y - currentCenterY;
|
|
2604
|
-
const newRoute = currentPath.route.map((
|
|
2605
|
-
...
|
|
2606
|
-
x:
|
|
2607
|
-
y:
|
|
2622
|
+
const newRoute = currentPath.route.map((point6) => ({
|
|
2623
|
+
...point6,
|
|
2624
|
+
x: point6.x + offsetX,
|
|
2625
|
+
y: point6.y + offsetY
|
|
2608
2626
|
}));
|
|
2609
2627
|
db.pcb_silkscreen_path.update(this.pcb_silkscreen_path_id, {
|
|
2610
2628
|
route: newRoute
|
|
@@ -2634,11 +2652,11 @@ var SilkscreenPath = class extends PrimitiveComponent2 {
|
|
|
2634
2652
|
return { width: 0, height: 0 };
|
|
2635
2653
|
}
|
|
2636
2654
|
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
2637
|
-
for (const
|
|
2638
|
-
minX = Math.min(minX,
|
|
2639
|
-
maxX = Math.max(maxX,
|
|
2640
|
-
minY = Math.min(minY,
|
|
2641
|
-
maxY = Math.max(maxY,
|
|
2655
|
+
for (const point6 of props.route) {
|
|
2656
|
+
minX = Math.min(minX, point6.x);
|
|
2657
|
+
maxX = Math.max(maxX, point6.x);
|
|
2658
|
+
minY = Math.min(minY, point6.y);
|
|
2659
|
+
maxY = Math.max(maxY, point6.y);
|
|
2642
2660
|
}
|
|
2643
2661
|
return {
|
|
2644
2662
|
width: maxX - minX,
|
|
@@ -2674,14 +2692,14 @@ var PcbTrace = class extends PrimitiveComponent2 {
|
|
|
2674
2692
|
const subcircuit = this.getSubcircuit();
|
|
2675
2693
|
const { maybeFlipLayer } = this._getPcbPrimitiveFlippedHelpers();
|
|
2676
2694
|
const parentTransform = this._computePcbGlobalTransformBeforeLayout();
|
|
2677
|
-
const transformedRoute = props.route.map((
|
|
2678
|
-
const { x, y, ...restOfPoint } =
|
|
2695
|
+
const transformedRoute = props.route.map((point6) => {
|
|
2696
|
+
const { x, y, ...restOfPoint } = point6;
|
|
2679
2697
|
const transformedPoint = applyToPoint4(parentTransform, { x, y });
|
|
2680
|
-
if (
|
|
2698
|
+
if (point6.route_type === "wire" && point6.layer) {
|
|
2681
2699
|
return {
|
|
2682
2700
|
...transformedPoint,
|
|
2683
2701
|
...restOfPoint,
|
|
2684
|
-
layer: maybeFlipLayer(
|
|
2702
|
+
layer: maybeFlipLayer(point6.layer)
|
|
2685
2703
|
};
|
|
2686
2704
|
}
|
|
2687
2705
|
return { ...transformedPoint, ...restOfPoint };
|
|
@@ -2701,16 +2719,16 @@ var PcbTrace = class extends PrimitiveComponent2 {
|
|
|
2701
2719
|
return { width: 0, height: 0 };
|
|
2702
2720
|
}
|
|
2703
2721
|
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
2704
|
-
for (const
|
|
2705
|
-
minX = Math.min(minX,
|
|
2706
|
-
maxX = Math.max(maxX,
|
|
2707
|
-
minY = Math.min(minY,
|
|
2708
|
-
maxY = Math.max(maxY,
|
|
2709
|
-
if (
|
|
2710
|
-
minX = Math.min(minX,
|
|
2711
|
-
maxX = Math.max(maxX,
|
|
2712
|
-
minY = Math.min(minY,
|
|
2713
|
-
maxY = Math.max(maxY,
|
|
2722
|
+
for (const point6 of props.route) {
|
|
2723
|
+
minX = Math.min(minX, point6.x);
|
|
2724
|
+
maxX = Math.max(maxX, point6.x);
|
|
2725
|
+
minY = Math.min(minY, point6.y);
|
|
2726
|
+
maxY = Math.max(maxY, point6.y);
|
|
2727
|
+
if (point6.route_type === "wire") {
|
|
2728
|
+
minX = Math.min(minX, point6.x - point6.width / 2);
|
|
2729
|
+
maxX = Math.max(maxX, point6.x + point6.width / 2);
|
|
2730
|
+
minY = Math.min(minY, point6.y - point6.width / 2);
|
|
2731
|
+
maxY = Math.max(maxY, point6.y + point6.width / 2);
|
|
2714
2732
|
}
|
|
2715
2733
|
}
|
|
2716
2734
|
if (minX === Infinity || maxX === -Infinity || minY === Infinity || maxY === -Infinity) {
|
|
@@ -2977,9 +2995,9 @@ var PlatedHole = class extends PrimitiveComponent2 {
|
|
|
2977
2995
|
});
|
|
2978
2996
|
this.pcb_plated_hole_id = pcb_plated_hole.pcb_plated_hole_id;
|
|
2979
2997
|
} else if (props.shape === "hole_with_polygon_pad") {
|
|
2980
|
-
const padOutline = (props.padOutline || []).map((
|
|
2981
|
-
const x = typeof
|
|
2982
|
-
const y = typeof
|
|
2998
|
+
const padOutline = (props.padOutline || []).map((point6) => {
|
|
2999
|
+
const x = typeof point6.x === "number" ? point6.x : parseFloat(String(point6.x));
|
|
3000
|
+
const y = typeof point6.y === "number" ? point6.y : parseFloat(String(point6.y));
|
|
2983
3001
|
return {
|
|
2984
3002
|
x,
|
|
2985
3003
|
y
|
|
@@ -3398,11 +3416,11 @@ var Cutout = class extends PrimitiveComponent2 {
|
|
|
3398
3416
|
if (props.shape === "polygon") {
|
|
3399
3417
|
if (props.points.length === 0) return { width: 0, height: 0 };
|
|
3400
3418
|
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
3401
|
-
for (const
|
|
3402
|
-
minX = Math.min(minX,
|
|
3403
|
-
maxX = Math.max(maxX,
|
|
3404
|
-
minY = Math.min(minY,
|
|
3405
|
-
maxY = Math.max(maxY,
|
|
3419
|
+
for (const point6 of props.points) {
|
|
3420
|
+
minX = Math.min(minX, point6.x);
|
|
3421
|
+
maxX = Math.max(maxX, point6.x);
|
|
3422
|
+
minY = Math.min(minY, point6.y);
|
|
3423
|
+
maxY = Math.max(maxY, point6.y);
|
|
3406
3424
|
}
|
|
3407
3425
|
return { width: maxX - minX, height: maxY - minY };
|
|
3408
3426
|
}
|
|
@@ -3441,11 +3459,11 @@ var Cutout = class extends PrimitiveComponent2 {
|
|
|
3441
3459
|
} else if (cutout.shape === "polygon") {
|
|
3442
3460
|
if (cutout.points.length === 0) return super._getPcbCircuitJsonBounds();
|
|
3443
3461
|
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
3444
|
-
for (const
|
|
3445
|
-
minX = Math.min(minX,
|
|
3446
|
-
maxX = Math.max(maxX,
|
|
3447
|
-
minY = Math.min(minY,
|
|
3448
|
-
maxY = Math.max(maxY,
|
|
3462
|
+
for (const point6 of cutout.points) {
|
|
3463
|
+
minX = Math.min(minX, point6.x);
|
|
3464
|
+
maxX = Math.max(maxX, point6.x);
|
|
3465
|
+
minY = Math.min(minY, point6.y);
|
|
3466
|
+
maxY = Math.max(maxY, point6.y);
|
|
3449
3467
|
}
|
|
3450
3468
|
return {
|
|
3451
3469
|
center: { x: (minX + maxX) / 2, y: (minY + maxY) / 2 },
|
|
@@ -5488,13 +5506,13 @@ var getDistance = (a, b) => {
|
|
|
5488
5506
|
const bPos = "_getGlobalPcbPositionBeforeLayout" in b ? b._getGlobalPcbPositionBeforeLayout() : b;
|
|
5489
5507
|
return Math.sqrt((aPos.x - bPos.x) ** 2 + (aPos.y - bPos.y) ** 2);
|
|
5490
5508
|
};
|
|
5491
|
-
function getClosest(
|
|
5509
|
+
function getClosest(point6, candidates) {
|
|
5492
5510
|
if (candidates.length === 0)
|
|
5493
5511
|
throw new Error("No candidates given to getClosest method");
|
|
5494
5512
|
let closest = candidates[0];
|
|
5495
5513
|
let closestDist = Infinity;
|
|
5496
5514
|
for (const candidate of candidates) {
|
|
5497
|
-
const dist = getDistance(
|
|
5515
|
+
const dist = getDistance(point6, candidate);
|
|
5498
5516
|
if (dist < closestDist) {
|
|
5499
5517
|
closest = candidate;
|
|
5500
5518
|
closestDist = dist;
|
|
@@ -5624,30 +5642,36 @@ function getTraceDisplayName({
|
|
|
5624
5642
|
}
|
|
5625
5643
|
|
|
5626
5644
|
// lib/utils/is-route-outside-board.ts
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5645
|
+
import { point as point2 } from "@flatten-js/core";
|
|
5646
|
+
|
|
5647
|
+
// lib/utils/get-pcb-board-outline-polygon.ts
|
|
5648
|
+
import { Box, point, Polygon } from "@flatten-js/core";
|
|
5649
|
+
var getPcbBoardOutlinePolygon = (pcbBoard) => {
|
|
5650
|
+
if (pcbBoard.outline && pcbBoard.outline.length > 0) {
|
|
5651
|
+
return new Polygon(pcbBoard.outline.map((p) => point(p.x, p.y)));
|
|
5652
|
+
}
|
|
5653
|
+
return new Polygon(
|
|
5654
|
+
new Box(
|
|
5655
|
+
pcbBoard.center.x - pcbBoard.width / 2,
|
|
5656
|
+
pcbBoard.center.y - pcbBoard.height / 2,
|
|
5657
|
+
pcbBoard.center.x + pcbBoard.width / 2,
|
|
5658
|
+
pcbBoard.center.y + pcbBoard.height / 2
|
|
5659
|
+
).toPoints()
|
|
5660
|
+
);
|
|
5661
|
+
};
|
|
5662
|
+
|
|
5663
|
+
// lib/utils/is-route-outside-board.ts
|
|
5664
|
+
var isRouteOutsideBoard = ({
|
|
5665
|
+
mergedRoute,
|
|
5666
|
+
db,
|
|
5667
|
+
pcbBoardId
|
|
5668
|
+
}) => {
|
|
5669
|
+
const pcbBoard = db.pcb_board.get(pcbBoardId);
|
|
5670
|
+
if (!pcbBoard) return false;
|
|
5671
|
+
const boardOutlinePolygon = getPcbBoardOutlinePolygon(pcbBoard);
|
|
5672
|
+
return !mergedRoute.flat().every(
|
|
5673
|
+
(routePoint) => boardOutlinePolygon.contains(point2(routePoint.x, routePoint.y))
|
|
5674
|
+
);
|
|
5651
5675
|
};
|
|
5652
5676
|
|
|
5653
5677
|
// lib/utils/obstacles/getObstaclesFromRoute.ts
|
|
@@ -6227,12 +6251,12 @@ var createSchematicTraceCrossingSegments = ({
|
|
|
6227
6251
|
|
|
6228
6252
|
// lib/components/primitive-components/Trace/trace-utils/create-schematic-trace-junctions.ts
|
|
6229
6253
|
var TOLERANCE = 1e-3;
|
|
6230
|
-
var isPointWithinEdge = (
|
|
6254
|
+
var isPointWithinEdge = (point6, edge) => {
|
|
6231
6255
|
const minX = Math.min(edge.from.x, edge.to.x);
|
|
6232
6256
|
const maxX = Math.max(edge.from.x, edge.to.x);
|
|
6233
6257
|
const minY = Math.min(edge.from.y, edge.to.y);
|
|
6234
6258
|
const maxY = Math.max(edge.from.y, edge.to.y);
|
|
6235
|
-
return
|
|
6259
|
+
return point6.x >= minX && point6.x <= maxX && point6.y >= minY && point6.y <= maxY;
|
|
6236
6260
|
};
|
|
6237
6261
|
var getEdgeOrientation = (edge) => {
|
|
6238
6262
|
const isVertical = Math.abs(edge.from.x - edge.to.x) < TOLERANCE;
|
|
@@ -6840,15 +6864,15 @@ import { getFullConnectivityMapFromCircuitJson } from "circuit-json-to-connectiv
|
|
|
6840
6864
|
function getTraceLength(route) {
|
|
6841
6865
|
let totalLength = 0;
|
|
6842
6866
|
for (let i = 0; i < route.length; i++) {
|
|
6843
|
-
const
|
|
6844
|
-
if (
|
|
6867
|
+
const point6 = route[i];
|
|
6868
|
+
if (point6.route_type === "wire") {
|
|
6845
6869
|
const nextPoint = route[i + 1];
|
|
6846
6870
|
if (nextPoint) {
|
|
6847
|
-
const dx = nextPoint.x -
|
|
6848
|
-
const dy = nextPoint.y -
|
|
6871
|
+
const dx = nextPoint.x - point6.x;
|
|
6872
|
+
const dy = nextPoint.y - point6.y;
|
|
6849
6873
|
totalLength += Math.sqrt(dx * dx + dy * dy);
|
|
6850
6874
|
}
|
|
6851
|
-
} else if (
|
|
6875
|
+
} else if (point6.route_type === "via") {
|
|
6852
6876
|
totalLength += 1.6;
|
|
6853
6877
|
}
|
|
6854
6878
|
}
|
|
@@ -7158,17 +7182,17 @@ function Trace_doInitialPcbTraceRender(trace) {
|
|
|
7158
7182
|
});
|
|
7159
7183
|
trace._portsRoutedOnPcb = ports;
|
|
7160
7184
|
trace.pcb_trace_id = pcb_trace.pcb_trace_id;
|
|
7161
|
-
for (const
|
|
7162
|
-
if (
|
|
7185
|
+
for (const point6 of mergedRoute) {
|
|
7186
|
+
if (point6.route_type === "via") {
|
|
7163
7187
|
db.pcb_via.insert({
|
|
7164
7188
|
pcb_trace_id: pcb_trace.pcb_trace_id,
|
|
7165
|
-
x:
|
|
7166
|
-
y:
|
|
7189
|
+
x: point6.x,
|
|
7190
|
+
y: point6.y,
|
|
7167
7191
|
hole_diameter: holeDiameter,
|
|
7168
7192
|
outer_diameter: padDiameter,
|
|
7169
|
-
layers: [
|
|
7170
|
-
from_layer:
|
|
7171
|
-
to_layer:
|
|
7193
|
+
layers: [point6.from_layer, point6.to_layer],
|
|
7194
|
+
from_layer: point6.from_layer,
|
|
7195
|
+
to_layer: point6.to_layer
|
|
7172
7196
|
});
|
|
7173
7197
|
}
|
|
7174
7198
|
}
|
|
@@ -7830,7 +7854,15 @@ var Trace3 = class extends PrimitiveComponent2 {
|
|
|
7830
7854
|
}
|
|
7831
7855
|
_insertErrorIfTraceIsOutsideBoard(mergedRoute, ports) {
|
|
7832
7856
|
const { db } = this.root;
|
|
7833
|
-
const
|
|
7857
|
+
const board = this._getBoard();
|
|
7858
|
+
if (!board) return;
|
|
7859
|
+
const pcbBoardId = board.pcb_board_id;
|
|
7860
|
+
if (!pcbBoardId) return;
|
|
7861
|
+
const isOutsideBoard = isRouteOutsideBoard({
|
|
7862
|
+
mergedRoute,
|
|
7863
|
+
db,
|
|
7864
|
+
pcbBoardId
|
|
7865
|
+
});
|
|
7834
7866
|
if (isOutsideBoard) {
|
|
7835
7867
|
db.pcb_trace_error.insert({
|
|
7836
7868
|
error_type: "pcb_trace_error",
|
|
@@ -10553,7 +10585,7 @@ var getSimpleRouteJsonFromCircuitJson = ({
|
|
|
10553
10585
|
layerCount: board?.num_layers ?? 2,
|
|
10554
10586
|
minTraceWidth,
|
|
10555
10587
|
nominalTraceWidth,
|
|
10556
|
-
outline: board?.outline?.map((
|
|
10588
|
+
outline: board?.outline?.map((point6) => ({ ...point6 }))
|
|
10557
10589
|
},
|
|
10558
10590
|
connMap
|
|
10559
10591
|
};
|
|
@@ -14249,16 +14281,16 @@ function splitRouteAtJumperPads(route, padInfos) {
|
|
|
14249
14281
|
const segments = [];
|
|
14250
14282
|
let currentSegment = [];
|
|
14251
14283
|
for (let i = 0; i < route.length; i++) {
|
|
14252
|
-
const
|
|
14253
|
-
currentSegment.push(
|
|
14254
|
-
if (
|
|
14255
|
-
const padInfo = findJumperPortContainingPoint(padInfos,
|
|
14284
|
+
const point6 = route[i];
|
|
14285
|
+
currentSegment.push(point6);
|
|
14286
|
+
if (point6.route_type === "wire" && i > 0 && i < route.length - 1) {
|
|
14287
|
+
const padInfo = findJumperPortContainingPoint(padInfos, point6.x, point6.y);
|
|
14256
14288
|
if (padInfo) {
|
|
14257
|
-
if (!
|
|
14258
|
-
|
|
14289
|
+
if (!point6.end_pcb_port_id) {
|
|
14290
|
+
point6.end_pcb_port_id = padInfo.pcb_port_id;
|
|
14259
14291
|
}
|
|
14260
14292
|
segments.push(currentSegment);
|
|
14261
|
-
const newStartPoint = { ...
|
|
14293
|
+
const newStartPoint = { ...point6 };
|
|
14262
14294
|
delete newStartPoint.end_pcb_port_id;
|
|
14263
14295
|
if (!newStartPoint.start_pcb_port_id) {
|
|
14264
14296
|
newStartPoint.start_pcb_port_id = padInfo.pcb_port_id;
|
|
@@ -14396,9 +14428,9 @@ var Group6 = class extends NormalComponent3 {
|
|
|
14396
14428
|
const { _parsedProps: props } = this;
|
|
14397
14429
|
const groupProps2 = props;
|
|
14398
14430
|
const hasOutline = groupProps2.outline && groupProps2.outline.length > 0;
|
|
14399
|
-
const numericOutline = hasOutline ? groupProps2.outline.map((
|
|
14400
|
-
x: distance8.parse(
|
|
14401
|
-
y: distance8.parse(
|
|
14431
|
+
const numericOutline = hasOutline ? groupProps2.outline.map((point6) => ({
|
|
14432
|
+
x: distance8.parse(point6.x),
|
|
14433
|
+
y: distance8.parse(point6.y)
|
|
14402
14434
|
})) : void 0;
|
|
14403
14435
|
const ctx = this.props;
|
|
14404
14436
|
const anchorPosition = this._getGlobalPcbPositionBeforeLayout();
|
|
@@ -14435,9 +14467,9 @@ var Group6 = class extends NormalComponent3 {
|
|
|
14435
14467
|
const hasOutline = props.outline && props.outline.length > 0;
|
|
14436
14468
|
const hasExplicitPositioning = this._parsedProps.pcbX !== void 0 || this._parsedProps.pcbY !== void 0;
|
|
14437
14469
|
if (hasOutline) {
|
|
14438
|
-
const numericOutline = props.outline.map((
|
|
14439
|
-
x: distance8.parse(
|
|
14440
|
-
y: distance8.parse(
|
|
14470
|
+
const numericOutline = props.outline.map((point6) => ({
|
|
14471
|
+
x: distance8.parse(point6.x),
|
|
14472
|
+
y: distance8.parse(point6.y)
|
|
14441
14473
|
}));
|
|
14442
14474
|
const outlineBounds = getBoundsFromPoints3(numericOutline);
|
|
14443
14475
|
if (!outlineBounds) return;
|
|
@@ -14907,20 +14939,20 @@ var Group6 = class extends NormalComponent3 {
|
|
|
14907
14939
|
continue;
|
|
14908
14940
|
}
|
|
14909
14941
|
if (pcb_trace.type === "pcb_trace") {
|
|
14910
|
-
for (const
|
|
14911
|
-
if (
|
|
14942
|
+
for (const point6 of pcb_trace.route) {
|
|
14943
|
+
if (point6.route_type === "via") {
|
|
14912
14944
|
db.pcb_via.insert({
|
|
14913
14945
|
pcb_trace_id: pcb_trace.pcb_trace_id,
|
|
14914
|
-
x:
|
|
14915
|
-
y:
|
|
14946
|
+
x: point6.x,
|
|
14947
|
+
y: point6.y,
|
|
14916
14948
|
hole_diameter: holeDiameter,
|
|
14917
14949
|
outer_diameter: padDiameter,
|
|
14918
14950
|
layers: [
|
|
14919
|
-
|
|
14920
|
-
|
|
14951
|
+
point6.from_layer,
|
|
14952
|
+
point6.to_layer
|
|
14921
14953
|
],
|
|
14922
|
-
from_layer:
|
|
14923
|
-
to_layer:
|
|
14954
|
+
from_layer: point6.from_layer,
|
|
14955
|
+
to_layer: point6.to_layer
|
|
14924
14956
|
});
|
|
14925
14957
|
}
|
|
14926
14958
|
}
|
|
@@ -16410,9 +16442,9 @@ var Board = class extends Group6 {
|
|
|
16410
16442
|
center
|
|
16411
16443
|
};
|
|
16412
16444
|
if (outline) {
|
|
16413
|
-
update.outline = outline.map((
|
|
16414
|
-
x:
|
|
16415
|
-
y:
|
|
16445
|
+
update.outline = outline.map((point6) => ({
|
|
16446
|
+
x: point6.x + (props.outlineOffsetX ?? 0),
|
|
16447
|
+
y: point6.y + (props.outlineOffsetY ?? 0)
|
|
16416
16448
|
}));
|
|
16417
16449
|
}
|
|
16418
16450
|
db.pcb_board.update(this.pcb_board_id, update);
|
|
@@ -16499,8 +16531,8 @@ var Board = class extends Group6 {
|
|
|
16499
16531
|
});
|
|
16500
16532
|
}
|
|
16501
16533
|
if (props.outline) {
|
|
16502
|
-
const xValues = props.outline.map((
|
|
16503
|
-
const yValues = props.outline.map((
|
|
16534
|
+
const xValues = props.outline.map((point6) => point6.x);
|
|
16535
|
+
const yValues = props.outline.map((point6) => point6.y);
|
|
16504
16536
|
const minX = Math.min(...xValues);
|
|
16505
16537
|
const maxX = Math.max(...xValues);
|
|
16506
16538
|
const minY = Math.min(...yValues);
|
|
@@ -16535,9 +16567,9 @@ var Board = class extends Group6 {
|
|
|
16535
16567
|
num_layers: this.allLayers.length,
|
|
16536
16568
|
width: computedWidth,
|
|
16537
16569
|
height: computedHeight,
|
|
16538
|
-
outline: outline?.map((
|
|
16539
|
-
x:
|
|
16540
|
-
y:
|
|
16570
|
+
outline: outline?.map((point6) => ({
|
|
16571
|
+
x: point6.x + (props.outlineOffsetX ?? 0) + outlineTranslation.x,
|
|
16572
|
+
y: point6.y + (props.outlineOffsetY ?? 0) + outlineTranslation.y
|
|
16541
16573
|
})),
|
|
16542
16574
|
material: props.material
|
|
16543
16575
|
});
|
|
@@ -16654,7 +16686,7 @@ import { distance as distance11 } from "circuit-json";
|
|
|
16654
16686
|
|
|
16655
16687
|
// lib/utils/panels/generate-panel-tabs-and-mouse-bites.ts
|
|
16656
16688
|
import * as Flatten from "@flatten-js/core";
|
|
16657
|
-
import { point as
|
|
16689
|
+
import { point as point5, Polygon as Polygon3 } from "@flatten-js/core";
|
|
16658
16690
|
var DEFAULT_TAB_LENGTH = 5;
|
|
16659
16691
|
var DEFAULT_TAB_WIDTH = 2;
|
|
16660
16692
|
var generateCutoutsAndMousebitesForOutline = (outline, options) => {
|
|
@@ -16790,8 +16822,8 @@ function generatePanelTabsAndMouseBites(boards, options) {
|
|
|
16790
16822
|
if (board.width && board.height) {
|
|
16791
16823
|
boardDimensions.push(Math.min(board.width, board.height));
|
|
16792
16824
|
} else if (board.outline && board.outline.length > 0) {
|
|
16793
|
-
const outlinePolygon = new
|
|
16794
|
-
board.outline.map((p) =>
|
|
16825
|
+
const outlinePolygon = new Polygon3(
|
|
16826
|
+
board.outline.map((p) => point5(p.x, p.y))
|
|
16795
16827
|
);
|
|
16796
16828
|
const area = Math.abs(outlinePolygon.area());
|
|
16797
16829
|
if (area > 0) {
|
|
@@ -18029,10 +18061,10 @@ var FabricationNotePath = class extends PrimitiveComponent2 {
|
|
|
18029
18061
|
const { _parsedProps: props } = this;
|
|
18030
18062
|
if (props.route.length === 0) return { width: 0, height: 0 };
|
|
18031
18063
|
const xs = props.route.map(
|
|
18032
|
-
(
|
|
18064
|
+
(point6) => typeof point6.x === "string" ? parseFloat(point6.x) : point6.x
|
|
18033
18065
|
);
|
|
18034
18066
|
const ys = props.route.map(
|
|
18035
|
-
(
|
|
18067
|
+
(point6) => typeof point6.y === "string" ? parseFloat(point6.y) : point6.y
|
|
18036
18068
|
);
|
|
18037
18069
|
const minX = Math.min(...xs);
|
|
18038
18070
|
const maxX = Math.max(...xs);
|
|
@@ -18450,8 +18482,8 @@ var PcbNotePath = class extends PrimitiveComponent2 {
|
|
|
18450
18482
|
const subcircuit = this.getSubcircuit();
|
|
18451
18483
|
const group = this.getGroup();
|
|
18452
18484
|
const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id ?? void 0;
|
|
18453
|
-
const transformedRoute = props.route.map((
|
|
18454
|
-
const { x, y, ...rest } =
|
|
18485
|
+
const transformedRoute = props.route.map((point6) => {
|
|
18486
|
+
const { x, y, ...rest } = point6;
|
|
18455
18487
|
const numericX = typeof x === "string" ? parseFloat(x) : x;
|
|
18456
18488
|
const numericY = typeof y === "string" ? parseFloat(y) : y;
|
|
18457
18489
|
const transformed = applyToPoint15(transform, { x: numericX, y: numericY });
|
|
@@ -18471,10 +18503,10 @@ var PcbNotePath = class extends PrimitiveComponent2 {
|
|
|
18471
18503
|
const { _parsedProps: props } = this;
|
|
18472
18504
|
if (props.route.length === 0) return { width: 0, height: 0 };
|
|
18473
18505
|
const xs = props.route.map(
|
|
18474
|
-
(
|
|
18506
|
+
(point6) => typeof point6.x === "string" ? parseFloat(point6.x) : point6.x
|
|
18475
18507
|
);
|
|
18476
18508
|
const ys = props.route.map(
|
|
18477
|
-
(
|
|
18509
|
+
(point6) => typeof point6.y === "string" ? parseFloat(point6.y) : point6.y
|
|
18478
18510
|
);
|
|
18479
18511
|
const minX = Math.min(...xs);
|
|
18480
18512
|
const maxX = Math.max(...xs);
|
|
@@ -18750,11 +18782,11 @@ var BreakoutPoint = class extends PrimitiveComponent2 {
|
|
|
18750
18782
|
if (this.root?.pcbDisabled) return;
|
|
18751
18783
|
const { db } = this.root;
|
|
18752
18784
|
if (!this.pcb_breakout_point_id) return;
|
|
18753
|
-
const
|
|
18754
|
-
if (
|
|
18785
|
+
const point6 = db.pcb_breakout_point.get(this.pcb_breakout_point_id);
|
|
18786
|
+
if (point6) {
|
|
18755
18787
|
db.pcb_breakout_point.update(this.pcb_breakout_point_id, {
|
|
18756
|
-
x:
|
|
18757
|
-
y:
|
|
18788
|
+
x: point6.x + deltaX,
|
|
18789
|
+
y: point6.y + deltaY
|
|
18758
18790
|
});
|
|
18759
18791
|
}
|
|
18760
18792
|
}
|
|
@@ -20325,9 +20357,9 @@ var SchematicPath = class extends PrimitiveComponent2 {
|
|
|
20325
20357
|
const schematic_component_id = this.getPrimitiveContainer()?.parent?.schematic_component_id;
|
|
20326
20358
|
db.schematic_path.insert({
|
|
20327
20359
|
schematic_component_id,
|
|
20328
|
-
points: props.points.map((
|
|
20329
|
-
x:
|
|
20330
|
-
y:
|
|
20360
|
+
points: props.points.map((point6) => ({
|
|
20361
|
+
x: point6.x + globalPos.x,
|
|
20362
|
+
y: point6.y + globalPos.y
|
|
20331
20363
|
})),
|
|
20332
20364
|
is_filled: props.isFilled,
|
|
20333
20365
|
fill_color: props.fillColor,
|
|
@@ -21002,7 +21034,7 @@ import { identity as identity5 } from "transformation-matrix";
|
|
|
21002
21034
|
var package_default = {
|
|
21003
21035
|
name: "@tscircuit/core",
|
|
21004
21036
|
type: "module",
|
|
21005
|
-
version: "0.0.
|
|
21037
|
+
version: "0.0.986",
|
|
21006
21038
|
types: "dist/index.d.ts",
|
|
21007
21039
|
main: "dist/index.js",
|
|
21008
21040
|
module: "dist/index.js",
|
|
@@ -21152,6 +21184,8 @@ var RootCircuit = class {
|
|
|
21152
21184
|
*/
|
|
21153
21185
|
projectUrl;
|
|
21154
21186
|
_hasRenderedAtleastOnce = false;
|
|
21187
|
+
_asyncEffectIdsByPhase = /* @__PURE__ */ new Map();
|
|
21188
|
+
_asyncEffectPhaseById = /* @__PURE__ */ new Map();
|
|
21155
21189
|
constructor({
|
|
21156
21190
|
platform,
|
|
21157
21191
|
projectUrl
|
|
@@ -21244,8 +21278,12 @@ var RootCircuit = class {
|
|
|
21244
21278
|
this.emit("renderComplete");
|
|
21245
21279
|
}
|
|
21246
21280
|
_hasIncompleteAsyncEffects() {
|
|
21281
|
+
if (this._asyncEffectPhaseById.size > 0) return true;
|
|
21247
21282
|
return this.children.some((child) => child._hasIncompleteAsyncEffects());
|
|
21248
21283
|
}
|
|
21284
|
+
_hasIncompleteAsyncEffectsForPhase(phase) {
|
|
21285
|
+
return (this._asyncEffectIdsByPhase.get(phase)?.size ?? 0) > 0;
|
|
21286
|
+
}
|
|
21249
21287
|
getCircuitJson() {
|
|
21250
21288
|
if (!this._hasRenderedAtleastOnce) this.render();
|
|
21251
21289
|
return this.db.toArray();
|
|
@@ -21295,6 +21333,11 @@ var RootCircuit = class {
|
|
|
21295
21333
|
}
|
|
21296
21334
|
_eventListeners = {};
|
|
21297
21335
|
emit(event, ...args) {
|
|
21336
|
+
if (event === "asyncEffect:start") {
|
|
21337
|
+
this._registerAsyncEffectStart(args[0]);
|
|
21338
|
+
} else if (event === "asyncEffect:end") {
|
|
21339
|
+
this._registerAsyncEffectEnd(args[0]);
|
|
21340
|
+
}
|
|
21298
21341
|
if (!this._eventListeners[event]) return;
|
|
21299
21342
|
for (const listener of this._eventListeners[event]) {
|
|
21300
21343
|
listener(...args);
|
|
@@ -21328,6 +21371,32 @@ var RootCircuit = class {
|
|
|
21328
21371
|
}
|
|
21329
21372
|
return "";
|
|
21330
21373
|
}
|
|
21374
|
+
_registerAsyncEffectStart(payload) {
|
|
21375
|
+
if (!payload?.asyncEffectId || !payload.phase) return;
|
|
21376
|
+
const { asyncEffectId, phase } = payload;
|
|
21377
|
+
const existingPhase = this._asyncEffectPhaseById.get(asyncEffectId);
|
|
21378
|
+
if (existingPhase && existingPhase !== phase) {
|
|
21379
|
+
this._asyncEffectIdsByPhase.get(existingPhase)?.delete(asyncEffectId);
|
|
21380
|
+
}
|
|
21381
|
+
if (!this._asyncEffectIdsByPhase.has(phase)) {
|
|
21382
|
+
this._asyncEffectIdsByPhase.set(phase, /* @__PURE__ */ new Set());
|
|
21383
|
+
}
|
|
21384
|
+
this._asyncEffectIdsByPhase.get(phase).add(asyncEffectId);
|
|
21385
|
+
this._asyncEffectPhaseById.set(asyncEffectId, phase);
|
|
21386
|
+
}
|
|
21387
|
+
_registerAsyncEffectEnd(payload) {
|
|
21388
|
+
if (!payload?.asyncEffectId) return;
|
|
21389
|
+
const { asyncEffectId } = payload;
|
|
21390
|
+
const phase = this._asyncEffectPhaseById.get(asyncEffectId) ?? payload.phase;
|
|
21391
|
+
if (phase) {
|
|
21392
|
+
const phaseSet = this._asyncEffectIdsByPhase.get(phase);
|
|
21393
|
+
phaseSet?.delete(asyncEffectId);
|
|
21394
|
+
if (phaseSet && phaseSet.size === 0) {
|
|
21395
|
+
this._asyncEffectIdsByPhase.delete(phase);
|
|
21396
|
+
}
|
|
21397
|
+
}
|
|
21398
|
+
this._asyncEffectPhaseById.delete(asyncEffectId);
|
|
21399
|
+
}
|
|
21331
21400
|
};
|
|
21332
21401
|
var Project = RootCircuit;
|
|
21333
21402
|
var Circuit = RootCircuit;
|