@12ui/design 0.2.71 → 0.2.73

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 (680) hide show
  1. package/README.md +248 -55
  2. package/SKILL.md +28 -33
  3. package/dist/cli-arguments.d.ts.map +1 -1
  4. package/dist/cli-arguments.js +3 -0
  5. package/dist/cli-arguments.js.map +1 -1
  6. package/dist/cli-branch-command.d.ts.map +1 -1
  7. package/dist/cli-branch-command.js +4 -0
  8. package/dist/cli-branch-command.js.map +1 -1
  9. package/dist/cli-capabilities.d.ts +35 -1
  10. package/dist/cli-capabilities.d.ts.map +1 -1
  11. package/dist/cli-capabilities.js +36 -1
  12. package/dist/cli-capabilities.js.map +1 -1
  13. package/dist/cli-corpus-command.d.ts +5 -4
  14. package/dist/cli-corpus-command.d.ts.map +1 -1
  15. package/dist/cli-corpus-command.js +17 -26
  16. package/dist/cli-corpus-command.js.map +1 -1
  17. package/dist/cli-corpus-run.js +1 -1
  18. package/dist/cli-corpus-run.js.map +1 -1
  19. package/dist/cli-draft-command.js +1 -1
  20. package/dist/cli-draft-command.js.map +1 -1
  21. package/dist/cli-help/design.d.ts +26 -6
  22. package/dist/cli-help/design.d.ts.map +1 -1
  23. package/dist/cli-help/design.js +39 -7
  24. package/dist/cli-help/design.js.map +1 -1
  25. package/dist/cli-help/index.d.ts +206 -7
  26. package/dist/cli-help/index.d.ts.map +1 -1
  27. package/dist/cli-help/index.js +4 -0
  28. package/dist/cli-help/index.js.map +1 -1
  29. package/dist/cli-help/meta.d.ts +1 -1
  30. package/dist/cli-help/meta.d.ts.map +1 -1
  31. package/dist/cli-help/meta.js +2 -1
  32. package/dist/cli-help/meta.js.map +1 -1
  33. package/dist/cli-help/scene.d.ts +96 -0
  34. package/dist/cli-help/scene.d.ts.map +1 -0
  35. package/dist/cli-help/scene.js +162 -0
  36. package/dist/cli-help/scene.js.map +1 -0
  37. package/dist/cli-help/workflow.d.ts +90 -0
  38. package/dist/cli-help/workflow.d.ts.map +1 -0
  39. package/dist/cli-help/workflow.js +89 -0
  40. package/dist/cli-help/workflow.js.map +1 -0
  41. package/dist/cli-open-browser.d.ts +7 -0
  42. package/dist/cli-open-browser.d.ts.map +1 -0
  43. package/dist/cli-open-browser.js +25 -0
  44. package/dist/cli-open-browser.js.map +1 -0
  45. package/dist/cli-prototype-command.d.ts +3 -1
  46. package/dist/cli-prototype-command.d.ts.map +1 -1
  47. package/dist/cli-prototype-command.js +33 -7
  48. package/dist/cli-prototype-command.js.map +1 -1
  49. package/dist/cli-review-command.d.ts.map +1 -1
  50. package/dist/cli-review-command.js +1 -16
  51. package/dist/cli-review-command.js.map +1 -1
  52. package/dist/cli-run.d.ts.map +1 -1
  53. package/dist/cli-run.js +41 -3
  54. package/dist/cli-run.js.map +1 -1
  55. package/dist/cli-scene-command.d.ts +3 -0
  56. package/dist/cli-scene-command.d.ts.map +1 -0
  57. package/dist/cli-scene-command.js +292 -0
  58. package/dist/cli-scene-command.js.map +1 -0
  59. package/dist/cli-usage.d.ts +8 -0
  60. package/dist/cli-usage.d.ts.map +1 -1
  61. package/dist/cli-usage.js +65 -6
  62. package/dist/cli-usage.js.map +1 -1
  63. package/dist/cli-workflow-command.d.ts +8 -0
  64. package/dist/cli-workflow-command.d.ts.map +1 -0
  65. package/dist/cli-workflow-command.js +97 -0
  66. package/dist/cli-workflow-command.js.map +1 -0
  67. package/dist/cli-workspace-command.d.ts +25 -0
  68. package/dist/cli-workspace-command.d.ts.map +1 -0
  69. package/dist/cli-workspace-command.js +95 -0
  70. package/dist/cli-workspace-command.js.map +1 -0
  71. package/dist/config.d.ts +6 -0
  72. package/dist/config.d.ts.map +1 -1
  73. package/dist/config.js +12 -4
  74. package/dist/config.js.map +1 -1
  75. package/dist/corpus-access.d.ts +11 -0
  76. package/dist/corpus-access.d.ts.map +1 -0
  77. package/dist/corpus-access.js +18 -0
  78. package/dist/corpus-access.js.map +1 -0
  79. package/dist/corpus-client.d.ts +11 -11
  80. package/dist/corpus-client.d.ts.map +1 -1
  81. package/dist/corpus-client.js +17 -6
  82. package/dist/corpus-client.js.map +1 -1
  83. package/dist/corpus-inspiration-failure.d.ts +1 -1
  84. package/dist/corpus-inspiration-failure.js +2 -2
  85. package/dist/corpus-inspiration-failure.js.map +1 -1
  86. package/dist/corpus-reference-download-retry.d.ts.map +1 -1
  87. package/dist/corpus-reference-download-retry.js +11 -1
  88. package/dist/corpus-reference-download-retry.js.map +1 -1
  89. package/dist/corpus-request-error.d.ts +2 -0
  90. package/dist/corpus-request-error.d.ts.map +1 -1
  91. package/dist/corpus-request-error.js +2 -0
  92. package/dist/corpus-request-error.js.map +1 -1
  93. package/dist/corpus-retry-guidance.d.ts +5 -0
  94. package/dist/corpus-retry-guidance.d.ts.map +1 -0
  95. package/dist/corpus-retry-guidance.js +18 -0
  96. package/dist/corpus-retry-guidance.js.map +1 -0
  97. package/dist/improve-pricing-plan.d.ts.map +1 -1
  98. package/dist/improve-pricing-plan.js +2 -4
  99. package/dist/improve-pricing-plan.js.map +1 -1
  100. package/dist/index.d.ts +10 -1
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/index.js +10 -1
  103. package/dist/index.js.map +1 -1
  104. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  105. package/dist/legacy-skill-catalog.js +52 -0
  106. package/dist/legacy-skill-catalog.js.map +1 -1
  107. package/dist/mcp-slate-command.d.ts +31 -0
  108. package/dist/mcp-slate-command.d.ts.map +1 -0
  109. package/dist/mcp-slate-command.js +118 -0
  110. package/dist/mcp-slate-command.js.map +1 -0
  111. package/dist/mcp-slate-image.d.ts +22 -0
  112. package/dist/mcp-slate-image.d.ts.map +1 -0
  113. package/dist/mcp-slate-image.js +28 -0
  114. package/dist/mcp-slate-image.js.map +1 -0
  115. package/dist/mcp-slate-latest.d.ts +13 -0
  116. package/dist/mcp-slate-latest.d.ts.map +1 -0
  117. package/dist/mcp-slate-latest.js +34 -0
  118. package/dist/mcp-slate-latest.js.map +1 -0
  119. package/dist/mcp-slate-names.d.ts +25 -0
  120. package/dist/mcp-slate-names.d.ts.map +1 -0
  121. package/dist/mcp-slate-names.js +49 -0
  122. package/dist/mcp-slate-names.js.map +1 -0
  123. package/dist/mcp-slate-resource.d.ts +5 -0
  124. package/dist/mcp-slate-resource.d.ts.map +1 -0
  125. package/dist/mcp-slate-resource.js +37 -0
  126. package/dist/mcp-slate-resource.js.map +1 -0
  127. package/dist/mcp-slate-run.d.ts +41 -0
  128. package/dist/mcp-slate-run.d.ts.map +1 -0
  129. package/dist/mcp-slate-run.js +88 -0
  130. package/dist/mcp-slate-run.js.map +1 -0
  131. package/dist/mcp-slate-tool-defs.d.ts +61 -0
  132. package/dist/mcp-slate-tool-defs.d.ts.map +1 -0
  133. package/dist/mcp-slate-tool-defs.js +247 -0
  134. package/dist/mcp-slate-tool-defs.js.map +1 -0
  135. package/dist/mcp-slate-tools.d.ts +8 -0
  136. package/dist/mcp-slate-tools.d.ts.map +1 -0
  137. package/dist/mcp-slate-tools.js +45 -0
  138. package/dist/mcp-slate-tools.js.map +1 -0
  139. package/dist/mcp-slate-ui-copy.d.ts +134 -0
  140. package/dist/mcp-slate-ui-copy.d.ts.map +1 -0
  141. package/dist/mcp-slate-ui-copy.js +136 -0
  142. package/dist/mcp-slate-ui-copy.js.map +1 -0
  143. package/dist/mcp-slate-ui-script-bridge.d.ts +18 -0
  144. package/dist/mcp-slate-ui-script-bridge.d.ts.map +1 -0
  145. package/dist/mcp-slate-ui-script-bridge.js +137 -0
  146. package/dist/mcp-slate-ui-script-bridge.js.map +1 -0
  147. package/dist/mcp-slate-ui-script-browser.d.ts +12 -0
  148. package/dist/mcp-slate-ui-script-browser.d.ts.map +1 -0
  149. package/dist/mcp-slate-ui-script-browser.js +19 -0
  150. package/dist/mcp-slate-ui-script-browser.js.map +1 -0
  151. package/dist/mcp-slate-ui-script-dialog.d.ts +20 -0
  152. package/dist/mcp-slate-ui-script-dialog.d.ts.map +1 -0
  153. package/dist/mcp-slate-ui-script-dialog.js +332 -0
  154. package/dist/mcp-slate-ui-script-dialog.js.map +1 -0
  155. package/dist/mcp-slate-ui-script-inline.d.ts +10 -0
  156. package/dist/mcp-slate-ui-script-inline.d.ts.map +1 -0
  157. package/dist/mcp-slate-ui-script-inline.js +221 -0
  158. package/dist/mcp-slate-ui-script-inline.js.map +1 -0
  159. package/dist/mcp-slate-ui-script-inspiration.d.ts +12 -0
  160. package/dist/mcp-slate-ui-script-inspiration.d.ts.map +1 -0
  161. package/dist/mcp-slate-ui-script-inspiration.js +216 -0
  162. package/dist/mcp-slate-ui-script-inspiration.js.map +1 -0
  163. package/dist/mcp-slate-ui-script-more.d.ts +30 -0
  164. package/dist/mcp-slate-ui-script-more.d.ts.map +1 -0
  165. package/dist/mcp-slate-ui-script-more.js +225 -0
  166. package/dist/mcp-slate-ui-script-more.js.map +1 -0
  167. package/dist/mcp-slate-ui-script-progress.d.ts +7 -0
  168. package/dist/mcp-slate-ui-script-progress.d.ts.map +1 -0
  169. package/dist/mcp-slate-ui-script-progress.js +9 -0
  170. package/dist/mcp-slate-ui-script-progress.js.map +1 -0
  171. package/dist/mcp-slate-ui-script-remote.d.ts +28 -0
  172. package/dist/mcp-slate-ui-script-remote.d.ts.map +1 -0
  173. package/dist/mcp-slate-ui-script-remote.js +147 -0
  174. package/dist/mcp-slate-ui-script-remote.js.map +1 -0
  175. package/dist/mcp-slate-ui-script-scribble.d.ts +19 -0
  176. package/dist/mcp-slate-ui-script-scribble.d.ts.map +1 -0
  177. package/dist/mcp-slate-ui-script-scribble.js +114 -0
  178. package/dist/mcp-slate-ui-script-scribble.js.map +1 -0
  179. package/dist/mcp-slate-ui-script-select.d.ts +16 -0
  180. package/dist/mcp-slate-ui-script-select.d.ts.map +1 -0
  181. package/dist/mcp-slate-ui-script-select.js +73 -0
  182. package/dist/mcp-slate-ui-script-select.js.map +1 -0
  183. package/dist/mcp-slate-ui-script-stage.d.ts +11 -0
  184. package/dist/mcp-slate-ui-script-stage.d.ts.map +1 -0
  185. package/dist/mcp-slate-ui-script-stage.js +181 -0
  186. package/dist/mcp-slate-ui-script-stage.js.map +1 -0
  187. package/dist/mcp-slate-ui-script-state.d.ts +13 -0
  188. package/dist/mcp-slate-ui-script-state.d.ts.map +1 -0
  189. package/dist/mcp-slate-ui-script-state.js +306 -0
  190. package/dist/mcp-slate-ui-script-state.js.map +1 -0
  191. package/dist/mcp-slate-ui-script-thumbtools.d.ts +23 -0
  192. package/dist/mcp-slate-ui-script-thumbtools.d.ts.map +1 -0
  193. package/dist/mcp-slate-ui-script-thumbtools.js +103 -0
  194. package/dist/mcp-slate-ui-script-thumbtools.js.map +1 -0
  195. package/dist/mcp-slate-ui-script.d.ts +28 -0
  196. package/dist/mcp-slate-ui-script.d.ts.map +1 -0
  197. package/dist/mcp-slate-ui-script.js +58 -0
  198. package/dist/mcp-slate-ui-script.js.map +1 -0
  199. package/dist/mcp-slate-ui-styles-dialog.d.ts +17 -0
  200. package/dist/mcp-slate-ui-styles-dialog.d.ts.map +1 -0
  201. package/dist/mcp-slate-ui-styles-dialog.js +73 -0
  202. package/dist/mcp-slate-ui-styles-dialog.js.map +1 -0
  203. package/dist/mcp-slate-ui-styles-stage.d.ts +12 -0
  204. package/dist/mcp-slate-ui-styles-stage.d.ts.map +1 -0
  205. package/dist/mcp-slate-ui-styles-stage.js +53 -0
  206. package/dist/mcp-slate-ui-styles-stage.js.map +1 -0
  207. package/dist/mcp-slate-ui-styles-thumbtools.d.ts +10 -0
  208. package/dist/mcp-slate-ui-styles-thumbtools.d.ts.map +1 -0
  209. package/dist/mcp-slate-ui-styles-thumbtools.js +25 -0
  210. package/dist/mcp-slate-ui-styles-thumbtools.js.map +1 -0
  211. package/dist/mcp-slate-ui-styles.d.ts +13 -0
  212. package/dist/mcp-slate-ui-styles.d.ts.map +1 -0
  213. package/dist/mcp-slate-ui-styles.js +117 -0
  214. package/dist/mcp-slate-ui-styles.js.map +1 -0
  215. package/dist/mcp-slate-ui.d.ts +16 -0
  216. package/dist/mcp-slate-ui.d.ts.map +1 -0
  217. package/dist/mcp-slate-ui.js +58 -0
  218. package/dist/mcp-slate-ui.js.map +1 -0
  219. package/dist/mcp-slate-workspace-tools.d.ts +15 -0
  220. package/dist/mcp-slate-workspace-tools.d.ts.map +1 -0
  221. package/dist/mcp-slate-workspace-tools.js +155 -0
  222. package/dist/mcp-slate-workspace-tools.js.map +1 -0
  223. package/dist/mcp-tool-definitions.d.ts.map +1 -1
  224. package/dist/mcp-tool-definitions.js +9 -7
  225. package/dist/mcp-tool-definitions.js.map +1 -1
  226. package/dist/mcp-tool-handler.d.ts +8 -2
  227. package/dist/mcp-tool-handler.d.ts.map +1 -1
  228. package/dist/mcp-tool-handler.js +34 -13
  229. package/dist/mcp-tool-handler.js.map +1 -1
  230. package/dist/mcp-workflow-tools.d.ts +6 -0
  231. package/dist/mcp-workflow-tools.d.ts.map +1 -0
  232. package/dist/mcp-workflow-tools.js +108 -0
  233. package/dist/mcp-workflow-tools.js.map +1 -0
  234. package/dist/prototype-browsers.d.ts +8 -2
  235. package/dist/prototype-browsers.d.ts.map +1 -1
  236. package/dist/prototype-browsers.js +8 -3
  237. package/dist/prototype-browsers.js.map +1 -1
  238. package/dist/prototype-label-client.d.ts +5 -0
  239. package/dist/prototype-label-client.d.ts.map +1 -1
  240. package/dist/prototype-label-client.js.map +1 -1
  241. package/dist/prototype-poststep.d.ts +2 -2
  242. package/dist/prototype-poststep.d.ts.map +1 -1
  243. package/dist/prototype-poststep.js +3 -0
  244. package/dist/prototype-poststep.js.map +1 -1
  245. package/dist/prototype-process.js +1 -1
  246. package/dist/prototype-process.js.map +1 -1
  247. package/dist/prototype-run-record.d.ts +6 -2
  248. package/dist/prototype-run-record.d.ts.map +1 -1
  249. package/dist/prototype-run-record.js +6 -0
  250. package/dist/prototype-run-record.js.map +1 -1
  251. package/dist/prototype-runner.d.ts +2 -2
  252. package/dist/prototype-runner.d.ts.map +1 -1
  253. package/dist/prototype-runner.js +5 -2
  254. package/dist/prototype-runner.js.map +1 -1
  255. package/dist/prototype-workflow-contract.d.ts +13 -0
  256. package/dist/prototype-workflow-contract.d.ts.map +1 -0
  257. package/dist/prototype-workflow-contract.js +82 -0
  258. package/dist/prototype-workflow-contract.js.map +1 -0
  259. package/dist/prototype-workflow-labels.d.ts +29 -0
  260. package/dist/prototype-workflow-labels.d.ts.map +1 -0
  261. package/dist/prototype-workflow-labels.js +93 -0
  262. package/dist/prototype-workflow-labels.js.map +1 -0
  263. package/dist/run-journal-commands.d.ts.map +1 -1
  264. package/dist/run-journal-commands.js +24 -5
  265. package/dist/run-journal-commands.js.map +1 -1
  266. package/dist/scene/camera-model.d.ts +48 -0
  267. package/dist/scene/camera-model.d.ts.map +1 -0
  268. package/dist/scene/camera-model.js +89 -0
  269. package/dist/scene/camera-model.js.map +1 -0
  270. package/dist/scene/camera-solve.d.ts +58 -0
  271. package/dist/scene/camera-solve.d.ts.map +1 -0
  272. package/dist/scene/camera-solve.js +288 -0
  273. package/dist/scene/camera-solve.js.map +1 -0
  274. package/dist/scene/capture-plan.d.ts +28 -0
  275. package/dist/scene/capture-plan.d.ts.map +1 -0
  276. package/dist/scene/capture-plan.js +79 -0
  277. package/dist/scene/capture-plan.js.map +1 -0
  278. package/dist/scene/capture.d.ts +21 -0
  279. package/dist/scene/capture.d.ts.map +1 -0
  280. package/dist/scene/capture.js +118 -0
  281. package/dist/scene/capture.js.map +1 -0
  282. package/dist/scene/image-colors.d.ts +25 -0
  283. package/dist/scene/image-colors.d.ts.map +1 -0
  284. package/dist/scene/image-colors.js +110 -0
  285. package/dist/scene/image-colors.js.map +1 -0
  286. package/dist/scene/image-rectify.d.ts +25 -0
  287. package/dist/scene/image-rectify.d.ts.map +1 -0
  288. package/dist/scene/image-rectify.js +82 -0
  289. package/dist/scene/image-rectify.js.map +1 -0
  290. package/dist/scene/image-sheet.d.ts +19 -0
  291. package/dist/scene/image-sheet.d.ts.map +1 -0
  292. package/dist/scene/image-sheet.js +118 -0
  293. package/dist/scene/image-sheet.js.map +1 -0
  294. package/dist/scene/least-squares.d.ts +31 -0
  295. package/dist/scene/least-squares.d.ts.map +1 -0
  296. package/dist/scene/least-squares.js +173 -0
  297. package/dist/scene/least-squares.js.map +1 -0
  298. package/dist/scene/numbers.d.ts +17 -0
  299. package/dist/scene/numbers.d.ts.map +1 -0
  300. package/dist/scene/numbers.js +39 -0
  301. package/dist/scene/numbers.js.map +1 -0
  302. package/dist/scene/placement.d.ts +43 -0
  303. package/dist/scene/placement.d.ts.map +1 -0
  304. package/dist/scene/placement.js +107 -0
  305. package/dist/scene/placement.js.map +1 -0
  306. package/dist/scene/raster.d.ts +18 -0
  307. package/dist/scene/raster.d.ts.map +1 -0
  308. package/dist/scene/raster.js +31 -0
  309. package/dist/scene/raster.js.map +1 -0
  310. package/dist/scene/scene-kit.d.ts +20 -0
  311. package/dist/scene/scene-kit.d.ts.map +1 -0
  312. package/dist/scene/scene-kit.js +74 -0
  313. package/dist/scene/scene-kit.js.map +1 -0
  314. package/dist/scene/scene-verbs.d.ts +4 -0
  315. package/dist/scene/scene-verbs.d.ts.map +1 -0
  316. package/dist/scene/scene-verbs.js +5 -0
  317. package/dist/scene/scene-verbs.js.map +1 -0
  318. package/dist/scene/seeded-random.d.ts +20 -0
  319. package/dist/scene/seeded-random.d.ts.map +1 -0
  320. package/dist/scene/seeded-random.js +42 -0
  321. package/dist/scene/seeded-random.js.map +1 -0
  322. package/dist/scene/spec-expression.d.ts +25 -0
  323. package/dist/scene/spec-expression.d.ts.map +1 -0
  324. package/dist/scene/spec-expression.js +234 -0
  325. package/dist/scene/spec-expression.js.map +1 -0
  326. package/dist/scene/static-server.d.ts +13 -0
  327. package/dist/scene/static-server.d.ts.map +1 -0
  328. package/dist/scene/static-server.js +99 -0
  329. package/dist/scene/static-server.js.map +1 -0
  330. package/dist/server.d.ts +22 -2
  331. package/dist/server.d.ts.map +1 -1
  332. package/dist/server.js +44 -8
  333. package/dist/server.js.map +1 -1
  334. package/dist/slate-actions.d.ts +38 -0
  335. package/dist/slate-actions.d.ts.map +1 -0
  336. package/dist/slate-actions.js +102 -0
  337. package/dist/slate-actions.js.map +1 -0
  338. package/dist/slate-annotate.d.ts +36 -0
  339. package/dist/slate-annotate.d.ts.map +1 -0
  340. package/dist/slate-annotate.js +71 -0
  341. package/dist/slate-annotate.js.map +1 -0
  342. package/dist/slate-approvals.d.ts +61 -0
  343. package/dist/slate-approvals.d.ts.map +1 -0
  344. package/dist/slate-approvals.js +153 -0
  345. package/dist/slate-approvals.js.map +1 -0
  346. package/dist/slate-browser-decision.d.ts +30 -0
  347. package/dist/slate-browser-decision.d.ts.map +1 -0
  348. package/dist/slate-browser-decision.js +24 -0
  349. package/dist/slate-browser-decision.js.map +1 -0
  350. package/dist/slate-browser-host-script.d.ts +14 -0
  351. package/dist/slate-browser-host-script.d.ts.map +1 -0
  352. package/dist/slate-browser-host-script.js +125 -0
  353. package/dist/slate-browser-host-script.js.map +1 -0
  354. package/dist/slate-browser-host.d.ts +9 -0
  355. package/dist/slate-browser-host.d.ts.map +1 -0
  356. package/dist/slate-browser-host.js +37 -0
  357. package/dist/slate-browser-host.js.map +1 -0
  358. package/dist/slate-browser-server.d.ts +37 -0
  359. package/dist/slate-browser-server.d.ts.map +1 -0
  360. package/dist/slate-browser-server.js +186 -0
  361. package/dist/slate-browser-server.js.map +1 -0
  362. package/dist/slate-commit.d.ts +28 -0
  363. package/dist/slate-commit.d.ts.map +1 -0
  364. package/dist/slate-commit.js +218 -0
  365. package/dist/slate-commit.js.map +1 -0
  366. package/dist/slate-corpus.d.ts +14 -0
  367. package/dist/slate-corpus.d.ts.map +1 -0
  368. package/dist/slate-corpus.js +32 -0
  369. package/dist/slate-corpus.js.map +1 -0
  370. package/dist/slate-edit-prompt.d.ts +18 -0
  371. package/dist/slate-edit-prompt.d.ts.map +1 -0
  372. package/dist/slate-edit-prompt.js +41 -0
  373. package/dist/slate-edit-prompt.js.map +1 -0
  374. package/dist/slate-edit-runner.d.ts +4 -0
  375. package/dist/slate-edit-runner.d.ts.map +1 -0
  376. package/dist/slate-edit-runner.js +90 -0
  377. package/dist/slate-edit-runner.js.map +1 -0
  378. package/dist/slate-editability.d.ts +20 -0
  379. package/dist/slate-editability.d.ts.map +1 -0
  380. package/dist/slate-editability.js +19 -0
  381. package/dist/slate-editability.js.map +1 -0
  382. package/dist/slate-errors.d.ts +15 -0
  383. package/dist/slate-errors.d.ts.map +1 -0
  384. package/dist/slate-errors.js +21 -0
  385. package/dist/slate-errors.js.map +1 -0
  386. package/dist/slate-handoff-options.d.ts +40 -0
  387. package/dist/slate-handoff-options.d.ts.map +1 -0
  388. package/dist/slate-handoff-options.js +127 -0
  389. package/dist/slate-handoff-options.js.map +1 -0
  390. package/dist/slate-handoff.d.ts +11 -0
  391. package/dist/slate-handoff.d.ts.map +1 -0
  392. package/dist/slate-handoff.js +56 -0
  393. package/dist/slate-handoff.js.map +1 -0
  394. package/dist/slate-ids.d.ts +33 -0
  395. package/dist/slate-ids.d.ts.map +1 -0
  396. package/dist/slate-ids.js +47 -0
  397. package/dist/slate-ids.js.map +1 -0
  398. package/dist/slate-image-executor.d.ts +39 -0
  399. package/dist/slate-image-executor.d.ts.map +1 -0
  400. package/dist/slate-image-executor.js +52 -0
  401. package/dist/slate-image-executor.js.map +1 -0
  402. package/dist/slate-inspiration.d.ts +22 -0
  403. package/dist/slate-inspiration.d.ts.map +1 -0
  404. package/dist/slate-inspiration.js +112 -0
  405. package/dist/slate-inspiration.js.map +1 -0
  406. package/dist/slate-labels.d.ts +11 -0
  407. package/dist/slate-labels.d.ts.map +1 -0
  408. package/dist/slate-labels.js +32 -0
  409. package/dist/slate-labels.js.map +1 -0
  410. package/dist/slate-ledger.d.ts +29 -0
  411. package/dist/slate-ledger.d.ts.map +1 -0
  412. package/dist/slate-ledger.js +65 -0
  413. package/dist/slate-ledger.js.map +1 -0
  414. package/dist/slate-liveness.d.ts +26 -0
  415. package/dist/slate-liveness.d.ts.map +1 -0
  416. package/dist/slate-liveness.js +49 -0
  417. package/dist/slate-liveness.js.map +1 -0
  418. package/dist/slate-local-image.d.ts +19 -0
  419. package/dist/slate-local-image.d.ts.map +1 -0
  420. package/dist/slate-local-image.js +36 -0
  421. package/dist/slate-local-image.js.map +1 -0
  422. package/dist/slate-lock.d.ts +64 -0
  423. package/dist/slate-lock.d.ts.map +1 -0
  424. package/dist/slate-lock.js +178 -0
  425. package/dist/slate-lock.js.map +1 -0
  426. package/dist/slate-paths.d.ts +45 -0
  427. package/dist/slate-paths.d.ts.map +1 -0
  428. package/dist/slate-paths.js +132 -0
  429. package/dist/slate-paths.js.map +1 -0
  430. package/dist/slate-pick.d.ts +29 -0
  431. package/dist/slate-pick.d.ts.map +1 -0
  432. package/dist/slate-pick.js +55 -0
  433. package/dist/slate-pick.js.map +1 -0
  434. package/dist/slate-reference-ids.d.ts +6 -0
  435. package/dist/slate-reference-ids.d.ts.map +1 -0
  436. package/dist/slate-reference-ids.js +17 -0
  437. package/dist/slate-reference-ids.js.map +1 -0
  438. package/dist/slate-reference-store.d.ts +23 -0
  439. package/dist/slate-reference-store.d.ts.map +1 -0
  440. package/dist/slate-reference-store.js +46 -0
  441. package/dist/slate-reference-store.js.map +1 -0
  442. package/dist/slate-resume.d.ts +19 -0
  443. package/dist/slate-resume.d.ts.map +1 -0
  444. package/dist/slate-resume.js +94 -0
  445. package/dist/slate-resume.js.map +1 -0
  446. package/dist/slate-round-params.d.ts +20 -0
  447. package/dist/slate-round-params.d.ts.map +1 -0
  448. package/dist/slate-round-params.js +32 -0
  449. package/dist/slate-round-params.js.map +1 -0
  450. package/dist/slate-round-prompt.d.ts +18 -0
  451. package/dist/slate-round-prompt.d.ts.map +1 -0
  452. package/dist/slate-round-prompt.js +20 -0
  453. package/dist/slate-round-prompt.js.map +1 -0
  454. package/dist/slate-round-runner.d.ts +4 -0
  455. package/dist/slate-round-runner.d.ts.map +1 -0
  456. package/dist/slate-round-runner.js +125 -0
  457. package/dist/slate-round-runner.js.map +1 -0
  458. package/dist/slate-round-search.d.ts +7 -0
  459. package/dist/slate-round-search.d.ts.map +1 -0
  460. package/dist/slate-round-search.js +77 -0
  461. package/dist/slate-round-search.js.map +1 -0
  462. package/dist/slate-run-action.d.ts +14 -0
  463. package/dist/slate-run-action.d.ts.map +1 -0
  464. package/dist/slate-run-action.js +81 -0
  465. package/dist/slate-run-action.js.map +1 -0
  466. package/dist/slate-runner-context.d.ts +57 -0
  467. package/dist/slate-runner-context.d.ts.map +1 -0
  468. package/dist/slate-runner-context.js +79 -0
  469. package/dist/slate-runner-context.js.map +1 -0
  470. package/dist/slate-runner-failure.d.ts +8 -0
  471. package/dist/slate-runner-failure.d.ts.map +1 -0
  472. package/dist/slate-runner-failure.js +17 -0
  473. package/dist/slate-runner-failure.js.map +1 -0
  474. package/dist/slate-runner-flag.d.ts +3 -0
  475. package/dist/slate-runner-flag.d.ts.map +1 -0
  476. package/dist/slate-runner-flag.js +3 -0
  477. package/dist/slate-runner-flag.js.map +1 -0
  478. package/dist/slate-runner-main.d.ts +31 -0
  479. package/dist/slate-runner-main.d.ts.map +1 -0
  480. package/dist/slate-runner-main.js +132 -0
  481. package/dist/slate-runner-main.js.map +1 -0
  482. package/dist/slate-runner-spawn.d.ts +23 -0
  483. package/dist/slate-runner-spawn.d.ts.map +1 -0
  484. package/dist/slate-runner-spawn.js +27 -0
  485. package/dist/slate-runner-spawn.js.map +1 -0
  486. package/dist/slate-runtime.d.ts +38 -0
  487. package/dist/slate-runtime.d.ts.map +1 -0
  488. package/dist/slate-runtime.js +48 -0
  489. package/dist/slate-runtime.js.map +1 -0
  490. package/dist/slate-versions.d.ts +26 -0
  491. package/dist/slate-versions.d.ts.map +1 -0
  492. package/dist/slate-versions.js +110 -0
  493. package/dist/slate-versions.js.map +1 -0
  494. package/dist/slate-view-contract.d.ts +233 -0
  495. package/dist/slate-view-contract.d.ts.map +1 -0
  496. package/dist/slate-view-contract.js +17 -0
  497. package/dist/slate-view-contract.js.map +1 -0
  498. package/dist/slate-view-types.d.ts +2 -0
  499. package/dist/slate-view-types.d.ts.map +1 -0
  500. package/dist/slate-view-types.js +2 -0
  501. package/dist/slate-view-types.js.map +1 -0
  502. package/dist/slate-view.d.ts +19 -0
  503. package/dist/slate-view.d.ts.map +1 -0
  504. package/dist/slate-view.js +184 -0
  505. package/dist/slate-view.js.map +1 -0
  506. package/dist/slate-workspace-parse.d.ts +20 -0
  507. package/dist/slate-workspace-parse.d.ts.map +1 -0
  508. package/dist/slate-workspace-parse.js +437 -0
  509. package/dist/slate-workspace-parse.js.map +1 -0
  510. package/dist/slate-workspace-store.d.ts +44 -0
  511. package/dist/slate-workspace-store.d.ts.map +1 -0
  512. package/dist/slate-workspace-store.js +270 -0
  513. package/dist/slate-workspace-store.js.map +1 -0
  514. package/dist/slate-workspace-types.d.ts +176 -0
  515. package/dist/slate-workspace-types.d.ts.map +1 -0
  516. package/dist/slate-workspace-types.js +13 -0
  517. package/dist/slate-workspace-types.js.map +1 -0
  518. package/dist/workflow/adapter-12ui.d.ts +4 -0
  519. package/dist/workflow/adapter-12ui.d.ts.map +1 -0
  520. package/dist/workflow/adapter-12ui.js +147 -0
  521. package/dist/workflow/adapter-12ui.js.map +1 -0
  522. package/dist/workflow/adapter-layerdoc.d.ts +16 -0
  523. package/dist/workflow/adapter-layerdoc.d.ts.map +1 -0
  524. package/dist/workflow/adapter-layerdoc.js +116 -0
  525. package/dist/workflow/adapter-layerdoc.js.map +1 -0
  526. package/dist/workflow/adapter-openai.d.ts +4 -0
  527. package/dist/workflow/adapter-openai.d.ts.map +1 -0
  528. package/dist/workflow/adapter-openai.js +166 -0
  529. package/dist/workflow/adapter-openai.js.map +1 -0
  530. package/dist/workflow/adapter-process.d.ts +7 -0
  531. package/dist/workflow/adapter-process.d.ts.map +1 -0
  532. package/dist/workflow/adapter-process.js +174 -0
  533. package/dist/workflow/adapter-process.js.map +1 -0
  534. package/dist/workflow/adapter-prototype-labels.d.ts +15 -0
  535. package/dist/workflow/adapter-prototype-labels.d.ts.map +1 -0
  536. package/dist/workflow/adapter-prototype-labels.js +71 -0
  537. package/dist/workflow/adapter-prototype-labels.js.map +1 -0
  538. package/dist/workflow/adapter-types.d.ts +40 -0
  539. package/dist/workflow/adapter-types.d.ts.map +1 -0
  540. package/dist/workflow/adapter-types.js +2 -0
  541. package/dist/workflow/adapter-types.js.map +1 -0
  542. package/dist/workflow/adapter-utils.d.ts +11 -0
  543. package/dist/workflow/adapter-utils.d.ts.map +1 -0
  544. package/dist/workflow/adapter-utils.js +72 -0
  545. package/dist/workflow/adapter-utils.js.map +1 -0
  546. package/dist/workflow/adapters.d.ts +6 -0
  547. package/dist/workflow/adapters.d.ts.map +1 -0
  548. package/dist/workflow/adapters.js +25 -0
  549. package/dist/workflow/adapters.js.map +1 -0
  550. package/dist/workflow/artifact.d.ts +11 -0
  551. package/dist/workflow/artifact.d.ts.map +1 -0
  552. package/dist/workflow/artifact.js +94 -0
  553. package/dist/workflow/artifact.js.map +1 -0
  554. package/dist/workflow/bundle-collect.d.ts +8 -0
  555. package/dist/workflow/bundle-collect.d.ts.map +1 -0
  556. package/dist/workflow/bundle-collect.js +56 -0
  557. package/dist/workflow/bundle-collect.js.map +1 -0
  558. package/dist/workflow/bundle-export.d.ts +16 -0
  559. package/dist/workflow/bundle-export.d.ts.map +1 -0
  560. package/dist/workflow/bundle-export.js +174 -0
  561. package/dist/workflow/bundle-export.js.map +1 -0
  562. package/dist/workflow/bundle-paths.d.ts +7 -0
  563. package/dist/workflow/bundle-paths.d.ts.map +1 -0
  564. package/dist/workflow/bundle-paths.js +35 -0
  565. package/dist/workflow/bundle-paths.js.map +1 -0
  566. package/dist/workflow/bundle.d.ts +4 -0
  567. package/dist/workflow/bundle.d.ts.map +1 -0
  568. package/dist/workflow/bundle.js +4 -0
  569. package/dist/workflow/bundle.js.map +1 -0
  570. package/dist/workflow/capture.d.ts +36 -0
  571. package/dist/workflow/capture.d.ts.map +1 -0
  572. package/dist/workflow/capture.js +81 -0
  573. package/dist/workflow/capture.js.map +1 -0
  574. package/dist/workflow/continuation-branch.d.ts +15 -0
  575. package/dist/workflow/continuation-branch.d.ts.map +1 -0
  576. package/dist/workflow/continuation-branch.js +103 -0
  577. package/dist/workflow/continuation-branch.js.map +1 -0
  578. package/dist/workflow/continuation-plans.d.ts +38 -0
  579. package/dist/workflow/continuation-plans.d.ts.map +1 -0
  580. package/dist/workflow/continuation-plans.js +78 -0
  581. package/dist/workflow/continuation-plans.js.map +1 -0
  582. package/dist/workflow/continuation.d.ts +25 -0
  583. package/dist/workflow/continuation.d.ts.map +1 -0
  584. package/dist/workflow/continuation.js +89 -0
  585. package/dist/workflow/continuation.js.map +1 -0
  586. package/dist/workflow/layerdoc-reader.d.ts +27 -0
  587. package/dist/workflow/layerdoc-reader.d.ts.map +1 -0
  588. package/dist/workflow/layerdoc-reader.js +81 -0
  589. package/dist/workflow/layerdoc-reader.js.map +1 -0
  590. package/dist/workflow/project-evidence.d.ts +48 -0
  591. package/dist/workflow/project-evidence.d.ts.map +1 -0
  592. package/dist/workflow/project-evidence.js +200 -0
  593. package/dist/workflow/project-evidence.js.map +1 -0
  594. package/dist/workflow/providers.d.ts +35 -0
  595. package/dist/workflow/providers.d.ts.map +1 -0
  596. package/dist/workflow/providers.js +110 -0
  597. package/dist/workflow/providers.js.map +1 -0
  598. package/dist/workflow/recipes-layerdoc-validation.d.ts +4 -0
  599. package/dist/workflow/recipes-layerdoc-validation.d.ts.map +1 -0
  600. package/dist/workflow/recipes-layerdoc-validation.js +98 -0
  601. package/dist/workflow/recipes-layerdoc-validation.js.map +1 -0
  602. package/dist/workflow/recipes-result-validation.d.ts +6 -0
  603. package/dist/workflow/recipes-result-validation.d.ts.map +1 -0
  604. package/dist/workflow/recipes-result-validation.js +38 -0
  605. package/dist/workflow/recipes-result-validation.js.map +1 -0
  606. package/dist/workflow/recipes-schemas.d.ts +7 -0
  607. package/dist/workflow/recipes-schemas.d.ts.map +1 -0
  608. package/dist/workflow/recipes-schemas.js +67 -0
  609. package/dist/workflow/recipes-schemas.js.map +1 -0
  610. package/dist/workflow/recipes-validation.d.ts +14 -0
  611. package/dist/workflow/recipes-validation.d.ts.map +1 -0
  612. package/dist/workflow/recipes-validation.js +68 -0
  613. package/dist/workflow/recipes-validation.js.map +1 -0
  614. package/dist/workflow/recipes.d.ts +20 -0
  615. package/dist/workflow/recipes.d.ts.map +1 -0
  616. package/dist/workflow/recipes.js +167 -0
  617. package/dist/workflow/recipes.js.map +1 -0
  618. package/dist/workflow/routing.d.ts +4 -0
  619. package/dist/workflow/routing.d.ts.map +1 -0
  620. package/dist/workflow/routing.js +28 -0
  621. package/dist/workflow/routing.js.map +1 -0
  622. package/dist/workflow/schema.d.ts +5 -0
  623. package/dist/workflow/schema.d.ts.map +1 -0
  624. package/dist/workflow/schema.js +29 -0
  625. package/dist/workflow/schema.js.map +1 -0
  626. package/dist/workflow/service.d.ts +59 -0
  627. package/dist/workflow/service.d.ts.map +1 -0
  628. package/dist/workflow/service.js +170 -0
  629. package/dist/workflow/service.js.map +1 -0
  630. package/dist/workflow/store-json.d.ts +5 -0
  631. package/dist/workflow/store-json.d.ts.map +1 -0
  632. package/dist/workflow/store-json.js +35 -0
  633. package/dist/workflow/store-json.js.map +1 -0
  634. package/dist/workflow/store-lock.d.ts +3 -0
  635. package/dist/workflow/store-lock.d.ts.map +1 -0
  636. package/dist/workflow/store-lock.js +85 -0
  637. package/dist/workflow/store-lock.js.map +1 -0
  638. package/dist/workflow/store-paths.d.ts +17 -0
  639. package/dist/workflow/store-paths.d.ts.map +1 -0
  640. package/dist/workflow/store-paths.js +67 -0
  641. package/dist/workflow/store-paths.js.map +1 -0
  642. package/dist/workflow/store-validation.d.ts +7 -0
  643. package/dist/workflow/store-validation.d.ts.map +1 -0
  644. package/dist/workflow/store-validation.js +119 -0
  645. package/dist/workflow/store-validation.js.map +1 -0
  646. package/dist/workflow/store.d.ts +10 -0
  647. package/dist/workflow/store.d.ts.map +1 -0
  648. package/dist/workflow/store.js +193 -0
  649. package/dist/workflow/store.js.map +1 -0
  650. package/dist/workflow/types.d.ts +120 -0
  651. package/dist/workflow/types.d.ts.map +1 -0
  652. package/dist/workflow/types.js +15 -0
  653. package/dist/workflow/types.js.map +1 -0
  654. package/dist/workflow-transport.d.ts +28 -0
  655. package/dist/workflow-transport.d.ts.map +1 -0
  656. package/dist/workflow-transport.js +184 -0
  657. package/dist/workflow-transport.js.map +1 -0
  658. package/open-design.json +2 -2
  659. package/package.json +4 -1
  660. package/prototype-kit/tests/rules-check.mjs +9 -0
  661. package/runtime/codex-conversion/src/images/native-invoke.mjs +1 -1
  662. package/runtime/codex-conversion/src/images/native.mjs +8 -4
  663. package/runtime/layerdoc-validator.mjs +1860 -0
  664. package/scene-kit/starter/camera.js +10 -0
  665. package/scene-kit/starter/gobo.js +60 -0
  666. package/scene-kit/starter/index.html +23 -0
  667. package/scene-kit/starter/lib.js +84 -0
  668. package/scene-kit/starter/main.js +78 -0
  669. package/scene-kit/starter/scene.js +33 -0
  670. package/scene-kit/vendor/LICENSE +21 -0
  671. package/scene-kit/vendor/addons/geometries/RoundedBoxGeometry.js +216 -0
  672. package/scene-kit/vendor/addons/renderers/CSS3DRenderer.js +454 -0
  673. package/scene-kit/vendor/three.core.js +60586 -0
  674. package/scene-kit/vendor/three.module.js +19719 -0
  675. package/skills/12ui-design/SKILL.md +21 -61
  676. package/skills/12ui-design/improve.md +5 -1
  677. package/skills/12ui-design/inspire.md +8 -5
  678. package/skills/12ui-design/outputs.md +23 -2
  679. package/skills/12ui-design/scene.md +172 -0
  680. package/skills/12ui-design/session.md +161 -0
@@ -0,0 +1,288 @@
1
+ import { degrees, projectPoints, radians, rotationMatrix, } from './camera-model.js';
2
+ import { multistart } from './least-squares.js';
3
+ import { fixed, roundTo } from './numbers.js';
4
+ import { seededRandom } from './seeded-random.js';
5
+ import { compileSpecCoordinate } from './spec-expression.js';
6
+ /**
7
+ * The least-squares camera (position, yaw, pitch, roll, vertical fov) that puts
8
+ * a spec's world landmarks on their source pixels. A port of the proven
9
+ * `solve_camera.py camera`: same parameterisation, bounds, penalty, multistart
10
+ * and diagnostics, and the same cam.json keys, so scene folders built with the
11
+ * Python helper keep working.
12
+ */
13
+ export const CAMERA_KEYS = ['cx', 'cy', 'cz', 'yaw', 'pitch', 'roll', 'fov'];
14
+ const ANGLE_KEYS = new Set(['yaw', 'pitch', 'roll']);
15
+ export class CameraSpecError extends Error {
16
+ constructor(message) {
17
+ super(message);
18
+ this.name = 'CameraSpecError';
19
+ }
20
+ }
21
+ const isFiniteNumber = (value) => typeof value === 'number' && Number.isFinite(value);
22
+ /** Validates and compiles a spec.json value; every refusal names the field. */
23
+ export const parseCameraSpec = (value, source = 'spec') => {
24
+ const fail = (message) => { throw new CameraSpecError(`${source}: ${message}`); };
25
+ if (!value || typeof value !== 'object' || Array.isArray(value))
26
+ fail('must be a JSON object');
27
+ const spec = value;
28
+ const image = spec.image;
29
+ if (!Array.isArray(image) || image.length !== 2 || !image.every((v) => isFiniteNumber(v) && v > 0)) {
30
+ fail('"image" must be [width, height] of the source image in pixels');
31
+ }
32
+ const freeValue = spec.free ?? {};
33
+ if (!freeValue || typeof freeValue !== 'object' || Array.isArray(freeValue))
34
+ fail('"free" must be an object of name: [low, high]');
35
+ const free = Object.entries(freeValue).map(([name, range]) => {
36
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/u.test(name))
37
+ fail(`free name "${name}" must be an identifier`);
38
+ if (CAMERA_KEYS.includes(name))
39
+ fail(`free name "${name}" collides with a camera key`);
40
+ if (!Array.isArray(range) || range.length !== 2 || !range.every(isFiniteNumber) || !(range[0] < range[1])) {
41
+ fail(`free "${name}" must be [low, high] with low < high`);
42
+ }
43
+ const [low, high] = range;
44
+ return { name, low, high };
45
+ });
46
+ const names = free.map((entry) => entry.name);
47
+ const fixValue = spec.fix ?? {};
48
+ if (!fixValue || typeof fixValue !== 'object' || Array.isArray(fixValue))
49
+ fail('"fix" must be an object of key: number');
50
+ const fix = new Map();
51
+ for (const [key, pinned] of Object.entries(fixValue)) {
52
+ if (!CAMERA_KEYS.includes(key) && !names.includes(key)) {
53
+ fail(`fix "${key}" is neither a camera key (${CAMERA_KEYS.join(' ')}) nor a free name`);
54
+ }
55
+ if (!isFiniteNumber(pinned))
56
+ fail(`fix "${key}" must be a number`);
57
+ fix.set(key, pinned);
58
+ }
59
+ // Almost every image is upright; a free roll trades against yaw near top-down and eats accuracy.
60
+ if (!fix.has('roll') && spec.solve_roll !== true)
61
+ fix.set('roll', 0);
62
+ const landmarksValue = spec.landmarks;
63
+ if (!Array.isArray(landmarksValue) || landmarksValue.length < 2)
64
+ fail('"landmarks" must list at least two landmarks');
65
+ const landmarks = landmarksValue.map((entry, index) => {
66
+ const record = entry;
67
+ const name = typeof record?.name === 'string' ? record.name : String(index);
68
+ const where = `${source} landmark "${name}"`;
69
+ const px = record?.px;
70
+ const world = record?.world;
71
+ if (!Array.isArray(px) || px.length !== 2 || !px.every(isFiniteNumber))
72
+ fail(`landmark "${name}": "px" must be [u, v]`);
73
+ if (!Array.isArray(world) || world.length !== 3)
74
+ fail(`landmark "${name}": "world" must be [x, y, z]`);
75
+ const coordinates = world.map((coordinate) => compileSpecCoordinate(coordinate, names, where));
76
+ return {
77
+ name,
78
+ px: [px[0], px[1]],
79
+ world: [coordinates[0], coordinates[1], coordinates[2]],
80
+ };
81
+ });
82
+ return { image: [image[0], image[1]], free, fix, landmarks };
83
+ };
84
+ const cameraOf = (p) => ({
85
+ pos: [p[0], p[1], p[2]],
86
+ yaw: p[3],
87
+ pitch: p[4],
88
+ roll: p[5],
89
+ fov: p[6],
90
+ });
91
+ /** Singular values of centred points: square roots of the covariance eigenvalues (Jacobi). */
92
+ const centredSingularValues = (points) => {
93
+ const mean = [0, 0, 0];
94
+ for (const point of points)
95
+ for (let axis = 0; axis < 3; axis += 1)
96
+ mean[axis] += point[axis] / points.length;
97
+ const a = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];
98
+ for (const point of points) {
99
+ const c = [point[0] - mean[0], point[1] - mean[1], point[2] - mean[2]];
100
+ for (let i = 0; i < 3; i += 1)
101
+ for (let j = 0; j < 3; j += 1)
102
+ a[i][j] += c[i] * c[j];
103
+ }
104
+ for (let sweep = 0; sweep < 64; sweep += 1) {
105
+ const off = a[0][1] ** 2 + a[0][2] ** 2 + a[1][2] ** 2;
106
+ if (off < 1e-30)
107
+ break;
108
+ for (let p = 0; p < 2; p += 1) {
109
+ for (let q = p + 1; q < 3; q += 1) {
110
+ if (Math.abs(a[p][q]) < 1e-300)
111
+ continue;
112
+ const theta = (a[q][q] - a[p][p]) / (2 * a[p][q]);
113
+ const t = Math.sign(theta || 1) / (Math.abs(theta) + Math.sqrt(theta * theta + 1));
114
+ const c = 1 / Math.sqrt(t * t + 1);
115
+ const s = t * c;
116
+ for (let k = 0; k < 3; k += 1) {
117
+ const akp = a[k][p], akq = a[k][q];
118
+ a[k][p] = c * akp - s * akq;
119
+ a[k][q] = s * akp + c * akq;
120
+ }
121
+ for (let k = 0; k < 3; k += 1) {
122
+ const apk = a[p][k], aqk = a[q][k];
123
+ a[p][k] = c * apk - s * aqk;
124
+ a[q][k] = s * apk + c * aqk;
125
+ }
126
+ }
127
+ }
128
+ }
129
+ return [a[0][0], a[1][1], a[2][2]].map((value) => Math.sqrt(Math.max(value, 0))).sort((x, y) => y - x);
130
+ };
131
+ export const solveCamera = (spec, { starts = 500, sensitivityStarts = 100 } = {}) => {
132
+ const [width, height] = spec.image;
133
+ const freeNames = spec.free.map((entry) => entry.name);
134
+ const names = [...CAMERA_KEYS, ...freeNames];
135
+ const low = [-1e4, -1e4, -1e4, -Math.PI, -1.5533, -0.5, 4, ...spec.free.map((entry) => entry.low)];
136
+ const high = [1e4, 1e4, 1e4, Math.PI, 1.5533, 0.5, 120, ...spec.free.map((entry) => entry.high)];
137
+ const pixels = spec.landmarks.map((landmark) => landmark.px);
138
+ const world = (freeValues) => spec.landmarks.map((landmark) => [
139
+ landmark.world[0](freeValues),
140
+ landmark.world[1](freeValues),
141
+ landmark.world[2](freeValues),
142
+ ]);
143
+ const run = (fixMap, startCount) => {
144
+ const fixed = new Map();
145
+ for (const [key, value] of fixMap) {
146
+ fixed.set(names.indexOf(key), ANGLE_KEYS.has(key) ? radians(value) : value);
147
+ }
148
+ const variable = names.map((_, index) => index).filter((index) => !fixed.has(index));
149
+ const full = (v) => {
150
+ const p = new Float64Array(names.length);
151
+ for (const [index, value] of fixed)
152
+ p[index] = value;
153
+ variable.forEach((index, position) => { p[index] = v[position]; });
154
+ return p;
155
+ };
156
+ const residuals = (v) => {
157
+ const p = full(v);
158
+ const camera = cameraOf(p);
159
+ const projected = projectPoints(camera, world(p.subarray(7)), spec.image, rotationMatrix(p[3], p[4], p[5]));
160
+ const out = new Float64Array(projected.length * 2);
161
+ projected.forEach((projection, index) => {
162
+ // Penalty: a landmark behind the camera.
163
+ const penalty = Math.max(projection.depth + 0.01, 0) * 1e4;
164
+ out[2 * index] = projection.u - pixels[index][0] + penalty;
165
+ out[2 * index + 1] = projection.v - pixels[index][1] + penalty;
166
+ });
167
+ return out;
168
+ };
169
+ const random = seededRandom(1);
170
+ const mid = spec.free.map((entry) => (entry.low + entry.high) / 2);
171
+ const w0 = world(mid);
172
+ const centre = [0, 0, 0];
173
+ for (const point of w0)
174
+ for (let axis = 0; axis < 3; axis += 1)
175
+ centre[axis] += point[axis] / w0.length;
176
+ let spread = 0;
177
+ for (let axis = 0; axis < 3; axis += 1) {
178
+ const values = w0.map((point) => point[axis]);
179
+ spread = Math.max(spread, Math.max(...values) - Math.min(...values));
180
+ }
181
+ const radius = Math.max(spread, 1e-3);
182
+ const startsList = [];
183
+ for (let index = 0; index < startCount; index += 1) {
184
+ const distance = radius * random.uniform(1.2, 8);
185
+ const direction = [random.normal(), random.normal(), random.normal()];
186
+ direction[1] = Math.abs(direction[1]) * random.uniform(0.05, 1.0);
187
+ const length = Math.hypot(...direction);
188
+ const pos = [
189
+ centre[0] + (direction[0] / length) * distance,
190
+ centre[1] + (direction[1] / length) * distance,
191
+ centre[2] + (direction[2] / length) * distance,
192
+ ];
193
+ const forward = [centre[0] - pos[0], centre[1] - pos[1], centre[2] - pos[2]];
194
+ const forwardLength = Math.hypot(...forward);
195
+ const fw = [forward[0] / forwardLength, forward[1] / forwardLength, forward[2] / forwardLength];
196
+ const p = new Float64Array(names.length);
197
+ p[0] = pos[0];
198
+ p[1] = pos[1];
199
+ p[2] = pos[2];
200
+ p[3] = Math.atan2(-fw[0], -fw[2]);
201
+ p[4] = Math.asin(Math.min(Math.max(fw[1], -1), 1));
202
+ p[6] = random.uniform(10, 70);
203
+ spec.free.forEach((entry, position) => { p[7 + position] = random.uniform(entry.low, entry.high); });
204
+ for (const [fixedIndex, value] of fixed)
205
+ p[fixedIndex] = value;
206
+ startsList.push(Float64Array.from(variable.map((variableIndex) => p[variableIndex])));
207
+ }
208
+ const best = multistart(residuals, startsList, variable.map((index) => low[index]), variable.map((index) => high[index]));
209
+ const p = full(best.parameters);
210
+ const camera = cameraOf(p);
211
+ const projected = projectPoints(camera, world(p.subarray(7)), spec.image);
212
+ const errors = projected.map((projection, index) => Math.hypot(projection.u - pixels[index][0], projection.v - pixels[index][1]));
213
+ const rms = Math.sqrt(errors.reduce((total, error) => total + error * error, 0) / errors.length);
214
+ return { parameters: p, camera, errors, rms };
215
+ };
216
+ const solved = run(spec.fix, starts);
217
+ const p = solved.parameters;
218
+ const warnings = [];
219
+ const worldPoints = world(p.subarray(7));
220
+ const singular = centredSingularValues(worldPoints);
221
+ const coplanar = singular[2] / Math.max(singular[0], 1e-9) < 0.03;
222
+ let sensitivity;
223
+ if (!spec.fix.has('fov')) {
224
+ sensitivity = [0.6, 0.8, 1.25, 1.6].map((factor) => {
225
+ const fov = Math.min(Math.max(p[6] * factor, 5), 110);
226
+ const pinned = new Map(spec.fix);
227
+ pinned.set('fov', fov);
228
+ return { fov: roundTo(fov, 1), rmsPx: roundTo(run(pinned, sensitivityStarts).rms, 2) };
229
+ });
230
+ const rmsValues = [...sensitivity.map((entry) => entry.rmsPx), solved.rms];
231
+ const spread = Math.max(...rmsValues) - Math.min(...rmsValues);
232
+ if (coplanar || spread < 2.0) {
233
+ warnings.push(`fov is weakly determined (rms only varies ${fixed(spread, 1)} px across fov`
234
+ + ` ${fixed(sensitivity[0].fov, 1)}..${fixed(sensitivity.at(-1).fov, 1)} deg): `
235
+ + (coplanar ? 'the landmarks are coplanar. ' : '')
236
+ + 'Add a landmark off the plane (an object\'s top edge above its base), or pin it with "fix": {"fov": 35}.'
237
+ + ' Pin a value from the source\'s look: 20-30 tele/product shot, 35-50 normal, 60+ wide/room.');
238
+ }
239
+ if (p[6] === 4 || p[6] === 120)
240
+ warnings.push('fov hit its bound.');
241
+ }
242
+ else if (coplanar) {
243
+ warnings.push('landmarks are coplanar: with fov pinned, distance and height trade against each other;'
244
+ + ' the result is a consistent view but not unique.');
245
+ }
246
+ if (Math.abs(degrees(p[4])) > 75) {
247
+ warnings.push(`near top-down (pitch ${fixed(degrees(p[4]), 0)} deg): yaw and roll are coupled and pitch is near its bound.`
248
+ + ' Roll is pinned to 0 (use "solve_roll": true to free it); if rms stays high, check the landmark readings'
249
+ + ' before blaming the model.');
250
+ }
251
+ if (solved.rms > 4) {
252
+ warnings.push('rms > 4 px: a landmark is misread, the world model is wrong (a circle drawn as an ellipse, an object that is'
253
+ + ' not flat), or the image is lens-distorted. Drop the worst landmark and re-solve rather than adding more.');
254
+ }
255
+ const centre = [0, 0, 0];
256
+ for (const point of worldPoints)
257
+ for (let axis = 0; axis < 3; axis += 1)
258
+ centre[axis] += point[axis] / worldPoints.length;
259
+ const distance = Math.hypot(p[0] - centre[0], p[1] - centre[1], p[2] - centre[2]);
260
+ const clip = { near: roundTo(distance / 10, 3), far: roundTo(distance * 4, 3) };
261
+ const residuals = {};
262
+ spec.landmarks.forEach((landmark, index) => { residuals[landmark.name] = roundTo(solved.errors[index], 1); });
263
+ const result = {
264
+ image: [width, height],
265
+ pos: [roundTo(p[0], 5), roundTo(p[1], 5), roundTo(p[2], 5)],
266
+ yawDeg: roundTo(degrees(p[3]), 4),
267
+ pitchDeg: roundTo(degrees(p[4]), 4),
268
+ rollDeg: roundTo(degrees(p[5]), 4),
269
+ vfovDeg: roundTo(p[6], 4),
270
+ free: Object.fromEntries(freeNames.map((name, index) => [name, roundTo(p[7 + index], 5)])),
271
+ rmsPx: roundTo(solved.rms, 2),
272
+ residuals,
273
+ clip,
274
+ 'camera.js': `export const CAM = { pos: [${fixed(p[0], 5)}, ${fixed(p[1], 5)}, ${fixed(p[2], 5)}],`
275
+ + ` yawDeg: ${fixed(degrees(p[3]), 4)}, pitchDeg: ${fixed(degrees(p[4]), 4)},`
276
+ + ` rollDeg: ${fixed(degrees(p[5]), 4)}, vfov: ${fixed(p[6], 4)} };`
277
+ + ` export const CLIP = { near: ${clip.near}, far: ${clip.far} };`,
278
+ threejs: `camera.position.set(${fixed(p[0], 5)},${fixed(p[1], 5)},${fixed(p[2], 5)});`
279
+ + ` camera.rotation.order='YXZ'; camera.rotation.set(${fixed(p[4], 6)},${fixed(p[3], 6)},${fixed(p[5], 6)});`
280
+ + ` camera.fov=${fixed(p[6], 4)};`,
281
+ };
282
+ if (sensitivity)
283
+ result.fovSensitivity = sensitivity;
284
+ if (warnings.length)
285
+ result.warnings = warnings;
286
+ return result;
287
+ };
288
+ //# sourceMappingURL=camera-solve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camera-solve.js","sourceRoot":"","sources":["../../src/scene/camera-solve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Whether a request stays on this machine. Loopback http(s)/ws(s) and local
3
+ * schemes pass; every other host is a remote request, which capture blocks
4
+ * and counts.
5
+ */
6
+ export declare const isLocalRequestUrl: (url: string) => boolean;
7
+ /** Only a page served on this machine can be captured (`12ui scene serve`). */
8
+ export declare const isLoopbackPageUrl: (url: string) => boolean;
9
+ export type CaptureView = {
10
+ name: string;
11
+ azimuth: number;
12
+ elevation: number;
13
+ actions: Array<{
14
+ name: string;
15
+ t: number;
16
+ }>;
17
+ };
18
+ /**
19
+ * One view: `name=azimuth:elevation[:action=t,action=t]`, degrees about the
20
+ * scene pivot and each action's t in 0..1, e.g. `half=0:0:lid=0.5`.
21
+ */
22
+ export declare const parseCaptureView: (text: string) => CaptureView;
23
+ /** The default set: landing, each orbit angle, and every action at t = 1. */
24
+ export declare const defaultCaptureViews: (orbits: readonly number[], actions: readonly string[]) => CaptureView[];
25
+ export declare const parseOrbits: (text: string) => number[];
26
+ /** Console noise from software GL that says nothing about the scene. */
27
+ export declare const isCaptureNoise: (line: string) => boolean;
28
+ //# sourceMappingURL=capture-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture-plan.d.ts","sourceRoot":"","sources":["../../src/scene/capture-plan.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,KAAG,OAW/C,CAAC;AAEF,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,KAAG,OAO/C,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,KAAG,WAqB/C,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,mBAAmB,GAAI,QAAQ,SAAS,MAAM,EAAE,EAAE,SAAS,SAAS,MAAM,EAAE,KAAG,WAAW,EAItG,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,MAAM,EAI/C,CAAC;AAEH,wEAAwE;AACxE,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,OAAmD,CAAC"}
@@ -0,0 +1,79 @@
1
+ import { SceneArgumentError } from './numbers.js';
2
+ /**
3
+ * The pure half of `12ui scene capture`: which URLs a scene may load, and which
4
+ * views to shoot. Kept apart from the browser so both are testable without one.
5
+ */
6
+ const LOOPBACK_HOSTS = new Set(['127.0.0.1', 'localhost', '[::1]', '::1']);
7
+ /** Schemes that never leave the machine: the page's own bytes, not a request. */
8
+ const LOCAL_SCHEMES = new Set(['data:', 'blob:', 'about:', 'file:']);
9
+ /**
10
+ * Whether a request stays on this machine. Loopback http(s)/ws(s) and local
11
+ * schemes pass; every other host is a remote request, which capture blocks
12
+ * and counts.
13
+ */
14
+ export const isLocalRequestUrl = (url) => {
15
+ let parsed;
16
+ try {
17
+ parsed = new URL(url);
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ if (LOCAL_SCHEMES.has(parsed.protocol))
23
+ return true;
24
+ if (!['http:', 'https:', 'ws:', 'wss:'].includes(parsed.protocol))
25
+ return false;
26
+ const host = parsed.hostname.toLowerCase();
27
+ return LOOPBACK_HOSTS.has(host) || /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/u.test(host) || host.endsWith('.localhost');
28
+ };
29
+ /** Only a page served on this machine can be captured (`12ui scene serve`). */
30
+ export const isLoopbackPageUrl = (url) => {
31
+ try {
32
+ const parsed = new URL(url);
33
+ return ['http:', 'https:'].includes(parsed.protocol) && isLocalRequestUrl(url);
34
+ }
35
+ catch {
36
+ return false;
37
+ }
38
+ };
39
+ /**
40
+ * One view: `name=azimuth:elevation[:action=t,action=t]`, degrees about the
41
+ * scene pivot and each action's t in 0..1, e.g. `half=0:0:lid=0.5`.
42
+ */
43
+ export const parseCaptureView = (text) => {
44
+ const equals = text.indexOf('=');
45
+ const name = equals > 0 ? text.slice(0, equals) : '';
46
+ if (!/^[A-Za-z0-9._+-]+$/u.test(name)) {
47
+ throw new SceneArgumentError(`view "${text}" must be name=azimuth:elevation[:action=t,...] with a file-safe name`);
48
+ }
49
+ const [az = '0', el = '0', ...rest] = text.slice(equals + 1).split(':');
50
+ const azimuth = Number(az || '0');
51
+ const elevation = Number(el || '0');
52
+ if (!Number.isFinite(azimuth) || !Number.isFinite(elevation)) {
53
+ throw new SceneArgumentError(`view "${text}": azimuth and elevation must be numbers of degrees`);
54
+ }
55
+ const actions = rest.join(':').split(',').filter(Boolean).map((pair) => {
56
+ const [action, t] = pair.split('=');
57
+ const value = Number(t);
58
+ if (!action || t === undefined || !Number.isFinite(value)) {
59
+ throw new SceneArgumentError(`view "${text}": each action must be name=t with t in 0..1`);
60
+ }
61
+ return { name: action, t: value };
62
+ });
63
+ return { name, azimuth, elevation, actions };
64
+ };
65
+ /** The default set: landing, each orbit angle, and every action at t = 1. */
66
+ export const defaultCaptureViews = (orbits, actions) => [
67
+ { name: 'landing', azimuth: 0, elevation: 0, actions: [] },
68
+ ...orbits.map((azimuth) => ({ name: `az${azimuth > 0 ? '+' : ''}${azimuth}`, azimuth, elevation: 0, actions: [] })),
69
+ ...actions.map((action) => ({ name: `act-${action}`, azimuth: 0, elevation: 0, actions: [{ name: action, t: 1 }] })),
70
+ ];
71
+ export const parseOrbits = (text) => text.split(',').filter(Boolean).map((value) => {
72
+ const angle = Number(value);
73
+ if (!Number.isFinite(angle))
74
+ throw new SceneArgumentError(`--orbit must be comma-separated degrees, got "${text}"`);
75
+ return angle;
76
+ });
77
+ /** Console noise from software GL that says nothing about the scene. */
78
+ export const isCaptureNoise = (line) => /GPU stall|Clock|ReadPixels/u.test(line);
79
+ //# sourceMappingURL=capture-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture-plan.js","sourceRoot":"","sources":["../../src/scene/capture-plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { type CaptureView } from './capture-plan.js';
2
+ export type CaptureOptions = {
3
+ url: string;
4
+ outDir: string;
5
+ size: [number, number];
6
+ orbits: readonly number[];
7
+ hide: readonly string[];
8
+ evalScript?: string;
9
+ views: readonly CaptureView[];
10
+ };
11
+ export type CaptureReport = {
12
+ written: string[];
13
+ blocked: string[];
14
+ fonts: {
15
+ loaded: number;
16
+ failed: string[];
17
+ };
18
+ console: string[];
19
+ };
20
+ export declare const captureScene: (options: CaptureOptions, log: (line: string) => void) => Promise<CaptureReport>;
21
+ //# sourceMappingURL=capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/scene/capture.ts"],"names":[],"mappings":"AAQA,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAC;AAsB3B,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC5C,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAcF,eAAO,MAAM,YAAY,GACvB,SAAS,cAAc,EACvB,KAAK,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAC1B,OAAO,CAAC,aAAa,CAwFvB,CAAC"}
@@ -0,0 +1,118 @@
1
+ import { mkdir } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { isMissingPrototypeBrowserOutput, missingPrototypeBrowserMessage, resolvePrototypeBrowserProvisioning, } from '../prototype-browsers.js';
4
+ import { defaultCaptureViews, isCaptureNoise, isLocalRequestUrl, } from './capture-plan.js';
5
+ /**
6
+ * Headless captures of a served scene with the CLI's managed Chromium.
7
+ *
8
+ * This is where the local-first rule is enforced: every request that would
9
+ * leave the machine is aborted and counted, and the report says how many and
10
+ * which fonts loaded, so a remote font or texture is a visible defect rather
11
+ * than a silent dependency. Nothing is ever downloaded: a missing browser stops
12
+ * with the managed install command.
13
+ */
14
+ const SOFTWARE_GL_ARGS = [
15
+ '--use-angle=swiftshader',
16
+ '--use-gl=angle',
17
+ '--enable-unsafe-swiftshader',
18
+ '--enable-webgl',
19
+ '--ignore-gpu-blocklist',
20
+ '--force-color-profile=srgb',
21
+ '--hide-scrollbars',
22
+ ];
23
+ export const captureScene = async (options, log) => {
24
+ const provisioning = await resolvePrototypeBrowserProvisioning();
25
+ process.env.PLAYWRIGHT_BROWSERS_PATH = provisioning.browsersPath;
26
+ const { chromium } = await import('@playwright/test');
27
+ let browser;
28
+ try {
29
+ browser = await chromium.launch({ args: SOFTWARE_GL_ARGS });
30
+ }
31
+ catch (error) {
32
+ const message = error instanceof Error ? error.message : String(error);
33
+ if (isMissingPrototypeBrowserOutput(message)) {
34
+ throw new Error(missingPrototypeBrowserMessage({ subject: 'Scene capture', provisioning }));
35
+ }
36
+ throw error;
37
+ }
38
+ const report = { written: [], blocked: [], fonts: { loaded: 0, failed: [] }, console: [] };
39
+ try {
40
+ const page = await browser.newPage({
41
+ viewport: { width: options.size[0], height: options.size[1] },
42
+ deviceScaleFactor: 1,
43
+ });
44
+ await page.route('**/*', async (route) => {
45
+ const url = route.request().url();
46
+ if (isLocalRequestUrl(url)) {
47
+ await route.continue();
48
+ return;
49
+ }
50
+ report.blocked.push(url);
51
+ await route.abort('blockedbyclient');
52
+ });
53
+ page.on('console', (message) => {
54
+ if (message.type() === 'error' || message.type() === 'warning') {
55
+ report.console.push(`[${message.type()}] ${message.text()}`);
56
+ }
57
+ });
58
+ page.on('pageerror', (error) => { report.console.push(`[pageerror] ${error.message}`); });
59
+ await mkdir(options.outDir, { recursive: true });
60
+ await page.goto(options.url, { waitUntil: 'load' });
61
+ await page.waitForFunction(() => window.__ready === true, null, { timeout: 120_000 });
62
+ await page.evaluate(() => document.fonts.ready.then(() => undefined));
63
+ await page.waitForTimeout(500);
64
+ const fonts = await page.evaluate(() => {
65
+ const faces = [];
66
+ document.fonts.forEach((face) => { faces.push({ family: face.family, status: face.status }); });
67
+ return faces;
68
+ });
69
+ report.fonts.loaded = fonts.filter((face) => face.status === 'loaded').length;
70
+ report.fonts.failed = fonts.filter((face) => face.status === 'error').map((face) => face.family);
71
+ if (options.evalScript)
72
+ await page.evaluate(options.evalScript);
73
+ const actions = await page.evaluate(() => window.__scene?.actions ?? []);
74
+ const views = options.views.length ? options.views : defaultCaptureViews(options.orbits, actions);
75
+ for (const view of views) {
76
+ await page.evaluate((v) => {
77
+ const scene = window.__scene;
78
+ scene.reset();
79
+ for (const action of v.actions)
80
+ scene.setAction(action.name, action.t);
81
+ scene.setOrbit(v.azimuth, v.elevation);
82
+ scene.render();
83
+ }, view);
84
+ if (options.hide.length) {
85
+ await page.evaluate((patterns) => {
86
+ const scene = window.__scene;
87
+ for (const pattern of patterns)
88
+ scene.setVisible?.(pattern, false);
89
+ scene.render();
90
+ }, [...options.hide]);
91
+ }
92
+ await page.waitForTimeout(250);
93
+ const file = path.join(options.outDir, `${view.name}.png`);
94
+ await page.screenshot({ path: file });
95
+ report.written.push(file);
96
+ log(`wrote ${file}`);
97
+ if (options.hide.length) {
98
+ await page.evaluate((patterns) => {
99
+ const scene = window.__scene;
100
+ for (const pattern of patterns)
101
+ scene.setVisible?.(pattern, true);
102
+ }, [...options.hide]);
103
+ }
104
+ }
105
+ }
106
+ finally {
107
+ await browser.close();
108
+ }
109
+ log(`remote requests blocked: ${report.blocked.length}`);
110
+ for (const url of report.blocked.slice(0, 10))
111
+ log(` blocked ${url}`);
112
+ log(`fonts: ${report.fonts.loaded} loaded, ${report.fonts.failed.length} failed${report.fonts.failed.length ? `: ${[...new Set(report.fonts.failed)].join(', ')}` : ''}`);
113
+ const consoleLines = report.console.filter((line) => !isCaptureNoise(line)).slice(0, 30);
114
+ for (const line of consoleLines)
115
+ log(line);
116
+ return report;
117
+ };
118
+ //# sourceMappingURL=capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/scene/capture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Where does the render differ most from the source, and what colour should a
3
+ * region be? A port of `sample_colors.py`. Boxes are x0,y0,x1,y1 in SOURCE
4
+ * pixels, clamped to the image; the render is resized to the source size first.
5
+ */
6
+ export type Box = [number, number, number, number];
7
+ export type NamedRegion = {
8
+ name: string;
9
+ box: Box;
10
+ };
11
+ /** The source colour of one box: the hex to put in a material. */
12
+ export declare const sampleSourceBox: (sourceFile: string, box: Box) => Promise<string>;
13
+ /**
14
+ * Compares a render with its source. With regions: source hex, render hex and
15
+ * brightness ratio per region (ratio < 1: the render is darker). Without: the
16
+ * eight worst cells of a 12x8 grid by mean colour difference, the next thing to
17
+ * fix. Excluded boxes (DOM text, labels) are masked out of every comparison.
18
+ */
19
+ export declare const compareWithSource: (args: {
20
+ sourceFile: string;
21
+ renderFile: string;
22
+ exclude: readonly Box[];
23
+ regions: readonly NamedRegion[];
24
+ }) => Promise<string[]>;
25
+ //# sourceMappingURL=image-colors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-colors.d.ts","sourceRoot":"","sources":["../../src/scene/image-colors.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AACnD,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,GAAG,CAAA;CAAE,CAAC;AA8BrD,kEAAkE;AAClE,eAAO,MAAM,eAAe,GAAU,YAAY,MAAM,EAAE,KAAK,GAAG,KAAG,OAAO,CAAC,MAAM,CAKlF,CAAC;AAWF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAU,MAAM;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,SAAS,GAAG,EAAE,CAAC;IACxB,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;CACjC,KAAG,OAAO,CAAC,MAAM,EAAE,CAyDnB,CAAC"}