@the-inclusionist/engine 9.0.0 → 11.0.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 (532) hide show
  1. package/README.md +120 -78
  2. package/app/css/style.css +761 -377
  3. package/app/public/vendor/fonts/playwrite-cu.woff2 +0 -0
  4. package/app/public/vendor/fonts/playwrite-es-deco.woff2 +0 -0
  5. package/app/public/vendor/fonts/playwrite-es.woff2 +0 -0
  6. package/app/public/vendor/fonts/playwrite-gb-j.woff2 +0 -0
  7. package/app/public/vendor/fonts/playwrite-gb-s.woff2 +0 -0
  8. package/app/public/vendor/fonts/playwrite-pe.woff2 +0 -0
  9. package/app/public/vendor/fonts/playwrite-pt.woff2 +0 -0
  10. package/app/public/vendor/fonts-licences/NOTICE.txt +166 -0
  11. package/app/public/vendor/fonts-licences/OFL-1.1.txt +86 -0
  12. package/app/public/vendor/fonts.css +36 -84
  13. package/dist-pkg/boot/create-game.d.ts +499 -219
  14. package/dist-pkg/boot/create-game.js +3944 -562
  15. package/dist-pkg/core/a11y-sr.d.ts +25 -3
  16. package/dist-pkg/core/a11y-sr.js +38 -19
  17. package/dist-pkg/core/accessible-label.d.ts +17 -0
  18. package/dist-pkg/core/accessible-label.js +37 -0
  19. package/dist-pkg/core/accommodation-subjects.d.ts +26 -0
  20. package/dist-pkg/core/accommodation-subjects.js +32 -0
  21. package/dist-pkg/core/accommodations.d.ts +125 -0
  22. package/dist-pkg/core/accommodations.js +195 -0
  23. package/dist-pkg/core/actions.d.ts +108 -55
  24. package/dist-pkg/core/actions.js +122 -71
  25. package/dist-pkg/core/calm-mode.d.ts +31 -0
  26. package/dist-pkg/core/calm-mode.js +47 -0
  27. package/dist-pkg/core/camera-cycle.d.ts +15 -0
  28. package/dist-pkg/core/camera-cycle.js +7 -0
  29. package/dist-pkg/core/caption-duration.d.ts +15 -0
  30. package/dist-pkg/core/caption-duration.js +19 -0
  31. package/dist-pkg/core/cartridge-problems.d.ts +34 -0
  32. package/dist-pkg/core/cartridge-problems.js +53 -0
  33. package/dist-pkg/core/constants.d.ts +0 -54
  34. package/dist-pkg/core/constants.js +9 -76
  35. package/dist-pkg/core/contract.d.ts +142 -164
  36. package/dist-pkg/core/contract.js +222 -208
  37. package/dist-pkg/core/dom-query.d.ts +4 -4
  38. package/dist-pkg/core/dom-query.js +12 -20
  39. package/dist-pkg/core/entity.d.ts +62 -77
  40. package/dist-pkg/core/entity.js +18 -32
  41. package/dist-pkg/core/escape-html.d.ts +9 -10
  42. package/dist-pkg/core/escape-html.js +16 -20
  43. package/dist-pkg/core/flash-threshold.d.ts +17 -0
  44. package/dist-pkg/core/flash-threshold.js +113 -0
  45. package/dist-pkg/core/game-speed.d.ts +11 -0
  46. package/dist-pkg/core/game-speed.js +16 -0
  47. package/dist-pkg/core/genres.d.ts +20 -0
  48. package/dist-pkg/core/genres.js +44 -0
  49. package/dist-pkg/core/i18n.d.ts +71 -60
  50. package/dist-pkg/core/i18n.js +186 -200
  51. package/dist-pkg/core/loop.d.ts +17 -6
  52. package/dist-pkg/core/loop.js +26 -26
  53. package/dist-pkg/core/pause-icon-catalogue.d.ts +15 -0
  54. package/dist-pkg/core/pause-icon-catalogue.js +54 -0
  55. package/dist-pkg/core/ring.d.ts +17 -0
  56. package/dist-pkg/core/ring.js +29 -0
  57. package/dist-pkg/core/rng.d.ts +7 -12
  58. package/dist-pkg/core/rng.js +23 -53
  59. package/dist-pkg/core/route.d.ts +26 -26
  60. package/dist-pkg/core/route.js +126 -121
  61. package/dist-pkg/core/scenes.d.ts +37 -40
  62. package/dist-pkg/core/scenes.js +41 -43
  63. package/dist-pkg/core/screens.d.ts +4 -4
  64. package/dist-pkg/core/screens.js +11 -16
  65. package/dist-pkg/core/session-clock.d.ts +23 -0
  66. package/dist-pkg/core/session-clock.js +37 -0
  67. package/dist-pkg/core/setting-defaults.d.ts +61 -0
  68. package/dist-pkg/core/setting-defaults.js +66 -0
  69. package/dist-pkg/core/speech-rate.d.ts +29 -0
  70. package/dist-pkg/core/speech-rate.js +47 -0
  71. package/dist-pkg/core/state.d.ts +118 -118
  72. package/dist-pkg/core/state.js +322 -297
  73. package/dist-pkg/core/visual-cycles.d.ts +30 -0
  74. package/dist-pkg/core/visual-cycles.js +52 -0
  75. package/dist-pkg/core/visual-state.d.ts +13 -0
  76. package/dist-pkg/core/visual-state.js +6 -0
  77. package/dist-pkg/educational/activities-registry.d.ts +1 -1
  78. package/dist-pkg/educational/activities-registry.js +9 -8
  79. package/dist-pkg/educational/adaptive-engine.d.ts +11 -11
  80. package/dist-pkg/educational/adaptive-engine.js +17 -17
  81. package/dist-pkg/educational/segment-bar.d.ts +12 -12
  82. package/dist-pkg/educational/segment-bar.js +9 -9
  83. package/dist-pkg/i18n/en.js +324 -223
  84. package/dist-pkg/i18n/es.js +323 -223
  85. package/dist-pkg/i18n/pt.js +348 -226
  86. package/dist-pkg/input/default-bindings.d.ts +37 -38
  87. package/dist-pkg/input/default-bindings.js +127 -144
  88. package/dist-pkg/input/devices.d.ts +7 -7
  89. package/dist-pkg/input/devices.js +17 -16
  90. package/dist-pkg/input/edges.d.ts +23 -32
  91. package/dist-pkg/input/edges.js +23 -28
  92. package/dist-pkg/input/empathy-filter.d.ts +22 -0
  93. package/dist-pkg/input/empathy-filter.js +34 -0
  94. package/dist-pkg/input/face-map.d.ts +96 -0
  95. package/dist-pkg/input/face-map.js +255 -0
  96. package/dist-pkg/input/face-signals.d.ts +40 -0
  97. package/dist-pkg/input/face-signals.js +48 -0
  98. package/dist-pkg/input/gamepad.d.ts +195 -145
  99. package/dist-pkg/input/gamepad.js +383 -556
  100. package/dist-pkg/input/gaze-cycle.d.ts +64 -0
  101. package/dist-pkg/input/gaze-cycle.js +133 -0
  102. package/dist-pkg/input/gaze-relative.d.ts +68 -0
  103. package/dist-pkg/input/gaze-relative.js +142 -0
  104. package/dist-pkg/input/hand-map.d.ts +28 -0
  105. package/dist-pkg/input/hand-map.js +142 -0
  106. package/dist-pkg/input/input-cooldown.d.ts +17 -0
  107. package/dist-pkg/input/input-cooldown.js +39 -0
  108. package/dist-pkg/input/key-default.d.ts +30 -0
  109. package/dist-pkg/input/key-default.js +60 -0
  110. package/dist-pkg/input/keyboard-runtime.d.ts +15 -21
  111. package/dist-pkg/input/keyboard-runtime.js +23 -27
  112. package/dist-pkg/input/keyboard.d.ts +68 -63
  113. package/dist-pkg/input/keyboard.js +83 -105
  114. package/dist-pkg/input/keydown.d.ts +123 -137
  115. package/dist-pkg/input/keydown.js +284 -289
  116. package/dist-pkg/input/latch-edge.d.ts +33 -21
  117. package/dist-pkg/input/latch-edge.js +34 -35
  118. package/dist-pkg/input/latch-scope.d.ts +51 -50
  119. package/dist-pkg/input/latch-scope.js +61 -82
  120. package/dist-pkg/input/latch-store.d.ts +26 -30
  121. package/dist-pkg/input/latch-store.js +42 -50
  122. package/dist-pkg/input/latch-sync.d.ts +29 -29
  123. package/dist-pkg/input/latch-sync.js +25 -25
  124. package/dist-pkg/input/latch.d.ts +14 -17
  125. package/dist-pkg/input/latch.js +29 -37
  126. package/dist-pkg/input/pad-defaults.d.ts +13 -16
  127. package/dist-pkg/input/pad-defaults.js +21 -28
  128. package/dist-pkg/input/pad-reading.d.ts +76 -0
  129. package/dist-pkg/input/pad-reading.js +169 -0
  130. package/dist-pkg/input/pad-wizard.d.ts +99 -0
  131. package/dist-pkg/input/pad-wizard.js +256 -0
  132. package/dist-pkg/input/pointer-space.d.ts +19 -20
  133. package/dist-pkg/input/pointer-space.js +27 -32
  134. package/dist-pkg/input/pointer.d.ts +39 -40
  135. package/dist-pkg/input/pointer.js +42 -45
  136. package/dist-pkg/input/state.d.ts +101 -89
  137. package/dist-pkg/input/state.js +54 -134
  138. package/dist-pkg/input/switch-scan.d.ts +59 -0
  139. package/dist-pkg/input/switch-scan.js +67 -0
  140. package/dist-pkg/input/synthetic-source.d.ts +42 -0
  141. package/dist-pkg/input/synthetic-source.js +57 -0
  142. package/dist-pkg/input/touch-bindings.d.ts +127 -116
  143. package/dist-pkg/input/touch-bindings.js +158 -173
  144. package/dist-pkg/input/touch.d.ts +147 -72
  145. package/dist-pkg/input/touch.js +362 -126
  146. package/dist-pkg/input/transport-in-use.d.ts +107 -0
  147. package/dist-pkg/input/transport-in-use.js +130 -0
  148. package/dist-pkg/input/transports.d.ts +90 -117
  149. package/dist-pkg/input/transports.js +104 -106
  150. package/dist-pkg/input/virtual-controller.d.ts +82 -0
  151. package/dist-pkg/input/virtual-controller.js +69 -0
  152. package/dist-pkg/input/vocabulary-migration.d.ts +50 -49
  153. package/dist-pkg/input/vocabulary-migration.js +80 -79
  154. package/dist-pkg/input/voice-map.d.ts +59 -0
  155. package/dist-pkg/input/voice-map.js +123 -0
  156. package/dist-pkg/platform/audio-ambient.d.ts +13 -2
  157. package/dist-pkg/platform/audio-ambient.js +14 -14
  158. package/dist-pkg/platform/audio-earcons.d.ts +20 -19
  159. package/dist-pkg/platform/audio-earcons.js +51 -42
  160. package/dist-pkg/platform/audio-jingles.js +9 -10
  161. package/dist-pkg/platform/audio-mixer.d.ts +14 -2
  162. package/dist-pkg/platform/audio-mixer.js +31 -39
  163. package/dist-pkg/platform/audio-sonar.d.ts +49 -152
  164. package/dist-pkg/platform/audio-sonar.js +124 -302
  165. package/dist-pkg/platform/audio.d.ts +62 -19
  166. package/dist-pkg/platform/audio.js +193 -168
  167. package/dist-pkg/platform/choose-by-voice.d.ts +70 -0
  168. package/dist-pkg/platform/choose-by-voice.js +157 -0
  169. package/dist-pkg/platform/flash-sampler.d.ts +19 -0
  170. package/dist-pkg/platform/flash-sampler.js +79 -0
  171. package/dist-pkg/platform/font-library.d.ts +77 -0
  172. package/dist-pkg/platform/font-library.js +98 -0
  173. package/dist-pkg/platform/font-library.json +721 -0
  174. package/dist-pkg/platform/heavy-catalogue.d.ts +77 -0
  175. package/dist-pkg/platform/heavy-catalogue.js +256 -0
  176. package/dist-pkg/platform/heavy-mirror.d.ts +20 -0
  177. package/dist-pkg/platform/heavy-mirror.js +73 -0
  178. package/dist-pkg/platform/heavy.d.ts +136 -0
  179. package/dist-pkg/platform/heavy.js +324 -0
  180. package/dist-pkg/platform/interruptible-speech.d.ts +23 -16
  181. package/dist-pkg/platform/interruptible-speech.js +77 -54
  182. package/dist-pkg/platform/kokoro-port.d.ts +27 -0
  183. package/dist-pkg/platform/kokoro-port.js +50 -0
  184. package/dist-pkg/platform/kokoro-runtime.d.ts +20 -0
  185. package/dist-pkg/platform/kokoro-runtime.js +52 -0
  186. package/dist-pkg/platform/kokoro.d.ts +70 -0
  187. package/dist-pkg/platform/kokoro.js +133 -0
  188. package/dist-pkg/platform/listener-scope.d.ts +12 -0
  189. package/dist-pkg/platform/listener-scope.js +90 -0
  190. package/dist-pkg/platform/locale-host.d.ts +14 -0
  191. package/dist-pkg/platform/locale-host.js +45 -0
  192. package/dist-pkg/platform/microphone.d.ts +51 -0
  193. package/dist-pkg/platform/microphone.js +118 -0
  194. package/dist-pkg/platform/onnx-runtime.d.ts +34 -0
  195. package/dist-pkg/platform/onnx-runtime.js +42 -0
  196. package/dist-pkg/platform/reading-in-worker.d.ts +64 -0
  197. package/dist-pkg/platform/reading-in-worker.js +125 -0
  198. package/dist-pkg/platform/reading-model.d.ts +94 -0
  199. package/dist-pkg/platform/reading-model.js +272 -0
  200. package/dist-pkg/platform/reading-runtime.d.ts +24 -0
  201. package/dist-pkg/platform/reading-runtime.js +164 -0
  202. package/dist-pkg/platform/reading-worker.d.ts +41 -0
  203. package/dist-pkg/platform/reading-worker.js +58 -0
  204. package/dist-pkg/platform/reading.d.ts +80 -0
  205. package/dist-pkg/platform/reading.js +136 -0
  206. package/dist-pkg/platform/speech-recognition.d.ts +60 -0
  207. package/dist-pkg/platform/speech-recognition.js +104 -0
  208. package/dist-pkg/platform/speech.d.ts +23 -1
  209. package/dist-pkg/platform/speech.js +29 -18
  210. package/dist-pkg/platform/storage-keys.d.ts +96 -0
  211. package/dist-pkg/platform/storage-keys.js +106 -0
  212. package/dist-pkg/platform/storage.d.ts +46 -111
  213. package/dist-pkg/platform/storage.js +104 -169
  214. package/dist-pkg/platform/tts.d.ts +85 -39
  215. package/dist-pkg/platform/tts.js +447 -127
  216. package/dist-pkg/platform/vision-loop.d.ts +23 -0
  217. package/dist-pkg/platform/vision-loop.js +56 -0
  218. package/dist-pkg/platform/vision.d.ts +132 -0
  219. package/dist-pkg/platform/vision.js +117 -0
  220. package/dist-pkg/platform/voice-listener.d.ts +40 -0
  221. package/dist-pkg/platform/voice-listener.js +88 -0
  222. package/dist-pkg/platform/voice-plan.d.ts +15 -98
  223. package/dist-pkg/platform/voice-plan.js +56 -143
  224. package/dist-pkg/platform/vosk-runtime.d.ts +96 -0
  225. package/dist-pkg/platform/vosk-runtime.js +151 -0
  226. package/dist-pkg/platform/vosk-vocabulary.d.ts +6 -0
  227. package/dist-pkg/platform/vosk-vocabulary.js +178 -0
  228. package/dist-pkg/render/canvas.d.ts +13 -7
  229. package/dist-pkg/render/canvas.js +13 -13
  230. package/dist-pkg/render/crt.d.ts +48 -12
  231. package/dist-pkg/render/crt.js +78 -80
  232. package/dist-pkg/render/cvd-matrices.d.ts +22 -18
  233. package/dist-pkg/render/cvd-matrices.js +37 -38
  234. package/dist-pkg/render/hc-role-data.d.ts +7 -7
  235. package/dist-pkg/render/hc-role-data.js +14 -14
  236. package/dist-pkg/render/high-contrast.d.ts +67 -56
  237. package/dist-pkg/render/high-contrast.js +226 -217
  238. package/dist-pkg/render/low-vision-drawing.d.ts +5 -0
  239. package/dist-pkg/render/low-vision-drawing.js +46 -0
  240. package/dist-pkg/render/lq-filter.d.ts +32 -20
  241. package/dist-pkg/render/lq-filter.js +59 -65
  242. package/dist-pkg/render/port.d.ts +86 -88
  243. package/dist-pkg/render/port.js +17 -23
  244. package/dist-pkg/render/screen-pipeline.d.ts +42 -42
  245. package/dist-pkg/render/screen-pipeline.js +80 -87
  246. package/dist-pkg/render/sprite-fx.d.ts +2 -1
  247. package/dist-pkg/render/sprite-fx.js +16 -14
  248. package/dist-pkg/render/viewports.d.ts +20 -15
  249. package/dist-pkg/render/viewports.js +83 -114
  250. package/dist-pkg/render/viz-axes-labels.d.ts +47 -0
  251. package/dist-pkg/render/viz-axes-labels.js +88 -0
  252. package/dist-pkg/render/viz-axes.d.ts +89 -86
  253. package/dist-pkg/render/viz-axes.js +128 -116
  254. package/dist-pkg/render/viz-modes.d.ts +28 -29
  255. package/dist-pkg/render/viz-modes.js +40 -45
  256. package/dist-pkg/render/viz-refusal.d.ts +32 -0
  257. package/dist-pkg/render/viz-refusal.js +57 -0
  258. package/dist-pkg/render/viz-setters.d.ts +104 -66
  259. package/dist-pkg/render/viz-setters.js +182 -191
  260. package/dist-pkg/ui/aac-sets.d.ts +45 -0
  261. package/dist-pkg/ui/aac-sets.js +41 -0
  262. package/dist-pkg/ui/audio-choices.d.ts +68 -0
  263. package/dist-pkg/ui/audio-choices.js +98 -0
  264. package/dist-pkg/ui/audio-rows-that-apply.d.ts +12 -0
  265. package/dist-pkg/ui/audio-rows-that-apply.js +43 -0
  266. package/dist-pkg/ui/camera-control.d.ts +53 -0
  267. package/dist-pkg/ui/camera-control.js +48 -0
  268. package/dist-pkg/ui/changed-mark.d.ts +9 -8
  269. package/dist-pkg/ui/changed-mark.js +22 -53
  270. package/dist-pkg/ui/control-choices.d.ts +37 -0
  271. package/dist-pkg/ui/control-choices.js +84 -0
  272. package/dist-pkg/ui/debug-panel.d.ts +59 -43
  273. package/dist-pkg/ui/debug-panel.js +68 -69
  274. package/dist-pkg/ui/declared-words.d.ts +21 -0
  275. package/dist-pkg/ui/declared-words.js +66 -0
  276. package/dist-pkg/ui/dom.d.ts +10 -14
  277. package/dist-pkg/ui/dom.js +10 -47
  278. package/dist-pkg/ui/drawing-problems.d.ts +25 -0
  279. package/dist-pkg/ui/drawing-problems.js +94 -0
  280. package/dist-pkg/ui/eye-control.d.ts +36 -0
  281. package/dist-pkg/ui/eye-control.js +178 -0
  282. package/dist-pkg/ui/face-control.d.ts +25 -0
  283. package/dist-pkg/ui/face-control.js +183 -0
  284. package/dist-pkg/ui/focus-trap.d.ts +39 -49
  285. package/dist-pkg/ui/focus-trap.js +56 -65
  286. package/dist-pkg/ui/fonts.d.ts +157 -68
  287. package/dist-pkg/ui/fonts.js +305 -115
  288. package/dist-pkg/ui/footer-scroll-driver.d.ts +14 -0
  289. package/dist-pkg/ui/footer-scroll-driver.js +201 -0
  290. package/dist-pkg/ui/footer-scroll.d.ts +38 -0
  291. package/dist-pkg/ui/footer-scroll.js +55 -0
  292. package/dist-pkg/ui/game-options.d.ts +47 -0
  293. package/dist-pkg/ui/game-options.js +158 -0
  294. package/dist-pkg/ui/gaze-overlay.d.ts +64 -0
  295. package/dist-pkg/ui/gaze-overlay.js +165 -0
  296. package/dist-pkg/ui/hand-control.d.ts +25 -0
  297. package/dist-pkg/ui/hand-control.js +143 -0
  298. package/dist-pkg/ui/help-panel.d.ts +87 -0
  299. package/dist-pkg/ui/help-panel.js +242 -0
  300. package/dist-pkg/ui/hud-bands.d.ts +62 -0
  301. package/dist-pkg/ui/hud-bands.js +146 -0
  302. package/dist-pkg/ui/hud-row.d.ts +34 -0
  303. package/dist-pkg/ui/hud-row.js +80 -0
  304. package/dist-pkg/ui/hud.d.ts +73 -73
  305. package/dist-pkg/ui/hud.js +94 -98
  306. package/dist-pkg/ui/item-announcement.d.ts +13 -12
  307. package/dist-pkg/ui/item-announcement.js +25 -26
  308. package/dist-pkg/ui/layout.d.ts +103 -28
  309. package/dist-pkg/ui/layout.js +117 -99
  310. package/dist-pkg/ui/libras-avatar-clip.d.ts +30 -0
  311. package/dist-pkg/ui/libras-avatar-clip.js +86 -0
  312. package/dist-pkg/ui/libras-avatar-load.d.ts +52 -0
  313. package/dist-pkg/ui/libras-avatar-load.js +134 -0
  314. package/dist-pkg/ui/libras-avatar-plan.d.ts +102 -0
  315. package/dist-pkg/ui/libras-avatar-plan.js +211 -0
  316. package/dist-pkg/ui/libras-avatar-player.d.ts +28 -0
  317. package/dist-pkg/ui/libras-avatar-player.js +226 -0
  318. package/dist-pkg/ui/libras-avatar-stage.d.ts +37 -0
  319. package/dist-pkg/ui/libras-avatar-stage.js +208 -0
  320. package/dist-pkg/ui/libras-glosses.d.ts +28 -0
  321. package/dist-pkg/ui/libras-glosses.js +161 -0
  322. package/dist-pkg/ui/locale-flags.d.ts +16 -0
  323. package/dist-pkg/ui/locale-flags.js +30 -0
  324. package/dist-pkg/ui/loop-crash.d.ts +17 -17
  325. package/dist-pkg/ui/loop-crash.js +33 -62
  326. package/dist-pkg/ui/menu-intent.d.ts +61 -0
  327. package/dist-pkg/ui/menu-intent.js +88 -0
  328. package/dist-pkg/ui/menu-items.d.ts +20 -0
  329. package/dist-pkg/ui/menu-items.js +51 -0
  330. package/dist-pkg/ui/menu-nav.d.ts +98 -92
  331. package/dist-pkg/ui/menu-nav.js +398 -286
  332. package/dist-pkg/ui/mobility-choices.d.ts +26 -0
  333. package/dist-pkg/ui/mobility-choices.js +41 -0
  334. package/dist-pkg/ui/motion-choices.d.ts +31 -0
  335. package/dist-pkg/ui/motion-choices.js +68 -0
  336. package/dist-pkg/ui/motion-scene.d.ts +24 -19
  337. package/dist-pkg/ui/motion-scene.js +29 -61
  338. package/dist-pkg/ui/mount-panel.d.ts +81 -0
  339. package/dist-pkg/ui/mount-panel.js +61 -0
  340. package/dist-pkg/ui/panel-shell.d.ts +65 -31
  341. package/dist-pkg/ui/panel-shell.js +92 -66
  342. package/dist-pkg/ui/panel-widgets.d.ts +150 -0
  343. package/dist-pkg/ui/panel-widgets.js +294 -0
  344. package/dist-pkg/ui/pause-buttons.d.ts +35 -0
  345. package/dist-pkg/ui/pause-buttons.js +66 -0
  346. package/dist-pkg/ui/pause-icons.d.ts +261 -347
  347. package/dist-pkg/ui/pause-icons.js +671 -601
  348. package/dist-pkg/ui/pause-markup.d.ts +86 -0
  349. package/dist-pkg/ui/pause-markup.js +125 -0
  350. package/dist-pkg/ui/reach-notice.d.ts +22 -23
  351. package/dist-pkg/ui/reach-notice.js +55 -58
  352. package/dist-pkg/ui/scan-overlay.d.ts +23 -0
  353. package/dist-pkg/ui/scan-overlay.js +50 -0
  354. package/dist-pkg/ui/screen-text.d.ts +25 -0
  355. package/dist-pkg/ui/screen-text.js +152 -0
  356. package/dist-pkg/ui/session-clock.d.ts +32 -0
  357. package/dist-pkg/ui/session-clock.js +67 -0
  358. package/dist-pkg/ui/settings-aac.d.ts +70 -0
  359. package/dist-pkg/ui/settings-aac.js +208 -0
  360. package/dist-pkg/ui/settings-audio.d.ts +97 -114
  361. package/dist-pkg/ui/settings-audio.js +493 -425
  362. package/dist-pkg/ui/settings-controls.d.ts +53 -96
  363. package/dist-pkg/ui/settings-controls.js +143 -215
  364. package/dist-pkg/ui/settings-empathy.d.ts +39 -30
  365. package/dist-pkg/ui/settings-empathy.js +53 -60
  366. package/dist-pkg/ui/settings-mobility.d.ts +192 -0
  367. package/dist-pkg/ui/settings-mobility.js +332 -0
  368. package/dist-pkg/ui/settings-motion.d.ts +91 -70
  369. package/dist-pkg/ui/settings-motion.js +287 -198
  370. package/dist-pkg/ui/settings-panel.d.ts +58 -45
  371. package/dist-pkg/ui/settings-panel.js +189 -94
  372. package/dist-pkg/ui/settings-typo.d.ts +29 -78
  373. package/dist-pkg/ui/settings-typo.js +158 -129
  374. package/dist-pkg/ui/settings-visual.d.ts +29 -87
  375. package/dist-pkg/ui/settings-visual.js +240 -193
  376. package/dist-pkg/ui/shell.d.ts +112 -135
  377. package/dist-pkg/ui/shell.js +148 -217
  378. package/dist-pkg/ui/simulation-list.d.ts +27 -0
  379. package/dist-pkg/ui/simulation-list.js +76 -0
  380. package/dist-pkg/ui/simulation-over-the-world.d.ts +23 -0
  381. package/dist-pkg/ui/simulation-over-the-world.js +131 -0
  382. package/dist-pkg/ui/simulation-refusal.d.ts +5 -31
  383. package/dist-pkg/ui/simulation-refusal.js +8 -56
  384. package/dist-pkg/ui/switchable-control.d.ts +11 -0
  385. package/dist-pkg/ui/switchable-control.js +19 -0
  386. package/dist-pkg/ui/title.d.ts +3 -12
  387. package/dist-pkg/ui/title.js +49 -18
  388. package/dist-pkg/ui/top-band.d.ts +26 -0
  389. package/dist-pkg/ui/top-band.js +96 -0
  390. package/dist-pkg/ui/typo-choices.d.ts +71 -0
  391. package/dist-pkg/ui/typo-choices.js +85 -0
  392. package/dist-pkg/ui/visual-axes-panel.d.ts +11 -47
  393. package/dist-pkg/ui/visual-axes-panel.js +12 -94
  394. package/dist-pkg/ui/visual-choices.d.ts +77 -0
  395. package/dist-pkg/ui/visual-choices.js +107 -0
  396. package/dist-pkg/ui/vlibras.d.ts +77 -10
  397. package/dist-pkg/ui/vlibras.js +130 -81
  398. package/dist-pkg/ui/voice-control.d.ts +68 -0
  399. package/dist-pkg/ui/voice-control.js +276 -0
  400. package/dist-pkg/ui/voice-settings.d.ts +95 -0
  401. package/dist-pkg/ui/voice-settings.js +352 -0
  402. package/dist-pkg/ui/where-the-child-is.d.ts +31 -0
  403. package/dist-pkg/ui/where-the-child-is.js +70 -0
  404. package/docs/CREDITS.md +300 -44
  405. package/docs/LICENSES.md +189 -145
  406. package/package.json +51 -27
  407. package/scripts/check-cartridge.mjs +78 -0
  408. package/scripts/game-build.d.mts +25 -0
  409. package/scripts/game-build.mjs +144 -0
  410. package/scripts/heavy-into-the-delivery.mjs +388 -0
  411. package/scripts/libras-avatar.json +680 -0
  412. package/scripts/libras-avatar.mjs +246 -0
  413. package/scripts/libras-glosses/gloss.py +95 -0
  414. package/scripts/libras-glosses/pyproject.toml +32 -0
  415. package/scripts/libras-glosses/uv.lock +781 -0
  416. package/scripts/libras-glosses.mjs +351 -0
  417. package/scripts/licences/Apache-2.0.txt +176 -0
  418. package/scripts/licences/GPL-3.0.txt +674 -0
  419. package/scripts/licences/MIT.txt +17 -0
  420. package/scripts/licences/OFL-1.1.txt +86 -0
  421. package/scripts/licences/UFL-1.0.txt +96 -0
  422. package/scripts/licences/fonts.mjs +389 -0
  423. package/scripts/licences/third-party.mjs +301 -0
  424. package/scripts/licences/vosk-browser.NOTICE.txt +268 -0
  425. package/app/public/vendor/fonts/comicneue-400.woff2 +0 -0
  426. package/app/public/vendor/fonts/comicneue-700.woff2 +0 -0
  427. package/app/public/vendor/fonts/fondamento-400-ext.woff2 +0 -0
  428. package/app/public/vendor/fonts/fondamento-400.woff2 +0 -0
  429. package/app/public/vendor/fonts/inter-400.woff2 +0 -0
  430. package/app/public/vendor/fonts/inter-700.woff2 +0 -0
  431. package/app/public/vendor/fonts/lato-400.woff2 +0 -0
  432. package/app/public/vendor/fonts/lato-700.woff2 +0 -0
  433. package/app/public/vendor/fonts/literata-400.woff2 +0 -0
  434. package/app/public/vendor/fonts/literata-700.woff2 +0 -0
  435. package/app/public/vendor/fonts/newsreader-400.woff2 +0 -0
  436. package/app/public/vendor/fonts/newsreader-700.woff2 +0 -0
  437. package/app/public/vendor/fonts/opendyslexic-400.woff2 +0 -0
  438. package/app/public/vendor/fonts/opensans-400.woff2 +0 -0
  439. package/app/public/vendor/fonts/opensans-700.woff2 +0 -0
  440. package/app/public/vendor/fonts/pinyon-400.woff2 +0 -0
  441. package/app/public/vendor/fonts/pressstart-400.woff2 +0 -0
  442. package/app/public/vendor/fonts/quattro-400.woff2 +0 -0
  443. package/app/public/vendor/fonts/quattro-700.woff2 +0 -0
  444. package/app/public/vendor/fonts/sourcesans-400.woff2 +0 -0
  445. package/app/public/vendor/fonts/sourcesans-700.woff2 +0 -0
  446. package/app/public/vendor/fonts/sourceserif-400.woff2 +0 -0
  447. package/app/public/vendor/fonts/sourceserif-700.woff2 +0 -0
  448. package/app/public/vendor/fonts/ufmag-400.woff2 +0 -0
  449. package/dist-pkg/core/anel.d.ts +0 -17
  450. package/dist-pkg/core/anel.js +0 -31
  451. package/dist-pkg/core/collision.d.ts +0 -21
  452. package/dist-pkg/core/collision.js +0 -62
  453. package/dist-pkg/core/layers.d.ts +0 -63
  454. package/dist-pkg/core/layers.js +0 -95
  455. package/dist-pkg/core/letter-grid.d.ts +0 -55
  456. package/dist-pkg/core/letter-grid.js +0 -116
  457. package/dist-pkg/core/password.d.ts +0 -34
  458. package/dist-pkg/core/password.js +0 -205
  459. package/dist-pkg/core/rotulo-acessivel.d.ts +0 -17
  460. package/dist-pkg/core/rotulo-acessivel.js +0 -41
  461. package/dist-pkg/core/run-state.d.ts +0 -115
  462. package/dist-pkg/core/run-state.js +0 -40
  463. package/dist-pkg/core/tiles.d.ts +0 -12
  464. package/dist-pkg/core/tiles.js +0 -61
  465. package/dist-pkg/core/world.d.ts +0 -4
  466. package/dist-pkg/core/world.js +0 -58
  467. package/dist-pkg/input/origem-sintetica.d.ts +0 -44
  468. package/dist-pkg/input/origem-sintetica.js +0 -60
  469. package/dist-pkg/input/transporte-em-uso.d.ts +0 -101
  470. package/dist-pkg/input/transporte-em-uso.js +0 -130
  471. package/dist-pkg/platform/audio-nav.d.ts +0 -51
  472. package/dist-pkg/platform/audio-nav.js +0 -99
  473. package/dist-pkg/platform/guide-intensity.d.ts +0 -40
  474. package/dist-pkg/platform/guide-intensity.js +0 -73
  475. package/dist-pkg/platform/pesados-catalogo.d.ts +0 -14
  476. package/dist-pkg/platform/pesados-catalogo.js +0 -177
  477. package/dist-pkg/platform/pesados.d.ts +0 -31
  478. package/dist-pkg/platform/pesados.js +0 -75
  479. package/dist-pkg/platform/vozes-prontas.d.ts +0 -28
  480. package/dist-pkg/platform/vozes-prontas.js +0 -61
  481. package/dist-pkg/render/camera.d.ts +0 -58
  482. package/dist-pkg/render/camera.js +0 -105
  483. package/dist-pkg/render/cenario-data.d.ts +0 -127
  484. package/dist-pkg/render/cenario-data.js +0 -145
  485. package/dist-pkg/render/city-tex.d.ts +0 -63
  486. package/dist-pkg/render/city-tex.js +0 -228
  487. package/dist-pkg/render/city-tiles.d.ts +0 -11
  488. package/dist-pkg/render/city-tiles.js +0 -140
  489. package/dist-pkg/render/draw.d.ts +0 -149
  490. package/dist-pkg/render/draw.js +0 -231
  491. package/dist-pkg/render/fx.d.ts +0 -63
  492. package/dist-pkg/render/fx.js +0 -123
  493. package/dist-pkg/render/minimap.d.ts +0 -11
  494. package/dist-pkg/render/minimap.js +0 -94
  495. package/dist-pkg/render/parallax.d.ts +0 -85
  496. package/dist-pkg/render/parallax.js +0 -158
  497. package/dist-pkg/render/player-anim.d.ts +0 -71
  498. package/dist-pkg/render/player-anim.js +0 -152
  499. package/dist-pkg/render/recycling-tex.d.ts +0 -48
  500. package/dist-pkg/render/recycling-tex.js +0 -164
  501. package/dist-pkg/render/scene-city.d.ts +0 -77
  502. package/dist-pkg/render/scene-city.js +0 -181
  503. package/dist-pkg/render/scene-parallax.d.ts +0 -72
  504. package/dist-pkg/render/scene-parallax.js +0 -426
  505. package/dist-pkg/render/scene-sky.d.ts +0 -126
  506. package/dist-pkg/render/scene-sky.js +0 -295
  507. package/dist-pkg/render/set-cenario.d.ts +0 -54
  508. package/dist-pkg/render/set-cenario.js +0 -103
  509. package/dist-pkg/render/textures.d.ts +0 -75
  510. package/dist-pkg/render/textures.js +0 -240
  511. package/dist-pkg/render/title-scene.d.ts +0 -46
  512. package/dist-pkg/render/title-scene.js +0 -75
  513. package/dist-pkg/render/weather.d.ts +0 -96
  514. package/dist-pkg/render/weather.js +0 -171
  515. package/dist-pkg/render/wheelchair-sprites.d.ts +0 -32
  516. package/dist-pkg/render/wheelchair-sprites.js +0 -69
  517. package/dist-pkg/render/world-tex.d.ts +0 -18
  518. package/dist-pkg/render/world-tex.js +0 -87
  519. package/dist-pkg/ui/activities-menu.d.ts +0 -258
  520. package/dist-pkg/ui/activities-menu.js +0 -648
  521. package/dist-pkg/ui/caa-sets.d.ts +0 -39
  522. package/dist-pkg/ui/caa-sets.js +0 -65
  523. package/dist-pkg/ui/latch-refusal.d.ts +0 -32
  524. package/dist-pkg/ui/latch-refusal.js +0 -60
  525. package/dist-pkg/ui/map-hub.d.ts +0 -56
  526. package/dist-pkg/ui/map-hub.js +0 -138
  527. package/dist-pkg/ui/settings-caa.d.ts +0 -45
  528. package/dist-pkg/ui/settings-caa.js +0 -137
  529. package/dist-pkg/ui/settings-motor.d.ts +0 -175
  530. package/dist-pkg/ui/settings-motor.js +0 -342
  531. package/dist-pkg/ui/webcam.d.ts +0 -7
  532. package/dist-pkg/ui/webcam.js +0 -93
@@ -1,43 +1,42 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
2
  import type { Action } from './actions.js';
3
- /** Gênero gramatical do nome. `n` = neutro/indefinido (o pt-BR usa o masculino como default nesse caso). */
3
+ /** The name's grammatical gender. `n` = neuter/unknown (Portuguese uses the masculine as the default then). */
4
4
  export type Gender = 'm' | 'f' | 'n';
5
- /** Um nome que pode ser FALADO (leitor de tela) e SINALIZADO (Libras, que traduz o mesmo texto). */
5
+ /** A name that can be SPOKEN (screen reader) and SIGNED (Libras, which translates the same text). */
6
6
  export interface Speakable {
7
- /** O nome, na língua da interface. Conteúdo de currículo NÃO se traduz — ver o pilar 3 do ADR-0010. */
7
+ /** The name, in the interface's language. Curriculum content is NOT translated — see pillar 3 of ADR-0010. */
8
8
  readonly text: string;
9
9
  readonly gender: Gender;
10
10
  readonly plural: boolean;
11
11
  }
12
12
  /**
13
- * COMO SE CONTA UM PASSO — e é isto que decide a métrica, que não é a mesma em todo tabuleiro.
13
+ * HOW A STEP IS COUNTED — and that is what decides the metric, which is not the same on every board.
14
14
  *
15
- * ⚠️ A grade tinha UMA métrica fixa (Chebyshev), com a razão escrita ao lado: *"numa grade, a diagonal custa um
16
- * passo, e é assim que quem joga conta"*. Verdade onde a diagonal é legal. **Falsa num quebra-cabeça
17
- * deslizante**, onde nada anda na diagonal: uma peça duas à direita e duas abaixo está a 2 por Chebyshev e a
18
- * QUATRO movimentos de distância. O sonar sub-relatava até 2× — e sub-relatar distância a quem não vê a tela
19
- * não é imprecisão, é mandar a criança para o lado errado com confiança.
15
+ * ⚠️ The grid had ONE fixed metric (Chebyshev), on the reasoning that on a grid a diagonal costs one step. True where the
16
+ * diagonal is legal. **False in a sliding puzzle**, where nothing moves diagonally: a piece two right and two down is 2
17
+ * away by Chebyshev and FOUR moves away. The sonar under-reported up to 2× — and under-reporting distance to someone who
18
+ * cannot see the screen is not imprecision, it is sending the child the wrong way with confidence.
20
19
  *
21
- * `grid` nunca foi UMA coisa. Quem declara a grade declara também como se anda nela.
20
+ * `grid` was never ONE thing. Whoever declares a grid declares how one walks on it.
22
21
  */
23
22
  export type MoveRule = 'orthogonal' | 'diagonal' | 'free';
24
23
  /**
25
- * EM QUE PALAVRAS SE DIZ UMA DIREÇÃO. Não é preferência de quem ouve: é propriedade do ESPAÇO do jogo.
24
+ * IN WHAT WORDS A DIRECTION IS SAID. Not the listener's preference: a property of the game's SPACE.
26
25
  *
27
- * `compass` norte · sul · leste · oeste (+ zênite e nadir) — tabuleiro, top-down, mapa, 3D
28
- * `clock` «às 2 horas», «às 10 horas» — PLATAFORMA 2D, vista lateral
26
+ * `compass` north · south · east · west (+ zenith and nadir) — board, top-down, map, 3D
27
+ * `clock` "at 2 o'clock", "at 10 o'clock" — a 2D PLATFORMER, side view
29
28
  *
30
- * ⚠️ Num jogo de plataforma, norte e sul não querem dizer nada: a criança não está a olhar um mapa, está a
31
- * olhar de lado. O relógio é o referencial que essa vista já usa, e dá 12 posições onde a rosa dá 8.
29
+ * ⚠️ In a platformer north and south mean nothing: the child is not looking at a map, they are looking from the side.
30
+ * The clock is the frame that view already uses, and gives 12 positions where the rose gives 8.
32
31
  *
33
- * ⚠️ E O RELÓGIO PRESSUPÕE LER RELÓGIO ANALÓGICO, num público que inclui alfabetização. Não é motivo para o
34
- * recusar — é motivo para o rótulo FALADO ser testado com criança (issue #7) antes de se declarar bom.
32
+ * ⚠️ AND THE CLOCK ASSUMES READING AN ANALOGUE CLOCK, for an audience that includes early literacy. Not a reason to
33
+ * refuse it — a reason for the SPOKEN label to be tested with children (issue #7) before it is declared good.
35
34
  */
36
35
  export type Frame = 'compass' | 'clock';
37
36
  export type Topology =
38
37
  /**
39
- * Grade discreta. A distância é em CÉLULAS, e a métrica sai de `move`.
40
- * `size` é `[colunas, linhas]` ou `[colunas, linhas, camadas]`.
38
+ * A discrete grid. Distance is in CELLS, and the metric comes from `move`.
39
+ * `size` is `[columns, rows]` or `[columns, rows, layers]`.
41
40
  */
42
41
  {
43
42
  readonly kind: 'grid';
@@ -46,8 +45,8 @@ export type Topology =
46
45
  readonly frame: Frame;
47
46
  }
48
47
  /**
49
- * Espaço contínuo. A distância é em UNIDADES do mundo; `unit` diz quanto vale um "passo" para quem narra.
50
- * `size` é `[largura, altura]` ou `[largura, altura, profundidade]`.
48
+ * Continuous space. Distance is in world UNITS; `unit` says what a "step" is worth to the narrator.
49
+ * `size` is `[width, height]` or `[width, height, depth]`.
51
50
  */
52
51
  | {
53
52
  readonly kind: 'continuous';
@@ -56,43 +55,41 @@ export type Topology =
56
55
  readonly move: MoveRule;
57
56
  readonly frame: Frame;
58
57
  }
59
- /** Sem espaço: uma lista ORDENADA de alvos. A distância é a diferença de índice, e não há direção. */
58
+ /** No space: an ORDERED list of targets. Distance is the difference of index, and there is no direction. */
60
59
  | {
61
60
  readonly kind: 'hotspots';
62
61
  readonly order: readonly string[];
63
62
  };
64
63
  /**
65
- * Uma posição, na métrica da topologia declarada. Em `hotspots`, `x` é o índice e `y` é ignorado.
64
+ * A position, in the declared topology's metric. In `hotspots`, `x` is the index and `y` is ignored.
66
65
  *
67
- * ⚠️ ASSIMETRIA DELIBERADA COM `size`, e vale dizer por quê. A EXTENSÃO é um vetor porque a dimensão varia e
68
- * `size.length` é o único lugar onde ela mora — sem isso, "tem profundidade?" viraria `depth !== undefined`
69
- * espalhado por cada consumidor. O PONTO tem eixos com nome porque é lido em código a toda hora: `alvo.at.x`
70
- * diz o que é, `alvo.at[0]` obriga a lembrar. Dimensão é 2 ou 3 e a conformidade recusa o resto, o que fecha
71
- * a assimetria: não há `size` que `Spot` não consiga representar.
66
+ * ⚠️ A DELIBERATE ASYMMETRY WITH `size`. The EXTENT is a vector because the dimension varies and `size.length` is the
67
+ * one place it lives — otherwise "does it have depth?" would become `depth !== undefined` in every consumer. The POINT
68
+ * has named axes because code reads it all the time: `target.at.x` says what it is, `target.at[0]` makes you remember.
69
+ * The dimension is 2 or 3 and conformance refuses the rest, which closes the asymmetry: there is no `size` `Spot`
70
+ * cannot represent.
72
71
  */
73
72
  export interface Spot {
74
73
  readonly x: number;
75
74
  readonly y: number;
76
75
  readonly z?: number;
77
76
  }
78
- /** A dimensão que a topologia declara. `hotspots` não tem espaço, logo não tem dimensão. */
79
- export declare function dimension(t: Topology): number;
80
77
  export type Role = 'hazard' | 'climb' | 'water' | 'goal' | 'gate' | 'key' | 'structure' | 'free';
81
78
  /**
82
- * ⚠️ `zenith` E `nadir` ENTRARAM PORQUE `up`/`down` JÁ QUEREM DIZER DUAS COISAS. `ACTIONS` (core/actions) tem
83
- * `up` e `down` como AÇÕES DE CONTROLE — o que a criança carrega —, e o eixo vertical do ESPAÇO é outra coisa
84
- * inteiramente. Enquanto o mundo era plano a ambiguidade não custava nada; num espaço de três dimensões
85
- * custaria o pior tipo de defeito, o que se lê certo e faz outra coisa. Palavras próprias, antes de o 3D chegar.
79
+ * ⚠️ `zenith` AND `nadir` EXIST BECAUSE `up`/`down` ALREADY MEAN TWO THINGS. `ACTIONS` (core/actions) has `up` and
80
+ * `down` as CONTROL ACTIONS — what the child presses — and the vertical axis of SPACE is something else entirely. On a
81
+ * flat world the ambiguity cost nothing; in three dimensions it would cost the worst kind of defect, one that reads right
82
+ * and does something else. Words of their own, before 3D arrives.
86
83
  */
87
84
  export type Heading = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw' | 'zenith' | 'nadir' | 'none';
88
85
  /**
89
- * PARA ONDE FICA UM PONTO VISTO DE OUTRO, já no referencial que a topologia declara.
86
+ * WHERE A POINT LIES AS SEEN FROM ANOTHER, already in the frame the topology declares.
90
87
  *
91
- * ⚠️ NÃO É O `heading` DO FOCO, e a diferença é o defeito que isto conserta. `Focus.heading` é para onde a
92
- * criança está VIRADA; isto é para onde está o ALVO. O sonar precisa do segundo e calculava-o à mão a partir
93
- * de `x` cru, com zona morta de ±4, dizendo `left`/`right`/`ahead` — três palavras onde o contrato tem oito, e
94
- * MISTURANDO REFERENCIAIS: *esquerda/direita* é relativo à tela, *à frente* é relativo ao corpo. Uma criança
95
- * cega que ouve as duas na mesma frase não tem como saber de qual origem cada uma fala.
88
+ * ⚠️ NOT THE FOCUS'S `heading`, and the difference is the defect this fixes. `Focus.heading` is where the child is
89
+ * FACING; this is where the TARGET is. The sonar needs the second and used to compute it by hand from a raw `x`, saying
90
+ * `left`/`right`/`ahead` — three words where the contract has eight, and MIXING FRAMES: left/right is relative to the
91
+ * screen, ahead is relative to the body. A blind child hearing both in one sentence cannot know which origin each one
92
+ * speaks from.
96
93
  */
97
94
  export type Bearing = {
98
95
  readonly kind: 'compass';
@@ -104,13 +101,13 @@ export type Bearing = {
104
101
  readonly kind: 'none';
105
102
  };
106
103
  export interface Focus {
107
- /** Quem está com o foco. Um id do jogo — a engine não o interpreta, só o carrega. */
104
+ /** Who has the focus. A game id — the engine does not interpret it, only carries it. */
108
105
  readonly id: string;
109
106
  readonly at: Spot;
110
107
  readonly heading: Heading;
111
108
  }
112
109
  export interface Objective {
113
- /** O que se está juntando/resolvendo: "moedas", "palavras", "contas". */
110
+ /** What is being gathered/solved: "coins", "words", "sums". */
114
111
  readonly name: Speakable;
115
112
  readonly have: number;
116
113
  readonly need: number;
@@ -125,202 +122,183 @@ export type Announcement = {
125
122
  readonly urgent: boolean;
126
123
  };
127
124
  /**
128
- * O que a criança vê como sendo o jogo.
125
+ * What the child sees as being the game.
129
126
  *
130
- * ⚠️ `none` NÃO É UM PADRÃO, É UMA ESCOLHA ESCRITA. Existe para atividade sem espaço — uma tela de pintura
131
- * livre, autoria, um formulário —, onde não há «mundo» para simular nem alvo para sonar. O Dev nomeou o caso:
132
- * *"atividades como paint não são exatamente jogos, mas podem ser feitas com a engine e sonar não vai
133
- * funcionar muito bem"*.
127
+ * ⚠️ `none` IS NOT A DEFAULT, IT IS A WRITTEN CHOICE. It exists for an activity without space — free painting,
128
+ * authoring, a form — where there is no world to simulate over and no target for a sonar. The Dev named the case:
129
+ * «atividades como paint não são exatamente jogos, mas podem ser feitas com a engine e sonar não vai funcionar muito
130
+ * bem».
134
131
  *
135
- * ⚠️ E O QUE ELE NÃO PODE SER É O QUE ACONTECE QUANDO ALGUÉM ESQUECE. Um jogo de DOM puro não é «um jogo onde
136
- * empatia não faz sentido»: o xadrez às cegas é a prova empírica de que faz. `none` é para quem DECLARA que
137
- * não tem espaço, e a ausência do campo é reprovada — hoje as duas coisas produzem o mesmo silêncio.
132
+ * ⚠️ AND WHAT IT CANNOT BE IS WHAT HAPPENS WHEN SOMEONE FORGETS. A pure-DOM game is not a game where empathy makes no
133
+ * sense: blindfold chess is the empirical proof that it does. `none` is for whoever DECLARES they have no space, and the
134
+ * field's absence is refused — otherwise both would produce the same silence.
138
135
  */
139
136
  export type WorldScope =
140
- /** O seletor do elemento que é o mundo. A engine aplica ali o que é do mundo, e só ali. */
137
+ /** The selector of the element that is the world. The engine applies what belongs to the world there, and only there. */
141
138
  {
142
139
  readonly kind: 'element';
143
140
  readonly selector: string;
144
141
  }
145
- /** Sem espaço. Empatia e sonar NÃO são oferecidos — e a tela de seleção diz isso antes de a criança começar. */
142
+ /** No space. Empathy and sonar are NOT offered — and the selection screen says so before the child starts. */
146
143
  | {
147
144
  readonly kind: 'none';
148
145
  };
149
146
  /**
150
- * O que um jogo entrega à engine. `tick` é dado; TODO O RESTO é função, porque a resposta muda com a posição,
151
- * o jogador e o instante.
147
+ * What a game hands the engine. `tick` is data; EVERYTHING ELSE is a function, because the answer changes with the
148
+ * position, the player and the instant.
152
149
  *
153
- * ⚠️ NÃO IMPORTE ISTO INTEIRO num módulo consumidor. Use `Pick<GameDeclaration, 'roleAt'>` e afins — a regra é
154
- * a de `core/entity`, e é o que mantém os fixtures de teste pequenos.
150
+ * ⚠️ DO NOT IMPORT THIS WHOLE into a consuming module. Use `Pick<GameDeclaration, 'roleAt'>` and the like — the rule of
151
+ * `core/entity`, which keeps test fixtures small.
155
152
  */
156
153
  export interface GameDeclaration {
157
154
  /**
158
- * A forma do espaço AGORA.
155
+ * The shape of the space NOW.
159
156
  *
160
- * ⚠️ ERA UM VALOR ATÉ 2026-09-06, e a assimetria já tinha sido remendada em dois lugares antes de alguém a
161
- * nomear: a porta do sonar sempre pediu `topology: () => Topology` (`platform/audio-sonar.ts`), e
162
- * `boot/create-game` fazia a ponte com `() => o.declaration.topology` — uma função que devolve uma
163
- * constante. O `game-15puzzle` (3×3/4×4/5×5) precisou de um getter para caber no tipo, e um getter que
164
- * satisfaz uma interface é COINCIDÊNCIA DO TypeScript, não contrato: nada avisava o próximo autor de que
165
- * era o esperado, e `conformanceProblems` lia uma vez só — quem memorizasse a topologia ficava defasado
166
- * em silêncio. Remendo que aparece duas vezes é o contrato a pedir para mudar. ADR-0084.
157
+ * ⚠️ It was a value, and the asymmetry had been patched in two places before anyone named it: the sonar's port always
158
+ * asked for a function, and the root bridged it with a function returning a constant. A sliding puzzle whose board
159
+ * size changes needed a getter to fit the type — and a getter that satisfies an interface is a TypeScript
160
+ * COINCIDENCE, not a contract: nothing told the next author it was expected, and conformance read it once, so whoever
161
+ * memorised the topology went stale in silence. A patch that shows up twice is the contract asking to change.
162
+ * ADR-0084.
167
163
  */
168
164
  topology(): Topology;
169
165
  /**
170
- * QUAL ELEMENTO É O MUNDO. Ver o bloco 8 acima para o defeito que este campo conserta.
166
+ * WHICH ELEMENT IS THE WORLD. See block 8 above for the defect this field fixes.
171
167
  *
172
- * ⚠️ OBRIGATÓRIO, e a obrigatoriedade é a decisão. A proposta original era um campo opcional com padrão;
173
- * o Dev recusou, e a razão é o BLINDFOLD CHESS: xadrez às cegas existe, logo um jogo de DOM puro não é um
174
- * jogo onde empatia não faz sentido — é um jogo onde ela exige mais de quem o programa. Um padrão deixaria
175
- * o esquecimento passar como se fosse escolha.
168
+ * ⚠️ REQUIRED, and requiring it is the decision. The original proposal was an optional field with a default; the Dev
169
+ * refused, and the reason is BLINDFOLD CHESS: it exists, so a pure-DOM game is not one where empathy makes no sense —
170
+ * it is one where it asks more of whoever programs it. A default would let forgetting pass as a choice.
176
171
  */
177
172
  world(): WorldScope;
178
173
  /**
179
- * QUANTAS POSIÇÕES ESTE JOGO PRECISA DE SEGURAR AO MESMO TEMPO. Correr + andar + pular são TRÊS; um quiz é
180
- * UM. (ADR-0104 §A.)
174
+ * HOW MANY POSITIONS THIS GAME NEEDS HELD AT THE SAME TIME. Run + walk + jump is THREE; a quiz is ONE. (ADR-0104 §A.)
181
175
  *
182
- * ⚠️ É UM EIXO DIFERENTE DE «QUANTAS AÇÕES», e é por não serem o mesmo que existia um ponto cego onde o
183
- * aviso nunca disparava. Medido: a plataforma declara NOVE ações e o controle de tela tem NOVE lugares,
184
- * então o `alcance().ok` era verdadeiro e o cartão da #112 nunca aparecia — mas correr, andar e pular ao
185
- * mesmo tempo são três dedos, e num telemóvel de dois a criança simplesmente não consegue, sem nada em
186
- * lado nenhum a dizer porquê. Alcançar uma ação e segurá-la junto com outra são perguntas distintas.
176
+ * ⚠️ A DIFFERENT AXIS FROM "HOW MANY ACTIONS", and because they are not the same there was a blind spot where the
177
+ * warning never fired: a game declaring nine actions on a pad with nine places reached them all, so the reach notice
178
+ * never appeared — but running, walking and jumping at once is three fingers, and on a two-finger phone the child
179
+ * simply cannot, with nothing anywhere saying why. Reaching an action and holding it with another are two questions.
187
180
  *
188
- * ⚠️ OBRIGATÓRIO, e a obrigatoriedade É a decisão, na frase do Dev: «os 300 jogos precisam declarar sim!
189
- * Não declarar é ter a acessibilidade programada no controle pro sorte». Um campo opcional é respondido
190
- * por SILÊNCIO, e aqui o silêncio decide pela criança — decide-o quem não pensou no assunto. Trezentos
191
- * jogos a responder deliberadamente é o custo; acessibilidade por sorte é a alternativa.
181
+ * ⚠️ REQUIRED, and requiring it IS the decision, in the Dev's words: «os 300 jogos precisam declarar sim! Não declarar
182
+ * é ter a acessibilidade programada no controle pro sorte». An optional field is answered by SILENCE, and here the
183
+ * silence decides for the child — decided by whoever did not think about it.
192
184
  *
193
- * FUNÇÃO e não valor, pela mesma razão que a `topology`: um jogo com fases troca de exigência entre elas —
194
- * uma fase a pé pede três, a mesma fase num veículo pode pedir uma. Um valor memorizado ficaria defasado
195
- * em silêncio, que é o defeito que o ADR-0084 nomeou.
185
+ * A FUNCTION and not a value, like `topology`: a game with stages changes its demand between them — on foot it asks
186
+ * for three, in a vehicle perhaps one. A memorised value would go stale in silence, the defect ADR-0084 named.
196
187
  */
197
188
  holdsAtOnce(): number;
198
189
  /**
199
- * ESTE JOGO SEGURA ALGUMA TECLA? — e a resposta não é derivável de mais nada. (ADR-0115.)
190
+ * DOES THIS GAME HOLD ANY KEY? — and the answer cannot be derived from anything else. (ADR-0115.)
200
191
  *
201
- * 🔴 A ALTERNÂNCIA EXISTE PARA UMA CRIANÇA CONCRETA: quem não consegue MANTER uma tecla premida carrega uma
202
- * vez para andar e outra para parar. Num jogo onde nada se segura — um quiz, um tabuleiro, um puzzle de
203
- * peças — não há nada a travar, e o controle passa a ser uma opção que **não faz nada**. A criança abre o
204
- * menu de acessibilidade, liga o ajuste de que depende, e não acontece nada: ela aprende que o ajuste está
205
- * partido. É o botão morto que o ADR-0106 §5 proíbe.
192
+ * 🔴 THE TOGGLE EXISTS FOR A CONCRETE CHILD: whoever cannot KEEP a key pressed taps once to walk and again to stop. In
193
+ * a game where nothing is held — a quiz, a board, a tile puzzle — there is nothing to latch, and the setting becomes
194
+ * an option that **does nothing**. The child opens the accessibility menu, turns on the setting they depend on, and
195
+ * nothing happens: they learn the setting is broken. It is the dead button ADR-0106 §5 forbids.
206
196
  *
207
- * ⚠️ E O `holdsAtOnce` ACIMA NÃO RESPONDE ISTO, o que foi o achado que obrigou a este campo: ele conta
208
- * POSIÇÕES SIMULTÂNEAS e recusa zero, porque zero faria a aritmética do alcance passar por vacuidade. O
209
- * `consumer-quiz` declara **1 sem segurar coisa nenhuma**. «Um de cada vez» e «um SEGURADO» são o mesmo
210
- * número, e toda decisão a jusante vinha a ler um número que responde a outra pergunta.
197
+ * ⚠️ AND `holdsAtOnce` ABOVE DOES NOT ANSWER THIS, which is the finding that forced this field: it counts SIMULTANEOUS
198
+ * positions and refuses zero, because zero would pass the reach arithmetic vacuously. The demo quiz declares **1
199
+ * while holding nothing at all**. "One at a time" and "one HELD" are the same number, and every decision downstream
200
+ * was reading a number that answers another question.
211
201
  *
212
- * ⚠️ OBRIGATÓRIO, e a obrigatoriedade É a decisão — a mesma do `holdsAtOnce`, pela mesma frase do Dev:
213
- * «não declarar é ter a acessibilidade programada no controle pro sorte». Um campo opcional faria um jogo
214
- * que ESQUECE a linha perder a alternância em silêncio, e quem paga é a criança com dificuldade motora.
202
+ * ⚠️ REQUIRED, and requiring it IS the decision — the same as `holdsAtOnce`, by the same words of the Dev. An optional
203
+ * field would let a game that FORGETS the line lose the toggle in silence, and the child with a motor difficulty pays.
215
204
  *
216
- * 📌 FUNÇÃO e não valor, pelo ADR-0084: um jogo muda de exigência entre fases. A pé segura-se uma direcção;
217
- * o mesmo jogo dentro de um veículo pode não segurar nada.
205
+ * 📌 A FUNCTION and not a value, by ADR-0084: a game changes its demand between stages. On foot one holds a direction;
206
+ * the same game in a vehicle may hold nothing.
218
207
  */
219
- seguraTeclas(): boolean;
208
+ holdsKeys(): boolean;
220
209
  /**
221
- * ESTE JOGO PRECISA DE UM PONTEIRO — posição contínua? (ADR-0112.)
210
+ * DOES THIS GAME NEED A POINTER — a continuous position? (ADR-0112.)
222
211
  *
223
- * Um jogo de desenho precisa; um quiz não. Declarar faz um aparelho sem ponteiro RECUSAR-SE antes de a
224
- * criança começar, em vez de ela descobrir a meio do primeiro traço.
212
+ * A drawing game does; a quiz does not. Declaring it makes a device without a pointer REFUSE before the child starts,
213
+ * instead of them finding out halfway through the first stroke.
225
214
  *
226
- * ⚠️ OPCIONAL, E A DIFERENÇA PARA O `holdsAtOnce` LOGO ACIMA É DELIBERADA — copiar a obrigatoriedade dele
227
- * seria aplicar uma regra cuja premissa não se sustenta aqui. O `holdsAtOnce` é obrigatório porque não tem
228
- * padrão seguro E porque falha INVISIVELMENTE a quem escreve o jogo: ele tem teclado completo, o jogo corre,
229
- * e quem descobre o defeito é a criança no telemóvel de dois dedos. Este tem padrão seguro (`false`) e falha
230
- * VISIVELMENTE — um jogo de desenho que se esqueça de o declarar é inoperável no próprio aparelho de quem o
231
- * escreve, porque ele também precisaria do ponteiro para o experimentar.
215
+ * ⚠️ OPTIONAL, AND THE DIFFERENCE FROM `holdsAtOnce` JUST ABOVE IS DELIBERATE — copying its requirement would apply a
216
+ * rule whose premise does not hold here. `holdsAtOnce` is required because it has no safe default AND fails INVISIBLY to
217
+ * whoever writes the game: they have a full keyboard, the game runs, and the child on a two-finger phone is who finds
218
+ * the defect. This one has a safe default (`false`) and fails VISIBLY — a drawing game that forgets to declare it is
219
+ * unusable on its own author's device, because they would need the pointer to try it.
232
220
  *
233
- * Obrigar trezentos jogos a escrever `needsPointer: () => false` cobraria o preço do `holdsAtOnce` sem o
234
- * motivo dele.
235
- *
236
- * FUNÇÃO e não valor, pela mesma razão das outras: uma actividade pode desenhar numa fase e não noutra.
221
+ * A FUNCTION and not a value, like the others: an activity may draw in one stage and not in another.
237
222
  */
238
223
  needsPointer?(): boolean;
239
224
  /**
240
- * O MAPEAMENTO DE TECLADO QUE ESTE JOGO QUER — por número de jogadores e por assento (ADR-0115).
241
- *
242
- * A precedência é a que o registo pede, e ela cabe entre duas linhas que já existiam no `input/keyboard`:
243
- * **fábrica da engine → padrão do JOGO → remapeamento da CRIANÇA.** Devolver `null` (ou não declarar) deixa
244
- * a fábrica da engine intacta, que é o comportamento de sempre.
225
+ * THE KEYBOARD MAPPING THIS GAME WANTS — by number of players and by seat (ADR-0115).
245
226
  *
246
- * PARCIAL de propósito: um jogo que só queira trocar o `action1` troca o `action1`. A fusão já existe — é o
247
- * `Object.assign` que sobrepõe o dado guardado —, então esta é mais uma camada no mesmo sítio e não uma
248
- * segunda forma de fundir.
227
+ * The precedence is the one the record asks for: **the engine's factory → the GAME's default → the CHILD's remap.**
228
+ * Returning `null` (or not declaring it) leaves the engine's factory untouched, which is the behaviour it always had.
249
229
  *
250
- * ⚠️ OPCIONAL, e aqui, ao contrário do `seguraTeclas`, o silêncio tem um lado seguro: sem declaração o jogo
251
- * fica com a fábrica da engine, que é jogável e é o que ele já tem hoje. Não há lado errado na ausência.
230
+ * PARTIAL on purpose: a game that only wants to change `action1` changes `action1`. The merge already exists — the
231
+ * `Object.assign` that lays the stored data on top — so this is one more layer in the same place, not a second way to
232
+ * merge.
252
233
  *
253
- * ⚠️ E LEVA O ASSENTO porque o teclado de dois jogadores não é o de um: as setas mudam de dono, e um padrão
254
- * que não soubesse o assento daria as mesmas teclas a duas crianças. `jogadores` é 1, 2, 3 ou 4; `assento` é
255
- * o índice dentro desse arranjo.
234
+ * ⚠️ OPTIONAL, and here, unlike `holdsKeys`, silence has a safe side: with no declaration the game keeps the engine's
235
+ * factory, which is playable and is what it has today.
256
236
  *
257
- * 📌 O irmão do CONTROLE é o campo logo abaixo, e chegou um commit depois: o obstáculo era que o assento
258
- * ainda não se conhecia no ponto em que a tabela de botões é lida, e a saída foi subi-lo no laço.
237
+ * ⚠️ AND IT TAKES THE SEAT because a two-player keyboard is not a one-player one: the arrows change owner, and a
238
+ * default that did not know the seat would give two children the same keys. `players` is 1, 2, 3 or 4; `seat` is the
239
+ * index within that arrangement.
259
240
  */
260
- mapeamentoDoTeclado?(jogadores: number, assento: number): Partial<Record<Action, readonly string[] | null>> | null;
241
+ keyboardMapping?(players: number, seat: number): Partial<Record<Action, readonly string[] | null>> | null;
261
242
  /**
262
- * O MAPEAMENTO DE BOTÕES QUE ESTE JOGO QUER NO CONTROLE — mesma pergunta, outro aparelho (ADR-0115).
243
+ * THE BUTTON MAPPING THIS GAME WANTS ON A PAD — the same question, another device (ADR-0115).
263
244
  *
264
- * Índices de botão da Gamepad API «standard», parciais: `{ action1: 3 }` troca só essa. `null` num botão diz
265
- * «esta posição não existe neste jogo», que é diferente de a deixar na fábrica.
245
+ * Button indices of the "standard" Gamepad API, partial: `{ action1: 3 }` changes just that one. `null` on a button
246
+ * says "this position does not exist in this game", which differs from leaving it at the factory.
266
247
  *
267
- * ⚠️ A PRECEDÊNCIA TEM UMA DIFERENÇA DE SÍTIO QUE VALE SABER: no teclado, o que a criança remapeou é uma
268
- * camada POR CIMA desta; no controle, o mapa que ela gravou no assistente é um RAMO inteiro — se ele existe,
269
- * este padrão não é consultado. Nos dois casos ela ganha, que é o que importa.
248
+ * ⚠️ THE PRECEDENCE SITS IN A DIFFERENT PLACE, worth knowing: on the keyboard, the child's remap is a layer ON TOP of
249
+ * this; on a pad, the map they recorded in the wizard is a whole BRANCH — if it exists, this default is not consulted.
250
+ * Either way the child wins, which is what matters.
270
251
  *
271
- * 📌 E leva o assento pela mesma razão do teclado, ainda que por um caminho diferente: dois controles são
272
- * dois aparelhos, mas o JOGO pode querer arranjos distintos por assento (o guarda-redes e o atacante não
273
- * fazem o mesmo).
252
+ * 📌 It takes the seat for the keyboard's reason, by another path: two pads are two devices, but the GAME may want
253
+ * different arrangements per seat (a goalkeeper and a striker do not do the same thing).
274
254
  */
275
- mapeamentoDoPad?(jogadores: number, assento: number): Partial<Record<Action, number | null>> | null;
255
+ padMapping?(players: number, seat: number): Partial<Record<Action, number | null>> | null;
276
256
  readonly tick: TickOwner;
277
- /** O papel do que está em `at`. É o campo 2, e é o que substitui `roleOf`. */
257
+ /** The role of what is at `at`. Field 2, and what replaces a table of tile numbers. */
278
258
  roleAt(at: Spot): Role;
279
- /** Como se chama o que está em `at`. Sem isto não há leitor de tela nem Libras. */
259
+ /** What the thing at `at` is called. Without it there is no screen reader and no Libras. */
280
260
  nameAt(at: Spot): Speakable | null;
281
- /** Quem tem o foco agora, e para onde aponta. `null` = ninguém (menu fechado, rodada não começou). */
261
+ /** Who has the focus now, and where it points. `null` = nobody (menu closed, round not started). */
282
262
  focusOf(playerIndex: number): Focus | null;
283
- /** O que a rodada pede deste jogador. */
263
+ /** What the round asks of this player. */
284
264
  objectiveOf(playerIndex: number): Objective;
285
265
  /**
286
- * ONDE estão os alvos ainda válidos deste jogador — a segunda metade do campo 5.
266
+ * WHERE this player's still-valid targets are — the second half of field 5.
287
267
  *
288
- * É o que substitui o `getCoins()` do sonar: em vez de a engine varrer um array de moedas e filtrar por
289
- * `taken`/`owner`, o jogo devolve os pontos que ainda contam para ESTE jogador. Um quiz devolve o índice da
290
- * pergunta em aberto; uma plataforma devolve as moedas não coletadas; um Sokoban devolve as caixas fora do
291
- * lugar. A engine só compara distâncias, e é por isso que o sonar passa a servir a qualquer gênero.
268
+ * Instead of the engine sweeping an array of coins and filtering by owner and taken, the game returns the spots that
269
+ * still count for THIS player. A quiz returns the open question's index; a platformer, the coins not taken; a
270
+ * Sokoban, the boxes out of place. The engine only compares distances, which is why the sonar serves any genre.
292
271
  *
293
- * Vazio é resposta legítima e significa "não há para onde apontar" — não é erro.
272
+ * Empty is a legitimate answer and means "there is nowhere to point" — not an error.
294
273
  */
295
274
  targetsOf(playerIndex: number): readonly Spot[];
296
275
  }
297
276
  /**
298
- * Uma declaração é bem-formada? Devolve a lista de problemas — VAZIA quer dizer conforme.
277
+ * Is a declaration well formed? Returns the list of problems — EMPTY means conformant.
299
278
  *
300
- * Existe porque um preset é uma promessa, e promessa sem verificação é comentário. O ADR-0030 diz que um
301
- * pacote de gênero "ou satisfaz os sete campos ou não satisfaz"; isto é o "ou não".
279
+ * It exists because a preset is a promise, and a promise without a check is a comment. ADR-0030 says a genre package
280
+ * "either satisfies the seven fields or does not"; this is the "does not".
302
281
  *
303
- * Confere FORMA, não verdade: que a topologia tenha medida positiva, que as funções existam, que o objetivo
304
- * não peça um alvo impossível. Não tem como conferir se `roleAt` devolve o papel CERTO — isso é o teste do
305
- * preset, não deste módulo.
282
+ * It checks SHAPE, not truth: that the topology has a positive measure, that the functions exist. It cannot check
283
+ * whether `roleAt` returns the RIGHT role — that is the preset's own test, not this module's.
306
284
  */
307
285
  export declare function conformanceProblems(d: Partial<GameDeclaration> | null | undefined): string[];
308
- /** Um nome falável bem-formado? Texto vazio é o defeito silencioso: o leitor de tela simplesmente cala. */
286
+ /** Is a speakable name well formed? Empty text is the silent defect: the screen reader simply goes quiet. */
309
287
  export declare function speakableProblems(s: Speakable | null | undefined): string[];
310
288
  /**
311
- * Distância entre dois pontos NA MÉTRICA declarada — a que o jogo declarou em `move`, e em quantas dimensões
312
- * ele declarou em `size`. É o que o sonar precisa e antes calculava em pixels.
289
+ * The distance between two spots IN THE DECLARED METRIC — the one the game declared in `move`, over as many dimensions
290
+ * as it declared in `size`. It is what the sonar needs and used to compute in pixels.
313
291
  *
314
- * ⚠️ A GRADE ERA SEMPRE CHEBYSHEV, e isso custava até 2× de erro num quebra-cabeça deslizante. As três regras
315
- * não são gosto: são o que "um passo" significa em cada jogo, e o sonar fala em passos.
292
+ * ⚠️ THE GRID WAS ALWAYS CHEBYSHEV, which cost up to 2× error in a sliding puzzle. The three rules are not taste: they
293
+ * are what "one step" means in each game, and the sonar speaks in steps.
316
294
  */
317
295
  export declare function distance(t: Topology, a: Spot, b: Spot): number;
318
296
  /**
319
- * PARA ONDE FICA `to` VISTO DE `from`, já nas palavras que a topologia declarou.
297
+ * WHERE `to` LIES AS SEEN FROM `from`, already in the words the topology declared.
320
298
  *
321
- * ⚠️ DOIS EIXOS COM CONVENÇÕES DIFERENTES, e o silêncio sobre isto seria o defeito. `y` CRESCE PARA BAIXO —
322
- * é a coordenada da tela, herdada da canvas e de todo o código que já existe, não uma escolha desta função.
323
- * `z` CRESCE PARA CIMA, e essa é escolha: nada a força, e num espaço de três dimensões «zênite» só pode
324
- * querer dizer o lado para onde a criança olharia levantando a cabeça. Um jogo 3D tem de saber os dois.
299
+ * ⚠️ TWO AXES WITH DIFFERENT CONVENTIONS, and silence about it would be the defect. `y` GROWS DOWNWARD — the screen's
300
+ * coordinate, inherited from the canvas and all existing code, not a choice of this function. `z` GROWS UPWARD, and
301
+ * that is a choice: nothing forces it, and in three dimensions "zenith" can only mean the side the child would look at
302
+ * by raising their head. A 3D game has to know both.
325
303
  */
326
304
  export declare function bearing(t: Topology, from: Spot, to: Spot): Bearing;