@tscircuit/parts-engine 0.0.30 → 0.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -26,8 +26,12 @@ __export(dist_exports, {
26
26
  experiment_type: () => experiment_type,
27
27
  external_footprint_load_error: () => external_footprint_load_error,
28
28
  frequency: () => frequency,
29
+ getRotationBetweenPcbPin1Locations: () => getRotationBetweenPcbPin1Locations,
29
30
  getZodPrefixedIdWithDefault: () => getZodPrefixedIdWithDefault,
30
31
  inductance: () => inductance,
32
+ insertionDirectionToCanonical: () => insertionDirectionToCanonical,
33
+ insertionDirectionToVector: () => insertionDirectionToVector,
34
+ insertion_direction: () => insertion_direction,
31
35
  kicadAt: () => kicadAt,
32
36
  kicadEffects: () => kicadEffects,
33
37
  kicadFont: () => kicadFont,
@@ -56,6 +60,7 @@ __export(dist_exports, {
56
60
  pcb_breakout_point: () => pcb_breakout_point,
57
61
  pcb_component: () => pcb_component,
58
62
  pcb_component_invalid_layer_error: () => pcb_component_invalid_layer_error,
63
+ pcb_component_missing_courtyard_warning: () => pcb_component_missing_courtyard_warning,
59
64
  pcb_component_not_on_board_edge_error: () => pcb_component_not_on_board_edge_error,
60
65
  pcb_component_outside_board_error: () => pcb_component_outside_board_error,
61
66
  pcb_connector_not_in_accessible_orientation_warning: () => pcb_connector_not_in_accessible_orientation_warning,
@@ -75,6 +80,11 @@ __export(dist_exports, {
75
80
  pcb_cutout_path: () => pcb_cutout_path,
76
81
  pcb_cutout_polygon: () => pcb_cutout_polygon,
77
82
  pcb_cutout_rect: () => pcb_cutout_rect,
83
+ pcb_debug_line: () => pcb_debug_line,
84
+ pcb_debug_object: () => pcb_debug_object,
85
+ pcb_debug_object_base: () => pcb_debug_object_base,
86
+ pcb_debug_point: () => pcb_debug_point,
87
+ pcb_debug_rect: () => pcb_debug_rect,
78
88
  pcb_fabrication_note_dimension: () => pcb_fabrication_note_dimension,
79
89
  pcb_fabrication_note_path: () => pcb_fabrication_note_path,
80
90
  pcb_fabrication_note_rect: () => pcb_fabrication_note_rect,
@@ -99,10 +109,12 @@ __export(dist_exports, {
99
109
  pcb_note_path: () => pcb_note_path,
100
110
  pcb_note_rect: () => pcb_note_rect,
101
111
  pcb_note_text: () => pcb_note_text,
112
+ pcb_packing_error: () => pcb_packing_error,
102
113
  pcb_pad_pad_clearance_error: () => pcb_pad_pad_clearance_error,
103
114
  pcb_pad_trace_clearance_error: () => pcb_pad_trace_clearance_error,
104
115
  pcb_panel: () => pcb_panel,
105
116
  pcb_panelization_placement_error: () => pcb_panelization_placement_error,
117
+ pcb_pin1_location: () => pcb_pin1_location,
106
118
  pcb_placement_error: () => pcb_placement_error,
107
119
  pcb_plated_hole: () => pcb_plated_hole,
108
120
  pcb_port: () => pcb_port,
@@ -132,6 +144,8 @@ __export(dist_exports, {
132
144
  pcb_trace_route_point_through_pad: () => pcb_trace_route_point_through_pad,
133
145
  pcb_trace_route_point_via: () => pcb_trace_route_point_via,
134
146
  pcb_trace_route_point_wire: () => pcb_trace_route_point_wire,
147
+ pcb_trace_too_long_warning: () => pcb_trace_too_long_warning,
148
+ pcb_trace_too_many_vias_warning: () => pcb_trace_too_many_vias_warning,
135
149
  pcb_trace_warning: () => pcb_trace_warning,
136
150
  pcb_via: () => pcb_via,
137
151
  pcb_via_clearance_error: () => pcb_via_clearance_error,
@@ -150,13 +164,16 @@ __export(dist_exports, {
150
164
  schematic_box: () => schematic_box,
151
165
  schematic_circle: () => schematic_circle,
152
166
  schematic_component: () => schematic_component,
167
+ schematic_component_overlap_warning: () => schematic_component_overlap_warning,
153
168
  schematic_component_port_arrangement_by_sides: () => schematic_component_port_arrangement_by_sides,
154
169
  schematic_component_port_arrangement_by_size: () => schematic_component_port_arrangement_by_size,
170
+ schematic_component_styling_warning: () => schematic_component_styling_warning,
155
171
  schematic_debug_line: () => schematic_debug_line,
156
172
  schematic_debug_object: () => schematic_debug_object,
157
173
  schematic_debug_object_base: () => schematic_debug_object_base,
158
174
  schematic_debug_point: () => schematic_debug_point,
159
175
  schematic_debug_rect: () => schematic_debug_rect,
176
+ schematic_element_outside_sheet_warning: () => schematic_element_outside_sheet_warning,
160
177
  schematic_error: () => schematic_error,
161
178
  schematic_group: () => schematic_group,
162
179
  schematic_layout_error: () => schematic_layout_error,
@@ -175,14 +192,26 @@ __export(dist_exports, {
175
192
  schematic_trace: () => schematic_trace,
176
193
  schematic_voltage_probe: () => schematic_voltage_probe,
177
194
  simulation_ac_current_source: () => simulation_ac_current_source,
195
+ simulation_ac_sweep_current_graph: () => simulation_ac_sweep_current_graph,
196
+ simulation_ac_sweep_voltage_graph: () => simulation_ac_sweep_voltage_graph,
178
197
  simulation_ac_voltage_source: () => simulation_ac_voltage_source,
198
+ simulation_complex_sample: () => simulation_complex_sample,
179
199
  simulation_current_probe: () => simulation_current_probe,
180
200
  simulation_current_source: () => simulation_current_source,
181
201
  simulation_dc_current_source: () => simulation_dc_current_source,
202
+ simulation_dc_operating_point_current: () => simulation_dc_operating_point_current,
203
+ simulation_dc_operating_point_voltage: () => simulation_dc_operating_point_voltage,
204
+ simulation_dc_sweep_current_graph: () => simulation_dc_sweep_current_graph,
205
+ simulation_dc_sweep_unit: () => simulation_dc_sweep_unit,
206
+ simulation_dc_sweep_voltage_graph: () => simulation_dc_sweep_voltage_graph,
182
207
  simulation_dc_voltage_source: () => simulation_dc_voltage_source,
183
208
  simulation_experiment: () => simulation_experiment,
184
209
  simulation_op_amp: () => simulation_op_amp,
185
210
  simulation_oscilloscope_trace: () => simulation_oscilloscope_trace,
211
+ simulation_parameter_sweep: () => simulation_parameter_sweep,
212
+ simulation_parameter_sweep_coordinate: () => simulation_parameter_sweep_coordinate,
213
+ simulation_parameter_type: () => simulation_parameter_type,
214
+ simulation_parameter_unit: () => simulation_parameter_unit,
186
215
  simulation_spice_subcircuit: () => simulation_spice_subcircuit,
187
216
  simulation_switch: () => simulation_switch,
188
217
  simulation_transient_current_graph: () => simulation_transient_current_graph,
@@ -222,6 +251,7 @@ __export(dist_exports, {
222
251
  source_simple_capacitor: () => source_simple_capacitor,
223
252
  source_simple_chip: () => source_simple_chip,
224
253
  source_simple_connector: () => source_simple_connector,
254
+ source_simple_connector_standards: () => source_simple_connector_standards,
225
255
  source_simple_crystal: () => source_simple_crystal,
226
256
  source_simple_current_source: () => source_simple_current_source,
227
257
  source_simple_diode: () => source_simple_diode,
@@ -266,6 +296,7 @@ var SI_PREFIX_VALUES = /* @__PURE__ */ new Map([
266
296
  ["", 1],
267
297
  ["m", 1e-3],
268
298
  ["\xB5", 1e-6],
299
+ ["\u03BC", 1e-6],
269
300
  ["u", 1e-6],
270
301
  ["n", 1e-9],
271
302
  ["p", 1e-12],
@@ -336,6 +367,7 @@ var unitMappings = {
336
367
  baseUnit: "A",
337
368
  variants: {
338
369
  \u00B5A: 1e-6,
370
+ \u03BCA: 1e-6,
339
371
  mA: 1e-3,
340
372
  ma: 1e-3,
341
373
  A: 1,
@@ -349,6 +381,7 @@ var unitMappings = {
349
381
  pF: 1e-12,
350
382
  nF: 1e-9,
351
383
  \u00B5F: 1e-6,
384
+ \u03BCF: 1e-6,
352
385
  uF: 1e-6,
353
386
  mF: 1e-3,
354
387
  F: 1,
@@ -363,6 +396,7 @@ var unitMappings = {
363
396
  pH: 1e-12,
364
397
  nH: 1e-9,
365
398
  \u00B5H: 1e-6,
399
+ \u03BCH: 1e-6,
366
400
  uH: 1e-6,
367
401
  mH: 1e-3,
368
402
  H: 1,
@@ -394,6 +428,7 @@ var unitMappings = {
394
428
  ns: 1e-6,
395
429
  us: 1e-3,
396
430
  \u00B5s: 1e-3,
431
+ \u03BCs: 1e-3,
397
432
  ms: 1,
398
433
  s: 1e3
399
434
  }
@@ -403,6 +438,7 @@ var unitMappings = {
403
438
  variants: {
404
439
  nm: 1e-6,
405
440
  \u00B5m: 1e-3,
441
+ \u03BCm: 1e-3,
406
442
  um: 1e-3,
407
443
  mm: 1,
408
444
  cm: 10,
@@ -4660,6 +4696,8 @@ var pcbRenderLayer = external_exports.enum([
4660
4696
  "inner4_copper",
4661
4697
  "inner5_copper",
4662
4698
  "inner6_copper",
4699
+ "inner7_copper",
4700
+ "inner8_copper",
4663
4701
  "edge_cuts",
4664
4702
  "drill"
4665
4703
  ]);
@@ -4956,9 +4994,20 @@ var source_simple_pin_header = source_component_base.extend({
4956
4994
  gender: external_exports.enum(["male", "female"]).optional().default("male")
4957
4995
  });
4958
4996
  expectTypesMatch(true);
4997
+ var source_simple_connector_standards = [
4998
+ "usb_c",
4999
+ "m2",
5000
+ "jst_sh",
5001
+ "jst_gh",
5002
+ "jst_zh",
5003
+ "jst_ph",
5004
+ "jst_xh",
5005
+ "jst_vh"
5006
+ ];
4959
5007
  var source_simple_connector = source_component_base.extend({
4960
5008
  ftype: external_exports.literal("simple_connector"),
4961
- standard: external_exports.enum(["usb_c", "m2"]).optional()
5009
+ standard: external_exports.enum(source_simple_connector_standards).optional(),
5010
+ pin_count: external_exports.number().int().positive().optional()
4962
5011
  });
4963
5012
  expectTypesMatch(true);
4964
5013
  var source_simple_pinout = source_component_base.extend({
@@ -5006,6 +5055,7 @@ var source_project_metadata = external_exports.object({
5006
5055
  name: external_exports.string().optional(),
5007
5056
  software_used_string: external_exports.string().optional(),
5008
5057
  project_url: external_exports.string().optional(),
5058
+ source_filesystem_md5_hash: external_exports.string().optional(),
5009
5059
  created_at: timestamp.optional()
5010
5060
  });
5011
5061
  expectTypesMatch(true);
@@ -5243,6 +5293,7 @@ var source_trace = external_exports.object({
5243
5293
  subcircuit_id: external_exports.string().optional(),
5244
5294
  subcircuit_connectivity_map_key: external_exports.string().optional(),
5245
5295
  max_length: external_exports.number().optional(),
5296
+ max_via_count: external_exports.number().int().nonnegative().optional(),
5246
5297
  name: external_exports.string().optional(),
5247
5298
  min_trace_thickness: external_exports.number().optional(),
5248
5299
  display_name: external_exports.string().optional()
@@ -5310,7 +5361,9 @@ var all_layers = [
5310
5361
  "inner3",
5311
5362
  "inner4",
5312
5363
  "inner5",
5313
- "inner6"
5364
+ "inner6",
5365
+ "inner7",
5366
+ "inner8"
5314
5367
  ];
5315
5368
  var layer_string = external_exports.enum(all_layers);
5316
5369
  var layer_ref = layer_string.or(
@@ -5329,7 +5382,7 @@ var source_manually_placed_via = external_exports.object({
5329
5382
  type: external_exports.literal("source_manually_placed_via"),
5330
5383
  source_manually_placed_via_id: external_exports.string(),
5331
5384
  source_group_id: external_exports.string(),
5332
- source_net_id: external_exports.string(),
5385
+ source_net_id: external_exports.string().min(1).optional(),
5333
5386
  subcircuit_id: external_exports.string().optional(),
5334
5387
  source_trace_id: external_exports.string().optional()
5335
5388
  }).describe("Defines a via that is manually placed in the source domain");
@@ -5651,6 +5704,7 @@ var schematic_text = external_exports.object({
5651
5704
  schematic_component_id: external_exports.string().optional(),
5652
5705
  schematic_symbol_id: external_exports.string().optional(),
5653
5706
  schematic_text_id: external_exports.string(),
5707
+ source_trace_id: external_exports.string().optional(),
5654
5708
  text: external_exports.string(),
5655
5709
  font_size: external_exports.number().default(0.18),
5656
5710
  position: external_exports.object({
@@ -5676,8 +5730,11 @@ var schematic_port = external_exports.object({
5676
5730
  true_ccw_index: external_exports.number().optional(),
5677
5731
  pin_number: external_exports.number().optional(),
5678
5732
  display_pin_label: external_exports.string().optional(),
5733
+ display_pin_label_font_size: external_exports.number().positive().finite().optional(),
5679
5734
  subcircuit_id: external_exports.string().optional(),
5680
5735
  is_connected: external_exports.boolean().optional(),
5736
+ is_internal_circuit_port: external_exports.boolean().optional(),
5737
+ is_overlapping_internal_circuit_port: external_exports.boolean().optional(),
5681
5738
  has_input_arrow: external_exports.boolean().optional(),
5682
5739
  has_output_arrow: external_exports.boolean().optional(),
5683
5740
  is_drawn_with_inversion_circle: external_exports.boolean().optional()
@@ -5772,6 +5829,54 @@ var schematic_manual_edit_conflict_warning = external_exports.object({
5772
5829
  "Warning emitted when a component has both manual placement and explicit schX/schY coordinates"
5773
5830
  );
5774
5831
  expectTypesMatch(true);
5832
+ var schematic_component_overlap_warning = external_exports.object({
5833
+ type: external_exports.literal("schematic_component_overlap_warning"),
5834
+ schematic_component_overlap_warning_id: getZodPrefixedIdWithDefault(
5835
+ "schematic_component_overlap_warning"
5836
+ ),
5837
+ warning_type: external_exports.literal("schematic_component_overlap_warning").default("schematic_component_overlap_warning"),
5838
+ message: external_exports.string(),
5839
+ schematic_component_ids: external_exports.tuple([external_exports.string(), external_exports.string()]),
5840
+ schematic_sheet_id: external_exports.string().optional()
5841
+ }).describe(
5842
+ "Warning emitted when the rendered bounds of two schematic components overlap"
5843
+ );
5844
+ expectTypesMatch(true);
5845
+ var schematic_component_styling_warning = external_exports.object({
5846
+ type: external_exports.literal("schematic_component_styling_warning"),
5847
+ schematic_component_styling_warning_id: getZodPrefixedIdWithDefault(
5848
+ "schematic_component_styling_warning"
5849
+ ),
5850
+ warning_type: external_exports.literal("schematic_component_styling_warning").default("schematic_component_styling_warning"),
5851
+ message: external_exports.string(),
5852
+ schematic_component_id: external_exports.string(),
5853
+ styling_issue_type: external_exports.string(),
5854
+ schematic_port_ids: external_exports.array(external_exports.string()).optional(),
5855
+ source_component_id: external_exports.string().optional(),
5856
+ schematic_sheet_id: external_exports.string().optional(),
5857
+ subcircuit_id: external_exports.string().optional()
5858
+ }).describe(
5859
+ "Warning emitted when a schematic component has a visual styling issue"
5860
+ );
5861
+ expectTypesMatch(true);
5862
+ var schematic_element_outside_sheet_warning = external_exports.object({
5863
+ type: external_exports.literal("schematic_element_outside_sheet_warning"),
5864
+ schematic_element_outside_sheet_warning_id: getZodPrefixedIdWithDefault(
5865
+ "schematic_element_outside_sheet_warning"
5866
+ ),
5867
+ warning_type: external_exports.literal("schematic_element_outside_sheet_warning").default("schematic_element_outside_sheet_warning"),
5868
+ message: external_exports.string(),
5869
+ schematic_sheet_id: external_exports.string(),
5870
+ schematic_element_type: external_exports.enum([
5871
+ "schematic_component",
5872
+ "schematic_net_label",
5873
+ "schematic_trace"
5874
+ ]),
5875
+ schematic_element_id: external_exports.string()
5876
+ }).describe(
5877
+ "Warning emitted when a schematic component, net label, or trace extends outside its schematic sheet"
5878
+ );
5879
+ expectTypesMatch(true);
5775
5880
  var schematic_group = external_exports.object({
5776
5881
  type: external_exports.literal("schematic_group"),
5777
5882
  schematic_group_id: getZodPrefixedIdWithDefault("schematic_group"),
@@ -5849,6 +5954,90 @@ var brep_shape = external_exports.object({
5849
5954
  inner_rings: external_exports.array(ring).default([])
5850
5955
  });
5851
5956
  expectTypesMatch(true);
5957
+ var insertionDirectionToCanonical = {
5958
+ from_left: "from_left",
5959
+ from_right: "from_right",
5960
+ from_top: "from_top",
5961
+ from_bottom: "from_bottom",
5962
+ from_above: "from_above",
5963
+ from_below: "from_below",
5964
+ from_x_neg: "from_left",
5965
+ from_x_pos: "from_right",
5966
+ from_y_pos: "from_top",
5967
+ from_y_neg: "from_bottom",
5968
+ from_z_pos: "from_above",
5969
+ from_z_neg: "from_below",
5970
+ /** @deprecated use `from_top` */
5971
+ from_front: "from_top",
5972
+ /** @deprecated use `from_bottom` */
5973
+ from_back: "from_bottom"
5974
+ };
5975
+ var insertionDirectionToVector = {
5976
+ from_left: { x: -1, y: 0, z: 0 },
5977
+ from_right: { x: 1, y: 0, z: 0 },
5978
+ from_top: { x: 0, y: 1, z: 0 },
5979
+ from_bottom: { x: 0, y: -1, z: 0 },
5980
+ from_above: { x: 0, y: 0, z: 1 },
5981
+ from_below: { x: 0, y: 0, z: -1 }
5982
+ };
5983
+ var insertion_direction = external_exports.enum([
5984
+ "from_left",
5985
+ "from_right",
5986
+ "from_top",
5987
+ "from_bottom",
5988
+ "from_above",
5989
+ "from_below",
5990
+ "from_x_neg",
5991
+ "from_x_pos",
5992
+ "from_y_pos",
5993
+ "from_y_neg",
5994
+ "from_z_pos",
5995
+ "from_z_neg",
5996
+ // Deprecated, accepted so existing Circuit JSON keeps parsing.
5997
+ "from_front",
5998
+ "from_back"
5999
+ ]).transform((value) => insertionDirectionToCanonical[value]).describe(
6000
+ 'The side exposing the receptacle where the cable or mating part is attached, following the 2D PCB diagram convention, not a 3D viewport frame. In project coordinate space, "from_top" is +Y, "from_bottom" -Y, "from_left" -X, "from_right" +X, "from_above" +Z and "from_below" -Z. A receptacle on the +Y edge is "from_top" even though the plug moves in -Y as it seats. Cartesian spellings such as "from_y_pos" are accepted and normalized to the named values, as are the deprecated "from_front" (now "from_top") and "from_back" (now "from_bottom").'
6001
+ );
6002
+ expectTypesMatch(true);
6003
+ expectTypesMatch(
6004
+ true
6005
+ );
6006
+ var pcb_pin1_location = external_exports.enum([
6007
+ "leftside_top",
6008
+ "leftside_bottom",
6009
+ "rightside_top",
6010
+ "rightside_bottom",
6011
+ "topside_left",
6012
+ "topside_right",
6013
+ "bottomside_left",
6014
+ "bottomside_right"
6015
+ ]);
6016
+ expectTypesMatch(true);
6017
+ var pin1LocationRotationCycles = [
6018
+ [
6019
+ "leftside_top",
6020
+ "bottomside_left",
6021
+ "rightside_bottom",
6022
+ "topside_right"
6023
+ ],
6024
+ [
6025
+ "leftside_bottom",
6026
+ "bottomside_right",
6027
+ "rightside_top",
6028
+ "topside_left"
6029
+ ]
6030
+ ];
6031
+ var getRotationBetweenPcbPin1Locations = (from, to) => {
6032
+ for (const cycle of pin1LocationRotationCycles) {
6033
+ const fromIndex = cycle.indexOf(from);
6034
+ const toIndex = cycle.indexOf(to);
6035
+ if (fromIndex !== -1 && toIndex !== -1) {
6036
+ return (toIndex - fromIndex + cycle.length) % cycle.length * 90;
6037
+ }
6038
+ }
6039
+ return null;
6040
+ };
5852
6041
  var pcb_route_hint = external_exports.object({
5853
6042
  x: distance,
5854
6043
  y: distance,
@@ -5909,13 +6098,13 @@ var pcb_component = external_exports.object({
5909
6098
  positioned_relative_to_pcb_group_id: external_exports.string().optional(),
5910
6099
  positioned_relative_to_pcb_board_id: external_exports.string().optional(),
5911
6100
  cable_insertion_center: point.optional(),
5912
- insertion_direction: external_exports.enum([
5913
- "from_above",
5914
- "from_left",
5915
- "from_right",
5916
- "from_front",
5917
- "from_back"
5918
- ]).optional(),
6101
+ insertion_direction: insertion_direction.optional(),
6102
+ pin1_location: pcb_pin1_location.optional().describe(
6103
+ "Location of pin 1 on the unrotated, top-view component footprint"
6104
+ ),
6105
+ supplier_pin1_location_map: external_exports.record(supplier_name, pcb_pin1_location).optional().describe(
6106
+ "Pin 1 location for each supplier's unrotated, top-view footprint"
6107
+ ),
5919
6108
  metadata: external_exports.object({
5920
6109
  kicad_footprint: kicadFootprintMetadata.optional()
5921
6110
  }).optional(),
@@ -5924,6 +6113,32 @@ var pcb_component = external_exports.object({
5924
6113
  )
5925
6114
  }).describe("Defines a component on the PCB");
5926
6115
  expectTypesMatch(true);
6116
+ var pcb_debug_object_base = external_exports.object({
6117
+ type: external_exports.literal("pcb_debug_object"),
6118
+ pcb_debug_object_id: getZodPrefixedIdWithDefault("pcb_debug_object"),
6119
+ label: external_exports.string().optional(),
6120
+ subcircuit_id: external_exports.string().optional()
6121
+ });
6122
+ var pcb_debug_rect = pcb_debug_object_base.extend({
6123
+ shape: external_exports.literal("rect"),
6124
+ center: point,
6125
+ size
6126
+ });
6127
+ var pcb_debug_line = pcb_debug_object_base.extend({
6128
+ shape: external_exports.literal("line"),
6129
+ start: point,
6130
+ end: point
6131
+ });
6132
+ var pcb_debug_point = pcb_debug_object_base.extend({
6133
+ shape: external_exports.literal("point"),
6134
+ center: point
6135
+ });
6136
+ var pcb_debug_object = external_exports.discriminatedUnion("shape", [
6137
+ pcb_debug_rect,
6138
+ pcb_debug_line,
6139
+ pcb_debug_point
6140
+ ]);
6141
+ expectTypesMatch(true);
5927
6142
  var pcb_hole_circle = external_exports.object({
5928
6143
  type: external_exports.literal("pcb_hole"),
5929
6144
  pcb_hole_id: getZodPrefixedIdWithDefault("pcb_hole"),
@@ -6214,7 +6429,8 @@ var pcb_smtpad_circle = external_exports.object({
6214
6429
  pcb_component_id: external_exports.string().optional(),
6215
6430
  pcb_port_id: external_exports.string().optional(),
6216
6431
  is_covered_with_solder_mask: external_exports.boolean().optional(),
6217
- soldermask_margin: external_exports.number().optional()
6432
+ soldermask_margin: external_exports.number().optional(),
6433
+ solderpaste_margin: external_exports.number().optional()
6218
6434
  });
6219
6435
  var pcb_smtpad_rect = external_exports.object({
6220
6436
  type: external_exports.literal("pcb_smtpad"),
@@ -6237,7 +6453,8 @@ var pcb_smtpad_rect = external_exports.object({
6237
6453
  soldermask_margin_left: external_exports.number().optional(),
6238
6454
  soldermask_margin_top: external_exports.number().optional(),
6239
6455
  soldermask_margin_right: external_exports.number().optional(),
6240
- soldermask_margin_bottom: external_exports.number().optional()
6456
+ soldermask_margin_bottom: external_exports.number().optional(),
6457
+ solderpaste_margin: external_exports.number().optional()
6241
6458
  });
6242
6459
  var pcb_smtpad_rotated_rect = external_exports.object({
6243
6460
  type: external_exports.literal("pcb_smtpad"),
@@ -6261,7 +6478,8 @@ var pcb_smtpad_rotated_rect = external_exports.object({
6261
6478
  soldermask_margin_left: external_exports.number().optional(),
6262
6479
  soldermask_margin_top: external_exports.number().optional(),
6263
6480
  soldermask_margin_right: external_exports.number().optional(),
6264
- soldermask_margin_bottom: external_exports.number().optional()
6481
+ soldermask_margin_bottom: external_exports.number().optional(),
6482
+ solderpaste_margin: external_exports.number().optional()
6265
6483
  });
6266
6484
  var pcb_smtpad_pill = external_exports.object({
6267
6485
  type: external_exports.literal("pcb_smtpad"),
@@ -6279,7 +6497,8 @@ var pcb_smtpad_pill = external_exports.object({
6279
6497
  pcb_component_id: external_exports.string().optional(),
6280
6498
  pcb_port_id: external_exports.string().optional(),
6281
6499
  is_covered_with_solder_mask: external_exports.boolean().optional(),
6282
- soldermask_margin: external_exports.number().optional()
6500
+ soldermask_margin: external_exports.number().optional(),
6501
+ solderpaste_margin: external_exports.number().optional()
6283
6502
  });
6284
6503
  var pcb_smtpad_rotated_pill = external_exports.object({
6285
6504
  type: external_exports.literal("pcb_smtpad"),
@@ -6298,7 +6517,8 @@ var pcb_smtpad_rotated_pill = external_exports.object({
6298
6517
  pcb_component_id: external_exports.string().optional(),
6299
6518
  pcb_port_id: external_exports.string().optional(),
6300
6519
  is_covered_with_solder_mask: external_exports.boolean().optional(),
6301
- soldermask_margin: external_exports.number().optional()
6520
+ soldermask_margin: external_exports.number().optional(),
6521
+ solderpaste_margin: external_exports.number().optional()
6302
6522
  });
6303
6523
  var pcb_smtpad_polygon = external_exports.object({
6304
6524
  type: external_exports.literal("pcb_smtpad"),
@@ -6312,7 +6532,8 @@ var pcb_smtpad_polygon = external_exports.object({
6312
6532
  pcb_component_id: external_exports.string().optional(),
6313
6533
  pcb_port_id: external_exports.string().optional(),
6314
6534
  is_covered_with_solder_mask: external_exports.boolean().optional(),
6315
- soldermask_margin: external_exports.number().optional()
6535
+ soldermask_margin: external_exports.number().optional(),
6536
+ solderpaste_margin: external_exports.number().optional()
6316
6537
  });
6317
6538
  var pcb_smtpad = external_exports.discriminatedUnion("shape", [
6318
6539
  pcb_smtpad_circle,
@@ -6385,6 +6606,22 @@ var pcb_solder_paste_rotated_rect = external_exports.object({
6385
6606
  pcb_component_id: external_exports.string().optional(),
6386
6607
  pcb_smtpad_id: external_exports.string().optional()
6387
6608
  });
6609
+ var pcb_solder_paste_rotated_pill = external_exports.object({
6610
+ type: external_exports.literal("pcb_solder_paste"),
6611
+ shape: external_exports.literal("rotated_pill"),
6612
+ pcb_solder_paste_id: getZodPrefixedIdWithDefault("pcb_solder_paste"),
6613
+ pcb_group_id: external_exports.string().optional(),
6614
+ subcircuit_id: external_exports.string().optional(),
6615
+ x: distance,
6616
+ y: distance,
6617
+ width: external_exports.number(),
6618
+ height: external_exports.number(),
6619
+ radius: external_exports.number(),
6620
+ ccw_rotation: rotation,
6621
+ layer: layer_ref,
6622
+ pcb_component_id: external_exports.string().optional(),
6623
+ pcb_smtpad_id: external_exports.string().optional()
6624
+ });
6388
6625
  var pcb_solder_paste_oval = external_exports.object({
6389
6626
  type: external_exports.literal("pcb_solder_paste"),
6390
6627
  shape: external_exports.literal("oval"),
@@ -6404,6 +6641,7 @@ var pcb_solder_paste = external_exports.union([
6404
6641
  pcb_solder_paste_rect,
6405
6642
  pcb_solder_paste_pill,
6406
6643
  pcb_solder_paste_rotated_rect,
6644
+ pcb_solder_paste_rotated_pill,
6407
6645
  pcb_solder_paste_oval
6408
6646
  ]).describe("Defines solderpaste on the PCB");
6409
6647
  expectTypesMatch(true);
@@ -6412,6 +6650,9 @@ expectTypesMatch(true);
6412
6650
  expectTypesMatch(
6413
6651
  true
6414
6652
  );
6653
+ expectTypesMatch(
6654
+ true
6655
+ );
6415
6656
  expectTypesMatch(true);
6416
6657
  var pcb_text = external_exports.object({
6417
6658
  type: external_exports.literal("pcb_text"),
@@ -6494,6 +6735,40 @@ var pcb_trace_warning = external_exports.object({
6494
6735
  subcircuit_id: external_exports.string().optional()
6495
6736
  }).describe("Defines a trace warning on the PCB");
6496
6737
  expectTypesMatch(true);
6738
+ var pcb_trace_too_long_warning = external_exports.object({
6739
+ type: external_exports.literal("pcb_trace_too_long_warning"),
6740
+ pcb_trace_too_long_warning_id: getZodPrefixedIdWithDefault(
6741
+ "pcb_trace_too_long_warning"
6742
+ ),
6743
+ warning_type: external_exports.literal("pcb_trace_too_long_warning").default("pcb_trace_too_long_warning"),
6744
+ message: external_exports.string(),
6745
+ pcb_trace_id: external_exports.string(),
6746
+ source_net_id: external_exports.string().optional(),
6747
+ source_trace_id: external_exports.string().optional(),
6748
+ actual_trace_length: distance,
6749
+ maximum_trace_length: distance,
6750
+ subcircuit_id: external_exports.string().optional()
6751
+ }).describe(
6752
+ "Warning emitted when a PCB trace is longer than its maximum allowed length"
6753
+ );
6754
+ expectTypesMatch(true);
6755
+ var pcb_trace_too_many_vias_warning = external_exports.object({
6756
+ type: external_exports.literal("pcb_trace_too_many_vias_warning"),
6757
+ pcb_trace_too_many_vias_warning_id: getZodPrefixedIdWithDefault(
6758
+ "pcb_trace_too_many_vias_warning"
6759
+ ),
6760
+ warning_type: external_exports.literal("pcb_trace_too_many_vias_warning").default("pcb_trace_too_many_vias_warning"),
6761
+ message: external_exports.string(),
6762
+ pcb_trace_id: external_exports.string(),
6763
+ source_net_id: external_exports.string().optional(),
6764
+ source_trace_id: external_exports.string().optional(),
6765
+ actual_via_count: external_exports.number().int().nonnegative(),
6766
+ maximum_via_count: external_exports.number().int().nonnegative(),
6767
+ subcircuit_id: external_exports.string().optional()
6768
+ }).describe(
6769
+ "Warning emitted when a PCB trace has more vias than its maximum allowed count"
6770
+ );
6771
+ expectTypesMatch(true);
6497
6772
  var pcb_trace_error = base_circuit_json_error.extend({
6498
6773
  type: external_exports.literal("pcb_trace_error"),
6499
6774
  pcb_trace_error_id: getZodPrefixedIdWithDefault("pcb_trace_error"),
@@ -6565,6 +6840,8 @@ var pcb_via = external_exports.object({
6565
6840
  to_layer: layer_ref.optional(),
6566
6841
  layers: external_exports.array(layer_ref),
6567
6842
  pcb_trace_id: external_exports.string().optional(),
6843
+ source_trace_id: external_exports.string().optional(),
6844
+ source_net_id: external_exports.string().min(1).optional(),
6568
6845
  net_is_assignable: external_exports.boolean().optional(),
6569
6846
  net_assigned: external_exports.boolean().optional(),
6570
6847
  is_tented: external_exports.boolean().optional()
@@ -6578,6 +6855,7 @@ var pcb_board = external_exports.object({
6578
6855
  is_subcircuit: external_exports.boolean().optional(),
6579
6856
  subcircuit_id: external_exports.string().optional(),
6580
6857
  is_mounted_to_carrier_board: external_exports.boolean().optional(),
6858
+ is_via_in_pad_allowed: external_exports.boolean().optional(),
6581
6859
  width: length.optional(),
6582
6860
  height: length.optional(),
6583
6861
  center: point,
@@ -6589,6 +6867,9 @@ var pcb_board = external_exports.object({
6589
6867
  ),
6590
6868
  thickness: length.optional().default(1.4),
6591
6869
  num_layers: external_exports.number().optional().default(4),
6870
+ allow_blind_and_buried_vias: external_exports.boolean().optional().describe(
6871
+ "Whether autorouters may generate blind and buried vias. False restricts newly generated vias to the full board stack."
6872
+ ),
6592
6873
  outline: external_exports.array(point).optional(),
6593
6874
  shape: external_exports.enum(["rect", "polygon"]).optional(),
6594
6875
  material: external_exports.enum(["fr4", "fr1"]).default("fr4"),
@@ -6616,6 +6897,14 @@ var pcb_placement_error = base_circuit_json_error.extend({
6616
6897
  subcircuit_id: external_exports.string().optional()
6617
6898
  }).describe("Defines a placement error on the PCB");
6618
6899
  expectTypesMatch(true);
6900
+ var pcb_packing_error = base_circuit_json_error.extend({
6901
+ type: external_exports.literal("pcb_packing_error"),
6902
+ pcb_packing_error_id: getZodPrefixedIdWithDefault("pcb_packing_error"),
6903
+ error_type: external_exports.literal("pcb_packing_error").default("pcb_packing_error"),
6904
+ pcb_group_id: external_exports.string().optional(),
6905
+ subcircuit_id: external_exports.string().optional()
6906
+ }).describe("Defines a failure to pack PCB components within layout bounds");
6907
+ expectTypesMatch(true);
6619
6908
  var pcb_panelization_placement_error = base_circuit_json_error.extend({
6620
6909
  type: external_exports.literal("pcb_panelization_placement_error"),
6621
6910
  pcb_panelization_placement_error_id: getZodPrefixedIdWithDefault(
@@ -7002,8 +7291,9 @@ var pcb_keepout = external_exports.object({
7002
7291
  pcb_keepout_id: external_exports.string(),
7003
7292
  layers: external_exports.array(external_exports.string()),
7004
7293
  // Specify layers where the keepout applies
7005
- description: external_exports.string().optional()
7294
+ description: external_exports.string().optional(),
7006
7295
  // Optional description of the keepout
7296
+ excluded_pcb_component_ids: external_exports.array(external_exports.string()).optional()
7007
7297
  }).or(
7008
7298
  external_exports.object({
7009
7299
  type: external_exports.literal("pcb_keepout"),
@@ -7015,8 +7305,9 @@ var pcb_keepout = external_exports.object({
7015
7305
  pcb_keepout_id: external_exports.string(),
7016
7306
  layers: external_exports.array(external_exports.string()),
7017
7307
  // Specify layers where the keepout applies
7018
- description: external_exports.string().optional()
7308
+ description: external_exports.string().optional(),
7019
7309
  // Optional description of the keepout
7310
+ excluded_pcb_component_ids: external_exports.array(external_exports.string()).optional()
7020
7311
  })
7021
7312
  );
7022
7313
  expectTypesMatch(true);
@@ -7175,6 +7466,18 @@ var pcb_connector_not_in_accessible_orientation_warning = external_exports.objec
7175
7466
  "Warning emitted when a connector PCB component is facing inward toward the board and should be reoriented to an outward-facing direction"
7176
7467
  );
7177
7468
  expectTypesMatch(true);
7469
+ var pcb_component_missing_courtyard_warning = external_exports.object({
7470
+ type: external_exports.literal("pcb_component_missing_courtyard_warning"),
7471
+ pcb_component_missing_courtyard_warning_id: getZodPrefixedIdWithDefault(
7472
+ "pcb_component_missing_courtyard_warning"
7473
+ ),
7474
+ warning_type: external_exports.literal("pcb_component_missing_courtyard_warning").default("pcb_component_missing_courtyard_warning"),
7475
+ message: external_exports.string(),
7476
+ pcb_component_id: external_exports.string(),
7477
+ source_component_id: external_exports.string().optional(),
7478
+ subcircuit_id: external_exports.string().optional()
7479
+ }).describe("Warning emitted when a PCB component has no courtyard geometry");
7480
+ expectTypesMatch(true);
7178
7481
  var supplier_footprint_mismatch_warning = external_exports.object({
7179
7482
  type: external_exports.literal("supplier_footprint_mismatch_warning"),
7180
7483
  supplier_footprint_mismatch_warning_id: getZodPrefixedIdWithDefault(
@@ -7202,6 +7505,7 @@ var pcb_breakout_point = external_exports.object({
7202
7505
  source_trace_id: external_exports.string().optional(),
7203
7506
  source_port_id: external_exports.string().optional(),
7204
7507
  source_net_id: external_exports.string().optional(),
7508
+ layer: layer_ref.optional(),
7205
7509
  x: distance,
7206
7510
  y: distance
7207
7511
  }).describe(
@@ -7526,6 +7830,7 @@ var cad_component = external_exports.object({
7526
7830
  model_jscad: external_exports.any().optional(),
7527
7831
  show_as_translucent_model: external_exports.boolean().optional(),
7528
7832
  show_as_bounding_box: external_exports.boolean().optional(),
7833
+ show_hidden_edges: external_exports.boolean().optional(),
7529
7834
  anchor_alignment: external_exports.enum(["center", "center_of_component_on_board_surface"]).optional().default("center")
7530
7835
  }).describe("Defines a component on the PCB");
7531
7836
  expectTypesMatch(true);
@@ -7551,7 +7856,9 @@ var simulation_dc_voltage_source = external_exports.object({
7551
7856
  negative_source_port_id: external_exports.string().optional(),
7552
7857
  positive_source_net_id: external_exports.string().optional(),
7553
7858
  negative_source_net_id: external_exports.string().optional(),
7554
- voltage
7859
+ voltage,
7860
+ ac_magnitude: voltage.optional(),
7861
+ ac_phase: rotation.optional()
7555
7862
  }).describe("Defines a DC voltage source for simulation");
7556
7863
  var simulation_ac_voltage_source = external_exports.object({
7557
7864
  type: external_exports.literal("simulation_voltage_source"),
@@ -7573,7 +7880,9 @@ var simulation_ac_voltage_source = external_exports.object({
7573
7880
  rise_time: ms.optional(),
7574
7881
  fall_time: ms.optional(),
7575
7882
  pulse_width: ms.optional(),
7576
- period: ms.optional()
7883
+ period: ms.optional(),
7884
+ ac_magnitude: voltage.optional(),
7885
+ ac_phase: rotation.optional()
7577
7886
  }).describe("Defines an AC voltage source for simulation");
7578
7887
  var simulation_voltage_source = external_exports.union([simulation_dc_voltage_source, simulation_ac_voltage_source]).describe("Defines a voltage source for simulation");
7579
7888
  expectTypesMatch(true);
@@ -7600,7 +7909,9 @@ var simulation_dc_current_source = external_exports.object({
7600
7909
  negative_source_port_id: external_exports.string().optional(),
7601
7910
  positive_source_net_id: external_exports.string().optional(),
7602
7911
  negative_source_net_id: external_exports.string().optional(),
7603
- current
7912
+ current,
7913
+ ac_magnitude: current.optional(),
7914
+ ac_phase: rotation.optional()
7604
7915
  }).describe("Defines a DC current source for simulation");
7605
7916
  var simulation_ac_current_source = external_exports.object({
7606
7917
  type: external_exports.literal("simulation_current_source"),
@@ -7617,12 +7928,20 @@ var simulation_ac_current_source = external_exports.object({
7617
7928
  peak_to_peak_current: current.optional(),
7618
7929
  wave_shape: wave_shape.optional(),
7619
7930
  phase: rotation.optional(),
7620
- duty_cycle: percentage2.optional()
7931
+ duty_cycle: percentage2.optional(),
7932
+ ac_magnitude: current.optional(),
7933
+ ac_phase: rotation.optional()
7621
7934
  }).describe("Defines an AC current source for simulation");
7622
7935
  var simulation_current_source = external_exports.union([simulation_dc_current_source, simulation_ac_current_source]).describe("Defines a current source for simulation");
7623
7936
  expectTypesMatch(true);
7624
7937
  expectTypesMatch(true);
7625
7938
  expectTypesMatch(true);
7939
+ var simulation_dc_sweep_unit = external_exports.custom(
7940
+ (dcSweepUnit) => dcSweepUnit === "V" || dcSweepUnit === "A"
7941
+ );
7942
+ var simulation_parameter_unit = external_exports.custom(
7943
+ (parameterUnit) => parameterUnit === "\u03A9" || parameterUnit === "F" || parameterUnit === "H" || parameterUnit === "V" || parameterUnit === "A"
7944
+ );
7626
7945
  var experiment_type = external_exports.union([
7627
7946
  external_exports.literal("spice_dc_sweep"),
7628
7947
  external_exports.literal("spice_dc_operating_point"),
@@ -7645,15 +7964,98 @@ var simulation_experiment = external_exports.object({
7645
7964
  time_per_step: duration_ms.optional(),
7646
7965
  start_time_ms: ms.optional(),
7647
7966
  end_time_ms: ms.optional(),
7648
- spice_options: spice_simulation_options.optional()
7967
+ spice_options: spice_simulation_options.optional(),
7968
+ dc_sweep_voltage_source_id: external_exports.string().optional(),
7969
+ dc_sweep_current_source_id: external_exports.string().optional(),
7970
+ dc_sweep_start: external_exports.number().optional(),
7971
+ dc_sweep_stop: external_exports.number().optional(),
7972
+ dc_sweep_step: external_exports.number().refine((dcSweepStep) => dcSweepStep !== 0).optional(),
7973
+ dc_sweep_unit: simulation_dc_sweep_unit.optional(),
7974
+ ac_sweep_type: external_exports.enum(["linear", "decade", "octave"]).optional(),
7975
+ ac_samples_per_interval: external_exports.number().int().positive().optional(),
7976
+ ac_sample_count: external_exports.number().int().positive().optional(),
7977
+ ac_start_frequency_hz: external_exports.number().positive().optional(),
7978
+ ac_stop_frequency_hz: external_exports.number().positive().optional()
7979
+ }).superRefine((experiment, context) => {
7980
+ if (experiment.experiment_type === "spice_dc_sweep") {
7981
+ const requiredFields = [
7982
+ "dc_sweep_start",
7983
+ "dc_sweep_stop",
7984
+ "dc_sweep_step",
7985
+ "dc_sweep_unit"
7986
+ ];
7987
+ for (const field of requiredFields) {
7988
+ if (experiment[field] === void 0) {
7989
+ context.addIssue({
7990
+ code: external_exports.ZodIssueCode.custom,
7991
+ path: [field],
7992
+ message: `${field} is required for a DC sweep`
7993
+ });
7994
+ }
7995
+ }
7996
+ const hasVoltageSource = experiment.dc_sweep_voltage_source_id !== void 0;
7997
+ const hasCurrentSource = experiment.dc_sweep_current_source_id !== void 0;
7998
+ if (hasVoltageSource === hasCurrentSource) {
7999
+ context.addIssue({
8000
+ code: external_exports.ZodIssueCode.custom,
8001
+ path: ["dc_sweep_voltage_source_id"],
8002
+ message: "Exactly one DC sweep voltage or current source ID is required"
8003
+ });
8004
+ }
8005
+ }
8006
+ if (experiment.experiment_type === "spice_ac_analysis") {
8007
+ if (experiment.ac_sweep_type === void 0) {
8008
+ context.addIssue({
8009
+ code: external_exports.ZodIssueCode.custom,
8010
+ path: ["ac_sweep_type"],
8011
+ message: "ac_sweep_type is required for an AC analysis"
8012
+ });
8013
+ }
8014
+ if (experiment.ac_start_frequency_hz === void 0) {
8015
+ context.addIssue({
8016
+ code: external_exports.ZodIssueCode.custom,
8017
+ path: ["ac_start_frequency_hz"],
8018
+ message: "ac_start_frequency_hz is required for an AC analysis"
8019
+ });
8020
+ }
8021
+ if (experiment.ac_stop_frequency_hz === void 0) {
8022
+ context.addIssue({
8023
+ code: external_exports.ZodIssueCode.custom,
8024
+ path: ["ac_stop_frequency_hz"],
8025
+ message: "ac_stop_frequency_hz is required for an AC analysis"
8026
+ });
8027
+ }
8028
+ if (experiment.ac_sweep_type === "linear" && experiment.ac_sample_count === void 0) {
8029
+ context.addIssue({
8030
+ code: external_exports.ZodIssueCode.custom,
8031
+ path: ["ac_sample_count"],
8032
+ message: "ac_sample_count is required for a linear AC analysis"
8033
+ });
8034
+ }
8035
+ if ((experiment.ac_sweep_type === "decade" || experiment.ac_sweep_type === "octave") && experiment.ac_samples_per_interval === void 0) {
8036
+ context.addIssue({
8037
+ code: external_exports.ZodIssueCode.custom,
8038
+ path: ["ac_samples_per_interval"],
8039
+ message: "ac_samples_per_interval is required for decade and octave AC analyses"
8040
+ });
8041
+ }
8042
+ }
7649
8043
  }).describe("Defines a simulation experiment configuration");
7650
8044
  expectTypesMatch(true);
8045
+ var simulation_parameter_sweep_coordinate = external_exports.object({
8046
+ simulation_parameter_sweep_id: external_exports.string(),
8047
+ sweep_index: external_exports.number().int().nonnegative(),
8048
+ parameter_value: external_exports.number(),
8049
+ parameter_unit: simulation_parameter_unit
8050
+ });
8051
+ expectTypesMatch(true);
7651
8052
  var simulation_transient_voltage_graph = external_exports.object({
7652
8053
  type: external_exports.literal("simulation_transient_voltage_graph"),
7653
8054
  simulation_transient_voltage_graph_id: getZodPrefixedIdWithDefault(
7654
8055
  "simulation_transient_voltage_graph"
7655
8056
  ),
7656
8057
  simulation_experiment_id: external_exports.string(),
8058
+ simulation_parameter_sweep_coordinate: simulation_parameter_sweep_coordinate.optional(),
7657
8059
  timestamps_ms: external_exports.array(external_exports.number()).optional(),
7658
8060
  voltage_levels: external_exports.array(external_exports.number()),
7659
8061
  source_component_id: external_exports.string().optional(),
@@ -7671,6 +8073,7 @@ var simulation_transient_current_graph = external_exports.object({
7671
8073
  "simulation_transient_current_graph"
7672
8074
  ),
7673
8075
  simulation_experiment_id: external_exports.string(),
8076
+ simulation_parameter_sweep_coordinate: simulation_parameter_sweep_coordinate.optional(),
7674
8077
  timestamps_ms: external_exports.array(external_exports.number()).optional(),
7675
8078
  current_levels: external_exports.array(external_exports.number()),
7676
8079
  source_component_id: external_exports.string().optional(),
@@ -7805,6 +8208,157 @@ var simulation_unknown_experiment_error = base_circuit_json_error.extend({
7805
8208
  subcircuit_id: external_exports.string().optional()
7806
8209
  }).describe("An unknown error occurred during the simulation experiment.");
7807
8210
  expectTypesMatch(true);
8211
+ var simulation_parameter_type = external_exports.enum([
8212
+ "resistance",
8213
+ "capacitance",
8214
+ "inductance",
8215
+ "voltage",
8216
+ "current"
8217
+ ]);
8218
+ var simulation_parameter_sweep_base = external_exports.object({
8219
+ type: external_exports.literal("simulation_parameter_sweep"),
8220
+ simulation_parameter_sweep_id: getZodPrefixedIdWithDefault(
8221
+ "simulation_parameter_sweep"
8222
+ ),
8223
+ simulation_experiment_id: external_exports.string(),
8224
+ name: external_exports.string().optional(),
8225
+ parameter_values: external_exports.array(external_exports.number()).min(1),
8226
+ parameter_unit: simulation_parameter_unit
8227
+ });
8228
+ var simulation_parameter_sweep = external_exports.discriminatedUnion("parameter_type", [
8229
+ simulation_parameter_sweep_base.extend({
8230
+ parameter_type: external_exports.literal("resistance"),
8231
+ resistor_source_component_id: external_exports.string()
8232
+ }),
8233
+ simulation_parameter_sweep_base.extend({
8234
+ parameter_type: external_exports.literal("capacitance"),
8235
+ capacitor_source_component_id: external_exports.string()
8236
+ }),
8237
+ simulation_parameter_sweep_base.extend({
8238
+ parameter_type: external_exports.literal("inductance"),
8239
+ inductor_source_component_id: external_exports.string()
8240
+ }),
8241
+ simulation_parameter_sweep_base.extend({
8242
+ parameter_type: external_exports.literal("voltage"),
8243
+ source_net_id: external_exports.string()
8244
+ }),
8245
+ simulation_parameter_sweep_base.extend({
8246
+ parameter_type: external_exports.literal("current"),
8247
+ current_source_component_id: external_exports.string()
8248
+ })
8249
+ ]).describe("Repeats a simulation experiment over component parameter values");
8250
+ expectTypesMatch(
8251
+ true
8252
+ );
8253
+ var simulation_dc_operating_point_voltage = external_exports.object({
8254
+ type: external_exports.literal("simulation_dc_operating_point_voltage"),
8255
+ simulation_dc_operating_point_voltage_id: getZodPrefixedIdWithDefault(
8256
+ "simulation_dc_operating_point_voltage"
8257
+ ),
8258
+ simulation_experiment_id: external_exports.string(),
8259
+ simulation_parameter_sweep_coordinate: simulation_parameter_sweep_coordinate.optional(),
8260
+ simulation_voltage_probe_id: external_exports.string(),
8261
+ voltage: external_exports.number(),
8262
+ name: external_exports.string().optional(),
8263
+ color: external_exports.string().optional()
8264
+ });
8265
+ expectTypesMatch(true);
8266
+ var simulation_dc_operating_point_current = external_exports.object({
8267
+ type: external_exports.literal("simulation_dc_operating_point_current"),
8268
+ simulation_dc_operating_point_current_id: getZodPrefixedIdWithDefault(
8269
+ "simulation_dc_operating_point_current"
8270
+ ),
8271
+ simulation_experiment_id: external_exports.string(),
8272
+ simulation_parameter_sweep_coordinate: simulation_parameter_sweep_coordinate.optional(),
8273
+ simulation_current_probe_id: external_exports.string(),
8274
+ current: external_exports.number(),
8275
+ name: external_exports.string().optional(),
8276
+ color: external_exports.string().optional()
8277
+ });
8278
+ expectTypesMatch(true);
8279
+ var simulation_dc_sweep_voltage_graph = external_exports.object({
8280
+ type: external_exports.literal("simulation_dc_sweep_voltage_graph"),
8281
+ simulation_dc_sweep_voltage_graph_id: getZodPrefixedIdWithDefault(
8282
+ "simulation_dc_sweep_voltage_graph"
8283
+ ),
8284
+ simulation_experiment_id: external_exports.string(),
8285
+ simulation_parameter_sweep_coordinate: simulation_parameter_sweep_coordinate.optional(),
8286
+ simulation_voltage_probe_id: external_exports.string(),
8287
+ sweep_values: external_exports.array(external_exports.number()),
8288
+ sweep_unit: simulation_dc_sweep_unit,
8289
+ voltage_levels: external_exports.array(external_exports.number()),
8290
+ name: external_exports.string().optional(),
8291
+ color: external_exports.string().optional()
8292
+ }).refine(
8293
+ (graph) => graph.sweep_values.length === graph.voltage_levels.length,
8294
+ {
8295
+ message: "sweep_values and voltage_levels must have the same length"
8296
+ }
8297
+ );
8298
+ expectTypesMatch(true);
8299
+ var simulation_dc_sweep_current_graph = external_exports.object({
8300
+ type: external_exports.literal("simulation_dc_sweep_current_graph"),
8301
+ simulation_dc_sweep_current_graph_id: getZodPrefixedIdWithDefault(
8302
+ "simulation_dc_sweep_current_graph"
8303
+ ),
8304
+ simulation_experiment_id: external_exports.string(),
8305
+ simulation_parameter_sweep_coordinate: simulation_parameter_sweep_coordinate.optional(),
8306
+ simulation_current_probe_id: external_exports.string(),
8307
+ sweep_values: external_exports.array(external_exports.number()),
8308
+ sweep_unit: simulation_dc_sweep_unit,
8309
+ current_levels: external_exports.array(external_exports.number()),
8310
+ name: external_exports.string().optional(),
8311
+ color: external_exports.string().optional()
8312
+ }).refine(
8313
+ (graph) => graph.sweep_values.length === graph.current_levels.length,
8314
+ {
8315
+ message: "sweep_values and current_levels must have the same length"
8316
+ }
8317
+ );
8318
+ expectTypesMatch(true);
8319
+ var simulation_complex_sample = external_exports.object({
8320
+ re: external_exports.number(),
8321
+ im: external_exports.number()
8322
+ });
8323
+ expectTypesMatch(true);
8324
+ var simulation_ac_sweep_voltage_graph = external_exports.object({
8325
+ type: external_exports.literal("simulation_ac_sweep_voltage_graph"),
8326
+ simulation_ac_sweep_voltage_graph_id: getZodPrefixedIdWithDefault(
8327
+ "simulation_ac_sweep_voltage_graph"
8328
+ ),
8329
+ simulation_experiment_id: external_exports.string(),
8330
+ simulation_parameter_sweep_coordinate: simulation_parameter_sweep_coordinate.optional(),
8331
+ simulation_voltage_probe_id: external_exports.string(),
8332
+ frequencies_hz: external_exports.array(external_exports.number()),
8333
+ complex_voltages: external_exports.array(simulation_complex_sample),
8334
+ name: external_exports.string().optional(),
8335
+ color: external_exports.string().optional()
8336
+ }).refine(
8337
+ (graph) => graph.frequencies_hz.length === graph.complex_voltages.length,
8338
+ {
8339
+ message: "frequencies_hz and complex_voltages must have the same length"
8340
+ }
8341
+ );
8342
+ expectTypesMatch(true);
8343
+ var simulation_ac_sweep_current_graph = external_exports.object({
8344
+ type: external_exports.literal("simulation_ac_sweep_current_graph"),
8345
+ simulation_ac_sweep_current_graph_id: getZodPrefixedIdWithDefault(
8346
+ "simulation_ac_sweep_current_graph"
8347
+ ),
8348
+ simulation_experiment_id: external_exports.string(),
8349
+ simulation_parameter_sweep_coordinate: simulation_parameter_sweep_coordinate.optional(),
8350
+ simulation_current_probe_id: external_exports.string(),
8351
+ frequencies_hz: external_exports.array(external_exports.number()),
8352
+ complex_currents: external_exports.array(simulation_complex_sample),
8353
+ name: external_exports.string().optional(),
8354
+ color: external_exports.string().optional()
8355
+ }).refine(
8356
+ (graph) => graph.frequencies_hz.length === graph.complex_currents.length,
8357
+ {
8358
+ message: "frequencies_hz and complex_currents must have the same length"
8359
+ }
8360
+ );
8361
+ expectTypesMatch(true);
7808
8362
  var simulation_op_amp = external_exports.object({
7809
8363
  type: external_exports.literal("simulation_op_amp"),
7810
8364
  simulation_op_amp_id: getZodPrefixedIdWithDefault("simulation_op_amp"),
@@ -7920,12 +8474,14 @@ var any_circuit_element = external_exports.union([
7920
8474
  source_component_misconfigured_error,
7921
8475
  source_ambiguous_port_reference,
7922
8476
  pcb_component,
8477
+ pcb_debug_object,
7923
8478
  pcb_hole,
7924
8479
  pcb_missing_footprint_error,
7925
8480
  external_footprint_load_error,
7926
8481
  circuit_json_footprint_load_error,
7927
8482
  pcb_manual_edit_conflict_warning,
7928
8483
  pcb_connector_not_in_accessible_orientation_warning,
8484
+ pcb_component_missing_courtyard_warning,
7929
8485
  supplier_footprint_mismatch_warning,
7930
8486
  pcb_plated_hole,
7931
8487
  pcb_keepout,
@@ -7934,6 +8490,8 @@ var any_circuit_element = external_exports.union([
7934
8490
  pcb_text,
7935
8491
  pcb_trace,
7936
8492
  pcb_trace_warning,
8493
+ pcb_trace_too_long_warning,
8494
+ pcb_trace_too_many_vias_warning,
7937
8495
  pcb_via,
7938
8496
  pcb_smtpad,
7939
8497
  pcb_solder_paste,
@@ -7953,6 +8511,7 @@ var any_circuit_element = external_exports.union([
7953
8511
  pcb_trace_error,
7954
8512
  pcb_trace_missing_error,
7955
8513
  pcb_placement_error,
8514
+ pcb_packing_error,
7956
8515
  pcb_panelization_placement_error,
7957
8516
  pcb_port_not_matched_error,
7958
8517
  pcb_port_not_connected_error,
@@ -8003,6 +8562,9 @@ var any_circuit_element = external_exports.union([
8003
8562
  schematic_debug_object,
8004
8563
  schematic_voltage_probe,
8005
8564
  schematic_manual_edit_conflict_warning,
8565
+ schematic_component_overlap_warning,
8566
+ schematic_component_styling_warning,
8567
+ schematic_element_outside_sheet_warning,
8006
8568
  schematic_group,
8007
8569
  schematic_sheet,
8008
8570
  schematic_table,
@@ -8013,6 +8575,13 @@ var any_circuit_element = external_exports.union([
8013
8575
  simulation_experiment,
8014
8576
  simulation_transient_voltage_graph,
8015
8577
  simulation_transient_current_graph,
8578
+ simulation_dc_operating_point_voltage,
8579
+ simulation_dc_operating_point_current,
8580
+ simulation_dc_sweep_voltage_graph,
8581
+ simulation_dc_sweep_current_graph,
8582
+ simulation_ac_sweep_voltage_graph,
8583
+ simulation_ac_sweep_current_graph,
8584
+ simulation_parameter_sweep,
8016
8585
  simulation_switch,
8017
8586
  simulation_voltage_probe,
8018
8587
  simulation_current_probe,
@@ -9075,9 +9644,9 @@ var insertionDirectionToVec = (direction) => {
9075
9644
  return { x: -1, y: 0 };
9076
9645
  case "from_right":
9077
9646
  return { x: 1, y: 0 };
9078
- case "from_front":
9647
+ case "from_top":
9079
9648
  return { x: 0, y: 1 };
9080
- case "from_back":
9649
+ case "from_bottom":
9081
9650
  return { x: 0, y: -1 };
9082
9651
  }
9083
9652
  };
@@ -9087,11 +9656,15 @@ var vecToInsertionDirection = ({
9087
9656
  }) => {
9088
9657
  if (x > 0) return "from_right";
9089
9658
  if (x < 0) return "from_left";
9090
- if (y > 0) return "from_front";
9091
- return "from_back";
9659
+ if (y > 0) return "from_top";
9660
+ return "from_bottom";
9092
9661
  };
9093
9662
  var transformInsertionDirection = (direction, opts) => {
9094
- if (!direction || direction === "from_above") return direction;
9663
+ if (!direction) return direction;
9664
+ if (direction === "from_above" || direction === "from_below") {
9665
+ if (!opts.isFlipped) return direction;
9666
+ return direction === "from_above" ? "from_below" : "from_above";
9667
+ }
9095
9668
  let { x, y } = insertionDirectionToVec(direction);
9096
9669
  let quarterTurns = Math.round(opts.rotationDegrees / 90);
9097
9670
  while (quarterTurns > 0) {
@@ -9114,7 +9687,7 @@ var transformPCBElement = (elm, matrix) => {
9114
9687
  const flipPadWidthHeight = Math.abs(getQuarterTurns(tsr.rotation.angle)) % 2 === 1;
9115
9688
  const rotationDegrees = tsr.rotation.angle / Math.PI * 180;
9116
9689
  const isFlipped = tsr.scale.sy < 0;
9117
- if (elm.type === "pcb_plated_hole" || elm.type === "pcb_hole" || elm.type === "pcb_via" || elm.type === "pcb_smtpad" || elm.type === "pcb_port") {
9690
+ if (elm.type === "pcb_plated_hole" || elm.type === "pcb_hole" || elm.type === "pcb_via" || elm.type === "pcb_smtpad" || elm.type === "pcb_solder_paste" || elm.type === "pcb_port") {
9118
9691
  const { x, y } = applyToPoint(matrix, {
9119
9692
  x: Number(elm.x),
9120
9693
  y: Number(elm.y)
@@ -9134,10 +9707,14 @@ var transformPCBElement = (elm, matrix) => {
9134
9707
  elm.center = applyToPoint(matrix, elm.center);
9135
9708
  } else if (elm.type === "pcb_silkscreen_text" || elm.type === "pcb_fabrication_note_text" || elm.type === "pcb_note_text") {
9136
9709
  elm.anchor_position = applyToPoint(matrix, elm.anchor_position);
9710
+ } else if (elm.type === "pcb_copper_text") {
9711
+ if (elm.anchor_position) {
9712
+ elm.anchor_position = applyToPoint(matrix, elm.anchor_position);
9713
+ }
9137
9714
  } else if (elm.type === "pcb_courtyard_rect") {
9138
9715
  elm.center = applyToPoint(matrix, elm.center);
9139
9716
  elm.ccw_rotation = ((elm.ccw_rotation ?? 0) + rotationDegrees) % 360;
9140
- } else if (elm.type === "pcb_silkscreen_circle" || elm.type === "pcb_silkscreen_rect" || elm.type === "pcb_note_rect" || elm.type === "pcb_courtyard_circle") {
9717
+ } else if (elm.type === "pcb_silkscreen_circle" || elm.type === "pcb_silkscreen_rect" || elm.type === "pcb_silkscreen_pill" || elm.type === "pcb_silkscreen_oval" || elm.type === "pcb_note_rect" || elm.type === "pcb_courtyard_circle") {
9141
9718
  elm.center = applyToPoint(matrix, elm.center);
9142
9719
  } else if (elm.type === "pcb_component") {
9143
9720
  elm.center = applyToPoint(matrix, elm.center);
@@ -9174,7 +9751,19 @@ var transformPCBElement = (elm, matrix) => {
9174
9751
  p.y = tp.y;
9175
9752
  return p;
9176
9753
  });
9177
- } else if (elm.type === "pcb_silkscreen_path" || elm.type === "pcb_trace" || elm.type === "pcb_fabrication_note_path" || elm.type === "pcb_note_path") {
9754
+ } else if (elm.type === "pcb_trace") {
9755
+ elm.route = elm.route.map((rp) => {
9756
+ if (!("x" in rp)) {
9757
+ rp.start = applyToPoint(matrix, rp.start);
9758
+ rp.end = applyToPoint(matrix, rp.end);
9759
+ return rp;
9760
+ }
9761
+ const tp = applyToPoint(matrix, rp);
9762
+ rp.x = tp.x;
9763
+ rp.y = tp.y;
9764
+ return rp;
9765
+ });
9766
+ } else if (elm.type === "pcb_silkscreen_path" || elm.type === "pcb_trace_hint" || elm.type === "pcb_fabrication_note_path" || elm.type === "pcb_note_path") {
9178
9767
  elm.route = elm.route.map((rp) => {
9179
9768
  const tp = applyToPoint(matrix, rp);
9180
9769
  rp.x = tp.x;
@@ -9207,7 +9796,7 @@ var transformPCBElements = (elms, matrix) => {
9207
9796
  let transformedElms = elms.map((elm) => transformPCBElement(elm, matrix));
9208
9797
  if (flipPadWidthHeight) {
9209
9798
  transformedElms = transformedElms.map((elm) => {
9210
- if (elm.type === "pcb_smtpad" && elm.shape === "rect") {
9799
+ if ((elm.type === "pcb_smtpad" || elm.type === "pcb_solder_paste") && (elm.shape === "rect" || elm.shape === "pill")) {
9211
9800
  ;
9212
9801
  [elm.width, elm.height] = [elm.height, elm.width];
9213
9802
  }
@@ -9362,7 +9951,10 @@ var getDebugLayoutObject = (lo) => {
9362
9951
  const content = lo;
9363
9952
  if (x === void 0 || y === void 0) return null;
9364
9953
  if (width === void 0) {
9365
- if ("outer_diameter" in lo) {
9954
+ if ("radius" in lo) {
9955
+ width = lo.radius * 2;
9956
+ height = lo.radius * 2;
9957
+ } else if ("outer_diameter" in lo) {
9366
9958
  width = lo.outer_diameter;
9367
9959
  height = lo.outer_diameter;
9368
9960
  } else if ("rect_pad_width" in lo && "rect_pad_height" in lo) {
@@ -9417,6 +10009,17 @@ var findBoundsAndCenter = (elements) => {
9417
10009
  const center = { x: minX + width / 2, y: minY + height / 2 };
9418
10010
  return { center, width, height };
9419
10011
  };
10012
+ var PIN1_LOCATION_PARTS = {
10013
+ leftside_top: { side: "leftside", alignment: "top" },
10014
+ leftside_bottom: { side: "leftside", alignment: "bottom" },
10015
+ rightside_top: { side: "rightside", alignment: "top" },
10016
+ rightside_bottom: { side: "rightside", alignment: "bottom" },
10017
+ topside_left: { side: "topside", alignment: "left" },
10018
+ topside_right: { side: "topside", alignment: "right" },
10019
+ bottomside_left: { side: "bottomside", alignment: "left" },
10020
+ bottomside_right: { side: "bottomside", alignment: "right" }
10021
+ };
10022
+ var PIN1_LOCATIONS = Object.keys(PIN1_LOCATION_PARTS);
9420
10023
  var unitToMm = {
9421
10024
  in: 25.4,
9422
10025
  inch: 25.4,
@@ -9463,8 +10066,9 @@ function generateArcFromSweep(startX, startY, endX, endY, radius, largeArcFlag,
9463
10066
  }
9464
10067
  const h = Math.sqrt(radius * radius - distance3 * distance3 / 4);
9465
10068
  const angle = Math.atan2(dy, dx);
9466
- const centerX = midX + h * Math.sin(angle) * (sweepFlag ? -1 : 1);
9467
- const centerY = midY - h * Math.cos(angle) * (sweepFlag ? -1 : 1);
10069
+ const centerDirection = (sweepFlag ? -1 : 1) * (largeArcFlag ? -1 : 1);
10070
+ const centerX = midX + h * Math.sin(angle) * centerDirection;
10071
+ const centerY = midY - h * Math.cos(angle) * centerDirection;
9468
10072
  const startAngle = Math.atan2(startY - centerY, startX - centerX);
9469
10073
  let endAngle = Math.atan2(endY - centerY, endX - centerX);
9470
10074
  if (sweepFlag && endAngle > startAngle) {
@@ -9494,6 +10098,69 @@ function generateArcFromSweep(startX, startY, endX, endY, radius, largeArcFlag,
9494
10098
  return path;
9495
10099
  }
9496
10100
  var mil10ToMm = (value) => value * 10 * 0.0254;
10101
+ var classifySemicircle = (arc, silkscreenTracks) => {
10102
+ const chord = {
10103
+ x: arc.end.x - arc.start.x,
10104
+ y: arc.end.y - arc.start.y
10105
+ };
10106
+ const chordLength = Math.hypot(chord.x, chord.y);
10107
+ const isSemicircle = !arc.largeArc && Math.abs(chordLength - 2 * arc.radiusX) <= Math.max(1e-6, arc.radiusX * 1e-4);
10108
+ if (!isSemicircle) return null;
10109
+ const endpointTolerance = Math.max(0.05, arc.radiusX * 0.02);
10110
+ const isNearEndpoint = (point2) => Math.hypot(point2.x - arc.start.x, point2.y - arc.start.y) <= endpointTolerance || Math.hypot(point2.x - arc.end.x, point2.y - arc.end.y) <= endpointTolerance;
10111
+ let hasConnectedSegment = false;
10112
+ for (const track of silkscreenTracks) {
10113
+ if (track.layer !== arc.layer) continue;
10114
+ for (const [pointIndex, point2] of track.points.entries()) {
10115
+ if (!isNearEndpoint(point2)) continue;
10116
+ const neighbors = [
10117
+ track.points[pointIndex - 1],
10118
+ track.points[pointIndex + 1]
10119
+ ];
10120
+ for (const neighbor of neighbors) {
10121
+ if (!neighbor) continue;
10122
+ hasConnectedSegment = true;
10123
+ const segment = {
10124
+ x: neighbor.x - point2.x,
10125
+ y: neighbor.y - point2.y
10126
+ };
10127
+ const segmentLength = Math.hypot(segment.x, segment.y);
10128
+ if (segmentLength === 0) continue;
10129
+ const normalizedDot = Math.abs(segment.x * chord.x + segment.y * chord.y) / (segmentLength * chordLength);
10130
+ if (normalizedDot < 0.25) return "end_cap";
10131
+ }
10132
+ }
10133
+ }
10134
+ return hasConnectedSegment ? "notch" : null;
10135
+ };
10136
+ var distanceFromRouteMidpoint = (route, point2) => {
10137
+ const midpoint2 = route[Math.floor(route.length / 2)];
10138
+ return Math.hypot(midpoint2.x - point2.x, midpoint2.y - point2.y);
10139
+ };
10140
+ var getSilkscreenArcPath = (arc, footprintCenter, silkscreenTracks) => {
10141
+ const generateArcPath = (sweepFlag2) => generateArcFromSweep(
10142
+ arc.start.x,
10143
+ arc.start.y,
10144
+ arc.end.x,
10145
+ arc.end.y,
10146
+ arc.radiusX,
10147
+ arc.largeArc,
10148
+ sweepFlag2
10149
+ );
10150
+ const sweepFlag = arc.sweepDirection === "CW";
10151
+ const arcPath = generateArcPath(sweepFlag);
10152
+ const semicircleRole = classifySemicircle(arc, silkscreenTracks);
10153
+ if (!semicircleRole) return arcPath;
10154
+ const oppositeArcPath = generateArcPath(!sweepFlag);
10155
+ const arcDistance = distanceFromRouteMidpoint(arcPath, footprintCenter);
10156
+ const oppositeDistance = distanceFromRouteMidpoint(
10157
+ oppositeArcPath,
10158
+ footprintCenter
10159
+ );
10160
+ const originalArcIsInward = arcDistance <= oppositeDistance;
10161
+ const shouldBowInward = semicircleRole === "notch";
10162
+ return originalArcIsInward === shouldBowInward ? arcPath : oppositeArcPath;
10163
+ };
9497
10164
  var getPinLabelValues = (labels) => {
9498
10165
  if (typeof labels === "string") return [labels];
9499
10166
  return [...labels];
@@ -9528,8 +10195,19 @@ var getPolarizedPinMetadata = (pinLabels) => {
9528
10195
  pinLabels: Object.fromEntries(polarizedPinEntries)
9529
10196
  };
9530
10197
  };
10198
+ var normalizeActiveLowPinLabel = (label) => {
10199
+ const hasActiveLowMarker = label.startsWith("#") || label.endsWith("#");
10200
+ if (!hasActiveLowMarker) return label;
10201
+ const activeLowLabel = label.replace(/^#/, "").replace(/#$/, "");
10202
+ if (activeLowLabel.length === 0) return label;
10203
+ if (activeLowLabel.startsWith("N_")) return activeLowLabel;
10204
+ return `N_${activeLowLabel}`;
10205
+ };
9531
10206
  var normalizePinLabels = (inputPinLabels) => {
9532
- const uniqueInputPinLabels = inputPinLabels.map((labels) => [
10207
+ const normalizedInputPinLabels = inputPinLabels.map(
10208
+ (labels) => labels.map(normalizeActiveLowPinLabel)
10209
+ );
10210
+ const uniqueInputPinLabels = normalizedInputPinLabels.map((labels) => [
9533
10211
  ...new Set(labels)
9534
10212
  ]);
9535
10213
  const result = uniqueInputPinLabels.map(() => []);
@@ -9599,7 +10277,7 @@ var normalizeSymbolName = (name) => {
9599
10277
  const trimmedName = name.trim();
9600
10278
  if (trimmedName === "+") return "_POS";
9601
10279
  if (trimmedName === "-") return "_NEG";
9602
- return trimmedName;
10280
+ return trimmedName.replace(/(?<=[A-Za-z0-9])-(?=[A-Za-z0-9])/g, "_");
9603
10281
  };
9604
10282
  var categoryValueContainsDiode = (value) => {
9605
10283
  if (typeof value === "string") {
@@ -9626,6 +10304,7 @@ var isDiodeCategoryComponent = (betterEasy) => {
9626
10304
  };
9627
10305
  var categoryValueContainsLed = (value) => {
9628
10306
  if (typeof value === "string") {
10307
+ if (/(^|[^a-z])leds?\s+drivers?([^a-z]|$)/i.test(value)) return false;
9629
10308
  return /(^|[^a-z])leds?([^a-z]|$)/i.test(value) || /light[-\s]?emitting\s+diodes?/i.test(value);
9630
10309
  }
9631
10310
  if (Array.isArray(value)) {
@@ -9805,8 +10484,7 @@ var handleSilkscreenPath = (track, index) => {
9805
10484
  type: "pcb_silkscreen_path",
9806
10485
  pcb_silkscreen_path_id: `pcb_silkscreen_path_${index + 1}`,
9807
10486
  pcb_component_id: "pcb_component_1",
9808
- layer: "top",
9809
- // Assuming all silkscreen is on top layer
10487
+ layer: getSideFromLayer(track.layer),
9810
10488
  route: track.points.map((point2) => ({
9811
10489
  x: milx10(point2.x),
9812
10490
  y: milx10(point2.y)
@@ -9816,26 +10494,85 @@ var handleSilkscreenPath = (track, index) => {
9816
10494
  };
9817
10495
  var isCourtyardLayer = (layer) => layer === 13 || layer === 14 || layer === 15;
9818
10496
  var isSilkscreenLayer = (layer) => layer === 3 || layer === 4;
10497
+ var isDocumentLayer = (layer) => layer === 12;
10498
+ var handleFabricationNotePath = (track, index) => pcb_fabrication_note_path.parse({
10499
+ type: "pcb_fabrication_note_path",
10500
+ pcb_fabrication_note_path_id: `pcb_fabrication_note_path_${index + 1}`,
10501
+ pcb_component_id: "pcb_component_1",
10502
+ layer: "top",
10503
+ route: track.points.map((point2) => ({
10504
+ x: mil10ToMm(point2.x),
10505
+ y: mil10ToMm(point2.y)
10506
+ })),
10507
+ stroke_width: mil10ToMm(track.width)
10508
+ });
10509
+ var handleFabricationNoteSolidRegion = (solidRegion, index) => {
10510
+ const rawRoute = [];
10511
+ let currentPoint;
10512
+ for (const commandMatch of solidRegion.pathData.matchAll(
10513
+ /([MLAZ])([^MLAZ]*)/gi
10514
+ )) {
10515
+ const command = commandMatch[1]?.toUpperCase();
10516
+ const values = commandMatch[2]?.match(/[-+]?(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?/g)?.map(Number) ?? [];
10517
+ if ((command === "M" || command === "L") && values.length >= 2) {
10518
+ currentPoint = { x: values[0], y: values[1] };
10519
+ rawRoute.push(currentPoint);
10520
+ } else if (command === "A" && currentPoint && values.length >= 7) {
10521
+ const [radiusX, , , largeArcFlag, sweepFlag, endX, endY] = values;
10522
+ const generatedArcRoute = generateArcFromSweep(
10523
+ currentPoint.x,
10524
+ currentPoint.y,
10525
+ endX,
10526
+ endY,
10527
+ radiusX,
10528
+ largeArcFlag === 1,
10529
+ sweepFlag === 1
10530
+ );
10531
+ const maxArcSegments = 16;
10532
+ const arcRoute = generatedArcRoute.length <= maxArcSegments + 1 ? generatedArcRoute : Array.from(
10533
+ { length: maxArcSegments + 1 },
10534
+ (_, pointIndex) => generatedArcRoute.at(
10535
+ Math.round(
10536
+ pointIndex * (generatedArcRoute.length - 1) / maxArcSegments
10537
+ )
10538
+ )
10539
+ ).filter((point2) => !!point2);
10540
+ rawRoute.push(...arcRoute.slice(1));
10541
+ currentPoint = { x: endX, y: endY };
10542
+ }
10543
+ }
10544
+ const route = rawRoute.map((point2) => ({
10545
+ x: mil10ToMm(point2.x),
10546
+ y: mil10ToMm(point2.y)
10547
+ }));
10548
+ const firstPoint = route[0];
10549
+ const lastPoint = route.at(-1);
10550
+ if (firstPoint && lastPoint && (firstPoint.x !== lastPoint.x || firstPoint.y !== lastPoint.y)) {
10551
+ route.push({ ...firstPoint });
10552
+ }
10553
+ if (route.length < 2) return null;
10554
+ return pcb_fabrication_note_path.parse({
10555
+ type: "pcb_fabrication_note_path",
10556
+ pcb_fabrication_note_path_id: `pcb_fabrication_note_solid_region_${index + 1}`,
10557
+ pcb_component_id: "pcb_component_1",
10558
+ layer: "top",
10559
+ route,
10560
+ // EasyEDA solid regions have no stroke width. Use its standard 1-unit
10561
+ // document stroke so the closed region remains visible as a note path.
10562
+ stroke_width: mil10ToMm(1)
10563
+ });
10564
+ };
9819
10565
  var getSideFromLayer = (layer) => {
9820
10566
  if (layer === 4 || layer === 14) return "bottom";
9821
10567
  return "top";
9822
10568
  };
9823
- var handleSilkscreenArc = (arc, index) => {
9824
- const arcPath = generateArcFromSweep(
9825
- arc.start.x,
9826
- arc.start.y,
9827
- arc.end.x,
9828
- arc.end.y,
9829
- arc.radiusX,
9830
- arc.largeArc,
9831
- arc.sweepDirection === "CW"
9832
- );
10569
+ var handleSilkscreenArc = (arc, index, footprintCenter, silkscreenTracks) => {
10570
+ const arcPath = getSilkscreenArcPath(arc, footprintCenter, silkscreenTracks);
9833
10571
  return pcb_silkscreen_path.parse({
9834
10572
  type: "pcb_silkscreen_path",
9835
10573
  pcb_silkscreen_path_id: `pcb_silkscreen_arc_${index + 1}`,
9836
10574
  pcb_component_id: "pcb_component_1",
9837
- layer: "top",
9838
- // Assuming all silkscreen is on top layer
10575
+ layer: getSideFromLayer(arc.layer),
9839
10576
  route: arcPath.map((p) => ({
9840
10577
  x: milx10(p.x),
9841
10578
  y: milx10(p.y)
@@ -9843,27 +10580,54 @@ var handleSilkscreenArc = (arc, index) => {
9843
10580
  stroke_width: mil10ToMm(arc.width)
9844
10581
  });
9845
10582
  };
9846
- var SILKSCREEN_CIRCLE_SEGMENTS = 24;
9847
10583
  var handleSilkscreenCircle = (circle, index) => {
9848
- const route = Array.from(
9849
- { length: SILKSCREEN_CIRCLE_SEGMENTS + 1 },
9850
- (_, segmentIndex) => {
9851
- const angle = Math.PI * 2 * segmentIndex / SILKSCREEN_CIRCLE_SEGMENTS;
9852
- return {
9853
- x: milx10(circle.center.x + Math.cos(angle) * circle.radius),
9854
- y: milx10(circle.center.y + Math.sin(angle) * circle.radius)
9855
- };
9856
- }
9857
- );
9858
- return pcb_silkscreen_path.parse({
9859
- type: "pcb_silkscreen_path",
9860
- pcb_silkscreen_path_id: `pcb_silkscreen_circle_${index + 1}`,
10584
+ return pcb_silkscreen_circle.parse({
10585
+ type: "pcb_silkscreen_circle",
10586
+ pcb_silkscreen_circle_id: `pcb_silkscreen_circle_${index + 1}`,
9861
10587
  pcb_component_id: "pcb_component_1",
9862
10588
  layer: getSideFromLayer(circle.layer),
9863
- route,
10589
+ center: {
10590
+ x: milx10(circle.center.x),
10591
+ y: milx10(circle.center.y)
10592
+ },
10593
+ radius: milx10(circle.radius),
9864
10594
  stroke_width: mil10ToMm(circle.width)
9865
10595
  });
9866
10596
  };
10597
+ var handleRect = (rect, index) => {
10598
+ const width = milx10(rect.width);
10599
+ const height = milx10(rect.height);
10600
+ const center = {
10601
+ x: milx10(rect.x) + width / 2,
10602
+ y: milx10(rect.y) + height / 2
10603
+ };
10604
+ const layer = getSideFromLayer(rect.layer);
10605
+ if (isCourtyardLayer(rect.layer)) {
10606
+ return pcb_courtyard_rect.parse({
10607
+ type: "pcb_courtyard_rect",
10608
+ pcb_courtyard_rect_id: `pcb_courtyard_rect_${index + 1}`,
10609
+ pcb_component_id: "pcb_component_1",
10610
+ center,
10611
+ width,
10612
+ height,
10613
+ layer,
10614
+ ccw_rotation: rect.rotation
10615
+ });
10616
+ }
10617
+ return pcb_silkscreen_rect.parse({
10618
+ type: "pcb_silkscreen_rect",
10619
+ pcb_silkscreen_rect_id: `pcb_silkscreen_rect_${index + 1}`,
10620
+ pcb_component_id: "pcb_component_1",
10621
+ center,
10622
+ width,
10623
+ height,
10624
+ layer,
10625
+ stroke_width: mil10ToMm(rect.lineWidth),
10626
+ is_filled: rect.fillStyle !== "none",
10627
+ has_stroke: rect.lineWidth > 0,
10628
+ ccw_rotation: rect.rotation
10629
+ });
10630
+ };
9867
10631
  var handleHole = (hole, index) => {
9868
10632
  return pcb_hole.parse({
9869
10633
  type: "pcb_hole",
@@ -9965,14 +10729,32 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
9965
10729
  if (pin) labels.push(normalizeSymbolName(pin.label));
9966
10730
  return labels;
9967
10731
  });
9968
- const normalizedPinLabels = normalizePinLabels(pinLabelSets);
10732
+ const padNumberKeys = pads.map((pad, index) => {
10733
+ const padNumber = String(pad.number ?? "").trim();
10734
+ return padNumber ? `number:${padNumber}` : `index:${index}`;
10735
+ });
10736
+ const uniquePinLabelSets = [];
10737
+ const uniquePinIndexByKey = /* @__PURE__ */ new Map();
10738
+ const uniquePinIndexByPad = padNumberKeys.map((key, padIndex) => {
10739
+ const existingIndex = uniquePinIndexByKey.get(key);
10740
+ if (existingIndex !== void 0) return existingIndex;
10741
+ const uniquePinIndex = uniquePinLabelSets.length;
10742
+ uniquePinIndexByKey.set(key, uniquePinIndex);
10743
+ uniquePinLabelSets.push(pinLabelSets[padIndex]);
10744
+ return uniquePinIndex;
10745
+ });
10746
+ const normalizedUniquePinLabels = normalizePinLabels(uniquePinLabelSets);
10747
+ const normalizedPinLabels = uniquePinIndexByPad.map(
10748
+ (uniquePinIndex) => normalizedUniquePinLabels[uniquePinIndex]
10749
+ );
9969
10750
  const normalizedPinLabelsByPin = Object.fromEntries(
9970
- normalizedPinLabels.map((labels) => {
10751
+ normalizedUniquePinLabels.map((labels) => {
9971
10752
  const pin = labels.find((label) => /^pin\d+$/i.test(label));
9972
10753
  return [pin, labels.filter((label) => label !== pin)];
9973
10754
  })
9974
10755
  );
9975
10756
  const polarizedPinMetadata = pads.length === 2 && (isDiodeCategoryComponent(easyEdaJson) || isLedCategoryComponent(easyEdaJson)) ? getPolarizedPinMetadata(normalizedPinLabelsByPin) : void 0;
10757
+ const emittedSourcePinIndexes = /* @__PURE__ */ new Set();
9976
10758
  pads.forEach((pad, index) => {
9977
10759
  const portHints = normalizedPinLabels[index];
9978
10760
  const pinNumber = Number.parseInt(
@@ -9980,14 +10762,18 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
9980
10762
  );
9981
10763
  const canonicalPinName = `pin${pinNumber}`;
9982
10764
  const pcbPortHints = polarizedPinMetadata?.portHintsMap[canonicalPinName] ?? [canonicalPinName];
9983
- circuitElements.push({
9984
- type: "source_port",
9985
- source_port_id: `source_port_${index + 1}`,
9986
- source_component_id: "source_component_1",
9987
- name: `pin${pinNumber}`,
9988
- pin_number: pinNumber,
9989
- port_hints: portHints.filter((hint) => hint !== `pin${pinNumber}`)
9990
- });
10765
+ const uniquePinIndex = uniquePinIndexByPad[index];
10766
+ if (!emittedSourcePinIndexes.has(uniquePinIndex)) {
10767
+ emittedSourcePinIndexes.add(uniquePinIndex);
10768
+ circuitElements.push({
10769
+ type: "source_port",
10770
+ source_port_id: `source_port_${index + 1}`,
10771
+ source_component_id: "source_component_1",
10772
+ name: `pin${pinNumber}`,
10773
+ pin_number: pinNumber,
10774
+ port_hints: portHints.filter((hint) => hint !== `pin${pinNumber}`)
10775
+ });
10776
+ }
9991
10777
  if (pad.holeRadius !== void 0 && mil2mm(pad.holeRadius) !== 0) {
9992
10778
  const platedHoleId = pad.shape === "RECT" && pad.rotation !== void 0 ? `pcb_plated_hole_${index + 1}_rot${pad.rotation}` : `pcb_plated_hole_${index + 1}`;
9993
10779
  const commonPlatedHoleProps = {
@@ -9995,7 +10781,8 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
9995
10781
  pcb_plated_hole_id: platedHoleId,
9996
10782
  x: mil2mm(pad.center.x),
9997
10783
  y: mil2mm(pad.center.y),
9998
- layers: ["top"],
10784
+ // Through-hole pads are plated on both outer copper layers.
10785
+ layers: ["top", "bottom"],
9999
10786
  port_hints: pcbPortHints,
10000
10787
  pcb_component_id: "pcb_component_1",
10001
10788
  pcb_port_id: `pcb_port_${index + 1}`
@@ -10049,10 +10836,15 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
10049
10836
  };
10050
10837
  } else {
10051
10838
  additionalPlatedHoleProps = {
10052
- shape: "circle",
10053
- hole_diameter: holeDiameter,
10054
- outer_diameter: Math.max(padWidth, padHeight),
10055
- radius: holeDiameter / 2
10839
+ shape: "rotated_pill_hole_with_rect_pad",
10840
+ hole_shape: "rotated_pill",
10841
+ pad_shape: "rect",
10842
+ hole_width: holeDiameter,
10843
+ hole_height: holeDiameter,
10844
+ hole_ccw_rotation: pad.rotation || 0,
10845
+ rect_ccw_rotation: pad.rotation || 0,
10846
+ rect_pad_width: padWidth,
10847
+ rect_pad_height: padHeight
10056
10848
  };
10057
10849
  }
10058
10850
  } else {
@@ -10074,7 +10866,7 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
10074
10866
  if (pad.shape === "RECT") {
10075
10867
  soupShape = "rect";
10076
10868
  } else if (pad.shape === "ELLIPSE") {
10077
- soupShape = "rect";
10869
+ soupShape = "circle";
10078
10870
  } else if (pad.shape === "OVAL") {
10079
10871
  soupShape = "pill";
10080
10872
  } else if (pad.shape === "POLYGON") {
@@ -10130,18 +10922,35 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
10130
10922
  circuitElements.push(handleCutout(sr, index));
10131
10923
  });
10132
10924
  let hasFoundDesignator = false;
10925
+ const silkscreenTracks = easyEdaJson.packageDetail.dataStr.shape.filter(
10926
+ (shape) => shape.type === "TRACK" && isSilkscreenLayer(shape.layer)
10927
+ );
10133
10928
  easyEdaJson.packageDetail.dataStr.shape.forEach((shape, index) => {
10134
10929
  if (shape.type === "TRACK") {
10135
- if (!isCourtyardLayer(shape.layer)) {
10930
+ if (isSilkscreenLayer(shape.layer)) {
10136
10931
  circuitElements.push(handleSilkscreenPath(shape, index));
10932
+ } else if (isDocumentLayer(shape.layer)) {
10933
+ circuitElements.push(handleFabricationNotePath(shape, index));
10137
10934
  }
10935
+ } else if (shape.type === "SOLIDREGION" && isDocumentLayer(shape.layermask)) {
10936
+ const fabricationNote = handleFabricationNoteSolidRegion(shape, index);
10937
+ if (fabricationNote) circuitElements.push(fabricationNote);
10138
10938
  } else if (shape.type === "CIRCLE") {
10139
10939
  if (isSilkscreenLayer(shape.layer)) {
10140
10940
  circuitElements.push(handleSilkscreenCircle(shape, index));
10141
10941
  }
10942
+ } else if (shape.type === "RECT") {
10943
+ circuitElements.push(handleRect(shape, index));
10142
10944
  } else if (shape.type === "ARC") {
10143
10945
  if (!isCourtyardLayer(shape.layer)) {
10144
- circuitElements.push(handleSilkscreenArc(shape, index));
10946
+ circuitElements.push(
10947
+ handleSilkscreenArc(
10948
+ shape,
10949
+ index,
10950
+ easyEdaJson.packageDetail.dataStr.head,
10951
+ silkscreenTracks
10952
+ )
10953
+ );
10145
10954
  }
10146
10955
  } else if (shape.type === "TEXT") {
10147
10956
  if (isCourtyardLayer(shape.layer)) return;
@@ -10171,6 +10980,9 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
10171
10980
  R: "bottom_right"
10172
10981
  }[shape.textAnchor ?? "L"],
10173
10982
  font_size: shape.size_mm || 1,
10983
+ ...shape.rotation !== void 0 && {
10984
+ ccw_rotation: shape.rotation
10985
+ },
10174
10986
  layer: "top"
10175
10987
  })
10176
10988
  );
@@ -10196,7 +11008,7 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
10196
11008
  );
10197
11009
  }
10198
11010
  const pcbElements = circuitElements.filter(
10199
- (e) => e.type === "pcb_smtpad" || e.type === "pcb_plated_hole" || e.type === "pcb_hole" || e.type === "pcb_via" || e.type === "pcb_courtyard_outline" || e.type === "pcb_silkscreen_path" || e.type === "pcb_silkscreen_text"
11011
+ (e) => e.type === "pcb_smtpad" || e.type === "pcb_plated_hole" || e.type === "pcb_hole" || e.type === "pcb_via" || e.type === "pcb_courtyard_outline" || e.type === "pcb_courtyard_rect" || e.type === "pcb_silkscreen_path" || e.type === "pcb_silkscreen_circle" || e.type === "pcb_silkscreen_rect" || e.type === "pcb_silkscreen_text"
10200
11012
  );
10201
11013
  if (pcbElements.length > 0) {
10202
11014
  const bounds = findBoundsAndCenter(pcbElements);
@@ -10263,7 +11075,7 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
10263
11075
  }
10264
11076
  if (shouldRecenter) {
10265
11077
  const elementsForBounds = circuitElements.filter(
10266
- (e) => e.type !== "pcb_component" && e.type !== "cad_component"
11078
+ (e) => e.type !== "pcb_component" && e.type !== "cad_component" && e.type !== "pcb_silkscreen_circle"
10267
11079
  );
10268
11080
  const bounds = findBoundsAndCenter(elementsForBounds);
10269
11081
  if (Number.isFinite(bounds.center.x) && Number.isFinite(bounds.center.y)) {
@@ -10311,8 +11123,16 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
10311
11123
  const t = DEFAULT_PCB_THICKNESS_MM / 2;
10312
11124
  const attrs = svgNode?.svgData?.attrs ?? {};
10313
11125
  const modelHeight = readModelHeightMm(attrs.c_height);
11126
+ const cadModelSize = resolvedCadModelBounds ? {
11127
+ x: resolvedCadModelBounds.max.x - resolvedCadModelBounds.min.x,
11128
+ y: resolvedCadModelBounds.max.y - resolvedCadModelBounds.min.y,
11129
+ z: resolvedCadModelBounds.max.z - resolvedCadModelBounds.min.z
11130
+ } : void 0;
11131
+ const hasValidCadModelSize = cadModelSize !== void 0 && Object.values(cadModelSize).every(
11132
+ (dimension) => Number.isFinite(dimension) && dimension > 0
11133
+ );
10314
11134
  if (!cad.size) {
10315
- cad.size = {
11135
+ cad.size = hasValidCadModelSize ? cadModelSize : {
10316
11136
  x: pcb_component2.width,
10317
11137
  y: pcb_component2.height,
10318
11138
  z: modelHeight
@@ -10437,8 +11257,9 @@ var CircleSchema = BaseShapeSchema.extend({
10437
11257
  var SolidRegionSchema = BaseShapeSchema.extend({
10438
11258
  type: external_exports.literal("SOLIDREGION"),
10439
11259
  layermask: external_exports.number(),
11260
+ pathData: external_exports.string(),
10440
11261
  points: external_exports.array(PointSchema),
10441
- fillStyle: external_exports.string()
11262
+ fillStyle: external_exports.string().default("none")
10442
11263
  });
10443
11264
  var SVGNodeSchema = BaseShapeSchema.extend({
10444
11265
  type: external_exports.literal("SVGNODE"),
@@ -10469,7 +11290,7 @@ var RectSchema = BaseShapeSchema.extend({
10469
11290
  width: tenthmil,
10470
11291
  height: tenthmil,
10471
11292
  lineWidth: external_exports.number(),
10472
- fillStyle: external_exports.string(),
11293
+ fillStyle: external_exports.string().default("none"),
10473
11294
  rotation: external_exports.number().optional()
10474
11295
  });
10475
11296
  var TextSchema = BaseShapeSchema.extend({
@@ -10631,8 +11452,9 @@ var ShapeItemSchema = external_exports.object({
10631
11452
  return SolidRegionSchema.parse({
10632
11453
  type: "SOLIDREGION",
10633
11454
  layermask: Number(layermask),
11455
+ pathData,
10634
11456
  points,
10635
- fillStyle,
11457
+ fillStyle: fillStyle || void 0,
10636
11458
  id
10637
11459
  });
10638
11460
  }
@@ -10641,7 +11463,7 @@ var ShapeItemSchema = external_exports.object({
10641
11463
  return SVGNodeSchema.parse({ type: "SVGNODE", svgData });
10642
11464
  }
10643
11465
  case "RECT": {
10644
- const [x, y, width, height, lineWidth, id, rotation2, layer, fillStyle] = shape.data.split("~");
11466
+ const [x, y, width, height, layer, id, rotation2, lineWidth, fillStyle] = shape.data.split("~");
10645
11467
  const r = rotation2 ? Number(rotation2) : void 0;
10646
11468
  return RectSchema.parse({
10647
11469
  type: "RECT",
@@ -10657,7 +11479,18 @@ var ShapeItemSchema = external_exports.object({
10657
11479
  });
10658
11480
  }
10659
11481
  case "TEXT": {
10660
- const [textAnchor, x, y, size2, layer, id, rotation2, , font, text] = shape.data.split("~");
11482
+ const [
11483
+ textAnchor,
11484
+ x,
11485
+ y,
11486
+ size2,
11487
+ rotation2,
11488
+ _mirror,
11489
+ layer,
11490
+ _net,
11491
+ font,
11492
+ text
11493
+ ] = shape.data.split("~");
10661
11494
  const r = rotation2 ? Number(rotation2) : void 0;
10662
11495
  return TextSchema.parse({
10663
11496
  type: "TEXT",
@@ -10667,7 +11500,6 @@ var ShapeItemSchema = external_exports.object({
10667
11500
  size_mm: Number(size2) * 2.54,
10668
11501
  // empirically this seems to match, C5248081 is a good test case
10669
11502
  layer: layer ? Number(layer) : void 0,
10670
- id,
10671
11503
  rotation: Number.isNaN(r) ? void 0 : r,
10672
11504
  textAnchor,
10673
11505
  font: font || void 0
@@ -10782,10 +11614,12 @@ var parsePin = (pinString) => {
10782
11614
  const [, visibility, , pinNumber, x, y, rotation2, id] = parts;
10783
11615
  const nameMatch = pinString.match(/~([\w+#-]+)~(start|end)~/);
10784
11616
  let label = nameMatch ? nameMatch[1] : "";
10785
- if (label.endsWith("+")) label = label.slice(0, -1) + "_POS";
10786
- if (label.endsWith("-")) label = label.slice(0, -1) + "_NEG";
10787
- if (label.endsWith("#")) label = label.slice(0, -1);
11617
+ if (label.endsWith("+")) label = `${label.slice(0, -1)}_POS`;
11618
+ if (label.endsWith("-")) label = `${label.slice(0, -1)}_NEG`;
11619
+ label = normalizeActiveLowPinLabel(label);
10788
11620
  if (/^\+\d+(?:\.\d+)?V$/i.test(label)) label = `V${label.slice(1, -1)}`;
11621
+ if (label.startsWith("+")) label = `${label.slice(1)}_POS`;
11622
+ if (label.startsWith("-")) label = `${label.slice(1)}_NEG`;
10789
11623
  const colorMatch = pinString.match(/#[0-9A-F]{6}/);
10790
11624
  const labelColor = colorMatch ? colorMatch[0] : "";
10791
11625
  const path = pinString.split("^^")[2]?.split("~")[0] ?? "";
@@ -10877,6 +11711,17 @@ var parsePath = (str) => {
10877
11711
  };
10878
11712
  };
10879
11713
  var PathShapeSchema = external_exports.string().startsWith("PT~").transform(parsePath).pipe(PathShapeOutputSchema);
11714
+ var IgnoredShapeOutputSchema = external_exports.object({
11715
+ type: external_exports.literal("IGNORED"),
11716
+ sourceType: external_exports.enum(["AR", "I"])
11717
+ });
11718
+ var IgnoredShapeSchema = external_exports.string().transform((shape) => {
11719
+ const sourceType = shape.startsWith("AR~") ? "AR" : shape.startsWith("I~") ? "I" : void 0;
11720
+ if (!sourceType) {
11721
+ throw new Error(`Invalid ignored shape: ${shape}`);
11722
+ }
11723
+ return { type: "IGNORED", sourceType };
11724
+ }).pipe(IgnoredShapeOutputSchema);
10880
11725
  var optionalEasyEdaTextField = (fieldSchema) => external_exports.preprocess((textField) => {
10881
11726
  if (textField == null) return void 0;
10882
11727
  if (typeof textField === "string") {
@@ -10928,7 +11773,8 @@ var parseText = (str) => {
10928
11773
  ] = str.split("~");
10929
11774
  return {
10930
11775
  type: "TEXT",
10931
- alignment,
11776
+ // Some EasyEDA component payloads use "P" for start-aligned text.
11777
+ alignment: alignment === "P" ? "L" : alignment,
10932
11778
  x: Number(x),
10933
11779
  y: Number(y),
10934
11780
  rotation: Number(rotation2),
@@ -10954,6 +11800,9 @@ var SingleLetterShapeSchema = external_exports.string().transform((x) => {
10954
11800
  if (x.startsWith("PG~")) return PolygonShapeSchema.parse(x);
10955
11801
  if (x.startsWith("PT~")) return PathShapeSchema.parse(x);
10956
11802
  if (x.startsWith("T~")) return TextShapeSchema.parse(x);
11803
+ if (x.startsWith("AR~") || x.startsWith("I~")) {
11804
+ return IgnoredShapeSchema.parse(x);
11805
+ }
10957
11806
  if (x.startsWith("A~")) return ArcShapeSchema.parse(x);
10958
11807
  throw new Error(`Invalid shape type: ${x}`);
10959
11808
  }).pipe(
@@ -10965,16 +11814,27 @@ var SingleLetterShapeSchema = external_exports.string().transform((x) => {
10965
11814
  PolygonShapeOutputSchema,
10966
11815
  PathShapeOutputSchema,
10967
11816
  TextShapeOutputSchema,
11817
+ IgnoredShapeOutputSchema,
10968
11818
  ArcShapeOutputSchema
10969
11819
  ])
10970
11820
  );
10971
11821
  var maybeNumber = external_exports.any().transform((k) => k === "nan" || Number.isNaN(k) ? null : k).pipe(external_exports.number().nullable().optional());
11822
+ var optionalNumberWithNumericString = external_exports.preprocess((value) => {
11823
+ if (typeof value !== "string") return value;
11824
+ if (value.trim() === "") return void 0;
11825
+ return Number(value);
11826
+ }, external_exports.number().optional());
10972
11827
  var SzlcscSchema = external_exports.object({
10973
- id: external_exports.number(),
11828
+ id: external_exports.preprocess((value) => {
11829
+ if (typeof value === "string" && /^\d+$/.test(value)) {
11830
+ return Number(value);
11831
+ }
11832
+ return value;
11833
+ }, external_exports.number()),
10974
11834
  number: external_exports.string(),
10975
11835
  step: external_exports.number().optional(),
10976
11836
  min: external_exports.number().optional(),
10977
- price: external_exports.number().optional(),
11837
+ price: optionalNumberWithNumericString,
10978
11838
  stock: external_exports.number().optional(),
10979
11839
  url: external_exports.string().url().optional(),
10980
11840
  image: external_exports.string().optional().optional()
@@ -10984,7 +11844,7 @@ var LcscSchema = external_exports.object({
10984
11844
  number: external_exports.string(),
10985
11845
  step: external_exports.number().optional(),
10986
11846
  min: external_exports.number().optional(),
10987
- price: external_exports.number().optional(),
11847
+ price: optionalNumberWithNumericString,
10988
11848
  stock: external_exports.number().optional(),
10989
11849
  url: external_exports.string().url().optional()
10990
11850
  });
@@ -11003,10 +11863,10 @@ var HeadSchema = external_exports.object({
11003
11863
  puuid: external_exports.string().optional(),
11004
11864
  uuid: external_exports.string(),
11005
11865
  utime: external_exports.preprocess((val) => {
11006
- if (val === "") return 0;
11866
+ if (val == null || val === "") return void 0;
11007
11867
  if (typeof val === "string") return Number(val);
11008
11868
  return val;
11009
- }, external_exports.number()),
11869
+ }, external_exports.number().optional()),
11010
11870
  importFlag: external_exports.number().optional(),
11011
11871
  c_spiceCmd: external_exports.any().optional(),
11012
11872
  hasIdFlag: external_exports.boolean().default(false)