, \"m\"),\n `$1(${id} \"${name}\" $2)`,\n )\n}\n\npcb = pcb\n .replace(\"(generator circuit-json-to-kicad)\", '(generator \"circuit-json-to-kicad\")')\n .replace(\"(generator_version 0.0.1)\", '(generator_version \"0.0.1\")')\n\n// KiCad 10 requires layer-name atoms and the paper name to be quoted.\npcb = pcb.replace(/\\(paper\\s+A4\\s*\\)/g, '(paper \"A4\")')\npcb = pcb.replace(\n /\\((layer|layers) ([^)\\r\\n]+)\\)/g,\n (_match, keyword, names) =\u003e {\n const quotedNames = names\n .trim()\n .split(/\\s+/)\n .map((name) =\u003e (name.startsWith('\"') ? name : `\"${name}\"`))\n .join(\" \")\n return `(${keyword} ${quotedNames})`\n },\n)\n\n// KiCad vias name exactly their start and end copper layers. The converter\n// emits every traversed layer, which crashes KiCad's board loader.\npcb = pcb.replace(\n /\\(layers ((?:\"(?:F\\.Cu|In1\\.Cu|In2\\.Cu|B\\.Cu)\"\\s*){3,})\\)/g,\n (_match, layerList) =\u003e {\n const layers = layerList.match(/\"[^\"]+\"/g)\n return `(layers ${layers[0]} ${layers.at(-1)})`\n },\n)\n\n// KiCad's s-expression number lexer does not accept JavaScript exponent form.\npcb = pcb.replace(/[+-]?\\d+\\.\\d+[eE][+-]?\\d+/g, (number) =\u003e {\n const fixed = Number(number).toFixed(12).replace(/\\.?0+$/, \"\")\n return fixed === \"-0\" || fixed === \"\" ? \"0\" : fixed\n})\n\nwriteFileSync(outputPath, pcb)\nconsole.log(`Corrected tscircuit KiCad layer syntax in ${outputPath}`)\n","content_mimetype":"text/javascript","created_at":"2026-08-13T08:24:51.092Z"}; window.SSR_PACKAGE_RELEASES = [{"package_release_id":"25f27c27-4922-4735-a190-f49e6759ff01","package_id":"4ee6efb2-a398-435c-9567-31ca52ddd6ed","version":"1.0.1","github_commit_sha":null,"is_locked":false,"is_latest":true,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-13T08:23:41.386Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-4fdd44c79c2659150d9143c9e9c2817d","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=25f27c27-4922-4735-a190-f49e6759ff01\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=25f27c27-4922-4735-a190-f49e6759ff01\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=25f27c27-4922-4735-a190-f49e6759ff01\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"d1b0917f-b91f-49bb-aaba-333e0e92c55d","user_code_job_started_at":"2026-08-13T08:24:59.919Z","user_code_job_completed_at":"2026-08-13T08:30:05.119Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=6e4153a4ee91d6452447310f7db4d6d83b85164c2cf1ac9ca36cd59ef272ee95","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"17297aeb-1b88-40d2-b581-f15e6f3cbbf2","package_id":"4ee6efb2-a398-435c-9567-31ca52ddd6ed","version":"1.0.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-11T04:23:41.385Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-cb1e929e2d97eaad3b49dcc74c1e5f43","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"2ca81b46-946c-4be9-a7e3-fb3b745a32d3","user_code_job_started_at":"2026-08-11T04:24:29.783Z","user_code_job_completed_at":"2026-08-11T04:30:05.729Z","user_code_job_error":{"message":"Your code failed to build (exit code 1), see build logs for the error details","error_code":"user_code_build_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=a1b4bf485f6d961325bdbac669c9c39359e5747bc44c3563bf70a2ebcaee6356","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null}]; window.SSR_PACKAGE_BUILDS = []; window.SSR_PACKAGE_ROUTE = {"author":"ShiboSoftwareDev","packageName":"MSP-EXP430FR2433","packageNameWithScope":"ShiboSoftwareDev/MSP-EXP430FR2433","version":null,"isLegacyRoute":false,"kind":"file","filePath":"scripts/fix-kicad-export.mjs"};
ShiboSoftwareDev/MSP-EXP430FR2433
This code defines a 4 MHz surface-mount quartz crystal resonator with 15pF load capacitance and ground pin configuration, including PCB footprint and 3D model details.
Version
1.0.1
License
unset
Stars
0
scripts/fix-kicad-export.mjs
import { readFileSync, writeFileSync } from "node:fs"
import { resolve } from "node:path"
const inputPath = resolve(process.argv[2])
const outputPath = resolve(process.argv[3] ?? process.argv[2])
let pcb = readFileSync(inputPath, "utf8")
// circuit-json-to-kicad currently emits the pre-KiCad-9 numeric layer IDs.
// KiCad 9+ uses a different fixed ID table, including even IDs for copper.
const kicad9LayerIds = {
"F.Cu": 0,
"In1.Cu": 2,
"In2.Cu": 4,
"B.Cu": 6,
"F.Mask": 1,
"B.Mask": 3,
"F.SilkS": 5,
"B.SilkS": 7,
"F.Adhes": 9,
"B.Adhes": 11,
"F.Paste": 13,
"B.Paste": 15,
"Dwgs.User": 17,
"Cmts.User": 19,
"Eco1.User": 21,
"Eco2.User": 23,
"Edge.Cuts": 25,
Margin: 27,
"B.CrtYd": 29,
"F.CrtYd": 31,
"B.Fab": 33,
"F.Fab": 35,
}
for (const [name, id] of Object.entries(kicad9LayerIds)) {
const escapedName = name.replaceAll(".", "\\.")
pcb = pcb.replace(
new RegExp(`^(\\s*)\\(\\d+ "${escapedName}" (signal|user)\\)$`, "m"),
`$1(${id} "${name}" $2)`,
)
}
pcb = pcb
.replace("(generator circuit-json-to-kicad)", '(generator "circuit-json-to-kicad")')
.replace("(generator_version 0.0.1)", '(generator_version "0.0.1")')
// KiCad 10 requires layer-name atoms and the paper name to be quoted.
pcb = pcb.replace(/\(paper\s+A4\s*\)/g, '(paper "A4")')
pcb = pcb.replace(
/\((layer|layers) ([^)\r\n]+)\)/g,
(_match, keyword, names) => {
const quotedNames = names
.trim()
.split(/\s+/)
.map((name) => (name.startsWith('"') ? name : `"${name}"`))
.join(" ")
return `(${keyword} ${quotedNames})`
},
)
// KiCad vias name exactly their start and end copper layers. The converter
// emits every traversed layer, which crashes KiCad's board loader.
pcb = pcb.replace(
/\(layers ((?:"(?:F\.Cu|In1\.Cu|In2\.Cu|B\.Cu)"\s*){3,})\)/g,
(_match, layerList) => {
const layers = layerList.match(/"[^"]+"/g)
return `(layers ${layers[0]} ${layers.at(-1)})`
},
)
// KiCad's s-expression number lexer does not accept JavaScript exponent form.
pcb = pcb.replace(/[+-]?\d+\.\d+[eE][+-]?\d+/g, (number) => {
const fixed = Number(number).toFixed(12).replace(/\.?0+$/, "")
return fixed === "-0" || fixed === "" ? "0" : fixed
})
writeFileSync(outputPath, pcb)
console.log(`Corrected tscircuit KiCad layer syntax in ${outputPath}`)