fritzkit 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/.claude-plugin/marketplace.json +12 -0
  2. package/.claude-plugin/plugin.json +13 -0
  3. package/CHANGELOG.md +8 -0
  4. package/LICENSE +21 -0
  5. package/README.md +429 -2
  6. package/dist/cli/commands/doctor.d.ts +4 -0
  7. package/dist/cli/commands/doctor.js +7 -0
  8. package/dist/cli/commands/doctor.js.map +1 -0
  9. package/dist/cli/commands/export.d.ts +17 -0
  10. package/dist/cli/commands/export.js +81 -0
  11. package/dist/cli/commands/export.js.map +1 -0
  12. package/dist/cli/commands/kicad.d.ts +10 -0
  13. package/dist/cli/commands/kicad.js +22 -0
  14. package/dist/cli/commands/kicad.js.map +1 -0
  15. package/dist/cli/commands/parts.d.ts +22 -0
  16. package/dist/cli/commands/parts.js +46 -0
  17. package/dist/cli/commands/parts.js.map +1 -0
  18. package/dist/cli/commands/prune.d.ts +14 -0
  19. package/dist/cli/commands/prune.js +67 -0
  20. package/dist/cli/commands/prune.js.map +1 -0
  21. package/dist/cli/commands/render.d.ts +24 -0
  22. package/dist/cli/commands/render.js +62 -0
  23. package/dist/cli/commands/render.js.map +1 -0
  24. package/dist/cli/commands/schema.d.ts +10 -0
  25. package/dist/cli/commands/schema.js +35 -0
  26. package/dist/cli/commands/schema.js.map +1 -0
  27. package/dist/cli/commands/ui.d.ts +14 -0
  28. package/dist/cli/commands/ui.js +67 -0
  29. package/dist/cli/commands/ui.js.map +1 -0
  30. package/dist/cli/commands/validate.d.ts +24 -0
  31. package/dist/cli/commands/validate.js +91 -0
  32. package/dist/cli/commands/validate.js.map +1 -0
  33. package/dist/cli/context.d.ts +81 -0
  34. package/dist/cli/context.js +139 -0
  35. package/dist/cli/context.js.map +1 -0
  36. package/dist/cli/main.d.ts +2 -0
  37. package/dist/cli/main.js +8 -0
  38. package/dist/cli/main.js.map +1 -0
  39. package/dist/cli/program.d.ts +21 -0
  40. package/dist/cli/program.js +158 -0
  41. package/dist/cli/program.js.map +1 -0
  42. package/dist/cli/raster.d.ts +4 -0
  43. package/dist/cli/raster.js +9 -0
  44. package/dist/cli/raster.js.map +1 -0
  45. package/dist/core/compile/breadboard-util.d.ts +12 -0
  46. package/dist/core/compile/breadboard-util.js +107 -0
  47. package/dist/core/compile/breadboard-util.js.map +1 -0
  48. package/dist/core/compile/breadboard.d.ts +60 -0
  49. package/dist/core/compile/breadboard.js +513 -0
  50. package/dist/core/compile/breadboard.js.map +1 -0
  51. package/dist/core/compile/fzp.d.ts +12 -0
  52. package/dist/core/compile/fzp.js +183 -0
  53. package/dist/core/compile/fzp.js.map +1 -0
  54. package/dist/core/compile/icon.d.ts +17 -0
  55. package/dist/core/compile/icon.js +27 -0
  56. package/dist/core/compile/icon.js.map +1 -0
  57. package/dist/core/compile/index.d.ts +4 -0
  58. package/dist/core/compile/index.js +62 -0
  59. package/dist/core/compile/index.js.map +1 -0
  60. package/dist/core/compile/pcb.d.ts +39 -0
  61. package/dist/core/compile/pcb.js +164 -0
  62. package/dist/core/compile/pcb.js.map +1 -0
  63. package/dist/core/compile/schematic.d.ts +69 -0
  64. package/dist/core/compile/schematic.js +240 -0
  65. package/dist/core/compile/schematic.js.map +1 -0
  66. package/dist/core/compile/style.d.ts +52 -0
  67. package/dist/core/compile/style.js +72 -0
  68. package/dist/core/compile/style.js.map +1 -0
  69. package/dist/core/compile/types.d.ts +50 -0
  70. package/dist/core/compile/types.js +15 -0
  71. package/dist/core/compile/types.js.map +1 -0
  72. package/dist/core/export/bin.d.ts +61 -0
  73. package/dist/core/export/bin.js +221 -0
  74. package/dist/core/export/bin.js.map +1 -0
  75. package/dist/core/export/fzpz.d.ts +37 -0
  76. package/dist/core/export/fzpz.js +121 -0
  77. package/dist/core/export/fzpz.js.map +1 -0
  78. package/dist/core/export/index.d.ts +5 -0
  79. package/dist/core/export/index.js +6 -0
  80. package/dist/core/export/index.js.map +1 -0
  81. package/dist/core/export/install.d.ts +77 -0
  82. package/dist/core/export/install.js +183 -0
  83. package/dist/core/export/install.js.map +1 -0
  84. package/dist/core/export/prune.d.ts +72 -0
  85. package/dist/core/export/prune.js +165 -0
  86. package/dist/core/export/prune.js.map +1 -0
  87. package/dist/core/fritzing.d.ts +22 -0
  88. package/dist/core/fritzing.js +77 -0
  89. package/dist/core/fritzing.js.map +1 -0
  90. package/dist/core/identity.d.ts +29 -0
  91. package/dist/core/identity.js +70 -0
  92. package/dist/core/identity.js.map +1 -0
  93. package/dist/core/image/bbox.d.ts +27 -0
  94. package/dist/core/image/bbox.js +24 -0
  95. package/dist/core/image/bbox.js.map +1 -0
  96. package/dist/core/image/index.d.ts +8 -0
  97. package/dist/core/image/index.js +9 -0
  98. package/dist/core/image/index.js.map +1 -0
  99. package/dist/core/image/key.d.ts +72 -0
  100. package/dist/core/image/key.js +317 -0
  101. package/dist/core/image/key.js.map +1 -0
  102. package/dist/core/image/prepare.d.ts +31 -0
  103. package/dist/core/image/prepare.js +98 -0
  104. package/dist/core/image/prepare.js.map +1 -0
  105. package/dist/core/image/remover.d.ts +17 -0
  106. package/dist/core/image/remover.js +51 -0
  107. package/dist/core/image/remover.js.map +1 -0
  108. package/dist/core/index.d.ts +16 -0
  109. package/dist/core/index.js +17 -0
  110. package/dist/core/index.js.map +1 -0
  111. package/dist/core/kicad/footprint.d.ts +104 -0
  112. package/dist/core/kicad/footprint.js +317 -0
  113. package/dist/core/kicad/footprint.js.map +1 -0
  114. package/dist/core/kicad/index.d.ts +25 -0
  115. package/dist/core/kicad/index.js +197 -0
  116. package/dist/core/kicad/index.js.map +1 -0
  117. package/dist/core/kicad/sexpr.d.ts +35 -0
  118. package/dist/core/kicad/sexpr.js +163 -0
  119. package/dist/core/kicad/sexpr.js.map +1 -0
  120. package/dist/core/resolve.d.ts +113 -0
  121. package/dist/core/resolve.js +301 -0
  122. package/dist/core/resolve.js.map +1 -0
  123. package/dist/core/schema/part.d.ts +995 -0
  124. package/dist/core/schema/part.js +278 -0
  125. package/dist/core/schema/part.js.map +1 -0
  126. package/dist/core/schema/part.schema.json +1122 -0
  127. package/dist/core/svg.d.ts +20 -0
  128. package/dist/core/svg.js +56 -0
  129. package/dist/core/svg.js.map +1 -0
  130. package/dist/core/units.d.ts +28 -0
  131. package/dist/core/units.js +42 -0
  132. package/dist/core/units.js.map +1 -0
  133. package/dist/core/validate/checker.d.ts +46 -0
  134. package/dist/core/validate/checker.js +142 -0
  135. package/dist/core/validate/checker.js.map +1 -0
  136. package/dist/core/validate/doctor.d.ts +25 -0
  137. package/dist/core/validate/doctor.js +156 -0
  138. package/dist/core/validate/doctor.js.map +1 -0
  139. package/dist/core/validate/explain.d.ts +10 -0
  140. package/dist/core/validate/explain.js +135 -0
  141. package/dist/core/validate/explain.js.map +1 -0
  142. package/dist/core/validate/index.d.ts +21 -0
  143. package/dist/core/validate/index.js +96 -0
  144. package/dist/core/validate/index.js.map +1 -0
  145. package/dist/core/validate/structural.d.ts +74 -0
  146. package/dist/core/validate/structural.js +664 -0
  147. package/dist/core/validate/structural.js.map +1 -0
  148. package/dist/core/workspace.d.ts +69 -0
  149. package/dist/core/workspace.js +213 -0
  150. package/dist/core/workspace.js.map +1 -0
  151. package/dist/mcp/jsonpatch.d.ts +30 -0
  152. package/dist/mcp/jsonpatch.js +145 -0
  153. package/dist/mcp/jsonpatch.js.map +1 -0
  154. package/dist/mcp/main.d.ts +2 -0
  155. package/dist/mcp/main.js +5 -0
  156. package/dist/mcp/main.js.map +1 -0
  157. package/dist/mcp/server.d.ts +28 -0
  158. package/dist/mcp/server.js +310 -0
  159. package/dist/mcp/server.js.map +1 -0
  160. package/dist/server/api.d.ts +72 -0
  161. package/dist/server/api.js +507 -0
  162. package/dist/server/api.js.map +1 -0
  163. package/dist/server/events.d.ts +28 -0
  164. package/dist/server/events.js +134 -0
  165. package/dist/server/events.js.map +1 -0
  166. package/dist/server/http.d.ts +36 -0
  167. package/dist/server/http.js +127 -0
  168. package/dist/server/http.js.map +1 -0
  169. package/dist/server/index.d.ts +65 -0
  170. package/dist/server/index.js +193 -0
  171. package/dist/server/index.js.map +1 -0
  172. package/dist/ui/assets/index-DLU8opyI.js +63 -0
  173. package/dist/ui/assets/index-GhUA-T3b.css +1 -0
  174. package/dist/ui/index.html +14 -0
  175. package/package.json +89 -4
  176. package/skills/fritzkit/SKILL.md +690 -0
  177. package/skills/fritzkit/reference/examples.md +275 -0
  178. package/skills/fritzkit/reference/part-json.md +333 -0
  179. package/skills/fritzkit/scripts/measure.py +197 -0
  180. package/tools/fzp-checker/.python-version +1 -0
  181. package/tools/fzp-checker/README.md +45 -0
  182. package/tools/fzp-checker/check_fzp.py +48 -0
  183. package/tools/fzp-checker/pyproject.toml +26 -0
  184. package/tools/fzp-checker/uv.lock +266 -0
  185. package/tools/fzp-checker/vendor/LICENSE.txt +8 -0
  186. package/tools/fzp-checker/vendor/UPSTREAM.md +25 -0
  187. package/tools/fzp-checker/vendor/fzp_checker.py +14 -0
  188. package/tools/fzp-checker/vendor/scripts/checks/__init__.py +26 -0
  189. package/tools/fzp-checker/vendor/scripts/checks/check_missing_leg_ids.py +44 -0
  190. package/tools/fzp-checker/vendor/scripts/checks/checkascii.py +27 -0
  191. package/tools/fzp-checker/vendor/scripts/checks/checkcase.py +156 -0
  192. package/tools/fzp-checker/vendor/scripts/checks/checkcopies.py +104 -0
  193. package/tools/fzp-checker/vendor/scripts/checks/connector_numbering.py +79 -0
  194. package/tools/fzp-checker/vendor/scripts/checks/connectors_misnumbered.py +228 -0
  195. package/tools/fzp-checker/vendor/scripts/checks/explain_errors.md +95 -0
  196. package/tools/fzp-checker/vendor/scripts/checks/fzp_checker_runner.py +717 -0
  197. package/tools/fzp-checker/vendor/scripts/checks/fzp_checkers.py +1069 -0
  198. package/tools/fzp-checker/vendor/scripts/checks/fzp_svg_checkers.py +62 -0
  199. package/tools/fzp-checker/vendor/scripts/checks/fzp_utils.py +222 -0
  200. package/tools/fzp-checker/vendor/scripts/checks/inspector_fc51.png +0 -0
  201. package/tools/fzp-checker/vendor/scripts/checks/invisibleconnectors.py +118 -0
  202. package/tools/fzp-checker/vendor/scripts/checks/nolayeridcheck.txt +758 -0
  203. package/tools/fzp-checker/vendor/scripts/checks/requirements.txt +3 -0
  204. package/tools/fzp-checker/vendor/scripts/checks/svg_checkers.py +953 -0
  205. package/tools/fzp-checker/vendor/scripts/checks/svg_utils.py +96 -0
  206. package/tools/fzp-checker/vendor/scripts/checks/test_checkers.py +839 -0
  207. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/author_missing.fzp.test +3 -0
  208. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/author_present.fzp.test +4 -0
  209. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/buses_missing_id.fzp.test +8 -0
  210. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/buses_missing_node_members.fzp.test +7 -0
  211. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/buses_present_valid.fzp.test +8 -0
  212. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_layers_missing_attributes.fzp.test +16 -0
  213. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_layers_present_valid.fzp.test +14 -0
  214. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_numbering_invalid.fzp.test +70 -0
  215. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_numbering_valid.fzp.test +70 -0
  216. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_refs_valid.fzp.test +53 -0
  217. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_mixed.fzp.test +11 -0
  218. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_silkscreen_nested.fzp.test +11 -0
  219. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_style_attr.fzp.test +11 -0
  220. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_white_stroke.fzp.test +11 -0
  221. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_wrong_color.fzp.test +11 -0
  222. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_inherited.fzp.test +11 -0
  223. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_legacy.fzp.test +12 -0
  224. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_nested_copper.fzp.test +12 -0
  225. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_none.fzp.test +11 -0
  226. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_standard.fzp.test +12 -0
  227. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_uppercase.fzp.test +11 -0
  228. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/css_connector.fzp.test +100 -0
  229. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/description_missing.fzp.test +3 -0
  230. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/description_present.fzp.test +4 -0
  231. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/duplicate_ids.fzp.test +27 -0
  232. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/family_property_missing.fzp.test +6 -0
  233. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/family_property_present_valid.fzp.test +6 -0
  234. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/font_size.fzp.test +46 -0
  235. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/fritzing_version_invalid_format.fzp.test +4 -0
  236. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/fritzing_version_missing.fzp.test +4 -0
  237. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/fritzing_version_present_valid.fzp.test +4 -0
  238. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/gorn_absent.fzp.test +15 -0
  239. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/gorn_present.fzp.test +15 -0
  240. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/hybrid_connectors.fzp.test +232 -0
  241. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/invalid_xml.fzp.test +12 -0
  242. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/layer_ids_match.fzp.test +29 -0
  243. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/layer_ids_mismatch.fzp.test +30 -0
  244. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/layer_nesting_invalid.fzp.test +11 -0
  245. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/layer_nesting_valid.fzp.test +11 -0
  246. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/matrix_transform.fzp.test +8 -0
  247. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/missing_connector_refs.fzp.test +63 -0
  248. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/missing_leg_ids.fzp.test +34 -0
  249. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_missing.fzp.test +4 -0
  250. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_non_alnum.fzp.test +4 -0
  251. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_present.fzp.test +4 -0
  252. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_special_chars_absent.fzp.test +4 -0
  253. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_special_chars_present.fzp.test +4 -0
  254. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_too_short.fzp.test +4 -0
  255. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/no_layer_invalid.fzp.test +19 -0
  256. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/no_layer_namedview.fzp.test +19 -0
  257. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/no_layer_valid.fzp.test +19 -0
  258. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/pcb_only.fzp.test +48 -0
  259. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/property_fields_missing_name.fzp.test +6 -0
  260. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/property_fields_missing_value.fzp.test +6 -0
  261. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/property_fields_present.fzp.test +6 -0
  262. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/required_tags_missing.fzp.test +3 -0
  263. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/required_tags_present.fzp.test +11 -0
  264. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/stroke_test.fzp.test +60 -0
  265. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/template_svgs.fzp.test +35 -0
  266. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/title_missing.fzp.test +3 -0
  267. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/title_present.fzp.test +4 -0
  268. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/unique_ids.fzp.test +27 -0
  269. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/unique_property_names_duplicates.fzp.test +7 -0
  270. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/unique_property_names_unique.fzp.test +7 -0
  271. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/valid_xml.fzp.test +249 -0
  272. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/version_invalid_format.fzp.test +4 -0
  273. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/version_missing.fzp.test +3 -0
  274. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/version_present_valid.fzp.test +4 -0
  275. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/views_missing.fzp.test +3 -0
  276. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/views_present.fzp.test +8 -0
  277. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/connector_refs_valid_breadboard.svg +7 -0
  278. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/duplicate_ids_breadboard.svg +13 -0
  279. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/gorn_absent_breadboard.svg +7 -0
  280. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/gorn_present_breadboard.svg +7 -0
  281. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/hybrid_connectors_breadboard.svg +102 -0
  282. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/layer_nesting_invalid.svg +13 -0
  283. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/layer_nesting_valid.svg +13 -0
  284. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/matrix_transform.svg +11 -0
  285. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/missing_connector_refs_breadboard.svg +8 -0
  286. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/missing_leg_ids_breadboard.svg +9 -0
  287. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/test_layer_ids_match_breadboard.svg +9 -0
  288. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/test_layer_ids_mismatch_breadboard.svg +9 -0
  289. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/unique_ids_breadboard.svg +13 -0
  290. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/hybrid_connectors_icon.svg +78 -0
  291. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/no_layer_invalid.svg +4 -0
  292. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/no_layer_namedview.svg +9 -0
  293. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/no_layer_valid.svg +7 -0
  294. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/plain_pcb.svg +10 -0
  295. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/connector_refs_valid_pcb.svg +10 -0
  296. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_mixed.svg +8 -0
  297. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_silkscreen_nested.svg +10 -0
  298. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_style_attr.svg +6 -0
  299. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_white_stroke.svg +6 -0
  300. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_wrong_color.svg +6 -0
  301. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_inherited.svg +7 -0
  302. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_legacy.svg +10 -0
  303. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_nested_copper.svg +9 -0
  304. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_none.svg +7 -0
  305. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_standard.svg +10 -0
  306. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_uppercase.svg +7 -0
  307. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/css_connector.svg +25 -0
  308. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/font_size.svg +54 -0
  309. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/hybrid_connectors_pcb.svg +35 -0
  310. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/missing_connector_refs_pcb.svg +14 -0
  311. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/pcb-arduino-shield.svg +25 -0
  312. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/stroke_test.svg +12 -0
  313. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/test_layer_ids_match_pcb.svg +12 -0
  314. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/test_layer_ids_mismatch_pcb.svg +12 -0
  315. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/connector_refs_valid_schematic.svg +7 -0
  316. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/hybrid_connectors_schematic.svg +59 -0
  317. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/missing_connector_refs_schematic.svg +8 -0
  318. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/test_layer_ids_match_schematic.svg +6 -0
  319. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/test_layer_ids_mismatch_schematic.svg +6 -0
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Optional ML background remover (spec decision D19, method "ml").
3
+ *
4
+ * Uses @imgly/background-removal-node, which is AGPL-3.0 licensed. fritzkit is MIT, so
5
+ * the module is NOT a dependency: the user installs it explicitly to opt in, and it is
6
+ * only loaded at runtime when method "ml" is requested.
7
+ */
8
+ export declare const ML_REMOVER_MODULE = "@imgly/background-removal-node";
9
+ export declare const ML_INSTALL_HINT: string;
10
+ export interface RemoverOptions {
11
+ /** Module loader (tests inject a fake). Defaults to a dynamic import of the package. */
12
+ load?: () => Promise<unknown>;
13
+ }
14
+ /** Mime type from magic bytes (PNG, JPEG, WebP); PNG when unknown. */
15
+ export declare function sniffMime(data: Uint8Array): string;
16
+ /** Remove the background with the ML model. Returns RGBA PNG bytes. */
17
+ export declare function removeBackgroundMl(data: Uint8Array, opts?: RemoverOptions): Promise<Uint8Array>;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Optional ML background remover (spec decision D19, method "ml").
3
+ *
4
+ * Uses @imgly/background-removal-node, which is AGPL-3.0 licensed. fritzkit is MIT, so
5
+ * the module is NOT a dependency: the user installs it explicitly to opt in, and it is
6
+ * only loaded at runtime when method "ml" is requested.
7
+ */
8
+ export const ML_REMOVER_MODULE = "@imgly/background-removal-node";
9
+ export const ML_INSTALL_HINT = `The "ml" background remover needs the optional package ${ML_REMOVER_MODULE} ` +
10
+ `(AGPL-3.0, not installed by default). Install it with: npm install ${ML_REMOVER_MODULE} ` +
11
+ `- or use the default "key" method.`;
12
+ /** Mime type from magic bytes (PNG, JPEG, WebP); PNG when unknown. */
13
+ export function sniffMime(data) {
14
+ if (data[0] === 0xff && data[1] === 0xd8)
15
+ return "image/jpeg";
16
+ const tag = String.fromCharCode(...data.subarray(0, 12));
17
+ if (tag.startsWith("RIFF") && tag.slice(8, 12) === "WEBP")
18
+ return "image/webp";
19
+ return "image/png";
20
+ }
21
+ function isModuleNotFound(err) {
22
+ const code = err?.code;
23
+ return code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND";
24
+ }
25
+ function pickApi(mod) {
26
+ const m = mod;
27
+ const fn = m?.removeBackground ?? m?.default?.removeBackground;
28
+ return typeof fn === "function" ? fn : undefined;
29
+ }
30
+ /** Remove the background with the ML model. Returns RGBA PNG bytes. */
31
+ export async function removeBackgroundMl(data, opts = {}) {
32
+ const specifier = ML_REMOVER_MODULE;
33
+ const load = opts.load ?? (() => import(specifier));
34
+ let mod;
35
+ try {
36
+ mod = await load();
37
+ }
38
+ catch (err) {
39
+ if (isModuleNotFound(err))
40
+ throw new Error(ML_INSTALL_HINT, { cause: err });
41
+ throw new Error(`failed to load ${ML_REMOVER_MODULE}: ${String(err)}`, { cause: err });
42
+ }
43
+ const removeBackground = pickApi(mod);
44
+ if (!removeBackground) {
45
+ throw new Error(`${ML_REMOVER_MODULE} does not export removeBackground(); unsupported version`);
46
+ }
47
+ const input = new Blob([new Uint8Array(data)], { type: sniffMime(data) });
48
+ const blob = await removeBackground(input, { output: { format: "image/png" } });
49
+ return new Uint8Array(await blob.arrayBuffer());
50
+ }
51
+ //# sourceMappingURL=remover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remover.js","sourceRoot":"","sources":["../../../src/core/image/remover.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,gCAAgC,CAAC;AAElE,MAAM,CAAC,MAAM,eAAe,GAC1B,0DAA0D,iBAAiB,GAAG;IAC9E,sEAAsE,iBAAiB,GAAG;IAC1F,oCAAoC,CAAC;AAcvC,sEAAsE;AACtE,MAAM,UAAU,SAAS,CAAC,IAAgB;IACxC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,YAAY,CAAC;IAC9D,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACzD,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM;QAAE,OAAO,YAAY,CAAC;IAC/E,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAY;IACpC,MAAM,IAAI,GAAI,GAAiC,EAAE,IAAI,CAAC;IACtD,OAAO,IAAI,KAAK,sBAAsB,IAAI,IAAI,KAAK,kBAAkB,CAAC;AACxE,CAAC;AAED,SAAS,OAAO,CAAC,GAAY;IAC3B,MAAM,CAAC,GAAG,GAA+E,CAAC;IAC1F,MAAM,EAAE,GAAG,CAAC,EAAE,gBAAgB,IAAI,CAAC,EAAE,OAAO,EAAE,gBAAgB,CAAC;IAC/D,OAAO,OAAO,EAAE,KAAK,UAAU,CAAC,CAAC,CAAE,EAAsC,CAAC,CAAC,CAAC,SAAS,CAAC;AACxF,CAAC;AAED,uEAAuE;AACvE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAgB,EAChB,OAAuB,EAAE;IAEzB,MAAM,SAAS,GAAG,iBAAiB,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAqB,CAAC,CAAC;IACxE,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,IAAI,EAAE,CAAC;IACrB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,gBAAgB,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5E,MAAM,IAAI,KAAK,CAAC,kBAAkB,iBAAiB,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,GAAG,iBAAiB,0DAA0D,CAAC,CAAC;IAClG,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1E,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;IAChF,OAAO,IAAI,UAAU,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * fritzkit core: pure functions that turn a part spec into Fritzing part files.
3
+ * Everything here is offline and deterministic (spec decision D2).
4
+ */
5
+ export declare const FRITZING_VERSION = "1.0.7";
6
+ export * from "./units.js";
7
+ export * from "./schema/part.js";
8
+ export * from "./resolve.js";
9
+ export * from "./identity.js";
10
+ export * from "./compile/types.js";
11
+ export { compilePart, GENERATOR } from "./compile/index.js";
12
+ export * from "./export/index.js";
13
+ export * from "./fritzing.js";
14
+ export * from "./validate/index.js";
15
+ export { parseKicadMod, kicadToSpecFragment, importKicadFile, chooseOutline, KicadParseError, KicadImportError, type KicadFootprint, type KicadPad, type KicadImportOptions, } from "./kicad/index.js";
16
+ export { preparePhoto, detectBoardBbox, keyBackground } from "./image/index.js";
@@ -0,0 +1,17 @@
1
+ /**
2
+ * fritzkit core: pure functions that turn a part spec into Fritzing part files.
3
+ * Everything here is offline and deterministic (spec decision D2).
4
+ */
5
+ export const FRITZING_VERSION = "1.0.7";
6
+ export * from "./units.js";
7
+ export * from "./schema/part.js";
8
+ export * from "./resolve.js";
9
+ export * from "./identity.js";
10
+ export * from "./compile/types.js";
11
+ export { compilePart, GENERATOR } from "./compile/index.js";
12
+ export * from "./export/index.js";
13
+ export * from "./fritzing.js";
14
+ export * from "./validate/index.js";
15
+ export { parseKicadMod, kicadToSpecFragment, importKicadFile, chooseOutline, KicadParseError, KicadImportError, } from "./kicad/index.js";
16
+ export { preparePhoto, detectBoardBbox, keyBackground } from "./image/index.js";
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AAExC,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC5D,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,eAAe,EACf,gBAAgB,GAIjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,104 @@
1
+ export type KicadPadType = "thru_hole" | "smd" | "np_thru_hole" | "connect";
2
+ export type KicadPadShape = "circle" | "rect" | "roundrect" | "oval" | "custom" | "trapezoid";
3
+ export interface KicadPad {
4
+ /** Pad number as written ("" for unnumbered mechanical pads). */
5
+ number: string;
6
+ type: KicadPadType;
7
+ shape: KicadPadShape;
8
+ /** Pad centre, footprint frame, mm, y down. */
9
+ x: number;
10
+ y: number;
11
+ /** Pad size before rotation. */
12
+ w: number;
13
+ h: number;
14
+ /** Round drill diameter, or the SMALLER axis of an oval drill. */
15
+ drill?: number;
16
+ /** Full drill geometry when a drill is present. */
17
+ drillShape?: "circle" | "oval";
18
+ drillW?: number;
19
+ drillH?: number;
20
+ layers: string[];
21
+ /** Degrees as written, normalised to [0, 360). */
22
+ rotation: number;
23
+ /** Source line of the pad list. */
24
+ line: number;
25
+ }
26
+ export interface KicadPoint {
27
+ x: number;
28
+ y: number;
29
+ }
30
+ export interface KicadLine {
31
+ x1: number;
32
+ y1: number;
33
+ x2: number;
34
+ y2: number;
35
+ layer: string;
36
+ width: number;
37
+ }
38
+ export interface KicadRect extends KicadLine {
39
+ filled: boolean;
40
+ }
41
+ export interface KicadCircle {
42
+ cx: number;
43
+ cy: number;
44
+ r: number;
45
+ layer: string;
46
+ width: number;
47
+ }
48
+ export interface KicadArc {
49
+ start: KicadPoint;
50
+ end: KicadPoint;
51
+ center: KicadPoint;
52
+ radius: number;
53
+ /** Signed sweep from start to end in degrees, measured with atan2 in the y-down frame. */
54
+ sweepDeg: number;
55
+ layer: string;
56
+ width: number;
57
+ }
58
+ export interface KicadPoly {
59
+ points: KicadPoint[];
60
+ layer: string;
61
+ width: number;
62
+ }
63
+ export interface BBox {
64
+ minX: number;
65
+ minY: number;
66
+ maxX: number;
67
+ maxY: number;
68
+ }
69
+ export interface KicadFootprint {
70
+ name: string;
71
+ /** "module" = KiCad 5 legacy header, "footprint" = KiCad 6+. */
72
+ format: "module" | "footprint";
73
+ version?: number;
74
+ generator?: string;
75
+ layer: string;
76
+ descr?: string;
77
+ tags?: string;
78
+ reference?: string;
79
+ value?: string;
80
+ pads: KicadPad[];
81
+ lines: KicadLine[];
82
+ rects: KicadRect[];
83
+ circles: KicadCircle[];
84
+ arcs: KicadArc[];
85
+ polys: KicadPoly[];
86
+ bbox: {
87
+ edge?: BBox;
88
+ courtyard?: BBox;
89
+ fab?: BBox;
90
+ silk?: BBox;
91
+ pads?: BBox;
92
+ };
93
+ }
94
+ /**
95
+ * Axis-aligned extent of a pad in the footprint frame. 0/180 keep w x h, 90/270 swap
96
+ * them exactly; any other angle gives the bounding box of the rotated rectangle
97
+ * (a circle pad keeps its size).
98
+ */
99
+ export declare function padExtent(pad: Pick<KicadPad, "w" | "h" | "rotation" | "shape">): {
100
+ w: number;
101
+ h: number;
102
+ };
103
+ /** Parse .kicad_mod text. Throws KicadParseError (with a line number) on bad input. */
104
+ export declare function parseKicadMod(text: string): KicadFootprint;
@@ -0,0 +1,317 @@
1
+ /**
2
+ * Parse a KiCad footprint (.kicad_mod) into plain geometry.
3
+ *
4
+ * Supported headers: KiCad 5 legacy `(module NAME (layer F.Cu) (tedit ..) ...)` and
5
+ * KiCad 6/7/8 `(footprint "NAME" (version ..) (generator ..) (layer "F.Cu") ...)`.
6
+ *
7
+ * Coordinate convention (assumed and applied everywhere): values are millimetres in
8
+ * the footprint frame exactly as stored in the file, origin at the footprint anchor,
9
+ * x to the right and y DOWN. KiCad's internal board coordinate system is y-down and
10
+ * .kicad_mod files store it unflipped (pin 2 of a vertical header at (at 0 2.54) sits
11
+ * BELOW pin 1), which is the same orientation as fritzkit's part frame, so no axis is
12
+ * flipped anywhere. Pad rotation (the third `at` value, degrees) is kept as written,
13
+ * normalised to [0, 360); only its effect on the pad's axis-aligned extent is used.
14
+ *
15
+ * Unknown list heads (attr, model, uuid, tstamp, embedded_fonts, fp_text user, ...)
16
+ * are ignored. Graphics on any layer are collected; bounding boxes are computed from
17
+ * the geometric centre lines (stroke width ignored) for Edge.Cuts, courtyard
18
+ * (F/B.CrtYd), fab (F/B.Fab), silkscreen (F/B.SilkS) and the pads.
19
+ */
20
+ import { find, findAll, KicadParseError, lineOf, num, parseSExpr, str, } from "./sexpr.js";
21
+ const PAD_TYPES = ["thru_hole", "smd", "np_thru_hole", "connect"];
22
+ const PAD_SHAPES = [
23
+ "circle",
24
+ "rect",
25
+ "roundrect",
26
+ "oval",
27
+ "custom",
28
+ "trapezoid",
29
+ ];
30
+ function point(list, what, parent) {
31
+ const x = num(list, 1);
32
+ const y = num(list, 2);
33
+ if (x === undefined || y === undefined) {
34
+ throw new KicadParseError(`missing or invalid (${what} x y)`, lineOf(list ?? parent));
35
+ }
36
+ return { x, y };
37
+ }
38
+ function layerOf(list) {
39
+ return str(find(list, "layer"), 1) ?? "";
40
+ }
41
+ /** KiCad 5/6 `(width w)` or KiCad 7/8 `(stroke (width w) (type ..))`. */
42
+ function strokeWidth(list) {
43
+ return num(find(list, "width"), 1) ?? num(find(find(list, "stroke") ?? [], "width"), 1) ?? 0;
44
+ }
45
+ function isFilled(list) {
46
+ const f = str(find(list, "fill"), 1);
47
+ return f === "solid" || f === "yes";
48
+ }
49
+ function normDeg(d) {
50
+ const r = ((d % 360) + 360) % 360;
51
+ return Math.abs(r - 360) < 1e-9 ? 0 : r;
52
+ }
53
+ function angleOf(c, p) {
54
+ return normDeg((Math.atan2(p.y - c.y, p.x - c.x) * 180) / Math.PI);
55
+ }
56
+ function parseArc(l) {
57
+ const layer = layerOf(l);
58
+ const width = strokeWidth(l);
59
+ const midList = find(l, "mid");
60
+ if (midList) {
61
+ // KiCad 6+: three points on the arc.
62
+ const a = point(find(l, "start"), "start", l);
63
+ const m = point(midList, "mid", l);
64
+ const b = point(find(l, "end"), "end", l);
65
+ const d = 2 * (a.x * (m.y - b.y) + m.x * (b.y - a.y) + b.x * (a.y - m.y));
66
+ if (Math.abs(d) < 1e-12)
67
+ return undefined; // collinear: not an arc
68
+ const a2 = a.x * a.x + a.y * a.y;
69
+ const m2 = m.x * m.x + m.y * m.y;
70
+ const b2 = b.x * b.x + b.y * b.y;
71
+ const center = {
72
+ x: (a2 * (m.y - b.y) + m2 * (b.y - a.y) + b2 * (a.y - m.y)) / d,
73
+ y: (a2 * (b.x - m.x) + m2 * (a.x - b.x) + b2 * (m.x - a.x)) / d,
74
+ };
75
+ const radius = Math.hypot(a.x - center.x, a.y - center.y);
76
+ const as = angleOf(center, a);
77
+ const ccw = normDeg(angleOf(center, b) - as);
78
+ const toMid = normDeg(angleOf(center, m) - as);
79
+ const sweepDeg = toMid <= ccw ? ccw : ccw - 360;
80
+ return { start: a, end: b, center, radius, sweepDeg, layer, width };
81
+ }
82
+ // KiCad 5: (start = centre) (end = arc start point) (angle sweep).
83
+ const center = point(find(l, "start"), "start", l);
84
+ const start = point(find(l, "end"), "end", l);
85
+ const sweepDeg = num(find(l, "angle"), 1) ?? 0;
86
+ const radius = Math.hypot(start.x - center.x, start.y - center.y);
87
+ const a1 = ((angleOf(center, start) + sweepDeg) * Math.PI) / 180;
88
+ const end = { x: center.x + radius * Math.cos(a1), y: center.y + radius * Math.sin(a1) };
89
+ return { start, end, center, radius, sweepDeg, layer, width };
90
+ }
91
+ /** Points that bound an arc: both ends plus every axis extreme inside the sweep. */
92
+ function arcExtremes(a) {
93
+ const pts = [a.start, a.end];
94
+ const as = angleOf(a.center, a.start);
95
+ for (const q of [0, 90, 180, 270]) {
96
+ const off = a.sweepDeg >= 0 ? normDeg(q - as) : normDeg(as - q);
97
+ if (off <= Math.abs(a.sweepDeg) + 1e-9) {
98
+ pts.push({
99
+ x: a.center.x + a.radius * Math.cos((q * Math.PI) / 180),
100
+ y: a.center.y + a.radius * Math.sin((q * Math.PI) / 180),
101
+ });
102
+ }
103
+ }
104
+ return pts;
105
+ }
106
+ /**
107
+ * Axis-aligned extent of a pad in the footprint frame. 0/180 keep w x h, 90/270 swap
108
+ * them exactly; any other angle gives the bounding box of the rotated rectangle
109
+ * (a circle pad keeps its size).
110
+ */
111
+ export function padExtent(pad) {
112
+ const r = normDeg(pad.rotation);
113
+ if (r === 0 || r === 180)
114
+ return { w: pad.w, h: pad.h };
115
+ if (r === 90 || r === 270)
116
+ return { w: pad.h, h: pad.w };
117
+ if (pad.shape === "circle")
118
+ return { w: pad.w, h: pad.h };
119
+ const t = (r * Math.PI) / 180;
120
+ const c = Math.abs(Math.cos(t));
121
+ const s = Math.abs(Math.sin(t));
122
+ return { w: pad.w * c + pad.h * s, h: pad.w * s + pad.h * c };
123
+ }
124
+ function parsePad(p) {
125
+ const line = lineOf(p);
126
+ const number = str(p, 1) ?? "";
127
+ const type = str(p, 2);
128
+ const shape = str(p, 3);
129
+ if (type === undefined || !PAD_TYPES.includes(type)) {
130
+ throw new KicadParseError(`pad "${number}": unknown pad type "${type ?? "(list)"}"`, line);
131
+ }
132
+ if (shape === undefined || !PAD_SHAPES.includes(shape)) {
133
+ throw new KicadParseError(`pad "${number}": unknown pad shape "${shape ?? "(list)"}"`, line);
134
+ }
135
+ const at = find(p, "at");
136
+ const pos = point(at, "at", p);
137
+ const size = find(p, "size");
138
+ const w = num(size, 1);
139
+ const h = num(size, 2) ?? w;
140
+ if (w === undefined || h === undefined) {
141
+ throw new KicadParseError(`pad "${number}": missing (size w h)`, line);
142
+ }
143
+ const pad = {
144
+ number,
145
+ type: type,
146
+ shape: shape,
147
+ x: pos.x,
148
+ y: pos.y,
149
+ w,
150
+ h,
151
+ layers: (find(p, "layers") ?? [])
152
+ .slice(1)
153
+ .flatMap((v) => (Array.isArray(v) ? [] : [String(v)])),
154
+ rotation: normDeg(num(at, 3) ?? 0),
155
+ line,
156
+ };
157
+ const drill = find(p, "drill");
158
+ if (drill) {
159
+ const oval = drill.includes("oval");
160
+ const nums = drill.slice(1).filter((v) => typeof v === "number");
161
+ const dw = nums[0];
162
+ if (dw !== undefined && dw > 0) {
163
+ const dh = oval ? (nums[1] ?? dw) : dw;
164
+ pad.drillShape = oval ? "oval" : "circle";
165
+ pad.drillW = dw;
166
+ pad.drillH = dh;
167
+ pad.drill = Math.min(dw, dh);
168
+ }
169
+ }
170
+ return pad;
171
+ }
172
+ function emptyBox() {
173
+ return { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity };
174
+ }
175
+ function grow(b, x, y) {
176
+ b.minX = Math.min(b.minX, x);
177
+ b.minY = Math.min(b.minY, y);
178
+ b.maxX = Math.max(b.maxX, x);
179
+ b.maxY = Math.max(b.maxY, y);
180
+ }
181
+ const LAYER_GROUPS = [
182
+ ["edge", ["Edge.Cuts"]],
183
+ ["courtyard", ["F.CrtYd", "B.CrtYd", "F.Courtyard", "B.Courtyard"]],
184
+ ["fab", ["F.Fab", "B.Fab"]],
185
+ ["silk", ["F.SilkS", "B.SilkS", "F.Silkscreen", "B.Silkscreen"]],
186
+ ];
187
+ /** Parse .kicad_mod text. Throws KicadParseError (with a line number) on bad input. */
188
+ export function parseKicadMod(text) {
189
+ const root = parseSExpr(text);
190
+ const kind = root[0];
191
+ if (kind !== "footprint" && kind !== "module") {
192
+ const got = typeof kind === "string" || typeof kind === "number" ? String(kind) : "(...)";
193
+ throw new KicadParseError(`not a KiCad footprint: expected (footprint ...) or (module ...), got (${got} ...)`, lineOf(root));
194
+ }
195
+ const name = str(root, 1);
196
+ if (name === undefined)
197
+ throw new KicadParseError(`(${kind} ...) has no name`, lineOf(root));
198
+ const fp = {
199
+ name,
200
+ format: kind,
201
+ layer: layerOf(root),
202
+ pads: [],
203
+ lines: [],
204
+ rects: [],
205
+ circles: [],
206
+ arcs: [],
207
+ polys: [],
208
+ bbox: {},
209
+ };
210
+ const version = num(find(root, "version"), 1);
211
+ if (version !== undefined)
212
+ fp.version = version;
213
+ const generator = str(find(root, "generator"), 1);
214
+ if (generator !== undefined)
215
+ fp.generator = generator;
216
+ const descr = str(find(root, "descr"), 1);
217
+ if (descr !== undefined)
218
+ fp.descr = descr;
219
+ const tags = str(find(root, "tags"), 1);
220
+ if (tags !== undefined)
221
+ fp.tags = tags;
222
+ for (const prop of findAll(root, "property")) {
223
+ const k = str(prop, 1)?.toLowerCase();
224
+ const v = str(prop, 2);
225
+ if (k === "reference" && v !== undefined)
226
+ fp.reference = v;
227
+ else if (k === "value" && v !== undefined)
228
+ fp.value = v;
229
+ }
230
+ for (const t of findAll(root, "fp_text")) {
231
+ const k = str(t, 1);
232
+ const v = str(t, 2);
233
+ if (v === undefined)
234
+ continue;
235
+ if (k === "reference" && fp.reference === undefined)
236
+ fp.reference = v;
237
+ else if (k === "value" && fp.value === undefined)
238
+ fp.value = v;
239
+ }
240
+ for (const p of findAll(root, "pad"))
241
+ fp.pads.push(parsePad(p));
242
+ // Per-layer points that bound the graphics.
243
+ const pts = [];
244
+ const add = (layer, x, y) => pts.push({ layer, x, y });
245
+ for (const l of findAll(root, "fp_line")) {
246
+ const a = point(find(l, "start"), "start", l);
247
+ const b = point(find(l, "end"), "end", l);
248
+ const line = { x1: a.x, y1: a.y, x2: b.x, y2: b.y, layer: layerOf(l), width: strokeWidth(l) };
249
+ fp.lines.push(line);
250
+ add(line.layer, a.x, a.y);
251
+ add(line.layer, b.x, b.y);
252
+ }
253
+ for (const r of findAll(root, "fp_rect")) {
254
+ const a = point(find(r, "start"), "start", r);
255
+ const b = point(find(r, "end"), "end", r);
256
+ const rect = {
257
+ x1: a.x,
258
+ y1: a.y,
259
+ x2: b.x,
260
+ y2: b.y,
261
+ layer: layerOf(r),
262
+ width: strokeWidth(r),
263
+ filled: isFilled(r),
264
+ };
265
+ fp.rects.push(rect);
266
+ add(rect.layer, a.x, a.y);
267
+ add(rect.layer, b.x, b.y);
268
+ }
269
+ for (const c of findAll(root, "fp_circle")) {
270
+ const ctr = point(find(c, "center"), "center", c);
271
+ const e = point(find(c, "end"), "end", c);
272
+ const circle = {
273
+ cx: ctr.x,
274
+ cy: ctr.y,
275
+ r: Math.hypot(e.x - ctr.x, e.y - ctr.y),
276
+ layer: layerOf(c),
277
+ width: strokeWidth(c),
278
+ };
279
+ fp.circles.push(circle);
280
+ add(circle.layer, ctr.x - circle.r, ctr.y - circle.r);
281
+ add(circle.layer, ctr.x + circle.r, ctr.y + circle.r);
282
+ }
283
+ for (const a of findAll(root, "fp_arc")) {
284
+ const arc = parseArc(a);
285
+ if (!arc)
286
+ continue;
287
+ fp.arcs.push(arc);
288
+ for (const q of arcExtremes(arc))
289
+ add(arc.layer, q.x, q.y);
290
+ }
291
+ for (const p of findAll(root, "fp_poly")) {
292
+ const points = findAll(find(p, "pts") ?? [], "xy").map((xy) => point(xy, "xy", p));
293
+ const poly = { points, layer: layerOf(p), width: strokeWidth(p) };
294
+ fp.polys.push(poly);
295
+ for (const q of points)
296
+ add(poly.layer, q.x, q.y);
297
+ }
298
+ for (const [group, layers] of LAYER_GROUPS) {
299
+ const b = emptyBox();
300
+ for (const p of pts)
301
+ if (layers.includes(p.layer))
302
+ grow(b, p.x, p.y);
303
+ if (b.minX <= b.maxX)
304
+ fp.bbox[group] = b;
305
+ }
306
+ if (fp.pads.length) {
307
+ const b = emptyBox();
308
+ for (const p of fp.pads) {
309
+ const e = padExtent(p);
310
+ grow(b, p.x - e.w / 2, p.y - e.h / 2);
311
+ grow(b, p.x + e.w / 2, p.y + e.h / 2);
312
+ }
313
+ fp.bbox.pads = b;
314
+ }
315
+ return fp;
316
+ }
317
+ //# sourceMappingURL=footprint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"footprint.js","sourceRoot":"","sources":["../../../src/core/kicad/footprint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { PartSpecInput } from "../schema/part.js";
2
+ import { type BBox, type KicadFootprint } from "./footprint.js";
3
+ export * from "./sexpr.js";
4
+ export * from "./footprint.js";
5
+ export type KicadOutlineSource = "courtyard" | "fab" | "edge" | "pads";
6
+ export interface KicadImportOptions {
7
+ slug: string;
8
+ title?: string;
9
+ /** Which bbox becomes the outline. Default: first available of edge, courtyard, fab, pads. */
10
+ outline?: KicadOutlineSource;
11
+ }
12
+ export declare class KicadImportError extends Error {
13
+ constructor(message: string);
14
+ }
15
+ /** Margin added around the pads when the outline comes from the pad bbox. */
16
+ export declare const PAD_OUTLINE_MARGIN_MM = 1;
17
+ /** The bbox the outline is taken from, and which source it came from. */
18
+ export declare function chooseOutline(fp: KicadFootprint, want?: KicadOutlineSource): {
19
+ source: KicadOutlineSource;
20
+ box: BBox;
21
+ };
22
+ /** Convert a parsed footprint into a part.json fragment (PartSpecInput). */
23
+ export declare function kicadToSpecFragment(fp: KicadFootprint, opts: KicadImportOptions): PartSpecInput;
24
+ /** Read a .kicad_mod (utf8), parse it and convert it to a part.json fragment. */
25
+ export declare function importKicadFile(path: string, opts: KicadImportOptions): Promise<PartSpecInput>;