/* 查看器数据:单文件时代这些是 build_viewer 字符串替换进来的 const, 现在用顶层 await 取。ESM 保证本模块在所有 import 它的模块之前完成, 所以下游文件可以直接读 DATA.parts,不需要 init() 编排。 路径相对文档基址(/webapp/index.html),因此 ../data 与 /docs 都能命中。 */ async function json(url) { const r = await fetch(url); if (!r.ok) throw new Error('取数据失败 ' + r.status + ' ' + url); return r.json(); } async function text(url) { const r = await fetch(url); if (!r.ok) throw new Error('取文件失败 ' + r.status + ' ' + url); return r.text(); } const [DATA, TRAVEL, COLLIDE, SCREWS, sheetSvg] = await Promise.all([ json('../data/mesh_arm.json'), json('/docs/travel.json'), json('/docs/collide.json'), json('/docs/screws.json'), // 工程图是 4 个真 SVG 文件(draw_sheet.py 产出),不再维护第二份 jsdata 副本 Promise.all(['front', 'joint', 'exploded', 'side'] .map(n => text('/docs/sheet_' + n + '.svg'))), ]); if (!DATA || !Array.isArray(DATA.parts) || !DATA.parts.length) { throw new Error('mesh_arm.json 里没有零件数据,先跑 python -m arm.build_model'); } if (sheetSvg.length !== 4 || sheetSvg.some(s => s.indexOf(')'); } export { DATA, TRAVEL, COLLIDE, SCREWS }; export const SHEETS = sheetSvg; export const TL = {}; for (const t of TRAVEL) TL[t.axis] = t;