fritzkit 0.0.0-stage → 0.1.0

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 (328) 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/__pycache__/__init__.cpython-313.pyc +0 -0
  190. package/tools/fzp-checker/vendor/scripts/checks/__pycache__/check_missing_leg_ids.cpython-313.pyc +0 -0
  191. package/tools/fzp-checker/vendor/scripts/checks/__pycache__/connector_numbering.cpython-313.pyc +0 -0
  192. package/tools/fzp-checker/vendor/scripts/checks/__pycache__/fzp_checker_runner.cpython-313.pyc +0 -0
  193. package/tools/fzp-checker/vendor/scripts/checks/__pycache__/fzp_checkers.cpython-313.pyc +0 -0
  194. package/tools/fzp-checker/vendor/scripts/checks/__pycache__/fzp_svg_checkers.cpython-313.pyc +0 -0
  195. package/tools/fzp-checker/vendor/scripts/checks/__pycache__/fzp_utils.cpython-313.pyc +0 -0
  196. package/tools/fzp-checker/vendor/scripts/checks/__pycache__/svg_checkers.cpython-313.pyc +0 -0
  197. package/tools/fzp-checker/vendor/scripts/checks/__pycache__/svg_utils.cpython-313.pyc +0 -0
  198. package/tools/fzp-checker/vendor/scripts/checks/check_missing_leg_ids.py +44 -0
  199. package/tools/fzp-checker/vendor/scripts/checks/checkascii.py +27 -0
  200. package/tools/fzp-checker/vendor/scripts/checks/checkcase.py +156 -0
  201. package/tools/fzp-checker/vendor/scripts/checks/checkcopies.py +104 -0
  202. package/tools/fzp-checker/vendor/scripts/checks/connector_numbering.py +79 -0
  203. package/tools/fzp-checker/vendor/scripts/checks/connectors_misnumbered.py +228 -0
  204. package/tools/fzp-checker/vendor/scripts/checks/explain_errors.md +95 -0
  205. package/tools/fzp-checker/vendor/scripts/checks/fzp_checker_runner.py +717 -0
  206. package/tools/fzp-checker/vendor/scripts/checks/fzp_checkers.py +1069 -0
  207. package/tools/fzp-checker/vendor/scripts/checks/fzp_svg_checkers.py +62 -0
  208. package/tools/fzp-checker/vendor/scripts/checks/fzp_utils.py +222 -0
  209. package/tools/fzp-checker/vendor/scripts/checks/inspector_fc51.png +0 -0
  210. package/tools/fzp-checker/vendor/scripts/checks/invisibleconnectors.py +118 -0
  211. package/tools/fzp-checker/vendor/scripts/checks/nolayeridcheck.txt +758 -0
  212. package/tools/fzp-checker/vendor/scripts/checks/requirements.txt +3 -0
  213. package/tools/fzp-checker/vendor/scripts/checks/svg_checkers.py +953 -0
  214. package/tools/fzp-checker/vendor/scripts/checks/svg_utils.py +96 -0
  215. package/tools/fzp-checker/vendor/scripts/checks/test_checkers.py +839 -0
  216. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/author_missing.fzp.test +3 -0
  217. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/author_present.fzp.test +4 -0
  218. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/buses_missing_id.fzp.test +8 -0
  219. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/buses_missing_node_members.fzp.test +7 -0
  220. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/buses_present_valid.fzp.test +8 -0
  221. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_layers_missing_attributes.fzp.test +16 -0
  222. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_layers_present_valid.fzp.test +14 -0
  223. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_numbering_invalid.fzp.test +70 -0
  224. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_numbering_valid.fzp.test +70 -0
  225. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_refs_valid.fzp.test +53 -0
  226. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_mixed.fzp.test +11 -0
  227. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_silkscreen_nested.fzp.test +11 -0
  228. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_style_attr.fzp.test +11 -0
  229. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_white_stroke.fzp.test +11 -0
  230. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_wrong_color.fzp.test +11 -0
  231. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_inherited.fzp.test +11 -0
  232. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_legacy.fzp.test +12 -0
  233. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_nested_copper.fzp.test +12 -0
  234. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_none.fzp.test +11 -0
  235. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_standard.fzp.test +12 -0
  236. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_uppercase.fzp.test +11 -0
  237. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/css_connector.fzp.test +100 -0
  238. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/description_missing.fzp.test +3 -0
  239. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/description_present.fzp.test +4 -0
  240. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/duplicate_ids.fzp.test +27 -0
  241. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/family_property_missing.fzp.test +6 -0
  242. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/family_property_present_valid.fzp.test +6 -0
  243. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/font_size.fzp.test +46 -0
  244. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/fritzing_version_invalid_format.fzp.test +4 -0
  245. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/fritzing_version_missing.fzp.test +4 -0
  246. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/fritzing_version_present_valid.fzp.test +4 -0
  247. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/gorn_absent.fzp.test +15 -0
  248. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/gorn_present.fzp.test +15 -0
  249. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/hybrid_connectors.fzp.test +232 -0
  250. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/invalid_xml.fzp.test +12 -0
  251. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/layer_ids_match.fzp.test +29 -0
  252. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/layer_ids_mismatch.fzp.test +30 -0
  253. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/layer_nesting_invalid.fzp.test +11 -0
  254. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/layer_nesting_valid.fzp.test +11 -0
  255. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/matrix_transform.fzp.test +8 -0
  256. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/missing_connector_refs.fzp.test +63 -0
  257. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/missing_leg_ids.fzp.test +34 -0
  258. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_missing.fzp.test +4 -0
  259. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_non_alnum.fzp.test +4 -0
  260. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_present.fzp.test +4 -0
  261. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_special_chars_absent.fzp.test +4 -0
  262. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_special_chars_present.fzp.test +4 -0
  263. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_too_short.fzp.test +4 -0
  264. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/no_layer_invalid.fzp.test +19 -0
  265. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/no_layer_namedview.fzp.test +19 -0
  266. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/no_layer_valid.fzp.test +19 -0
  267. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/pcb_only.fzp.test +48 -0
  268. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/property_fields_missing_name.fzp.test +6 -0
  269. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/property_fields_missing_value.fzp.test +6 -0
  270. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/property_fields_present.fzp.test +6 -0
  271. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/required_tags_missing.fzp.test +3 -0
  272. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/required_tags_present.fzp.test +11 -0
  273. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/stroke_test.fzp.test +60 -0
  274. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/template_svgs.fzp.test +35 -0
  275. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/title_missing.fzp.test +3 -0
  276. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/title_present.fzp.test +4 -0
  277. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/unique_ids.fzp.test +27 -0
  278. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/unique_property_names_duplicates.fzp.test +7 -0
  279. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/unique_property_names_unique.fzp.test +7 -0
  280. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/valid_xml.fzp.test +249 -0
  281. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/version_invalid_format.fzp.test +4 -0
  282. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/version_missing.fzp.test +3 -0
  283. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/version_present_valid.fzp.test +4 -0
  284. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/views_missing.fzp.test +3 -0
  285. package/tools/fzp-checker/vendor/scripts/checks/test_data/core/views_present.fzp.test +8 -0
  286. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/connector_refs_valid_breadboard.svg +7 -0
  287. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/duplicate_ids_breadboard.svg +13 -0
  288. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/gorn_absent_breadboard.svg +7 -0
  289. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/gorn_present_breadboard.svg +7 -0
  290. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/hybrid_connectors_breadboard.svg +102 -0
  291. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/layer_nesting_invalid.svg +13 -0
  292. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/layer_nesting_valid.svg +13 -0
  293. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/matrix_transform.svg +11 -0
  294. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/missing_connector_refs_breadboard.svg +8 -0
  295. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/missing_leg_ids_breadboard.svg +9 -0
  296. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/test_layer_ids_match_breadboard.svg +9 -0
  297. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/test_layer_ids_mismatch_breadboard.svg +9 -0
  298. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/unique_ids_breadboard.svg +13 -0
  299. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/hybrid_connectors_icon.svg +78 -0
  300. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/no_layer_invalid.svg +4 -0
  301. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/no_layer_namedview.svg +9 -0
  302. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/no_layer_valid.svg +7 -0
  303. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/plain_pcb.svg +10 -0
  304. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/connector_refs_valid_pcb.svg +10 -0
  305. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_mixed.svg +8 -0
  306. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_silkscreen_nested.svg +10 -0
  307. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_style_attr.svg +6 -0
  308. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_white_stroke.svg +6 -0
  309. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_wrong_color.svg +6 -0
  310. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_inherited.svg +7 -0
  311. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_legacy.svg +10 -0
  312. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_nested_copper.svg +9 -0
  313. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_none.svg +7 -0
  314. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_standard.svg +10 -0
  315. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_uppercase.svg +7 -0
  316. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/css_connector.svg +25 -0
  317. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/font_size.svg +54 -0
  318. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/hybrid_connectors_pcb.svg +35 -0
  319. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/missing_connector_refs_pcb.svg +14 -0
  320. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/pcb-arduino-shield.svg +25 -0
  321. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/stroke_test.svg +12 -0
  322. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/test_layer_ids_match_pcb.svg +12 -0
  323. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/test_layer_ids_mismatch_pcb.svg +12 -0
  324. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/connector_refs_valid_schematic.svg +7 -0
  325. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/hybrid_connectors_schematic.svg +59 -0
  326. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/missing_connector_refs_schematic.svg +8 -0
  327. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/test_layer_ids_match_schematic.svg +6 -0
  328. package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/test_layer_ids_mismatch_schematic.svg +6 -0
@@ -0,0 +1,183 @@
1
+ /**
2
+ * fzp XML builder (Fritzing 1.0.7 module description).
3
+ *
4
+ * Element order follows the core library and vanepp's community parts: version, author,
5
+ * title, label, date, tags, properties, description, spice, views, connectors, buses.
6
+ * Output is pretty printed with 2-space indentation and LF line endings, and is
7
+ * byte-deterministic for a given (ResolvedPart, RenderContext).
8
+ */
9
+ import { layerImage } from "../identity.js";
10
+ import { esc } from "../svg.js";
11
+ import { layerIdsFor } from "./types.js";
12
+ export const FRITZING_VERSION = "1.0.7";
13
+ export const PROJECT_URL = "https://github.com/pmaxhogan/fritzkit";
14
+ /** View order inside <views> (the spike parts that passed the checker use this order). */
15
+ const FZP_VIEWS = ["icon", "breadboard", "schematic", "pcb"];
16
+ /** Properties fritzkit owns; spec.properties entries with these names are ignored. */
17
+ const RESERVED_PROPERTIES = new Set(["family", "variant"]);
18
+ /** Tiny line-oriented XML writer: one element per line, 2-space indent. */
19
+ class XmlWriter {
20
+ lines = [];
21
+ depth = 0;
22
+ push(s) {
23
+ this.lines.push(" ".repeat(this.depth) + s);
24
+ }
25
+ open(tag, attrs = []) {
26
+ this.push(`<${tag}${fmtAttrs(attrs)}>`);
27
+ this.depth++;
28
+ }
29
+ close(tag) {
30
+ this.depth--;
31
+ this.push(`</${tag}>`);
32
+ }
33
+ empty(tag, attrs = []) {
34
+ this.push(`<${tag}${fmtAttrs(attrs)}/>`);
35
+ }
36
+ /** <tag attrs>escaped text</tag>; text may span several lines. */
37
+ text(tag, content, attrs = []) {
38
+ this.push(`<${tag}${fmtAttrs(attrs)}>${esc(content)}</${tag}>`);
39
+ }
40
+ toString() {
41
+ return this.lines.join("\n") + "\n";
42
+ }
43
+ }
44
+ function fmtAttrs(attrs) {
45
+ return attrs.map(([k, v]) => ` ${k}="${esc(v)}"`).join("");
46
+ }
47
+ /** Normalise CRLF / CR to LF so the fzp stays LF-only even if the spec text is not. */
48
+ function lf(s) {
49
+ return s.replace(/\r\n?/g, "\n");
50
+ }
51
+ /**
52
+ * The fzp <description> text: the spec description, the source URLs, then the
53
+ * generator and licence notice. Plain text (escaped by the writer), LF newlines.
54
+ */
55
+ export function fzpDescription(part, ctx) {
56
+ const { spec } = part;
57
+ const year = ctx.date.slice(0, 4);
58
+ const blocks = [];
59
+ const body = lf(spec.description).trim();
60
+ if (body)
61
+ blocks.push(body);
62
+ if (spec.sources.length)
63
+ blocks.push(["Sources:", ...spec.sources].join("\n"));
64
+ blocks.push(`Generated by ${ctx.generator} (${PROJECT_URL}). Part artwork and data (c) ${year} ${spec.author}, ` +
65
+ "licensed CC-BY-SA 3.0 like the Fritzing parts library.");
66
+ return blocks.join("\n\n");
67
+ }
68
+ /** Ordered [name, value] pairs for <properties>: family, variant, then spec.properties by key. */
69
+ export function fzpProperties(part, ctx) {
70
+ const out = [
71
+ ["family", ctx.identity.family],
72
+ ["variant", ctx.identity.variant],
73
+ ];
74
+ const keys = Object.keys(part.spec.properties).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
75
+ for (const k of keys) {
76
+ if (RESERVED_PROPERTIES.has(k.toLowerCase()))
77
+ continue;
78
+ out.push([k, part.spec.properties[k] ?? ""]);
79
+ }
80
+ return out.filter(([, v]) => v.trim() !== "");
81
+ }
82
+ function writeConnector(w, c) {
83
+ w.open("connector", [
84
+ ["id", c.fzpId],
85
+ ["type", c.type],
86
+ ["name", c.name],
87
+ ]);
88
+ w.text("description", lf(c.description));
89
+ w.open("views");
90
+ w.open("breadboardView");
91
+ w.empty("p", [
92
+ ["layer", "breadboard"],
93
+ ["svgId", c.svgId],
94
+ c.legId ? ["legId", c.legId] : ["terminalId", c.terminalId],
95
+ ]);
96
+ w.close("breadboardView");
97
+ w.open("schematicView");
98
+ w.empty("p", [
99
+ ["layer", "schematic"],
100
+ ["svgId", c.svgId],
101
+ ["terminalId", c.terminalId],
102
+ ]);
103
+ w.close("schematicView");
104
+ w.open("pcbView");
105
+ if (c.tht)
106
+ w.empty("p", [
107
+ ["layer", "copper0"],
108
+ ["svgId", c.svgId],
109
+ ]);
110
+ w.empty("p", [
111
+ ["layer", "copper1"],
112
+ ["svgId", c.svgId],
113
+ ]);
114
+ w.close("pcbView");
115
+ w.close("views");
116
+ w.close("connector");
117
+ }
118
+ export function buildFzp(part, ctx) {
119
+ const { spec } = part;
120
+ const { identity } = ctx;
121
+ const w = new XmlWriter();
122
+ w.open("module", [
123
+ ["moduleId", identity.moduleId],
124
+ ["referenceFile", `${identity.moduleId}.fzp`],
125
+ ["fritzingVersion", FRITZING_VERSION],
126
+ ]);
127
+ w.text("version", String(spec.version));
128
+ w.text("author", spec.author);
129
+ w.text("title", spec.title);
130
+ w.text("label", spec.label);
131
+ w.text("date", ctx.date);
132
+ if (spec.tags.length) {
133
+ w.open("tags");
134
+ for (const t of spec.tags)
135
+ w.text("tag", t);
136
+ w.close("tags");
137
+ }
138
+ else {
139
+ w.empty("tags");
140
+ }
141
+ w.open("properties");
142
+ for (const [name, value] of fzpProperties(part, ctx)) {
143
+ w.text("property", value, [["name", name]]);
144
+ }
145
+ w.close("properties");
146
+ w.text("description", fzpDescription(part, ctx));
147
+ if (spec.spice) {
148
+ w.open("spice");
149
+ if (spec.spice.model !== undefined && spec.spice.model.trim() !== "") {
150
+ w.text("model", lf(spec.spice.model));
151
+ }
152
+ for (const line of spec.spice.lines)
153
+ w.text("line", lf(line));
154
+ w.close("spice");
155
+ }
156
+ w.open("views");
157
+ for (const view of FZP_VIEWS) {
158
+ w.open(`${view}View`);
159
+ w.open("layers", [["image", layerImage(identity, view)]]);
160
+ for (const id of layerIdsFor(view, part.hasTht))
161
+ w.empty("layer", [["layerId", id]]);
162
+ w.close("layers");
163
+ w.close(`${view}View`);
164
+ }
165
+ w.close("views");
166
+ w.open("connectors");
167
+ for (const c of [...part.connectors].sort((a, b) => a.id - b.id))
168
+ writeConnector(w, c);
169
+ w.close("connectors");
170
+ if (part.buses.length) {
171
+ w.open("buses");
172
+ for (const b of part.buses) {
173
+ w.open("bus", [["id", b.id]]);
174
+ for (const id of b.connectorIds)
175
+ w.empty("nodeMember", [["connectorId", `connector${id}`]]);
176
+ w.close("bus");
177
+ }
178
+ w.close("buses");
179
+ }
180
+ w.close("module");
181
+ return `<?xml version="1.0" encoding="UTF-8"?>\n` + w.toString();
182
+ }
183
+ //# sourceMappingURL=fzp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fzp.js","sourceRoot":"","sources":["../../../src/core/compile/fzp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Icon view renderer: the parts bin thumbnail. A fixed 320 mil square holding the
3
+ * breadboard artwork (same drawing, every id stripped so the icon carries no
4
+ * connector ids) scaled to fit inside a 16 mil margin and centred. A long thin board
5
+ * becomes a thin strip, as with Fritzing's own parts.
6
+ */
7
+ import type { ResolvedPart } from "../resolve.js";
8
+ import type { RenderContext } from "./types.js";
9
+ export declare const ICON_SIZE_MIL = 320;
10
+ export declare const ICON_MARGIN_MIL = 16;
11
+ /** Scale + translate that fits a w x h mil drawing into the icon square, centred. */
12
+ export declare function iconTransform(wMil: number, hMil: number): {
13
+ scale: number;
14
+ tx: number;
15
+ ty: number;
16
+ };
17
+ export declare function renderIcon(part: ResolvedPart, ctx: RenderContext): string;
@@ -0,0 +1,27 @@
1
+ import { svgRoot } from "../svg.js";
2
+ import { fmt, milToMm, mmToMil } from "../units.js";
3
+ import { extraNamespaces, group, renderBreadboardContent } from "./breadboard.js";
4
+ export const ICON_SIZE_MIL = 320;
5
+ export const ICON_MARGIN_MIL = 16;
6
+ /** Scale + translate that fits a w x h mil drawing into the icon square, centred. */
7
+ export function iconTransform(wMil, hMil) {
8
+ const avail = ICON_SIZE_MIL - 2 * ICON_MARGIN_MIL;
9
+ // Floor the scale to the 3 decimals fmt emits (never overflow the margin) and centre
10
+ // with exactly the emitted value.
11
+ const scale = Math.max(0.001, Math.floor(Math.min(avail / wMil, avail / hMil) * 1000) / 1000);
12
+ return {
13
+ scale,
14
+ tx: (ICON_SIZE_MIL - wMil * scale) / 2,
15
+ ty: (ICON_SIZE_MIL - hMil * scale) / 2,
16
+ };
17
+ }
18
+ export function renderIcon(part, ctx) {
19
+ const body = renderBreadboardContent(part, ctx, { ids: false });
20
+ const t = iconTransform(mmToMil(part.frame.widthMm), mmToMil(part.frame.heightMm));
21
+ const inner = group(undefined, body, {
22
+ transform: `translate(${fmt(t.tx)} ${fmt(t.ty)}) scale(${fmt(t.scale)})`,
23
+ });
24
+ const side = milToMm(ICON_SIZE_MIL);
25
+ return svgRoot(side, side, [group("icon", [inner])], extraNamespaces(ctx));
26
+ }
27
+ //# sourceMappingURL=icon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icon.js","sourceRoot":"","sources":["../../../src/core/compile/icon.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAGlF,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC;AACjC,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAElC,qFAAqF;AACrF,MAAM,UAAU,aAAa,CAC3B,IAAY,EACZ,IAAY;IAEZ,MAAM,KAAK,GAAG,aAAa,GAAG,CAAC,GAAG,eAAe,CAAC;IAClD,qFAAqF;IACrF,kCAAkC;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9F,OAAO;QACL,KAAK;QACL,EAAE,EAAE,CAAC,aAAa,GAAG,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC;QACtC,EAAE,EAAE,CAAC,aAAa,GAAG,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC;KACvC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAkB,EAAE,GAAkB;IAC/D,MAAM,IAAI,GAAG,uBAAuB,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IAChE,MAAM,CAAC,GAAG,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnF,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE;QACnC,SAAS,EAAE,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG;KACzE,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACpC,OAAO,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { PartSpec } from "../schema/part.js";
2
+ import type { CompileOptions, CompiledPart } from "./types.js";
3
+ export declare const GENERATOR = "fritzkit";
4
+ export declare function compilePart(spec: PartSpec, opts?: CompileOptions): Promise<CompiledPart>;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * compilePart: PartSpec (+ assets) -> fzp + four SVGs + flat zip entry list.
3
+ * Deterministic for a fixed date; never touches the network or the filesystem.
4
+ */
5
+ import { identityFor, fzpzEntryNames } from "../identity.js";
6
+ import { resolvePart } from "../resolve.js";
7
+ import { renderBreadboard } from "./breadboard.js";
8
+ import { buildFzp } from "./fzp.js";
9
+ import { renderIcon } from "./icon.js";
10
+ import { renderPcb } from "./pcb.js";
11
+ import { renderSchematic } from "./schematic.js";
12
+ export const GENERATOR = "fritzkit";
13
+ const enc = new TextEncoder();
14
+ export async function compilePart(spec, opts = {}) {
15
+ const warnings = [];
16
+ const assets = [];
17
+ if (opts.assets) {
18
+ for (const [name, data] of [...opts.assets.entries()].sort())
19
+ assets.push({ name, data });
20
+ }
21
+ const identity = identityFor(spec, assets);
22
+ const resolved = resolvePart(spec);
23
+ const ctx = {
24
+ identity,
25
+ date: opts.date ?? new Date().toISOString().slice(0, 10),
26
+ generator: opts.generator ?? GENERATOR,
27
+ };
28
+ if (spec.artwork.style === "photo") {
29
+ const src = spec.artwork.photo?.src;
30
+ const data = src ? opts.assets?.get(src) : undefined;
31
+ if (!src || !data) {
32
+ warnings.push(`artwork.style is "photo" but asset "${src ?? "(none)"}" was not provided; rendering vector style`);
33
+ }
34
+ else if (!opts.preparePhoto) {
35
+ warnings.push('artwork.style is "photo" but no photo preparer is available; rendering vector style');
36
+ }
37
+ else {
38
+ const photo = await opts.preparePhoto(data, spec);
39
+ if (photo)
40
+ ctx.photo = photo;
41
+ else
42
+ warnings.push("photo preparation failed; rendering vector style");
43
+ }
44
+ }
45
+ const svgs = {
46
+ breadboard: renderBreadboard(resolved, ctx),
47
+ schematic: renderSchematic(resolved, ctx),
48
+ pcb: renderPcb(resolved, ctx),
49
+ icon: renderIcon(resolved, ctx),
50
+ };
51
+ const fzp = buildFzp(resolved, ctx);
52
+ const names = fzpzEntryNames(identity);
53
+ const entries = [
54
+ { name: names.fzp, data: enc.encode(fzp) },
55
+ { name: names.breadboard, data: enc.encode(svgs.breadboard) },
56
+ { name: names.schematic, data: enc.encode(svgs.schematic) },
57
+ { name: names.pcb, data: enc.encode(svgs.pcb) },
58
+ { name: names.icon, data: enc.encode(svgs.icon) },
59
+ ];
60
+ return { identity, resolved, fzp, svgs, entries, warnings };
61
+ }
62
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/compile/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * pcb view renderer: a real footprint built from the resolved pad table (decision D7).
3
+ *
4
+ * Layout (copied from Fritzing's core THT parts, e.g. svg/core/pcb/dip_8_300mil.svg):
5
+ *
6
+ * <g id="silkscreen">outline + mounting holes</g>
7
+ * <g id="copper1">
8
+ * <g id="copper0">THT pads</g> (omitted when the part has no THT connector)
9
+ * SMD pads
10
+ * </g>
11
+ *
12
+ * A THT pad lives ONCE, inside copper0. Because copper0 is nested in copper1 the same
13
+ * element is a descendant of both layer groups, so the fzp's copper0 and copper1 <p>
14
+ * entries both resolve to it. Emitting a second copy would duplicate the id, which the
15
+ * Fritzing part checker reports as an error.
16
+ *
17
+ * Canvas = part.frame (same size and offsets as the breadboard view, so the views line
18
+ * up). viewBox units are mils.
19
+ */
20
+ import { type ResolvedPart } from "../resolve.js";
21
+ import type { RenderContext } from "./types.js";
22
+ /** Annular ring geometry in mils. */
23
+ export interface Ring {
24
+ /** Drill radius. */
25
+ holeR: number;
26
+ /** Outer copper radius. */
27
+ padR: number;
28
+ /** circle r (centre line of the stroke). */
29
+ r: number;
30
+ /** circle stroke-width (ring width). */
31
+ strokeWidth: number;
32
+ }
33
+ /**
34
+ * Ring geometry for a through-hole pad of the given copper size and drill (mm).
35
+ * The drill is clamped to STYLE.pcb.minHoleMil and the ring width to
36
+ * STYLE.pcb.minRingMil (the pad grows; the hole never shrinks).
37
+ */
38
+ export declare function ringGeometry(wMm: number, hMm: number, holeMm: number | undefined): Ring;
39
+ export declare function renderPcb(part: ResolvedPart, _ctx: RenderContext): string;
@@ -0,0 +1,164 @@
1
+ /**
2
+ * pcb view renderer: a real footprint built from the resolved pad table (decision D7).
3
+ *
4
+ * Layout (copied from Fritzing's core THT parts, e.g. svg/core/pcb/dip_8_300mil.svg):
5
+ *
6
+ * <g id="silkscreen">outline + mounting holes</g>
7
+ * <g id="copper1">
8
+ * <g id="copper0">THT pads</g> (omitted when the part has no THT connector)
9
+ * SMD pads
10
+ * </g>
11
+ *
12
+ * A THT pad lives ONCE, inside copper0. Because copper0 is nested in copper1 the same
13
+ * element is a descendant of both layer groups, so the fzp's copper0 and copper1 <p>
14
+ * entries both resolve to it. Emitting a second copy would duplicate the id, which the
15
+ * Fritzing part checker reports as an error.
16
+ *
17
+ * Canvas = part.frame (same size and offsets as the breadboard view, so the views line
18
+ * up). viewBox units are mils.
19
+ */
20
+ import { toCanvas } from "../resolve.js";
21
+ import { el, svgRoot } from "../svg.js";
22
+ import { fmt, MIL_PER_MM, mmToMil } from "../units.js";
23
+ import { STYLE } from "./style.js";
24
+ /**
25
+ * Ring geometry for a through-hole pad of the given copper size and drill (mm).
26
+ * The drill is clamped to STYLE.pcb.minHoleMil and the ring width to
27
+ * STYLE.pcb.minRingMil (the pad grows; the hole never shrinks).
28
+ */
29
+ export function ringGeometry(wMm, hMm, holeMm) {
30
+ const holeR = Math.max(mmToMil(holeMm ?? 0) / 2, STYLE.pcb.minHoleMil / 2);
31
+ const padR = Math.max(mmToMil(Math.min(wMm, hMm)) / 2, holeR + STYLE.pcb.minRingMil);
32
+ return { holeR, padR, r: (holeR + padR) / 2, strokeWidth: padR - holeR };
33
+ }
34
+ /** Where a connector's copper sits, canvas mm. A lead is soldered at its board end. */
35
+ function padCentre(part, c) {
36
+ if (c.lead)
37
+ return toCanvas(part.frame, c.lead.fromXMm, c.lead.fromYMm);
38
+ return toCanvas(part.frame, c.xMm, c.yMm);
39
+ }
40
+ function thtPad(part, c) {
41
+ const { x, y } = padCentre(part, c);
42
+ const cx = mmToMil(x);
43
+ const cy = mmToMil(y);
44
+ const pad = c.pad;
45
+ const out = [];
46
+ // resolve.ts already stores a lead's drill (0.6 x gauge) in pad.holeMm.
47
+ const ring = ringGeometry(pad.wMm, pad.hMm, pad.holeMm);
48
+ const longSide = Math.max(pad.wMm, pad.hMm);
49
+ const shortSide = Math.min(pad.wMm, pad.hMm);
50
+ if (!c.lead && pad.shape !== "round" && longSide > 1.3 * shortSide) {
51
+ // Oblong solder pad: real copper under the ring (no id; the ring carries it).
52
+ const w = mmToMil(pad.wMm);
53
+ const h = mmToMil(pad.hMm);
54
+ out.push(el("rect", {
55
+ x: cx - w / 2,
56
+ y: cy - h / 2,
57
+ width: w,
58
+ height: h,
59
+ rx: pad.shape === "oval" ? Math.min(w, h) / 2 : undefined,
60
+ fill: STYLE.pcb.copper,
61
+ stroke: "none",
62
+ }));
63
+ }
64
+ out.push(el("circle", {
65
+ id: c.svgId,
66
+ cx,
67
+ cy,
68
+ r: ring.r,
69
+ fill: "none",
70
+ stroke: STYLE.pcb.copper,
71
+ "stroke-width": ring.strokeWidth,
72
+ }));
73
+ return out;
74
+ }
75
+ function smdPad(part, c) {
76
+ const { x, y } = padCentre(part, c);
77
+ const w = mmToMil(c.pad.wMm);
78
+ const h = mmToMil(c.pad.hMm);
79
+ const rounded = c.pad.shape === "oval" || c.pad.shape === "round";
80
+ return el("rect", {
81
+ id: c.svgId,
82
+ x: mmToMil(x) - w / 2,
83
+ y: mmToMil(y) - h / 2,
84
+ width: w,
85
+ height: h,
86
+ rx: rounded ? Math.min(w, h) / 2 : undefined,
87
+ fill: STYLE.pcb.copper,
88
+ stroke: "none",
89
+ });
90
+ }
91
+ function silkscreen(part) {
92
+ const o = part.spec.outline;
93
+ const f = part.frame;
94
+ const sw = STYLE.pcb.silkStrokeMil;
95
+ const out = [];
96
+ if (o.shape === "custom" && o.pathMm) {
97
+ // The path is in part-frame mm: map it onto the canvas with translate + scale and
98
+ // compensate the stroke so it renders at silkStrokeMil.
99
+ out.push(el("g", {
100
+ transform: `translate(${fmt(mmToMil(f.offsetXMm))} ${fmt(mmToMil(f.offsetYMm))}) scale(${fmt(MIL_PER_MM)})`,
101
+ }, el("path", {
102
+ d: o.pathMm,
103
+ fill: "none",
104
+ stroke: STYLE.pcb.silkscreen,
105
+ "stroke-width": sw / MIL_PER_MM,
106
+ })));
107
+ }
108
+ else {
109
+ // Stroke centred half a stroke inside the outline so it stays on the canvas edge.
110
+ const x = mmToMil(f.offsetXMm) + sw / 2;
111
+ const y = mmToMil(f.offsetYMm) + sw / 2;
112
+ const w = Math.max(mmToMil(o.widthMm) - sw, 0);
113
+ const h = Math.max(mmToMil(o.heightMm) - sw, 0);
114
+ const r = o.shape === "rounded" ? Math.min(mmToMil(o.cornerRadiusMm), w / 2, h / 2) : 0;
115
+ out.push(el("rect", {
116
+ x,
117
+ y,
118
+ width: w,
119
+ height: h,
120
+ rx: r > 0 ? r : undefined,
121
+ ry: r > 0 ? r : undefined,
122
+ fill: "none",
123
+ stroke: STYLE.pcb.silkscreen,
124
+ "stroke-width": sw,
125
+ }));
126
+ }
127
+ for (const hole of o.holes) {
128
+ const { x, y } = toCanvas(f, hole.xMm, hole.yMm);
129
+ out.push(el("circle", {
130
+ cx: mmToMil(x),
131
+ cy: mmToMil(y),
132
+ r: mmToMil(hole.dMm) / 2,
133
+ fill: "none",
134
+ stroke: STYLE.pcb.silkscreen,
135
+ "stroke-width": sw,
136
+ }));
137
+ }
138
+ return out;
139
+ }
140
+ /** One child per line (readable golden files); empty stays empty so el() self-closes. */
141
+ function lines(children) {
142
+ return children.length ? `\n${children.join("\n")}\n` : "";
143
+ }
144
+ export function renderPcb(part, _ctx) {
145
+ const silk = part.spec.pcb.silkscreenOutline ? silkscreen(part) : [];
146
+ const tht = [];
147
+ const smd = [];
148
+ for (const c of part.connectors) {
149
+ if (c.tht)
150
+ tht.push(...thtPad(part, c));
151
+ else
152
+ smd.push(smdPad(part, c));
153
+ }
154
+ const copper1 = [];
155
+ if (part.hasTht)
156
+ copper1.push(el("g", { id: "copper0" }, lines(tht)));
157
+ copper1.push(...smd);
158
+ // An empty group would self-close; that is still a valid layer element.
159
+ return svgRoot(part.frame.widthMm, part.frame.heightMm, [
160
+ el("g", { id: "silkscreen" }, lines(silk)),
161
+ el("g", { id: "copper1" }, lines(copper1)),
162
+ ]);
163
+ }
164
+ //# sourceMappingURL=pcb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pcb.js","sourceRoot":"","sources":["../../../src/core/compile/pcb.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * schematic view renderer (decision D9, Fritzing graphic standard).
3
+ *
4
+ * An auto-generated rectangle symbol on the 0.1 in (100 mil) grid. Pins are grouped by
5
+ * role onto the four sides of the body (DEFAULT_SIDES, overridable per role with
6
+ * spec.schematic.sides); within a side they keep connector id order. Each pin is a
7
+ * 100 mil line from the body edge outward whose OUTER end sits exactly on a grid
8
+ * intersection, with a 1 mil terminal rect centred on that end (Fritzing snaps wires
9
+ * to the terminal centre). Labels sit inside the body next to the pin.
10
+ *
11
+ * Every coordinate is in mils (the viewBox is in mils). Attributes only, no CSS.
12
+ * part.frame is ignored: the schematic has its own layout. Leads are ordinary pins.
13
+ */
14
+ import type { ResolvedConnector, ResolvedPart } from "../resolve.js";
15
+ import type { PinRole } from "../schema/part.js";
16
+ import type { RenderContext } from "./types.js";
17
+ export type Side = "left" | "right" | "top" | "bottom";
18
+ /** Default side for each role. Nothing goes on top unless spec.schematic.sides says so. */
19
+ export declare const DEFAULT_SIDES: Readonly<Record<PinRole, Side>>;
20
+ /**
21
+ * Width estimate for a run of Noto Sans text: 0.6 x font size per character. Used to
22
+ * size the body so labels never overflow; generous for a proportional font.
23
+ */
24
+ export declare function estimateTextWidthMil(s: string, fontSizeMil: number): number;
25
+ /**
26
+ * Role -> side map after applying spec.schematic.sides. A role listed on a side goes
27
+ * there (sides are applied in the order left, right, top, bottom, so a role listed on
28
+ * two sides ends up on the later one); unlisted roles keep DEFAULT_SIDES.
29
+ */
30
+ export declare function sideMap(overrides: Partial<Record<Side, PinRole[] | undefined>> | undefined): Record<PinRole, Side>;
31
+ export interface SchematicPin {
32
+ connector: ResolvedConnector;
33
+ side: Side;
34
+ /** Body-edge end of the pin line (mils, canvas). */
35
+ x1: number;
36
+ y1: number;
37
+ /** Outer end of the pin line: always a grid intersection. */
38
+ x2: number;
39
+ y2: number;
40
+ }
41
+ export interface SchematicLayout {
42
+ widthMil: number;
43
+ heightMil: number;
44
+ body: {
45
+ x: number;
46
+ y: number;
47
+ w: number;
48
+ h: number;
49
+ };
50
+ title: {
51
+ text: string;
52
+ x: number;
53
+ y: number;
54
+ };
55
+ pins: SchematicPin[];
56
+ }
57
+ /**
58
+ * Pick the title: spec.title if it fits maxWidth, else properties.mpn when it is short
59
+ * (<= 16 chars), else the first 16 chars + "..." (only when that is actually shorter
60
+ * than the title; a title of up to 19 chars is kept whole). needsWidth is the width the
61
+ * chosen short form needs (the body grows to fit it); 0 when the full title fits.
62
+ */
63
+ export declare function chooseTitle(title: string, mpn: string | undefined, maxWidth: number): {
64
+ text: string;
65
+ needsWidth: number;
66
+ };
67
+ /** Compute the whole symbol geometry (mils). Pure; exported for tests. */
68
+ export declare function layoutSchematic(part: ResolvedPart): SchematicLayout;
69
+ export declare function renderSchematic(part: ResolvedPart, _ctx: RenderContext): string;