@hraness/slopcamera 3.2.4

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 (441) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +60 -0
  3. package/PRIVACY.md +46 -0
  4. package/README.md +311 -0
  5. package/SECURITY.md +21 -0
  6. package/apps/desktop/README.md +966 -0
  7. package/apps/desktop/analysis/protocol.ts +223 -0
  8. package/apps/desktop/application/capability-binding.ts +594 -0
  9. package/apps/desktop/application/context.ts +97 -0
  10. package/apps/desktop/application/creative-iteration.ts +1385 -0
  11. package/apps/desktop/application/default-registry.ts +146 -0
  12. package/apps/desktop/application/directing-contract.ts +218 -0
  13. package/apps/desktop/application/directing-plan.ts +178 -0
  14. package/apps/desktop/application/errors.ts +18 -0
  15. package/apps/desktop/application/gateway-port.ts +867 -0
  16. package/apps/desktop/application/html-overlay-browser-runtime.ts +687 -0
  17. package/apps/desktop/application/html-overlay-integrity.ts +337 -0
  18. package/apps/desktop/application/html-overlay-renderer.ts +45 -0
  19. package/apps/desktop/application/index.ts +13 -0
  20. package/apps/desktop/application/operation-completion-checkpoint.ts +333 -0
  21. package/apps/desktop/application/operation-effects.ts +94 -0
  22. package/apps/desktop/application/operation.ts +224 -0
  23. package/apps/desktop/application/operations/analysis/faces.ts +244 -0
  24. package/apps/desktop/application/operations/analysis/music.ts +248 -0
  25. package/apps/desktop/application/operations/analysis/project-auto-zooms.ts +302 -0
  26. package/apps/desktop/application/operations/analysis/project-inactivity.ts +381 -0
  27. package/apps/desktop/application/operations/analysis/scenes.ts +272 -0
  28. package/apps/desktop/application/operations/analysis/shared.ts +202 -0
  29. package/apps/desktop/application/operations/derive/edit-batch.ts +967 -0
  30. package/apps/desktop/application/operations/derive/follow-faces.ts +454 -0
  31. package/apps/desktop/application/operations/edit/bind-candidate-revision.ts +91 -0
  32. package/apps/desktop/application/operations/edit/create-candidate-revision.ts +377 -0
  33. package/apps/desktop/application/operations/edit/create-revision.ts +255 -0
  34. package/apps/desktop/application/operations/edit/freeze-revision.ts +182 -0
  35. package/apps/desktop/application/operations/gateway/image.ts +41 -0
  36. package/apps/desktop/application/operations/gateway/index.ts +17 -0
  37. package/apps/desktop/application/operations/gateway/shared.ts +122 -0
  38. package/apps/desktop/application/operations/gateway/speech.ts +41 -0
  39. package/apps/desktop/application/operations/gateway/transcription.ts +42 -0
  40. package/apps/desktop/application/operations/gateway/video.ts +41 -0
  41. package/apps/desktop/application/operations/index.ts +31 -0
  42. package/apps/desktop/application/operations/iteration/create-candidate.ts +240 -0
  43. package/apps/desktop/application/operations/iteration/create-matrix.ts +117 -0
  44. package/apps/desktop/application/operations/iteration/select.ts +155 -0
  45. package/apps/desktop/application/operations/iteration/shared.ts +250 -0
  46. package/apps/desktop/application/operations/media/audio-effects.ts +376 -0
  47. package/apps/desktop/application/operations/media/binding.ts +79 -0
  48. package/apps/desktop/application/operations/media/capabilities.ts +112 -0
  49. package/apps/desktop/application/operations/media/color-grade.ts +343 -0
  50. package/apps/desktop/application/operations/media/html-overlay.ts +802 -0
  51. package/apps/desktop/application/operations/media/index.ts +8 -0
  52. package/apps/desktop/application/operations/media/ingest.ts +303 -0
  53. package/apps/desktop/application/operations/media/overlay.ts +729 -0
  54. package/apps/desktop/application/operations/media/shared.ts +845 -0
  55. package/apps/desktop/application/operations/media/transform-platform.ts +120 -0
  56. package/apps/desktop/application/operations/project/commit-edits.ts +2054 -0
  57. package/apps/desktop/application/operations/project/promote-selection.ts +495 -0
  58. package/apps/desktop/application/operations/project/snapshot.ts +95 -0
  59. package/apps/desktop/application/operations/recording/index.ts +5 -0
  60. package/apps/desktop/application/operations/recording/pause.ts +34 -0
  61. package/apps/desktop/application/operations/recording/resume.ts +34 -0
  62. package/apps/desktop/application/operations/recording/shared.ts +199 -0
  63. package/apps/desktop/application/operations/recording/start.ts +169 -0
  64. package/apps/desktop/application/operations/recording/stop.ts +34 -0
  65. package/apps/desktop/application/operations/render/bind-candidate-output.ts +324 -0
  66. package/apps/desktop/application/operations/render/materialize-selection.ts +322 -0
  67. package/apps/desktop/application/operations/render/project-caption-plan.ts +287 -0
  68. package/apps/desktop/application/operations/render/project-plan.ts +939 -0
  69. package/apps/desktop/application/operations/render/project-spatial-receipt.ts +70 -0
  70. package/apps/desktop/application/operations/render/project.ts +1922 -0
  71. package/apps/desktop/application/operations/shared.ts +67 -0
  72. package/apps/desktop/application/operations/slopcamera-portable.ts +1188 -0
  73. package/apps/desktop/application/operations/slopcamera-visuals.ts +784 -0
  74. package/apps/desktop/application/operations/spatial-project.ts +209 -0
  75. package/apps/desktop/application/operations/spatial-render.ts +415 -0
  76. package/apps/desktop/application/operations/spatial-scene.ts +97 -0
  77. package/apps/desktop/application/operations/studio.ts +143 -0
  78. package/apps/desktop/application/output-publication-lease.ts +163 -0
  79. package/apps/desktop/application/project-publication-lease.ts +233 -0
  80. package/apps/desktop/application/project-store.ts +196 -0
  81. package/apps/desktop/application/receipts.ts +533 -0
  82. package/apps/desktop/application/registry.ts +182 -0
  83. package/apps/desktop/application/spatial-assets.ts +675 -0
  84. package/apps/desktop/application/spatial-compositor-cadence.ts +23 -0
  85. package/apps/desktop/application/spatial-project-authority.ts +35 -0
  86. package/apps/desktop/application/spatial-project-lease.ts +126 -0
  87. package/apps/desktop/application/spatial-project-render-preparation.ts +225 -0
  88. package/apps/desktop/application/spatial-project-store.ts +286 -0
  89. package/apps/desktop/application/spatial-render-projection.ts +201 -0
  90. package/apps/desktop/application/spatial-render.ts +677 -0
  91. package/apps/desktop/application/spatial-spz.ts +44 -0
  92. package/apps/desktop/application/spatial-world-import.ts +135 -0
  93. package/apps/desktop/application/spatial-world-provenance.ts +46 -0
  94. package/apps/desktop/application/studio-port.ts +58 -0
  95. package/apps/desktop/application/verified-receipt-reconciliation.ts +1574 -0
  96. package/apps/desktop/capture/protocol.ts +689 -0
  97. package/apps/desktop/cli/analyzer.ts +406 -0
  98. package/apps/desktop/cli/args.ts +3181 -0
  99. package/apps/desktop/cli/asset-ingest.ts +747 -0
  100. package/apps/desktop/cli/atomic-render-effects.ts +210 -0
  101. package/apps/desktop/cli/atomic-render-platform.ts +205 -0
  102. package/apps/desktop/cli/atomic-render.ts +50 -0
  103. package/apps/desktop/cli/audio-analysis.ts +252 -0
  104. package/apps/desktop/cli/bounded-map.ts +39 -0
  105. package/apps/desktop/cli/bundle-service.ts +256 -0
  106. package/apps/desktop/cli/capabilities.ts +212 -0
  107. package/apps/desktop/cli/capture-bundle.ts +1117 -0
  108. package/apps/desktop/cli/command-host-resources.ts +251 -0
  109. package/apps/desktop/cli/commands.ts +6836 -0
  110. package/apps/desktop/cli/directing-blob.ts +291 -0
  111. package/apps/desktop/cli/directing-media.ts +517 -0
  112. package/apps/desktop/cli/directing-quote.ts +89 -0
  113. package/apps/desktop/cli/directing-service.ts +288 -0
  114. package/apps/desktop/cli/emoji-assets.ts +538 -0
  115. package/apps/desktop/cli/errors.ts +29 -0
  116. package/apps/desktop/cli/face-analysis-service.ts +940 -0
  117. package/apps/desktop/cli/filter-script.ts +76 -0
  118. package/apps/desktop/cli/gateway-application-port.ts +1142 -0
  119. package/apps/desktop/cli/gateway-credential.ts +81 -0
  120. package/apps/desktop/cli/gateway-media-artifacts.ts +723 -0
  121. package/apps/desktop/cli/gateway-media-catalog.ts +922 -0
  122. package/apps/desktop/cli/gateway-media-service.ts +3106 -0
  123. package/apps/desktop/cli/gateway-media-signature.ts +122 -0
  124. package/apps/desktop/cli/gateway-provider-options.ts +562 -0
  125. package/apps/desktop/cli/gateway-scene-provider.ts +391 -0
  126. package/apps/desktop/cli/help.ts +501 -0
  127. package/apps/desktop/cli/html-overlay-gpu.ts +97 -0
  128. package/apps/desktop/cli/html-overlay-renderer.ts +2478 -0
  129. package/apps/desktop/cli/io.ts +290 -0
  130. package/apps/desktop/cli/main.ts +123 -0
  131. package/apps/desktop/cli/media-effects-service.ts +885 -0
  132. package/apps/desktop/cli/media-ingest-model.ts +364 -0
  133. package/apps/desktop/cli/media-ingest-platform.ts +227 -0
  134. package/apps/desktop/cli/media-ingest-program.ts +200 -0
  135. package/apps/desktop/cli/media-ingest.ts +30 -0
  136. package/apps/desktop/cli/music-analysis-service.ts +434 -0
  137. package/apps/desktop/cli/mutation-lock.ts +530 -0
  138. package/apps/desktop/cli/native-assets.d.ts +12 -0
  139. package/apps/desktop/cli/native-media-runtime.macos.ts +7 -0
  140. package/apps/desktop/cli/overlay-playback.ts +177 -0
  141. package/apps/desktop/cli/paths.ts +265 -0
  142. package/apps/desktop/cli/portable-surface.ts +242 -0
  143. package/apps/desktop/cli/project-camera-receipt.ts +112 -0
  144. package/apps/desktop/cli/project-face-camera.ts +394 -0
  145. package/apps/desktop/cli/project-inactivity-service.ts +552 -0
  146. package/apps/desktop/cli/project-media-integrity.ts +121 -0
  147. package/apps/desktop/cli/project-renderer.ts +1526 -0
  148. package/apps/desktop/cli/project-service.ts +519 -0
  149. package/apps/desktop/cli/project-state-transaction.ts +520 -0
  150. package/apps/desktop/cli/query-limits.ts +1 -0
  151. package/apps/desktop/cli/recording-controller.ts +1567 -0
  152. package/apps/desktop/cli/recording-daemon.ts +931 -0
  153. package/apps/desktop/cli/recording-ref.ts +56 -0
  154. package/apps/desktop/cli/renamed-environment.ts +6 -0
  155. package/apps/desktop/cli/renderer.ts +1439 -0
  156. package/apps/desktop/cli/run-cli-test-helper.ts +60 -0
  157. package/apps/desktop/cli/scene-analysis-service.ts +879 -0
  158. package/apps/desktop/cli/spatial-compositor-verifier.ts +213 -0
  159. package/apps/desktop/cli/spatial-project-service.ts +90 -0
  160. package/apps/desktop/cli/spatial-scene-service.ts +105 -0
  161. package/apps/desktop/cli/spatial-world-service.ts +39 -0
  162. package/apps/desktop/cli/speech-analysis-service.ts +682 -0
  163. package/apps/desktop/cli/studio-assemble.ts +58 -0
  164. package/apps/desktop/cli/studio-command.ts +60 -0
  165. package/apps/desktop/cli/studio-custody.ts +60 -0
  166. package/apps/desktop/cli/studio-encode.ts +216 -0
  167. package/apps/desktop/cli/studio-exr.ts +52 -0
  168. package/apps/desktop/cli/studio-files.ts +179 -0
  169. package/apps/desktop/cli/studio-output-validation.ts +162 -0
  170. package/apps/desktop/cli/studio-process.ts +145 -0
  171. package/apps/desktop/cli/studio-runtime.ts +77 -0
  172. package/apps/desktop/cli/studio-scaffold.ts +70 -0
  173. package/apps/desktop/cli/studio-service.ts +301 -0
  174. package/apps/desktop/cli/studio-spatial-asset.ts +248 -0
  175. package/apps/desktop/cli/studio-template-names.ts +3 -0
  176. package/apps/desktop/cli/studio-workflow.ts +19 -0
  177. package/apps/desktop/cli/time.ts +25 -0
  178. package/apps/desktop/cli/workflow-code.ts +584 -0
  179. package/apps/desktop/cli/workflow-runs.ts +576 -0
  180. package/apps/desktop/code/advanced.ts +139 -0
  181. package/apps/desktop/code/application-node-planner.ts +1288 -0
  182. package/apps/desktop/code/compiler.ts +329 -0
  183. package/apps/desktop/code/contracts.ts +13 -0
  184. package/apps/desktop/code/creative-recipes.ts +94 -0
  185. package/apps/desktop/code/define-workflow.ts +115 -0
  186. package/apps/desktop/code/editing.ts +284 -0
  187. package/apps/desktop/code/file-candidate-provenance.ts +420 -0
  188. package/apps/desktop/code/file-candidate.ts +69 -0
  189. package/apps/desktop/code/graph-builder.ts +10 -0
  190. package/apps/desktop/code/host-resource-policy.ts +55 -0
  191. package/apps/desktop/code/plan-contracts.ts +159 -0
  192. package/apps/desktop/code/planning.ts +361 -0
  193. package/apps/desktop/code/public.ts +134 -0
  194. package/apps/desktop/code/reference-projection.ts +62 -0
  195. package/apps/desktop/code/run-contracts.ts +466 -0
  196. package/apps/desktop/code/run-store.ts +2478 -0
  197. package/apps/desktop/code/runtime-identity.ts +328 -0
  198. package/apps/desktop/code/scheduler.ts +3067 -0
  199. package/apps/desktop/code/semantic-builder.ts +1436 -0
  200. package/apps/desktop/code/source-bundle.ts +1641 -0
  201. package/apps/desktop/code/source-typecheck.ts +211 -0
  202. package/apps/desktop/code/testing.ts +79 -0
  203. package/apps/desktop/code/worker-client.ts +1675 -0
  204. package/apps/desktop/code/worker-effects.ts +141 -0
  205. package/apps/desktop/code/worker-entry.ts +435 -0
  206. package/apps/desktop/code/worker-lease-guardian.ts +179 -0
  207. package/apps/desktop/code/worker-process-identity.ts +484 -0
  208. package/apps/desktop/code/worker-protocol.ts +211 -0
  209. package/apps/desktop/code/workflow-effects.ts +132 -0
  210. package/apps/desktop/contracts/analysis.ts +949 -0
  211. package/apps/desktop/contracts/edit.ts +576 -0
  212. package/apps/desktop/contracts/index.ts +9 -0
  213. package/apps/desktop/contracts/media-effects.ts +139 -0
  214. package/apps/desktop/contracts/project-render.ts +644 -0
  215. package/apps/desktop/contracts/project.ts +740 -0
  216. package/apps/desktop/contracts/recording.ts +1434 -0
  217. package/apps/desktop/contracts/render.ts +334 -0
  218. package/apps/desktop/contracts/runtime.ts +155 -0
  219. package/apps/desktop/contracts/spatial-compositor.ts +58 -0
  220. package/apps/desktop/contracts/spatial-project.ts +159 -0
  221. package/apps/desktop/contracts/spatial-world.ts +48 -0
  222. package/apps/desktop/contracts/video-effects.ts +120 -0
  223. package/apps/desktop/core/alignment-apply.ts +400 -0
  224. package/apps/desktop/core/audio-alignment.ts +466 -0
  225. package/apps/desktop/core/auto-zoom.ts +209 -0
  226. package/apps/desktop/core/canonical-json.ts +14 -0
  227. package/apps/desktop/core/emoji.ts +210 -0
  228. package/apps/desktop/core/events.ts +409 -0
  229. package/apps/desktop/core/face-framing.ts +533 -0
  230. package/apps/desktop/core/face-tracks.ts +326 -0
  231. package/apps/desktop/core/inactivity.ts +137 -0
  232. package/apps/desktop/core/index.ts +30 -0
  233. package/apps/desktop/core/intervals.ts +123 -0
  234. package/apps/desktop/core/montage.ts +236 -0
  235. package/apps/desktop/core/music-analysis.ts +518 -0
  236. package/apps/desktop/core/plan.ts +244 -0
  237. package/apps/desktop/core/project-auto-zoom.ts +75 -0
  238. package/apps/desktop/core/project-camera-spatial.ts +676 -0
  239. package/apps/desktop/core/project-camera.ts +403 -0
  240. package/apps/desktop/core/project-captions.ts +888 -0
  241. package/apps/desktop/core/project-inactivity.ts +125 -0
  242. package/apps/desktop/core/project-metadata.ts +927 -0
  243. package/apps/desktop/core/project-plan.ts +375 -0
  244. package/apps/desktop/core/project-render-plan.ts +303 -0
  245. package/apps/desktop/core/project-time.ts +469 -0
  246. package/apps/desktop/core/render-plan.ts +442 -0
  247. package/apps/desktop/core/scene-cache.ts +174 -0
  248. package/apps/desktop/core/scene-sampling.ts +448 -0
  249. package/apps/desktop/core/spatial-compositor.ts +22 -0
  250. package/apps/desktop/core/spatial-durability.ts +99 -0
  251. package/apps/desktop/core/spatial-project.ts +169 -0
  252. package/apps/desktop/core/spatial-shot-clock.ts +32 -0
  253. package/apps/desktop/core/speech-analysis.ts +333 -0
  254. package/apps/desktop/core/storage.ts +970 -0
  255. package/apps/desktop/core/time-map.ts +91 -0
  256. package/apps/desktop/core/time.ts +61 -0
  257. package/apps/desktop/core/video-effects.ts +660 -0
  258. package/apps/desktop/dist/cli/NebulaSans-Bold-26se8aek.otf +0 -0
  259. package/apps/desktop/dist/cli/NebulaSans-Bold-bcz7y08t.woff2 +0 -0
  260. package/apps/desktop/dist/cli/NebulaSans-Book-5ax05zvn.woff2 +0 -0
  261. package/apps/desktop/dist/cli/NebulaSans-Book-8cenzchw.otf +0 -0
  262. package/apps/desktop/dist/cli/main.js +5086 -0
  263. package/apps/desktop/html-overlay/catalog.ts +171 -0
  264. package/apps/desktop/html-overlay/contracts.ts +372 -0
  265. package/apps/desktop/html-overlay/execution-profile.ts +77 -0
  266. package/apps/desktop/html-overlay/index.ts +98 -0
  267. package/apps/desktop/html-overlay/libraries.ts +263 -0
  268. package/apps/desktop/html-overlay/random.ts +49 -0
  269. package/apps/desktop/html-overlay/runtime.ts +813 -0
  270. package/apps/desktop/html-overlay/scaffolds.ts +792 -0
  271. package/apps/desktop/html-overlay/spark-runtime.ts +88 -0
  272. package/apps/desktop/html-overlay/spatial-splat-runtime.ts +60 -0
  273. package/apps/desktop/html-overlay/spatial.ts +720 -0
  274. package/apps/desktop/studio/assets/README.md +39 -0
  275. package/apps/desktop/studio/assets/contracts.ts +129 -0
  276. package/apps/desktop/studio/assets/network.ts +64 -0
  277. package/apps/desktop/studio/assets/poly-haven.ts +148 -0
  278. package/apps/desktop/studio/drivers/blender_driver.py +466 -0
  279. package/apps/desktop/studio/drivers/cadquery_driver.py +176 -0
  280. package/apps/desktop/studio/education/driver.py +308 -0
  281. package/apps/desktop/studio/education/lesson.py +180 -0
  282. package/apps/desktop/studio/education/toolkit.py +249 -0
  283. package/apps/desktop/workflows/chaptered-demo.ts +48 -0
  284. package/apps/desktop/workflows/creative-iteration.ts +107 -0
  285. package/apps/desktop/workflows/creative-selection.ts +92 -0
  286. package/apps/desktop/workflows/fragments.ts +486 -0
  287. package/apps/desktop/workflows/index.ts +93 -0
  288. package/apps/desktop/workflows/polished-screen-demo.ts +128 -0
  289. package/apps/desktop/workflows/scene-direction.ts +12 -0
  290. package/apps/desktop/workflows/social-variants.ts +75 -0
  291. package/apps/desktop/workflows/talking-head-cleanup.ts +53 -0
  292. package/dist/NebulaSans-Bold-26se8aek.otf +0 -0
  293. package/dist/NebulaSans-Bold-bcz7y08t.woff2 +0 -0
  294. package/dist/NebulaSans-Book-5ax05zvn.woff2 +0 -0
  295. package/dist/NebulaSans-Book-8cenzchw.otf +0 -0
  296. package/dist/cli.js +479 -0
  297. package/dist/code/advanced.js +270 -0
  298. package/dist/code/index.js +2240 -0
  299. package/dist/generate.js +24 -0
  300. package/dist/host-resources.js +26 -0
  301. package/dist/index-42zsesc1.js +2257 -0
  302. package/dist/index-7308egqr.js +48 -0
  303. package/dist/index-8txs6fkn.js +712 -0
  304. package/dist/index-mcy8z0br.js +192 -0
  305. package/dist/index-p63wavx0.js +2029 -0
  306. package/dist/index-r7gdhmsp.js +424 -0
  307. package/dist/index-sh6xbav6.js +1219 -0
  308. package/dist/index-z1w83f81.js +4 -0
  309. package/dist/index-z7239b4h.js +2363 -0
  310. package/dist/index-zfeg9hmw.js +2013 -0
  311. package/dist/index.js +241 -0
  312. package/dist/operations.js +29 -0
  313. package/dist/skill-install-dh0ntqba.js +10 -0
  314. package/dist/vectorize/worker.js +142 -0
  315. package/dist/workflow.js +16 -0
  316. package/docs/README.md +38 -0
  317. package/docs/studio.md +215 -0
  318. package/examples/studio/blender/README.md +26 -0
  319. package/examples/studio/blender/character.py +152 -0
  320. package/examples/studio/blender/cloth.py +101 -0
  321. package/examples/studio/blender/color_chart.py +29 -0
  322. package/examples/studio/blender/fluid.py +78 -0
  323. package/examples/studio/blender/import_model.py +74 -0
  324. package/examples/studio/blender/product.py +53 -0
  325. package/examples/studio/blender/shaded_street.py +481 -0
  326. package/examples/studio/blender/studio_scene.py +147 -0
  327. package/examples/studio/cadquery/README.md +13 -0
  328. package/examples/studio/cadquery/bracket.py +36 -0
  329. package/examples/studio/cadquery/import_step.py +12 -0
  330. package/examples/studio/education/README.md +46 -0
  331. package/examples/studio/education/lesson.json +99 -0
  332. package/examples/studio/education/scene.py +7 -0
  333. package/examples/studio/hybrid-scene.ts +96 -0
  334. package/examples/studio/native-workflow.ts +14 -0
  335. package/examples/studio/vgpu/README.md +64 -0
  336. package/examples/studio/vgpu/heat-field.mjs +290 -0
  337. package/package.json +304 -0
  338. package/packages/scene/src/index.ts +1 -0
  339. package/packages/scene/src/scene.ts +215 -0
  340. package/schema/diagram.schema.json +334 -0
  341. package/skills/slopcamera/SKILL.md +45 -0
  342. package/skills/slopcamera/agents/openai.yaml +4 -0
  343. package/skills/slopcamera/references/customization.md +77 -0
  344. package/skills/slopcamera/references/diagrams.md +153 -0
  345. package/skills/slopcamera/references/directed-scenes.md +42 -0
  346. package/skills/slopcamera/references/directing-video.md +18 -0
  347. package/skills/slopcamera/references/educational-video.md +26 -0
  348. package/skills/slopcamera/references/gateway-media.md +134 -0
  349. package/skills/slopcamera/references/install.md +62 -0
  350. package/skills/slopcamera/references/native-studio.md +31 -0
  351. package/skills/slopcamera/references/reference-led-3d.md +140 -0
  352. package/skills/slopcamera/references/rubber-stamp-examples/poster-example-1.jpg +0 -0
  353. package/skills/slopcamera/references/rubber-stamp-examples/poster-example-2.jpg +0 -0
  354. package/skills/slopcamera/references/rubber-stamp-examples/stamp-style-1.png +0 -0
  355. package/skills/slopcamera/references/rubber-stamp-examples/stamp-style-2.png +0 -0
  356. package/skills/slopcamera/references/rubber-stamp-field-notes.md +144 -0
  357. package/skills/slopcamera/references/vectorization.md +29 -0
  358. package/skills/slopcamera/references/video-projects.md +187 -0
  359. package/skills/slopcamera/references/visual-communication.md +120 -0
  360. package/skills/slopcamera/references/workflows-sdk.md +45 -0
  361. package/skills/slopcamera/scripts/compose-rubber-stamp-field-note.ts +229 -0
  362. package/src/artifacts.ts +106 -0
  363. package/src/assets/fonts/nebula-sans/LICENSE.txt +96 -0
  364. package/src/assets/fonts/nebula-sans/NebulaSans-Bold.otf +0 -0
  365. package/src/assets/fonts/nebula-sans/NebulaSans-Bold.woff2 +0 -0
  366. package/src/assets/fonts/nebula-sans/NebulaSans-Book.otf +0 -0
  367. package/src/assets/fonts/nebula-sans/NebulaSans-Book.woff2 +0 -0
  368. package/src/assets/fonts/nebula-sans/PROVENANCE.md +21 -0
  369. package/src/assets.d.ts +9 -0
  370. package/src/cli.ts +601 -0
  371. package/src/cloud-errors.ts +26 -0
  372. package/src/code/advanced.ts +10 -0
  373. package/src/code/boundary.ts +21 -0
  374. package/src/code/canonical-json.ts +129 -0
  375. package/src/code/compiler.ts +953 -0
  376. package/src/code/contracts.ts +576 -0
  377. package/src/code/define-workflow.ts +334 -0
  378. package/src/code/errors.ts +41 -0
  379. package/src/code/graph-builder.ts +945 -0
  380. package/src/code/index.ts +121 -0
  381. package/src/code/json-snapshot.ts +899 -0
  382. package/src/code/json-utf8.ts +88 -0
  383. package/src/code/portable-builder.ts +136 -0
  384. package/src/code/projection.ts +378 -0
  385. package/src/code/public-operations.ts +450 -0
  386. package/src/code/runtime.ts +580 -0
  387. package/src/code/sha256.ts +36 -0
  388. package/src/config.ts +180 -0
  389. package/src/desktop.ts +253 -0
  390. package/src/fs.ts +10 -0
  391. package/src/generate.ts +704 -0
  392. package/src/host-resource-posix.ts +161 -0
  393. package/src/host-resources.ts +1749 -0
  394. package/src/icons.ts +58 -0
  395. package/src/index.ts +200 -0
  396. package/src/label-layout.ts +130 -0
  397. package/src/layout.ts +413 -0
  398. package/src/lint.ts +127 -0
  399. package/src/mcp/boundary.ts +354 -0
  400. package/src/mcp/index.ts +33 -0
  401. package/src/mcp/server.ts +272 -0
  402. package/src/mcp/tools.ts +963 -0
  403. package/src/mcp/types.ts +71 -0
  404. package/src/operations.ts +775 -0
  405. package/src/parse.ts +861 -0
  406. package/src/process-environment.ts +17 -0
  407. package/src/render.ts +437 -0
  408. package/src/skill-install.ts +49 -0
  409. package/src/spatial-scene/authoring.ts +27 -0
  410. package/src/spatial-scene/camera-track.ts +83 -0
  411. package/src/spatial-scene/contracts.ts +277 -0
  412. package/src/spatial-scene/evaluate.ts +145 -0
  413. package/src/spatial-scene/gltf.ts +558 -0
  414. package/src/spatial-scene/identity.ts +260 -0
  415. package/src/spatial-scene/index.ts +10 -0
  416. package/src/spatial-scene/inspect.ts +68 -0
  417. package/src/spatial-scene/math.ts +280 -0
  418. package/src/spatial-scene/patch.ts +131 -0
  419. package/src/spatial-scene/time.ts +53 -0
  420. package/src/studio/contracts.ts +129 -0
  421. package/src/studio/index.ts +2 -0
  422. package/src/studio/plan.ts +156 -0
  423. package/src/studio/shared.ts +41 -0
  424. package/src/theme.ts +68 -0
  425. package/src/tldr.ts +474 -0
  426. package/src/types.ts +212 -0
  427. package/src/vectorize/archive.ts +101 -0
  428. package/src/vectorize/command.ts +797 -0
  429. package/src/vectorize/index.ts +27 -0
  430. package/src/vectorize/limits.ts +61 -0
  431. package/src/vectorize/metrics.ts +351 -0
  432. package/src/vectorize/pixels.ts +323 -0
  433. package/src/vectorize/supervisor.ts +339 -0
  434. package/src/vectorize/svg.ts +188 -0
  435. package/src/vectorize/tool.ts +542 -0
  436. package/src/vectorize/types.ts +113 -0
  437. package/src/vectorize/vectorize.ts +634 -0
  438. package/src/vectorize/worker-protocol.ts +40 -0
  439. package/src/vectorize/worker.ts +209 -0
  440. package/src/version.ts +1 -0
  441. package/src/workflow.ts +409 -0
@@ -0,0 +1,813 @@
1
+ import { z } from "zod";
2
+
3
+ import { canonicalJson } from "../core/canonical-json";
4
+ import {
5
+ HtmlOverlayCanvasSchema,
6
+ HtmlOverlayDeclaredResourcesSchema,
7
+ HtmlOverlayParametersSchema,
8
+ HtmlOverlayTimingSchema,
9
+ htmlOverlayFrameCount,
10
+ } from "./contracts";
11
+ import { htmlOverlayAssetLocalUrl } from "./libraries";
12
+ import { HTML_OVERLAY_RANDOM_ALGORITHM } from "./random";
13
+
14
+ const Uint32Schema = z.number().int().safe().min(0).max(0xffff_ffff);
15
+
16
+ export const HtmlOverlayBrowserRuntimeConfigSchema = z.strictObject({
17
+ canvas: HtmlOverlayCanvasSchema,
18
+ parameters: HtmlOverlayParametersSchema,
19
+ resources: HtmlOverlayDeclaredResourcesSchema,
20
+ seed: Uint32Schema,
21
+ timing: HtmlOverlayTimingSchema,
22
+ });
23
+ export type HtmlOverlayBrowserRuntimeConfig = Readonly<
24
+ z.infer<typeof HtmlOverlayBrowserRuntimeConfigSchema>
25
+ >;
26
+
27
+ function scriptLiteral(value: unknown): string {
28
+ return canonicalJson(value)
29
+ .replaceAll("<", "\\u003c")
30
+ .replaceAll(">", "\\u003e")
31
+ .replaceAll("&", "\\u0026")
32
+ .replaceAll("\u2028", "\\u2028")
33
+ .replaceAll("\u2029", "\\u2029");
34
+ }
35
+
36
+ /**
37
+ * Produces a complete JavaScript expression. Evaluating it installs the frozen
38
+ * page-facing `globalThis.SlopcameraOverlay` API and returns a host controller with
39
+ * `renderFrame(frame)`. The controller is not stored on the page global.
40
+ */
41
+ export function createHtmlOverlayBrowserRuntimeSource(
42
+ input: HtmlOverlayBrowserRuntimeConfig,
43
+ ): string {
44
+ const config = HtmlOverlayBrowserRuntimeConfigSchema.parse(input);
45
+ const assets = Object.fromEntries(
46
+ config.resources.map(resource => [resource.name, htmlOverlayAssetLocalUrl(resource)]),
47
+ );
48
+ const embedded = scriptLiteral({
49
+ assets,
50
+ durationMs: config.timing.durationUs / 1_000,
51
+ epochMs: Date.UTC(2000, 0, 1),
52
+ fps: config.timing.fps,
53
+ frameCount: htmlOverlayFrameCount(config.timing),
54
+ height: config.canvas.height,
55
+ parameters: config.parameters,
56
+ randomAlgorithm: HTML_OVERLAY_RANDOM_ALGORITHM,
57
+ seed: config.seed,
58
+ width: config.canvas.width,
59
+ });
60
+
61
+ return `(() => {
62
+ "use strict";
63
+ const config = ${embedded};
64
+ const callbacks = [];
65
+ const readiness = [];
66
+ const animationFrames = new Map();
67
+ const timers = new Map();
68
+ const trackedAnimations = new Set();
69
+ let currentTimeMs = 0;
70
+ let nextScheduledId = 1;
71
+ let pendingReadiness = 0;
72
+ let readinessSettled = false;
73
+ let registrationOpen = true;
74
+ let securityViolations = 0;
75
+
76
+ if (typeof globalThis.addEventListener === "function") {
77
+ globalThis.addEventListener("securitypolicyviolation", () => {
78
+ securityViolations += 1;
79
+ });
80
+ }
81
+
82
+ const deepFreeze = (value) => {
83
+ if (value === null || typeof value !== "object" || Object.isFrozen(value)) return value;
84
+ for (const key of Object.keys(value)) deepFreeze(value[key]);
85
+ return Object.freeze(value);
86
+ };
87
+
88
+ const replaceRuntimeValue = (
89
+ target,
90
+ name,
91
+ value,
92
+ enumerable = false,
93
+ ) => {
94
+ const descriptor = {
95
+ configurable: false,
96
+ enumerable,
97
+ value,
98
+ writable: false,
99
+ };
100
+ let prototype = Object.getPrototypeOf(target);
101
+ while (
102
+ prototype !== null
103
+ && prototype !== Object.prototype
104
+ && prototype !== Function.prototype
105
+ ) {
106
+ if (Object.prototype.hasOwnProperty.call(prototype, name)) {
107
+ Object.defineProperty(prototype, name, descriptor);
108
+ }
109
+ prototype = Object.getPrototypeOf(prototype);
110
+ }
111
+ Object.defineProperty(target, name, descriptor);
112
+ };
113
+
114
+ const replaceRuntimeGetter = (target, name, get) => {
115
+ const descriptor = {
116
+ configurable: false,
117
+ enumerable: false,
118
+ get,
119
+ };
120
+ let prototype = Object.getPrototypeOf(target);
121
+ while (
122
+ prototype !== null
123
+ && prototype !== Object.prototype
124
+ && prototype !== Function.prototype
125
+ ) {
126
+ if (Object.prototype.hasOwnProperty.call(prototype, name)) {
127
+ Object.defineProperty(prototype, name, descriptor);
128
+ }
129
+ prototype = Object.getPrototypeOf(prototype);
130
+ }
131
+ Object.defineProperty(target, name, descriptor);
132
+ };
133
+
134
+ const hashDomain = (value) => {
135
+ let hash = 0x811c9dc5;
136
+ for (let index = 0; index < value.length; index += 1) {
137
+ hash ^= value.charCodeAt(index);
138
+ hash = Math.imul(hash, 0x01000193);
139
+ }
140
+ return hash >>> 0;
141
+ };
142
+
143
+ const nextMulberry32 = (state) => {
144
+ const nextState = (state + 0x6d2b79f5) >>> 0;
145
+ let value = nextState;
146
+ value = Math.imul(value ^ (value >>> 15), value | 1);
147
+ value ^= value + Math.imul(value ^ (value >>> 7), value | 61);
148
+ return [nextState, ((value ^ (value >>> 14)) >>> 0) / 4294967296];
149
+ };
150
+
151
+ const randomSeed = (namespace) =>
152
+ hashDomain(config.randomAlgorithm + "\\0" + (config.seed >>> 0) + "\\0" + namespace);
153
+ let sequenceState = randomSeed("sequence");
154
+ const random = () => {
155
+ const result = nextMulberry32(sequenceState);
156
+ sequenceState = result[0];
157
+ return result[1];
158
+ };
159
+ const randomFor = (key) => {
160
+ if (typeof key !== "string" || key.length === 0 || key.length > 256) {
161
+ throw new TypeError("SlopcameraOverlay.randomFor requires a nonempty string key of at most 256 characters.");
162
+ }
163
+ return nextMulberry32(randomSeed("key\\0" + key))[1];
164
+ };
165
+
166
+ const deterministicRandomValues = (array) => {
167
+ const supported = new Set([
168
+ "[object BigInt64Array]",
169
+ "[object BigUint64Array]",
170
+ "[object Int8Array]",
171
+ "[object Int16Array]",
172
+ "[object Int32Array]",
173
+ "[object Uint8Array]",
174
+ "[object Uint8ClampedArray]",
175
+ "[object Uint16Array]",
176
+ "[object Uint32Array]",
177
+ ]);
178
+ if (
179
+ array === null
180
+ || typeof array !== "object"
181
+ || !ArrayBuffer.isView(array)
182
+ || !supported.has(Object.prototype.toString.call(array))
183
+ ) {
184
+ throw new TypeError("crypto.getRandomValues requires an integer TypedArray.");
185
+ }
186
+ if (array.byteLength > 65536) {
187
+ throw new DOMException(
188
+ "crypto.getRandomValues is limited to 65536 bytes.",
189
+ "QuotaExceededError",
190
+ );
191
+ }
192
+ const bytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
193
+ for (let index = 0; index < bytes.length; index += 1) {
194
+ bytes[index] = Math.floor(random() * 256);
195
+ }
196
+ return array;
197
+ };
198
+
199
+ const deterministicRandomUuid = () => {
200
+ const bytes = deterministicRandomValues(new Uint8Array(16));
201
+ bytes[6] = (bytes[6] & 0x0f) | 0x40;
202
+ bytes[8] = (bytes[8] & 0x3f) | 0x80;
203
+ const hex = [...bytes].map(value => value.toString(16).padStart(2, "0"));
204
+ return (
205
+ hex.slice(0, 4).join("")
206
+ + "-" + hex.slice(4, 6).join("")
207
+ + "-" + hex.slice(6, 8).join("")
208
+ + "-" + hex.slice(8, 10).join("")
209
+ + "-" + hex.slice(10).join("")
210
+ );
211
+ };
212
+
213
+ replaceRuntimeValue(Math, "random", random);
214
+ if (globalThis.crypto !== undefined) {
215
+ replaceRuntimeValue(
216
+ globalThis.crypto,
217
+ "getRandomValues",
218
+ deterministicRandomValues,
219
+ );
220
+ if (typeof globalThis.crypto.randomUUID === "function") {
221
+ replaceRuntimeValue(
222
+ globalThis.crypto,
223
+ "randomUUID",
224
+ deterministicRandomUuid,
225
+ );
226
+ }
227
+ if (globalThis.crypto.subtle !== undefined) {
228
+ const rejectAmbientEntropy = () => Promise.reject(
229
+ new DOMException(
230
+ "This Web Crypto operation uses ambient entropy and is unavailable in deterministic HTML overlays.",
231
+ "NotSupportedError",
232
+ ),
233
+ );
234
+ for (const method of ["encrypt", "generateKey", "sign", "wrapKey"]) {
235
+ replaceRuntimeValue(
236
+ globalThis.crypto.subtle,
237
+ method,
238
+ rejectAmbientEntropy,
239
+ );
240
+ }
241
+ }
242
+ }
243
+
244
+ const NativeDate = globalThis.Date;
245
+ function SlopcameraDate(...args) {
246
+ if (new.target === undefined) {
247
+ return new NativeDate(config.epochMs + currentTimeMs).toString();
248
+ }
249
+ return Reflect.construct(
250
+ NativeDate,
251
+ args.length === 0
252
+ ? [config.epochMs + currentTimeMs]
253
+ : args,
254
+ new.target,
255
+ );
256
+ }
257
+ SlopcameraDate.prototype = NativeDate.prototype;
258
+ Object.defineProperty(NativeDate.prototype, "constructor", {
259
+ configurable: false,
260
+ enumerable: false,
261
+ value: SlopcameraDate,
262
+ writable: false,
263
+ });
264
+ for (const [name, value] of [
265
+ ["parse", NativeDate.parse.bind(NativeDate)],
266
+ ["UTC", NativeDate.UTC.bind(NativeDate)],
267
+ ]) {
268
+ Object.defineProperty(SlopcameraDate, name, {
269
+ configurable: false,
270
+ enumerable: false,
271
+ value,
272
+ writable: false,
273
+ });
274
+ }
275
+ Object.defineProperty(SlopcameraDate, "now", {
276
+ configurable: false,
277
+ enumerable: false,
278
+ value: () => config.epochMs + currentTimeMs,
279
+ writable: false,
280
+ });
281
+ replaceRuntimeValue(globalThis, "Date", SlopcameraDate);
282
+ if (typeof globalThis.File === "function") {
283
+ const NativeFile = globalThis.File;
284
+ function SlopcameraFile(bits, name, options) {
285
+ const normalizedOptions = (
286
+ options === undefined
287
+ || options === null
288
+ || typeof options !== "object"
289
+ )
290
+ ? { lastModified: config.epochMs + currentTimeMs }
291
+ : (
292
+ Object.prototype.hasOwnProperty.call(options, "lastModified")
293
+ ? options
294
+ : {
295
+ ...options,
296
+ lastModified: config.epochMs + currentTimeMs,
297
+ }
298
+ );
299
+ return Reflect.construct(
300
+ NativeFile,
301
+ [bits, name, normalizedOptions],
302
+ new.target ?? SlopcameraFile,
303
+ );
304
+ }
305
+ SlopcameraFile.prototype = Object.create(NativeFile.prototype, {
306
+ constructor: {
307
+ configurable: false,
308
+ enumerable: false,
309
+ value: SlopcameraFile,
310
+ writable: false,
311
+ },
312
+ });
313
+ Object.defineProperty(NativeFile.prototype, "constructor", {
314
+ configurable: false,
315
+ enumerable: false,
316
+ value: SlopcameraFile,
317
+ writable: false,
318
+ });
319
+ Object.defineProperty(SlopcameraFile, "name", {
320
+ configurable: false,
321
+ value: "File",
322
+ });
323
+ replaceRuntimeValue(globalThis, "File", SlopcameraFile);
324
+ }
325
+ if (globalThis.performance !== undefined) {
326
+ replaceRuntimeValue(
327
+ globalThis.performance,
328
+ "now",
329
+ () => currentTimeMs,
330
+ );
331
+ replaceRuntimeValue(
332
+ globalThis.performance,
333
+ "timeOrigin",
334
+ config.epochMs,
335
+ true,
336
+ );
337
+ const emptyPerformanceEntries = () => Object.freeze([]);
338
+ for (const name of [
339
+ "getEntries",
340
+ "getEntriesByName",
341
+ "getEntriesByType",
342
+ ]) {
343
+ replaceRuntimeValue(
344
+ globalThis.performance,
345
+ name,
346
+ emptyPerformanceEntries,
347
+ );
348
+ }
349
+ const rejectPerformanceTimelineWrite = () => {
350
+ throw new DOMException(
351
+ "The ambient Performance Timeline is unavailable; use the SlopcameraOverlay frame clock.",
352
+ "NotSupportedError",
353
+ );
354
+ };
355
+ for (const name of ["mark", "measure"]) {
356
+ replaceRuntimeValue(
357
+ globalThis.performance,
358
+ name,
359
+ rejectPerformanceTimelineWrite,
360
+ );
361
+ }
362
+ const clearPerformanceEntries = () => undefined;
363
+ for (const name of [
364
+ "clearMarks",
365
+ "clearMeasures",
366
+ "clearResourceTimings",
367
+ "setResourceTimingBufferSize",
368
+ ]) {
369
+ replaceRuntimeValue(
370
+ globalThis.performance,
371
+ name,
372
+ clearPerformanceEntries,
373
+ );
374
+ }
375
+ for (const [name, value] of [
376
+ ["eventCounts", undefined],
377
+ ["memory", Object.freeze({
378
+ jsHeapSizeLimit: 0,
379
+ totalJSHeapSize: 0,
380
+ usedJSHeapSize: 0,
381
+ })],
382
+ ["navigation", Object.freeze({
383
+ redirectCount: 0,
384
+ type: 0,
385
+ })],
386
+ ["timing", Object.freeze({
387
+ loadEventEnd: config.epochMs,
388
+ loadEventStart: config.epochMs,
389
+ navigationStart: config.epochMs,
390
+ })],
391
+ ]) {
392
+ replaceRuntimeValue(globalThis.performance, name, value);
393
+ }
394
+ replaceRuntimeValue(
395
+ globalThis.performance,
396
+ "toJSON",
397
+ () => Object.freeze({ timeOrigin: config.epochMs }),
398
+ );
399
+ }
400
+ if (typeof globalThis.Event === "function") {
401
+ replaceRuntimeGetter(
402
+ globalThis.Event.prototype,
403
+ "timeStamp",
404
+ () => currentTimeMs,
405
+ );
406
+ }
407
+ if (globalThis.document?.timeline !== undefined) {
408
+ replaceRuntimeGetter(
409
+ globalThis.document.timeline,
410
+ "currentTime",
411
+ () => currentTimeMs,
412
+ );
413
+ }
414
+ if (typeof globalThis.Intl?.DateTimeFormat === "function") {
415
+ const dateTimeFormatPrototype = globalThis.Intl.DateTimeFormat.prototype;
416
+ const nativeFormatGetter = Object.getOwnPropertyDescriptor(
417
+ dateTimeFormatPrototype,
418
+ "format",
419
+ )?.get;
420
+ if (typeof nativeFormatGetter === "function") {
421
+ Object.defineProperty(dateTimeFormatPrototype, "format", {
422
+ configurable: false,
423
+ enumerable: false,
424
+ get() {
425
+ const nativeFormat = nativeFormatGetter.call(this);
426
+ return (value) => nativeFormat(
427
+ value === undefined
428
+ ? config.epochMs + currentTimeMs
429
+ : value,
430
+ );
431
+ },
432
+ });
433
+ }
434
+ const nativeFormatToParts = dateTimeFormatPrototype.formatToParts;
435
+ if (typeof nativeFormatToParts === "function") {
436
+ Object.defineProperty(dateTimeFormatPrototype, "formatToParts", {
437
+ configurable: false,
438
+ enumerable: false,
439
+ value(value) {
440
+ return nativeFormatToParts.call(
441
+ this,
442
+ value === undefined
443
+ ? config.epochMs + currentTimeMs
444
+ : value,
445
+ );
446
+ },
447
+ writable: false,
448
+ });
449
+ }
450
+ }
451
+ if (typeof globalThis.PerformanceObserver === "function") {
452
+ replaceRuntimeValue(
453
+ globalThis,
454
+ "PerformanceObserver",
455
+ function () {
456
+ throw new DOMException(
457
+ "PerformanceObserver is unavailable; use the SlopcameraOverlay frame clock.",
458
+ "NotSupportedError",
459
+ );
460
+ },
461
+ );
462
+ }
463
+ if (typeof globalThis.URL?.createObjectURL === "function") {
464
+ const rejectObjectUrl = () => {
465
+ throw new DOMException(
466
+ "Blob object URLs are unavailable; declare the overlay asset with SlopcameraOverlay.asset().",
467
+ "NotSupportedError",
468
+ );
469
+ };
470
+ replaceRuntimeValue(
471
+ globalThis.URL,
472
+ "createObjectURL",
473
+ rejectObjectUrl,
474
+ );
475
+ replaceRuntimeValue(
476
+ globalThis.URL,
477
+ "revokeObjectURL",
478
+ rejectObjectUrl,
479
+ );
480
+ }
481
+
482
+ const installGlobalFunction = (name, value) => {
483
+ replaceRuntimeValue(globalThis, name, value, true);
484
+ };
485
+ const nextId = () => {
486
+ const id = nextScheduledId;
487
+ nextScheduledId += 1;
488
+ if (!Number.isSafeInteger(nextScheduledId)) {
489
+ throw new RangeError("HTML overlay scheduled callback ID space is exhausted.");
490
+ }
491
+ return id;
492
+ };
493
+ const finiteDelay = (value, minimum) => {
494
+ const numeric = Number(value ?? 0);
495
+ if (!Number.isFinite(numeric)) return minimum;
496
+ return Math.max(minimum, numeric);
497
+ };
498
+ const scheduleTimer = (callback, delay, interval, args) => {
499
+ if (typeof callback !== "function") {
500
+ throw new TypeError("Deterministic HTML overlay timers require function callbacks.");
501
+ }
502
+ const id = nextId();
503
+ const normalizedDelay = finiteDelay(delay, interval ? 1 : 0);
504
+ timers.set(id, {
505
+ args,
506
+ at: currentTimeMs + normalizedDelay,
507
+ callback,
508
+ intervalMs: interval ? normalizedDelay : null,
509
+ });
510
+ return id;
511
+ };
512
+ installGlobalFunction("setTimeout", (callback, delay, ...args) =>
513
+ scheduleTimer(callback, delay, false, args));
514
+ installGlobalFunction("setInterval", (callback, delay, ...args) =>
515
+ scheduleTimer(callback, delay, true, args));
516
+ const clearTimer = (id) => {
517
+ timers.delete(Number(id));
518
+ };
519
+ installGlobalFunction("clearTimeout", clearTimer);
520
+ installGlobalFunction("clearInterval", clearTimer);
521
+ installGlobalFunction("requestAnimationFrame", (callback) => {
522
+ if (typeof callback !== "function") {
523
+ throw new TypeError("requestAnimationFrame requires a function callback.");
524
+ }
525
+ const id = nextId();
526
+ animationFrames.set(id, callback);
527
+ return id;
528
+ });
529
+ installGlobalFunction("cancelAnimationFrame", (id) => {
530
+ animationFrames.delete(Number(id));
531
+ });
532
+ installGlobalFunction("requestIdleCallback", (callback, options = {}) => {
533
+ if (typeof callback !== "function") {
534
+ throw new TypeError("requestIdleCallback requires a function callback.");
535
+ }
536
+ const timeout = (
537
+ options !== null
538
+ && typeof options === "object"
539
+ && "timeout" in options
540
+ ) ? options.timeout : 0;
541
+ return scheduleTimer(
542
+ () => callback(Object.freeze({
543
+ didTimeout: false,
544
+ timeRemaining: () => 50,
545
+ })),
546
+ timeout,
547
+ false,
548
+ [],
549
+ );
550
+ });
551
+ installGlobalFunction("cancelIdleCallback", clearTimer);
552
+
553
+ const nextTimerAt = () => {
554
+ let next = null;
555
+ for (const timer of timers.values()) {
556
+ if (next === null || timer.at < next) next = timer.at;
557
+ }
558
+ return next;
559
+ };
560
+ const runScheduledWork = async (targetTimeMs, includeAnimationFrame = true) => {
561
+ let executed = 0;
562
+ while (true) {
563
+ let selectedId = null;
564
+ let selected = null;
565
+ for (const [id, timer] of timers) {
566
+ if (
567
+ timer.at <= targetTimeMs
568
+ && (
569
+ selected === null
570
+ || timer.at < selected.at
571
+ || (timer.at === selected.at && id < selectedId)
572
+ )
573
+ ) {
574
+ selectedId = id;
575
+ selected = timer;
576
+ }
577
+ }
578
+ if (selected === null || selectedId === null) break;
579
+ executed += 1;
580
+ if (executed > 10000) {
581
+ throw new RangeError("HTML overlay scheduled too many callbacks in one frame.");
582
+ }
583
+ currentTimeMs = selected.at;
584
+ if (selected.intervalMs === null) {
585
+ timers.delete(selectedId);
586
+ } else {
587
+ selected.at += selected.intervalMs;
588
+ }
589
+ await selected.callback(...selected.args);
590
+ await Promise.resolve();
591
+ }
592
+ currentTimeMs = targetTimeMs;
593
+ if (includeAnimationFrame) {
594
+ const batch = [...animationFrames.entries()];
595
+ for (const [id] of batch) animationFrames.delete(id);
596
+ for (const [, callback] of batch) {
597
+ executed += 1;
598
+ if (executed > 10000) {
599
+ throw new RangeError("HTML overlay scheduled too many callbacks in one frame.");
600
+ }
601
+ await callback(targetTimeMs);
602
+ await Promise.resolve();
603
+ }
604
+ }
605
+ };
606
+
607
+ const settleReadiness = async () => {
608
+ await Promise.resolve();
609
+ let startupCallbacks = 0;
610
+ while (pendingReadiness > 0 && startupCallbacks < 10000) {
611
+ if (animationFrames.size > 0) {
612
+ startupCallbacks += animationFrames.size;
613
+ await runScheduledWork(currentTimeMs, true);
614
+ continue;
615
+ }
616
+ const nextAt = nextTimerAt();
617
+ if (nextAt === null || nextAt > 60000) break;
618
+ startupCallbacks += 1;
619
+ await runScheduledWork(nextAt, false);
620
+ }
621
+ await Promise.all(readiness);
622
+ currentTimeMs = 0;
623
+ };
624
+
625
+ const denyAmbientNetwork = (name) => {
626
+ const denied = function () {
627
+ throw new DOMException(
628
+ name + " is unavailable in an isolated HTML overlay.",
629
+ "SecurityError",
630
+ );
631
+ };
632
+ replaceRuntimeValue(globalThis, name, denied);
633
+ };
634
+ for (const name of [
635
+ "EventSource",
636
+ "RTCPeerConnection",
637
+ "WebSocket",
638
+ "WebTransport",
639
+ "webkitRTCPeerConnection",
640
+ ]) {
641
+ denyAmbientNetwork(name);
642
+ }
643
+ if (globalThis.Temporal?.Now !== undefined) {
644
+ const rejectTemporalNow = () => {
645
+ throw new DOMException(
646
+ "Temporal.Now is unavailable; use the SlopcameraOverlay frame clock.",
647
+ "NotSupportedError",
648
+ );
649
+ };
650
+ for (const name of Object.getOwnPropertyNames(globalThis.Temporal.Now)) {
651
+ if (name === "prototype") continue;
652
+ if (typeof globalThis.Temporal.Now[name] !== "function") continue;
653
+ Object.defineProperty(globalThis.Temporal.Now, name, {
654
+ configurable: false,
655
+ enumerable: false,
656
+ value: rejectTemporalNow,
657
+ writable: false,
658
+ });
659
+ }
660
+ }
661
+
662
+ const requireRegistration = (name) => {
663
+ if (!registrationOpen) {
664
+ throw new Error("SlopcameraOverlay." + name + " must be called before the first rendered frame.");
665
+ }
666
+ };
667
+
668
+ const pauseAnimation = (animation) => {
669
+ if (typeof animation.pause === "function") animation.pause();
670
+ };
671
+
672
+ const seekDocumentAnimation = (animation, timeMs) => {
673
+ pauseAnimation(animation);
674
+ animation.currentTime = timeMs;
675
+ };
676
+
677
+ const seekTrackedAnimation = (animation, timeMs) => {
678
+ pauseAnimation(animation);
679
+ if ("time" in animation) {
680
+ animation.time = timeMs / 1000;
681
+ return;
682
+ }
683
+ if ("currentTime" in animation) {
684
+ animation.currentTime = timeMs;
685
+ return;
686
+ }
687
+ throw new TypeError("A tracked animation must expose Motion time or WAAPI currentTime.");
688
+ };
689
+
690
+ const publicApi = Object.freeze({
691
+ asset(name) {
692
+ if (typeof name !== "string" || !Object.hasOwn(config.assets, name)) {
693
+ throw new RangeError("HTML overlay asset is not declared: " + String(name));
694
+ }
695
+ return config.assets[name];
696
+ },
697
+ durationMs: config.durationMs,
698
+ fps: config.fps,
699
+ height: config.height,
700
+ onFrame(callback) {
701
+ requireRegistration("onFrame");
702
+ if (typeof callback !== "function") {
703
+ throw new TypeError("SlopcameraOverlay.onFrame requires a callback.");
704
+ }
705
+ callbacks.push(callback);
706
+ return () => {
707
+ if (!registrationOpen) {
708
+ throw new Error("Frame callbacks cannot be removed after rendering begins.");
709
+ }
710
+ const index = callbacks.indexOf(callback);
711
+ if (index >= 0) callbacks.splice(index, 1);
712
+ };
713
+ },
714
+ parameters: deepFreeze(config.parameters),
715
+ random,
716
+ randomFor,
717
+ ready(promise) {
718
+ requireRegistration("ready");
719
+ if (
720
+ (typeof promise !== "object" && typeof promise !== "function")
721
+ || promise === null
722
+ || typeof promise.then !== "function"
723
+ ) {
724
+ throw new TypeError("SlopcameraOverlay.ready requires a promise or thenable.");
725
+ }
726
+ pendingReadiness += 1;
727
+ const pending = Promise.resolve(promise).finally(() => {
728
+ pendingReadiness -= 1;
729
+ });
730
+ void pending.catch(() => undefined);
731
+ readiness.push(pending);
732
+ return pending;
733
+ },
734
+ seed: config.seed,
735
+ trackAnimation(animation) {
736
+ requireRegistration("trackAnimation");
737
+ if ((typeof animation !== "object" && typeof animation !== "function") || animation === null) {
738
+ throw new TypeError("SlopcameraOverlay.trackAnimation requires animation controls.");
739
+ }
740
+ if (!("time" in animation) && !("currentTime" in animation)) {
741
+ throw new TypeError("A tracked animation must expose Motion time or WAAPI currentTime.");
742
+ }
743
+ pauseAnimation(animation);
744
+ trackedAnimations.add(animation);
745
+ return animation;
746
+ },
747
+ width: config.width,
748
+ });
749
+
750
+ if (Object.hasOwn(globalThis, "SlopcameraOverlay")) {
751
+ throw new Error("The HTML overlay authoring API is already installed.");
752
+ }
753
+ Object.defineProperty(globalThis, "SlopcameraOverlay", {
754
+ configurable: false,
755
+ enumerable: true,
756
+ value: publicApi,
757
+ writable: false,
758
+ });
759
+ const validateFrame = (value) => {
760
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
761
+ throw new TypeError("The HTML overlay frame must be an object.");
762
+ }
763
+ const keys = Object.keys(value).sort();
764
+ const expectedKeys = ["deltaMs", "frame", "height", "progress", "timeMs", "width"];
765
+ if (
766
+ keys.length !== expectedKeys.length
767
+ || keys.some((key, index) => key !== expectedKeys[index])
768
+ ) {
769
+ throw new TypeError("The HTML overlay frame has unknown or missing fields.");
770
+ }
771
+ if (!Number.isSafeInteger(value.frame) || value.frame < 0 || value.frame >= config.frameCount) {
772
+ throw new RangeError("The HTML overlay frame index is outside the render range.");
773
+ }
774
+ const timeMs = value.frame * 1000 / config.fps;
775
+ const expected = {
776
+ deltaMs: value.frame === 0 ? 0 : 1000 / config.fps,
777
+ frame: value.frame,
778
+ height: config.height,
779
+ progress: Math.min(1, timeMs / config.durationMs),
780
+ timeMs,
781
+ width: config.width,
782
+ };
783
+ for (const key of expectedKeys) {
784
+ if (!Object.is(value[key], expected[key])) {
785
+ throw new RangeError("HTML overlay frame field " + key + " does not match the absolute render clock.");
786
+ }
787
+ }
788
+ return Object.freeze(expected);
789
+ };
790
+
791
+ return Object.freeze({
792
+ async renderFrame(value) {
793
+ const frame = validateFrame(value);
794
+ registrationOpen = false;
795
+ if (!readinessSettled) {
796
+ await settleReadiness();
797
+ readinessSettled = true;
798
+ }
799
+ currentTimeMs = frame.timeMs;
800
+ await runScheduledWork(frame.timeMs);
801
+ const animations = document.getAnimations();
802
+ for (const animation of animations) seekDocumentAnimation(animation, frame.timeMs);
803
+ for (const animation of trackedAnimations) {
804
+ if (!animations.includes(animation)) seekTrackedAnimation(animation, frame.timeMs);
805
+ }
806
+ for (const callback of [...callbacks]) await callback(frame);
807
+ },
808
+ securityViolationCount() {
809
+ return securityViolations;
810
+ },
811
+ });
812
+ })()`;
813
+ }