@vfrey/vfrey 0.0.1 → 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (603) hide show
  1. package/LICENSE +33 -0
  2. package/README.md +78 -3
  3. package/accounts.example.json +61 -0
  4. package/accounts.first-run.json +41 -0
  5. package/bin/vfrey.mjs +36 -0
  6. package/integration-tools/README.md +43 -0
  7. package/integration-tools/image/pillow.md +32 -0
  8. package/integration-tools/image/playwright.md +33 -0
  9. package/integration-tools/image/resvg.md +36 -0
  10. package/integration-tools/image/satori.md +36 -0
  11. package/integration-tools/image/sharp.md +38 -0
  12. package/integration-tools/video/blender.md +34 -0
  13. package/integration-tools/video/ffmpeg.md +41 -0
  14. package/integration-tools/video/manim.md +37 -0
  15. package/integration-tools/video/motion-canvas.md +37 -0
  16. package/integration-tools/video/remotion.md +50 -0
  17. package/integration-tools/video/revideo.md +32 -0
  18. package/package.json +74 -6
  19. package/skills/vfrey-orchestrator/SKILL.md +15 -0
  20. package/skills/vfrey-orchestrator/channel-video/SKILL.md +41 -0
  21. package/skills/vfrey-product/SKILL.md +63 -0
  22. package/skills/vfrey-product/examples/concurrency-vs-parallelism/framey/cook-one.svg +14 -0
  23. package/skills/vfrey-product/examples/concurrency-vs-parallelism/framey/cook-two.svg +22 -0
  24. package/skills/vfrey-product/examples/concurrency-vs-parallelism/framey/index.html +70 -0
  25. package/skills/vfrey-product/examples/concurrency-vs-parallelism/remotion/cook-one.svg +14 -0
  26. package/skills/vfrey-product/examples/concurrency-vs-parallelism/remotion/cook-two.svg +22 -0
  27. package/skills/vfrey-product/examples/concurrency-vs-parallelism/remotion/index.tsx +49 -0
  28. package/skills/vfrey-product/examples/concurrency-vs-parallelism/script.json +15 -0
  29. package/skills/vfrey-product/examples/octopus-facts/index.html +60 -0
  30. package/skills/vfrey-product/examples/octopus-facts/octopus.svg +8 -0
  31. package/skills/vfrey-product/examples/octopus-facts/script.json +14 -0
  32. package/skills/vfrey-product/push/SKILL.md +15 -0
  33. package/skills/vfrey-product/scenes/NOTICE +5 -0
  34. package/skills/vfrey-product/scenes/blocks.md +57 -0
  35. package/skills/vfrey-product/scenes/craft.md +118 -0
  36. package/skills/vfrey-product/scenes/motion.md +88 -0
  37. package/src/analytics/dashboard.ts +109 -0
  38. package/src/analytics/index.ts +260 -0
  39. package/src/api/client.ts +282 -0
  40. package/src/api/commands.ts +330 -0
  41. package/src/api/config.ts +34 -0
  42. package/src/api/creators.ts +463 -0
  43. package/src/api/credentials.ts +152 -0
  44. package/src/api/mail.ts +333 -0
  45. package/src/api/topics.ts +207 -0
  46. package/src/api/types.ts +205 -0
  47. package/src/cli.ts +467 -0
  48. package/src/cloud/executor.ts +281 -0
  49. package/src/cloud/job.ts +106 -0
  50. package/src/cloud/render-job.ts +187 -0
  51. package/src/config.ts +309 -0
  52. package/src/dashboard-link.ts +180 -0
  53. package/src/dashboard-start.ts +103 -0
  54. package/src/desk/channel.ts +64 -0
  55. package/src/desk/cli.ts +216 -0
  56. package/src/desk/creators-route.ts +129 -0
  57. package/src/desk/fonts/JetBrainsMono-OFL.txt +93 -0
  58. package/src/desk/fonts/google-sans-flex-latin.woff2 +0 -0
  59. package/src/desk/fonts/jetbrains-mono-medium.woff2 +0 -0
  60. package/src/desk/http.ts +460 -0
  61. package/src/desk/mail-route.ts +103 -0
  62. package/src/desk/overlay.ts +112 -0
  63. package/src/desk/preview.ts +422 -0
  64. package/src/desk/screens.ts +149 -0
  65. package/src/desk/secrets.ts +143 -0
  66. package/src/desk/series.ts +127 -0
  67. package/src/desk/state.ts +77 -0
  68. package/src/desk/studio-route.ts +119 -0
  69. package/src/desk/tick-runner.ts +66 -0
  70. package/src/desk/tick.ts +56 -0
  71. package/src/desk/topics-route.ts +41 -0
  72. package/src/desk/ui/app.css +505 -0
  73. package/src/desk/ui/app.js +185 -0
  74. package/src/desk/ui/apple-icon.png +0 -0
  75. package/src/desk/ui/components.js +79 -0
  76. package/src/desk/ui/core.js +156 -0
  77. package/src/desk/ui/favicon.ico +0 -0
  78. package/src/desk/ui/icon.svg +1 -0
  79. package/src/desk/ui/icons.js +49 -0
  80. package/src/desk/ui/index.html +41 -0
  81. package/src/desk/ui/metrics-math.d.ts +22 -0
  82. package/src/desk/ui/metrics-math.js +135 -0
  83. package/src/desk/ui/theme.js +5 -0
  84. package/src/desk/ui/views-creators.js +209 -0
  85. package/src/desk/ui/views-keys.js +114 -0
  86. package/src/desk/ui/views-mail.js +188 -0
  87. package/src/desk/ui/views-misc.js +123 -0
  88. package/src/desk/ui/views-review.js +119 -0
  89. package/src/desk/ui/views-runs.js +350 -0
  90. package/src/desk/ui/views-screens.js +163 -0
  91. package/src/desk/ui/views-series.js +318 -0
  92. package/src/desk/ui/views-topics.js +87 -0
  93. package/src/desk/verbs.ts +361 -0
  94. package/src/doctor.ts +212 -0
  95. package/src/drain.ts +14 -0
  96. package/src/engage/index.ts +217 -0
  97. package/src/generate/index.ts +110 -0
  98. package/src/generate/script.ts +152 -0
  99. package/src/generate/title.ts +78 -0
  100. package/src/help.ts +233 -0
  101. package/src/home.ts +45 -0
  102. package/src/llm/client.ts +177 -0
  103. package/src/log.ts +7 -0
  104. package/src/oauth/tokens.ts +189 -0
  105. package/src/oauth/vault.ts +72 -0
  106. package/src/pipeline/review.ts +642 -0
  107. package/src/pipeline/run.ts +443 -0
  108. package/src/pipeline/series-guard.ts +26 -0
  109. package/src/pipeline/source-fetch.ts +69 -0
  110. package/src/pipeline/stages.ts +728 -0
  111. package/src/pipeline/topics-source.ts +90 -0
  112. package/src/product/commands.ts +296 -0
  113. package/src/product/config-file.ts +38 -0
  114. package/src/product/engine-choice.ts +89 -0
  115. package/src/product/engines.ts +103 -0
  116. package/src/product/insights.ts +50 -0
  117. package/src/product/keys.ts +67 -0
  118. package/src/product/paths.ts +18 -0
  119. package/src/product/probes.ts +88 -0
  120. package/src/product/push-flow.ts +90 -0
  121. package/src/product/render-video.ts +21 -0
  122. package/src/product/short.ts +62 -0
  123. package/src/product/update.ts +32 -0
  124. package/src/project/canonical.ts +14 -0
  125. package/src/project/commands.ts +177 -0
  126. package/src/project/dashboard-status.ts +28 -0
  127. package/src/project/discover.ts +19 -0
  128. package/src/project/index-file.ts +73 -0
  129. package/src/project/marker.ts +87 -0
  130. package/src/project/migrate.ts +201 -0
  131. package/src/project/names.ts +27 -0
  132. package/src/project/notice.ts +16 -0
  133. package/src/project/open.ts +88 -0
  134. package/src/project/scaffold.ts +112 -0
  135. package/src/project/templates.ts +42 -0
  136. package/src/project/videos.ts +64 -0
  137. package/src/publish/facebook.ts +91 -0
  138. package/src/publish/index.ts +12 -0
  139. package/src/publish/instagram.ts +97 -0
  140. package/src/publish/rate.ts +62 -0
  141. package/src/publish/session.ts +242 -0
  142. package/src/publish/tiktok.ts +202 -0
  143. package/src/publish/youtube.ts +177 -0
  144. package/src/queue/desk-ops.ts +1170 -0
  145. package/src/queue/seal.ts +3 -0
  146. package/src/queue/store.ts +1006 -0
  147. package/src/remotion/AiLabel.tsx +26 -0
  148. package/src/remotion/Root.tsx +73 -0
  149. package/src/remotion/defaults.ts +26 -0
  150. package/src/remotion/films/claude/ClaudeFilm.tsx +1014 -0
  151. package/src/remotion/films/engine/EngineMark.tsx +17 -0
  152. package/src/remotion/films/rea/ReaShort.tsx +552 -0
  153. package/src/remotion/films/rea/drawings.tsx +907 -0
  154. package/src/remotion/films/rea/timing.ts +144 -0
  155. package/src/remotion/index.ts +4 -0
  156. package/src/remotion/templates/EditorialSplit.tsx +39 -0
  157. package/src/remotion/templates/KineticType.tsx +39 -0
  158. package/src/remotion/templates/SignalBoard.tsx +50 -0
  159. package/src/remotion/timing.ts +22 -0
  160. package/src/render/chrome.ts +78 -0
  161. package/src/render/engine-mark.ts +29 -0
  162. package/src/render/framey-template.ts +130 -0
  163. package/src/render/html-engine.ts +149 -0
  164. package/src/render/node-crypto-stub.ts +11 -0
  165. package/src/render/probe.ts +29 -0
  166. package/src/render/props.ts +17 -0
  167. package/src/render/vertical-short.ts +35 -0
  168. package/src/render/webpack.ts +33 -0
  169. package/src/render/worker.ts +65 -0
  170. package/src/scene/assets/fonts/TitanOne-OFL.txt +94 -0
  171. package/src/scene/assets/fonts/titan-one.woff2 +0 -0
  172. package/src/scene/assets/gsap/LICENSE.txt +8 -0
  173. package/src/scene/assets/gsap/gsap.min.js +11 -0
  174. package/src/scene/audio.ts +54 -0
  175. package/src/scene/blocks/LICENSE +190 -0
  176. package/src/scene/blocks/NOTICE +5 -0
  177. package/src/scene/blocks/bar-chart-race/bar-chart-race.html +585 -0
  178. package/src/scene/blocks/beat-freeze-cut/beat-freeze-cut.html +874 -0
  179. package/src/scene/blocks/camcorder-hud/camcorder-hud.html +164 -0
  180. package/src/scene/blocks/camera-dolly-zoom/camera-dolly-zoom.html +355 -0
  181. package/src/scene/blocks/code-diff/code-diff.html +817 -0
  182. package/src/scene/blocks/code-snippet-apple-terminal-pro/code-snippet-apple-terminal-pro.html +248 -0
  183. package/src/scene/blocks/code-typing/code-typing.html +764 -0
  184. package/src/scene/blocks/data-chart/data-chart.html +452 -0
  185. package/src/scene/blocks/flowchart-vertical/flowchart-vertical.html +454 -0
  186. package/src/scene/blocks/hw-scribble-transition/hw-scribble-transition.html +153 -0
  187. package/src/scene/blocks/index.json +824 -0
  188. package/src/scene/blocks/lt-accent-underline/lt-accent-underline.html +107 -0
  189. package/src/scene/blocks/lt-bold-block/lt-bold-block.html +109 -0
  190. package/src/scene/blocks/lt-clean-bar/lt-clean-bar.html +112 -0
  191. package/src/scene/blocks/lt-dark-card/lt-dark-card.html +111 -0
  192. package/src/scene/blocks/lt-kicker-name/lt-kicker-name.html +114 -0
  193. package/src/scene/blocks/lt-mask-reveal/lt-mask-reveal.html +120 -0
  194. package/src/scene/blocks/lt-neon-border/lt-neon-border.html +391 -0
  195. package/src/scene/blocks/lt-stack-bars/lt-stack-bars.html +109 -0
  196. package/src/scene/blocks/macos-notification/macos-notification.html +194 -0
  197. package/src/scene/blocks/mk-background/mk-background.html +236 -0
  198. package/src/scene/blocks/mk-callout-highlight/mk-callout-highlight.html +183 -0
  199. package/src/scene/blocks/mk-clone-wall-transition/mk-clone-wall-transition.html +226 -0
  200. package/src/scene/blocks/mk-line-graph/mk-line-graph.html +293 -0
  201. package/src/scene/blocks/mk-progress-stat/mk-progress-stat.html +186 -0
  202. package/src/scene/blocks/mk-specs-list/mk-specs-list.html +223 -0
  203. package/src/scene/blocks/news-ticker/news-ticker.html +409 -0
  204. package/src/scene/blocks/organic-light-leak-overlay/organic-light-leak-overlay.html +126 -0
  205. package/src/scene/blocks/oscilloscope-trace/oscilloscope-trace.html +519 -0
  206. package/src/scene/blocks/snow/snow.html +205 -0
  207. package/src/scene/blocks/split-flap-board/split-flap-board.html +347 -0
  208. package/src/scene/blocks/spotify-card/spotify-card.html +294 -0
  209. package/src/scene/blocks/starfield/starfield.html +188 -0
  210. package/src/scene/blocks/thread-message-stack/thread-message-stack.html +239 -0
  211. package/src/scene/blocks/week-in-merges/week-in-merges.html +470 -0
  212. package/src/scene/blocks/x-post/x-post.html +437 -0
  213. package/src/scene/blocks/yt-comment-card/yt-comment-card.html +319 -0
  214. package/src/scene/blocks/yt-lcd-background/yt-lcd-background.html +307 -0
  215. package/src/scene/blocks/yt-prism-title/yt-prism-title.html +205 -0
  216. package/src/scene/blocks.ts +229 -0
  217. package/src/scene/command.ts +272 -0
  218. package/src/scene/figure.ts +181 -0
  219. package/src/scene/glyphs.ts +107 -0
  220. package/src/scene/init.ts +86 -0
  221. package/src/scene/inspect/css-tree.d.ts +6 -0
  222. package/src/scene/inspect/page-scripts.ts +272 -0
  223. package/src/scene/inspect/report.ts +405 -0
  224. package/src/scene/inspect/run.ts +200 -0
  225. package/src/scene/inspect/source.ts +236 -0
  226. package/src/scene/label.ts +131 -0
  227. package/src/scene/net-guard.ts +74 -0
  228. package/src/scene/render.ts +292 -0
  229. package/src/scene/runtime/browser.ts +199 -0
  230. package/src/scene/runtime/core.ts +181 -0
  231. package/src/scene/runtime/react.tsx +115 -0
  232. package/src/scene/runtime/transitions.ts +133 -0
  233. package/src/scene/sanitize.ts +181 -0
  234. package/src/scene/scene.ts +152 -0
  235. package/src/scene/studio-command.ts +48 -0
  236. package/src/scene/studio-skin.ts +59 -0
  237. package/src/scene/studio.ts +337 -0
  238. package/src/scene/supply.ts +111 -0
  239. package/src/scene/timing.ts +288 -0
  240. package/src/scene/transitions/LICENSE +190 -0
  241. package/src/scene/transitions/NOTICE +5 -0
  242. package/src/scene/transitions/SOURCE.json +24 -0
  243. package/src/scene/transitions/transitions.global.js +38 -0
  244. package/src/scene/transitions.ts +26 -0
  245. package/src/service/all-projects.ts +153 -0
  246. package/src/service/commands.ts +256 -0
  247. package/src/service/due.ts +82 -0
  248. package/src/service/lock.ts +101 -0
  249. package/src/service/log-file.ts +56 -0
  250. package/src/service/state.ts +41 -0
  251. package/src/service/units.ts +90 -0
  252. package/src/service/worker.ts +51 -0
  253. package/src/skill-agents.ts +74 -0
  254. package/src/skill-install.ts +334 -0
  255. package/src/sync-write.ts +21 -0
  256. package/src/tick-report.ts +205 -0
  257. package/src/tts.ts +124 -0
  258. package/vendor/@vfrey/contracts/dist/account.d.ts +97 -0
  259. package/vendor/@vfrey/contracts/dist/account.js +27 -0
  260. package/vendor/@vfrey/contracts/dist/checks.d.ts +8 -0
  261. package/vendor/@vfrey/contracts/dist/checks.js +1 -0
  262. package/vendor/@vfrey/contracts/dist/credentials/crypto.d.ts +4 -0
  263. package/vendor/@vfrey/contracts/dist/credentials/crypto.js +38 -0
  264. package/vendor/@vfrey/contracts/dist/domain/advice-persona.d.ts +10 -0
  265. package/vendor/@vfrey/contracts/dist/domain/advice-persona.js +24 -0
  266. package/vendor/@vfrey/contracts/dist/domain/backoff.d.ts +13 -0
  267. package/vendor/@vfrey/contracts/dist/domain/backoff.js +27 -0
  268. package/vendor/@vfrey/contracts/dist/domain/cadence.d.ts +29 -0
  269. package/vendor/@vfrey/contracts/dist/domain/cadence.js +95 -0
  270. package/vendor/@vfrey/contracts/dist/domain/creators.d.ts +146 -0
  271. package/vendor/@vfrey/contracts/dist/domain/creators.js +2 -0
  272. package/vendor/@vfrey/contracts/dist/domain/disclosure.d.ts +127 -0
  273. package/vendor/@vfrey/contracts/dist/domain/disclosure.js +250 -0
  274. package/vendor/@vfrey/contracts/dist/domain/errors.d.ts +34 -0
  275. package/vendor/@vfrey/contracts/dist/domain/errors.js +68 -0
  276. package/vendor/@vfrey/contracts/dist/domain/redact.d.ts +1 -0
  277. package/vendor/@vfrey/contracts/dist/domain/redact.js +21 -0
  278. package/vendor/@vfrey/contracts/dist/domain/revenue.d.ts +13 -0
  279. package/vendor/@vfrey/contracts/dist/domain/revenue.js +16 -0
  280. package/vendor/@vfrey/contracts/dist/domain/safety.d.ts +20 -0
  281. package/vendor/@vfrey/contracts/dist/domain/safety.js +61 -0
  282. package/vendor/@vfrey/contracts/dist/domain/similarity.d.ts +13 -0
  283. package/vendor/@vfrey/contracts/dist/domain/similarity.js +100 -0
  284. package/vendor/@vfrey/contracts/dist/domain/templates.d.ts +18 -0
  285. package/vendor/@vfrey/contracts/dist/domain/templates.js +67 -0
  286. package/vendor/@vfrey/contracts/dist/domain/tiktok-chunks.d.ts +19 -0
  287. package/vendor/@vfrey/contracts/dist/domain/tiktok-chunks.js +52 -0
  288. package/vendor/@vfrey/contracts/dist/domain/topics.d.ts +78 -0
  289. package/vendor/@vfrey/contracts/dist/domain/topics.js +4 -0
  290. package/vendor/@vfrey/contracts/dist/domain/types.d.ts +216 -0
  291. package/vendor/@vfrey/contracts/dist/domain/types.js +1 -0
  292. package/vendor/@vfrey/contracts/dist/domain/variation.d.ts +57 -0
  293. package/vendor/@vfrey/contracts/dist/domain/variation.js +278 -0
  294. package/vendor/@vfrey/contracts/dist/events.d.ts +20 -0
  295. package/vendor/@vfrey/contracts/dist/events.js +1 -0
  296. package/vendor/@vfrey/contracts/dist/http.d.ts +11 -0
  297. package/vendor/@vfrey/contracts/dist/http.js +37 -0
  298. package/vendor/@vfrey/contracts/dist/index.d.ts +22 -0
  299. package/vendor/@vfrey/contracts/dist/index.js +22 -0
  300. package/vendor/@vfrey/contracts/dist/log.d.ts +2 -0
  301. package/vendor/@vfrey/contracts/dist/log.js +10 -0
  302. package/vendor/@vfrey/contracts/dist/mail.d.ts +55 -0
  303. package/vendor/@vfrey/contracts/dist/mail.js +1 -0
  304. package/vendor/@vfrey/contracts/package.json +18 -0
  305. package/vendor/@vfrey/ingest/dist/index.d.ts +41 -0
  306. package/vendor/@vfrey/ingest/dist/index.js +221 -0
  307. package/vendor/@vfrey/ingest/dist/parse.d.ts +5 -0
  308. package/vendor/@vfrey/ingest/dist/parse.js +165 -0
  309. package/vendor/@vfrey/ingest/package.json +21 -0
  310. package/vendor/framey/LICENSE +190 -0
  311. package/vendor/framey/NOTICE +15 -0
  312. package/vendor/framey/SOURCE.json +24 -0
  313. package/vendor/framey/STUDIO-SOURCE.json +9 -0
  314. package/vendor/framey/bin/framey-localize-fonts.mjs +12 -0
  315. package/vendor/framey/bin/framey.mjs +16 -0
  316. package/vendor/framey/dist/add-VMJD5KBS.js +75 -0
  317. package/vendor/framey/dist/animatedGifPrep-QPKGJ6PM.js +43 -0
  318. package/vendor/framey/dist/api.d.ts +211 -0
  319. package/vendor/framey/dist/api.js +76 -0
  320. package/vendor/framey/dist/appHistory-WW56FZTT.js +31 -0
  321. package/vendor/framey/dist/asset-WQKGOELE.js +26 -0
  322. package/vendor/framey/dist/audio-RSJWVWRA.js +1936 -0
  323. package/vendor/framey/dist/batchRender-3HPICDCT.js +366 -0
  324. package/vendor/framey/dist/beats-HL2BDUZI.js +273 -0
  325. package/vendor/framey/dist/benchmark-RWCWHI5Z.js +230 -0
  326. package/vendor/framey/dist/browser-ECYET3Q2.js +206 -0
  327. package/vendor/framey/dist/bundleWithLocalizedFonts-ALYBQEQT.js +52 -0
  328. package/vendor/framey/dist/captureCompositionFrame-4DA6SEH2.js +94 -0
  329. package/vendor/framey/dist/catalog-5JVDEUWK.js +979 -0
  330. package/vendor/framey/dist/catch-up-NEBCL5NO.js +106 -0
  331. package/vendor/framey/dist/check-F5N544ML.js +111 -0
  332. package/vendor/framey/dist/checkBrowser-LZ66CMJG.js +110 -0
  333. package/vendor/framey/dist/chunk-2K7Z2HVP.js +372 -0
  334. package/vendor/framey/dist/chunk-2UZQHDM7.js +323 -0
  335. package/vendor/framey/dist/chunk-2X4PQEYM.js +34 -0
  336. package/vendor/framey/dist/chunk-3422KMTD.js +168 -0
  337. package/vendor/framey/dist/chunk-3FYD4YEK.js +72 -0
  338. package/vendor/framey/dist/chunk-3GXQPCJC.js +682 -0
  339. package/vendor/framey/dist/chunk-3LM6YPBR.js +179 -0
  340. package/vendor/framey/dist/chunk-442JNXRM.js +20 -0
  341. package/vendor/framey/dist/chunk-4BNN5FGX.js +182 -0
  342. package/vendor/framey/dist/chunk-4P7NX5BM.js +11532 -0
  343. package/vendor/framey/dist/chunk-4UMPIPCQ.js +88 -0
  344. package/vendor/framey/dist/chunk-4YYJOFKS.js +28 -0
  345. package/vendor/framey/dist/chunk-54HJ63Q2.js +29 -0
  346. package/vendor/framey/dist/chunk-5ETJX6WM.js +89 -0
  347. package/vendor/framey/dist/chunk-5SG54JRS.js +68 -0
  348. package/vendor/framey/dist/chunk-634HSJ3J.js +58 -0
  349. package/vendor/framey/dist/chunk-66LREXGS.js +48 -0
  350. package/vendor/framey/dist/chunk-6BEFEWFB.js +25 -0
  351. package/vendor/framey/dist/chunk-6BNTGNGD.js +286 -0
  352. package/vendor/framey/dist/chunk-6DDPOHMK.js +140 -0
  353. package/vendor/framey/dist/chunk-6GV5XSOR.js +214 -0
  354. package/vendor/framey/dist/chunk-6JR2XUEE.js +127 -0
  355. package/vendor/framey/dist/chunk-73QVATIM.js +362 -0
  356. package/vendor/framey/dist/chunk-7FMUTGOH.js +279 -0
  357. package/vendor/framey/dist/chunk-7JQFJ6JJ.js +291 -0
  358. package/vendor/framey/dist/chunk-AHPGAESX.js +113 -0
  359. package/vendor/framey/dist/chunk-AHX34EFP.js +15 -0
  360. package/vendor/framey/dist/chunk-AJ5CSAEZ.js +487 -0
  361. package/vendor/framey/dist/chunk-B7RJV74O.js +5047 -0
  362. package/vendor/framey/dist/chunk-BL4U6U52.js +254 -0
  363. package/vendor/framey/dist/chunk-BSQ7XANM.js +210 -0
  364. package/vendor/framey/dist/chunk-BZ56MTDX.js +6 -0
  365. package/vendor/framey/dist/chunk-C5BO7PMT.js +282 -0
  366. package/vendor/framey/dist/chunk-CFUCHO4T.js +358 -0
  367. package/vendor/framey/dist/chunk-CZGHFATT.js +31 -0
  368. package/vendor/framey/dist/chunk-DLA44CMS.js +5649 -0
  369. package/vendor/framey/dist/chunk-DPVXBVLL.js +31292 -0
  370. package/vendor/framey/dist/chunk-DQBY7FRR.js +397 -0
  371. package/vendor/framey/dist/chunk-EAMLBAHA.js +154 -0
  372. package/vendor/framey/dist/chunk-EOVYQ3IG.js +143 -0
  373. package/vendor/framey/dist/chunk-EVMY7IPL.js +612 -0
  374. package/vendor/framey/dist/chunk-FG4BBFZI.js +122 -0
  375. package/vendor/framey/dist/chunk-FI4I7CME.js +56 -0
  376. package/vendor/framey/dist/chunk-FLREUEHW.js +2081 -0
  377. package/vendor/framey/dist/chunk-FUFP7A7S.js +1126 -0
  378. package/vendor/framey/dist/chunk-FV3PIKGH.js +56 -0
  379. package/vendor/framey/dist/chunk-FXMKHHPO.js +123 -0
  380. package/vendor/framey/dist/chunk-GGZAM5VH.js +1187 -0
  381. package/vendor/framey/dist/chunk-GKZEVJIB.js +39 -0
  382. package/vendor/framey/dist/chunk-GMECXFAN.js +57 -0
  383. package/vendor/framey/dist/chunk-GNEFDLFB.js +621 -0
  384. package/vendor/framey/dist/chunk-GPMLSOEG.js +19274 -0
  385. package/vendor/framey/dist/chunk-GPYVT5EE.js +59 -0
  386. package/vendor/framey/dist/chunk-H6IEMZEV.js +40 -0
  387. package/vendor/framey/dist/chunk-HEFQCIXR.js +170 -0
  388. package/vendor/framey/dist/chunk-HFQ4CWHA.js +118 -0
  389. package/vendor/framey/dist/chunk-HPDTCOKE.js +304 -0
  390. package/vendor/framey/dist/chunk-HTUHQKDB.js +548 -0
  391. package/vendor/framey/dist/chunk-HU2SPFNG.js +103 -0
  392. package/vendor/framey/dist/chunk-HVW7ABXD.js +19 -0
  393. package/vendor/framey/dist/chunk-IG7NDKXO.js +26 -0
  394. package/vendor/framey/dist/chunk-II3J3WXK.js +246 -0
  395. package/vendor/framey/dist/chunk-IR35BCLK.js +13 -0
  396. package/vendor/framey/dist/chunk-ISN5GRYI.js +20 -0
  397. package/vendor/framey/dist/chunk-IUONB55J.js +669 -0
  398. package/vendor/framey/dist/chunk-IVSUQR2B.js +161 -0
  399. package/vendor/framey/dist/chunk-IXU6PQSW.js +259 -0
  400. package/vendor/framey/dist/chunk-IZCW2NKT.js +29 -0
  401. package/vendor/framey/dist/chunk-JGXJU5PF.js +68 -0
  402. package/vendor/framey/dist/chunk-JHOCK3DG.js +27 -0
  403. package/vendor/framey/dist/chunk-JVBRJMOP.js +121 -0
  404. package/vendor/framey/dist/chunk-K4MJX7SR.js +17 -0
  405. package/vendor/framey/dist/chunk-K4WKGXRC.js +18 -0
  406. package/vendor/framey/dist/chunk-KGPLIH7B.js +127 -0
  407. package/vendor/framey/dist/chunk-KLIKCX6Q.js +63 -0
  408. package/vendor/framey/dist/chunk-KXTKKBOC.js +61 -0
  409. package/vendor/framey/dist/chunk-KZI44OPA.js +185 -0
  410. package/vendor/framey/dist/chunk-LEKZNRKI.js +45 -0
  411. package/vendor/framey/dist/chunk-LFGJWOVA.js +61 -0
  412. package/vendor/framey/dist/chunk-LLMSX6V6.js +17 -0
  413. package/vendor/framey/dist/chunk-LTGTN2TH.js +195 -0
  414. package/vendor/framey/dist/chunk-M2WBOQ2Q.js +54 -0
  415. package/vendor/framey/dist/chunk-MI5FTLYK.js +399 -0
  416. package/vendor/framey/dist/chunk-MLQP2QUF.js +1809 -0
  417. package/vendor/framey/dist/chunk-MMQ52NIZ.js +956 -0
  418. package/vendor/framey/dist/chunk-ND46XKK3.js +742 -0
  419. package/vendor/framey/dist/chunk-NYEXNSHM.js +504 -0
  420. package/vendor/framey/dist/chunk-O4YRB27L.js +57 -0
  421. package/vendor/framey/dist/chunk-O7BGSQ5F.js +92 -0
  422. package/vendor/framey/dist/chunk-OFQWTKPW.js +117 -0
  423. package/vendor/framey/dist/chunk-P5ZBLXJ6.js +91 -0
  424. package/vendor/framey/dist/chunk-P6LJ4Y32.js +4662 -0
  425. package/vendor/framey/dist/chunk-PKZ7RK5N.js +281 -0
  426. package/vendor/framey/dist/chunk-PURHAXFL.js +15 -0
  427. package/vendor/framey/dist/chunk-Q5X2B5WT.js +29 -0
  428. package/vendor/framey/dist/chunk-QAMKOG67.js +248 -0
  429. package/vendor/framey/dist/chunk-R6YBK4XX.js +514 -0
  430. package/vendor/framey/dist/chunk-RGLQURIX.js +2997 -0
  431. package/vendor/framey/dist/chunk-RNV3DM4S.js +3573 -0
  432. package/vendor/framey/dist/chunk-ROEW726S.js +4638 -0
  433. package/vendor/framey/dist/chunk-RQVDTPGD.js +6 -0
  434. package/vendor/framey/dist/chunk-RVZHGOGR.js +26 -0
  435. package/vendor/framey/dist/chunk-RXATE6FZ.js +385 -0
  436. package/vendor/framey/dist/chunk-S3S4TGEH.js +424 -0
  437. package/vendor/framey/dist/chunk-SDYDNHEE.js +11202 -0
  438. package/vendor/framey/dist/chunk-SSWBU67I.js +173 -0
  439. package/vendor/framey/dist/chunk-ST35C4K6.js +28 -0
  440. package/vendor/framey/dist/chunk-SZNTYTIV.js +990 -0
  441. package/vendor/framey/dist/chunk-T2EUWCJE.js +29 -0
  442. package/vendor/framey/dist/chunk-T6AGUTZJ.js +444 -0
  443. package/vendor/framey/dist/chunk-THJALHFJ.js +11131 -0
  444. package/vendor/framey/dist/chunk-TIQB63MX.js +18128 -0
  445. package/vendor/framey/dist/chunk-U242RTCT.js +134 -0
  446. package/vendor/framey/dist/chunk-UJZREAV6.js +3901 -0
  447. package/vendor/framey/dist/chunk-UMD3V7CU.js +264 -0
  448. package/vendor/framey/dist/chunk-UOFAE5RF.js +42 -0
  449. package/vendor/framey/dist/chunk-UTEIUGAZ.js +29 -0
  450. package/vendor/framey/dist/chunk-VAS6HQX3.js +138 -0
  451. package/vendor/framey/dist/chunk-VC76R6W2.js +27 -0
  452. package/vendor/framey/dist/chunk-VFZ7W5W7.js +226 -0
  453. package/vendor/framey/dist/chunk-VHNLZAE2.js +348 -0
  454. package/vendor/framey/dist/chunk-VMC4WSH5.js +278 -0
  455. package/vendor/framey/dist/chunk-VORQIH64.js +108 -0
  456. package/vendor/framey/dist/chunk-VTXFRIHO.js +186 -0
  457. package/vendor/framey/dist/chunk-W2LGJSEN.js +182 -0
  458. package/vendor/framey/dist/chunk-WKBM7NDG.js +32 -0
  459. package/vendor/framey/dist/chunk-WMQNIQDJ.js +2057 -0
  460. package/vendor/framey/dist/chunk-WN4XZC5F.js +504 -0
  461. package/vendor/framey/dist/chunk-WQ6ZXHFQ.js +133 -0
  462. package/vendor/framey/dist/chunk-X7HBSTCZ.js +53 -0
  463. package/vendor/framey/dist/chunk-X7MTZ4T2.js +6 -0
  464. package/vendor/framey/dist/chunk-XPTOJZJF.js +308 -0
  465. package/vendor/framey/dist/chunk-XT6MXC7A.js +6 -0
  466. package/vendor/framey/dist/chunk-XT7X6QCP.js +6 -0
  467. package/vendor/framey/dist/chunk-XTMDWNEC.js +2820 -0
  468. package/vendor/framey/dist/chunk-XUHOIDKG.js +6 -0
  469. package/vendor/framey/dist/chunk-XX7LTW5Y.js +138 -0
  470. package/vendor/framey/dist/chunk-Y3YGTZEG.js +382 -0
  471. package/vendor/framey/dist/chunk-Y5SBSGN7.js +346 -0
  472. package/vendor/framey/dist/chunk-YCMVI4MZ.js +625 -0
  473. package/vendor/framey/dist/chunk-YOR4CTCE.js +261 -0
  474. package/vendor/framey/dist/chunk-YPRBGITP.js +2748 -0
  475. package/vendor/framey/dist/chunk-ZKDMAOFU.js +32 -0
  476. package/vendor/framey/dist/chunk-ZW6DURPF.js +1318 -0
  477. package/vendor/framey/dist/clean-ZJOGDKDM.js +336 -0
  478. package/vendor/framey/dist/cli.js +439 -0
  479. package/vendor/framey/dist/cloudrun-HGJ3B6ZV.js +767 -0
  480. package/vendor/framey/dist/commands/contrast-audit.browser.js +643 -0
  481. package/vendor/framey/dist/commands/layout-audit.browser.js +2914 -0
  482. package/vendor/framey/dist/commands/motion-sample.browser.js +74 -0
  483. package/vendor/framey/dist/commands/motion-signature.browser.js +475 -0
  484. package/vendor/framey/dist/compare-W7UY3BAZ.js +463 -0
  485. package/vendor/framey/dist/compiler-TM3W6GYF.js +136 -0
  486. package/vendor/framey/dist/component-QF5VGYMU.js +176 -0
  487. package/vendor/framey/dist/compositions-XT3PMNDF.js +238 -0
  488. package/vendor/framey/dist/contactSheet-7W6GYHBQ.js +24 -0
  489. package/vendor/framey/dist/deploy-6FJPWKF2.js +299 -0
  490. package/vendor/framey/dist/destroy-HE2RIPKZ.js +57 -0
  491. package/vendor/framey/dist/deterministicFonts-RADD3BSX.js +50 -0
  492. package/vendor/framey/dist/dist-4S2FGGVY.js +422 -0
  493. package/vendor/framey/dist/dist-BE4B2EZE.js +32 -0
  494. package/vendor/framey/dist/dist-EWXJGN63.js +129 -0
  495. package/vendor/framey/dist/docs-VKIRFEEX.js +131 -0
  496. package/vendor/framey/dist/doctor-2UNJ2G7U.js +74 -0
  497. package/vendor/framey/dist/dom-37K6YOH4.js +14 -0
  498. package/vendor/framey/dist/dotEnv-7PZQTVIM.js +54 -0
  499. package/vendor/framey/dist/events-ACY3P2PA.js +76 -0
  500. package/vendor/framey/dist/events-IHB3B2MK.js +69 -0
  501. package/vendor/framey/dist/ffmpeg-DR5LGGSK.js +63 -0
  502. package/vendor/framey/dist/figma-BODVUPHB.js +63 -0
  503. package/vendor/framey/dist/fontData.generated-NXAOI4GH.js +13 -0
  504. package/vendor/framey/dist/fontLocalizeCli.js +142 -0
  505. package/vendor/framey/dist/gpuPolicy-XLEXORZY.js +49 -0
  506. package/vendor/framey/dist/grade-compare-GAXFQ74C.js +661 -0
  507. package/vendor/framey/dist/gsapParser-IEUSLYDJ.js +2885 -0
  508. package/vendor/framey/dist/gsapParserAcorn-LZJKCFQI.js +30 -0
  509. package/vendor/framey/dist/help-VCB5X2HS.js +184 -0
  510. package/vendor/framey/dist/history-ENGZEVFT.js +471 -0
  511. package/vendor/framey/dist/hyperframe.manifest.json +22 -0
  512. package/vendor/framey/dist/hyperframe.runtime.iife.js +1132 -0
  513. package/vendor/framey/dist/hyperframes-player.global.js +478 -0
  514. package/vendor/framey/dist/hyperframes-slideshow.global.js +148 -0
  515. package/vendor/framey/dist/info-WPCJHBMU.js +182 -0
  516. package/vendor/framey/dist/init-G4WGLYGD.js +1176 -0
  517. package/vendor/framey/dist/inspect-5IQ6CNEQ.js +106 -0
  518. package/vendor/framey/dist/installer-ML4HWUV7.js +40 -0
  519. package/vendor/framey/dist/keyframes-Q6XJO7VW.js +2755 -0
  520. package/vendor/framey/dist/lambda-A7JC74JF.js +468 -0
  521. package/vendor/framey/dist/layout-YET6XNXA.js +95 -0
  522. package/vendor/framey/dist/lint-I7FZN2VJ.js +162 -0
  523. package/vendor/framey/dist/lintProject-PDB3UN72.js +30 -0
  524. package/vendor/framey/dist/manager-CD6LJ7ZN.js +45 -0
  525. package/vendor/framey/dist/manager-WA4F2GST.js +67 -0
  526. package/vendor/framey/dist/media-treatment-BXYS4WVA.js +1030 -0
  527. package/vendor/framey/dist/media-use-LWH3MANK.js +113 -0
  528. package/vendor/framey/dist/models-K363FYM4.js +195 -0
  529. package/vendor/framey/dist/motionShot-GPAVWXLH.js +640 -0
  530. package/vendor/framey/dist/normalize-FASIPBUM.js +24 -0
  531. package/vendor/framey/dist/normalize-audio-VDWYRHN6.js +268 -0
  532. package/vendor/framey/dist/open-E3TB6P6J.js +128 -0
  533. package/vendor/framey/dist/parakeetRunner-UP34UOI2.js +58 -0
  534. package/vendor/framey/dist/pipeline-VXIUYEBU.js +64 -0
  535. package/vendor/framey/dist/play-BUTDQ4DV.js +353 -0
  536. package/vendor/framey/dist/policies-OLDYGFK5.js +309 -0
  537. package/vendor/framey/dist/preflight-2KZ2GWAZ.js +55 -0
  538. package/vendor/framey/dist/present-GXYSM7NX.js +353 -0
  539. package/vendor/framey/dist/preview-EKZ33JOJ.js +1910 -0
  540. package/vendor/framey/dist/producer-SKU5EV3J.js +13 -0
  541. package/vendor/framey/dist/progress-ZWB4Z4ET.js +76 -0
  542. package/vendor/framey/dist/projectConfig-3MZAYVTS.js +60 -0
  543. package/vendor/framey/dist/publication-DTKWNF74.js +33 -0
  544. package/vendor/framey/dist/remove-background-OY5L7XN2.js +265 -0
  545. package/vendor/framey/dist/render-CDV4GDFX.js +187 -0
  546. package/vendor/framey/dist/render-YE5YAMOD.js +2620 -0
  547. package/vendor/framey/dist/render-batch-ZAMFPCLL.js +274 -0
  548. package/vendor/framey/dist/renderSetupWorker.js +120 -0
  549. package/vendor/framey/dist/resolver-D5BIPSEW.js +42 -0
  550. package/vendor/framey/dist/runtimeVersion.js +18 -0
  551. package/vendor/framey/dist/sam-WFZXI4F7.js +23 -0
  552. package/vendor/framey/dist/shaderTransitionWorker.js +44 -0
  553. package/vendor/framey/dist/sherpa-RQWLV7I3.js +79 -0
  554. package/vendor/framey/dist/sherpaWorker.js +84 -0
  555. package/vendor/framey/dist/sites-AMOVABTK.js +54 -0
  556. package/vendor/framey/dist/skill-ZHVLH7KX.js +15 -0
  557. package/vendor/framey/dist/slideshow-SJGK4RQS.js +24 -0
  558. package/vendor/framey/dist/snapshot-TUXL6LBQ.js +1515 -0
  559. package/vendor/framey/dist/src-JHQGB2S6.js +215 -0
  560. package/vendor/framey/dist/src-Z5PGEMXB.js +532 -0
  561. package/vendor/framey/dist/state-B6H3WHCF.js +28 -0
  562. package/vendor/framey/dist/staticProjectServer-DFVZOUGI.js +63 -0
  563. package/vendor/framey/dist/studio/assets/hyperframes-player-DLaKjw0L.js +478 -0
  564. package/vendor/framey/dist/studio/assets/index-BX3KHhGX.js +71 -0
  565. package/vendor/framey/dist/studio/assets/index-CYbvOVp-.css +1 -0
  566. package/vendor/framey/dist/studio/assets/index-Dp3QEUGL.js +402 -0
  567. package/vendor/framey/dist/studio/assets/index-qrTAXbqc.js +531 -0
  568. package/vendor/framey/dist/studio/favicon.svg +14 -0
  569. package/vendor/framey/dist/studio/icons/timeline/audio.svg +7 -0
  570. package/vendor/framey/dist/studio/icons/timeline/captions.svg +5 -0
  571. package/vendor/framey/dist/studio/icons/timeline/composition.svg +12 -0
  572. package/vendor/framey/dist/studio/icons/timeline/image.svg +18 -0
  573. package/vendor/framey/dist/studio/icons/timeline/music.svg +10 -0
  574. package/vendor/framey/dist/studio/icons/timeline/text.svg +3 -0
  575. package/vendor/framey/dist/studio/index.html +23 -0
  576. package/vendor/framey/dist/studio-api-2NECGRMB.js +179 -0
  577. package/vendor/framey/dist/studioSelectionClient-IUUPKUHZ.js +25 -0
  578. package/vendor/framey/dist/studioServer-N2OPUMOQ.js +1569 -0
  579. package/vendor/framey/dist/synthesize-PKTB5ATG.js +183 -0
  580. package/vendor/framey/dist/system-7F3UEHQT.js +27 -0
  581. package/vendor/framey/dist/telemetry-DQGPEKM6.js +145 -0
  582. package/vendor/framey/dist/telemetry-UN55N6U6.js +77 -0
  583. package/vendor/framey/dist/timeline-LHUUMK63.js +1295 -0
  584. package/vendor/framey/dist/tokens-OLECWDFK.js +92 -0
  585. package/vendor/framey/dist/transcribe-O7HQKMIV.js +331 -0
  586. package/vendor/framey/dist/transcribe-UJESPBT5.js +76 -0
  587. package/vendor/framey/dist/tts-YCCQHZD4.js +234 -0
  588. package/vendor/framey/dist/urlDownloader-H2LXLG4U.js +48 -0
  589. package/vendor/framey/dist/usage-HG4WMM7A.js +2167 -0
  590. package/vendor/framey/dist/validate-F2XMN6EV.js +87 -0
  591. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/GSAP-LICENSE.txt +8 -0
  592. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/CustomEase.min.js +11 -0
  593. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/MotionPathPlugin.min.js +11 -0
  594. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/gsap.min.js +11 -0
  595. package/vendor/framey/dist/warmCheck.js +220 -0
  596. package/vendor/framey/dist/warmCheckClient.js +139 -0
  597. package/vendor/framey/dist/workspaceBuildCheck-XYD2YTFW.js +133 -0
  598. package/vendor/framey-player/LICENSE +190 -0
  599. package/vendor/framey-player/NOTICE +16 -0
  600. package/vendor/framey-player/SOURCE.json +6 -0
  601. package/vendor/framey-player/hyperframes-player.global.js +478 -0
  602. package/vendor/framey.pin +1 -0
  603. package/bin/index.js +0 -3
@@ -0,0 +1,519 @@
1
+ <!doctype html>
2
+ <!-- vfrey scene block "oscilloscope-trace": from Framey (HyperFrames by HeyGen, Apache-2.0) registry/blocks/oscilloscope-trace at 9d893096f7df. GSAP loads from the scene's vfrey/ folder; Google Fonts links were removed (the renderer supplies the font). See ../NOTICE. -->
3
+ <html lang="en">
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=1920, height=1080" />
7
+ <title>Oscilloscope Trace</title>
8
+ <script src="../../vfrey/gsap.min.js"></script>
9
+ <style>
10
+ * {
11
+ margin: 0;
12
+ padding: 0;
13
+ box-sizing: border-box;
14
+ }
15
+ html,
16
+ body {
17
+ width: 1920px;
18
+ height: 1080px;
19
+ overflow: hidden;
20
+ background: #05070a;
21
+ }
22
+ #os-root {
23
+ position: relative;
24
+ width: 1920px;
25
+ height: 1080px;
26
+ font-family: "JetBrains Mono", ui-monospace, monospace;
27
+ }
28
+ #os-bg {
29
+ position: absolute;
30
+ inset: 0;
31
+ background: radial-gradient(120% 120% at 30% 25%, #0d141b 0%, #05070a 68%);
32
+ }
33
+ #os-screen {
34
+ position: absolute;
35
+ inset: 0;
36
+ width: 1920px;
37
+ height: 1080px;
38
+ display: block;
39
+ }
40
+ /* Purely decorative CRT falloff — no timing, no motion. */
41
+ #os-vignette {
42
+ position: absolute;
43
+ inset: 0;
44
+ pointer-events: none;
45
+ background: radial-gradient(
46
+ 78% 78% at 34% 50%,
47
+ rgba(0, 0, 0, 0) 55%,
48
+ rgba(0, 0, 0, 0.55) 100%
49
+ );
50
+ }
51
+ #os-readout {
52
+ position: absolute;
53
+ left: 1250px;
54
+ top: 150px;
55
+ width: 520px;
56
+ color: #6f8794;
57
+ font-size: 26px;
58
+ line-height: 1.15;
59
+ letter-spacing: 0.04em;
60
+ }
61
+ #os-readout .os-title {
62
+ color: #b9ccd6;
63
+ font-size: 34px;
64
+ letter-spacing: 0.22em;
65
+ padding-bottom: 26px;
66
+ border-bottom: 2px solid #1d2a33;
67
+ margin-bottom: 26px;
68
+ }
69
+ #os-readout .os-row {
70
+ display: flex;
71
+ justify-content: space-between;
72
+ padding: 13px 0;
73
+ }
74
+ #os-readout .os-val {
75
+ color: #d7e6ee;
76
+ }
77
+ #os-readout .os-note {
78
+ margin-top: 28px;
79
+ font-size: 20px;
80
+ color: #6a7b85;
81
+ line-height: 1.5;
82
+ }
83
+ </style>
84
+ </head>
85
+ <body>
86
+ <div
87
+ id="os-root"
88
+ data-composition-variables='[
89
+ {"id":"waveform","type":"enum","label":"Waveform","default":"sine","options":[{"value":"sine","label":"Sine"},{"value":"square","label":"Square"},{"value":"triangle","label":"Triangle"},{"value":"data","label":"Data series"}]},
90
+ {"id":"frequency","type":"number","label":"Signal frequency","unit":"Hz","default":12,"min":0.1,"max":200,"step":0.1},
91
+ {"id":"amplitude","type":"number","label":"Amplitude","unit":"div","default":3,"min":0.1,"max":4,"step":0.1},
92
+ {"id":"persistenceMs","type":"number","label":"Phosphor persistence (tau)","unit":"ms","default":100,"min":1,"max":1000,"step":1},
93
+ {"id":"phosphorColor","type":"color","label":"Phosphor colour","default":"#5dff8f"},
94
+ {"id":"sweepRate","type":"number","label":"Sweep rate","unit":"sweeps/s","default":5,"min":0.25,"max":60,"step":0.25},
95
+ {"id":"dataSeries","type":"string","label":"Data series (waveform=data)","default":"","placeholder":"0,0.4,0.9,0.3,-0.6,-1,-0.2,0.5"}
96
+ ]'
97
+ data-composition-id="oscilloscope-trace"
98
+ data-start="0"
99
+ data-duration="6"
100
+ data-width="1920"
101
+ data-height="1080"
102
+ >
103
+ <div id="os-bg"></div>
104
+ <canvas
105
+ id="os-screen"
106
+ class="clip"
107
+ width="1920"
108
+ height="1080"
109
+ data-start="0"
110
+ data-duration="6"
111
+ data-track-index="0"
112
+ ></canvas>
113
+ <div id="os-vignette"></div>
114
+ <div id="os-readout" class="clip" data-start="0" data-duration="6" data-track-index="1">
115
+ <div class="os-title">OSCILLOSCOPE</div>
116
+ <div class="os-row"><span>SOURCE</span><span class="os-val" id="os-r-wave">SINE</span></div>
117
+ <div class="os-row"><span>FREQ</span><span class="os-val" id="os-r-freq">-</span></div>
118
+ <div class="os-row"><span>TIMEBASE</span><span class="os-val" id="os-r-time">-</span></div>
119
+ <div class="os-row"><span>VERT</span><span class="os-val" id="os-r-amp">-</span></div>
120
+ <div class="os-row"><span>PHOSPHOR</span><span class="os-val" id="os-r-phos">-</span></div>
121
+ <div class="os-note" id="os-r-note"></div>
122
+ </div>
123
+ </div>
124
+ <script>
125
+ (function () {
126
+ "use strict";
127
+
128
+ // ---------------------------------------------------------------
129
+ // Oscilloscope trace with phosphor persistence.
130
+ //
131
+ // Two pieces of physical truth drive the look:
132
+ //
133
+ // 1. PERSISTENCE. The phosphor keeps emitting after the beam has
134
+ // passed, decaying as exp(-age/tau). Decay constants by EIA
135
+ // phosphor class (research entry F#10):
136
+ // P11/P31 - 0.01-1 ms (what a real bench scope uses: no
137
+ // visible afterglow at video rates)
138
+ // P1 - 80-150 ms (the "vintage glow" look; tau ~= 100 ms
139
+ // is the entry's recommended default)
140
+ // P33 - > 1 s
141
+ // P2/P7 - 30 s .. ~1 min (radar territory, out of range here)
142
+ // The tail window is 3*tau: after three time constants ~5% of the
143
+ // brightness remains, which the entry gives as the safe cutoff.
144
+ //
145
+ // 2. BEAM-VELOCITY BRIGHTNESS. A trace is brighter where the beam
146
+ // moves slower, because the same deposited energy is spread over
147
+ // a shorter path. Each sub-step deposits a fixed amount of energy
148
+ // (constant dt), so surface brightness goes as 1/segment-length.
149
+ // Flat parts of the waveform are bright; fast vertical edges are
150
+ // faint. Qualitative law only - the research entry states it with
151
+ // no proportionality constant, so the reference length below is
152
+ // the physical minimum (pure horizontal sweep motion), not a
153
+ // fudge factor.
154
+ //
155
+ // SWEEP RATE PROVENANCE. The phosphor decay constants above are
156
+ // measured; the sweep rate is NOT - the research entry gives no
157
+ // timebase figure. The default of 5 sweeps/s is authored: across the
158
+ // 10-division graticule it works out to 20 ms/div, a real value from
159
+ // the standard 1-2-5 timebase sequence, picked because it puts a few
160
+ // cycles of the default signal on screen. Treat it as a dial, not as
161
+ // a measurement.
162
+ //
163
+ // NO FEEDBACK BUFFER. The canvas is cleared every frame and the tail
164
+ // is recomputed by evaluating the beam curve backwards in time from
165
+ // the current frame: P(t - k*dt) for k = 0..K. Frame N depends only
166
+ // on N, so seeking anywhere is exact rather than approximate.
167
+ // ---------------------------------------------------------------
168
+
169
+ var COMP_ID = "oscilloscope-trace";
170
+ var DURATION = 6;
171
+
172
+ // Screen geometry: a 10x8 division graticule of SQUARE divisions,
173
+ // the standard CRT scope face.
174
+ var DIV = 100;
175
+ var DIVS_X = 10;
176
+ var DIVS_Y = 8;
177
+ var SW = DIV * DIVS_X;
178
+ var SH = DIV * DIVS_Y;
179
+ var SX = 140;
180
+ var SY = 140;
181
+ var CY = SY + SH / 2;
182
+
183
+ // Tail window in time constants (research entry F#10: 3*tau leaves
184
+ // ~5% weight, stated there as the safe cutoff).
185
+ var TAIL_TAUS = 3;
186
+ // Sub-step count. The entry suggests K ~= 24 steps across the window,
187
+ // which is enough to quantise the DECAY but far too coarse spatially:
188
+ // at 12 Hz the beam would advance 0.15 of a cycle per step and the
189
+ // trace would render as a polygon. So K is derived from how fast the
190
+ // beam actually moves - keep each sub-step under SEG_TARGET_PX of
191
+ // travel. That target and the clamps are MY numbers, not measured
192
+ // ones; the clamp bounds per-frame cost when persistence is long.
193
+ var SEG_TARGET_PX = 3;
194
+ var K_MIN = 120;
195
+ var K_MAX = 8000;
196
+
197
+ // Band-limit for the square wave. A real generator + a real scope
198
+ // front end both have finite bandwidth, so the edge is steep but not
199
+ // instantaneous; a mathematical step would make the vertical edge one
200
+ // sub-step long and the velocity law would erase it entirely.
201
+ var SQUARE_SHARPNESS = 8;
202
+
203
+ function readVariables() {
204
+ var api = window.__hyperframes && window.__hyperframes.getVariables;
205
+ if (typeof api === "function") return api() || {};
206
+ // Standalone fallback (raw file opened without the runtime): read
207
+ // the same declaration the runtime reads, so defaults have exactly
208
+ // one home.
209
+ var out = {};
210
+ try {
211
+ var raw = document.getElementById("os-root").getAttribute("data-composition-variables");
212
+ var decls = JSON.parse(raw || "[]");
213
+ for (var i = 0; i < decls.length; i++) out[decls[i].id] = decls[i].default;
214
+ } catch (err) {
215
+ /* declaration missing or malformed - fall through to hard defaults */
216
+ }
217
+ return out;
218
+ }
219
+
220
+ function num(value, fallback, min, max) {
221
+ var n = typeof value === "number" ? value : parseFloat(value);
222
+ if (!isFinite(n)) n = fallback;
223
+ return Math.min(max, Math.max(min, n));
224
+ }
225
+
226
+ var V = readVariables();
227
+ var waveform =
228
+ ["sine", "square", "triangle", "data"].indexOf(String(V.waveform)) >= 0
229
+ ? String(V.waveform)
230
+ : "sine";
231
+ var frequency = num(V.frequency, 12, 0.1, 200);
232
+ var amplitude = num(V.amplitude, 3, 0.1, 4);
233
+ var tau = num(V.persistenceMs, 100, 1, 1000) / 1000;
234
+ var sweepRate = num(V.sweepRate, 5, 0.25, 60);
235
+ var phosphor = parseColor(V.phosphorColor, [93, 255, 143]);
236
+
237
+ // waveform="data" replays a supplied series instead of a synthetic
238
+ // shape: comma/whitespace separated numbers, clamped to -1..1, linearly
239
+ // interpolated, one full pass of the series per `frequency` cycle.
240
+ // Empty or unparseable -> falls back to sine.
241
+ var series = String(V.dataSeries == null ? "" : V.dataSeries)
242
+ .split(/[\s,]+/)
243
+ .map(parseFloat)
244
+ .filter(function (n) {
245
+ return isFinite(n);
246
+ })
247
+ .map(function (n) {
248
+ return Math.min(1, Math.max(-1, n));
249
+ });
250
+ if (waveform === "data" && series.length < 2) waveform = "sine";
251
+
252
+ function parseColor(value, fallback) {
253
+ var m = /^#?([0-9a-f]{6})$/i.exec(String(value == null ? "" : value).trim());
254
+ if (!m) return fallback;
255
+ var v = parseInt(m[1], 16);
256
+ return [(v >> 16) & 255, (v >> 8) & 255, v & 255];
257
+ }
258
+
259
+ function rgba(c, a) {
260
+ return "rgba(" + c[0] + "," + c[1] + "," + c[2] + "," + a.toFixed(4) + ")";
261
+ }
262
+
263
+ // --- the signal: pure function of time, no state ------------------
264
+
265
+ function wave(t) {
266
+ var p = frequency * t; // cycles elapsed
267
+ if (waveform === "square") {
268
+ return Math.tanh(SQUARE_SHARPNESS * Math.sin(2 * Math.PI * p));
269
+ }
270
+ if (waveform === "triangle") {
271
+ return (2 / Math.PI) * Math.asin(Math.sin(2 * Math.PI * p));
272
+ }
273
+ if (waveform === "data") {
274
+ var frac = p - Math.floor(p);
275
+ var pos = frac * (series.length - 1);
276
+ var i = Math.floor(pos);
277
+ var f = pos - i;
278
+ var a = series[i];
279
+ var b = series[Math.min(series.length - 1, i + 1)];
280
+ return a + (b - a) * f;
281
+ }
282
+ return Math.sin(2 * Math.PI * p);
283
+ }
284
+
285
+ /** Horizontal sweep position, 0..1 across the graticule. */
286
+ function sweepU(t) {
287
+ var s = t * sweepRate;
288
+ return s - Math.floor(s);
289
+ }
290
+
291
+ function beamX(t) {
292
+ return SX + sweepU(t) * SW;
293
+ }
294
+
295
+ function beamY(t) {
296
+ return CY - wave(t) * amplitude * DIV;
297
+ }
298
+
299
+ // Upper bound on beam speed, in px/s, used to pick the sub-step count.
300
+ // Horizontal is the constant sweep; vertical is the waveform's steepest
301
+ // slope, which differs per shape - a band-limited square is
302
+ // SQUARE_SHARPNESS times steeper at its edge than a sine of the same
303
+ // frequency, and under-sampling exactly there is what turns the edge
304
+ // into a polygon.
305
+ var slopeBound;
306
+ if (waveform === "square") {
307
+ slopeBound = SQUARE_SHARPNESS * 2 * Math.PI * frequency;
308
+ } else if (waveform === "triangle") {
309
+ slopeBound = 4 * frequency;
310
+ } else if (waveform === "data") {
311
+ var maxStep = 0;
312
+ for (var si = 1; si < series.length; si++) {
313
+ maxStep = Math.max(maxStep, Math.abs(series[si] - series[si - 1]));
314
+ }
315
+ slopeBound = maxStep * (series.length - 1) * frequency;
316
+ } else {
317
+ slopeBound = 2 * Math.PI * frequency;
318
+ }
319
+ var beamSpeedMax = Math.sqrt(
320
+ Math.pow(SW * sweepRate, 2) + Math.pow(slopeBound * amplitude * DIV, 2),
321
+ );
322
+
323
+ // --- graticule (drawn once to an offscreen canvas) ----------------
324
+
325
+ var grat = document.createElement("canvas");
326
+ grat.width = 1920;
327
+ grat.height = 1080;
328
+ (function drawGraticule() {
329
+ var g = grat.getContext("2d");
330
+ g.fillStyle = "#04080a";
331
+ g.fillRect(SX, SY, SW, SH);
332
+ g.strokeStyle = "rgba(120,180,160,0.16)";
333
+ g.lineWidth = 1;
334
+ for (var i = 1; i < DIVS_X; i++) {
335
+ g.beginPath();
336
+ g.moveTo(SX + i * DIV + 0.5, SY);
337
+ g.lineTo(SX + i * DIV + 0.5, SY + SH);
338
+ g.stroke();
339
+ }
340
+ for (var j = 1; j < DIVS_Y; j++) {
341
+ g.beginPath();
342
+ g.moveTo(SX, SY + j * DIV + 0.5);
343
+ g.lineTo(SX + SW, SY + j * DIV + 0.5);
344
+ g.stroke();
345
+ }
346
+ // Centre axes carry the fine 0.2-division ticks, as on a real face.
347
+ g.strokeStyle = "rgba(150,205,185,0.32)";
348
+ var cx = SX + SW / 2 + 0.5;
349
+ var cy = CY + 0.5;
350
+ g.beginPath();
351
+ g.moveTo(cx, SY);
352
+ g.lineTo(cx, SY + SH);
353
+ g.moveTo(SX, cy);
354
+ g.lineTo(SX + SW, cy);
355
+ g.stroke();
356
+ g.strokeStyle = "rgba(150,205,185,0.42)";
357
+ for (var k = 1; k < DIVS_X * 5; k++) {
358
+ var x = SX + (k * DIV) / 5 + 0.5;
359
+ g.beginPath();
360
+ g.moveTo(x, cy - 9);
361
+ g.lineTo(x, cy + 9);
362
+ g.stroke();
363
+ }
364
+ for (var m = 1; m < DIVS_Y * 5; m++) {
365
+ var y = SY + (m * DIV) / 5 + 0.5;
366
+ g.beginPath();
367
+ g.moveTo(cx - 9, y);
368
+ g.lineTo(cx + 9, y);
369
+ g.stroke();
370
+ }
371
+ g.strokeStyle = "rgba(160,215,195,0.55)";
372
+ g.lineWidth = 2;
373
+ g.strokeRect(SX + 1, SY + 1, SW - 2, SH - 2);
374
+ })();
375
+
376
+ // --- per-frame paint ----------------------------------------------
377
+
378
+ var canvas = document.getElementById("os-screen");
379
+ var ctx = canvas.getContext("2d");
380
+
381
+ function draw(t) {
382
+ ctx.globalCompositeOperation = "source-over";
383
+ ctx.clearRect(0, 0, 1920, 1080);
384
+ ctx.drawImage(grat, 0, 0);
385
+
386
+ var windowS = TAIL_TAUS * tau;
387
+ var K = Math.max(
388
+ K_MIN,
389
+ Math.min(K_MAX, Math.round((windowS * beamSpeedMax) / SEG_TARGET_PX)),
390
+ );
391
+ var dt = windowS / K;
392
+ // Length the beam covers in one sub-step with zero vertical motion.
393
+ // That is the slowest the beam can ever move, so it is the maximum
394
+ // brightness reference and the velocity weight never exceeds 1.
395
+ var lRef = SW * sweepRate * dt;
396
+
397
+ ctx.globalCompositeOperation = "lighter";
398
+ ctx.lineCap = "round";
399
+
400
+ // Oldest -> newest, so the bright head lands on top.
401
+ var prevX = 0;
402
+ var prevY = 0;
403
+ var prevU = 0;
404
+ var havePrev = false;
405
+ for (var k = K; k >= 0; k--) {
406
+ var tk = t - k * dt;
407
+ if (tk < 0) {
408
+ // Before frame 0 the beam had not been switched on yet.
409
+ havePrev = false;
410
+ continue;
411
+ }
412
+ var u = sweepU(tk);
413
+ var x = SX + u * SW;
414
+ var y = beamY(tk);
415
+ if (havePrev && u >= prevU) {
416
+ var dx = x - prevX;
417
+ var dy = y - prevY;
418
+ var len = Math.sqrt(dx * dx + dy * dy);
419
+ // Beam-velocity law: brightness ~ 1 / path length per unit time.
420
+ var vel = len > 1e-6 ? Math.min(1, lRef / len) : 1;
421
+ var decay = Math.exp((-k * dt) / tau);
422
+ var a = decay * vel;
423
+ if (a > 0.002) {
424
+ ctx.beginPath();
425
+ ctx.moveTo(prevX, prevY);
426
+ ctx.lineTo(x, y);
427
+ ctx.strokeStyle = rgba(phosphor, a * 0.13);
428
+ ctx.lineWidth = 13;
429
+ ctx.stroke();
430
+ ctx.strokeStyle = rgba(phosphor, a * 0.9);
431
+ ctx.lineWidth = 3;
432
+ ctx.stroke();
433
+ if (a > 0.55) {
434
+ // Overdriven phosphor saturates towards white at the head.
435
+ ctx.strokeStyle =
436
+ "rgba(255,255,255," + (((a - 0.55) / 0.45) * 0.7).toFixed(4) + ")";
437
+ ctx.lineWidth = 1.4;
438
+ ctx.stroke();
439
+ }
440
+ }
441
+ }
442
+ // Retrace is blanked on a real scope: when u wraps, drop the
443
+ // connecting segment instead of drawing a line back across.
444
+ prevX = x;
445
+ prevY = y;
446
+ prevU = u;
447
+ havePrev = true;
448
+ }
449
+
450
+ // Beam head: the spot itself, brightest point on the screen.
451
+ var hx = beamX(t);
452
+ var hy = beamY(t);
453
+ var glow = ctx.createRadialGradient(hx, hy, 0, hx, hy, 22);
454
+ glow.addColorStop(0, "rgba(255,255,255,0.95)");
455
+ glow.addColorStop(0.22, rgba(phosphor, 0.85));
456
+ glow.addColorStop(1, rgba(phosphor, 0));
457
+ ctx.fillStyle = glow;
458
+ ctx.beginPath();
459
+ ctx.arc(hx, hy, 22, 0, Math.PI * 2);
460
+ ctx.fill();
461
+
462
+ ctx.globalCompositeOperation = "source-over";
463
+ }
464
+
465
+ // --- readout --------------------------------------------------------
466
+
467
+ (function fillReadout() {
468
+ // Nearest EIA phosphor class for the chosen tau (bands from the
469
+ // research entry). Labelling, not simulation.
470
+ var tauMs = tau * 1000;
471
+ var cls = tauMs <= 1 ? "P31" : tauMs <= 150 ? "P1" : "P33";
472
+ var msPerDiv = 1000 / (sweepRate * DIVS_X);
473
+ function set(id, text) {
474
+ document.getElementById(id).textContent = text;
475
+ }
476
+ set("os-r-wave", waveform.toUpperCase());
477
+ set("os-r-freq", frequency.toFixed(frequency < 10 ? 2 : 1) + " Hz");
478
+ set(
479
+ "os-r-time",
480
+ (msPerDiv >= 10 ? msPerDiv.toFixed(0) : msPerDiv.toFixed(2)) + " ms/div",
481
+ );
482
+ set("os-r-amp", amplitude.toFixed(1) + " div pk");
483
+ set("os-r-phos", cls + " tau " + tauMs.toFixed(0) + " ms");
484
+ set(
485
+ "os-r-note",
486
+ "Trace brightness falls as exp(-age/tau) behind the beam, and rises where the beam slows.",
487
+ );
488
+ })();
489
+
490
+ // --- timeline -------------------------------------------------------
491
+ //
492
+ // tl.eventCallback("onUpdate", ...) is NOT usable here: the runtime
493
+ // seeks with suppressEvents, so the callback never fires on a seek and
494
+ // the canvas would keep whatever the last played frame drew. A tweened
495
+ // property with an accessor is applied by GSAP on every render,
496
+ // including suppressed ones, so the repaint is driven from the setter.
497
+
498
+ var beam = { t: 0 };
499
+ var driver = {};
500
+ Object.defineProperty(driver, "t", {
501
+ get: function () {
502
+ return beam.t;
503
+ },
504
+ set: function (value) {
505
+ beam.t = value;
506
+ draw(value);
507
+ },
508
+ });
509
+
510
+ window.__timelines = window.__timelines || {};
511
+ var tl = gsap.timeline({ paused: true });
512
+ tl.to(driver, { t: DURATION, duration: DURATION, ease: "none", lazy: false }, 0);
513
+ window.__timelines[COMP_ID] = tl;
514
+
515
+ draw(0);
516
+ })();
517
+ </script>
518
+ </body>
519
+ </html>