@thunderclap-engine/engine 0.0.0-stage → 1.1.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 (566) hide show
  1. package/CHANGELOG.md +390 -0
  2. package/LICENSE +21 -0
  3. package/README.md +333 -2
  4. package/dist/analytics/analytics.d.ts +80 -0
  5. package/dist/analytics/analytics.js +129 -0
  6. package/dist/analytics/index.d.ts +1 -0
  7. package/dist/analytics/index.js +1 -0
  8. package/dist/anim/aim.d.ts +43 -0
  9. package/dist/anim/aim.js +157 -0
  10. package/dist/anim/clip.d.ts +98 -0
  11. package/dist/anim/clip.js +282 -0
  12. package/dist/anim/compress.d.ts +65 -0
  13. package/dist/anim/compress.js +339 -0
  14. package/dist/anim/foot-ik.d.ts +74 -0
  15. package/dist/anim/foot-ik.js +241 -0
  16. package/dist/anim/graph.d.ts +153 -0
  17. package/dist/anim/graph.js +532 -0
  18. package/dist/anim/ik.d.ts +105 -0
  19. package/dist/anim/ik.js +435 -0
  20. package/dist/anim/index.d.ts +36 -0
  21. package/dist/anim/index.js +21 -0
  22. package/dist/anim/match.d.ts +66 -0
  23. package/dist/anim/match.js +153 -0
  24. package/dist/anim/mixer.d.ts +113 -0
  25. package/dist/anim/mixer.js +314 -0
  26. package/dist/anim/morph.d.ts +41 -0
  27. package/dist/anim/morph.js +94 -0
  28. package/dist/anim/pose.d.ts +74 -0
  29. package/dist/anim/pose.js +254 -0
  30. package/dist/anim/quat.d.ts +44 -0
  31. package/dist/anim/quat.js +187 -0
  32. package/dist/anim/retarget.d.ts +97 -0
  33. package/dist/anim/retarget.js +366 -0
  34. package/dist/anim/root-motion.d.ts +44 -0
  35. package/dist/anim/root-motion.js +224 -0
  36. package/dist/anim/skin-pose.d.ts +39 -0
  37. package/dist/anim/skin-pose.js +53 -0
  38. package/dist/anim/socket.d.ts +47 -0
  39. package/dist/anim/socket.js +84 -0
  40. package/dist/anim/spring-chain.d.ts +73 -0
  41. package/dist/anim/spring-chain.js +294 -0
  42. package/dist/assets/atlas.d.ts +90 -0
  43. package/dist/assets/atlas.js +212 -0
  44. package/dist/assets/baked.d.ts +33 -0
  45. package/dist/assets/baked.js +38 -0
  46. package/dist/assets/bundle.d.ts +88 -0
  47. package/dist/assets/bundle.js +464 -0
  48. package/dist/assets/cache.d.ts +56 -0
  49. package/dist/assets/cache.js +123 -0
  50. package/dist/assets/gltf-load.d.ts +252 -0
  51. package/dist/assets/gltf-load.js +661 -0
  52. package/dist/assets/gltf-skin.d.ts +36 -0
  53. package/dist/assets/gltf-skin.js +109 -0
  54. package/dist/assets/gltf.d.ts +706 -0
  55. package/dist/assets/gltf.js +1376 -0
  56. package/dist/assets/index.d.ts +20 -0
  57. package/dist/assets/index.js +10 -0
  58. package/dist/assets/ktx2.d.ts +71 -0
  59. package/dist/assets/ktx2.js +213 -0
  60. package/dist/assets/manifest.d.ts +79 -0
  61. package/dist/assets/manifest.js +7 -0
  62. package/dist/assets/meshopt.d.ts +23 -0
  63. package/dist/assets/meshopt.js +403 -0
  64. package/dist/audio/audio.d.ts +733 -0
  65. package/dist/audio/audio.js +2013 -0
  66. package/dist/audio/dsp.d.ts +61 -0
  67. package/dist/audio/dsp.js +159 -0
  68. package/dist/audio/duck.d.ts +44 -0
  69. package/dist/audio/duck.js +101 -0
  70. package/dist/audio/envelope.d.ts +53 -0
  71. package/dist/audio/envelope.js +106 -0
  72. package/dist/audio/index.d.ts +13 -0
  73. package/dist/audio/index.js +14 -0
  74. package/dist/audio/music.d.ts +113 -0
  75. package/dist/audio/music.js +548 -0
  76. package/dist/audio/occlusion.d.ts +55 -0
  77. package/dist/audio/occlusion.js +61 -0
  78. package/dist/audio/persist.d.ts +23 -0
  79. package/dist/audio/persist.js +27 -0
  80. package/dist/audio/recipes.d.ts +55 -0
  81. package/dist/audio/recipes.js +227 -0
  82. package/dist/audio/send.d.ts +41 -0
  83. package/dist/audio/send.js +118 -0
  84. package/dist/audio/sprites.d.ts +59 -0
  85. package/dist/audio/sprites.js +43 -0
  86. package/dist/audio/synth.d.ts +103 -0
  87. package/dist/audio/synth.js +197 -0
  88. package/dist/audio/variations.d.ts +25 -0
  89. package/dist/audio/variations.js +55 -0
  90. package/dist/audio/zones.d.ts +100 -0
  91. package/dist/audio/zones.js +167 -0
  92. package/dist/core/detached-surface.d.ts +44 -0
  93. package/dist/core/detached-surface.js +104 -0
  94. package/dist/core/events.d.ts +24 -0
  95. package/dist/core/events.js +43 -0
  96. package/dist/core/game.d.ts +409 -0
  97. package/dist/core/game.js +530 -0
  98. package/dist/core/hash.d.ts +24 -0
  99. package/dist/core/hash.js +49 -0
  100. package/dist/core/index.d.ts +17 -0
  101. package/dist/core/index.js +9 -0
  102. package/dist/core/loop.d.ts +113 -0
  103. package/dist/core/loop.js +185 -0
  104. package/dist/core/math.d.ts +58 -0
  105. package/dist/core/math.js +210 -0
  106. package/dist/core/noise.d.ts +40 -0
  107. package/dist/core/noise.js +247 -0
  108. package/dist/core/pool.d.ts +42 -0
  109. package/dist/core/pool.js +85 -0
  110. package/dist/core/random.d.ts +61 -0
  111. package/dist/core/random.js +199 -0
  112. package/dist/core/scene.d.ts +79 -0
  113. package/dist/core/scene.js +195 -0
  114. package/dist/core/timer.d.ts +66 -0
  115. package/dist/core/timer.js +286 -0
  116. package/dist/fx/billboard-wgsl.d.ts +29 -0
  117. package/dist/fx/billboard-wgsl.js +158 -0
  118. package/dist/fx/billboard.d.ts +249 -0
  119. package/dist/fx/billboard.js +702 -0
  120. package/dist/fx/debug-draw.d.ts +127 -0
  121. package/dist/fx/debug-draw.js +523 -0
  122. package/dist/fx/debug-wgsl.d.ts +7 -0
  123. package/dist/fx/debug-wgsl.js +32 -0
  124. package/dist/fx/decals-wgsl.d.ts +15 -0
  125. package/dist/fx/decals-wgsl.js +173 -0
  126. package/dist/fx/decals.d.ts +216 -0
  127. package/dist/fx/decals.js +607 -0
  128. package/dist/fx/effect.d.ts +129 -0
  129. package/dist/fx/effect.js +349 -0
  130. package/dist/fx/effects/hit-spark.json +48 -0
  131. package/dist/fx/effects/index.d.ts +8 -0
  132. package/dist/fx/effects/index.js +9 -0
  133. package/dist/fx/effects/magic-aura.json +47 -0
  134. package/dist/fx/effects/smoke-puff.json +34 -0
  135. package/dist/fx/emit-surface.d.ts +40 -0
  136. package/dist/fx/emit-surface.js +124 -0
  137. package/dist/fx/flicker.d.ts +30 -0
  138. package/dist/fx/flicker.js +42 -0
  139. package/dist/fx/index.d.ts +31 -0
  140. package/dist/fx/index.js +20 -0
  141. package/dist/fx/particles-wgsl.d.ts +57 -0
  142. package/dist/fx/particles-wgsl.js +828 -0
  143. package/dist/fx/particles.d.ts +566 -0
  144. package/dist/fx/particles.js +1533 -0
  145. package/dist/fx/random.d.ts +15 -0
  146. package/dist/fx/random.js +20 -0
  147. package/dist/fx/sky-wgsl.d.ts +23 -0
  148. package/dist/fx/sky-wgsl.js +127 -0
  149. package/dist/fx/sky.d.ts +96 -0
  150. package/dist/fx/sky.js +175 -0
  151. package/dist/fx/text-atlas.d.ts +143 -0
  152. package/dist/fx/text-atlas.js +327 -0
  153. package/dist/fx/trail-wgsl.d.ts +11 -0
  154. package/dist/fx/trail-wgsl.js +42 -0
  155. package/dist/fx/trail.d.ts +194 -0
  156. package/dist/fx/trail.js +555 -0
  157. package/dist/fx/water-wgsl.d.ts +34 -0
  158. package/dist/fx/water-wgsl.js +197 -0
  159. package/dist/fx/water.d.ts +176 -0
  160. package/dist/fx/water.js +371 -0
  161. package/dist/geom/collide/bvh.d.ts +151 -0
  162. package/dist/geom/collide/bvh.js +493 -0
  163. package/dist/geom/collide/debug.d.ts +14 -0
  164. package/dist/geom/collide/debug.js +74 -0
  165. package/dist/geom/collide/grid.d.ts +26 -0
  166. package/dist/geom/collide/grid.js +91 -0
  167. package/dist/geom/collide/index.d.ts +8 -0
  168. package/dist/geom/collide/index.js +8 -0
  169. package/dist/geom/collide/queries.d.ts +70 -0
  170. package/dist/geom/collide/queries.js +583 -0
  171. package/dist/geom/collide/serialize.d.ts +14 -0
  172. package/dist/geom/collide/serialize.js +145 -0
  173. package/dist/geom/collide/shapes.d.ts +161 -0
  174. package/dist/geom/collide/shapes.js +686 -0
  175. package/dist/geom/collide/slide.d.ts +66 -0
  176. package/dist/geom/collide/slide.js +375 -0
  177. package/dist/geom/collide/tile-slide.d.ts +88 -0
  178. package/dist/geom/collide/tile-slide.js +255 -0
  179. package/dist/geom/geometry.d.ts +95 -0
  180. package/dist/geom/geometry.js +322 -0
  181. package/dist/geom/heightfield.d.ts +72 -0
  182. package/dist/geom/heightfield.js +295 -0
  183. package/dist/geom/hull.d.ts +27 -0
  184. package/dist/geom/hull.js +279 -0
  185. package/dist/geom/index.d.ts +35 -0
  186. package/dist/geom/index.js +23 -0
  187. package/dist/geom/iso.d.ts +74 -0
  188. package/dist/geom/iso.js +89 -0
  189. package/dist/geom/lod.d.ts +29 -0
  190. package/dist/geom/lod.js +27 -0
  191. package/dist/geom/ops.d.ts +47 -0
  192. package/dist/geom/ops.js +285 -0
  193. package/dist/geom/primitives.d.ts +97 -0
  194. package/dist/geom/primitives.js +359 -0
  195. package/dist/geom/shapes.d.ts +43 -0
  196. package/dist/geom/shapes.js +88 -0
  197. package/dist/geom/simplify.d.ts +38 -0
  198. package/dist/geom/simplify.js +519 -0
  199. package/dist/geom/split.d.ts +37 -0
  200. package/dist/geom/split.js +413 -0
  201. package/dist/geom/sweep.d.ts +83 -0
  202. package/dist/geom/sweep.js +534 -0
  203. package/dist/geom/tangents.d.ts +16 -0
  204. package/dist/geom/tangents.js +124 -0
  205. package/dist/geom/triangulate.d.ts +19 -0
  206. package/dist/geom/triangulate.js +147 -0
  207. package/dist/host/default.d.ts +10 -0
  208. package/dist/host/default.js +10 -0
  209. package/dist/host/index.d.ts +4 -0
  210. package/dist/host/index.js +3 -0
  211. package/dist/host/types.d.ts +144 -0
  212. package/dist/host/types.js +1 -0
  213. package/dist/host/web-links.d.ts +38 -0
  214. package/dist/host/web-links.js +110 -0
  215. package/dist/host/web.d.ts +30 -0
  216. package/dist/host/web.js +216 -0
  217. package/dist/host/xr.d.ts +24 -0
  218. package/dist/host/xr.js +59 -0
  219. package/dist/i18n/i18n.d.ts +59 -0
  220. package/dist/i18n/i18n.js +241 -0
  221. package/dist/i18n/index.d.ts +3 -0
  222. package/dist/i18n/index.js +3 -0
  223. package/dist/i18n/message.d.ts +72 -0
  224. package/dist/i18n/message.js +369 -0
  225. package/dist/i18n/negotiate.d.ts +17 -0
  226. package/dist/i18n/negotiate.js +58 -0
  227. package/dist/index.d.ts +7 -0
  228. package/dist/index.js +1 -0
  229. package/dist/input/bindings.d.ts +31 -0
  230. package/dist/input/bindings.js +141 -0
  231. package/dist/input/clock.d.ts +44 -0
  232. package/dist/input/clock.js +49 -0
  233. package/dist/input/follow.d.ts +133 -0
  234. package/dist/input/follow.js +218 -0
  235. package/dist/input/gestures.d.ts +281 -0
  236. package/dist/input/gestures.js +662 -0
  237. package/dist/input/glyphs.d.ts +35 -0
  238. package/dist/input/glyphs.js +216 -0
  239. package/dist/input/gyro.d.ts +85 -0
  240. package/dist/input/gyro.js +140 -0
  241. package/dist/input/index.d.ts +19 -0
  242. package/dist/input/index.js +16 -0
  243. package/dist/input/input.d.ts +543 -0
  244. package/dist/input/input.js +1492 -0
  245. package/dist/input/look.d.ts +327 -0
  246. package/dist/input/look.js +681 -0
  247. package/dist/input/magnify.d.ts +177 -0
  248. package/dist/input/magnify.js +131 -0
  249. package/dist/input/pointer-dispatch.d.ts +138 -0
  250. package/dist/input/pointer-dispatch.js +180 -0
  251. package/dist/input/pointer-router.d.ts +204 -0
  252. package/dist/input/pointer-router.js +533 -0
  253. package/dist/input/pointer-sources.d.ts +164 -0
  254. package/dist/input/pointer-sources.js +306 -0
  255. package/dist/input/rays.d.ts +138 -0
  256. package/dist/input/rays.js +615 -0
  257. package/dist/input/record.d.ts +209 -0
  258. package/dist/input/record.js +601 -0
  259. package/dist/input/touch-zones.d.ts +147 -0
  260. package/dist/input/touch-zones.js +300 -0
  261. package/dist/input/types.d.ts +158 -0
  262. package/dist/input/types.js +1 -0
  263. package/dist/input/xr-source.d.ts +53 -0
  264. package/dist/input/xr-source.js +164 -0
  265. package/dist/nav/astar.d.ts +45 -0
  266. package/dist/nav/astar.js +182 -0
  267. package/dist/nav/corridor.d.ts +40 -0
  268. package/dist/nav/corridor.js +95 -0
  269. package/dist/nav/crowd.d.ts +94 -0
  270. package/dist/nav/crowd.js +624 -0
  271. package/dist/nav/flow.d.ts +61 -0
  272. package/dist/nav/flow.js +193 -0
  273. package/dist/nav/grid.d.ts +108 -0
  274. package/dist/nav/grid.js +210 -0
  275. package/dist/nav/heap.d.ts +22 -0
  276. package/dist/nav/heap.js +92 -0
  277. package/dist/nav/index.d.ts +37 -0
  278. package/dist/nav/index.js +19 -0
  279. package/dist/nav/mesh/areas.d.ts +44 -0
  280. package/dist/nav/mesh/areas.js +98 -0
  281. package/dist/nav/mesh/bake-options.d.ts +33 -0
  282. package/dist/nav/mesh/bake-options.js +76 -0
  283. package/dist/nav/mesh/contour.d.ts +22 -0
  284. package/dist/nav/mesh/contour.js +323 -0
  285. package/dist/nav/mesh/flow3.d.ts +35 -0
  286. package/dist/nav/mesh/flow3.js +229 -0
  287. package/dist/nav/mesh/links.d.ts +38 -0
  288. package/dist/nav/mesh/links.js +72 -0
  289. package/dist/nav/mesh/mesh-path.d.ts +152 -0
  290. package/dist/nav/mesh/mesh-path.js +643 -0
  291. package/dist/nav/mesh/mesh-reach.d.ts +78 -0
  292. package/dist/nav/mesh/mesh-reach.js +450 -0
  293. package/dist/nav/mesh/navmesh.d.ts +117 -0
  294. package/dist/nav/mesh/navmesh.js +647 -0
  295. package/dist/nav/mesh/polymesh.d.ts +24 -0
  296. package/dist/nav/mesh/polymesh.js +384 -0
  297. package/dist/nav/mesh/regions.d.ts +12 -0
  298. package/dist/nav/mesh/regions.js +367 -0
  299. package/dist/nav/mesh/serialize.d.ts +13 -0
  300. package/dist/nav/mesh/serialize.js +197 -0
  301. package/dist/nav/mesh/voxelize.d.ts +111 -0
  302. package/dist/nav/mesh/voxelize.js +552 -0
  303. package/dist/nav/obstacles.d.ts +75 -0
  304. package/dist/nav/obstacles.js +294 -0
  305. package/dist/nav/path.d.ts +59 -0
  306. package/dist/nav/path.js +177 -0
  307. package/dist/nav/query-queue.d.ts +46 -0
  308. package/dist/nav/query-queue.js +308 -0
  309. package/dist/nav/reach.d.ts +53 -0
  310. package/dist/nav/reach.js +148 -0
  311. package/dist/nav/steer.d.ts +36 -0
  312. package/dist/nav/steer.js +78 -0
  313. package/dist/platform/boot.d.ts +28 -0
  314. package/dist/platform/boot.js +43 -0
  315. package/dist/platform/device-mode.d.ts +40 -0
  316. package/dist/platform/device-mode.js +104 -0
  317. package/dist/platform/device.d.ts +31 -0
  318. package/dist/platform/device.js +91 -0
  319. package/dist/platform/environment.d.ts +42 -0
  320. package/dist/platform/environment.js +82 -0
  321. package/dist/platform/gpu.d.ts +40 -0
  322. package/dist/platform/gpu.js +57 -0
  323. package/dist/platform/index.d.ts +18 -0
  324. package/dist/platform/index.js +10 -0
  325. package/dist/platform/letterbox.d.ts +43 -0
  326. package/dist/platform/letterbox.js +57 -0
  327. package/dist/platform/links.d.ts +20 -0
  328. package/dist/platform/links.js +43 -0
  329. package/dist/platform/screens.d.ts +36 -0
  330. package/dist/platform/screens.js +138 -0
  331. package/dist/platform/surface.d.ts +72 -0
  332. package/dist/platform/surface.js +157 -0
  333. package/dist/platform/xr-fake.d.ts +168 -0
  334. package/dist/platform/xr-fake.js +434 -0
  335. package/dist/platform/xr-surface.d.ts +120 -0
  336. package/dist/platform/xr-surface.js +214 -0
  337. package/dist/platform/xr-types.d.ts +262 -0
  338. package/dist/post/ao.d.ts +12 -0
  339. package/dist/post/ao.js +136 -0
  340. package/dist/post/blend.d.ts +27 -0
  341. package/dist/post/blend.js +129 -0
  342. package/dist/post/depth-pass.d.ts +43 -0
  343. package/dist/post/depth-pass.js +118 -0
  344. package/dist/post/dof.d.ts +1 -0
  345. package/dist/post/dof.js +66 -0
  346. package/dist/post/exposure.d.ts +80 -0
  347. package/dist/post/exposure.js +322 -0
  348. package/dist/post/index.d.ts +12 -0
  349. package/dist/post/index.js +11 -0
  350. package/dist/post/lens-dirt.d.ts +13 -0
  351. package/dist/post/lens-dirt.js +91 -0
  352. package/dist/post/lut.d.ts +19 -0
  353. package/dist/post/lut.js +50 -0
  354. package/dist/post/motion-blur.d.ts +9 -0
  355. package/dist/post/motion-blur.js +78 -0
  356. package/dist/post/post-stack.d.ts +302 -0
  357. package/dist/post/post-stack.js +1137 -0
  358. package/dist/post/settings.d.ts +485 -0
  359. package/dist/post/settings.js +416 -0
  360. package/dist/post/shaders.d.ts +25 -0
  361. package/dist/post/shaders.js +410 -0
  362. package/dist/post/ssr.d.ts +16 -0
  363. package/dist/post/ssr.js +155 -0
  364. package/dist/post/taa.d.ts +74 -0
  365. package/dist/post/taa.js +235 -0
  366. package/dist/post/white-balance.d.ts +25 -0
  367. package/dist/post/white-balance.js +98 -0
  368. package/dist/render/bindings.d.ts +98 -0
  369. package/dist/render/bindings.js +281 -0
  370. package/dist/render/blend.d.ts +13 -0
  371. package/dist/render/blend.js +26 -0
  372. package/dist/render/camera-2d.d.ts +72 -0
  373. package/dist/render/camera-2d.js +92 -0
  374. package/dist/render/camera.d.ts +302 -0
  375. package/dist/render/camera.js +671 -0
  376. package/dist/render/color.d.ts +16 -0
  377. package/dist/render/color.js +41 -0
  378. package/dist/render/compressed.d.ts +104 -0
  379. package/dist/render/compressed.js +248 -0
  380. package/dist/render/diagnostics.d.ts +15 -0
  381. package/dist/render/diagnostics.js +43 -0
  382. package/dist/render/dynamic-resolution.d.ts +70 -0
  383. package/dist/render/dynamic-resolution.js +126 -0
  384. package/dist/render/fake-gpu.d.ts +204 -0
  385. package/dist/render/fake-gpu.js +426 -0
  386. package/dist/render/flipbook.d.ts +56 -0
  387. package/dist/render/flipbook.js +87 -0
  388. package/dist/render/frame.d.ts +278 -0
  389. package/dist/render/frame.js +174 -0
  390. package/dist/render/fullscreen.d.ts +54 -0
  391. package/dist/render/fullscreen.js +91 -0
  392. package/dist/render/gpu-timer.d.ts +73 -0
  393. package/dist/render/gpu-timer.js +186 -0
  394. package/dist/render/index.d.ts +53 -0
  395. package/dist/render/index.js +29 -0
  396. package/dist/render/instance-list.d.ts +185 -0
  397. package/dist/render/instance-list.js +547 -0
  398. package/dist/render/lights.d.ts +181 -0
  399. package/dist/render/lights.js +233 -0
  400. package/dist/render/lod.d.ts +54 -0
  401. package/dist/render/lod.js +52 -0
  402. package/dist/render/material.d.ts +165 -0
  403. package/dist/render/material.js +292 -0
  404. package/dist/render/mesh.d.ts +284 -0
  405. package/dist/render/mesh.js +472 -0
  406. package/dist/render/mipmap.d.ts +16 -0
  407. package/dist/render/mipmap.js +121 -0
  408. package/dist/render/parallax.d.ts +50 -0
  409. package/dist/render/parallax.js +47 -0
  410. package/dist/render/pbr-wgsl.d.ts +31 -0
  411. package/dist/render/pbr-wgsl.js +119 -0
  412. package/dist/render/ping-pong.d.ts +42 -0
  413. package/dist/render/ping-pong.js +74 -0
  414. package/dist/render/renderer.d.ts +741 -0
  415. package/dist/render/renderer.js +2486 -0
  416. package/dist/render/scene-pipelines.d.ts +44 -0
  417. package/dist/render/scene-pipelines.js +92 -0
  418. package/dist/render/scene-target.d.ts +170 -0
  419. package/dist/render/scene-target.js +450 -0
  420. package/dist/render/shadow.d.ts +74 -0
  421. package/dist/render/shadow.js +208 -0
  422. package/dist/render/skin.d.ts +112 -0
  423. package/dist/render/skin.js +240 -0
  424. package/dist/render/snapshot.d.ts +36 -0
  425. package/dist/render/snapshot.js +34 -0
  426. package/dist/render/standard.d.ts +162 -0
  427. package/dist/render/standard.js +263 -0
  428. package/dist/render/texture.d.ts +142 -0
  429. package/dist/render/texture.js +228 -0
  430. package/dist/render/tile-layer.d.ts +110 -0
  431. package/dist/render/tile-layer.js +304 -0
  432. package/dist/render/transform.d.ts +115 -0
  433. package/dist/render/transform.js +318 -0
  434. package/dist/render/wgsl.d.ts +131 -0
  435. package/dist/render/wgsl.js +528 -0
  436. package/dist/save/codec.d.ts +49 -0
  437. package/dist/save/codec.js +169 -0
  438. package/dist/save/index.d.ts +8 -0
  439. package/dist/save/index.js +8 -0
  440. package/dist/save/journal.d.ts +24 -0
  441. package/dist/save/journal.js +102 -0
  442. package/dist/save/migrate.d.ts +15 -0
  443. package/dist/save/migrate.js +37 -0
  444. package/dist/save/schema.d.ts +72 -0
  445. package/dist/save/schema.js +154 -0
  446. package/dist/save/settings.d.ts +28 -0
  447. package/dist/save/settings.js +59 -0
  448. package/dist/save/slots.d.ts +56 -0
  449. package/dist/save/slots.js +200 -0
  450. package/dist/save/storage.d.ts +35 -0
  451. package/dist/save/storage.js +62 -0
  452. package/dist/save/store.d.ts +114 -0
  453. package/dist/save/store.js +269 -0
  454. package/dist/testing/fake-host.d.ts +103 -0
  455. package/dist/testing/fake-host.js +163 -0
  456. package/dist/testing/fixed-clock.d.ts +25 -0
  457. package/dist/testing/fixed-clock.js +30 -0
  458. package/dist/testing/index.d.ts +4 -0
  459. package/dist/testing/index.js +5 -0
  460. package/dist/testing/test-game.d.ts +76 -0
  461. package/dist/testing/test-game.js +92 -0
  462. package/dist/tween/ease.d.ts +77 -0
  463. package/dist/tween/ease.js +192 -0
  464. package/dist/tween/index.d.ts +8 -0
  465. package/dist/tween/index.js +7 -0
  466. package/dist/tween/timeline.d.ts +78 -0
  467. package/dist/tween/timeline.js +269 -0
  468. package/dist/tween/tween.d.ts +168 -0
  469. package/dist/tween/tween.js +320 -0
  470. package/dist/ui/anchor.d.ts +206 -0
  471. package/dist/ui/anchor.js +307 -0
  472. package/dist/ui/caption.d.ts +122 -0
  473. package/dist/ui/caption.js +286 -0
  474. package/dist/ui/cursor.d.ts +105 -0
  475. package/dist/ui/cursor.js +261 -0
  476. package/dist/ui/dom.d.ts +30 -0
  477. package/dist/ui/dom.js +92 -0
  478. package/dist/ui/floats.d.ts +86 -0
  479. package/dist/ui/floats.js +260 -0
  480. package/dist/ui/hud.d.ts +198 -0
  481. package/dist/ui/hud.js +431 -0
  482. package/dist/ui/index.d.ts +37 -0
  483. package/dist/ui/index.js +34 -0
  484. package/dist/ui/inventory-card.d.ts +52 -0
  485. package/dist/ui/inventory-card.js +173 -0
  486. package/dist/ui/inventory-context.d.ts +29 -0
  487. package/dist/ui/inventory-context.js +125 -0
  488. package/dist/ui/inventory-drag.d.ts +63 -0
  489. package/dist/ui/inventory-drag.js +394 -0
  490. package/dist/ui/inventory-grid.d.ts +66 -0
  491. package/dist/ui/inventory-grid.js +625 -0
  492. package/dist/ui/inventory-radial.d.ts +39 -0
  493. package/dist/ui/inventory-radial.js +168 -0
  494. package/dist/ui/inventory.d.ts +128 -0
  495. package/dist/ui/inventory.js +154 -0
  496. package/dist/ui/layout.d.ts +356 -0
  497. package/dist/ui/layout.js +856 -0
  498. package/dist/ui/link.d.ts +64 -0
  499. package/dist/ui/link.js +155 -0
  500. package/dist/ui/loading.d.ts +40 -0
  501. package/dist/ui/loading.js +157 -0
  502. package/dist/ui/loupe.d.ts +74 -0
  503. package/dist/ui/loupe.js +164 -0
  504. package/dist/ui/menu-nav.d.ts +33 -0
  505. package/dist/ui/menu-nav.js +28 -0
  506. package/dist/ui/minimap-canvas.d.ts +145 -0
  507. package/dist/ui/minimap-canvas.js +460 -0
  508. package/dist/ui/notify.d.ts +40 -0
  509. package/dist/ui/notify.js +141 -0
  510. package/dist/ui/orb.d.ts +53 -0
  511. package/dist/ui/orb.js +304 -0
  512. package/dist/ui/overlay.d.ts +213 -0
  513. package/dist/ui/overlay.js +394 -0
  514. package/dist/ui/padnav.d.ts +53 -0
  515. package/dist/ui/padnav.js +146 -0
  516. package/dist/ui/perf.d.ts +130 -0
  517. package/dist/ui/perf.js +329 -0
  518. package/dist/ui/rotate-card.d.ts +54 -0
  519. package/dist/ui/rotate-card.js +97 -0
  520. package/dist/ui/stack.d.ts +128 -0
  521. package/dist/ui/stack.js +312 -0
  522. package/dist/ui/styles.d.ts +13 -0
  523. package/dist/ui/styles.js +200 -0
  524. package/dist/ui/text-scale.d.ts +67 -0
  525. package/dist/ui/text-scale.js +102 -0
  526. package/dist/ui/theme.d.ts +70 -0
  527. package/dist/ui/theme.js +98 -0
  528. package/dist/ui/toast.d.ts +23 -0
  529. package/dist/ui/toast.js +46 -0
  530. package/dist/ui/tooltip.d.ts +89 -0
  531. package/dist/ui/tooltip.js +333 -0
  532. package/dist/ui/widgets-2.d.ts +134 -0
  533. package/dist/ui/widgets-2.js +399 -0
  534. package/dist/ui/widgets-3.d.ts +91 -0
  535. package/dist/ui/widgets-3.js +212 -0
  536. package/dist/ui/widgets.d.ts +34 -0
  537. package/dist/ui/widgets.js +50 -0
  538. package/dist/ui/world-panel/index.d.ts +5 -0
  539. package/dist/ui/world-panel/index.js +5 -0
  540. package/dist/ui/world-panel/layout.d.ts +38 -0
  541. package/dist/ui/world-panel/layout.js +68 -0
  542. package/dist/ui/world-panel/paint.d.ts +96 -0
  543. package/dist/ui/world-panel/paint.js +136 -0
  544. package/dist/ui/world-panel/panel.d.ts +235 -0
  545. package/dist/ui/world-panel/panel.js +762 -0
  546. package/dist/ui/world-panel/wgsl.d.ts +10 -0
  547. package/dist/ui/world-panel/wgsl.js +52 -0
  548. package/dist/ui/world-panel/widgets.d.ts +207 -0
  549. package/dist/ui/world-panel/widgets.js +569 -0
  550. package/dist/voxel/chunks.d.ts +77 -0
  551. package/dist/voxel/chunks.js +149 -0
  552. package/dist/voxel/grid.d.ts +84 -0
  553. package/dist/voxel/grid.js +223 -0
  554. package/dist/voxel/index.d.ts +22 -0
  555. package/dist/voxel/index.js +7 -0
  556. package/dist/voxel/mesher-worker.d.ts +14 -0
  557. package/dist/voxel/mesher-worker.js +47 -0
  558. package/dist/voxel/mesher.d.ts +73 -0
  559. package/dist/voxel/mesher.js +306 -0
  560. package/dist/voxel/ray.d.ts +32 -0
  561. package/dist/voxel/ray.js +73 -0
  562. package/dist/voxel/wgsl.d.ts +16 -0
  563. package/dist/voxel/wgsl.js +28 -0
  564. package/dist/voxel/worker-client.d.ts +79 -0
  565. package/dist/voxel/worker-client.js +122 -0
  566. package/package.json +177 -3
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Notifications (ws/ui-3): richer than toasts (which are one line of text, top-centre): a titled
3
+ * card with a body, an icon, a tone and action buttons, stacked top-right on the `toasts` layer
4
+ * in a `role="status"` polite live region. Each one times out unless hovered or focused (or
5
+ * `timeout: 0`); a close button and Escape dismiss it. The actions are plain buttons, so the
6
+ * game's pad drives them through `menuNav(input, ui.notifications.element)` when it wants to.
7
+ */
8
+ import { h } from './dom.js';
9
+ import { toFrameUnits } from './text-scale.js';
10
+ import { button } from './widgets.js';
11
+ /** A notifier stacked top-right in `container` (the overlay's `toasts` layer). */
12
+ export function createNotifier(container, max = 4) {
13
+ const doc = container.ownerDocument;
14
+ ensureNotifyStyles(doc);
15
+ const element = h('div', { class: 'tc-notify', role: 'status', 'aria-live': 'polite' });
16
+ container.append(element);
17
+ const live = [];
18
+ const notifier = {
19
+ element,
20
+ get count() {
21
+ return live.length;
22
+ },
23
+ notify(opts) {
24
+ const tone = opts.tone ?? 'info';
25
+ const actions = (opts.actions ?? []).map((a) => button(a.label, () => {
26
+ a.onClick();
27
+ if (!a.keep)
28
+ handle.dismiss();
29
+ }, { variant: 'ghost', className: 'tc-notification-action' }));
30
+ const close = button('×', () => handle.dismiss(), {
31
+ variant: 'ghost',
32
+ className: 'tc-notification-close',
33
+ ariaLabel: 'Dismiss',
34
+ });
35
+ const card = h('div', { class: 'tc-notification', dataset: { tone }, tabindex: '-1' }, opts.icon !== undefined
36
+ ? h('span', { class: 'tc-notification-icon', 'aria-hidden': 'true' }, opts.icon)
37
+ : null, h('div', { class: 'tc-notification-main' }, h('div', { class: 'tc-notification-title' }, opts.title), opts.body !== undefined ? h('div', { class: 'tc-notification-body' }, opts.body) : null, actions.length > 0 ? h('div', { class: 'tc-notification-actions' }, ...actions) : null), close);
38
+ let timer = null;
39
+ let open = true;
40
+ const timeout = opts.timeout ?? 6000;
41
+ const arm = () => {
42
+ if (timer)
43
+ clearTimeout(timer);
44
+ timer = timeout > 0 ? setTimeout(() => handle.dismiss(), timeout) : null;
45
+ };
46
+ const pause = () => {
47
+ if (timer) {
48
+ clearTimeout(timer);
49
+ timer = null;
50
+ }
51
+ };
52
+ const handle = {
53
+ element: card,
54
+ get open() {
55
+ return open;
56
+ },
57
+ dismiss() {
58
+ if (!open)
59
+ return;
60
+ open = false;
61
+ pause();
62
+ const i = live.indexOf(handle);
63
+ if (i >= 0)
64
+ live.splice(i, 1);
65
+ const hadFocus = card.contains(doc.activeElement);
66
+ card.remove();
67
+ // Keep a pad user on the stack rather than dropping focus to the body.
68
+ if (hadFocus)
69
+ notifier.focus();
70
+ },
71
+ };
72
+ card.addEventListener('pointerenter', pause);
73
+ card.addEventListener('pointerleave', arm);
74
+ card.addEventListener('focusin', pause);
75
+ card.addEventListener('focusout', (e) => {
76
+ if (!card.contains(e.relatedTarget))
77
+ arm();
78
+ });
79
+ card.addEventListener('keydown', (e) => {
80
+ if (e.key === 'Escape') {
81
+ e.stopPropagation();
82
+ handle.dismiss();
83
+ }
84
+ });
85
+ element.prepend(card);
86
+ live.push(handle);
87
+ while (live.length > max)
88
+ live[0].dismiss();
89
+ arm();
90
+ return handle;
91
+ },
92
+ dismissAll() {
93
+ for (const n of [...live])
94
+ n.dismiss();
95
+ },
96
+ focus() {
97
+ const first = element.querySelector('.tc-notification button');
98
+ if (!first)
99
+ return false;
100
+ first.focus();
101
+ return true;
102
+ },
103
+ dispose() {
104
+ notifier.dismissAll();
105
+ element.remove();
106
+ },
107
+ };
108
+ return notifier;
109
+ }
110
+ /**
111
+ * Stylesheet for notifications (design px, theme tokens).
112
+ */
113
+ export const NOTIFY_CSS = toFrameUnits(`
114
+ .tc-notify { position: absolute; top: var(--tc-space-5); right: var(--tc-space-5); display: flex; flex-direction: column;
115
+ gap: var(--tc-space-2); width: min(560px, calc(100% - 2 * var(--tc-space-5))); pointer-events: none; }
116
+ .tc-notification { display: flex; align-items: flex-start; gap: var(--tc-space-3); pointer-events: auto;
117
+ padding: var(--tc-space-3) var(--tc-space-3) var(--tc-space-3) var(--tc-space-4); color: var(--tc-color-text);
118
+ font-family: var(--tc-font-ui); font-size: var(--tc-font-size-s); background: var(--tc-color-surface);
119
+ border: var(--tc-border-width) solid var(--tc-color-border); border-left-width: 6px; border-left-color: var(--tc-color-info);
120
+ border-radius: var(--tc-radius-m); box-shadow: var(--tc-shadow); animation: tc-drop var(--tc-duration-normal) var(--tc-easing); outline: none; }
121
+ .tc-notification[data-tone="success"] { border-left-color: var(--tc-color-success); }
122
+ .tc-notification[data-tone="warn"] { border-left-color: var(--tc-color-warn); }
123
+ .tc-notification[data-tone="danger"] { border-left-color: var(--tc-color-danger); }
124
+ .tc-notification-icon { flex: none; font-size: var(--tc-font-size-m); line-height: 1.2; }
125
+ .tc-notification-main { flex: 1 1 auto; min-width: 0; display: grid; gap: var(--tc-space-1); }
126
+ .tc-notification-title { font-weight: 700; }
127
+ .tc-notification-body { color: var(--tc-color-text-muted); overflow-wrap: break-word; }
128
+ .tc-notification-actions { display: flex; flex-wrap: wrap; gap: var(--tc-space-2); margin-top: var(--tc-space-1); }
129
+ .tc-notification-close { flex: none; margin: calc(-1 * var(--tc-space-2)) calc(-1 * var(--tc-space-2)) 0 0; }
130
+ @media (prefers-reduced-motion: reduce) { .tc-notification { animation: none; } }
131
+ `);
132
+ const STYLE_ID = 'tc-ui-notify';
133
+ /** Add `NOTIFY_CSS` to `doc` once (the first notification does it). */
134
+ export function ensureNotifyStyles(doc = document) {
135
+ if (doc.getElementById(STYLE_ID))
136
+ return;
137
+ const style = doc.createElement('style');
138
+ style.id = STYLE_ID;
139
+ style.textContent = NOTIFY_CSS;
140
+ doc.head.appendChild(style);
141
+ }
@@ -0,0 +1,53 @@
1
+ import type { HudHost, Meter, MeterOptions, MeterTrailOptions } from './hud.js';
2
+ import { type RegionName, type WidgetOptions } from './layout.js';
3
+ /**
4
+ * Where a lagging band is, from the times of the last change: it holds at `from` for `delay` ms
5
+ * after `t0`, then moves linearly to `to` over `duration` ms (a CSS `linear` transition with that
6
+ * delay draws the same curve). @internal
7
+ */
8
+ export declare class TrailClock {
9
+ readonly delay: number;
10
+ readonly duration: number;
11
+ private readonly now;
12
+ from: number;
13
+ to: number;
14
+ t0: number;
15
+ constructor(delay: number, duration: number, now: () => number);
16
+ /** The band's value at time `t` (default now). */
17
+ at(t?: number): number;
18
+ /** Retarget to `to` from wherever the band is now, as a restarted CSS transition does. */
19
+ retarget(to: number): void;
20
+ /** Jump to `v` with no lag. */
21
+ reset(v: number): void;
22
+ /** The clock's time now, ms. */
23
+ time(): number;
24
+ }
25
+ /**
26
+ * Restart a trail band's CSS transition where `clock` has it (ws/ui-11). Moving a node (the
27
+ * layout putting a meter in another region) cancels its transitions, so the band would jump to
28
+ * the value; this puts it back where the model is and runs the rest of the hold and the drain,
29
+ * on the same curve. `prefix` is `orb` or `meter`: `--tc-<prefix>-trail` goes on `valueEl`, the
30
+ * timings (`--tc-<prefix>-trail-delay`, `-duration`) on `timingEl`. Returns whether it re-armed
31
+ * (the caller puts the configured timings back on its next change). @internal
32
+ */
33
+ export declare function rearmTrail(clock: TrailClock, band: HTMLElement, prefix: 'orb' | 'meter', valueEl: HTMLElement, timingEl: HTMLElement): boolean;
34
+ /** A meter's layout placement: `MeterOptions.place`, else `region` (default `bottom`). @internal */
35
+ export declare function meterPlace(place: RegionName | WidgetOptions['place'] | undefined, region: RegionName | undefined): WidgetOptions['place'];
36
+ /** Resolve `MeterOptions.trail` into timings, or null when off (or under reduced motion). */
37
+ export declare function trailTimings(opts: MeterOptions, reduced: boolean): Required<MeterTrailOptions> | null;
38
+ export declare function meterClock(opts: MeterOptions): () => number;
39
+ export declare function meterReducedMotion(host: HudHost, opts: MeterOptions): boolean;
40
+ /**
41
+ * The orb stylesheet, under `.tc-overlay` and in `--tc-*` tokens. `--tc-orb-color` is the fill
42
+ * (the tone's token, or the per-call `color`); `--tc-color-meter-trail` the trail band.
43
+ */
44
+ export declare const ORB_CSS: string;
45
+ /** Add `ORB_CSS` to `doc` once (the first orb does it). */
46
+ export declare function ensureOrbStyles(doc?: Document): void;
47
+ /** What a readout shows for `value` of `max`. @internal */
48
+ export declare function readoutText(mode: MeterOptions['readout'], value: number, max: number, format?: (value: number, max: number) => string): string;
49
+ /**
50
+ * The orb (see the module comment). `ui.meter({ shape: 'orb' })` and `createMeter(host, { shape:
51
+ * 'orb' })` come here; it returns the same `Meter` handle as the bar.
52
+ */
53
+ export declare function createOrbMeter(host: HudHost, opts?: MeterOptions): Meter;
package/dist/ui/orb.js ADDED
@@ -0,0 +1,304 @@
1
+ /**
2
+ * Orb meter (ws/ui-5): `ui.meter({ shape: 'orb' })`, the round fill gauge an action-RPG HUD puts
3
+ * either side of its ability row. The fill rises from the bottom of a round well with a bright
4
+ * meniscus line on its surface; an optional damage `trail` (a lighter band) holds where the value
5
+ * was for `delay` ms, then drains to it over `duration` ms. A readout in the middle shows the value,
6
+ * a percent or nothing.
7
+ *
8
+ * Everything moves by `transform` on CSS transitions, so an orb costs nothing per frame: a `set`
9
+ * writes two custom properties and the compositor does the rest. `trail` (the trail's value now)
10
+ * is computed from the same clock and timings as the transition, so a test or a game reads where
11
+ * the band is without measuring it. `prefers-reduced-motion` (or `reducedMotion: true`) turns the
12
+ * trail and the fill's easing off.
13
+ *
14
+ * The trail model is shared with the bar meter (`createMeter` with `trail`).
15
+ */
16
+ import { h } from './dom.js';
17
+ import { formSize, } from './layout.js';
18
+ import { prefersReducedMotionIn } from './styles.js';
19
+ /** `n` theme px (the same `calc` as `themePx` in `hud.ts`, kept local to avoid an import cycle). */
20
+ const tpx = (n) => `calc(${n} * var(--tc-space-1) / 4)`;
21
+ /**
22
+ * Where a lagging band is, from the times of the last change: it holds at `from` for `delay` ms
23
+ * after `t0`, then moves linearly to `to` over `duration` ms (a CSS `linear` transition with that
24
+ * delay draws the same curve). @internal
25
+ */
26
+ export class TrailClock {
27
+ delay;
28
+ duration;
29
+ now;
30
+ from = 0;
31
+ to = 0;
32
+ t0 = -1e12;
33
+ constructor(delay, duration, now) {
34
+ this.delay = delay;
35
+ this.duration = duration;
36
+ this.now = now;
37
+ }
38
+ /** The band's value at time `t` (default now). */
39
+ at(t = this.now()) {
40
+ const k = this.duration > 0 ? (t - this.t0 - this.delay) / this.duration : 1;
41
+ if (k <= 0)
42
+ return this.from;
43
+ if (k >= 1)
44
+ return this.to;
45
+ return this.from + (this.to - this.from) * k;
46
+ }
47
+ /** Retarget to `to` from wherever the band is now, as a restarted CSS transition does. */
48
+ retarget(to) {
49
+ const t = this.now();
50
+ this.from = this.at(t);
51
+ this.to = to;
52
+ this.t0 = t;
53
+ }
54
+ /** Jump to `v` with no lag. */
55
+ reset(v) {
56
+ this.from = v;
57
+ this.to = v;
58
+ this.t0 = -1e12;
59
+ }
60
+ /** The clock's time now, ms. */
61
+ time() {
62
+ return this.now();
63
+ }
64
+ }
65
+ /**
66
+ * Restart a trail band's CSS transition where `clock` has it (ws/ui-11). Moving a node (the
67
+ * layout putting a meter in another region) cancels its transitions, so the band would jump to
68
+ * the value; this puts it back where the model is and runs the rest of the hold and the drain,
69
+ * on the same curve. `prefix` is `orb` or `meter`: `--tc-<prefix>-trail` goes on `valueEl`, the
70
+ * timings (`--tc-<prefix>-trail-delay`, `-duration`) on `timingEl`. Returns whether it re-armed
71
+ * (the caller puts the configured timings back on its next change). @internal
72
+ */
73
+ export function rearmTrail(clock, band, prefix, valueEl, timingEl) {
74
+ const t = clock.time();
75
+ const v = clock.at(t);
76
+ if (v === clock.to)
77
+ return false;
78
+ const since = t - clock.t0;
79
+ band.style.transition = 'none';
80
+ valueEl.style.setProperty(`--tc-${prefix}-trail`, String(v));
81
+ // One style read so the jump lands before the transition comes back (off the frame path).
82
+ void band.ownerDocument.defaultView?.getComputedStyle(band).transform;
83
+ band.style.transition = '';
84
+ timingEl.style.setProperty(`--tc-${prefix}-trail-delay`, `${Math.max(0, clock.delay - since)}ms`);
85
+ timingEl.style.setProperty(`--tc-${prefix}-trail-duration`, `${clock.duration - Math.max(0, since - clock.delay)}ms`);
86
+ valueEl.style.setProperty(`--tc-${prefix}-trail`, String(clock.to));
87
+ return true;
88
+ }
89
+ /** A meter's layout placement: `MeterOptions.place`, else `region` (default `bottom`). @internal */
90
+ export function meterPlace(place, region) {
91
+ if (typeof place === 'string')
92
+ return { default: place };
93
+ return place ?? { default: region ?? 'bottom' };
94
+ }
95
+ /** Resolve `MeterOptions.trail` into timings, or null when off (or under reduced motion). */
96
+ export function trailTimings(opts, reduced) {
97
+ if (!opts.trail || reduced)
98
+ return null;
99
+ const t = opts.trail === true ? {} : opts.trail;
100
+ return { delay: Math.max(0, t.delay ?? 400), duration: Math.max(0, t.duration ?? 600) };
101
+ }
102
+ export function meterClock(opts) {
103
+ return opts.now ?? (() => globalThis.performance?.now() ?? Date.now());
104
+ }
105
+ export function meterReducedMotion(host, opts) {
106
+ return (opts.reducedMotion ??
107
+ prefersReducedMotionIn(host.layers.hud.ownerDocument.defaultView ?? undefined));
108
+ }
109
+ const STYLE_ID = 'tc-ui-orb';
110
+ /**
111
+ * The orb stylesheet, under `.tc-overlay` and in `--tc-*` tokens. `--tc-orb-color` is the fill
112
+ * (the tone's token, or the per-call `color`); `--tc-color-meter-trail` the trail band.
113
+ */
114
+ export const ORB_CSS = `
115
+ .tc-overlay .tc-orb { position: relative; width: var(--tc-orb-size, ${tpx(128)}); height: var(--tc-orb-size, ${tpx(128)});
116
+ flex: none; pointer-events: none; font-family: var(--tc-font-ui); color: var(--tc-color-text);
117
+ --tc-orb-tone: var(--tc-color-accent); --tc-orb-color: var(--tc-meter-color, var(--tc-orb-tone)); }
118
+ .tc-overlay .tc-orb[data-tone="info"] { --tc-orb-tone: var(--tc-color-info); }
119
+ .tc-overlay .tc-orb[data-tone="success"] { --tc-orb-tone: var(--tc-color-success); }
120
+ .tc-overlay .tc-orb[data-tone="warn"] { --tc-orb-tone: var(--tc-color-warn); }
121
+ .tc-overlay .tc-orb[data-tone="danger"] { --tc-orb-tone: var(--tc-color-danger); }
122
+ .tc-overlay .tc-orb-well { position: absolute; inset: 0; border-radius: 50%; overflow: hidden; isolation: isolate;
123
+ background: radial-gradient(circle at 50% 60%, var(--tc-color-surface-alt), var(--tc-color-bg));
124
+ border: calc(var(--tc-border-width) * 1.5) solid var(--tc-color-border);
125
+ box-shadow: var(--tc-shadow), inset 0 0 ${tpx(18)} rgba(0, 0, 0, 0.8); }
126
+ .tc-overlay .tc-orb-fill, .tc-overlay .tc-orb-trail { position: absolute; left: 0; right: 0; top: 0; height: 100%;
127
+ will-change: transform; transform: translateY(calc((1 - var(--tc-orb-value, 1)) * 100%)); }
128
+ .tc-overlay .tc-orb-trail { transform: translateY(calc((1 - var(--tc-orb-trail, 1)) * 100%));
129
+ background: var(--tc-color-meter-trail); transition: transform var(--tc-orb-trail-duration, 600ms) linear var(--tc-orb-trail-delay, 400ms); }
130
+ .tc-overlay .tc-orb-fill { transition: transform var(--tc-duration-fast) var(--tc-easing);
131
+ background: radial-gradient(circle at 38% 30%, color-mix(in srgb, var(--tc-orb-color) 55%, white), var(--tc-orb-color) 45%,
132
+ color-mix(in srgb, var(--tc-orb-color) 40%, black)); }
133
+ .tc-overlay .tc-orb-fill::before { content: ''; position: absolute; left: 0; right: 0; top: 0; height: ${tpx(3)};
134
+ background: color-mix(in srgb, var(--tc-orb-color) 30%, white); box-shadow: 0 0 ${tpx(6)} color-mix(in srgb, var(--tc-orb-color) 50%, white);
135
+ opacity: 0.9; }
136
+ .tc-overlay .tc-orb[data-empty] .tc-orb-fill::before { display: none; }
137
+ .tc-overlay .tc-orb-gloss { position: absolute; inset: 8% 22% 56% 18%; border-radius: 50%; pointer-events: none;
138
+ background: linear-gradient(rgba(255, 255, 255, 0.35), rgba(255, 255, 255, 0)); }
139
+ .tc-overlay .tc-orb-readout { position: absolute; inset: 0; display: grid; place-items: center; font-weight: 700;
140
+ font-size: var(--tc-font-size-m); line-height: 1; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9), 0 0 ${tpx(4)} rgba(0, 0, 0, 0.6);
141
+ font-variant-numeric: tabular-nums; }
142
+ .tc-overlay .tc-orb-readout:empty { display: none; }
143
+ .tc-overlay .tc-orb[data-reduced] .tc-orb-fill { transition: none; }
144
+ @media (prefers-reduced-motion: reduce) {
145
+ .tc-overlay .tc-orb-fill { transition: none; }
146
+ .tc-overlay .tc-orb-trail { display: none; }
147
+ }
148
+ `;
149
+ /** Add `ORB_CSS` to `doc` once (the first orb does it). */
150
+ export function ensureOrbStyles(doc = document) {
151
+ if (doc.getElementById(STYLE_ID))
152
+ return;
153
+ const style = doc.createElement('style');
154
+ style.id = STYLE_ID;
155
+ style.textContent = ORB_CSS;
156
+ doc.head.appendChild(style);
157
+ }
158
+ /** What a readout shows for `value` of `max`. @internal */
159
+ export function readoutText(mode, value, max, format) {
160
+ if (mode === 'none')
161
+ return '';
162
+ if (mode === 'percent')
163
+ return `${Math.round(max > 0 ? (value / max) * 100 : 0)}%`;
164
+ return format ? format(value, max) : String(Math.round(value));
165
+ }
166
+ /**
167
+ * The orb (see the module comment). `ui.meter({ shape: 'orb' })` and `createMeter(host, { shape:
168
+ * 'orb' })` come here; it returns the same `Meter` handle as the bar.
169
+ */
170
+ export function createOrbMeter(host, opts = {}) {
171
+ const doc = host.layers.hud.ownerDocument;
172
+ ensureOrbStyles(doc);
173
+ let max = Math.max(0, opts.max ?? 1);
174
+ let value = Math.min(max, Math.max(0, opts.value ?? max));
175
+ const reduced = meterReducedMotion(host, opts);
176
+ const timings = trailTimings(opts, reduced);
177
+ const clock = timings ? new TrailClock(timings.delay, timings.duration, meterClock(opts)) : null;
178
+ const mode = opts.readout ?? 'value';
179
+ const fill = h('div', { class: 'tc-orb-fill' });
180
+ const trailEl = clock ? h('div', { class: 'tc-orb-trail' }) : null;
181
+ const readout = h('span', { class: 'tc-orb-readout', 'aria-hidden': 'true' });
182
+ const well = h('div', { class: 'tc-orb-well' }, trailEl, fill, h('div', { class: 'tc-orb-gloss' }));
183
+ const style = {};
184
+ if (opts.color)
185
+ style['--tc-meter-color'] = opts.color;
186
+ if (timings) {
187
+ style['--tc-orb-trail-delay'] = `${timings.delay}ms`;
188
+ style['--tc-orb-trail-duration'] = `${timings.duration}ms`;
189
+ }
190
+ const el = h('div', {
191
+ class: 'tc-orb',
192
+ role: 'meter',
193
+ 'aria-label': opts.label,
194
+ 'aria-valuemin': '0',
195
+ dataset: { tone: opts.tone ?? 'accent', shape: 'orb', ...(reduced ? { reduced: '' } : {}) },
196
+ style,
197
+ }, well, readout);
198
+ const frac = (v) => (max > 0 ? v / max : 0);
199
+ /** The band's timings were rewritten by a re-arm after a move (ws/ui-11). */
200
+ let rearmed = false;
201
+ const write = () => {
202
+ el.setAttribute('aria-valuenow', String(value));
203
+ el.setAttribute('aria-valuemax', String(max));
204
+ const f = frac(value);
205
+ el.style.setProperty('--tc-orb-value', String(f));
206
+ el.toggleAttribute('data-empty', f <= 0);
207
+ const text = readoutText(mode, value, max, opts.format);
208
+ if (readout.textContent !== text)
209
+ readout.textContent = text;
210
+ if (opts.format)
211
+ el.setAttribute('aria-valuetext', opts.format(value, max));
212
+ else if (mode === 'percent')
213
+ el.setAttribute('aria-valuetext', text);
214
+ if (clock && timings) {
215
+ if (rearmed) {
216
+ rearmed = false;
217
+ el.style.setProperty('--tc-orb-trail-delay', `${timings.delay}ms`);
218
+ el.style.setProperty('--tc-orb-trail-duration', `${timings.duration}ms`);
219
+ }
220
+ clock.retarget(f);
221
+ el.style.setProperty('--tc-orb-trail', String(f));
222
+ }
223
+ };
224
+ // The diameter in the current form factor (ws/ui-10): written now and on every re-layout,
225
+ // before the layout measures, so a content bar or rail sizes to it.
226
+ let size = opts.size;
227
+ let sized = '';
228
+ const writeSize = (ff) => {
229
+ const v = size === undefined ? '' : tpx(formSize(size, ff));
230
+ if (v === sized)
231
+ return false;
232
+ sized = v;
233
+ if (v)
234
+ el.style.setProperty('--tc-orb-size', v);
235
+ else
236
+ el.style.removeProperty('--tc-orb-size');
237
+ return true;
238
+ };
239
+ writeSize(host.layout.formFactor);
240
+ clock?.reset(frac(value));
241
+ if (trailEl)
242
+ el.style.setProperty('--tc-orb-trail', String(frac(value)));
243
+ write();
244
+ const handle = host.layout.add(el, {
245
+ place: meterPlace(opts.place, opts.region),
246
+ order: opts.order,
247
+ onForm: writeSize,
248
+ // A move cancels the band's transition: run the rest of it from where the model is.
249
+ onMove: () => {
250
+ if (clock && trailEl && rearmTrail(clock, trailEl, 'orb', el, el))
251
+ rearmed = true;
252
+ },
253
+ });
254
+ return {
255
+ el,
256
+ shape: 'orb',
257
+ get value() {
258
+ return value;
259
+ },
260
+ get max() {
261
+ return max;
262
+ },
263
+ get trail() {
264
+ // The band never shows under the fill, so a rising value reads as the value.
265
+ return clock ? Math.max(value, clock.at() * max) : value;
266
+ },
267
+ get size() {
268
+ return size ?? 128;
269
+ },
270
+ get region() {
271
+ return handle.region;
272
+ },
273
+ set(v, m) {
274
+ if (m !== undefined)
275
+ max = Math.max(0, m);
276
+ const next = Math.min(max, Math.max(0, v));
277
+ if (next === value && m === undefined)
278
+ return;
279
+ value = next;
280
+ write();
281
+ },
282
+ setTone(tone) {
283
+ el.dataset.tone = tone;
284
+ },
285
+ setColor(color) {
286
+ if (color)
287
+ el.style.setProperty('--tc-meter-color', color);
288
+ else
289
+ el.style.removeProperty('--tc-meter-color');
290
+ },
291
+ setSize(next) {
292
+ size = next;
293
+ if (writeSize(host.layout.formFactor))
294
+ host.layout.refresh();
295
+ },
296
+ setPlace(place) {
297
+ handle.setPlace(meterPlace(place, undefined));
298
+ },
299
+ remove() {
300
+ handle.remove();
301
+ el.remove();
302
+ },
303
+ };
304
+ }