circuit-to-svg 0.0.38 → 0.0.39

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 CHANGED
@@ -1,16 +1,20 @@
1
1
  import { AnyCircuitElement } from 'circuit-json';
2
2
 
3
- interface Options {
3
+ interface Options$1 {
4
4
  width?: number;
5
5
  height?: number;
6
6
  }
7
- declare function convertCircuitJsonToPcbSvg(soup: AnyCircuitElement[], options?: Options): string;
7
+ declare function convertCircuitJsonToPcbSvg(soup: AnyCircuitElement[], options?: Options$1): string;
8
8
  /**
9
9
  * @deprecated use `convertCircuitJsonToPcbSvg` instead
10
10
  */
11
11
  declare const circuitJsonToPcbSvg: typeof convertCircuitJsonToPcbSvg;
12
12
 
13
- declare function convertCircuitJsonToSchematicSvg(soup: AnyCircuitElement[]): string;
13
+ interface Options {
14
+ width?: number;
15
+ height?: number;
16
+ }
17
+ declare function convertCircuitJsonToSchematicSvg(soup: AnyCircuitElement[], options?: Options): string;
14
18
  /**
15
19
  * @deprecated use `convertCircuitJsonToSchematicSvg` instead
16
20
  */
package/dist/index.js CHANGED
@@ -740,10 +740,495 @@ function createSvgObjectFromPcbBoundary(transform, minX, minY, maxX, maxY) {
740
740
  }
741
741
  var circuitJsonToPcbSvg = convertCircuitJsonToPcbSvg;
742
742
 
743
+ // lib/utils/colors.ts
744
+ var colorMap = {
745
+ "3d_viewer": {
746
+ background_bottom: "rgb(102, 102, 128)",
747
+ background_top: "rgb(204, 204, 230)",
748
+ board: "rgb(51, 43, 23)",
749
+ copper: "rgb(179, 156, 0)",
750
+ silkscreen_bottom: "rgb(230, 230, 230)",
751
+ silkscreen_top: "rgb(230, 230, 230)",
752
+ soldermask: "rgb(20, 51, 36)",
753
+ solderpaste: "rgb(128, 128, 128)"
754
+ },
755
+ board: {
756
+ anchor: "rgb(255, 38, 226)",
757
+ aux_items: "rgb(255, 255, 255)",
758
+ b_adhes: "rgb(0, 0, 132)",
759
+ b_crtyd: "rgb(255, 38, 226)",
760
+ b_fab: "rgb(88, 93, 132)",
761
+ b_mask: "rgba(2, 255, 238, 0.400)",
762
+ b_paste: "rgb(0, 194, 194)",
763
+ b_silks: "rgb(232, 178, 167)",
764
+ background: "rgb(0, 16, 35)",
765
+ cmts_user: "rgb(89, 148, 220)",
766
+ copper: {
767
+ b: "rgb(77, 127, 196)",
768
+ f: "rgb(200, 52, 52)",
769
+ in1: "rgb(127, 200, 127)",
770
+ in10: "rgb(237, 124, 51)",
771
+ in11: "rgb(91, 195, 235)",
772
+ in12: "rgb(247, 111, 142)",
773
+ in13: "rgb(167, 165, 198)",
774
+ in14: "rgb(40, 204, 217)",
775
+ in15: "rgb(232, 178, 167)",
776
+ in16: "rgb(242, 237, 161)",
777
+ in17: "rgb(237, 124, 51)",
778
+ in18: "rgb(91, 195, 235)",
779
+ in19: "rgb(247, 111, 142)",
780
+ in2: "rgb(206, 125, 44)",
781
+ in20: "rgb(167, 165, 198)",
782
+ in21: "rgb(40, 204, 217)",
783
+ in22: "rgb(232, 178, 167)",
784
+ in23: "rgb(242, 237, 161)",
785
+ in24: "rgb(237, 124, 51)",
786
+ in25: "rgb(91, 195, 235)",
787
+ in26: "rgb(247, 111, 142)",
788
+ in27: "rgb(167, 165, 198)",
789
+ in28: "rgb(40, 204, 217)",
790
+ in29: "rgb(232, 178, 167)",
791
+ in3: "rgb(79, 203, 203)",
792
+ in30: "rgb(242, 237, 161)",
793
+ in4: "rgb(219, 98, 139)",
794
+ in5: "rgb(167, 165, 198)",
795
+ in6: "rgb(40, 204, 217)",
796
+ in7: "rgb(232, 178, 167)",
797
+ in8: "rgb(242, 237, 161)",
798
+ in9: "rgb(141, 203, 129)"
799
+ },
800
+ cursor: "rgb(255, 255, 255)",
801
+ drc: "rgb(194, 194, 194)",
802
+ drc_error: "rgba(215, 91, 107, 0.800)",
803
+ drc_exclusion: "rgb(255, 255, 255)",
804
+ drc_warning: "rgba(255, 208, 66, 0.902)",
805
+ dwgs_user: "rgb(194, 194, 194)",
806
+ eco1_user: "rgb(180, 219, 210)",
807
+ eco2_user: "rgb(216, 200, 82)",
808
+ edge_cuts: "rgb(208, 210, 205)",
809
+ f_adhes: "rgb(132, 0, 132)",
810
+ f_crtyd: "rgb(255, 0, 245)",
811
+ f_fab: "rgb(175, 175, 175)",
812
+ f_mask: "rgba(216, 100, 255, 0.400)",
813
+ f_paste: "rgba(180, 160, 154, 0.902)",
814
+ f_silks: "rgb(242, 237, 161)",
815
+ footprint_text_back: "rgb(0, 0, 132)",
816
+ footprint_text_front: "rgb(194, 194, 194)",
817
+ footprint_text_invisible: "rgb(132, 132, 132)",
818
+ grid: "rgb(132, 132, 132)",
819
+ grid_axes: "rgb(194, 194, 194)",
820
+ margin: "rgb(255, 38, 226)",
821
+ microvia: "rgb(0, 132, 132)",
822
+ no_connect: "rgb(0, 0, 132)",
823
+ pad_back: "rgb(77, 127, 196)",
824
+ pad_front: "rgb(200, 52, 52)",
825
+ pad_plated_hole: "rgb(194, 194, 0)",
826
+ pad_through_hole: "rgb(227, 183, 46)",
827
+ plated_hole: "rgb(26, 196, 210)",
828
+ ratsnest: "rgba(245, 255, 213, 0.702)",
829
+ select_overlay: "rgb(4, 255, 67)",
830
+ through_via: "rgb(236, 236, 236)",
831
+ user_1: "rgb(194, 194, 194)",
832
+ user_2: "rgb(89, 148, 220)",
833
+ user_3: "rgb(180, 219, 210)",
834
+ user_4: "rgb(216, 200, 82)",
835
+ user_5: "rgb(194, 194, 194)",
836
+ user_6: "rgb(89, 148, 220)",
837
+ user_7: "rgb(180, 219, 210)",
838
+ user_8: "rgb(216, 200, 82)",
839
+ user_9: "rgb(232, 178, 167)",
840
+ via_blind_buried: "rgb(187, 151, 38)",
841
+ via_hole: "rgb(227, 183, 46)",
842
+ via_micro: "rgb(0, 132, 132)",
843
+ via_through: "rgb(236, 236, 236)",
844
+ worksheet: "rgb(200, 114, 171)"
845
+ },
846
+ gerbview: {
847
+ axes: "rgb(0, 0, 132)",
848
+ background: "rgb(0, 0, 0)",
849
+ dcodes: "rgb(255, 255, 255)",
850
+ grid: "rgb(132, 132, 132)",
851
+ layers: [
852
+ "rgb(132, 0, 0)",
853
+ "rgb(194, 194, 0)",
854
+ "rgb(194, 0, 194)",
855
+ "rgb(194, 0, 0)",
856
+ "rgb(0, 132, 132)",
857
+ "rgb(0, 132, 0)",
858
+ "rgb(0, 0, 132)",
859
+ "rgb(132, 132, 132)",
860
+ "rgb(132, 0, 132)",
861
+ "rgb(194, 194, 194)",
862
+ "rgb(132, 0, 132)",
863
+ "rgb(132, 0, 0)",
864
+ "rgb(132, 132, 0)",
865
+ "rgb(194, 194, 194)",
866
+ "rgb(0, 0, 132)",
867
+ "rgb(0, 132, 0)",
868
+ "rgb(132, 0, 0)",
869
+ "rgb(194, 194, 0)",
870
+ "rgb(194, 0, 194)",
871
+ "rgb(194, 0, 0)",
872
+ "rgb(0, 132, 132)",
873
+ "rgb(0, 132, 0)",
874
+ "rgb(0, 0, 132)",
875
+ "rgb(132, 132, 132)",
876
+ "rgb(132, 0, 132)",
877
+ "rgb(194, 194, 194)",
878
+ "rgb(132, 0, 132)",
879
+ "rgb(132, 0, 0)",
880
+ "rgb(132, 132, 0)",
881
+ "rgb(194, 194, 194)",
882
+ "rgb(0, 0, 132)",
883
+ "rgb(0, 132, 0)",
884
+ "rgb(132, 0, 0)",
885
+ "rgb(194, 194, 0)",
886
+ "rgb(194, 0, 194)",
887
+ "rgb(194, 0, 0)",
888
+ "rgb(0, 132, 132)",
889
+ "rgb(0, 132, 0)",
890
+ "rgb(0, 0, 132)",
891
+ "rgb(132, 132, 132)",
892
+ "rgb(132, 0, 132)",
893
+ "rgb(194, 194, 194)",
894
+ "rgb(132, 0, 132)",
895
+ "rgb(132, 0, 0)",
896
+ "rgb(132, 132, 0)",
897
+ "rgb(194, 194, 194)",
898
+ "rgb(0, 0, 132)",
899
+ "rgb(0, 132, 0)",
900
+ "rgb(132, 0, 0)",
901
+ "rgb(194, 194, 0)",
902
+ "rgb(194, 0, 194)",
903
+ "rgb(194, 0, 0)",
904
+ "rgb(0, 132, 132)",
905
+ "rgb(0, 132, 0)",
906
+ "rgb(0, 0, 132)",
907
+ "rgb(132, 132, 132)",
908
+ "rgb(132, 0, 132)",
909
+ "rgb(194, 194, 194)",
910
+ "rgb(132, 0, 132)",
911
+ "rgb(132, 0, 0)"
912
+ ],
913
+ negative_objects: "rgb(132, 132, 132)",
914
+ worksheet: "rgb(0, 0, 132)"
915
+ },
916
+ meta: {
917
+ filename: "kicad_2020",
918
+ name: "KiCad 2020",
919
+ version: 2
920
+ },
921
+ palette: [
922
+ "rgb(132, 0, 0)",
923
+ "rgb(194, 194, 0)",
924
+ "rgb(194, 0, 194)",
925
+ "rgb(194, 0, 0)",
926
+ "rgb(0, 132, 132)",
927
+ "rgb(0, 132, 0)",
928
+ "rgb(0, 0, 132)",
929
+ "rgb(132, 132, 132)",
930
+ "rgb(132, 0, 132)",
931
+ "rgb(194, 194, 194)",
932
+ "rgb(132, 0, 132)",
933
+ "rgb(132, 0, 0)",
934
+ "rgb(132, 132, 0)",
935
+ "rgb(194, 194, 194)",
936
+ "rgb(0, 0, 132)",
937
+ "rgb(0, 132, 0)"
938
+ ],
939
+ schematic: {
940
+ aux_items: "rgb(46, 46, 46)",
941
+ background: "rgb(245, 241, 237)",
942
+ brightened: "rgb(255, 0, 255)",
943
+ bus: "rgb(0, 0, 132)",
944
+ bus_junction: "rgb(0, 0, 132)",
945
+ component_body: "rgb(255, 255, 194)",
946
+ component_outline: "rgb(132, 0, 0)",
947
+ cursor: "rgb(15, 15, 15)",
948
+ erc_error: "rgba(230, 9, 13, 0.800)",
949
+ erc_warning: "rgba(209, 146, 0, 0.800)",
950
+ fields: "rgb(132, 0, 132)",
951
+ grid: "rgb(181, 181, 181)",
952
+ grid_axes: "rgb(0, 0, 132)",
953
+ hidden: "rgb(194, 194, 194)",
954
+ junction: "rgb(0, 150, 0)",
955
+ label_global: "rgb(132, 0, 0)",
956
+ label_hier: "rgb(114, 86, 0)",
957
+ label_local: "rgb(15, 15, 15)",
958
+ net_name: "rgb(132, 132, 132)",
959
+ no_connect: "rgb(0, 0, 132)",
960
+ note: "rgb(0, 0, 194)",
961
+ override_item_colors: false,
962
+ pin: "rgb(132, 0, 0)",
963
+ pin_name: "rgb(0, 100, 100)",
964
+ pin_number: "rgb(169, 0, 0)",
965
+ reference: "rgb(0, 100, 100)",
966
+ shadow: "rgba(102, 179, 255, 0.800)",
967
+ sheet: "rgb(132, 0, 0)",
968
+ sheet_background: "rgba(253, 255, 231, 0.000)",
969
+ sheet_fields: "rgb(132, 0, 132)",
970
+ sheet_filename: "rgb(114, 86, 0)",
971
+ sheet_label: "rgb(0, 100, 100)",
972
+ sheet_name: "rgb(0, 100, 100)",
973
+ value: "rgb(0, 100, 100)",
974
+ wire: "rgb(0, 150, 0)",
975
+ worksheet: "rgb(132, 0, 0)"
976
+ }
977
+ };
978
+
743
979
  // lib/sch/convert-circuit-json-to-schematic-svg.ts
980
+ import { stringify as stringify2 } from "svgson";
981
+
982
+ // lib/sch/svg-object-fns/create-svg-objects-from-sch-component.ts
744
983
  import { getSvg, symbols } from "schematic-symbols";
745
- import { parseSync, stringify as stringify2 } from "svgson";
746
- function convertCircuitJsonToSchematicSvg(soup) {
984
+ import { parseSync } from "svgson";
985
+ function createSchematicComponent(center, size, rotation, symbolName, portArrangement, portLabels, sourceComponentId, circuitJson) {
986
+ const transform = `translate(${center.x}, ${center.y}) rotate(${rotation * 180 / Math.PI})`;
987
+ let children = [];
988
+ const sourceComponent = circuitJson?.find(
989
+ (item) => item.type === "source_component" && item.source_component_id === sourceComponentId
990
+ );
991
+ const componentName = sourceComponent && "name" in sourceComponent ? sourceComponent.name : "";
992
+ const manufacturerNumber = sourceComponent && "manufacturer_part_number" in sourceComponent ? sourceComponent.manufacturer_part_number : "";
993
+ const resistance = sourceComponent && "resistance" in sourceComponent ? sourceComponent.resistance : "";
994
+ const capacitance = sourceComponent && "capacitance" in sourceComponent ? sourceComponent.capacitance : "";
995
+ if (symbolName) {
996
+ const symbol = symbols[symbolName];
997
+ const paths = symbol.primitives.filter((p) => p.type === "path");
998
+ const updatedSymbol = {
999
+ ...symbol,
1000
+ primitives: paths
1001
+ };
1002
+ const svg = parseSync(
1003
+ getSvg(updatedSymbol, {
1004
+ width: size.width,
1005
+ height: size.height
1006
+ })
1007
+ );
1008
+ children = svg.children.filter(
1009
+ (child) => child.name === "path" && child.attributes.fill !== "green"
1010
+ ).map((path) => {
1011
+ const currentStrokeWidth = Number.parseFloat(
1012
+ path.attributes["stroke-width"] || "0.02"
1013
+ );
1014
+ const newStrokeWidth = (currentStrokeWidth * 1.5).toString();
1015
+ return {
1016
+ ...path,
1017
+ attributes: {
1018
+ ...path.attributes,
1019
+ stroke: path.attributes.stroke === "black" ? `${colorMap.schematic.component_outline}` : path.attributes.stroke,
1020
+ "stroke-width": newStrokeWidth
1021
+ }
1022
+ };
1023
+ });
1024
+ } else {
1025
+ children.push({
1026
+ name: "rect",
1027
+ type: "element",
1028
+ attributes: {
1029
+ class: "component chip",
1030
+ x: -size.width / 2,
1031
+ y: -size.height / 2,
1032
+ width: size.width,
1033
+ height: size.height
1034
+ }
1035
+ });
1036
+ }
1037
+ if (manufacturerNumber) {
1038
+ children.push({
1039
+ name: "text",
1040
+ type: "element",
1041
+ attributes: {
1042
+ class: "component-name",
1043
+ x: 1.2,
1044
+ y: -size.height / 2 - 0.4,
1045
+ // Position above the component
1046
+ "text-anchor": "right",
1047
+ "dominant-baseline": "auto"
1048
+ },
1049
+ children: [{ type: "text", value: manufacturerNumber }]
1050
+ });
1051
+ children.push({
1052
+ name: "text",
1053
+ type: "element",
1054
+ attributes: {
1055
+ class: "component-name",
1056
+ x: 1.2,
1057
+ y: -size.height / 2 - 0.7,
1058
+ // Position above the component
1059
+ "text-anchor": "right",
1060
+ "dominant-baseline": "auto"
1061
+ },
1062
+ children: [{ type: "text", value: componentName }]
1063
+ });
1064
+ }
1065
+ if (resistance || capacitance) {
1066
+ children.push({
1067
+ name: "text",
1068
+ type: "element",
1069
+ attributes: {
1070
+ class: "component-name",
1071
+ x: 0,
1072
+ y: -size.height / 2 - 0.2,
1073
+ // Position above the component
1074
+ "text-anchor": "middle",
1075
+ "dominant-baseline": "auto"
1076
+ },
1077
+ children: [{ type: "text", value: resistance || capacitance }]
1078
+ });
1079
+ children.push({
1080
+ name: "text",
1081
+ type: "element",
1082
+ attributes: {
1083
+ class: "component-name",
1084
+ x: 0,
1085
+ y: -size.height / 2 - 0.5,
1086
+ // Position above the component
1087
+ "text-anchor": "middle",
1088
+ "dominant-baseline": "auto"
1089
+ },
1090
+ children: [{ type: "text", value: componentName }]
1091
+ });
1092
+ }
1093
+ if (portArrangement) {
1094
+ const portLength = 0.2;
1095
+ const circleRadius = 0.05;
1096
+ const labelOffset = 0.1;
1097
+ for (const [side, arrangement] of Object.entries(portArrangement)) {
1098
+ if (!arrangement) continue;
1099
+ const pins = arrangement.pins;
1100
+ const direction = arrangement.direction;
1101
+ let getX;
1102
+ let getY;
1103
+ let getEndX;
1104
+ let getEndY;
1105
+ let getLabelX;
1106
+ let getLabelY;
1107
+ let labelAnchor;
1108
+ let isVertical = false;
1109
+ switch (side) {
1110
+ case "left_side":
1111
+ getX = () => -size.width / 2;
1112
+ getY = (index, total) => -size.height / 2 + size.height * (index + 1) / (total + 1);
1113
+ getEndX = (x) => x - portLength;
1114
+ getEndY = (y) => y;
1115
+ getLabelX = (x) => x + labelOffset;
1116
+ getLabelY = (y) => y;
1117
+ labelAnchor = "start";
1118
+ break;
1119
+ case "right_side":
1120
+ getX = () => size.width / 2;
1121
+ getY = (index, total) => -size.height / 2 + size.height * (index + 1) / (total + 1);
1122
+ getEndX = (x) => x + portLength;
1123
+ getEndY = (y) => y;
1124
+ getLabelX = (x) => x - labelOffset;
1125
+ getLabelY = (y) => y;
1126
+ labelAnchor = "end";
1127
+ break;
1128
+ case "top_side":
1129
+ getX = (index, total) => -size.width / 2 + size.width * (index + 1) / (total + 1);
1130
+ getY = () => -size.height / 2;
1131
+ getEndX = (x) => x;
1132
+ getEndY = (y) => y - portLength;
1133
+ getLabelX = (x) => x;
1134
+ getLabelY = (y) => y + labelOffset + 0.15;
1135
+ labelAnchor = "middle";
1136
+ isVertical = true;
1137
+ break;
1138
+ case "bottom_side":
1139
+ getX = (index, total) => -size.width / 2 + size.width * (index + 1) / (total + 1);
1140
+ getY = () => size.height / 2;
1141
+ getEndX = (x) => x;
1142
+ getEndY = (y) => y + portLength;
1143
+ getLabelX = (x) => x;
1144
+ getLabelY = (y) => y - labelOffset - 0.15;
1145
+ labelAnchor = "middle";
1146
+ isVertical = true;
1147
+ break;
1148
+ default:
1149
+ continue;
1150
+ }
1151
+ const totalPins = pins.length;
1152
+ pins.forEach((pin, index) => {
1153
+ let x = getX(index, totalPins);
1154
+ let y = getY(index, totalPins);
1155
+ if (direction === "bottom-to-top" || direction === "right-to-left") {
1156
+ ;
1157
+ [x, y] = [
1158
+ getX(totalPins - 1 - index, totalPins),
1159
+ getY(totalPins - 1 - index, totalPins)
1160
+ ];
1161
+ }
1162
+ const endX = getEndX(x);
1163
+ const endY = getEndY(y);
1164
+ children.push({
1165
+ name: "line",
1166
+ type: "element",
1167
+ attributes: {
1168
+ class: "component-pin",
1169
+ x1: x,
1170
+ y1: y,
1171
+ x2: endX,
1172
+ y2: endY
1173
+ }
1174
+ });
1175
+ children.push({
1176
+ name: "circle",
1177
+ type: "element",
1178
+ attributes: {
1179
+ class: "component-pin",
1180
+ cx: endX,
1181
+ cy: endY,
1182
+ r: circleRadius
1183
+ }
1184
+ });
1185
+ const labelKey = `pin${pin}`;
1186
+ if (portLabels && labelKey in portLabels) {
1187
+ let labelTransform = "";
1188
+ if (isVertical) {
1189
+ labelTransform = `rotate(${side === "top_side" ? -90 : 270}, ${getLabelX(x)}, ${getLabelY(y)})`;
1190
+ }
1191
+ children.push({
1192
+ name: "text",
1193
+ type: "element",
1194
+ attributes: {
1195
+ class: "port-label",
1196
+ x: getLabelX(x),
1197
+ y: getLabelY(y),
1198
+ "text-anchor": labelAnchor,
1199
+ "dominant-baseline": "middle",
1200
+ "font-size": "0.2",
1201
+ transform: labelTransform
1202
+ },
1203
+ children: [{ type: "text", value: portLabels[labelKey] }]
1204
+ });
1205
+ }
1206
+ children.push({
1207
+ name: "text",
1208
+ type: "element",
1209
+ attributes: {
1210
+ class: "pin-number",
1211
+ x: endX,
1212
+ y: endY + (side === "bottom_side" ? 0.15 : -0.15),
1213
+ "text-anchor": "middle",
1214
+ "dominant-baseline": "middle",
1215
+ "font-size": "0.15"
1216
+ },
1217
+ children: [{ type: "text", value: pin.toString() }]
1218
+ });
1219
+ });
1220
+ }
1221
+ }
1222
+ return {
1223
+ name: "g",
1224
+ type: "element",
1225
+ attributes: { transform },
1226
+ children
1227
+ };
1228
+ }
1229
+
1230
+ // lib/sch/convert-circuit-json-to-schematic-svg.ts
1231
+ function convertCircuitJsonToSchematicSvg(soup, options) {
747
1232
  let minX = Number.POSITIVE_INFINITY;
748
1233
  let minY = Number.POSITIVE_INFINITY;
749
1234
  let maxX = Number.NEGATIVE_INFINITY;
@@ -756,8 +1241,6 @@ function convertCircuitJsonToSchematicSvg(soup) {
756
1241
  } else if (item.type === "schematic_port") {
757
1242
  updateBounds(item.center, { width: portSize, height: portSize }, 0);
758
1243
  portPositions.set(item.schematic_port_id, item.center);
759
- } else if (item.type === "schematic_text") {
760
- updateBounds(item.position, { width: 0, height: 0 }, 0);
761
1244
  }
762
1245
  }
763
1246
  const height = maxY - minY;
@@ -775,34 +1258,19 @@ function convertCircuitJsonToSchematicSvg(soup) {
775
1258
  flippedCenter,
776
1259
  component.size,
777
1260
  component.rotation || 0,
778
- component.symbol_name
1261
+ component.symbol_name,
1262
+ component.port_arrangement,
1263
+ component.port_labels,
1264
+ component.source_component_id,
1265
+ soup
779
1266
  );
780
1267
  svgChildren.push(svg);
781
1268
  componentMap.set(component.schematic_component_id, component);
782
1269
  }
783
- for (const port of soup.filter((item) => item.type === "schematic_port")) {
784
- const flippedCenter = { x: port.center.x, y: flipY(port.center.y) };
785
- const svg = createSchematicPort(flippedCenter);
786
- svgChildren.push(svg);
787
- const component = componentMap.get(port.schematic_component_id);
788
- if (component) {
789
- const line = createPortToComponentLine(
790
- flippedCenter,
791
- component,
792
- port.facing_direction || "right"
793
- );
794
- svgChildren.push(line);
795
- }
796
- }
797
1270
  for (const trace of soup.filter((item) => item.type === "schematic_trace")) {
798
1271
  const svg = createSchematicTrace(trace, flipY, portPositions);
799
1272
  if (svg) svgChildren.push(svg);
800
1273
  }
801
- for (const text of soup.filter((item) => item.type === "schematic_text")) {
802
- const flippedPosition = { x: text.position.x, y: flipY(text.position.y) };
803
- const svg = createSchematicText(text, flippedPosition);
804
- svgChildren.push(svg);
805
- }
806
1274
  const padding = 1;
807
1275
  const width = maxX - minX + 2 * padding;
808
1276
  const viewBox = `${minX - padding} ${minY - padding} ${width} ${height + 2 * padding}`;
@@ -812,9 +1280,9 @@ function convertCircuitJsonToSchematicSvg(soup) {
812
1280
  attributes: {
813
1281
  xmlns: "http://www.w3.org/2000/svg",
814
1282
  viewBox,
815
- width: "1200",
816
- height: "600",
817
- style: "background-color: #fff;"
1283
+ width: options?.width ?? "1200",
1284
+ height: options?.height ?? "600",
1285
+ style: `background-color: ${colorMap.schematic.background}`
818
1286
  },
819
1287
  children: [
820
1288
  {
@@ -824,11 +1292,14 @@ function convertCircuitJsonToSchematicSvg(soup) {
824
1292
  {
825
1293
  type: "text",
826
1294
  value: `
827
- .component { fill: none; stroke: red; stroke-width: 0.03; }
828
- .component-pin { fill: none; stroke: red; stroke-width: 0.03; }
829
- .trace { stroke: green; stroke-width: 0.03; fill: none; }
830
- .text { font-family: Arial, sans-serif; font-size: 0.2px; }
831
- .port { fill: none; stroke: blue; stroke-width: 0.03; }
1295
+ .component { fill: none; stroke: ${colorMap.schematic.component_outline}; stroke-width: 0.03; }
1296
+ .chip { fill: ${colorMap.schematic.component_body}; stroke: ${colorMap.schematic.component_outline}; stroke-width: 0.03; }
1297
+ .component-pin { fill: none; stroke: ${colorMap.schematic.component_outline}; stroke-width: 0.02; }
1298
+ .trace { stroke: ${colorMap.schematic.wire}; stroke-width: 0.02; fill: none; }
1299
+ .text { font-family: Arial, sans-serif; font-size: 0.2px; fill: ${colorMap.schematic.wire}; }
1300
+ .pin-number { font-size: 0.15px; fill: ${colorMap.schematic.pin_number}; }
1301
+ .port-label { fill: ${colorMap.schematic.reference}; }
1302
+ .component-name { font-size: 0.25px; fill: ${colorMap.schematic.reference}; }
832
1303
  `
833
1304
  }
834
1305
  ]
@@ -836,7 +1307,54 @@ function convertCircuitJsonToSchematicSvg(soup) {
836
1307
  ...svgChildren
837
1308
  ]
838
1309
  };
839
- return stringify2({ value: "", ...svgObject });
1310
+ return stringify2({
1311
+ value: "",
1312
+ ...svgObject,
1313
+ attributes: {
1314
+ ...svgObject.attributes,
1315
+ width: svgObject.attributes.width.toString(),
1316
+ height: svgObject.attributes.height.toString()
1317
+ }
1318
+ });
1319
+ function createSchematicTrace(trace, flipY2, portPositions2) {
1320
+ const edges = trace.edges;
1321
+ if (edges.length === 0) return null;
1322
+ let path = "";
1323
+ edges.forEach((edge, index) => {
1324
+ const fromPoint = edge.from.ti !== void 0 ? portPositions2.get(edge.from.ti) : edge.from;
1325
+ const toPoint = edge.to.ti !== void 0 ? portPositions2.get(edge.to.ti) : edge.to;
1326
+ if (!fromPoint || !toPoint) {
1327
+ return;
1328
+ }
1329
+ const fromCoord = `${fromPoint.x - 0.15} ${flipY2(fromPoint.y)}`;
1330
+ const toCoord = `${toPoint.x + 0.15} ${flipY2(toPoint.y)}`;
1331
+ if (index === 0) {
1332
+ path += `M ${fromCoord} L ${toCoord}`;
1333
+ } else {
1334
+ path += ` L ${toCoord}`;
1335
+ }
1336
+ });
1337
+ if (trace.to_schematic_port_id) {
1338
+ const finalPort = portPositions2.get(trace.to_schematic_port_id);
1339
+ if (finalPort) {
1340
+ const lastFromPoint = path.split("M")[1]?.split("L")[0];
1341
+ const lastEdge = edges[edges.length - 1];
1342
+ const lastPoint = lastEdge.to.ti !== void 0 ? portPositions2.get(lastEdge.to.ti) : lastEdge.to;
1343
+ if (lastPoint.x !== finalPort.x || lastPoint.y !== finalPort.y) {
1344
+ const finalCoord = `${finalPort.x} ${flipY2(finalPort.y)}`;
1345
+ path += ` M ${lastFromPoint} L ${finalCoord}`;
1346
+ }
1347
+ }
1348
+ }
1349
+ return path ? {
1350
+ name: "path",
1351
+ type: "element",
1352
+ attributes: {
1353
+ class: "trace",
1354
+ d: path
1355
+ }
1356
+ } : null;
1357
+ }
840
1358
  function updateBounds(center, size, rotation) {
841
1359
  const corners = [
842
1360
  { x: -size.width / 2, y: -size.height / 2 },
@@ -854,192 +1372,6 @@ function convertCircuitJsonToSchematicSvg(soup) {
854
1372
  }
855
1373
  }
856
1374
  }
857
- function createSchematicComponent(center, size, rotation, symbolName) {
858
- const transform = `translate(${center.x}, ${center.y}) rotate(${rotation * 180 / Math.PI})`;
859
- if (symbolName) {
860
- const symbol = symbols[symbolName];
861
- const paths = symbol.primitives.filter((p) => p.type === "path");
862
- const updatedSymbol = {
863
- ...symbol,
864
- primitives: paths
865
- };
866
- const svg = parseSync(
867
- getSvg(updatedSymbol, {
868
- width: size.width,
869
- height: size.height
870
- })
871
- );
872
- const pathElements = svg.children.filter(
873
- (child) => child.name === "path" && child.attributes.fill !== "green"
874
- ).map((path) => {
875
- const currentStrokeWidth = Number.parseFloat(
876
- path.attributes["stroke-width"] || "0.02"
877
- );
878
- const newStrokeWidth = (currentStrokeWidth * 1.5).toString();
879
- return {
880
- ...path,
881
- attributes: {
882
- ...path.attributes,
883
- stroke: path.attributes.stroke === "black" ? "red" : path.attributes.stroke,
884
- "stroke-width": newStrokeWidth
885
- }
886
- };
887
- });
888
- const viewBoxAttr = svg.attributes.viewBox;
889
- if (typeof viewBoxAttr === "undefined") {
890
- throw new Error("SVG does not have a viewBox attribute.");
891
- }
892
- const viewBox = viewBoxAttr.split(" ").map(Number);
893
- if (viewBox.length < 4) {
894
- throw new Error("Invalid viewBox attribute.");
895
- }
896
- const [minX, minY, width = 0, height = 0] = viewBox;
897
- const scaleX = size.width / (width || 1);
898
- const scaleY = size.height / (height || 1);
899
- const scale2 = Math.min(scaleX, scaleY);
900
- const adjustedTransform = `${transform} scale(${scale2}) translate(${-(minX ?? 0) - width / 2}, ${-(minY ?? 0) - height / 2})`;
901
- return {
902
- name: "g",
903
- type: "element",
904
- attributes: { transform: adjustedTransform },
905
- children: pathElements
906
- };
907
- }
908
- return {
909
- name: "g",
910
- type: "element",
911
- attributes: { transform },
912
- children: [
913
- {
914
- name: "rect",
915
- type: "element",
916
- attributes: {
917
- class: "component",
918
- x: (-size.width / 2).toString(),
919
- y: (-size.height / 2).toString(),
920
- width: size.width.toString(),
921
- height: size.height.toString()
922
- }
923
- }
924
- ]
925
- };
926
- }
927
- function createSchematicPort(center) {
928
- const portSize = 0.2;
929
- const x = center.x - portSize / 2;
930
- const y = center.y - portSize / 2;
931
- return {
932
- name: "rect",
933
- type: "element",
934
- attributes: {
935
- class: "port",
936
- x: x.toString(),
937
- y: y.toString(),
938
- width: portSize.toString(),
939
- height: portSize.toString()
940
- }
941
- };
942
- }
943
- function createPortToComponentLine(portCenter, component, facingDirection) {
944
- const componentCenter = { x: component.center.x, y: portCenter.y };
945
- const halfWidth = component.size.width / 2;
946
- const halfHeight = component.size.height / 2;
947
- let endX = portCenter.x;
948
- let endY = portCenter.y;
949
- switch (facingDirection) {
950
- case "left":
951
- endX = componentCenter.x - halfWidth;
952
- break;
953
- case "right":
954
- endX = componentCenter.x + halfWidth;
955
- break;
956
- case "up":
957
- endY = componentCenter.y - halfHeight;
958
- break;
959
- case "down":
960
- endY = componentCenter.y + halfHeight;
961
- break;
962
- }
963
- return {
964
- name: "line",
965
- type: "element",
966
- attributes: {
967
- class: "component-pin",
968
- x1: portCenter.x.toString(),
969
- y1: portCenter.y.toString(),
970
- x2: endX.toString(),
971
- y2: endY.toString()
972
- }
973
- };
974
- }
975
- function createSchematicTrace(trace, flipY, portPositions) {
976
- const edges = trace.edges;
977
- if (edges.length === 0) return null;
978
- let path = "";
979
- edges.forEach((edge, index) => {
980
- const fromPoint = edge.from.ti !== void 0 ? portPositions.get(edge.from.ti) : edge.from;
981
- const toPoint = edge.to.ti !== void 0 ? portPositions.get(edge.to.ti) : edge.to;
982
- if (!fromPoint || !toPoint) {
983
- return;
984
- }
985
- const fromCoord = `${fromPoint.x} ${flipY(fromPoint.y)}`;
986
- const toCoord = `${toPoint.x} ${flipY(toPoint.y)}`;
987
- if (index === 0) {
988
- path += `M ${fromCoord} L ${toCoord}`;
989
- } else {
990
- path += ` L ${toCoord}`;
991
- }
992
- });
993
- if (trace.to_schematic_port_id) {
994
- const finalPort = portPositions.get(trace.to_schematic_port_id);
995
- if (finalPort) {
996
- const lastFromPoint = path.split("M")[1]?.split("L")[0];
997
- const lastEdge = edges[edges.length - 1];
998
- const lastPoint = lastEdge.to.ti !== void 0 ? portPositions.get(lastEdge.to.ti) : lastEdge.to;
999
- if (lastPoint.x !== finalPort.x || lastPoint.y !== finalPort.y) {
1000
- const finalCoord = `${finalPort.x} ${flipY(finalPort.y)}`;
1001
- path += ` M ${lastFromPoint} L ${finalCoord}`;
1002
- }
1003
- }
1004
- }
1005
- return path ? {
1006
- name: "path",
1007
- type: "element",
1008
- attributes: {
1009
- class: "trace",
1010
- d: path
1011
- }
1012
- } : null;
1013
- }
1014
- function createSchematicText(text, position) {
1015
- return {
1016
- name: "text",
1017
- type: "element",
1018
- attributes: {
1019
- class: "text",
1020
- x: position.x.toString(),
1021
- y: position.y.toString(),
1022
- "text-anchor": getTextAnchor(text.anchor),
1023
- "dominant-baseline": "middle"
1024
- },
1025
- children: [
1026
- {
1027
- type: "text",
1028
- value: text.text ? text.text : ""
1029
- }
1030
- ]
1031
- };
1032
- }
1033
- function getTextAnchor(anchor) {
1034
- switch (anchor) {
1035
- case "left":
1036
- return "start";
1037
- case "right":
1038
- return "end";
1039
- default:
1040
- return "middle";
1041
- }
1042
- }
1043
1375
  var circuitJsonToSchematicSvg = convertCircuitJsonToSchematicSvg;
1044
1376
  export {
1045
1377
  circuitJsonToPcbSvg,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/pcb/convert-circuit-json-to-pcb-svg.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-fabrication-note-path.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-fabrication-note-text.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-plated-hole.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-silkscreen-path.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-silkscreen-text.ts","../lib/utils/pairs.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-trace.ts","../lib/pcb/layer-name-to-color.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-smt-pads.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-board.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-via.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-hole.ts","../lib/pcb/colors.ts","../lib/sch/convert-circuit-json-to-schematic-svg.ts"],"sourcesContent":["import type { Point, AnyCircuitElement } from \"circuit-json\"\nimport { type INode as SvgObject, stringify } from \"svgson\"\nimport {\n type Matrix,\n applyToPoint,\n compose,\n scale,\n translate,\n} from \"transformation-matrix\"\nimport { createSvgObjectsFromPcbFabricationNotePath } from \"./svg-object-fns/create-svg-objects-from-pcb-fabrication-note-path\"\nimport { createSvgObjectsFromPcbFabricationNoteText } from \"./svg-object-fns/create-svg-objects-from-pcb-fabrication-note-text\"\nimport { createSvgObjectsFromPcbPlatedHole } from \"./svg-object-fns/create-svg-objects-from-pcb-plated-hole\"\nimport { createSvgObjectsFromPcbSilkscreenPath } from \"./svg-object-fns/create-svg-objects-from-pcb-silkscreen-path\"\nimport { createSvgObjectsFromPcbSilkscreenText } from \"./svg-object-fns/create-svg-objects-from-pcb-silkscreen-text\"\nimport { createSvgObjectsFromPcbTrace } from \"./svg-object-fns/create-svg-objects-from-pcb-trace\"\nimport { createSvgObjectsFromSmtPad } from \"./svg-object-fns/create-svg-objects-from-smt-pads\"\nimport { createSvgObjectsFromPcbBoard } from \"./svg-object-fns/create-svg-objects-from-pcb-board\"\nimport { createSvgObjectsFromPcbVia } from \"./svg-object-fns/create-svg-objects-from-pcb-via\"\nimport { createSvgObjectsFromPcbHole } from \"./svg-object-fns/create-svg-objects-from-pcb-hole\"\n\nconst OBJECT_ORDER: AnyCircuitElement[\"type\"][] = [\n \"pcb_plated_hole\",\n \"pcb_fabrication_note_text\",\n \"pcb_fabrication_note_path\",\n \"pcb_silkscreen_text\",\n \"pcb_silkscreen_path\",\n \"pcb_via\",\n \"pcb_trace\",\n \"pcb_smtpad\",\n \"pcb_component\",\n \"pcb_board\",\n]\n\ninterface PointObjectNotation {\n x: number\n y: number\n}\n\ninterface Options {\n width?: number\n height?: number\n}\n\nexport function convertCircuitJsonToPcbSvg(\n soup: AnyCircuitElement[],\n options?: Options,\n): string {\n let minX = Number.POSITIVE_INFINITY\n let minY = Number.POSITIVE_INFINITY\n let maxX = Number.NEGATIVE_INFINITY\n let maxY = Number.NEGATIVE_INFINITY\n\n // Process all elements to determine bounds\n for (const item of soup) {\n if (item.type === \"pcb_board\") {\n if (\n item.outline &&\n Array.isArray(item.outline) &&\n item.outline.length >= 3\n )\n updateBoundsToIncludeOutline(item.outline)\n else if (\"center\" in item && \"width\" in item && \"height\" in item)\n updateBounds(item.center, item.width, item.height)\n } else if (\"x\" in item && \"y\" in item) {\n updateBounds({ x: item.x, y: item.y }, 0, 0)\n } else if (\"route\" in item) {\n updateTraceBounds(item.route)\n }\n }\n\n const padding = 1 // Reduced padding for tighter boundary\n const circuitWidth = maxX - minX + 2 * padding\n const circuitHeight = maxY - minY + 2 * padding\n\n const svgWidth = options?.width ?? 800\n const svgHeight = options?.height ?? 600\n const paths: PointObjectNotation[][] = []\n for (const item of soup) {\n if (\"route\" in item && item.route !== undefined) {\n paths.push(item.route as PointObjectNotation[])\n }\n }\n\n // Calculate scale factor to fit the circuit within the SVG, maintaining aspect ratio\n const scaleX = svgWidth / circuitWidth\n const scaleY = svgHeight / circuitHeight\n const scaleFactor = Math.min(scaleX, scaleY)\n\n // Calculate centering offsets\n const offsetX = (svgWidth - circuitWidth * scaleFactor) / 2\n const offsetY = (svgHeight - circuitHeight * scaleFactor) / 2\n\n const transform = compose(\n translate(\n offsetX - minX * scaleFactor + padding * scaleFactor,\n svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor,\n ),\n scale(scaleFactor, -scaleFactor), // Flip in y-direction\n )\n\n const svgObjects = soup\n .sort(\n (a, b) =>\n (OBJECT_ORDER.indexOf(b.type) ?? 9999) -\n (OBJECT_ORDER.indexOf(a.type) ?? 9999),\n )\n .flatMap((item) => createSvgObjects(item, transform))\n\n let strokeWidth = String(0.05 * scaleFactor)\n\n for (const element of soup) {\n if (\"stroke_width\" in element) {\n strokeWidth = String(scaleFactor * element.stroke_width)\n break\n }\n }\n\n const svgObject: SvgObject = {\n name: \"svg\",\n type: \"element\",\n attributes: {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: svgWidth.toString(),\n height: svgHeight.toString(),\n },\n value: \"\",\n children: [\n {\n name: \"style\",\n type: \"element\",\n children: [\n {\n type: \"text\",\n value: `\n .boundary { fill: #000; }\n .pcb-board { fill: none; }\n .pcb-trace { fill: none; }\n .pcb-hole-outer { fill: rgb(200, 52, 52); }\n .pcb-hole-inner { fill: rgb(255, 38, 226); }\n .pcb-pad { }\n .pcb-boundary { fill: none; stroke: #fff; stroke-width: 0.3; }\n .pcb-silkscreen { fill: none; }\n .pcb-silkscreen-top { stroke: #f2eda1; }\n .pcb-silkscreen-bottom { stroke: #f2eda1; }\n .pcb-silkscreen-text { fill: #f2eda1; }\n `,\n },\n ],\n },\n {\n name: \"rect\",\n type: \"element\",\n attributes: {\n class: \"boundary\",\n x: \"0\",\n y: \"0\",\n width: svgWidth.toString(),\n height: svgHeight.toString(),\n },\n },\n createSvgObjectFromPcbBoundary(transform, minX, minY, maxX, maxY),\n ...svgObjects,\n ].filter((child): child is SvgObject => child !== null),\n }\n\n try {\n return stringify(svgObject as SvgObject)\n } catch (error) {\n console.error(\"Error stringifying SVG object:\", error)\n throw error\n }\n\n function updateBounds(center: any, width: any, height: any) {\n const halfWidth = width / 2\n const halfHeight = height / 2\n minX = Math.min(minX, center.x - halfWidth)\n minY = Math.min(minY, center.y - halfHeight)\n maxX = Math.max(maxX, center.x + halfWidth)\n maxY = Math.max(maxY, center.y + halfHeight)\n }\n\n function updateBoundsToIncludeOutline(outline: Point[]) {\n for (const point of outline) {\n minX = Math.min(minX, point.x)\n minY = Math.min(minY, point.y)\n maxX = Math.max(maxX, point.x)\n maxY = Math.max(maxY, point.y)\n }\n }\n\n function updateTraceBounds(route: any[]) {\n for (const point of route) {\n minX = Math.min(minX, point.x)\n minY = Math.min(minY, point.y)\n maxX = Math.max(maxX, point.x)\n maxY = Math.max(maxY, point.y)\n }\n }\n}\n\nfunction createSvgObjects(\n elm: AnyCircuitElement,\n transform: Matrix,\n): SvgObject[] {\n switch (elm.type) {\n case \"pcb_component\":\n return [createSvgObjectsFromPcbComponent(elm, transform)].filter(Boolean)\n case \"pcb_trace\":\n return createSvgObjectsFromPcbTrace(elm, transform)\n case \"pcb_plated_hole\":\n return createSvgObjectsFromPcbPlatedHole(elm, transform).filter(Boolean)\n case \"pcb_hole\":\n return createSvgObjectsFromPcbHole(elm, transform)\n case \"pcb_smtpad\":\n return createSvgObjectsFromSmtPad(elm, transform)\n case \"pcb_silkscreen_text\":\n return createSvgObjectsFromPcbSilkscreenText(elm, transform)\n case \"pcb_fabrication_note_path\":\n return createSvgObjectsFromPcbFabricationNotePath(elm, transform)\n case \"pcb_fabrication_note_text\":\n return createSvgObjectsFromPcbFabricationNoteText(elm, transform)\n case \"pcb_silkscreen_path\":\n return createSvgObjectsFromPcbSilkscreenPath(elm, transform)\n case \"pcb_board\":\n return createSvgObjectsFromPcbBoard(elm, transform)\n case \"pcb_via\":\n return createSvgObjectsFromPcbVia(elm, transform)\n default:\n return []\n }\n}\n\nfunction createSvgObjectsFromPcbComponent(component: any, transform: any): any {\n const { center, width, height, rotation = 0 } = component\n const [x, y] = applyToPoint(transform, [center.x, center.y])\n const scaledWidth = width * Math.abs(transform.a)\n const scaledHeight = height * Math.abs(transform.d)\n const transformStr = `translate(${x}, ${y}) rotate(${-rotation}) scale(1, -1)`\n\n return {\n name: \"g\",\n type: \"element\",\n attributes: { transform: transformStr },\n children: [\n {\n name: \"rect\",\n type: \"element\",\n attributes: {\n class: \"pcb-component\",\n x: (-scaledWidth / 2).toString(),\n y: (-scaledHeight / 2).toString(),\n width: scaledWidth.toString(),\n height: scaledHeight.toString(),\n },\n },\n {\n name: \"rect\",\n type: \"element\",\n attributes: {\n class: \"pcb-component-outline\",\n x: (-scaledWidth / 2).toString(),\n y: (-scaledHeight / 2).toString(),\n width: scaledWidth.toString(),\n height: scaledHeight.toString(),\n },\n },\n ],\n }\n}\n\nfunction createSvgObjectFromPcbBoundary(\n transform: any,\n minX: number,\n minY: number,\n maxX: number,\n maxY: number,\n): SvgObject {\n const [x1, y1] = applyToPoint(transform, [minX, minY])\n const [x2, y2] = applyToPoint(transform, [maxX, maxY])\n const width = Math.abs(x2 - x1)\n const height = Math.abs(y2 - y1)\n const x = Math.min(x1, x2)\n const y = Math.min(y1, y2)\n return {\n name: \"rect\",\n type: \"element\",\n value: \"\",\n children: [],\n attributes: {\n class: \"pcb-boundary\",\n x: x.toString(),\n y: y.toString(),\n width: width.toString(),\n height: height.toString(),\n },\n }\n}\n\n/**\n * @deprecated use `convertCircuitJsonToPcbSvg` instead\n */\nexport const circuitJsonToPcbSvg = convertCircuitJsonToPcbSvg\n","import type { PcbSilkscreenPath, PcbFabricationNotePath } from \"circuit-json\"\nimport { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport type { SvgObject } from \"lib/svg-object\"\n\nexport function createSvgObjectsFromPcbFabricationNotePath(\n fabNotePath: PcbFabricationNotePath,\n transform: Matrix,\n): SvgObject[] {\n if (!fabNotePath.route || !Array.isArray(fabNotePath.route)) return []\n\n // Close the path if the first and last points are the same\n const firstPoint = fabNotePath.route[0]\n const lastPoint = fabNotePath.route[fabNotePath.route.length - 1]\n const isClosed =\n firstPoint!.x === lastPoint!.x && firstPoint!.y === lastPoint!.y\n\n const path =\n fabNotePath.route\n .slice(0, isClosed ? -1 : undefined)\n .map((point: any, index: number) => {\n const [x, y] = applyToPoint(transform, [point.x, point.y])\n return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`\n })\n .join(\" \") + (isClosed ? \" Z\" : \"\")\n\n return [\n {\n name: \"path\",\n type: \"element\",\n attributes: {\n class: \"pcb-fabrication-note-path\",\n stroke: fabNotePath.color || \"rgba(255,255,255,0.5)\",\n fill: \"none\",\n d: path,\n \"stroke-width\": (\n fabNotePath.stroke_width * Math.abs(transform.a)\n ).toString(),\n \"data-pcb-component-id\": fabNotePath.pcb_component_id,\n \"data-pcb-fabrication-note-path-id\":\n fabNotePath.pcb_fabrication_note_path_id,\n },\n value: \"\",\n children: [],\n },\n ]\n}\n","import type { PcbFabricationNoteText } from \"circuit-json\"\nimport type { INode as SvgObject } from \"svgson\"\nimport { toString as matrixToString } from \"transformation-matrix\"\nimport {\n type Matrix,\n applyToPoint,\n compose,\n rotate,\n translate,\n} from \"transformation-matrix\"\n\nexport function createSvgObjectsFromPcbFabricationNoteText(\n pcbFabNoteText: PcbFabricationNoteText,\n transform: Matrix,\n): SvgObject[] {\n const {\n anchor_position,\n anchor_alignment,\n text,\n font_size = 1,\n layer = \"top\",\n color,\n } = pcbFabNoteText\n\n if (\n !anchor_position ||\n typeof anchor_position.x !== \"number\" ||\n typeof anchor_position.y !== \"number\"\n ) {\n console.error(\"Invalid anchor_position:\", anchor_position)\n return []\n }\n\n const [transformedX, transformedY] = applyToPoint(transform, [\n anchor_position.x,\n anchor_position.y,\n ])\n const transformedFontSize = font_size * Math.abs(transform.a)\n\n // Remove ${} from text value and handle undefined text\n\n // Create a composite transformation\n const textTransform = compose(\n translate(transformedX, transformedY), // TODO do anchor_alignment\n rotate(Math.PI / 180), // Convert degrees to radians\n )\n\n const svgObject: SvgObject = {\n name: \"text\",\n type: \"element\",\n attributes: {\n x: \"0\",\n y: \"0\",\n \"font-family\": \"Arial, sans-serif\",\n \"font-size\": transformedFontSize.toString(),\n \"text-anchor\": \"middle\",\n \"dominant-baseline\": \"central\",\n transform: matrixToString(textTransform),\n class: \"pcb-fabrication-note-text\",\n fill: color || \"rgba(255,255,255,0.5)\",\n },\n children: [\n {\n type: \"text\",\n value: text,\n name: \"\",\n attributes: {},\n children: [],\n },\n ],\n value: \"\",\n }\n\n return [svgObject]\n}\n","import type { PCBPlatedHole } from \"circuit-json\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { SvgObject } from \"lib/svg-object\"\n\nexport function createSvgObjectsFromPcbPlatedHole(\n hole: PCBPlatedHole,\n transform: any,\n): SvgObject[] {\n const [x, y] = applyToPoint(transform, [hole.x, hole.y])\n\n if (hole.shape === \"pill\") {\n const scaledOuterWidth = hole.outer_width * Math.abs(transform.a)\n const scaledOuterHeight = hole.outer_height * Math.abs(transform.a)\n const scaledHoleWidth = hole.hole_width * Math.abs(transform.a)\n const scaledHoleHeight = hole.hole_height * Math.abs(transform.a)\n\n const outerRadiusX = scaledOuterWidth / 2\n const outerRadiusY = scaledOuterHeight / 2\n const innerRadiusX = scaledHoleWidth / 2\n const innerRadiusY = scaledHoleHeight / 2\n const straightLength = scaledOuterHeight - scaledOuterWidth\n\n return [\n {\n name: \"g\",\n type: \"element\",\n children: [\n // Outer pill shape\n {\n name: \"path\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole-outer\",\n d:\n `M${x - outerRadiusX},${y - straightLength / 2} ` +\n `v${straightLength} ` +\n `a${outerRadiusX},${outerRadiusX} 0 0 0 ${scaledOuterWidth},0 ` +\n `v-${straightLength} ` +\n `a${outerRadiusX},${outerRadiusX} 0 0 0 -${scaledOuterWidth},0 z`,\n },\n value: \"\",\n children: [],\n },\n // Inner pill shape\n {\n name: \"path\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole-inner\",\n d:\n `M${x - innerRadiusX},${y - (scaledHoleHeight - scaledHoleWidth) / 2} ` +\n `v${scaledHoleHeight - scaledHoleWidth} ` +\n `a${innerRadiusX},${innerRadiusX} 0 0 0 ${scaledHoleWidth},0 ` +\n `v-${scaledHoleHeight - scaledHoleWidth} ` +\n `a${innerRadiusX},${innerRadiusX} 0 0 0 -${scaledHoleWidth},0 z`,\n },\n value: \"\",\n children: [],\n },\n ],\n value: \"\",\n attributes: {},\n },\n ]\n }\n // Fallback to circular hole if not pill-shaped\n if (hole.shape === \"circle\") {\n const scaledOuterWidth = hole.outer_diameter * Math.abs(transform.a)\n const scaledOuterHeight = hole.outer_diameter * Math.abs(transform.a)\n const scaledHoleWidth = hole.hole_diameter * Math.abs(transform.a)\n const scaledHoleHeight = hole.hole_diameter * Math.abs(transform.a)\n\n const outerRadius = Math.min(scaledOuterWidth, scaledOuterHeight) / 2\n const innerRadius = Math.min(scaledHoleWidth, scaledHoleHeight) / 2\n return [\n {\n name: \"g\",\n type: \"element\",\n children: [\n {\n name: \"circle\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole-outer\",\n cx: x.toString(),\n cy: y.toString(),\n r: outerRadius.toString(),\n },\n value: \"\",\n children: [],\n },\n {\n name: \"circle\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole-inner\",\n cx: x.toString(),\n cy: y.toString(),\n r: innerRadius.toString(),\n },\n value: \"\",\n children: [],\n },\n ],\n value: \"\",\n attributes: {},\n },\n ]\n }\n return []\n}\n","import type { PcbSilkscreenPath } from \"circuit-json\"\nimport { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport type { SvgObject } from \"lib/svg-object\"\n\nexport function createSvgObjectsFromPcbSilkscreenPath(\n silkscreenPath: PcbSilkscreenPath,\n transform: Matrix,\n): SvgObject[] {\n if (!silkscreenPath.route || !Array.isArray(silkscreenPath.route)) return []\n\n let path = silkscreenPath.route\n .map((point: any, index: number) => {\n const [x, y] = applyToPoint(transform, [point.x, point.y])\n return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`\n })\n .join(\" \")\n\n // Close the path if it's not already closed\n const firstPoint = silkscreenPath.route[0]\n const lastPoint = silkscreenPath.route[silkscreenPath.route.length - 1]\n if (firstPoint!.x !== lastPoint!.x || firstPoint!.y !== lastPoint!.y) {\n path += \" Z\"\n }\n return [\n {\n name: \"path\",\n type: \"element\",\n attributes: {\n class: `pcb-silkscreen pcb-silkscreen-${silkscreenPath.layer}`,\n d: path,\n \"stroke-width\": (\n silkscreenPath.stroke_width * Math.abs(transform.a)\n ).toString(),\n \"data-pcb-component-id\": silkscreenPath.pcb_component_id,\n \"data-pcb-silkscreen-path-id\": silkscreenPath.pcb_silkscreen_path_id,\n },\n value: \"\",\n children: [],\n },\n ]\n}\n","import type { PcbSilkscreenText } from \"circuit-json\"\nimport type { INode as SvgObject } from \"svgson\"\nimport {\n type Matrix,\n applyToPoint,\n compose,\n rotate,\n translate,\n toString as matrixToString,\n} from \"transformation-matrix\"\n\nexport function createSvgObjectsFromPcbSilkscreenText(\n pcbSilkscreenText: PcbSilkscreenText,\n transform: Matrix,\n): SvgObject[] {\n const {\n anchor_position,\n text,\n font_size = 1,\n layer = \"top\",\n } = pcbSilkscreenText\n\n if (\n !anchor_position ||\n typeof anchor_position.x !== \"number\" ||\n typeof anchor_position.y !== \"number\"\n ) {\n console.error(\"Invalid anchor_position:\", anchor_position)\n return []\n }\n\n const [transformedX, transformedY] = applyToPoint(transform, [\n anchor_position.x,\n anchor_position.y,\n ])\n const transformedFontSize = font_size * Math.abs(transform.a)\n\n // Remove ${} from text value and handle undefined text\n\n // Create a composite transformation\n const textTransform = compose(\n translate(transformedX, transformedY),\n rotate(Math.PI / 180), // Convert degrees to radians\n )\n\n const svgObject: SvgObject = {\n name: \"text\",\n type: \"element\",\n attributes: {\n x: \"0\",\n y: \"0\",\n \"font-family\": \"Arial, sans-serif\",\n \"font-size\": transformedFontSize.toString(),\n \"text-anchor\": \"middle\",\n \"dominant-baseline\": \"central\",\n transform: matrixToString(textTransform),\n class: `pcb-silkscreen-text pcb-silkscreen-${layer}`,\n \"data-pcb-silkscreen-text-id\": pcbSilkscreenText.pcb_component_id,\n },\n children: [\n {\n type: \"text\",\n value: text,\n name: \"\",\n attributes: {},\n children: [],\n },\n ],\n value: \"\",\n }\n\n return [svgObject]\n}\n","/**\n * Return pairs of adjacent elements in an array.\n */\nexport function pairs<T>(arr: Array<T>): Array<[T, T]> {\n const result: Array<[T, T]> = []\n for (let i = 0; i < arr.length - 1; i++) {\n result.push([arr[i]!, arr[i + 1]!])\n }\n return result\n}\n","import type { PCBTrace } from \"circuit-json\"\nimport { pairs } from \"lib/utils/pairs\"\nimport type { INode as SvgObject } from \"svgson\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport { LAYER_NAME_TO_COLOR } from \"../layer-name-to-color\"\n\nexport function createSvgObjectsFromPcbTrace(\n trace: PCBTrace,\n transform: any,\n): SvgObject[] {\n if (!trace.route || !Array.isArray(trace.route) || trace.route.length < 2)\n return []\n\n const segments = pairs(trace.route)\n const svgObjects: SvgObject[] = []\n\n for (const [start, end] of segments) {\n const startPoint = applyToPoint(transform, [start.x, start.y])\n const endPoint = applyToPoint(transform, [end.x, end.y])\n\n const layer =\n \"layer\" in start ? start.layer : \"layer\" in end ? end.layer : null\n if (!layer) continue\n\n const layerColor =\n LAYER_NAME_TO_COLOR[layer as keyof typeof LAYER_NAME_TO_COLOR] ?? \"white\"\n\n const traceWidth =\n \"width\" in start ? start.width : \"width\" in end ? end.width : null\n\n svgObjects.push({\n name: \"path\",\n type: \"element\",\n value: \"\",\n children: [],\n attributes: {\n class: \"pcb-trace\",\n stroke: layerColor,\n d: `M ${startPoint[0]} ${startPoint[1]} L ${endPoint[0]} ${endPoint[1]}`,\n \"stroke-width\": traceWidth\n ? (traceWidth * Math.abs(transform.a)).toString()\n : \"0.3\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n \"shape-rendering\": \"crispEdges\",\n },\n })\n }\n return svgObjects\n}\n","/**\n * TODO use @tscircuit/pcb-colors when it's published\n */\nexport const LAYER_NAME_TO_COLOR = {\n top: \"rgb(200, 52, 52)\",\n bottom: \"rgb(77, 127, 196)\",\n}\n\nexport function layerNameToColor(layerName: string) {\n return (\n LAYER_NAME_TO_COLOR[layerName as keyof typeof LAYER_NAME_TO_COLOR] ??\n \"white\"\n )\n}\n","import type { PCBSMTPad } from \"circuit-json\"\nimport { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { layerNameToColor } from \"../layer-name-to-color\"\n\nexport function createSvgObjectsFromSmtPad(\n pad: PCBSMTPad,\n transform: Matrix,\n): any {\n const [x, y] = applyToPoint(transform, [pad.x, pad.y])\n\n if (pad.shape === \"rect\") {\n const width = pad.width * Math.abs(transform.a)\n const height = pad.height * Math.abs(transform.d)\n return [\n {\n name: \"rect\",\n type: \"element\",\n attributes: {\n class: \"pcb-pad\",\n fill: layerNameToColor(pad.layer),\n x: (x - width / 2).toString(),\n y: (y - height / 2).toString(),\n width: width.toString(),\n height: height.toString(),\n },\n },\n ]\n }\n // TODO implement smtpad circles/ovals etc.\n return []\n}\n","import type { PCBBoard, Point } from \"circuit-json\"\nimport { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport type { SvgObject } from \"lib/svg-object\"\n\nexport function createSvgObjectsFromPcbBoard(\n pcbBoard: PCBBoard,\n transform: Matrix,\n): SvgObject[] {\n const { width, height, center, outline } = pcbBoard\n\n let path: string\n if (outline && Array.isArray(outline) && outline.length >= 3) {\n path = outline\n .map((point: Point, index: number) => {\n const [x, y] = applyToPoint(transform, [point.x, point.y])\n return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`\n })\n .join(\" \")\n } else {\n const halfWidth = width / 2\n const halfHeight = height / 2\n\n const topLeft = applyToPoint(transform, [\n center.x - halfWidth,\n center.y - halfHeight,\n ])\n const topRight = applyToPoint(transform, [\n center.x + halfWidth,\n center.y - halfHeight,\n ])\n const bottomRight = applyToPoint(transform, [\n center.x + halfWidth,\n center.y + halfHeight,\n ])\n const bottomLeft = applyToPoint(transform, [\n center.x - halfWidth,\n center.y + halfHeight,\n ])\n\n path =\n `M ${topLeft[0]} ${topLeft[1]} ` +\n `L ${topRight[0]} ${topRight[1]} ` +\n `L ${bottomRight[0]} ${bottomRight[1]} ` +\n `L ${bottomLeft[0]} ${bottomLeft[1]}`\n }\n\n path += \" Z\"\n\n return [\n {\n name: \"path\",\n type: \"element\",\n value: \"\",\n children: [],\n attributes: {\n class: \"pcb-board\",\n d: path,\n stroke: \"rgba(255, 255, 255, 0.5)\",\n \"stroke-width\": (0.1 * Math.abs(transform.a)).toString(),\n },\n },\n ]\n}\n","import type { PCBVia } from \"circuit-json\"\nimport { applyToPoint } from \"transformation-matrix\"\n\nexport function createSvgObjectsFromPcbVia(hole: PCBVia, transform: any): any {\n const [x, y] = applyToPoint(transform, [hole.x, hole.y])\n const scaledOuterWidth = hole.outer_diameter * Math.abs(transform.a)\n const scaledOuterHeight = hole.outer_diameter * Math.abs(transform.a)\n const scaledHoleWidth = hole.hole_diameter * Math.abs(transform.a)\n const scaledHoleHeight = hole.hole_diameter * Math.abs(transform.a)\n\n const outerRadius = Math.min(scaledOuterWidth, scaledOuterHeight) / 2\n const innerRadius = Math.min(scaledHoleWidth, scaledHoleHeight) / 2\n return {\n name: \"g\",\n type: \"element\",\n children: [\n {\n name: \"circle\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole-outer\",\n cx: x.toString(),\n cy: y.toString(),\n r: outerRadius.toString(),\n },\n },\n {\n name: \"circle\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole-inner\",\n cx: x.toString(),\n cy: y.toString(),\n r: innerRadius.toString(),\n },\n },\n ],\n }\n}\n","import type { PCBHole } from \"circuit-json\"\nimport { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport type { SvgObject } from \"lib/svg-object\"\nimport { HOLE_COLOR } from \"../colors\"\n\nexport function createSvgObjectsFromPcbHole(\n hole: PCBHole,\n transform: Matrix,\n): SvgObject[] {\n const [x, y] = applyToPoint(transform, [hole.x, hole.y])\n\n if (hole.hole_shape === \"circle\" || hole.hole_shape === \"square\") {\n const scaledDiameter = hole.hole_diameter * Math.abs(transform.a)\n const radius = scaledDiameter / 2\n\n if (hole.hole_shape === \"circle\") {\n return [\n {\n name: \"circle\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole\",\n cx: x.toString(),\n cy: y.toString(),\n r: radius.toString(),\n fill: HOLE_COLOR,\n },\n children: [],\n value: \"\",\n },\n ]\n }\n // Square hole\n return [\n {\n name: \"rect\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole\",\n x: (x - radius).toString(),\n y: (y - radius).toString(),\n width: scaledDiameter.toString(),\n height: scaledDiameter.toString(),\n fill: HOLE_COLOR,\n },\n children: [],\n value: \"\",\n },\n ]\n }\n if (hole.hole_shape === \"oval\") {\n const scaledWidth = hole.hole_width * Math.abs(transform.a)\n const scaledHeight = hole.hole_height * Math.abs(transform.a)\n const rx = scaledWidth / 2\n const ry = scaledHeight / 2\n\n return [\n {\n name: \"ellipse\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole\",\n cx: x.toString(),\n cy: y.toString(),\n rx: rx.toString(),\n ry: ry.toString(),\n fill: HOLE_COLOR,\n },\n children: [],\n value: \"\",\n },\n ]\n }\n\n return []\n}\n","export const HOLE_COLOR = \"#FF26E2\"\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { getSvg, symbols } from \"schematic-symbols\"\nimport { parseSync, stringify } from \"svgson\"\n\nexport function convertCircuitJsonToSchematicSvg(\n soup: AnyCircuitElement[],\n): string {\n let minX = Number.POSITIVE_INFINITY\n let minY = Number.POSITIVE_INFINITY\n let maxX = Number.NEGATIVE_INFINITY\n let maxY = Number.NEGATIVE_INFINITY\n\n const portSize = 0.2\n const portPositions = new Map()\n\n // First pass: find the bounds and collect port positions\n for (const item of soup) {\n if (item.type === \"schematic_component\") {\n updateBounds(item.center, item.size, item.rotation || 0)\n } else if (item.type === \"schematic_port\") {\n updateBounds(item.center, { width: portSize, height: portSize }, 0)\n portPositions.set(item.schematic_port_id, item.center)\n } else if (item.type === \"schematic_text\") {\n updateBounds(item.position, { width: 0, height: 0 }, 0)\n }\n }\n\n const height = maxY - minY\n const flipY = (y: number) => height - (y - minY) + minY\n\n const svgChildren: any[] = []\n\n // Process components\n const componentMap = new Map()\n for (const component of soup.filter(\n (item) => item.type === \"schematic_component\",\n )) {\n const flippedCenter = {\n x: component.center.x,\n y: flipY(component.center.y),\n }\n const svg = createSchematicComponent(\n flippedCenter,\n component.size,\n component.rotation || 0,\n (component as any).symbol_name,\n )\n svgChildren.push(svg)\n componentMap.set(component.schematic_component_id, component)\n }\n\n // Process ports and add lines to component edges\n for (const port of soup.filter((item) => item.type === \"schematic_port\")) {\n const flippedCenter = { x: port.center.x, y: flipY(port.center.y) }\n const svg = createSchematicPort(flippedCenter)\n svgChildren.push(svg)\n\n const component = componentMap.get(port.schematic_component_id)\n if (component) {\n const line = createPortToComponentLine(\n flippedCenter,\n component,\n port.facing_direction || \"right\",\n )\n svgChildren.push(line)\n }\n }\n\n // Process schematic traces\n for (const trace of soup.filter((item) => item.type === \"schematic_trace\")) {\n const svg = createSchematicTrace(trace, flipY, portPositions)\n if (svg) svgChildren.push(svg)\n }\n\n // Process text\n for (const text of soup.filter((item) => item.type === \"schematic_text\")) {\n const flippedPosition = { x: text.position.x, y: flipY(text.position.y) }\n const svg = createSchematicText(text, flippedPosition)\n svgChildren.push(svg)\n }\n\n const padding = 1\n const width = maxX - minX + 2 * padding\n const viewBox = `${minX - padding} ${minY - padding} ${width} ${height + 2 * padding}`\n\n const svgObject = {\n name: \"svg\",\n type: \"element\",\n attributes: {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox,\n width: \"1200\",\n height: \"600\",\n style: \"background-color: #fff;\",\n },\n children: [\n {\n name: \"style\",\n type: \"element\",\n children: [\n {\n type: \"text\",\n value: `\n .component { fill: none; stroke: red; stroke-width: 0.03; }\n .component-pin { fill: none; stroke: red; stroke-width: 0.03; }\n .trace { stroke: green; stroke-width: 0.03; fill: none; }\n .text { font-family: Arial, sans-serif; font-size: 0.2px; }\n .port { fill: none; stroke: blue; stroke-width: 0.03; }\n `,\n },\n ],\n },\n ...svgChildren,\n ],\n }\n\n return stringify({ value: \"\", ...svgObject })\n\n function updateBounds(center: any, size: any, rotation: number) {\n const corners = [\n { x: -size.width / 2, y: -size.height / 2 },\n { x: size.width / 2, y: -size.height / 2 },\n { x: size.width / 2, y: size.height / 2 },\n { x: -size.width / 2, y: size.height / 2 },\n ]\n\n for (const corner of corners) {\n const rotatedX =\n corner.x * Math.cos(rotation) - corner.y * Math.sin(rotation) + center.x\n const rotatedY =\n corner.x * Math.sin(rotation) + corner.y * Math.cos(rotation) + center.y\n minX = Math.min(minX, rotatedX)\n minY = Math.min(minY, rotatedY)\n maxX = Math.max(maxX, rotatedX)\n maxY = Math.max(maxY, rotatedY)\n }\n }\n}\n\nfunction createSchematicComponent(\n center: { x: number; y: number },\n size: { width: number; height: number },\n rotation: number,\n symbolName?: string,\n): any {\n const transform = `translate(${center.x}, ${center.y}) rotate(${(rotation * 180) / Math.PI})`\n\n if (symbolName) {\n const symbol = (symbols as any)[symbolName]\n const paths = symbol.primitives.filter((p: any) => p.type === \"path\")\n const updatedSymbol = {\n ...symbol,\n primitives: paths,\n }\n const svg = parseSync(\n getSvg(updatedSymbol, {\n width: size.width,\n height: size.height,\n }),\n )\n\n // Filter out non-path elements and modify path colors\n const pathElements = svg.children\n .filter(\n (child: any) =>\n child.name === \"path\" && child.attributes.fill !== \"green\",\n )\n .map((path: any) => {\n const currentStrokeWidth = Number.parseFloat(\n path.attributes[\"stroke-width\"] || \"0.02\",\n )\n const newStrokeWidth = (currentStrokeWidth * 1.5).toString()\n\n return {\n ...path,\n attributes: {\n ...path.attributes,\n stroke:\n path.attributes.stroke === \"black\"\n ? \"red\"\n : path.attributes.stroke,\n \"stroke-width\": newStrokeWidth,\n },\n }\n })\n\n // Check if viewBox attribute exists\n const viewBoxAttr = svg.attributes.viewBox\n if (typeof viewBoxAttr === \"undefined\") {\n throw new Error(\"SVG does not have a viewBox attribute.\")\n }\n\n // Extract viewBox values\n const viewBox = viewBoxAttr.split(\" \").map(Number)\n if (viewBox.length < 4) {\n throw new Error(\"Invalid viewBox attribute.\")\n }\n const [minX, minY, width = 0, height = 0] = viewBox\n\n // Calculate scale factors\n const scaleX = size.width / (width || 1)\n const scaleY = size.height / (height || 1)\n\n const scale = Math.min(scaleX, scaleY)\n\n // Adjust transformation to include scaling and centering\n const adjustedTransform = `${transform} scale(${scale}) translate(${-(minX ?? 0) - width / 2}, ${-(minY ?? 0) - height / 2})`\n\n return {\n name: \"g\",\n type: \"element\",\n attributes: { transform: adjustedTransform },\n children: pathElements,\n }\n }\n\n return {\n name: \"g\",\n type: \"element\",\n attributes: { transform },\n children: [\n {\n name: \"rect\",\n type: \"element\",\n attributes: {\n class: \"component\",\n x: (-size.width / 2).toString(),\n y: (-size.height / 2).toString(),\n width: size.width.toString(),\n height: size.height.toString(),\n },\n },\n ],\n }\n}\n\nfunction createSchematicPort(center: { x: number; y: number }): any {\n const portSize = 0.2\n const x = center.x - portSize / 2\n const y = center.y - portSize / 2\n\n return {\n name: \"rect\",\n type: \"element\",\n attributes: {\n class: \"port\",\n x: x.toString(),\n y: y.toString(),\n width: portSize.toString(),\n height: portSize.toString(),\n },\n }\n}\n\nfunction createPortToComponentLine(\n portCenter: { x: number; y: number },\n component: any,\n facingDirection: string,\n): any {\n const componentCenter = { x: component.center.x, y: portCenter.y }\n const halfWidth = component.size.width / 2\n const halfHeight = component.size.height / 2\n\n let endX = portCenter.x\n let endY = portCenter.y\n\n switch (facingDirection) {\n case \"left\":\n endX = componentCenter.x - halfWidth\n break\n case \"right\":\n endX = componentCenter.x + halfWidth\n break\n case \"up\":\n endY = componentCenter.y - halfHeight\n break\n case \"down\":\n endY = componentCenter.y + halfHeight\n break\n }\n\n return {\n name: \"line\",\n type: \"element\",\n attributes: {\n class: \"component-pin\",\n x1: portCenter.x.toString(),\n y1: portCenter.y.toString(),\n x2: endX.toString(),\n y2: endY.toString(),\n },\n }\n}\n\nfunction createSchematicTrace(\n trace: any,\n flipY: (y: number) => number,\n portPositions: Map<string, { x: number; y: number }>,\n): any {\n const edges = trace.edges\n if (edges.length === 0) return null\n\n let path = \"\"\n\n // Process all edges\n edges.forEach((edge: any, index: number) => {\n const fromPoint =\n edge.from.ti !== undefined ? portPositions.get(edge.from.ti) : edge.from\n const toPoint =\n edge.to.ti !== undefined ? portPositions.get(edge.to.ti) : edge.to\n\n if (!fromPoint || !toPoint) {\n return\n }\n\n const fromCoord = `${fromPoint.x} ${flipY(fromPoint.y)}`\n const toCoord = `${toPoint.x} ${flipY(toPoint.y)}`\n\n if (index === 0) {\n path += `M ${fromCoord} L ${toCoord}`\n } else {\n path += ` L ${toCoord}`\n }\n })\n\n // Handle connection to final port if needed\n if (trace.to_schematic_port_id) {\n const finalPort = portPositions.get(trace.to_schematic_port_id)\n if (finalPort) {\n const lastFromPoint = path.split(\"M\")[1]?.split(\"L\")[0]\n const lastEdge = edges[edges.length - 1]\n const lastPoint =\n lastEdge.to.ti !== undefined\n ? portPositions.get(lastEdge.to.ti)\n : lastEdge.to\n if (lastPoint.x !== finalPort.x || lastPoint.y !== finalPort.y) {\n const finalCoord = `${finalPort.x} ${flipY(finalPort.y)}`\n path += ` M ${lastFromPoint} L ${finalCoord}`\n }\n }\n }\n\n return path\n ? {\n name: \"path\",\n type: \"element\",\n attributes: {\n class: \"trace\",\n d: path,\n },\n }\n : null\n}\n\nfunction createSchematicText(\n text: any,\n position: { x: number; y: number },\n): any {\n return {\n name: \"text\",\n type: \"element\",\n attributes: {\n class: \"text\",\n x: position.x.toString(),\n y: position.y.toString(),\n \"text-anchor\": getTextAnchor(text.anchor),\n \"dominant-baseline\": \"middle\",\n },\n children: [\n {\n type: \"text\",\n value: text.text ? text.text : \"\",\n },\n ],\n }\n}\n\nfunction getTextAnchor(anchor: string): string {\n switch (anchor) {\n case \"left\":\n return \"start\"\n case \"right\":\n return \"end\"\n default:\n return \"middle\"\n }\n}\n\n/**\n * @deprecated use `convertCircuitJsonToSchematicSvg` instead\n */\nexport const circuitJsonToSchematicSvg = convertCircuitJsonToSchematicSvg\n"],"mappings":"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","names":["applyToPoint","compose","translate","applyToPoint","applyToPoint","applyToPoint","applyToPoint","compose","rotate","translate","matrixToString","applyToPoint","applyToPoint","applyToPoint","applyToPoint","applyToPoint","applyToPoint","applyToPoint","applyToPoint","compose","translate","applyToPoint","stringify","scale"]}
1
+ {"version":3,"sources":["../lib/pcb/convert-circuit-json-to-pcb-svg.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-fabrication-note-path.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-fabrication-note-text.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-plated-hole.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-silkscreen-path.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-silkscreen-text.ts","../lib/utils/pairs.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-trace.ts","../lib/pcb/layer-name-to-color.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-smt-pads.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-board.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-via.ts","../lib/pcb/svg-object-fns/create-svg-objects-from-pcb-hole.ts","../lib/pcb/colors.ts","../lib/utils/colors.ts","../lib/sch/convert-circuit-json-to-schematic-svg.ts","../lib/sch/svg-object-fns/create-svg-objects-from-sch-component.ts"],"sourcesContent":["import type { Point, AnyCircuitElement } from \"circuit-json\"\nimport { type INode as SvgObject, stringify } from \"svgson\"\nimport {\n type Matrix,\n applyToPoint,\n compose,\n scale,\n translate,\n} from \"transformation-matrix\"\nimport { createSvgObjectsFromPcbFabricationNotePath } from \"./svg-object-fns/create-svg-objects-from-pcb-fabrication-note-path\"\nimport { createSvgObjectsFromPcbFabricationNoteText } from \"./svg-object-fns/create-svg-objects-from-pcb-fabrication-note-text\"\nimport { createSvgObjectsFromPcbPlatedHole } from \"./svg-object-fns/create-svg-objects-from-pcb-plated-hole\"\nimport { createSvgObjectsFromPcbSilkscreenPath } from \"./svg-object-fns/create-svg-objects-from-pcb-silkscreen-path\"\nimport { createSvgObjectsFromPcbSilkscreenText } from \"./svg-object-fns/create-svg-objects-from-pcb-silkscreen-text\"\nimport { createSvgObjectsFromPcbTrace } from \"./svg-object-fns/create-svg-objects-from-pcb-trace\"\nimport { createSvgObjectsFromSmtPad } from \"./svg-object-fns/create-svg-objects-from-smt-pads\"\nimport { createSvgObjectsFromPcbBoard } from \"./svg-object-fns/create-svg-objects-from-pcb-board\"\nimport { createSvgObjectsFromPcbVia } from \"./svg-object-fns/create-svg-objects-from-pcb-via\"\nimport { createSvgObjectsFromPcbHole } from \"./svg-object-fns/create-svg-objects-from-pcb-hole\"\n\nconst OBJECT_ORDER: AnyCircuitElement[\"type\"][] = [\n \"pcb_plated_hole\",\n \"pcb_fabrication_note_text\",\n \"pcb_fabrication_note_path\",\n \"pcb_silkscreen_text\",\n \"pcb_silkscreen_path\",\n \"pcb_via\",\n \"pcb_trace\",\n \"pcb_smtpad\",\n \"pcb_component\",\n \"pcb_board\",\n]\n\ninterface PointObjectNotation {\n x: number\n y: number\n}\n\ninterface Options {\n width?: number\n height?: number\n}\n\nexport function convertCircuitJsonToPcbSvg(\n soup: AnyCircuitElement[],\n options?: Options,\n): string {\n let minX = Number.POSITIVE_INFINITY\n let minY = Number.POSITIVE_INFINITY\n let maxX = Number.NEGATIVE_INFINITY\n let maxY = Number.NEGATIVE_INFINITY\n\n // Process all elements to determine bounds\n for (const item of soup) {\n if (item.type === \"pcb_board\") {\n if (\n item.outline &&\n Array.isArray(item.outline) &&\n item.outline.length >= 3\n )\n updateBoundsToIncludeOutline(item.outline)\n else if (\"center\" in item && \"width\" in item && \"height\" in item)\n updateBounds(item.center, item.width, item.height)\n } else if (\"x\" in item && \"y\" in item) {\n updateBounds({ x: item.x, y: item.y }, 0, 0)\n } else if (\"route\" in item) {\n updateTraceBounds(item.route)\n }\n }\n\n const padding = 1 // Reduced padding for tighter boundary\n const circuitWidth = maxX - minX + 2 * padding\n const circuitHeight = maxY - minY + 2 * padding\n\n const svgWidth = options?.width ?? 800\n const svgHeight = options?.height ?? 600\n const paths: PointObjectNotation[][] = []\n for (const item of soup) {\n if (\"route\" in item && item.route !== undefined) {\n paths.push(item.route as PointObjectNotation[])\n }\n }\n\n // Calculate scale factor to fit the circuit within the SVG, maintaining aspect ratio\n const scaleX = svgWidth / circuitWidth\n const scaleY = svgHeight / circuitHeight\n const scaleFactor = Math.min(scaleX, scaleY)\n\n // Calculate centering offsets\n const offsetX = (svgWidth - circuitWidth * scaleFactor) / 2\n const offsetY = (svgHeight - circuitHeight * scaleFactor) / 2\n\n const transform = compose(\n translate(\n offsetX - minX * scaleFactor + padding * scaleFactor,\n svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor,\n ),\n scale(scaleFactor, -scaleFactor), // Flip in y-direction\n )\n\n const svgObjects = soup\n .sort(\n (a, b) =>\n (OBJECT_ORDER.indexOf(b.type) ?? 9999) -\n (OBJECT_ORDER.indexOf(a.type) ?? 9999),\n )\n .flatMap((item) => createSvgObjects(item, transform))\n\n let strokeWidth = String(0.05 * scaleFactor)\n\n for (const element of soup) {\n if (\"stroke_width\" in element) {\n strokeWidth = String(scaleFactor * element.stroke_width)\n break\n }\n }\n\n const svgObject: SvgObject = {\n name: \"svg\",\n type: \"element\",\n attributes: {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: svgWidth.toString(),\n height: svgHeight.toString(),\n },\n value: \"\",\n children: [\n {\n name: \"style\",\n type: \"element\",\n children: [\n {\n type: \"text\",\n value: `\n .boundary { fill: #000; }\n .pcb-board { fill: none; }\n .pcb-trace { fill: none; }\n .pcb-hole-outer { fill: rgb(200, 52, 52); }\n .pcb-hole-inner { fill: rgb(255, 38, 226); }\n .pcb-pad { }\n .pcb-boundary { fill: none; stroke: #fff; stroke-width: 0.3; }\n .pcb-silkscreen { fill: none; }\n .pcb-silkscreen-top { stroke: #f2eda1; }\n .pcb-silkscreen-bottom { stroke: #f2eda1; }\n .pcb-silkscreen-text { fill: #f2eda1; }\n `,\n },\n ],\n },\n {\n name: \"rect\",\n type: \"element\",\n attributes: {\n class: \"boundary\",\n x: \"0\",\n y: \"0\",\n width: svgWidth.toString(),\n height: svgHeight.toString(),\n },\n },\n createSvgObjectFromPcbBoundary(transform, minX, minY, maxX, maxY),\n ...svgObjects,\n ].filter((child): child is SvgObject => child !== null),\n }\n\n try {\n return stringify(svgObject as SvgObject)\n } catch (error) {\n console.error(\"Error stringifying SVG object:\", error)\n throw error\n }\n\n function updateBounds(center: any, width: any, height: any) {\n const halfWidth = width / 2\n const halfHeight = height / 2\n minX = Math.min(minX, center.x - halfWidth)\n minY = Math.min(minY, center.y - halfHeight)\n maxX = Math.max(maxX, center.x + halfWidth)\n maxY = Math.max(maxY, center.y + halfHeight)\n }\n\n function updateBoundsToIncludeOutline(outline: Point[]) {\n for (const point of outline) {\n minX = Math.min(minX, point.x)\n minY = Math.min(minY, point.y)\n maxX = Math.max(maxX, point.x)\n maxY = Math.max(maxY, point.y)\n }\n }\n\n function updateTraceBounds(route: any[]) {\n for (const point of route) {\n minX = Math.min(minX, point.x)\n minY = Math.min(minY, point.y)\n maxX = Math.max(maxX, point.x)\n maxY = Math.max(maxY, point.y)\n }\n }\n}\n\nfunction createSvgObjects(\n elm: AnyCircuitElement,\n transform: Matrix,\n): SvgObject[] {\n switch (elm.type) {\n case \"pcb_component\":\n return [createSvgObjectsFromPcbComponent(elm, transform)].filter(Boolean)\n case \"pcb_trace\":\n return createSvgObjectsFromPcbTrace(elm, transform)\n case \"pcb_plated_hole\":\n return createSvgObjectsFromPcbPlatedHole(elm, transform).filter(Boolean)\n case \"pcb_hole\":\n return createSvgObjectsFromPcbHole(elm, transform)\n case \"pcb_smtpad\":\n return createSvgObjectsFromSmtPad(elm, transform)\n case \"pcb_silkscreen_text\":\n return createSvgObjectsFromPcbSilkscreenText(elm, transform)\n case \"pcb_fabrication_note_path\":\n return createSvgObjectsFromPcbFabricationNotePath(elm, transform)\n case \"pcb_fabrication_note_text\":\n return createSvgObjectsFromPcbFabricationNoteText(elm, transform)\n case \"pcb_silkscreen_path\":\n return createSvgObjectsFromPcbSilkscreenPath(elm, transform)\n case \"pcb_board\":\n return createSvgObjectsFromPcbBoard(elm, transform)\n case \"pcb_via\":\n return createSvgObjectsFromPcbVia(elm, transform)\n default:\n return []\n }\n}\n\nfunction createSvgObjectsFromPcbComponent(component: any, transform: any): any {\n const { center, width, height, rotation = 0 } = component\n const [x, y] = applyToPoint(transform, [center.x, center.y])\n const scaledWidth = width * Math.abs(transform.a)\n const scaledHeight = height * Math.abs(transform.d)\n const transformStr = `translate(${x}, ${y}) rotate(${-rotation}) scale(1, -1)`\n\n return {\n name: \"g\",\n type: \"element\",\n attributes: { transform: transformStr },\n children: [\n {\n name: \"rect\",\n type: \"element\",\n attributes: {\n class: \"pcb-component\",\n x: (-scaledWidth / 2).toString(),\n y: (-scaledHeight / 2).toString(),\n width: scaledWidth.toString(),\n height: scaledHeight.toString(),\n },\n },\n {\n name: \"rect\",\n type: \"element\",\n attributes: {\n class: \"pcb-component-outline\",\n x: (-scaledWidth / 2).toString(),\n y: (-scaledHeight / 2).toString(),\n width: scaledWidth.toString(),\n height: scaledHeight.toString(),\n },\n },\n ],\n }\n}\n\nfunction createSvgObjectFromPcbBoundary(\n transform: any,\n minX: number,\n minY: number,\n maxX: number,\n maxY: number,\n): SvgObject {\n const [x1, y1] = applyToPoint(transform, [minX, minY])\n const [x2, y2] = applyToPoint(transform, [maxX, maxY])\n const width = Math.abs(x2 - x1)\n const height = Math.abs(y2 - y1)\n const x = Math.min(x1, x2)\n const y = Math.min(y1, y2)\n return {\n name: \"rect\",\n type: \"element\",\n value: \"\",\n children: [],\n attributes: {\n class: \"pcb-boundary\",\n x: x.toString(),\n y: y.toString(),\n width: width.toString(),\n height: height.toString(),\n },\n }\n}\n\n/**\n * @deprecated use `convertCircuitJsonToPcbSvg` instead\n */\nexport const circuitJsonToPcbSvg = convertCircuitJsonToPcbSvg\n","import type { PcbSilkscreenPath, PcbFabricationNotePath } from \"circuit-json\"\nimport { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport type { SvgObject } from \"lib/svg-object\"\n\nexport function createSvgObjectsFromPcbFabricationNotePath(\n fabNotePath: PcbFabricationNotePath,\n transform: Matrix,\n): SvgObject[] {\n if (!fabNotePath.route || !Array.isArray(fabNotePath.route)) return []\n\n // Close the path if the first and last points are the same\n const firstPoint = fabNotePath.route[0]\n const lastPoint = fabNotePath.route[fabNotePath.route.length - 1]\n const isClosed =\n firstPoint!.x === lastPoint!.x && firstPoint!.y === lastPoint!.y\n\n const path =\n fabNotePath.route\n .slice(0, isClosed ? -1 : undefined)\n .map((point: any, index: number) => {\n const [x, y] = applyToPoint(transform, [point.x, point.y])\n return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`\n })\n .join(\" \") + (isClosed ? \" Z\" : \"\")\n\n return [\n {\n name: \"path\",\n type: \"element\",\n attributes: {\n class: \"pcb-fabrication-note-path\",\n stroke: fabNotePath.color || \"rgba(255,255,255,0.5)\",\n fill: \"none\",\n d: path,\n \"stroke-width\": (\n fabNotePath.stroke_width * Math.abs(transform.a)\n ).toString(),\n \"data-pcb-component-id\": fabNotePath.pcb_component_id,\n \"data-pcb-fabrication-note-path-id\":\n fabNotePath.pcb_fabrication_note_path_id,\n },\n value: \"\",\n children: [],\n },\n ]\n}\n","import type { PcbFabricationNoteText } from \"circuit-json\"\nimport type { INode as SvgObject } from \"svgson\"\nimport { toString as matrixToString } from \"transformation-matrix\"\nimport {\n type Matrix,\n applyToPoint,\n compose,\n rotate,\n translate,\n} from \"transformation-matrix\"\n\nexport function createSvgObjectsFromPcbFabricationNoteText(\n pcbFabNoteText: PcbFabricationNoteText,\n transform: Matrix,\n): SvgObject[] {\n const {\n anchor_position,\n anchor_alignment,\n text,\n font_size = 1,\n layer = \"top\",\n color,\n } = pcbFabNoteText\n\n if (\n !anchor_position ||\n typeof anchor_position.x !== \"number\" ||\n typeof anchor_position.y !== \"number\"\n ) {\n console.error(\"Invalid anchor_position:\", anchor_position)\n return []\n }\n\n const [transformedX, transformedY] = applyToPoint(transform, [\n anchor_position.x,\n anchor_position.y,\n ])\n const transformedFontSize = font_size * Math.abs(transform.a)\n\n // Remove ${} from text value and handle undefined text\n\n // Create a composite transformation\n const textTransform = compose(\n translate(transformedX, transformedY), // TODO do anchor_alignment\n rotate(Math.PI / 180), // Convert degrees to radians\n )\n\n const svgObject: SvgObject = {\n name: \"text\",\n type: \"element\",\n attributes: {\n x: \"0\",\n y: \"0\",\n \"font-family\": \"Arial, sans-serif\",\n \"font-size\": transformedFontSize.toString(),\n \"text-anchor\": \"middle\",\n \"dominant-baseline\": \"central\",\n transform: matrixToString(textTransform),\n class: \"pcb-fabrication-note-text\",\n fill: color || \"rgba(255,255,255,0.5)\",\n },\n children: [\n {\n type: \"text\",\n value: text,\n name: \"\",\n attributes: {},\n children: [],\n },\n ],\n value: \"\",\n }\n\n return [svgObject]\n}\n","import type { PCBPlatedHole } from \"circuit-json\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { SvgObject } from \"lib/svg-object\"\n\nexport function createSvgObjectsFromPcbPlatedHole(\n hole: PCBPlatedHole,\n transform: any,\n): SvgObject[] {\n const [x, y] = applyToPoint(transform, [hole.x, hole.y])\n\n if (hole.shape === \"pill\") {\n const scaledOuterWidth = hole.outer_width * Math.abs(transform.a)\n const scaledOuterHeight = hole.outer_height * Math.abs(transform.a)\n const scaledHoleWidth = hole.hole_width * Math.abs(transform.a)\n const scaledHoleHeight = hole.hole_height * Math.abs(transform.a)\n\n const outerRadiusX = scaledOuterWidth / 2\n const outerRadiusY = scaledOuterHeight / 2\n const innerRadiusX = scaledHoleWidth / 2\n const innerRadiusY = scaledHoleHeight / 2\n const straightLength = scaledOuterHeight - scaledOuterWidth\n\n return [\n {\n name: \"g\",\n type: \"element\",\n children: [\n // Outer pill shape\n {\n name: \"path\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole-outer\",\n d:\n `M${x - outerRadiusX},${y - straightLength / 2} ` +\n `v${straightLength} ` +\n `a${outerRadiusX},${outerRadiusX} 0 0 0 ${scaledOuterWidth},0 ` +\n `v-${straightLength} ` +\n `a${outerRadiusX},${outerRadiusX} 0 0 0 -${scaledOuterWidth},0 z`,\n },\n value: \"\",\n children: [],\n },\n // Inner pill shape\n {\n name: \"path\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole-inner\",\n d:\n `M${x - innerRadiusX},${y - (scaledHoleHeight - scaledHoleWidth) / 2} ` +\n `v${scaledHoleHeight - scaledHoleWidth} ` +\n `a${innerRadiusX},${innerRadiusX} 0 0 0 ${scaledHoleWidth},0 ` +\n `v-${scaledHoleHeight - scaledHoleWidth} ` +\n `a${innerRadiusX},${innerRadiusX} 0 0 0 -${scaledHoleWidth},0 z`,\n },\n value: \"\",\n children: [],\n },\n ],\n value: \"\",\n attributes: {},\n },\n ]\n }\n // Fallback to circular hole if not pill-shaped\n if (hole.shape === \"circle\") {\n const scaledOuterWidth = hole.outer_diameter * Math.abs(transform.a)\n const scaledOuterHeight = hole.outer_diameter * Math.abs(transform.a)\n const scaledHoleWidth = hole.hole_diameter * Math.abs(transform.a)\n const scaledHoleHeight = hole.hole_diameter * Math.abs(transform.a)\n\n const outerRadius = Math.min(scaledOuterWidth, scaledOuterHeight) / 2\n const innerRadius = Math.min(scaledHoleWidth, scaledHoleHeight) / 2\n return [\n {\n name: \"g\",\n type: \"element\",\n children: [\n {\n name: \"circle\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole-outer\",\n cx: x.toString(),\n cy: y.toString(),\n r: outerRadius.toString(),\n },\n value: \"\",\n children: [],\n },\n {\n name: \"circle\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole-inner\",\n cx: x.toString(),\n cy: y.toString(),\n r: innerRadius.toString(),\n },\n value: \"\",\n children: [],\n },\n ],\n value: \"\",\n attributes: {},\n },\n ]\n }\n return []\n}\n","import type { PcbSilkscreenPath } from \"circuit-json\"\nimport { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport type { SvgObject } from \"lib/svg-object\"\n\nexport function createSvgObjectsFromPcbSilkscreenPath(\n silkscreenPath: PcbSilkscreenPath,\n transform: Matrix,\n): SvgObject[] {\n if (!silkscreenPath.route || !Array.isArray(silkscreenPath.route)) return []\n\n let path = silkscreenPath.route\n .map((point: any, index: number) => {\n const [x, y] = applyToPoint(transform, [point.x, point.y])\n return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`\n })\n .join(\" \")\n\n // Close the path if it's not already closed\n const firstPoint = silkscreenPath.route[0]\n const lastPoint = silkscreenPath.route[silkscreenPath.route.length - 1]\n if (firstPoint!.x !== lastPoint!.x || firstPoint!.y !== lastPoint!.y) {\n path += \" Z\"\n }\n return [\n {\n name: \"path\",\n type: \"element\",\n attributes: {\n class: `pcb-silkscreen pcb-silkscreen-${silkscreenPath.layer}`,\n d: path,\n \"stroke-width\": (\n silkscreenPath.stroke_width * Math.abs(transform.a)\n ).toString(),\n \"data-pcb-component-id\": silkscreenPath.pcb_component_id,\n \"data-pcb-silkscreen-path-id\": silkscreenPath.pcb_silkscreen_path_id,\n },\n value: \"\",\n children: [],\n },\n ]\n}\n","import type { PcbSilkscreenText } from \"circuit-json\"\nimport type { INode as SvgObject } from \"svgson\"\nimport {\n type Matrix,\n applyToPoint,\n compose,\n rotate,\n translate,\n toString as matrixToString,\n} from \"transformation-matrix\"\n\nexport function createSvgObjectsFromPcbSilkscreenText(\n pcbSilkscreenText: PcbSilkscreenText,\n transform: Matrix,\n): SvgObject[] {\n const {\n anchor_position,\n text,\n font_size = 1,\n layer = \"top\",\n } = pcbSilkscreenText\n\n if (\n !anchor_position ||\n typeof anchor_position.x !== \"number\" ||\n typeof anchor_position.y !== \"number\"\n ) {\n console.error(\"Invalid anchor_position:\", anchor_position)\n return []\n }\n\n const [transformedX, transformedY] = applyToPoint(transform, [\n anchor_position.x,\n anchor_position.y,\n ])\n const transformedFontSize = font_size * Math.abs(transform.a)\n\n // Remove ${} from text value and handle undefined text\n\n // Create a composite transformation\n const textTransform = compose(\n translate(transformedX, transformedY),\n rotate(Math.PI / 180), // Convert degrees to radians\n )\n\n const svgObject: SvgObject = {\n name: \"text\",\n type: \"element\",\n attributes: {\n x: \"0\",\n y: \"0\",\n \"font-family\": \"Arial, sans-serif\",\n \"font-size\": transformedFontSize.toString(),\n \"text-anchor\": \"middle\",\n \"dominant-baseline\": \"central\",\n transform: matrixToString(textTransform),\n class: `pcb-silkscreen-text pcb-silkscreen-${layer}`,\n \"data-pcb-silkscreen-text-id\": pcbSilkscreenText.pcb_component_id,\n },\n children: [\n {\n type: \"text\",\n value: text,\n name: \"\",\n attributes: {},\n children: [],\n },\n ],\n value: \"\",\n }\n\n return [svgObject]\n}\n","/**\n * Return pairs of adjacent elements in an array.\n */\nexport function pairs<T>(arr: Array<T>): Array<[T, T]> {\n const result: Array<[T, T]> = []\n for (let i = 0; i < arr.length - 1; i++) {\n result.push([arr[i]!, arr[i + 1]!])\n }\n return result\n}\n","import type { PCBTrace } from \"circuit-json\"\nimport { pairs } from \"lib/utils/pairs\"\nimport type { INode as SvgObject } from \"svgson\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport { LAYER_NAME_TO_COLOR } from \"../layer-name-to-color\"\n\nexport function createSvgObjectsFromPcbTrace(\n trace: PCBTrace,\n transform: any,\n): SvgObject[] {\n if (!trace.route || !Array.isArray(trace.route) || trace.route.length < 2)\n return []\n\n const segments = pairs(trace.route)\n const svgObjects: SvgObject[] = []\n\n for (const [start, end] of segments) {\n const startPoint = applyToPoint(transform, [start.x, start.y])\n const endPoint = applyToPoint(transform, [end.x, end.y])\n\n const layer =\n \"layer\" in start ? start.layer : \"layer\" in end ? end.layer : null\n if (!layer) continue\n\n const layerColor =\n LAYER_NAME_TO_COLOR[layer as keyof typeof LAYER_NAME_TO_COLOR] ?? \"white\"\n\n const traceWidth =\n \"width\" in start ? start.width : \"width\" in end ? end.width : null\n\n svgObjects.push({\n name: \"path\",\n type: \"element\",\n value: \"\",\n children: [],\n attributes: {\n class: \"pcb-trace\",\n stroke: layerColor,\n d: `M ${startPoint[0]} ${startPoint[1]} L ${endPoint[0]} ${endPoint[1]}`,\n \"stroke-width\": traceWidth\n ? (traceWidth * Math.abs(transform.a)).toString()\n : \"0.3\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n \"shape-rendering\": \"crispEdges\",\n },\n })\n }\n return svgObjects\n}\n","/**\n * TODO use @tscircuit/pcb-colors when it's published\n */\nexport const LAYER_NAME_TO_COLOR = {\n top: \"rgb(200, 52, 52)\",\n bottom: \"rgb(77, 127, 196)\",\n}\n\nexport function layerNameToColor(layerName: string) {\n return (\n LAYER_NAME_TO_COLOR[layerName as keyof typeof LAYER_NAME_TO_COLOR] ??\n \"white\"\n )\n}\n","import type { PCBSMTPad } from \"circuit-json\"\nimport { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { layerNameToColor } from \"../layer-name-to-color\"\n\nexport function createSvgObjectsFromSmtPad(\n pad: PCBSMTPad,\n transform: Matrix,\n): any {\n const [x, y] = applyToPoint(transform, [pad.x, pad.y])\n\n if (pad.shape === \"rect\") {\n const width = pad.width * Math.abs(transform.a)\n const height = pad.height * Math.abs(transform.d)\n return [\n {\n name: \"rect\",\n type: \"element\",\n attributes: {\n class: \"pcb-pad\",\n fill: layerNameToColor(pad.layer),\n x: (x - width / 2).toString(),\n y: (y - height / 2).toString(),\n width: width.toString(),\n height: height.toString(),\n },\n },\n ]\n }\n // TODO implement smtpad circles/ovals etc.\n return []\n}\n","import type { PCBBoard, Point } from \"circuit-json\"\nimport { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport type { SvgObject } from \"lib/svg-object\"\n\nexport function createSvgObjectsFromPcbBoard(\n pcbBoard: PCBBoard,\n transform: Matrix,\n): SvgObject[] {\n const { width, height, center, outline } = pcbBoard\n\n let path: string\n if (outline && Array.isArray(outline) && outline.length >= 3) {\n path = outline\n .map((point: Point, index: number) => {\n const [x, y] = applyToPoint(transform, [point.x, point.y])\n return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`\n })\n .join(\" \")\n } else {\n const halfWidth = width / 2\n const halfHeight = height / 2\n\n const topLeft = applyToPoint(transform, [\n center.x - halfWidth,\n center.y - halfHeight,\n ])\n const topRight = applyToPoint(transform, [\n center.x + halfWidth,\n center.y - halfHeight,\n ])\n const bottomRight = applyToPoint(transform, [\n center.x + halfWidth,\n center.y + halfHeight,\n ])\n const bottomLeft = applyToPoint(transform, [\n center.x - halfWidth,\n center.y + halfHeight,\n ])\n\n path =\n `M ${topLeft[0]} ${topLeft[1]} ` +\n `L ${topRight[0]} ${topRight[1]} ` +\n `L ${bottomRight[0]} ${bottomRight[1]} ` +\n `L ${bottomLeft[0]} ${bottomLeft[1]}`\n }\n\n path += \" Z\"\n\n return [\n {\n name: \"path\",\n type: \"element\",\n value: \"\",\n children: [],\n attributes: {\n class: \"pcb-board\",\n d: path,\n stroke: \"rgba(255, 255, 255, 0.5)\",\n \"stroke-width\": (0.1 * Math.abs(transform.a)).toString(),\n },\n },\n ]\n}\n","import type { PCBVia } from \"circuit-json\"\nimport { applyToPoint } from \"transformation-matrix\"\n\nexport function createSvgObjectsFromPcbVia(hole: PCBVia, transform: any): any {\n const [x, y] = applyToPoint(transform, [hole.x, hole.y])\n const scaledOuterWidth = hole.outer_diameter * Math.abs(transform.a)\n const scaledOuterHeight = hole.outer_diameter * Math.abs(transform.a)\n const scaledHoleWidth = hole.hole_diameter * Math.abs(transform.a)\n const scaledHoleHeight = hole.hole_diameter * Math.abs(transform.a)\n\n const outerRadius = Math.min(scaledOuterWidth, scaledOuterHeight) / 2\n const innerRadius = Math.min(scaledHoleWidth, scaledHoleHeight) / 2\n return {\n name: \"g\",\n type: \"element\",\n children: [\n {\n name: \"circle\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole-outer\",\n cx: x.toString(),\n cy: y.toString(),\n r: outerRadius.toString(),\n },\n },\n {\n name: \"circle\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole-inner\",\n cx: x.toString(),\n cy: y.toString(),\n r: innerRadius.toString(),\n },\n },\n ],\n }\n}\n","import type { PCBHole } from \"circuit-json\"\nimport { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport type { SvgObject } from \"lib/svg-object\"\nimport { HOLE_COLOR } from \"../colors\"\n\nexport function createSvgObjectsFromPcbHole(\n hole: PCBHole,\n transform: Matrix,\n): SvgObject[] {\n const [x, y] = applyToPoint(transform, [hole.x, hole.y])\n\n if (hole.hole_shape === \"circle\" || hole.hole_shape === \"square\") {\n const scaledDiameter = hole.hole_diameter * Math.abs(transform.a)\n const radius = scaledDiameter / 2\n\n if (hole.hole_shape === \"circle\") {\n return [\n {\n name: \"circle\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole\",\n cx: x.toString(),\n cy: y.toString(),\n r: radius.toString(),\n fill: HOLE_COLOR,\n },\n children: [],\n value: \"\",\n },\n ]\n }\n // Square hole\n return [\n {\n name: \"rect\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole\",\n x: (x - radius).toString(),\n y: (y - radius).toString(),\n width: scaledDiameter.toString(),\n height: scaledDiameter.toString(),\n fill: HOLE_COLOR,\n },\n children: [],\n value: \"\",\n },\n ]\n }\n if (hole.hole_shape === \"oval\") {\n const scaledWidth = hole.hole_width * Math.abs(transform.a)\n const scaledHeight = hole.hole_height * Math.abs(transform.a)\n const rx = scaledWidth / 2\n const ry = scaledHeight / 2\n\n return [\n {\n name: \"ellipse\",\n type: \"element\",\n attributes: {\n class: \"pcb-hole\",\n cx: x.toString(),\n cy: y.toString(),\n rx: rx.toString(),\n ry: ry.toString(),\n fill: HOLE_COLOR,\n },\n children: [],\n value: \"\",\n },\n ]\n }\n\n return []\n}\n","export const HOLE_COLOR = \"#FF26E2\"\n","// Kicad-2020 color scheme\nexport const colorMap = {\n \"3d_viewer\": {\n background_bottom: \"rgb(102, 102, 128)\",\n background_top: \"rgb(204, 204, 230)\",\n board: \"rgb(51, 43, 23)\",\n copper: \"rgb(179, 156, 0)\",\n silkscreen_bottom: \"rgb(230, 230, 230)\",\n silkscreen_top: \"rgb(230, 230, 230)\",\n soldermask: \"rgb(20, 51, 36)\",\n solderpaste: \"rgb(128, 128, 128)\",\n },\n board: {\n anchor: \"rgb(255, 38, 226)\",\n aux_items: \"rgb(255, 255, 255)\",\n b_adhes: \"rgb(0, 0, 132)\",\n b_crtyd: \"rgb(255, 38, 226)\",\n b_fab: \"rgb(88, 93, 132)\",\n b_mask: \"rgba(2, 255, 238, 0.400)\",\n b_paste: \"rgb(0, 194, 194)\",\n b_silks: \"rgb(232, 178, 167)\",\n background: \"rgb(0, 16, 35)\",\n cmts_user: \"rgb(89, 148, 220)\",\n copper: {\n b: \"rgb(77, 127, 196)\",\n f: \"rgb(200, 52, 52)\",\n in1: \"rgb(127, 200, 127)\",\n in10: \"rgb(237, 124, 51)\",\n in11: \"rgb(91, 195, 235)\",\n in12: \"rgb(247, 111, 142)\",\n in13: \"rgb(167, 165, 198)\",\n in14: \"rgb(40, 204, 217)\",\n in15: \"rgb(232, 178, 167)\",\n in16: \"rgb(242, 237, 161)\",\n in17: \"rgb(237, 124, 51)\",\n in18: \"rgb(91, 195, 235)\",\n in19: \"rgb(247, 111, 142)\",\n in2: \"rgb(206, 125, 44)\",\n in20: \"rgb(167, 165, 198)\",\n in21: \"rgb(40, 204, 217)\",\n in22: \"rgb(232, 178, 167)\",\n in23: \"rgb(242, 237, 161)\",\n in24: \"rgb(237, 124, 51)\",\n in25: \"rgb(91, 195, 235)\",\n in26: \"rgb(247, 111, 142)\",\n in27: \"rgb(167, 165, 198)\",\n in28: \"rgb(40, 204, 217)\",\n in29: \"rgb(232, 178, 167)\",\n in3: \"rgb(79, 203, 203)\",\n in30: \"rgb(242, 237, 161)\",\n in4: \"rgb(219, 98, 139)\",\n in5: \"rgb(167, 165, 198)\",\n in6: \"rgb(40, 204, 217)\",\n in7: \"rgb(232, 178, 167)\",\n in8: \"rgb(242, 237, 161)\",\n in9: \"rgb(141, 203, 129)\",\n },\n cursor: \"rgb(255, 255, 255)\",\n drc: \"rgb(194, 194, 194)\",\n drc_error: \"rgba(215, 91, 107, 0.800)\",\n drc_exclusion: \"rgb(255, 255, 255)\",\n drc_warning: \"rgba(255, 208, 66, 0.902)\",\n dwgs_user: \"rgb(194, 194, 194)\",\n eco1_user: \"rgb(180, 219, 210)\",\n eco2_user: \"rgb(216, 200, 82)\",\n edge_cuts: \"rgb(208, 210, 205)\",\n f_adhes: \"rgb(132, 0, 132)\",\n f_crtyd: \"rgb(255, 0, 245)\",\n f_fab: \"rgb(175, 175, 175)\",\n f_mask: \"rgba(216, 100, 255, 0.400)\",\n f_paste: \"rgba(180, 160, 154, 0.902)\",\n f_silks: \"rgb(242, 237, 161)\",\n footprint_text_back: \"rgb(0, 0, 132)\",\n footprint_text_front: \"rgb(194, 194, 194)\",\n footprint_text_invisible: \"rgb(132, 132, 132)\",\n grid: \"rgb(132, 132, 132)\",\n grid_axes: \"rgb(194, 194, 194)\",\n margin: \"rgb(255, 38, 226)\",\n microvia: \"rgb(0, 132, 132)\",\n no_connect: \"rgb(0, 0, 132)\",\n pad_back: \"rgb(77, 127, 196)\",\n pad_front: \"rgb(200, 52, 52)\",\n pad_plated_hole: \"rgb(194, 194, 0)\",\n pad_through_hole: \"rgb(227, 183, 46)\",\n plated_hole: \"rgb(26, 196, 210)\",\n ratsnest: \"rgba(245, 255, 213, 0.702)\",\n select_overlay: \"rgb(4, 255, 67)\",\n through_via: \"rgb(236, 236, 236)\",\n user_1: \"rgb(194, 194, 194)\",\n user_2: \"rgb(89, 148, 220)\",\n user_3: \"rgb(180, 219, 210)\",\n user_4: \"rgb(216, 200, 82)\",\n user_5: \"rgb(194, 194, 194)\",\n user_6: \"rgb(89, 148, 220)\",\n user_7: \"rgb(180, 219, 210)\",\n user_8: \"rgb(216, 200, 82)\",\n user_9: \"rgb(232, 178, 167)\",\n via_blind_buried: \"rgb(187, 151, 38)\",\n via_hole: \"rgb(227, 183, 46)\",\n via_micro: \"rgb(0, 132, 132)\",\n via_through: \"rgb(236, 236, 236)\",\n worksheet: \"rgb(200, 114, 171)\",\n },\n gerbview: {\n axes: \"rgb(0, 0, 132)\",\n background: \"rgb(0, 0, 0)\",\n dcodes: \"rgb(255, 255, 255)\",\n grid: \"rgb(132, 132, 132)\",\n layers: [\n \"rgb(132, 0, 0)\",\n \"rgb(194, 194, 0)\",\n \"rgb(194, 0, 194)\",\n \"rgb(194, 0, 0)\",\n \"rgb(0, 132, 132)\",\n \"rgb(0, 132, 0)\",\n \"rgb(0, 0, 132)\",\n \"rgb(132, 132, 132)\",\n \"rgb(132, 0, 132)\",\n \"rgb(194, 194, 194)\",\n \"rgb(132, 0, 132)\",\n \"rgb(132, 0, 0)\",\n \"rgb(132, 132, 0)\",\n \"rgb(194, 194, 194)\",\n \"rgb(0, 0, 132)\",\n \"rgb(0, 132, 0)\",\n \"rgb(132, 0, 0)\",\n \"rgb(194, 194, 0)\",\n \"rgb(194, 0, 194)\",\n \"rgb(194, 0, 0)\",\n \"rgb(0, 132, 132)\",\n \"rgb(0, 132, 0)\",\n \"rgb(0, 0, 132)\",\n \"rgb(132, 132, 132)\",\n \"rgb(132, 0, 132)\",\n \"rgb(194, 194, 194)\",\n \"rgb(132, 0, 132)\",\n \"rgb(132, 0, 0)\",\n \"rgb(132, 132, 0)\",\n \"rgb(194, 194, 194)\",\n \"rgb(0, 0, 132)\",\n \"rgb(0, 132, 0)\",\n \"rgb(132, 0, 0)\",\n \"rgb(194, 194, 0)\",\n \"rgb(194, 0, 194)\",\n \"rgb(194, 0, 0)\",\n \"rgb(0, 132, 132)\",\n \"rgb(0, 132, 0)\",\n \"rgb(0, 0, 132)\",\n \"rgb(132, 132, 132)\",\n \"rgb(132, 0, 132)\",\n \"rgb(194, 194, 194)\",\n \"rgb(132, 0, 132)\",\n \"rgb(132, 0, 0)\",\n \"rgb(132, 132, 0)\",\n \"rgb(194, 194, 194)\",\n \"rgb(0, 0, 132)\",\n \"rgb(0, 132, 0)\",\n \"rgb(132, 0, 0)\",\n \"rgb(194, 194, 0)\",\n \"rgb(194, 0, 194)\",\n \"rgb(194, 0, 0)\",\n \"rgb(0, 132, 132)\",\n \"rgb(0, 132, 0)\",\n \"rgb(0, 0, 132)\",\n \"rgb(132, 132, 132)\",\n \"rgb(132, 0, 132)\",\n \"rgb(194, 194, 194)\",\n \"rgb(132, 0, 132)\",\n \"rgb(132, 0, 0)\",\n ],\n negative_objects: \"rgb(132, 132, 132)\",\n worksheet: \"rgb(0, 0, 132)\",\n },\n meta: {\n filename: \"kicad_2020\",\n name: \"KiCad 2020\",\n version: 2,\n },\n palette: [\n \"rgb(132, 0, 0)\",\n \"rgb(194, 194, 0)\",\n \"rgb(194, 0, 194)\",\n \"rgb(194, 0, 0)\",\n \"rgb(0, 132, 132)\",\n \"rgb(0, 132, 0)\",\n \"rgb(0, 0, 132)\",\n \"rgb(132, 132, 132)\",\n \"rgb(132, 0, 132)\",\n \"rgb(194, 194, 194)\",\n \"rgb(132, 0, 132)\",\n \"rgb(132, 0, 0)\",\n \"rgb(132, 132, 0)\",\n \"rgb(194, 194, 194)\",\n \"rgb(0, 0, 132)\",\n \"rgb(0, 132, 0)\",\n ],\n schematic: {\n aux_items: \"rgb(46, 46, 46)\",\n background: \"rgb(245, 241, 237)\",\n brightened: \"rgb(255, 0, 255)\",\n bus: \"rgb(0, 0, 132)\",\n bus_junction: \"rgb(0, 0, 132)\",\n component_body: \"rgb(255, 255, 194)\",\n component_outline: \"rgb(132, 0, 0)\",\n cursor: \"rgb(15, 15, 15)\",\n erc_error: \"rgba(230, 9, 13, 0.800)\",\n erc_warning: \"rgba(209, 146, 0, 0.800)\",\n fields: \"rgb(132, 0, 132)\",\n grid: \"rgb(181, 181, 181)\",\n grid_axes: \"rgb(0, 0, 132)\",\n hidden: \"rgb(194, 194, 194)\",\n junction: \"rgb(0, 150, 0)\",\n label_global: \"rgb(132, 0, 0)\",\n label_hier: \"rgb(114, 86, 0)\",\n label_local: \"rgb(15, 15, 15)\",\n net_name: \"rgb(132, 132, 132)\",\n no_connect: \"rgb(0, 0, 132)\",\n note: \"rgb(0, 0, 194)\",\n override_item_colors: false,\n pin: \"rgb(132, 0, 0)\",\n pin_name: \"rgb(0, 100, 100)\",\n pin_number: \"rgb(169, 0, 0)\",\n reference: \"rgb(0, 100, 100)\",\n shadow: \"rgba(102, 179, 255, 0.800)\",\n sheet: \"rgb(132, 0, 0)\",\n sheet_background: \"rgba(253, 255, 231, 0.000)\",\n sheet_fields: \"rgb(132, 0, 132)\",\n sheet_filename: \"rgb(114, 86, 0)\",\n sheet_label: \"rgb(0, 100, 100)\",\n sheet_name: \"rgb(0, 100, 100)\",\n value: \"rgb(0, 100, 100)\",\n wire: \"rgb(0, 150, 0)\",\n worksheet: \"rgb(132, 0, 0)\",\n },\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { colorMap } from \"lib/utils/colors\"\nimport { stringify } from \"svgson\"\nimport { createSchematicComponent } from \"./svg-object-fns/create-svg-objects-from-sch-component\"\n\ninterface Options {\n width?: number\n height?: number\n}\n\nexport function convertCircuitJsonToSchematicSvg(\n soup: AnyCircuitElement[],\n options?: Options,\n): string {\n let minX = Number.POSITIVE_INFINITY\n let minY = Number.POSITIVE_INFINITY\n let maxX = Number.NEGATIVE_INFINITY\n let maxY = Number.NEGATIVE_INFINITY\n\n const portSize = 0.2\n const portPositions = new Map()\n\n // First pass: find the bounds and collect port positions\n for (const item of soup) {\n if (item.type === \"schematic_component\") {\n updateBounds(item.center, item.size, item.rotation || 0)\n } else if (item.type === \"schematic_port\") {\n updateBounds(item.center, { width: portSize, height: portSize }, 0)\n portPositions.set(item.schematic_port_id, item.center)\n }\n }\n\n const height = maxY - minY\n const flipY = (y: number) => height - (y - minY) + minY\n\n const svgChildren: any[] = []\n\n // Process components\n const componentMap = new Map()\n for (const component of soup.filter(\n (item) => item.type === \"schematic_component\",\n )) {\n const flippedCenter = {\n x: component.center.x,\n y: flipY(component.center.y),\n }\n const svg = createSchematicComponent(\n flippedCenter,\n component.size,\n component.rotation || 0,\n (component as any).symbol_name,\n (component as any).port_arrangement,\n (component as any).port_labels,\n (component as any).source_component_id,\n soup,\n )\n svgChildren.push(svg)\n componentMap.set(component.schematic_component_id, component)\n }\n\n // Process schematic traces\n for (const trace of soup.filter((item) => item.type === \"schematic_trace\")) {\n const svg = createSchematicTrace(trace, flipY, portPositions)\n if (svg) svgChildren.push(svg)\n }\n\n const padding = 1\n const width = maxX - minX + 2 * padding\n const viewBox = `${minX - padding} ${minY - padding} ${width} ${height + 2 * padding}`\n\n const svgObject = {\n name: \"svg\",\n type: \"element\",\n attributes: {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox,\n width: options?.width ?? \"1200\",\n height: options?.height ?? \"600\",\n style: `background-color: ${colorMap.schematic.background}`,\n },\n children: [\n {\n name: \"style\",\n type: \"element\",\n children: [\n {\n type: \"text\",\n value: `\n .component { fill: none; stroke: ${colorMap.schematic.component_outline}; stroke-width: 0.03; }\n .chip { fill: ${colorMap.schematic.component_body}; stroke: ${colorMap.schematic.component_outline}; stroke-width: 0.03; }\n .component-pin { fill: none; stroke: ${colorMap.schematic.component_outline}; stroke-width: 0.02; }\n .trace { stroke: ${colorMap.schematic.wire}; stroke-width: 0.02; fill: none; }\n .text { font-family: Arial, sans-serif; font-size: 0.2px; fill: ${colorMap.schematic.wire}; }\n .pin-number { font-size: 0.15px; fill: ${colorMap.schematic.pin_number}; }\n .port-label { fill: ${colorMap.schematic.reference}; }\n .component-name { font-size: 0.25px; fill: ${colorMap.schematic.reference}; }\n `,\n },\n ],\n },\n ...svgChildren,\n ],\n }\n\n return stringify({\n value: \"\",\n ...svgObject,\n attributes: {\n ...svgObject.attributes,\n width: svgObject.attributes.width.toString(),\n height: svgObject.attributes.height.toString(),\n },\n })\n\n function createSchematicTrace(\n trace: any,\n flipY: (y: number) => number,\n portPositions: Map<string, { x: number; y: number }>,\n ): any {\n const edges = trace.edges\n if (edges.length === 0) return null\n\n let path = \"\"\n\n // Process all edges\n edges.forEach((edge: any, index: number) => {\n const fromPoint =\n edge.from.ti !== undefined ? portPositions.get(edge.from.ti) : edge.from\n const toPoint =\n edge.to.ti !== undefined ? portPositions.get(edge.to.ti) : edge.to\n\n if (!fromPoint || !toPoint) {\n return\n }\n\n const fromCoord = `${fromPoint.x - 0.15} ${flipY(fromPoint.y)}`\n const toCoord = `${toPoint.x + 0.15} ${flipY(toPoint.y)}`\n\n if (index === 0) {\n path += `M ${fromCoord} L ${toCoord}`\n } else {\n path += ` L ${toCoord}`\n }\n })\n\n // Handle connection to final port if needed\n if (trace.to_schematic_port_id) {\n const finalPort = portPositions.get(trace.to_schematic_port_id)\n if (finalPort) {\n const lastFromPoint = path.split(\"M\")[1]?.split(\"L\")[0]\n const lastEdge = edges[edges.length - 1]\n const lastPoint =\n lastEdge.to.ti !== undefined\n ? portPositions.get(lastEdge.to.ti)\n : lastEdge.to\n if (lastPoint.x !== finalPort.x || lastPoint.y !== finalPort.y) {\n const finalCoord = `${finalPort.x} ${flipY(finalPort.y)}`\n path += ` M ${lastFromPoint} L ${finalCoord}`\n }\n }\n }\n\n return path\n ? {\n name: \"path\",\n type: \"element\",\n attributes: {\n class: \"trace\",\n d: path,\n },\n }\n : null\n }\n\n function updateBounds(center: any, size: any, rotation: number) {\n const corners = [\n { x: -size.width / 2, y: -size.height / 2 },\n { x: size.width / 2, y: -size.height / 2 },\n { x: size.width / 2, y: size.height / 2 },\n { x: -size.width / 2, y: size.height / 2 },\n ]\n\n for (const corner of corners) {\n const rotatedX =\n corner.x * Math.cos(rotation) - corner.y * Math.sin(rotation) + center.x\n const rotatedY =\n corner.x * Math.sin(rotation) + corner.y * Math.cos(rotation) + center.y\n minX = Math.min(minX, rotatedX)\n minY = Math.min(minY, rotatedY)\n maxX = Math.max(maxX, rotatedX)\n maxY = Math.max(maxY, rotatedY)\n }\n }\n}\n\n/**\n * @deprecated use `convertCircuitJsonToSchematicSvg` instead\n */\nexport const circuitJsonToSchematicSvg = convertCircuitJsonToSchematicSvg\n","import type { AnyCircuitElement } from \"circuit-json\";\nimport { colorMap } from \"lib/utils/colors\";\nimport { getSvg, symbols } from \"schematic-symbols\";\nimport { parseSync } from \"svgson\";\n\nexport function createSchematicComponent(\n center: { x: number; y: number },\n size: { width: number; height: number },\n rotation: number,\n symbolName?: string,\n portArrangement?: any,\n portLabels?: any,\n sourceComponentId?: string,\n circuitJson?: AnyCircuitElement[],\n ): any {\n const transform = `translate(${center.x}, ${center.y}) rotate(${(rotation * 180) / Math.PI})`\n\n let children: any[] = []\n\n // Find the source component and get its name\n const sourceComponent = circuitJson?.find(\n (item) =>\n item.type === \"source_component\" &&\n item.source_component_id === sourceComponentId,\n )\n const componentName =\n sourceComponent && \"name\" in sourceComponent ? sourceComponent.name : \"\"\n const manufacturerNumber =\n sourceComponent && \"manufacturer_part_number\" in sourceComponent\n ? sourceComponent.manufacturer_part_number\n : \"\"\n const resistance =\n sourceComponent && \"resistance\" in sourceComponent\n ? sourceComponent.resistance\n : \"\"\n const capacitance =\n sourceComponent && \"capacitance\" in sourceComponent\n ? sourceComponent.capacitance\n : \"\"\n\n if (symbolName) {\n const symbol = (symbols as any)[symbolName]\n const paths = symbol.primitives.filter((p: any) => p.type === \"path\")\n const updatedSymbol = {\n ...symbol,\n primitives: paths,\n }\n const svg = parseSync(\n getSvg(updatedSymbol, {\n width: size.width,\n height: size.height,\n }),\n )\n\n children = svg.children\n .filter(\n (child: any) =>\n child.name === \"path\" && child.attributes.fill !== \"green\",\n )\n .map((path: any) => {\n const currentStrokeWidth = Number.parseFloat(\n path.attributes[\"stroke-width\"] || \"0.02\",\n )\n const newStrokeWidth = (currentStrokeWidth * 1.5).toString()\n\n return {\n ...path,\n attributes: {\n ...path.attributes,\n stroke:\n path.attributes.stroke === \"black\"\n ? `${colorMap.schematic.component_outline}`\n : path.attributes.stroke,\n \"stroke-width\": newStrokeWidth,\n },\n }\n })\n } else {\n children.push({\n name: \"rect\",\n type: \"element\",\n attributes: {\n class: \"component chip\",\n x: -size.width / 2,\n y: -size.height / 2,\n width: size.width,\n height: size.height,\n },\n })\n }\n\n if (manufacturerNumber) {\n children.push({\n name: \"text\",\n type: \"element\",\n attributes: {\n class: \"component-name\",\n x: 1.2,\n y: -size.height / 2 - 0.4, // Position above the component\n \"text-anchor\": \"right\",\n \"dominant-baseline\": \"auto\",\n },\n children: [{ type: \"text\", value: manufacturerNumber }],\n })\n\n // Add component name on top\n children.push({\n name: \"text\",\n type: \"element\",\n attributes: {\n class: \"component-name\",\n x: 1.2,\n y: -size.height / 2 - 0.7, // Position above the component\n \"text-anchor\": \"right\",\n \"dominant-baseline\": \"auto\",\n },\n children: [{ type: \"text\", value: componentName }],\n })\n }\n\n if (resistance || capacitance) {\n children.push({\n name: \"text\",\n type: \"element\",\n attributes: {\n class: \"component-name\",\n x: 0,\n y: -size.height / 2 - 0.2, // Position above the component\n \"text-anchor\": \"middle\",\n \"dominant-baseline\": \"auto\",\n },\n children: [{ type: \"text\", value: resistance || capacitance }],\n })\n\n // Add component name on top\n children.push({\n name: \"text\",\n type: \"element\",\n attributes: {\n class: \"component-name\",\n x: 0,\n y: -size.height / 2 - 0.5, // Position above the component\n \"text-anchor\": \"middle\",\n \"dominant-baseline\": \"auto\",\n },\n children: [{ type: \"text\", value: componentName }],\n })\n }\n\n // Add ports if portArrangement is provided\n if (portArrangement) {\n const portLength = 0.2 // Length of the port line\n const circleRadius = 0.05 // Radius of the port circle\n const labelOffset = 0.1 // Offset for label positioning\n\n // console.log(portArrangement)\n\n for (const [side, arrangement] of Object.entries(portArrangement)) {\n if (!arrangement) continue\n\n const pins = (arrangement as any).pins\n const direction = (arrangement as any).direction\n\n let getX: (index: number, total: number) => number\n let getY: (index: number, total: number) => number\n let getEndX: (x: number) => number\n let getEndY: (y: number) => number\n let getLabelX: (x: number) => number\n let getLabelY: (y: number) => number\n let labelAnchor: string\n let isVertical = false\n\n switch (side) {\n case \"left_side\":\n getX = () => -size.width / 2\n getY = (index, total) =>\n -size.height / 2 + (size.height * (index + 1)) / (total + 1)\n getEndX = (x) => x - portLength\n getEndY = (y) => y\n getLabelX = (x) => x + labelOffset\n getLabelY = (y) => y\n labelAnchor = \"start\"\n break\n case \"right_side\":\n getX = () => size.width / 2\n getY = (index, total) =>\n -size.height / 2 + (size.height * (index + 1)) / (total + 1)\n getEndX = (x) => x + portLength\n getEndY = (y) => y\n getLabelX = (x) => x - labelOffset\n getLabelY = (y) => y\n labelAnchor = \"end\"\n break\n case \"top_side\":\n getX = (index, total) =>\n -size.width / 2 + (size.width * (index + 1)) / (total + 1)\n getY = () => -size.height / 2\n getEndX = (x) => x\n getEndY = (y) => y - portLength\n getLabelX = (x) => x\n getLabelY = (y) => y + labelOffset + 0.15\n labelAnchor = \"middle\"\n isVertical = true\n break\n case \"bottom_side\":\n getX = (index, total) =>\n -size.width / 2 + (size.width * (index + 1)) / (total + 1)\n getY = () => size.height / 2\n getEndX = (x) => x\n getEndY = (y) => y + portLength\n getLabelX = (x) => x\n getLabelY = (y) => y - labelOffset - 0.15\n labelAnchor = \"middle\"\n isVertical = true\n break\n default:\n continue // Skip unknown sides\n }\n\n const totalPins = pins.length\n\n pins.forEach((pin: number, index: number) => {\n let x = getX(index, totalPins)\n let y = getY(index, totalPins)\n\n if (direction === \"bottom-to-top\" || direction === \"right-to-left\") {\n ;[x, y] = [\n getX(totalPins - 1 - index, totalPins),\n getY(totalPins - 1 - index, totalPins),\n ]\n }\n\n const endX = getEndX(x)\n const endY = getEndY(y)\n\n children.push({\n name: \"line\",\n type: \"element\",\n attributes: {\n class: \"component-pin\",\n x1: x,\n y1: y,\n x2: endX,\n y2: endY,\n },\n })\n\n children.push({\n name: \"circle\",\n type: \"element\",\n attributes: {\n class: \"component-pin\",\n cx: endX,\n cy: endY,\n r: circleRadius,\n },\n })\n\n // Add label if it exists in portLabels\n const labelKey = `pin${pin}`\n if (portLabels && labelKey in portLabels) {\n let labelTransform = \"\"\n if (isVertical) {\n labelTransform = `rotate(${side === \"top_side\" ? -90 : 270}, ${getLabelX(x)}, ${getLabelY(y)})`\n }\n children.push({\n name: \"text\",\n type: \"element\",\n attributes: {\n class: \"port-label\",\n x: getLabelX(x),\n y: getLabelY(y),\n \"text-anchor\": labelAnchor,\n \"dominant-baseline\": \"middle\",\n \"font-size\": \"0.2\",\n transform: labelTransform,\n },\n children: [{ type: \"text\", value: portLabels[labelKey] }],\n })\n }\n // Add pin number\n children.push({\n name: \"text\",\n type: \"element\",\n attributes: {\n class: \"pin-number\",\n x: endX,\n y: endY + (side === \"bottom_side\" ? 0.15 : -0.15),\n \"text-anchor\": \"middle\",\n \"dominant-baseline\": \"middle\",\n \"font-size\": \"0.15\",\n },\n children: [{ type: \"text\", value: pin.toString() }],\n })\n })\n }\n }\n\n return {\n name: \"g\",\n type: \"element\",\n attributes: { transform },\n children,\n }\n }"],"mappings":"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","names":["applyToPoint","compose","translate","applyToPoint","applyToPoint","applyToPoint","applyToPoint","compose","rotate","translate","matrixToString","applyToPoint","applyToPoint","applyToPoint","applyToPoint","applyToPoint","applyToPoint","applyToPoint","applyToPoint","compose","translate","applyToPoint","stringify","stringify","flipY","portPositions"]}
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "circuit-to-svg",
3
3
  "type": "module",
4
- "version": "0.0.38",
4
+ "version": "0.0.39",
5
5
  "description": "Convert Circuit JSON to SVG",
6
6
  "main": "dist/index.js",
7
7
  "files": [
8
8
  "dist"
9
9
  ],
10
10
  "scripts": {
11
+ "start": "storybook dev -p 6006",
11
12
  "prepublish": "npm run build",
12
13
  "build": "tsup-node ./lib/index.ts --format esm --dts --sourcemap",
13
14
  "format": "biome format . --write",
@@ -26,7 +27,7 @@
26
27
  "@storybook/react": "^8.2.5",
27
28
  "@storybook/react-vite": "^8.2.5",
28
29
  "@storybook/test": "^8.2.5",
29
- "@tscircuit/core": "^0.0.71",
30
+ "@tscircuit/core": "^0.0.98",
30
31
  "@tscircuit/plop": "^0.0.10",
31
32
  "@types/bun": "^1.1.9",
32
33
  "bun-match-svg": "^0.0.6",
@@ -44,10 +45,10 @@
44
45
  "dependencies": {
45
46
  "@tscircuit/footprinter": "^0.0.57",
46
47
  "@tscircuit/routing": "^1.3.5",
47
- "circuit-json": "*",
48
48
  "@tscircuit/soup-util": "^0.0.28",
49
49
  "@types/node": "^22.5.5",
50
- "schematic-symbols": "^0.0.17",
50
+ "circuit-json": "*",
51
+ "schematic-symbols": "^0.0.32",
51
52
  "svgson": "^5.3.1",
52
53
  "transformation-matrix": "^2.16.1"
53
54
  }